diff --git a/AGENTS.md b/AGENTS.md index 94eadf63..e22f63ac 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1223,7 +1223,23 @@ php artisan plugin:build sirsoft-payment --active # 활성 디렉토리에 > **빌드 원칙**: 기본값은 `_bundled` 디렉토리. 빌드 결과물은 빌드 경로 내에만 남음. -`_bundled` 의 `dist/`(코어는 `public/build/core/`)는 Git 추적되는 배포 산출물이다 (`*.map` 만 ignore). src 변경 시 커밋 dist 를 `--production` 으로 동반 재빌드한다 — 신규 소스 리터럴이 dist 에 없으면 stale 빌드이며, 정적 검사가 이를 검출한다. 커밋 dist 에 `//# sourceMappingURL=` 참조를 남기지 않는다 — `.map` 은 배포본에 존재하지 않아 브라우저 개발자 도구에서 404 를 유발한다. 코어 3번들 재빌드는 `core:build --production` (`--full` 은 앱 번들 전용 — `public/build` 를 비워 코어 3번들을 지운다). +`_bundled` 의 `dist/`(코어는 `public/build/core/`)는 Git 추적되는 배포 산출물이다 (`*.map` 만 ignore). src 변경 시 커밋 dist 를 `--production` 으로 동반 재빌드한다 — 신규 소스 리터럴이 dist 에 없으면 stale 빌드이며, 정적 검사가 이를 검출한다. 커밋 dist 에 `//# sourceMappingURL=` 참조를 남기지 않는다 — `.map` 은 배포본에 존재하지 않아 브라우저 개발자 도구에서 404 를 유발한다. 코어 3번들 재빌드는 `core:build --production`. + +### 빌드는 자기 산출물만 교체한다 (`emptyOutDir`) + +모든 vite config 는 `build.emptyOutDir: false` 를 **명시**한다. 기본값 `true` 는 산출물 디렉토리를 통째로 비우는데, 그 디렉토리에는 vite 가 만들지 않는 서빙 자산이 함께 산다. + +| 함께 지워지던 것 | 결과 | +|---|---| +| `public/build/core/` 3번들 | 폴백이 없다 — `template-engine.min.js` 는 동기 classic 스크립트라 소실 = **사이트 부팅 불가**, 안내 화면조차 렌더되지 않는다 | +| `public/build/ext/{v}/` 게시본 | 이미 배달된 HTML 의 immutable URL 이 404. 재게시로 새 버전이 생겨도 **그 URL 은 복구되지 않는다** | +| 확장 `dist/vendor/` | 확장이 동봉한 구동 제3자 자산 소실 (자체 제공 원칙 위반) | + +소실은 예외도 서버 로그도 남기지 않는다 — 브라우저 404 로만 나타나므로 운영자에게는 흔적이 없다. 잔존하는 구 해시 산출물은 `manifest.json`(또는 고정 파일명)이 선택하므로 참조되지 않는 사표이고, 정리 책임은 빌드 커맨드가 진다. + +빌드 커맨드의 산출물 정리는 **활성 디렉토리를 건너뛴다.** 정리는 빌드 *전에* 돌므로 웹이 서빙 중인 `dist/` 를 비우면 빌드 완료까지가 통째로 서빙 공백이 되고, 빌드가 실패하면 빈 채로 남는다. 정리 대상은 `_bundled` / `_pending` 소스 디렉토리뿐이다. + +정적 검사가 모든 vite config 의 명시 선언을 강제한다 (기본값 의존 금지 — 규약이 코드에 남지 않으면 다음 편집자가 같은 결함을 재도입한다). > 활성 디렉토리 반영은 `update` 커맨드로만 수행. `--watch` 모드는 실시간 개발용으로 활성 디렉토리를 자동 사용. --- diff --git a/CHANGELOG.md b/CHANGELOG.md index b43a6845..7967164f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - 주소 끝에 `?custom=off` 를 붙여 열면 운영자가 추가한 CSS·JS 없이 화면이 표시됩니다. 추가한 스타일이 화면을 망가뜨려 고치러 들어갈 수조차 없게 된 상황에서 쓰는 탈출구이며, 레이아웃 편집기 툴바에도 같은 동작의 버튼이 있습니다. 이 설정은 저장되지 않고 그 화면에만 적용됩니다. - 템플릿·모듈·플러그인의 `custom/` 파일이 다른 확장 자산과 같은 방식으로 정적 파일로 게시됩니다. CSS 안에서 글꼴·이미지를 상대 경로(`url('./font.woff2')`)로 참조할 수 있게 되었고, 파일을 고치면 자동으로 다시 게시됩니다. - 초기 화면에 필요한 다국어·컴포넌트 정의·라우트 정보·확장 번들·템플릿 에셋을 정적 파일로 미리 만들어 웹서버가 직접 전달합니다. 확장 설치/활성화나 레이아웃 편집 시 자동으로 다시 생성되며, 파일이 없으면 기존 방식으로 동작합니다. 초기 화면 표시가 빨라집니다. (#122 @glitter-gim 님께서 건의해주셨습니다.) +- 관리자 대시보드에 초기 화면 파일 생성 실패 알림이 추가되었습니다. 원인(폴더 권한·디스크 공간·캐시)에 따라 다른 안내가 표시되며, 서버에서 `php artisan ext-static:status` 로 더 자세한 상태를 확인할 수 있습니다. (#122 @glitter-gim 님께서 건의해주셨습니다.) ### Changed @@ -29,6 +30,15 @@ - 사이트 첫 접속 시 확장 캐시 버전이 어긋나 있으면 라우트·다국어 데이터를 두 번 내려받던 문제를 수정했습니다. (#122 @glitter-gim 님께서 건의해주셨습니다.) - 레이아웃 props 의 `$switch` 조건 분기 값이 검색엔진(봇) 화면에서는 해석되지 않아 해당 속성이 표시되지 않던 문제를 수정했습니다. 이제 일반 화면과 봇 화면이 동일하게 분기 값을 렌더링합니다. - sudo(root) 로 코어를 업데이트하면 업데이트 과정이 만든 캐시 파일이 root 소유로 남아, 이후 웹 화면 전체가 서버 오류(500)가 되거나 캐시가 동작하지 않을 수 있던 문제를 수정했습니다. 업데이트 종료 시 캐시·번들 디렉토리 소유권을 자동 정상화하고, 캐시 쓰기 실패는 화면을 중단시키지 않고 경고 로그와 함께 무캐시로 계속 동작합니다. +- 프론트엔드를 다시 빌드하면 초기 화면 파일과 화면 구동에 필요한 코어 파일이 함께 지워져, 이미 열려 있던 페이지에서 파일을 찾지 못하던 문제를 수정했습니다. 빌드는 이제 자기 산출물만 교체합니다. (#122 @glitter-gim 님께서 건의해주셨습니다.) +- 명령줄에서 초기 화면 파일을 처음 만들면 이후 웹에서 다시 만들지 못해, 확장을 설치·변경해도 초기 화면 파일이 갱신되지 않던 문제를 수정했습니다. 만들어진 파일이 웹 프로세스도 쓸 수 있는 권한을 갖도록 정리하고, 권한이 부족하면 화면이 느려질 뿐 멈추지 않도록 처리한 뒤 관리자 대시보드에 원인을 알립니다. (#122 @glitter-gim 님께서 건의해주셨습니다.) +- 디스크가 가득 찬 상태에서 만들어진 손상된 초기 화면 파일이 그대로 사용되어 화면이 뜨지 않던 문제를 수정했습니다. 파일을 만들 때 기록된 내용이 온전한지 확인하고, 손상이 확인되면 종전 방식으로 자동 전환합니다. (#122 @glitter-gim 님께서 건의해주셨습니다.) +- 초기 화면 파일을 새로 만드는 도중 짧은 시간 동안 기존 파일을 찾지 못할 수 있던 문제를 수정했습니다. 새 파일이 완성된 뒤에야 이전 파일을 정리합니다. (#122 @glitter-gim 님께서 건의해주셨습니다.) +- 캐시를 비운 뒤 정리 작업이 먼저 실행되면 아직 사용 중인 직전 초기 화면 파일이 삭제될 수 있던 문제를 수정했습니다. (#122 @glitter-gim 님께서 건의해주셨습니다.) +- 확장 프로그램의 스크립트·스타일 묶음을 저장하지 못하는 환경에서 해당 요청이 서버 오류(500)가 되던 문제를 수정했습니다. 저장에 실패해도 화면에는 정상적으로 전달됩니다. (#122 @glitter-gim 님께서 건의해주셨습니다.) +- 배포 도중 확장 파일이 잠시 비면 내용이 빠진 빈 묶음이 정상 응답으로 전달되어, 한참 뒤 기능이 동작하지 않는 형태로만 드러나던 문제를 수정했습니다. 이제 그 상태를 오류로 알립니다. (#122 @glitter-gim 님께서 건의해주셨습니다.) +- 일부 확장자(`.mjs`, `.webp`, `.otf`) 의 없는 파일을 요청하면 파일 대신 페이지 내용이 전달되어 화면이 깨지던 문제를 수정했습니다. (#122 @glitter-gim 님께서 건의해주셨습니다.) +- 초기 화면 파일을 새로 만들 때 파일 시스템이 일시적으로 이동을 거부하면 그 한 번으로 생성이 실패하던 문제를 수정했습니다. 이제 잠시 후 다시 시도하며, 사이트 동작에는 영향이 없지만 불필요한 실패 알림이 뜨던 상황이 사라집니다. (#122 @glitter-gim 님께서 건의해주셨습니다.) ## [7.0.9] - 2026-08-24 diff --git a/README.ko.md b/README.ko.md index ae61f7be..fd9e9b0c 100644 --- a/README.ko.md +++ b/README.ko.md @@ -516,8 +516,8 @@ cp .env.example .env

jiwonpapa - Tuwasduliebst glitter-gim + Tuwasduliebst jordy-bitree laelbe lyg-kaban diff --git a/README.md b/README.md index 55ed9323..4ad934a7 100644 --- a/README.md +++ b/README.md @@ -530,8 +530,8 @@ Thanks to everyone who reported an issue or suggested a feature that shipped —

jiwonpapa - Tuwasduliebst glitter-gim + Tuwasduliebst jordy-bitree laelbe lyg-kaban diff --git a/app/Console/Commands/Concerns/PrunesBuildOutput.php b/app/Console/Commands/Concerns/PrunesBuildOutput.php index ecc54442..55afbce0 100644 --- a/app/Console/Commands/Concerns/PrunesBuildOutput.php +++ b/app/Console/Commands/Concerns/PrunesBuildOutput.php @@ -26,6 +26,13 @@ trait PrunesBuildOutput * 감시(watch) 모드에서는 호출하지 않는다 — 개발 중 재빌드마다 지우면 브라우저가 * 참조 중인 파일이 사라진다. * + * **활성 디렉토리는 정리하지 않는다.** prune 은 빌드 *전에* 실행되므로, 웹이 서빙 + * 중인 `dist/` 를 비우면 prune~빌드 완료 구간 전체가 서빙 공백이 된다(빌드가 실패하면 + * 빈 채로 남는다). 확장 개발은 `_bundled` 에서 수행하고 활성 반영은 `{type}:update` + * 가 담당하므로, 활성 경로 빌드는 예외적 경로다 — 그 경우 stale 산출물이 누적되는 + * 것을 감수하고 서빙 연속성을 택한다. 외부 확장처럼 `_bundled` 가 없어 활성 빌드가 + * 유일한 경로인 경우에도 사이트가 끊기지 않는다. + * * @param string $buildPath 확장 루트 경로 (`dist/` 의 부모) * @param array $preserve 삭제하지 않을 최상위 항목명 * @return array 삭제한 최상위 항목명 목록 @@ -38,6 +45,16 @@ trait PrunesBuildOutput return []; } + if (! $this->isBundledSourcePath($buildPath)) { + $this->warn( + ' ⚠️ 활성 디렉토리 빌드 — 이전 산출물을 정리하지 않습니다 ' + .'(정리하면 빌드 완료까지 서빙이 끊깁니다). stale 산출물이 누적될 수 있으니 ' + .'개발은 _bundled 에서 하고 활성 반영은 update 커맨드로 하세요.' + ); + + return []; + } + $removed = []; foreach (new \FilesystemIterator($distPath, \FilesystemIterator::SKIP_DOTS) as $item) { @@ -66,4 +83,21 @@ trait PrunesBuildOutput return $removed; } + + /** + * 빌드 경로가 소스 디렉토리(`_bundled` / `_pending`)인지 판정합니다. + * + * 이 둘은 웹이 서빙하지 않는 소스 보관소라 비워도 서빙 공백이 없다. 그 밖의 경로는 + * 활성 디렉토리(= 서빙 중)로 본다 — 판정을 뒤집어 두면(활성 목록을 열거하면) 새로운 + * 배치가 생길 때마다 조용히 활성 경로가 정리 대상이 된다. + * + * @param string $buildPath 확장 루트 경로 + * @return bool 소스 디렉토리 여부 + */ + private function isBundledSourcePath(string $buildPath): bool + { + $normalized = str_replace('\\', '/', $buildPath); + + return str_contains($normalized, '/_bundled/') || str_contains($normalized, '/_pending/'); + } } diff --git a/app/Console/Commands/Core/BuildCoreCommand.php b/app/Console/Commands/Core/BuildCoreCommand.php index 593abad9..365b70ad 100644 --- a/app/Console/Commands/Core/BuildCoreCommand.php +++ b/app/Console/Commands/Core/BuildCoreCommand.php @@ -135,6 +135,8 @@ class BuildCoreCommand extends Command return $dashboardResult; } + $this->pruneStaleSourceMaps($productionMode); + $this->info('✅ 코어 빌드 완료 (템플릿 엔진 + 레이아웃 편집기 + DevTools + 개발 대시보드 CSS)'); $this->showEngineBuildResults($projectPath); $this->incrementExtensionCacheVersion(); @@ -142,6 +144,44 @@ class BuildCoreCommand extends Command return Command::SUCCESS; } + /** + * 프로덕션 빌드 후 `public/build/core/` 에 남은 소스맵을 제거합니다. + * + * 프로덕션 빌드는 `G7_BUILD_SOURCEMAP=0` 으로 맵을 **만들지 않을 뿐**, 이전 개발 빌드가 + * 남긴 맵을 지우지는 않는다. 그 디렉토리는 웹루트라 남아 있는 맵은 웹서버가 그대로 + * 서빙하고, 맵에는 원본 코드 전문(`sourcesContent`)이 담긴다 — 확장자 화이트리스트가 + * 막아 주는 확장 에셋과 달리 이 경로는 정적 서빙이라 통과한다. + * + * 종전에는 루트 `npm run build` 의 `emptyOutDir` 이 디렉토리를 통째로 비우면서 이 맵들을 + * 함께 지웠다. 그 동작은 서빙 중인 코어 번들·게시본까지 지우는 결함이라 껐으므로(#122), + * 소스맵 정리 책임을 빌드 커맨드가 명시적으로 넘겨받는다. + * + * @param bool $productionMode 프로덕션 빌드 여부 + */ + private function pruneStaleSourceMaps(bool $productionMode): void + { + if (! $productionMode) { + // 로컬 빌드는 디버깅을 위해 맵을 의도적으로 생성한다 — 지우면 그 목적이 사라진다. + return; + } + + $removed = []; + + foreach (glob(public_path('build/core').DIRECTORY_SEPARATOR.'*.map') ?: [] as $map) { + if (@unlink($map)) { + $removed[] = basename($map); + + continue; + } + + $this->warn(' ⚠️ 소스맵 삭제 실패 (수동 제거 필요): '.$map); + } + + if ($removed !== []) { + $this->line(' 🧹 잔존 소스맵 제거: '.implode(', ', $removed)); + } + } + /** * 감시 모드에서 엔진 번들 + 편집기 번들을 병렬로 vite --watch 실행합니다. * @@ -222,6 +262,7 @@ class BuildCoreCommand extends Command ); if ($result === Command::SUCCESS && ! $watchMode) { + $this->pruneStaleSourceMaps($productionMode); $this->info('✅ 코어 빌드 완료 (전체)'); $this->showFullBuildResults($projectPath); $this->incrementExtensionCacheVersion(); diff --git a/app/Console/Commands/StatusExtensionStaticCacheCommand.php b/app/Console/Commands/StatusExtensionStaticCacheCommand.php new file mode 100644 index 00000000..f93b4865 --- /dev/null +++ b/app/Console/Commands/StatusExtensionStaticCacheCommand.php @@ -0,0 +1,208 @@ +isEnabled(); + $version = ExtensionStaticCacheService::getExtensionCacheVersion(); + $base = $service->baseDir(); + $versionDir = $service->versionDir($version); + $published = $service->isPublished($version); + + $this->line(''); + $this->line('부트스트랩 리소스 정적 게시 상태'); + $this->line(''); + + $this->line(' 실행 계정 : '.ExtensionStaticCacheService::currentProcessUser()); + $this->line(' kill-switch : '.($enabled ? '활성 (게시함)' : '비활성 (게시 안 함)')); + $this->line(' 현재 캐시 버전 : '.$version); + $this->line(' 게시 루트 : '.$base); + + // kill-switch 가 꺼져 있으면 미게시는 정상이다 — 이상으로 세지 않는다. + if (! $enabled) { + $this->line(''); + $this->comment('kill-switch 가 꺼져 있어 게시 상태는 점검하지 않습니다 (core.static_cache.enabled).'); + + return self::SUCCESS; + } + + // 1) 게시 트리 쓰기 가능성 — 제보 본건(P1/P2)의 직접 지표 + $writable = File::isDirectory($base) ? is_writable($base) : $this->parentIsWritable($base); + + if ($writable) { + $this->line(' 트리 쓰기 : 가능'); + } else { + $this->line(' 트리 쓰기 : 불가'); + $problems[] = sprintf( + '게시 트리에 쓸 수 없습니다 (%s, owner=%s, perms=%s). 웹 계정이 재게시할 수 없어 ' + .'모든 요청이 API 폴백으로 동작합니다.', + $base, + (string) (@fileowner($base) ?: 'unknown'), + File::exists($base) ? substr(sprintf('%o', @fileperms($base)), -4) : 'absent' + ); + } + + // 2) 현재 버전 게시 여부 + if ($published) { + $manifest = json_decode((string) @file_get_contents($versionDir.'/manifest.json'), true); + $fileCount = is_array($manifest) ? count($manifest['files'] ?? []) : 0; + + $this->line(' 게시 상태 : 완료'); + $this->line(' manifest 파일 : '.$fileCount.'건'); + $this->line(' 게시 시각 : '.(is_array($manifest) ? ($manifest['published_at'] ?? '?') : '?')); + + if ($fileCount === 0) { + $problems[] = 'manifest 에 기록된 파일이 0건입니다 — 게시가 비어 있습니다.'; + } + } else { + $this->line(' 게시 상태 : 미게시'); + $problems[] = sprintf( + '현재 버전(%d)이 게시되지 않았습니다. 다음 웹 렌더의 자가 치유가 시도하며, ' + .'즉시 게시하려면 `php artisan ext-static:publish` 를 실행하세요.', + $version + ); + } + + // 3) 최근 실패 마커 — 원인별로 조치가 다르다 + $marker = ExtensionStaticCacheService::failureMarker(); + + if ($marker !== null) { + $this->line(''); + $this->line(' 최근 게시 실패'); + $this->line(' 사유 : '.($marker['reason'] ?? '?').' — '.$this->reasonHint($marker['reason'] ?? '')); + $this->line(' 버전 : '.($marker['version'] ?? '?')); + $this->line(' 시각 : '.($marker['at'] ?? '?')); + $this->line(' 연속 실패 : '.($marker['count'] ?? '?').'회'); + $this->line(' 상세 : '.($marker['message'] ?? '')); + + $problems[] = '게시 실패 마커가 남아 있습니다 (사유: '.($marker['reason'] ?? '?').').'; + } + + // 4) 잔존 버전 목록 — 누적은 삭제 실패(소유권 불일치)의 지표다 + $versions = $this->publishedVersions($base); + + $this->line(''); + $this->line(' 잔존 버전 : '.($versions === [] ? '(없음)' : implode(', ', $versions))); + + if (count($versions) > 3) { + $problems[] = sprintf( + '게시 버전이 %d개 누적됐습니다 (정상은 현재+직전 2개). 삭제가 실패하고 있을 수 ' + .'있습니다 — 소유권/권한을 확인하세요.', + count($versions) + ); + } + + $this->line(''); + + if ($problems === []) { + $this->info('이상 없음.'); + + return self::SUCCESS; + } + + foreach ($problems as $problem) { + $this->warn('• '.$problem); + } + + $this->line(''); + + return self::FAILURE; + } + + /** + * 게시 루트가 아직 없을 때, 만들 수 있는지(부모 쓰기 가능) 판정합니다. + * + * @param string $base 게시 루트 절대 경로 + * @return bool 생성 가능 여부 + */ + private function parentIsWritable(string $base): bool + { + $parent = dirname($base); + + return File::isDirectory($parent) && is_writable($parent); + } + + /** + * 실패 사유 코드에 대한 조치 힌트를 반환합니다. + * + * 사유별로 볼 곳이 다르다 — 뭉뚱그리면 운영자가 어디를 봐야 할지 알 수 없다. + * + * @param string $reason 사유 코드 + * @return string 조치 힌트 + */ + private function reasonHint(string $reason): string + { + return match ($reason) { + 'parent_not_writable' => '게시 트리 권한 문제입니다. CLI 계정과 웹 계정이 그룹을 공유하고 ' + .'`public/build` 가 그룹 쓰기(g+w)인지 확인하세요.', + 'write_failed' => '쓰기 도중 실패했습니다. 디스크 여유 공간과 quota 를 확인하세요.', + 'lock_unavailable' => '캐시 락을 얻지 못했습니다. 캐시 저장소(파일 캐시 디렉토리 권한 등)를 확인하세요.', + default => '상세 메시지를 확인하세요.', + }; + } + + /** + * 게시 루트에 남아 있는 버전 디렉토리 목록을 반환합니다 (오름차순). + * + * @param string $base 게시 루트 절대 경로 + * @return array 버전 목록 + */ + private function publishedVersions(string $base): array + { + if (! File::isDirectory($base)) { + return []; + } + + $versions = []; + + foreach (File::directories($base) as $dir) { + $name = basename($dir); + + if (ctype_digit($name)) { + $versions[] = (int) $name; + } + } + + sort($versions); + + return $versions; + } +} diff --git a/app/Extension/Helpers/ExtensionPendingHelper.php b/app/Extension/Helpers/ExtensionPendingHelper.php index 2755b9d6..1fe66a25 100644 --- a/app/Extension/Helpers/ExtensionPendingHelper.php +++ b/app/Extension/Helpers/ExtensionPendingHelper.php @@ -344,6 +344,11 @@ class ExtensionPendingHelper ?\Closure $onProgress = null ): void { File::ensureDirectoryExists($dest, 0775); + // 디렉토리도 부모 소유권을 상속시킨다 — 파일만 `copyFile` 로 상속시키면 sudo 로 + // 실행된 설치/업데이트가 만든 **디렉토리**가 root 소유로 남아, 이후 웹 프로세스의 + // 쓰기가 그 디렉토리에서 막힌다. 형제 구현 `ExtensionBackupHelper:: + // copyDirectoryWithProgress` 는 이미 같은 방어를 갖고 있다 (계층 불균형 해소). + FilePermissionHelper::inheritOwnershipFromParent($dest); $items = new \FilesystemIterator($source, \FilesystemIterator::SKIP_DOTS); foreach ($items as $item) { @@ -384,6 +389,7 @@ class ExtensionPendingHelper private static function syncDirectoryContents(string $source, string $dest, ?\Closure $onProgress = null): void { File::ensureDirectoryExists($dest, 0775); + FilePermissionHelper::inheritOwnershipFromParent($dest); $failed = []; self::overlayDirectory($source, $dest, $source, $onProgress, $failed); @@ -458,6 +464,9 @@ class ExtensionPendingHelper array &$failed ): void { File::ensureDirectoryExists($dest, 0775); + // 제자리 동기화 폴백 경로도 동일 방어 — rename 경로만 고치면 파일 잠금으로 + // 이 경로로 떨어진 교체에서만 소유권이 조용히 어긋난다. + FilePermissionHelper::inheritOwnershipFromParent($dest); $items = new \FilesystemIterator($source, \FilesystemIterator::SKIP_DOTS); foreach ($items as $item) { diff --git a/app/Extension/Traits/ClearsTemplateCaches.php b/app/Extension/Traits/ClearsTemplateCaches.php index 2cf403e2..d056af18 100644 --- a/app/Extension/Traits/ClearsTemplateCaches.php +++ b/app/Extension/Traits/ClearsTemplateCaches.php @@ -109,6 +109,17 @@ trait ClearsTemplateCaches ]); } + // 재생성도 bump 다 — 게시를 예약한다. `incrementExtensionCacheVersion()` 과 + // 동형화해 "캐시 버전 갱신 → 게시" 가 **모든 경로**에서 성립하게 한다 (#122). + // + // 이 경로가 빠져 있던 동안 `cache:clear` 후 첫 호출자가 CLI 면 포인터만 새 버전으로 + // 점프하고 산출물은 옛 버전에 남았다. 스케줄 GC(`ext-static:cleanup`)가 바로 그 + // 첫 호출자라, cleanup 첫 줄의 `getExtensionCacheVersion()` 이 실존하지 않는 새 + // 버전을 만들어 내고 보존 대상이 `[없는 새 버전, 실존 최신 1개]` 가 되어 **진짜 + // 직전 버전이 삭제**됐다 (매일 04:28 재현). CLI 는 terminating 예약이 그대로 + // 유효하므로 커맨드 종료 시점에 게시가 수행된다. + ExtensionStaticCacheService::schedulePublishOnTerminate(); + return $newVersion; } diff --git a/app/Http/Controllers/Api/Public/PublicModuleController.php b/app/Http/Controllers/Api/Public/PublicModuleController.php index 1604afec..8e472bbb 100644 --- a/app/Http/Controllers/Api/Public/PublicModuleController.php +++ b/app/Http/Controllers/Api/Public/PublicModuleController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\Api\Public; use App\Http\Controllers\Api\Base\PublicBaseController; +use App\Http\Controllers\Concerns\ServesExtensionBundles; use App\Http\Requests\Public\Module\ServeModuleAssetRequest; use App\Services\ExtensionBundleService; use App\Services\ModuleService; @@ -17,6 +18,8 @@ use Symfony\Component\HttpFoundation\BinaryFileResponse; */ class PublicModuleController extends PublicBaseController { + use ServesExtensionBundles; + public function __construct( private readonly ModuleService $moduleService, private readonly ExtensionBundleService $bundleService @@ -27,9 +30,10 @@ class PublicModuleController extends PublicBaseController /** * 활성 모듈 프론트엔드 IIFE 병합 번들(JS)을 서빙합니다. * - * 활성 global 모듈 에셋이 없으면 빈 200 응답(text/javascript)을 반환한다 - * (프론트는 빈 스크립트 로드로 무해). 그 외에는 병합 파일을 fileResponse 로 - * 서빙(ETag/304/환경별 Cache-Control 재사용). + * 병합 파일을 fileResponse 로 서빙한다(ETag/304/환경별 Cache-Control 재사용). + * 디스크 캐시가 실패하면 메모리 병합 결과로 200 을 낸다(캐시는 최적화일 뿐이다). + * 에셋을 선언한 활성 확장이 0개면 빈 200, 선언은 있는데 결과가 비면 503 — + * 판정은 ServesExtensionBundles::bundleResponse() 단일 지점. * * @return BinaryFileResponse|Response 병합 JS 파일 응답 또는 빈 응답 */ @@ -37,14 +41,7 @@ class PublicModuleController extends PublicBaseController { $this->logApiUsage('modules.bundle', ['kind' => 'js']); - $version = $this->bundleService->getCurrentVersion(); - $path = $this->bundleService->getBundleFilePath('module', 'js', $version); - - if ($path === '') { - return response('', 200)->header('Content-Type', 'text/javascript'); - } - - return $this->fileResponse($path, 'text/javascript', 31536000); + return $this->bundleResponse($this->bundleService, 'module', 'js', 'text/javascript'); } /** @@ -56,14 +53,7 @@ class PublicModuleController extends PublicBaseController { $this->logApiUsage('modules.bundle', ['kind' => 'css']); - $version = $this->bundleService->getCurrentVersion(); - $path = $this->bundleService->getBundleFilePath('module', 'css', $version); - - if ($path === '') { - return response('', 200)->header('Content-Type', 'text/css'); - } - - return $this->fileResponse($path, 'text/css', 31536000); + return $this->bundleResponse($this->bundleService, 'module', 'css', 'text/css'); } /** diff --git a/app/Http/Controllers/Api/Public/PublicPluginController.php b/app/Http/Controllers/Api/Public/PublicPluginController.php index 2305cfe2..35335911 100644 --- a/app/Http/Controllers/Api/Public/PublicPluginController.php +++ b/app/Http/Controllers/Api/Public/PublicPluginController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\Api\Public; use App\Http\Controllers\Api\Base\PublicBaseController; +use App\Http\Controllers\Concerns\ServesExtensionBundles; use App\Http\Requests\Public\Plugin\ServePluginAssetRequest; use App\Services\ExtensionBundleService; use App\Services\PluginService; @@ -17,6 +18,8 @@ use Symfony\Component\HttpFoundation\BinaryFileResponse; */ class PublicPluginController extends PublicBaseController { + use ServesExtensionBundles; + public function __construct( private readonly PluginService $pluginService, private readonly ExtensionBundleService $bundleService @@ -27,8 +30,10 @@ class PublicPluginController extends PublicBaseController /** * 활성 플러그인 프론트엔드 IIFE 병합 번들(JS)을 서빙합니다. * - * 활성 global 플러그인 에셋이 없으면 빈 200 응답(text/javascript)을 반환한다. - * 그 외에는 병합 파일을 fileResponse 로 서빙(ETag/304/환경별 Cache-Control 재사용). + * 병합 파일을 fileResponse 로 서빙한다(ETag/304/환경별 Cache-Control 재사용). + * 디스크 캐시가 실패하면 메모리 병합 결과로 200 을 낸다(캐시는 최적화일 뿐이다). + * 에셋을 선언한 활성 확장이 0개면 빈 200, 선언은 있는데 결과가 비면 503 — + * 판정은 ServesExtensionBundles::bundleResponse() 단일 지점. * * @return BinaryFileResponse|Response 병합 JS 파일 응답 또는 빈 응답 */ @@ -36,14 +41,7 @@ class PublicPluginController extends PublicBaseController { $this->logApiUsage('plugins.bundle', ['kind' => 'js']); - $version = $this->bundleService->getCurrentVersion(); - $path = $this->bundleService->getBundleFilePath('plugin', 'js', $version); - - if ($path === '') { - return response('', 200)->header('Content-Type', 'text/javascript'); - } - - return $this->fileResponse($path, 'text/javascript', 31536000); + return $this->bundleResponse($this->bundleService, 'plugin', 'js', 'text/javascript'); } /** @@ -55,14 +53,7 @@ class PublicPluginController extends PublicBaseController { $this->logApiUsage('plugins.bundle', ['kind' => 'css']); - $version = $this->bundleService->getCurrentVersion(); - $path = $this->bundleService->getBundleFilePath('plugin', 'css', $version); - - if ($path === '') { - return response('', 200)->header('Content-Type', 'text/css'); - } - - return $this->fileResponse($path, 'text/css', 31536000); + return $this->bundleResponse($this->bundleService, 'plugin', 'css', 'text/css'); } /** diff --git a/app/Http/Controllers/Concerns/ServesExtensionBundles.php b/app/Http/Controllers/Concerns/ServesExtensionBundles.php new file mode 100644 index 00000000..3ea0bcfa --- /dev/null +++ b/app/Http/Controllers/Concerns/ServesExtensionBundles.php @@ -0,0 +1,83 @@ +getCurrentVersion(); + $path = $bundleService->getBundleFilePath($type, $kind, $version); + + if ($path !== '') { + return $this->fileResponse($path, $mimeType, 31536000); + } + + // 파일 경로가 비었다 — 병합 결과 자체가 비었거나, 디스크 캐시가 실패했다. + $content = $bundleService->buildBundleContent($type, $kind); + + if ($content !== '') { + // 디스크 캐시 실패 (2) — 메모리 결과로 서빙한다. 캐시 헤더는 붙이지 않는다: + // 이 응답은 캐시에 실패한 상태의 산출물이라 다음 요청에서 정상 경로로 + // 돌아갈 수 있어야 한다. + return response($content, 200) + ->header('Content-Type', $mimeType) + ->header('Cache-Control', 'no-cache, private'); + } + + $declared = $bundleService->countAssetDeclaringExtensions($type, $kind); + + if ($declared > 0) { + // (3) 장애 — 선언은 있는데 결과가 0 + Log::error('확장 번들 병합 결과가 비었습니다 — 에셋을 선언한 활성 확장이 있습니다', [ + 'type' => $type, + 'kind' => $kind, + 'version' => $version, + 'declared_extensions' => $declared, + ]); + + return response('', 503) + ->header('Content-Type', $mimeType) + ->header('Cache-Control', 'no-cache, private'); + } + + // (3) 정상 — 선언이 0개면 빈 번들이 맞다 + return response('', 200)->header('Content-Type', $mimeType); + } +} diff --git a/app/Listeners/StaticPublishFailureAlertListener.php b/app/Listeners/StaticPublishFailureAlertListener.php new file mode 100644 index 00000000..20ea2b60 --- /dev/null +++ b/app/Listeners/StaticPublishFailureAlertListener.php @@ -0,0 +1,115 @@ + [ + 'method' => 'addStaticPublishAlert', + 'priority' => 15, + 'type' => 'filter', + ], + ]; + } + + /** + * 훅 이벤트 처리 (기본 핸들러). + * + * @param mixed ...$args 훅에서 전달된 인수들 + */ + public function handle(...$args): void + { + // 기본 핸들러는 사용하지 않음 + } + + /** + * 정적 게시 실패 알림을 대시보드에 추가합니다. + * + * @param array $alerts 기존 알림 배열 + * @return array 알림이 추가된 배열 + */ + public function addStaticPublishAlert(array $alerts): array + { + $marker = ExtensionStaticCacheService::failureMarker(); + + if ($marker === null) { + return $alerts; + } + + $count = (int) ($marker['count'] ?? 0); + + if ($count < self::ALERT_THRESHOLD) { + return $alerts; + } + + $reason = (string) ($marker['reason'] ?? 'write_failed'); + + $alerts[] = [ + 'id' => 'static_publish_failure', + 'type' => 'warning', + // 원인별로 조치가 다르다 — 뭉뚱그리면 운영자가 어디를 봐야 할지 알 수 없다. + 'subtype' => 'static_publish_'.$reason, + 'icon' => 'exclamation-triangle', + 'title' => __('extensions.alerts.static_publish_failed_title'), + 'message' => __('extensions.alerts.static_publish_failed_'.$this->messageKeySuffix($reason), [ + 'count' => $count, + ]), + 'time' => isset($marker['at']) + ? TimezoneHelper::toUserCarbon(Carbon::parse($marker['at']))?->diffForHumans() + : null, + 'read' => false, + ]; + + return $alerts; + } + + /** + * 사유 코드를 다국어 키 접미사로 변환합니다. + * + * 알 수 없는 사유는 일반 문구로 떨어뜨린다 — 키가 없으면 번역기가 키 문자열을 그대로 + * 화면에 내보낸다. + * + * @param string $reason 사유 코드 + * @return string 다국어 키 접미사 + */ + private function messageKeySuffix(string $reason): string + { + return match ($reason) { + 'parent_not_writable', 'write_failed', 'lock_unavailable' => $reason, + default => 'write_failed', + }; + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 4975166c..149f6007 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -12,6 +12,7 @@ use App\Extension\PluginManager; use App\Http\View\Composers\TemplateComposer; use App\Http\View\Composers\UserTemplateComposer; use App\Listeners\ExtensionCompatibilityAlertListener; +use App\Listeners\StaticPublishFailureAlertListener; use App\Notifications\NotificationChannelManager; use App\Services\ChannelReadinessService; use App\Services\GeoIpService; @@ -99,8 +100,8 @@ class AppServiceProvider extends ServiceProvider View::composer('admin', TemplateComposer::class); View::composer('app', UserTemplateComposer::class); - // 확장 호환성 알림 리스너 등록 - $this->registerExtensionCompatibilityAlertListener(); + // 코어 훅 리스너 등록 (대시보드 알림 등) + $this->registerCoreHookListeners(); // SQL 쿼리 로그 설정 $this->configureSqlQueryLogging(); @@ -135,25 +136,36 @@ class AppServiceProvider extends ServiceProvider } /** - * 확장 호환성 알림 리스너를 등록합니다. + * 코어가 소유한 훅 리스너를 등록합니다. * - * 코어 버전 호환성 문제로 자동 비활성화된 확장에 대한 - * 알림을 관리자 대시보드에 표시하기 위한 훅 리스너입니다. + * 확장 리스너와 달리 코어 리스너는 자동 발견 대상이 아니므로 여기서 등록한다. 목록만 + * 늘리면 되도록 루프로 둔다 — 리스너마다 등록 메서드를 복제하면 한 곳만 빠져도 그 + * 리스너가 조용히 동작하지 않는다(등록 실패는 예외도 로그도 남기지 않는다). + * + * 등록 대상: + * - `ExtensionCompatibilityAlertListener` — 코어 호환성으로 자동 비활성화/재호환된 확장 + * - `StaticPublishFailureAlertListener` — 부트스트랩 리소스 정적 게시 실패 (#122) */ - private function registerExtensionCompatibilityAlertListener(): void + private function registerCoreHookListeners(): void { - $listener = new ExtensionCompatibilityAlertListener; - $subscribedHooks = ExtensionCompatibilityAlertListener::getSubscribedHooks(); + $listenerClasses = [ + ExtensionCompatibilityAlertListener::class, + StaticPublishFailureAlertListener::class, + ]; - foreach ($subscribedHooks as $hookName => $config) { - $method = $config['method'] ?? 'handle'; - $priority = $config['priority'] ?? 10; - $type = $config['type'] ?? 'action'; + foreach ($listenerClasses as $listenerClass) { + $listener = new $listenerClass; - if ($type === 'filter') { - HookManager::addFilter($hookName, [$listener, $method], $priority); - } else { - HookManager::addAction($hookName, [$listener, $method], $priority); + foreach ($listenerClass::getSubscribedHooks() as $hookName => $config) { + $method = $config['method'] ?? 'handle'; + $priority = $config['priority'] ?? 10; + $type = $config['type'] ?? 'action'; + + if ($type === 'filter') { + HookManager::addFilter($hookName, [$listener, $method], $priority); + } else { + HookManager::addAction($hookName, [$listener, $method], $priority); + } } } } diff --git a/app/Rules/AllowedModuleFileType.php b/app/Rules/AllowedModuleFileType.php index a212873c..5794a14e 100644 --- a/app/Rules/AllowedModuleFileType.php +++ b/app/Rules/AllowedModuleFileType.php @@ -27,6 +27,20 @@ class AllowedModuleFileType implements ValidationRule 'woff', 'woff2', 'ttf', 'otf', 'eot', ]; + /** + * 환경과 무관한 기본 허용 확장자 목록을 반환합니다. + * + * `getAllowedExtensions()` 는 로컬에서 소스맵(`map`)을 덧붙이는 **환경 의존** 게터라 + * 라우트 패턴처럼 정의 시점에 한 번 굳어 캐시에 박히는 소비자가 쓰면 안 된다 + * (캐시를 구운 환경에 따라 패턴이 달라진다). 그런 소비자는 이 게터를 쓴다. + * + * @return array 기본 허용 확장자 목록 + */ + public static function allowedExtensions(): array + { + return self::ALLOWED_EXTENSIONS; + } + /** * 허용된 파일 타입인지 검증 */ diff --git a/app/Rules/AllowedPluginFileType.php b/app/Rules/AllowedPluginFileType.php index b4ccab54..15e529a7 100644 --- a/app/Rules/AllowedPluginFileType.php +++ b/app/Rules/AllowedPluginFileType.php @@ -27,6 +27,20 @@ class AllowedPluginFileType implements ValidationRule 'woff', 'woff2', 'ttf', 'otf', 'eot', ]; + /** + * 환경과 무관한 기본 허용 확장자 목록을 반환합니다. + * + * `getAllowedExtensions()` 는 로컬에서 소스맵(`map`)을 덧붙이는 **환경 의존** 게터라 + * 라우트 패턴처럼 정의 시점에 한 번 굳어 캐시에 박히는 소비자가 쓰면 안 된다 + * (캐시를 구운 환경에 따라 패턴이 달라진다). 그런 소비자는 이 게터를 쓴다. + * + * @return array 기본 허용 확장자 목록 + */ + public static function allowedExtensions(): array + { + return self::ALLOWED_EXTENSIONS; + } + /** * 허용된 파일 타입인지 검증 */ diff --git a/app/Rules/AllowedTemplateFileType.php b/app/Rules/AllowedTemplateFileType.php index 1614e5bc..3807634d 100644 --- a/app/Rules/AllowedTemplateFileType.php +++ b/app/Rules/AllowedTemplateFileType.php @@ -27,6 +27,20 @@ class AllowedTemplateFileType implements ValidationRule 'woff', 'woff2', 'ttf', 'otf', 'eot', ]; + /** + * 환경과 무관한 기본 허용 확장자 목록을 반환합니다. + * + * `getAllowedExtensions()` 는 로컬에서 소스맵(`map`)을 덧붙이는 **환경 의존** 게터라 + * 라우트 패턴처럼 정의 시점에 한 번 굳어 캐시에 박히는 소비자가 쓰면 안 된다 + * (캐시를 구운 환경에 따라 패턴이 달라진다). 그런 소비자는 이 게터를 쓴다. + * + * @return array 기본 허용 확장자 목록 + */ + public static function allowedExtensions(): array + { + return self::ALLOWED_EXTENSIONS; + } + /** * 허용된 파일 타입인지 검증 */ diff --git a/app/Services/ExtensionBundleService.php b/app/Services/ExtensionBundleService.php index f43a13f4..01be3701 100644 --- a/app/Services/ExtensionBundleService.php +++ b/app/Services/ExtensionBundleService.php @@ -39,6 +39,13 @@ class ExtensionBundleService */ private const BUNDLE_DISK = 'ext-bundles'; + /** + * 원자적 쓰기 임시 파일(`*.tmp.{pid}`)을 잔존물로 보는 나이 (초). + * + * pid 는 재사용되므로 "그 pid 가 살아 있는가" 로는 진행 중 여부를 판정할 수 없다. + */ + private const TEMP_BUNDLE_STALE_SECONDS = 600; + /** * 서비스 주입 * @@ -236,20 +243,104 @@ class ExtensionBundleService return ''; } - $storage = $this->bundleStorage(); $relativeName = $this->bundleFileName($type, $kind, $version); - // 비프로덕션은 캐시하지 않고 임시 파일로 매번 build → rebuild 즉시 반영 - if (! app()->environment('production')) { - return $this->writeAtomically($storage, $relativeName, $content, cache: false); - } + // 디스크 캐시는 **최적화**다 — 쓰기 실패가 공개 엔드포인트의 500 이 되면 안 된다. + // `ext-bundles` 디스크는 `throw => true` 라 권한 문제(uid 독점 0700 등)에서 + // `UnableToWriteFile` 이 그대로 올라오고, 그러면 모든 확장의 프론트엔드 JS/CSS 가 + // 통째로 나가지 못한다. 병합 결과는 이미 메모리에 있으므로 그것을 그대로 응답하면 + // 화면은 정상이다 (커밋 63a30ab29 의 AbstractCacheDriver fail-soft 와 같은 원칙). + try { + $storage = $this->bundleStorage(); - // 프로덕션: 동일 version 캐시가 있으면 그대로 사용 - if ($storage->exists('', $relativeName)) { - return $storage->getBasePath('').'/'.$relativeName; - } + // 비프로덕션은 캐시하지 않고 임시 파일로 매번 build → rebuild 즉시 반영 + if (! app()->environment('production')) { + return $this->writeAtomically($storage, $relativeName, $content, cache: false); + } - return $this->writeAtomically($storage, $relativeName, $content, cache: true); + // 프로덕션: 동일 version 캐시가 있으면 그대로 사용 + if ($storage->exists('', $relativeName)) { + return $storage->getBasePath('').'/'.$relativeName; + } + + return $this->writeAtomically($storage, $relativeName, $content, cache: true); + } catch (\Throwable $e) { + Log::warning('확장 번들 디스크 캐시 실패 — 메모리 병합 결과로 서빙합니다', [ + 'type' => $type, + 'kind' => $kind, + 'version' => $version, + 'error' => $e->getMessage(), + ]); + + return ''; + } + } + + /** + * 번들을 서빙할 때 쓸 병합 결과를 반환합니다 (디스크 캐시 실패 시 메모리 폴백용). + * + * @param string $type 'module' | 'plugin' + * @param string $kind 'js' | 'css' + * @return string 병합 결과 (없으면 빈 문자열) + */ + public function buildBundleContent(string $type, string $kind): string + { + return $kind === 'css' + ? $this->buildCssBundle($type) + : $this->buildJsBundle($type); + } + + /** + * 해당 타입에서 프론트엔드 에셋을 **선언한** 활성 확장 수를 반환합니다. + * + * "선언이 0 이라 빈 번들" (정상)과 "선언은 있는데 병합 결과가 0" (장애 — 배포 중 + * `dist` 가 잠깐 비었거나 경로가 어긋났다)을 구분하는 유일한 근거다. 구분하지 않으면 + * 후자가 빈 200 으로 나가고, 프론트는 404 도 오류도 받지 못한 채 한참 뒤 + * "Unknown action handler" 로 죽는다. + * + * 판정은 **kind 별**이다 — js 만 선언한 확장이 있는 상태에서 css 번들이 비는 것은 + * 정상이므로, 그 경우까지 장애로 보면 정상 구성이 503 이 된다. + * + * 근거는 manifest 의 `assets.{kind}.output` **선언**이며 산출물 파일의 존재를 보지 + * 않는다. `getOrderedGlobalAssetPaths()` / `hasAssets()` / `getBuiltAssetPaths()` 는 + * 전부 `file_exists()` 게이트를 타므로, 그 경로로 세면 "dist 가 잠깐 빔" 이 곧 + * "선언 0" 이 되어 **막으려던 바로 그 상태가 정상(빈 200)으로 판정된다.** 선언과 + * 산출은 다른 축이고, 이 메서드가 재는 것은 선언 축이다. + * + * @param string $type 'module' | 'plugin' + * @param string $kind 'js' | 'css' + * @return int 해당 kind 의 에셋을 선언한 활성 확장 수 + */ + public function countAssetDeclaringExtensions(string $type, string $kind): int + { + try { + $extensions = $type === 'plugin' + ? $this->pluginManager->getActivePlugins() + : $this->moduleManager->getActiveModules(); + + $declared = 0; + + foreach ($extensions as $extension) { + // global 전략만 번들 대상 — 병합 대상 모집단과 동일한 필터를 쓴다 + if (($extension->getAssetLoadingConfig()['strategy'] ?? 'global') !== 'global') { + continue; + } + + if (! empty($extension->getAssets()[$kind]['output'] ?? null)) { + $declared++; + } + } + + return $declared; + } catch (\Throwable $e) { + Log::warning('확장 에셋 선언 수 집계 실패', [ + 'type' => $type, + 'kind' => $kind, + 'error' => $e->getMessage(), + ]); + + return 0; + } } /** @@ -271,6 +362,17 @@ class ExtensionBundleService continue; } + // 원자적 쓰기의 임시 파일(`{type}.{v}.{kind}.tmp.{pid}`)은 번들 파일 패턴에 + // 맞지 않아 GC 대상에서 통째로 빠져 있었다 — rename 이 실패한 만큼 영구 + // 잔존한다(실측 560개). 나이 가드를 붙여 진행 중인 쓰기는 건드리지 않는다. + if ($this->isStaleTempBundleFile($name, $storage)) { + if ($storage->delete('', $name)) { + $deleted++; + } + + continue; + } + if ($this->isBundleFile($name) && $storage->delete('', $name)) { $deleted++; } @@ -279,15 +381,43 @@ class ExtensionBundleService return $deleted; } + /** + * 파일명이 **오래된** 원자적 쓰기 임시 파일인지 판정합니다. + * + * 진행 중인 쓰기를 파괴하지 않도록 나이 가드를 둔다 — pid 는 재사용되므로 "그 pid 가 + * 살아 있는가" 로는 판정할 수 없다. + * + * @param string $name 파일명 + * @param CoreStorageDriver $storage 번들 디스크 스토리지 + * @return bool 삭제 대상 여부 + */ + private function isStaleTempBundleFile(string $name, CoreStorageDriver $storage): bool + { + if (! preg_match('/^(module|plugin)\.\d+\.(js|css)\.tmp\.\d+$/', $name)) { + return false; + } + + $mtime = @filemtime($storage->getBasePath('').'/'.$name); + + // 나이를 읽지 못하면 남긴다 — 진행 중인 쓰기를 지우는 쪽이 더 나쁘다. + return $mtime !== false && (time() - $mtime) > self::TEMP_BUNDLE_STALE_SECONDS; + } + /** * 번들 캐시 파일을 삭제합니다(cache-clear 커맨드용). * + * **현재 버전은 보존한다** — `cleanupStaleBundles()` 와 같은 정책이다. 현재 버전까지 + * 지우면 같은 순간 서빙 중인 웹 요청이 "존재함" 판정 직후 `filemtime()` 에서 500 을 + * 낸다(bump 직후 TOCTOU). 캐시 파일은 없으면 다음 요청이 다시 만들므로, 지우는 것의 + * 이득은 없고 그 창의 500 만 남는다. + * * @param string|null $type 'module' | 'plugin' 지정 시 해당 타입만, null 이면 전체 * @return int 삭제된 파일 수 */ public function clearBundles(?string $type = null): int { $storage = $this->bundleStorage(); + $currentVersion = $this->getCurrentVersion(); $deleted = 0; foreach ($storage->files('', '') as $file) { @@ -297,6 +427,11 @@ class ExtensionBundleService continue; } + // 현재 버전 보존 (cleanupStaleBundles 와 동형 — 정책이 갈라지면 한쪽이 창을 연다) + if ($this->matchesVersion($name, $currentVersion)) { + continue; + } + // 타입 필터 (파일명 접두사 `{type}.`) if ($type !== null && ! str_starts_with($name, $type.'.')) { continue; diff --git a/app/Services/ExtensionStaticCacheService.php b/app/Services/ExtensionStaticCacheService.php index eca69fea..8e61826e 100644 --- a/app/Services/ExtensionStaticCacheService.php +++ b/app/Services/ExtensionStaticCacheService.php @@ -2,10 +2,12 @@ namespace App\Services; +use App\Contracts\Extension\CacheInterface; use App\Contracts\Repositories\ModuleRepositoryInterface; use App\Contracts\Repositories\PluginRepositoryInterface; use App\Contracts\Repositories\TemplateRepositoryInterface; use App\Exceptions\StaticCachePublishException; +use App\Extension\Cache\CoreCacheDriver; use App\Extension\Helpers\FilePermissionHelper; use App\Extension\Traits\ClearsTemplateCaches; use App\Helpers\ResponseHelper; @@ -46,6 +48,24 @@ class ExtensionStaticCacheService /** 로케일 패턴 — 경로 세그먼트 화이트리스트 */ private const LOCALE_PATTERN = '/^[a-z]{2}(?:[-_][A-Za-z0-9]{2,8})?$/'; + /** 게시 작업 디렉토리(.tmp/.old)를 미완료 잔존물로 보는 나이 (초) — 게시 락 TTL 300 의 2배 */ + private const WORK_DIR_STALE_SECONDS = 600; + + /** 게시 실패 마커 캐시 키 */ + private const FAILURE_MARKER_KEY = 'ext.static.publish_failure'; + + /** 실패 마커 TTL (초) — 이 창 안에서는 같은 버전의 재예약을 억제한다 */ + private const FAILURE_MARKER_TTL = 300; + + /** 게시 트리 디렉토리 권한 — umask 무력화 대상 */ + private const PUBLISH_DIR_MODE = 0775; + + /** 게시 트리 디렉토리 rename 시도 횟수 (일시 거부 흡수) */ + private const RENAME_ATTEMPTS = 3; + + /** rename 재시도 간 대기 (마이크로초) — 실측 표본은 전부 1회 재시도로 해소됐다 */ + private const RENAME_RETRY_DELAY_US = 200_000; + /** terminating 게시 예약 플래그 (프로세스당 1회) */ private static bool $publishScheduled = false; @@ -85,9 +105,35 @@ class ExtensionStaticCacheService return true; } - $lock = Cache::lock(self::LOCK_PREFIX.$version, 300); + // 락 미획득은 두 상황이고 조치가 다르다. + // + // (a) 다른 프로세스가 게시 중 (정상) — `get()` 이 예외 없이 false. + // 건너뛰는 것이 옳은 동작이므로 마커를 남기지 않는다. 남기면 정상적인 동시 + // 요청 경합이 실패로 집계돼 대시보드에 거짓 장애 알림이 뜬다. + // (b) 캐시 저장소가 락을 제공하지 못함 (장애) — `Cache::lock()`/`get()` 이 던진다 + // (락 미지원 드라이버, 파일 캐시 디렉토리 권한 불일치 등). 이 경우 게시는 + // 매 요청 조용히 스킵되므로 사유를 마커에 남겨 진단 표면까지 도달시킨다. + try { + $lock = Cache::lock(self::LOCK_PREFIX.$version, 300); + $acquired = $lock->get(); + } catch (\Throwable $e) { + Log::warning('정적 게시 락 획득 불가 — 캐시 저장소를 확인하세요', [ + 'version' => $version, + 'store' => config('cache.default'), + 'error' => $e->getMessage(), + ]); + + self::recordFailure($version, 'lock_unavailable', $e->getMessage()); + + return false; + } + + if (! $acquired) { + Log::debug('정적 게시 락 미획득 — 이번 호출은 건너뜁니다', [ + 'version' => $version, + 'store' => config('cache.default'), + ]); - if (! $lock->get()) { return false; } @@ -142,10 +188,16 @@ class ExtensionStaticCacheService foreach (File::directories($base) as $dir) { $name = basename($dir); - // 미완료 tmp 잔존물은 무조건 제거 대상 (rename 전 실패 흔적) - if (str_ends_with($name, '.tmp')) { - File::deleteDirectory($dir); - $deleted++; + // 진행 중 게시의 작업 디렉토리(`{v}.tmp`)와 스왑 대기분(`{v}.old`)은 나이로 + // 가른다 — 락은 **버전별**이라 서로 다른 버전의 게시가 동시에 진행될 수 있고, + // 나이 무관 삭제는 그 순간 살아 있는 남의 tmp 를 파괴한다. 게시 락 TTL 이 + // 300초이므로 그 두 배를 미완료 판정 기준으로 삼는다. + if (str_ends_with($name, '.tmp') || str_ends_with($name, '.old')) { + if (! $this->isStaleWorkDirectory($dir)) { + continue; + } + + $deleted += $this->deleteVersionDirectory($dir) ? 1 : 0; continue; } @@ -155,27 +207,79 @@ class ExtensionStaticCacheService } } - // 현재 버전과, 현재를 제외한 최신 1개(직전) 보존 - $keep = [$current]; + // 현재 버전과, 현재를 제외한 최신 1개(직전) 보존. + // + // 현재 버전 디렉토리가 **실존하지 않으면** 그 자리를 보존 슬롯으로 쓰지 않는다 — + // 없는 것을 보존해 봐야 슬롯 하나를 버리는 셈이고, 그만큼 실존 버전이 한 개 더 + // 지워진다. 그 경우 "실존하는 최신 2개" 를 보존한다. 게시는 GC 시점 이후 + // (terminating)에 수행되므로 "포인터는 새 버전인데 산출물은 아직 없음" 은 + // 정상 상태이며, 브라우저에 배달된 직전 HTML 은 여전히 옛 버전 URL 을 참조한다. + $keep = File::isDirectory($this->versionDir($current)) ? [$current] : []; $others = array_keys($versions); rsort($others); foreach ($others as $v) { - if ($v !== $current) { - $keep[] = $v; + if (in_array($v, $keep, true)) { + continue; + } + + $keep[] = $v; + + if (count($keep) >= 2) { break; } } foreach ($versions as $v => $dir) { if (! in_array($v, $keep, true)) { - File::deleteDirectory($dir); - $deleted++; + $deleted += $this->deleteVersionDirectory($dir) ? 1 : 0; } } return $deleted; } + /** + * 게시 작업 디렉토리(`.tmp` / `.old`)가 미완료 잔존물로 판정될 만큼 오래됐는지 봅니다. + * + * 나이를 읽지 못하는 경우(권한·경합으로 `filemtime` 실패)는 **삭제하지 않는다** — + * 진행 중인 게시를 파괴하는 쪽이 잔존물을 한 주기 더 남기는 쪽보다 나쁘다. + * + * @param string $dir 검사할 작업 디렉토리 절대 경로 + * @return bool 삭제 대상 여부 + */ + private function isStaleWorkDirectory(string $dir): bool + { + $mtime = @filemtime($dir); + + if ($mtime === false) { + return false; + } + + return (time() - $mtime) > self::WORK_DIR_STALE_SECONDS; + } + + /** + * 게시 디렉토리를 삭제하고 성공 여부를 반환합니다. + * + * 반환값을 검사하지 않으면 소유권 불일치로 삭제가 실패해도 "N개 삭제" 로 보고되어, + * 구버전·고아 tmp 가 무한 누적되는 동안 운영자에게는 정상으로 보인다. + * + * @param string $dir 삭제할 디렉토리 절대 경로 + * @return bool 삭제 성공 여부 + */ + private function deleteVersionDirectory(string $dir): bool + { + if (File::deleteDirectory($dir)) { + return true; + } + + Log::warning('정적 게시 디렉토리 삭제 실패 — 잔존물이 누적됩니다 (소유권/권한 확인 필요)', [ + 'path' => $dir, + ]); + + return false; + } + /** * 수명주기 이벤트에서 호출되는 terminating 게시 예약. * @@ -204,6 +308,20 @@ class ExtensionStaticCacheService return; } + // 신선한 실패 마커가 있으면 예약하지 않는다 (백오프). + // + // 쓰기 불가 환경(게시 트리 소유권 불일치 등)에서는 게시가 **매 요청** 실패하는데, + // 실패 전까지 전 로케일 lang 병합 + 전 템플릿 dist 복사를 이미 다 헛돈 뒤다. + // 사이트는 API 폴백으로 살아 있어 아무도 눈치채지 못한 채 모든 프로덕션 요청이 + // 그 비용을 낸다. 마커 TTL 창당 1회로 억제한다. + // + // 억제 대상은 **같은 버전**뿐이다. 버전이 오르면 그 버전은 아직 한 번도 시도된 + // 적이 없으므로, 이전 버전의 마커로 막으면 "버전 갱신 → 게시" 규율(D1)이 TTL + // 창(최대 300초) 동안 도로 끊긴다. + if (self::hasFreshFailureMarker(self::getExtensionCacheVersion())) { + return; + } + self::$publishScheduled = true; app()->terminating(static function (): void { @@ -223,6 +341,19 @@ class ExtensionStaticCacheService }); } + /** + * 테스트 전용 — terminating 예약 플래그의 현재 값을 반환합니다. + * + * 게시 예약은 부수효과가 `app()->terminating()` 콜백 등록뿐이라 밖에서 관측할 방법이 + * 없다. "예약했는가" 를 단언하려면 이 플래그가 유일한 통로다. + * + * @return bool 예약 여부 + */ + public static function isPublishScheduledForTesting(): bool + { + return self::$publishScheduled; + } + /** * 테스트 격리용 — terminating 예약 플래그를 초기화합니다. */ @@ -232,6 +363,101 @@ class ExtensionStaticCacheService self::$rootProcessForTesting = null; } + /** + * 최근 게시 실패 마커를 반환합니다 (없으면 null). + * + * 진단 표면(`ext-static:status`, 대시보드 알림)이 읽는 유일한 통로다 — 게시 실패는 + * 사이트를 멈추지 않고 API 폴백으로 넘어가므로, 이 마커가 없으면 정상 운영 환경에서 + * 실패를 확인할 방법이 로그뿐이다. + * + * @return array{version:int, at:string, reason:string, count:int, message:string}|null 실패 마커 + */ + public static function failureMarker(): ?array + { + try { + $marker = self::markerCache()->get(self::FAILURE_MARKER_KEY); + } catch (\Throwable) { + // 마커 저장소 자체가 불능인 환경 — best-effort 다 (아래 recordFailure 주석 참조) + return null; + } + + return is_array($marker) ? $marker : null; + } + + /** + * 게시 실패를 마커에 기록합니다 (연속 실패 횟수 누적). + * + * best-effort 다 — 마커를 쓰지 못하는 환경(캐시 저장소 자체가 불능)이 실재하며, + * 그 경우 백오프는 걸리지 않는다. 다만 in-process `$publishScheduled` 가드는 그대로 + * 유효하므로 한 요청 안에서 반복되지는 않는다. + * + * @param int $version 실패한 확장 캐시 버전 + * @param string $reason 실패 사유 코드 (`parent_not_writable` / `write_failed` / `lock_unavailable`) + * @param string $message 진단용 원문 메시지 + */ + private static function recordFailure(int $version, string $reason, string $message): void + { + try { + $previous = self::failureMarker(); + $count = ($previous !== null && ($previous['version'] ?? null) === $version) + ? (int) ($previous['count'] ?? 0) + 1 + : 1; + + self::markerCache()->put(self::FAILURE_MARKER_KEY, [ + 'version' => $version, + 'at' => now()->toIso8601String(), + 'reason' => $reason, + 'count' => $count, + 'message' => $message, + ], self::FAILURE_MARKER_TTL); + } catch (\Throwable $e) { + Log::debug('정적 게시 실패 마커 기록 실패 (백오프 미적용)', ['error' => $e->getMessage()]); + } + } + + /** + * 게시 성공 시 실패 마커를 제거합니다. + */ + private static function clearFailureMarker(): void + { + try { + self::markerCache()->forget(self::FAILURE_MARKER_KEY); + } catch (\Throwable) { + // 마커 제거 실패는 무해하다 — TTL 로 자연 만료된다 + } + } + + /** + * 지정 버전에 대한 TTL 창 안의 실패 마커가 존재하는지 판정합니다 (백오프 게이트). + * + * 버전을 한정하지 않으면 bump 직후의 새 버전이 이전 버전의 마커로 억제된다 — + * 아직 한 번도 시도되지 않은 버전을 실패로 취급하는 셈이다. + * + * @param int $version 판정할 확장 캐시 버전 + * @return bool 해당 버전의 신선한 실패 마커 존재 여부 + */ + private static function hasFreshFailureMarker(int $version): bool + { + $marker = self::failureMarker(); + + return $marker !== null && ($marker['version'] ?? null) === $version; + } + + /** + * 실패 마커용 캐시 드라이버를 반환합니다. + * + * 캐시 버전 키와 **같은 스토어**를 쓴다 — 마커를 쓰는 쪽(게시)과 읽는 쪽(진단 커맨드· + * 대시보드 알림)이 다른 스토어를 가리키면 실패가 기록돼도 화면에는 영영 뜨지 않는다. + * `ClearsTemplateCaches::extensionCacheStore()` 는 프로세스 1회 메모이즈된 고정 스토어라 + * settings 로드 타이밍에 좌우되지 않는다. + * + * @return CacheInterface 코어 네임스페이스 캐시 드라이버 + */ + private static function markerCache(): CacheInterface + { + return new CoreCacheDriver(self::extensionCacheStore()); + } + /** * 테스트 전용 — root 프로세스 판정을 강제합니다 (null 로 실판정 복귀). * @@ -300,10 +526,19 @@ class ExtensionStaticCacheService $base = $this->baseDir(); $tmp = $base.DIRECTORY_SEPARATOR.$version.'.tmp'; $final = $this->versionDir($version); + $old = $final.'.old'; + $swapped = false; + + // 프리플라이트 — 게시 트리를 만들 수 없는 환경이면 병합을 시작하기 전에 끊는다. + // 전 로케일 lang 병합 + 전 템플릿 dist 복사를 다 헛돈 뒤 mkdir 에서 실패하는 + // 것과, 시작 전에 사유를 남기고 끊는 것은 비용이 전혀 다르다. + if (! $this->ensurePublishRootWritable($version)) { + return false; + } try { File::deleteDirectory($tmp); - File::ensureDirectoryExists($tmp, 0775); + $this->makeDirectory($tmp); $files = []; @@ -319,12 +554,24 @@ class ExtensionStaticCacheService $this->publishExtensionCustomAssets($tmp, $files); - // 원자적 스왑 — force 재게시 시 기존 디렉토리를 비켜낸 뒤 rename - if (File::isDirectory($final)) { - File::deleteDirectory($final); + // 원자적 스왑 — 기존 디렉토리를 **먼저 지우지 않는다.** 삭제 후 rename 사이의 + // 창에서는 이미 배달된 HTML 이 참조하는 CSS/JS/폰트가 전부 404 가 되고, 폰트는 + // 복구기가 없다. 대신 `.old` 로 비켜낸 뒤 rename 하고, 성공을 확인한 다음에 + // `.old` 를 지운다. 중간 실패 시 `.old` 를 제자리로 되돌린다. + File::deleteDirectory($old); + + if (File::isDirectory($final) && ! $this->renameDirectory($final, $old)) { + throw new StaticCachePublishException("Failed to move aside publish directory: {$final} -> {$old}"); } - if (! @rename($tmp, $final)) { + $swapped = File::isDirectory($old); + + if (! $this->renameDirectory($tmp, $final)) { + // 새 디렉토리를 앉히지 못했다 — 비켜낸 기존 버전을 즉시 되돌린다. + if ($swapped && $this->renameDirectory($old, $final)) { + $swapped = false; + } + throw new StaticCachePublishException("Failed to rename publish directory: {$tmp} -> {$final}"); } @@ -332,6 +579,12 @@ class ExtensionStaticCacheService $this->writeManifest($final, $version, $files); unset($this->publishedMemo[$version]); + // 새 버전이 완성된 뒤에만 구버전을 치운다 (여기까지 오면 404 창이 없다) + if ($swapped) { + File::deleteDirectory($old); + $swapped = false; + } + // sudo/root CLI 게시 대응 — terminating 게시는 코어 업데이트의 // restoreOwnership **이후**(프로세스 종료 시)에 실행되므로, root 소유로 // 남으면 이후 php-fpm 의 재게시·GC 가 영구 실패한다. 부모(public/build) @@ -341,6 +594,8 @@ class ExtensionStaticCacheService // 인라인 GC (현재 + 직전 1개 보존) $this->cleanup(); + self::clearFailureMarker(); + Log::info('부트스트랩 리소스 정적 게시 완료', [ 'version' => $version, 'files' => count($files), @@ -357,12 +612,220 @@ class ExtensionStaticCacheService 'error' => $e->getMessage(), 'at' => $e->getFile().':'.$e->getLine(), ]); + + // 정리 대상은 **실제 존재하는 쪽**이다. rename 이 이미 성공했다면 `$tmp` 는 + // 존재하지 않으므로 그것만 지우는 종전 코드는 no-op 이었고, manifest 기록이 + // 실패한 경우 manifest 없는 완성 디렉토리가 영구 잔존했다 — + // `isPublished()` 가 영원히 false 라 요청마다 지웠다 만들기를 반복한다. File::deleteDirectory($tmp); + if (! File::isDirectory($final.DIRECTORY_SEPARATOR) + || ! is_file($final.DIRECTORY_SEPARATOR.self::MANIFEST_FILE)) { + File::deleteDirectory($final); + } + + // 비켜낸 기존 버전이 남아 있으면 제자리로 되돌린다 — 되돌리지 못하면 + // `.old` 로 둔 채 나이 가드가 붙은 GC 에 맡긴다(즉시 삭제하지 않는다). + if ($swapped && ! File::isDirectory($final)) { + $this->renameDirectory($old, $final); + } + + unset($this->publishedMemo[$version]); + + self::recordFailure($version, 'write_failed', $e->getMessage()); + return false; } } + /** + * 게시 루트(`public/build/ext`)를 만들 수 있고 쓸 수 있는지 확인합니다. + * + * 부모(`public/build`)가 다른 계정 소유 + `g-w` 면 웹 프로세스는 `ext` 를 **mkdir 조차 + * 하지 못한다.** 그 경우 최초 게시가 CLI 로 강제되고, 그 순간 트리 소유권이 CLI 계정으로 + * 고정되어 이후 웹 재게시가 영구 실패한다 (제보 본건). + * + * @param int $version 게시 대상 버전 (실패 마커 기록용) + * @return bool 게시를 진행해도 되는지 여부 + */ + private function ensurePublishRootWritable(int $version): bool + { + $base = $this->baseDir(); + + if (! File::isDirectory($base)) { + // 게시 루트가 아직 없으면 만든다. 검사 대상은 `public/build` 고정이 아니라 + // **실재하는 최근접 조상**이다 — `public/build` 자체가 없는 환경(신규 설치, + // 테스트 격리 public 경로)에서 부모 존재를 요구하면 정상 상황을 실패로 만든다. + $ancestor = $this->nearestExistingAncestor($base); + + if ($ancestor === null || ! is_writable($ancestor)) { + $this->failPreflight( + $version, + $ancestor ?? dirname($base), + '게시 루트를 만들 상위 디렉토리에 쓸 수 없습니다' + ); + + return false; + } + + // 조상이 쓰기 가능해도 mkdir 은 실패할 수 있다 — 경로 중간이 **파일**이거나 + // 경합으로 사라지는 경우다. `ensureDirectoryExists` 는 그 실패를 예외로 + // 던지는데, 이 프리플라이트는 `publishVersion` 의 try 블록 **밖**에서 돌므로 + // 잡지 않으면 예외가 호출자에게 그대로 새어 나간다 — 게시 실패는 사이트를 + // 멈추지 않는다는 계약이 그 지점에서 깨진다. + try { + $this->makeDirectory($base); + } catch (\Throwable $e) { + $this->failPreflight($version, $base, '게시 루트를 만들지 못했습니다: '.$e->getMessage()); + + return false; + } + } + + clearstatcache(true, $base); + + if (! File::isDirectory($base) || ! is_writable($base)) { + $this->failPreflight($version, $base, '게시 루트에 쓸 수 없습니다'); + + return false; + } + + return true; + } + + /** + * 경로에서 위로 올라가며 실재하는 첫 디렉토리를 찾습니다. + * + * @param string $path 기준 경로 + * @return string|null 실재하는 최근접 조상 (루트까지 없으면 null) + */ + private function nearestExistingAncestor(string $path): ?string + { + $current = dirname($path); + + while (! File::isDirectory($current)) { + $parent = dirname($current); + + if ($parent === $current) { + return null; + } + + $current = $parent; + } + + return $current; + } + + /** + * 프리플라이트 실패를 로그 + 실패 마커에 남깁니다. + * + * @param int $version 게시 대상 버전 + * @param string $path 쓰기 불가로 판정된 경로 + * @param string $summary 사람이 읽는 요약 + */ + private function failPreflight(int $version, string $path, string $summary): void + { + $detail = sprintf( + '%s (%s, owner=%s, perms=%s, process_user=%s)', + $summary, + $path, + (string) (@fileowner($path) ?: 'unknown'), + File::exists($path) ? substr(sprintf('%o', @fileperms($path)), -4) : 'absent', + self::currentProcessUser(), + ); + + Log::warning('부트스트랩 리소스 정적 게시 프리플라이트 실패 — API 폴백으로 동작합니다', [ + 'version' => $version, + 'path' => $path, + 'reason' => 'parent_not_writable', + 'detail' => $detail, + ]); + + self::recordFailure($version, 'parent_not_writable', $detail); + } + + /** + * 현재 프로세스의 실행 계정명을 반환합니다 (진단용, 미지원 환경은 'unknown'). + * + * @return string 계정명 또는 uid 문자열 + */ + public static function currentProcessUser(): string + { + if (! function_exists('posix_geteuid')) { + return 'unknown'; + } + + $uid = posix_geteuid(); + + if (function_exists('posix_getpwuid')) { + $info = @posix_getpwuid($uid); + + if (is_array($info) && isset($info['name'])) { + return (string) $info['name']; + } + } + + return (string) $uid; + } + + /** + * 게시 트리 디렉토리를 만들고 umask 와 무관하게 권한·소유권을 정합화합니다. + * + * `File::ensureDirectoryExists($dir, 0775)` 의 mode 인자는 **umask 로 깎인다** — + * umask 022 환경에서는 0755 가 되어 웹 계정(그룹 공유)이 쓸 수 없다. 명시 `chmod` 로 + * umask 를 무력화하고, 부모 소유권을 상속시켜 CLI 계정 고정을 막는다. + * (선례: `CoreUpdateService::ensureWritableDirectories`) + * + * @param string $dir 생성할 디렉토리 절대 경로 + */ + private function makeDirectory(string $dir): void + { + File::ensureDirectoryExists($dir, self::PUBLISH_DIR_MODE); + + // ensureDirectoryExists 의 mode 는 umask 로 깎이므로 명시 chmod 로 확정한다. + @chmod($dir, self::PUBLISH_DIR_MODE); + + FilePermissionHelper::inheritOwnershipFromParent($dir); + } + + /** + * 게시 트리의 디렉토리 rename 을 유한 재시도와 함께 수행합니다. + * + * 갓 쓰여진 파일이 든 디렉토리의 rename 은 **목적지가 비어 있는데도** 첫 시도가 + * 거부될 수 있다. 실측(4표본): 실패 순간 `$final` 은 부재였고 `.old` 스왑도 + * 관여하지 않았는데 `rename` 이 false 를 돌려줬으며, 상태를 바꾸지 않고 그대로 + * 다시 호출하면 전부 성공했다(즉시 1건 / 200ms 후 3건, 1,200ms 까지 간 표본 0). + * 운영 환경에서도 같은 사유의 게시 실패가 관측됐다 — 재시도 한 번이면 성공했을 + * 게시가 실패 마커와 대시보드 알림까지 올라간다. + * + * 특정 OS 로 분기하지 않는다. 이 거부는 파일시스템·스토리지 계층(네트워크 마운트, + * 스냅샷, 백신·인덱서 등)이면 어디서든 성립하는 조건이고, 분기를 두면 그 플랫폼 + * 밖에서 같은 실패가 조용히 남는다. 재시도가 불필요한 환경에서는 첫 시도가 + * 성공하므로 비용이 0 이다. + * + * 성공하지 못하면 false 를 돌려주며 **실패 계약은 종전 그대로다** — 호출부가 + * `.old` 롤백과 예외를 그대로 수행한다. + * + * @param string $from 원본 경로 + * @param string $to 목적지 경로 + * @return bool rename 성공 여부 + */ + private function renameDirectory(string $from, string $to): bool + { + for ($attempt = 1; $attempt <= self::RENAME_ATTEMPTS; $attempt++) { + if (@rename($from, $to)) { + return true; + } + + if ($attempt < self::RENAME_ATTEMPTS) { + usleep(self::RENAME_RETRY_DELAY_US); + clearstatcache(); + } + } + + return false; + } + /** * root 로 실행된 CLI 게시의 산출물 소유권을 부모 디렉토리 기준으로 정상화합니다. * @@ -373,19 +836,38 @@ class ExtensionStaticCacheService */ private function normalizeOwnership(): void { - if (! function_exists('chown') || ! function_exists('posix_geteuid') || posix_geteuid() !== 0) { + $base = $this->baseDir(); + + if (! File::isDirectory($base)) { return; } - $parent = dirname($this->baseDir()); - $owner = @fileowner($parent); - $group = @filegroup($parent); + // ① root 갈래 — 소유권을 부모 기준으로 되돌린다 (sudo CLI 게시 대응). + if (function_exists('chown') && function_exists('posix_geteuid') && posix_geteuid() === 0) { + $parent = dirname($base); + $owner = @fileowner($parent); + $group = @filegroup($parent); - if ($owner === false || $owner === 0) { - return; + if ($owner !== false && $owner !== 0) { + FilePermissionHelper::chownRecursive($base, $owner, $group); + } } - FilePermissionHelper::chownRecursive($this->baseDir(), $owner, $group); + // ② 항상 실행 갈래 — 비-root CLI 계정(`deploy` 등)으로 게시한 경우를 덮는다. + // + // 종전에는 root 가 아니면 즉시 no-op 이었다. 그러나 실제 제보는 **비-root CLI 계정 + // ≠ 웹 계정** 이었다: CLI 가 최초 게시하면서 트리가 `0755 deploy:deploy` 로 굳고, + // 이후 웹(php-fpm)의 재게시가 영구 실패한 채 로그 warning 만 남았다. + // + // chgrp 로 부모 그룹을 상속시키고 트리에 `g+w` 를 승격하면 그룹을 공유하는 웹 + // 계정이 재게시할 수 있다. 비-root 에서 `@chown` 은 실패해도 무해하고(false 반환), + // `chgrp`(자기가 속한 그룹으로) 와 `chmod g+w`(자기 소유 파일)는 성립한다. + // + // 한계: 이 방식은 CLI 계정과 웹 계정이 **그룹을 공유**할 때만 성립한다. 공유하지 + // 않는 환경은 프리플라이트가 실패 마커를 남기고 진단 표면(`ext-static:status`, + // 대시보드 알림)이 그 사실을 운영자에게 전달한다 — 규정 문서 §6 참조. + FilePermissionHelper::inheritOwnershipFromParent($base); + FilePermissionHelper::syncGroupWritabilityDetailed($base, force: true); } /** @@ -658,7 +1140,7 @@ class ExtensionStaticCacheService */ private function writeJson(string $absolutePath, mixed $data, array &$files, string $tmp): void { - File::ensureDirectoryExists(dirname($absolutePath), 0775); + $this->makeDirectory(dirname($absolutePath)); $json = json_encode($data, ResponseHelper::JSON_ENCODE_OPTIONS); @@ -666,9 +1148,7 @@ class ExtensionStaticCacheService throw new StaticCachePublishException("Failed to encode JSON payload: {$absolutePath}"); } - if (File::put($absolutePath, $json) === false) { - throw new StaticCachePublishException("Failed to write file: {$absolutePath}"); - } + $this->putVerified($absolutePath, $json); $files[] = $this->relativePath($absolutePath, $tmp); } @@ -683,12 +1163,24 @@ class ExtensionStaticCacheService */ private function copyFile(string $source, string $target, array &$files, string $tmp): void { - File::ensureDirectoryExists(dirname($target), 0775); + $this->makeDirectory(dirname($target)); if (! File::copy($source, $target)) { throw new StaticCachePublishException("Failed to copy file: {$source} -> {$target}"); } + // 복사도 절단될 수 있다 — 디스크 풀/quota 에서 `copy()` 는 true 를 반환하면서 + // 짧은 파일을 남긴다. 크기 대조로 그 자리에서 잡는다. + clearstatcache(true, $target); + $expected = @filesize($source); + $actual = @filesize($target); + + if ($expected !== false && $actual !== $expected) { + throw new StaticCachePublishException( + "Truncated copy: {$target} ({$actual} of {$expected} bytes)" + ); + } + $files[] = $this->relativePath($target, $tmp); } @@ -715,9 +1207,7 @@ class ExtensionStaticCacheService HTACCESS; - if (File::put($tmp.DIRECTORY_SEPARATOR.'.htaccess', $content) === false) { - throw new StaticCachePublishException('Failed to write .htaccess'); - } + $this->putVerified($tmp.DIRECTORY_SEPARATOR.'.htaccess', $content); $files[] = '.htaccess'; } @@ -739,8 +1229,40 @@ class ExtensionStaticCacheService $json = json_encode($manifest, ResponseHelper::JSON_ENCODE_OPTIONS); - if ($json === false || File::put($finalDir.DIRECTORY_SEPARATOR.self::MANIFEST_FILE, $json) === false) { - throw new StaticCachePublishException('Failed to write manifest'); + if ($json === false) { + throw new StaticCachePublishException('Failed to encode manifest'); + } + + $this->putVerified($finalDir.DIRECTORY_SEPARATOR.self::MANIFEST_FILE, $json); + } + + /** + * 파일을 기록하고 **기록된 바이트 수를 검증**합니다. + * + * `File::put()` 은 실패 시에만 `false` 를 돌려주는 게 아니다 — 디스크 풀·quota 초과에서는 + * 쓴 만큼의 짧은 `int` 를 반환하며 성공한 것처럼 보인다. `=== false` 검사만 하면 그 + * **절단된 JSON 이 200 으로 서빙**되고, 프론트의 `fetchStaticFirst` 는 `response.ok` 만 + * 보므로 폴백하지 않은 채 `response.json()` 이 던져 부팅 전체가 실패한다. 3층 폴백이 + * 유일하게 개입하지 못하는 경로라, 여기서 잡지 못하면 다른 어디서도 잡히지 않는다. + * + * @param string $absolutePath 기록 대상 절대 경로 + * @param string $contents 기록할 내용 + * + * @throws StaticCachePublishException 쓰기 실패 또는 바이트 수 불일치 + */ + private function putVerified(string $absolutePath, string $contents): void + { + $expected = strlen($contents); + $written = File::put($absolutePath, $contents); + + if ($written === false) { + throw new StaticCachePublishException("Failed to write file: {$absolutePath}"); + } + + if ($written !== $expected) { + throw new StaticCachePublishException( + "Truncated write: {$absolutePath} ({$written} of {$expected} bytes)" + ); } } diff --git a/app/Support/StaticExtensionPattern.php b/app/Support/StaticExtensionPattern.php new file mode 100644 index 00000000..3f2d921e --- /dev/null +++ b/app/Support/StaticExtensionPattern.php @@ -0,0 +1,64 @@ + 중복 없는 확장자 목록 + */ + public static function servedExtensions(): array + { + return array_values(array_unique([ + ...AllowedTemplateFileType::allowedExtensions(), + ...AllowedModuleFileType::allowedExtensions(), + ...AllowedPluginFileType::allowedExtensions(), + ])); + } +} diff --git a/config/filesystems.php b/config/filesystems.php index a2f3655b..43181493 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -76,12 +76,22 @@ return [ // 확장(모듈/플러그인) 프론트엔드 IIFE/CSS 번들 병합 결과 캐시. // ExtensionBundleService 가 version-in-path 파일명으로 저장/서빙한다. + // + // `permissions` 선언이 없으면 Flysystem 이 디스크 인스턴스화 시점에 root 를 + // `0700` 으로 만든다. 그러면 **먼저 touch 한 프로세스가 독점**한다 — CLI 가 먼저면 + // 이후 php-fpm 의 쓰기가 `UnableToWriteFile` 로 죽고, `throw => true` 라 그 예외가 + // 공개 번들 엔드포인트의 500 으로 그대로 나간다. 디스크 생성 시점이 유일한 예방 + // 지점이므로 여기서 그룹 쓰기를 열어 둔다 (실패 시 fail-soft 는 서비스가 담당). 'ext-bundles' => [ 'driver' => 'local', 'root' => storage_path('app/ext-bundles'), 'serve' => false, 'throw' => true, 'report' => false, + 'permissions' => [ + 'file' => ['public' => 0664, 'private' => 0664], + 'dir' => ['public' => 0775, 'private' => 0775], + ], ], 'public' => [ diff --git a/docs/backend/api/dashboard.md b/docs/backend/api/dashboard.md index faaf8672..56b8a414 100644 --- a/docs/backend/api/dashboard.md +++ b/docs/backend/api/dashboard.md @@ -141,13 +141,13 @@ Authorization: Bearer {YOUR_TOKEN} **응답 필드** (`data` 내부) -_목록 응답: `data` 배열 항목의 필드. `data` 는 `core.dashboard.alerts` 필터 훅의 결과이며, 알릴 항목이 없으면 빈 배열(`[]`)입니다. 코어 기본 리스너(`ExtensionCompatibilityAlertListener`)가 주입하는 항목의 필드는 다음과 같습니다._ +_목록 응답: `data` 배열 항목의 필드. `data` 는 `core.dashboard.alerts` 필터 훅의 결과이며, 알릴 항목이 없으면 빈 배열(`[]`)입니다. 코어 기본 리스너(`ExtensionCompatibilityAlertListener`, `StaticPublishFailureAlertListener`)가 주입하는 항목의 필드는 다음과 같습니다._ | 필드 | 타입 | 실측 예시값 | 용도/설명 | | --- | --- | --- | --- | | id | string | `compat_plugins_sirsoft-gdpr` | 알림 식별자 (`compat_{type}_{identifier}` = 자동 비활성화, `recover_{type}_{identifier}` = 재호환. 알림 닫기(dismiss) 상태 판정 키) | | type | string | `warning` | 알림 등급 (`warning`: 코어 비호환 자동 비활성화, `info`: 재호환 복구 가능) | -| subtype | string | `incompatible_core` | 알림 세부 분류 (`incompatible_core`: 코어 버전 비호환으로 자동 비활성화됨, `recovery_available`: 코어 업그레이드 후 다시 활성화 가능) | +| subtype | string | `incompatible_core` | 알림 세부 분류 (`incompatible_core`: 코어 버전 비호환으로 자동 비활성화됨, `recovery_available`: 코어 업그레이드 후 다시 활성화 가능, `static_publish_parent_not_writable` · `static_publish_write_failed` · `static_publish_lock_unavailable`: 초기 화면 파일 생성이 2회 이상 연속 실패 — 각각 폴더 권한 / 디스크 공간 / 캐시 저장소가 원인) | | icon | string | `exclamation-triangle` | 아이콘 식별자 (warning: `exclamation-triangle`, info: `check-circle`) | | title | string | `플러그인 "sirsoft-gdpr" 자동 비활성화됨` | 알림 제목 (다국어 문구 — `extensions.alerts.incompatible_deactivated` / `recovered_title`) | | message | string | `필요 버전: 7.0.0-beta.9, 현재 설치됨: 7.0.0-beta.8` | 알림 본문 (다국어 문구 — `extensions.alerts.incompatible_message` / `recovered_body`) | diff --git a/docs/backend/routing.md b/docs/backend/routing.md index 669aee69..16210e5e 100644 --- a/docs/backend/routing.md +++ b/docs/backend/routing.md @@ -144,6 +144,29 @@ URL 을 만드는 쪽도 문자열로 직접 조립하지 않는다. 서버는 ` 자동 차단: 정적 검사 대상 (위반 시 차단). 면제는 인라인 주석 `// audit:allow dynamic-route-static-extension reason: ...`. +### SPA catch-all 의 정적 확장자 제외 + +SPA catch-all(`routes/web.php` 의 admin·user 그룹)은 등록되지 않은 경로에 SPA 셸 HTML 을 돌려준다. +**정적 자산 요청이 거기 걸리면 안 된다** — 없는 `.mjs` 가 `Content-Type: text/html` 인 200 을 받고, +브라우저는 그것을 스크립트로 파싱하다 죽는다. 응답이 성공이라 `onerror` 는 발화하지 않으므로 태그 +복구기도 뜨지 않는다: 예외도 404 도 없이 화면 기능만 사라진다. + +제외 목록을 라우트 파일에 손으로 적으면 에셋 서빙이 허용하는 확장자와 갈라진다. 실제로 갈라져 있었고 +(`mjs` · `webp` · `otf` 가 서빙은 되는데 제외 목록엔 없었다), `.json` 이 무사했던 것은 lookahead 에 끝 +앵커가 없어 `.js` 에 **부분일치**한 우연이었다. + +그래서 목록을 파생시킨다 — `App\Support\StaticExtensionPattern::catchAllExclusion()` 이 +`Allowed{Template,Module,Plugin}FileType` 세 화이트리스트의 **합집합**에서 패턴을 만들고, 두 catch-all 이 +그것을 호출한다. 합집합인 이유: 게시 트리에는 템플릿 dist 뿐 아니라 모듈·플러그인의 사용자 추가 에셋도 +함께 실리므로 한 종류만 기준으로 삼으면 나머지가 서빙하는 확장자(`ico`)가 다시 빠진다. + +환경 의존 게터(`getAllowedExtensions()`, 로컬에서 `map` 을 덧붙인다)는 쓰지 않는다 — `where()` 인자는 +정의 시점에 평가되어 컴파일된 정규식으로 라우트 캐시에 박히므로, 패턴이 **캐시를 구운 환경**에 따라 +달라지면 안 된다. 캐시 로드 경로는 이 클래스를 참조하지 않으므로 캐시 안전성도 유지된다. + +라우트 정의를 바꿨으므로 배포 시 라우트 캐시를 재생성해야 한다 — 재생성 전에는 이전에 컴파일된 패턴이 +그대로 쓰인다. + 두 형태는 모두 영구 유지한다 — 확장자 형태를 제거하면 URL 을 하드코딩한 서드파티 확장이 깨진다. 엔드포인트별 변환 규칙 표와 프로브 판정 절차: [API 레퍼런스 진입점](./api/README.md) "자산 URL 이중 모드". diff --git a/docs/backend/static-asset-publishing.md b/docs/backend/static-asset-publishing.md index 72e0026f..a096704c 100644 --- a/docs/backend/static-asset-publishing.md +++ b/docs/backend/static-asset-publishing.md @@ -110,6 +110,35 @@ URL 은 **public 아래 실제 파일일 때만** 200 이 되므로, "폰트· - 동시성: 게시는 캐시 락으로 단일 실행. manifest 존재 시 skip(멱등). - 실패 정책: 쓰기 실패는 로그만 남기고 tmp 정리 — 사이트는 API 폴백으로 정상 ("정적 fast path 미적용" 상태이지 장애가 아니다). 다음 렌더의 자가 치유가 재시도한다. + +### 게시는 갱신 → 생성 → **완전성 확인** 이 한 묶음이다 + +"캐시 버전이 올랐다" 와 "그 버전의 산출물이 온전히 존재한다" 는 다른 사실이다. 둘 사이가 벌어지면 포인터는 미래를 가리키는데 파일은 없거나 깨진 상태가 되고, 그 상태는 예외도 로그도 남기지 않는다. 그래서 게시는 다음 4단계를 한 묶음으로 수행한다. + +| 단계 | 수행 | 실패 시 | +|---|---|---| +| ① 프리플라이트 | 게시 루트를 만들고 쓸 수 있는지 먼저 확인 | 전 로케일 병합·전 템플릿 복사를 **시작하기 전에** 중단 + 실패 마커 기록 | +| ② staging 쓰기 | `{v}.tmp/` 에 전부 기록 | tmp 정리 후 폴백 | +| ③ 완전성 확인 | 파일마다 **기록된 바이트 수**를 대조 (복사는 원본과 크기 대조) | 예외 → manifest 미기록 → 그 버전은 영원히 "미게시" | +| ④ 원자 스왑 | 기존 버전을 `.old` 로 비켜낸 뒤 rename → manifest 기록 → `.old` 삭제 | 비켜낸 기존 버전을 제자리로 되돌린다 | + +③ 이 없으면 `File::put()` 의 반환값이 짧은 `int` 인 경우(디스크 풀·quota)를 통과시킨다 — `=== false` 검사만으로는 잡히지 않고, 절단된 JSON 을 웹서버가 정상 200 으로 서빙한다. 프론트의 `fetchStaticFirst` 도 같은 이유로 본문이 JSON 으로 파싱되는지까지 확인한다 (양쪽 다 있어야 3층 폴백에 구멍이 없다). + +④ 에서 기존 디렉토리를 **먼저 지우지 않는** 이유: 삭제와 rename 사이의 창에서 이미 배달된 HTML 이 참조하는 CSS/JS/폰트가 전부 404 가 되고, 폰트에는 복구기가 없다. + +`.tmp` 와 `.old` 는 GC 대상이되 **10분 나이 가드**를 받는다. 게시 락은 버전별이라 서로 다른 버전의 게시가 동시에 진행될 수 있고, 나이를 보지 않으면 그 순간 살아 있는 다른 게시의 작업 디렉토리를 파괴한다. + +④ 의 디렉토리 rename 은 **유한 재시도**를 거친 뒤에야 실패로 본다. 갓 쓰여진 파일이 든 디렉토리의 rename 은 목적지가 비어 있는데도 첫 시도가 거부될 수 있고, 상태를 바꾸지 않고 그대로 다시 호출하면 성공한다(실측 4표본: 즉시 1건 · 200ms 후 3건). 재시도가 없으면 그 한 번이 그대로 게시 실패가 되어, 사이트는 API 폴백으로 멀쩡한데 실패 마커와 대시보드 알림만 올라간다. + +이 재시도는 OS 로 분기하지 않는다. 거부는 파일시스템·스토리지 계층(네트워크 마운트, 스냅샷, 백신·인덱서 등)이면 어디서든 성립하는 조건이고, 특정 플랫폼에서만 재시도하면 그 밖에서 같은 실패가 조용히 남는다. 재시도가 불필요한 환경에서는 첫 시도가 성공하므로 비용이 0 이다. **실패 계약은 종전 그대로다** — 끝내 실패하면 `.old` 롤백과 예외가 그대로 수행된다. + +### 실패는 억제되고 기록된다 + +쓰기 불가 환경에서는 게시가 **매 요청** 실패한다. 그 전까지 전 로케일 lang 병합과 전 템플릿 dist 복사를 이미 다 헛돈 뒤이고, 사이트는 폴백으로 살아 있어 아무도 눈치채지 못한다. 그래서 실패는 캐시 키 `ext.static.publish_failure` 에 `{version, at, reason, count}` 로 기록되고, 그 마커가 신선한 동안(TTL 300초)에는 게시를 재예약하지 않는다. + +마커는 진단 표면의 입력이기도 하다 — `ext-static:status` 커맨드와 관리자 대시보드 알림이 이 마커를 읽는다. 사유는 셋으로 갈린다: `parent_not_writable`(권한) / `write_failed`(디스크) / `lock_unavailable`(캐시). 조치할 곳이 다르므로 뭉뚱그리지 않는다. + +마커 자체를 쓰지 못하는 환경(캐시 저장소 불능)에서는 백오프가 걸리지 않는다 — best-effort 다. 그 경우에도 프로세스 안의 예약 가드는 그대로 유효해 한 요청 안에서 반복되지는 않는다. - routes 병합이 열화 상태(확장 업데이트 진행 중 등)면 그 산출물은 게시하지 않는다 — 정적 파일은 스스로 회복되지 않으므로 열화가 다음 bump 까지 박제된다. 같은 규율이 폴백 API 의 HTTP 캐시 헤더에도 적용된다 — 열화 응답에는 `public, max-age` 를 부여하지 않는다 (브라우저/CDN 박제 방지). ## 5. 운영자 kill-switch @@ -125,6 +154,27 @@ URL 은 **public 아래 실제 파일일 때만** 200 이 되므로, "폰트· - **sudo 코어 업데이트 시**: 업데이트가 root 로 실행되면 종료 시점(소유권 복원 `app.update.restore_ownership` **이후**)에 도는 terminating 게시가 root 소유 산출물을 만들 수 있다. 산출물은 게시 트리만이 아니다 — 게시는 캐시 락(`storage/framework/cache/data/xx` 샤드 디렉토리 신설)과 병합 번들 빌드(`storage/app/ext-bundles`)까지 **간접적으로 쓴다**. root 소유 캐시 샤드가 남으면 이후 웹 프로세스의 캐시 쓰기가 그 샤드에 해시되는 순간 Permission denied 로 죽어 전면 500 이 된다(7.0.10 업그레이드 실사례). 따라서 **root 프로세스에서는 terminating 자동 게시를 예약하지 않고** 다음 웹 렌더의 자가 치유(웹 계정)에 위임한다. 명시적 `ext-static:publish` 는 root 로도 실행 가능하며 게시 트리(`public/build/ext`)는 부모 소유권 상속으로 정상화되지만, storage 측 간접 산출물의 소유권은 운영자 책임이다 — sudo 로 수동 게시했다면 `storage`/`bootstrap/cache` 의 그룹 쓰기(`chgrp -R {웹그룹}` + `chmod -R g+w`)를 확인한다. - **코어 업데이트의 orphan 정리**: 게시본은 릴리즈 소스에 없는 로컬 파생물이므로 `app.update.excludes` 에 `build/ext` 로 등록되어 있다 — `--prune` 업데이트가 orphan 으로 삭제하지 않고, 백업 대상에서도 제외된다. +### CLI 계정과 웹 계정이 다를 때 + +제보된 실제 상황은 root 가 아니었다 — **비-root CLI 계정(`deploy` 등)이 웹 계정과 다른** 구성이다. CLI 가 최초 게시를 하면 트리가 `0755 deploy:deploy` 로 굳고, 이후 웹(php-fpm)의 재게시가 영구히 실패한다. 사이트는 API 폴백으로 살아 있어 아무도 모른 채 정적 fast path 만 꺼진다. + +그래서 게시는 소유권 정상화를 **두 갈래**로 수행한다. + +- root 갈래: 부모 기준으로 소유권을 되돌린다 (sudo CLI 게시 대응). +- 항상 실행 갈래: 부모 그룹을 상속(`chgrp`)시키고 트리에 `g+w` 를 승격한다. 비-root 에서 `chown` 은 실패해도 무해하고, `chgrp`(자기가 속한 그룹으로)와 `chmod g+w`(자기 소유 파일)는 성립한다. + +디렉토리는 `ensureDirectoryExists(..., 0775)` **직후 명시 `chmod`** 로 굳힌다 — mode 인자는 umask 로 깎이므로(umask 022 → 0755) 그것만으로는 그룹 쓰기가 남지 않는다. + +**이 방식의 한계**: CLI 계정과 웹 계정이 **그룹을 공유**할 때만 성립한다. 공유하지 않는 환경에서는 프리플라이트가 `parent_not_writable` 로 실패 마커를 남기고, `ext-static:status` 와 관리자 대시보드 알림이 그 사실을 운영자에게 전달한다. 그 경우의 조치는 운영자가 `public/build` 의 그룹·권한을 맞추는 것이다. + +### 상태 점검 + +```bash +php artisan ext-static:status +``` + +현재 버전 / 게시 여부 / manifest 파일 수 / 트리 쓰기 가능성 / 최근 실패 마커(사유별 조치 힌트 포함) / 잔존 버전 목록을 출력한다. **이상이 있으면 비-0 으로 종료**한다 — 이는 "커맨드 실행 실패" 가 아니라 조치할 대상이 있다는 신호다. + 권한 문제로 게시가 계속 실패하는 환경(공유 호스팅 등)에서는 `G7_STATIC_CACHE=false` 로 기능을 끄면 경고 로그도 남지 않는다. ## 7. 다중 웹서버 제약 @@ -152,5 +202,5 @@ Apache 는 게시 트리에 포함된 `.htaccess` 가 같은 캐시 헤더와 `m - 정적 우선 URL 규칙은 서버측 `AssetUrl` 과 프론트측 `assetUrl.ts`(+ 자가 복구 파샬 역변환)가 **항상 쌍으로** 수정되어야 한다 — 한쪽만 바꾸면 그 자산만 404 가 된다. - 게시 산출물(`public/build/ext/`)은 git 미추적·release 페이로드 제외다. `public/build/core/` 는 계속 추적한다 (배포 산출물) — 혼동 금지. -- 루트 `npm run build`(기본 vite 앱 빌드)는 `public/build` 를 비운다(`emptyOutDir`) — `core` 와 `ext` 가 함께 지워진다. `core` 는 `core:build --production` 으로 재생성해야 하고(공개 #70 의 실제 원인), `ext` 는 다음 프로덕션 렌더의 자가 치유가 재게시한다. +- 루트 `npm run build`(기본 vite 앱 빌드)는 더 이상 `public/build` 를 비우지 않는다 — 루트 vite config 가 `build.emptyOutDir: false` 를 명시한다. 종전에는 기본값 `true` 로 `core`(폴백 없는 코어 3번들)와 `ext`(게시본)가 함께 지워졌고, 이미 배달된 HTML 의 immutable URL 은 재게시로도 복구되지 않았다(공개 #70 · #122). 잔존 구 해시 산출물은 `manifest.json` 이 선택하므로 참조되지 않는 사표이며, 산출물 정리 책임은 빌드 커맨드(`PrunesBuildOutput`)가 진다. 저장소의 모든 vite config 는 이 규약을 명시해야 한다 — 기본값 의존은 정적 검사가 차단한다. - 확장 병합 번들의 생성 규율은 [module-assets.md "서버측 번들 병합"](../extension/module-assets.md) 이 소유한다. 본 게시는 그 산출물의 **사본**만 만든다. diff --git a/docs/extension/module-assets.md b/docs/extension/module-assets.md index f2779cfd..a7354ab1 100644 --- a/docs/extension/module-assets.md +++ b/docs/extension/module-assets.md @@ -501,6 +501,27 @@ GET /api/plugins/bundle.css?v={version} | 절대경로 게터 | `getBuiltAssetAbsolutePaths()` 사용. `base_path("modules"\|"plugins")` 직접 조립 금지 | `extension-bundle-asset-path-getter` | | 확장별 try/catch | 파일 읽기 실패 시 해당 확장만 skip, 나머지 병합 지속 | (메모리+회귀테스트) | | CSS url() | 상대경로 url() 을 가진 CSS 는 번들 제외(개별 폴백) | - | +| 디스크 캐시 fail-soft | 캐시 쓰기 실패는 **500 이 아니다** — 메모리 병합 결과를 그대로 200 으로 서빙 | (계약 테스트) | +| 빈 번들 판정 | 선언 0개면 빈 200, 선언은 있는데 결과가 0이면 **503** | (계약 테스트) | + +### 디스크 캐시 실패와 빈 번들 (응답 계약) + +번들 디스크 캐시는 **최적화**다. `ext-bundles` 디스크는 `throw => true` 라 권한 문제(먼저 touch 한 프로세스가 `0700` 으로 독점하는 경우 등)에서 `UnableToWriteFile` 이 그대로 올라오는데, 그것이 공개 엔드포인트의 500 이 되면 **모든 확장의 프론트엔드 JS/CSS 가 통째로 나가지 못한다.** 병합 결과는 이미 메모리에 있으므로 그것을 그대로 응답한다(코어 캐시 드라이버의 fail-soft 와 같은 원칙). 예방 지점은 디스크 선언이다 — `config/filesystems.php` 의 `ext-bundles` 에 `permissions`(dir `0775` / file `0664`)를 선언해 Flysystem 이 root 를 `0700` 으로 만들지 않게 한다. + +빈 번들은 두 가지를 구분해야 한다. + +| 상태 | 판정 | 응답 | +|---|---|---| +| 에셋을 선언한 활성 확장이 0개 | 정상 | 빈 200 | +| 선언은 있는데 병합 결과가 0 | 장애 (배포 중 `dist` 가 잠깐 빔, 경로 어긋남) | **503** + `Log::error` | + +구분하지 않으면 후자가 빈 200 으로 나가고, 프론트는 404 도 오류도 받지 못한 채 한참 뒤 "Unknown action handler" 로 죽는다 — 그 시점에는 원인이 번들이라는 사실이 화면에도 로그에도 남아 있지 않다. 판정은 **kind 별**이다(js 만 선언한 확장이 있는 상태에서 css 번들이 비는 것은 정상). + +"선언" 의 근거는 manifest 의 `assets.{kind}.output` 이며 **산출물 파일의 존재를 보지 않는다.** 병합 경로가 쓰는 게터들(`getOrderedGlobalAssetPaths()` · `hasAssets()` · `getBuiltAssetPaths()`)은 모두 `file_exists()` 로 거르므로, 그 경로로 선언 수를 세면 "`dist` 가 잠깐 빔" 이 곧 "선언 0" 이 되어 **막으려던 상태가 정상(빈 200)으로 판정된다.** 선언과 산출은 다른 축이고, 이 판정이 재는 것은 선언 축이다. + +두 판정은 모듈·플러그인 컨트롤러가 **공유하는 단일 지점**(`ServesExtensionBundles::bundleResponse()`)에 둔다. 각자 구현하면 한쪽만 고쳐진 채 다른 쪽이 옛 동작으로 남는다. + +`clearBundles()`(cache-clear 커맨드)는 **현재 버전을 보존**한다 — `cleanupStaleBundles()` 와 같은 정책이다. 현재 버전까지 지우면 같은 순간 서빙 중인 요청이 "존재함" 판정 직후 `filemtime()` 에서 500 을 낸다. 원자적 쓰기의 임시 파일(`*.tmp.{pid}`)도 GC 대상이되 10분 나이 가드를 받는다(pid 는 재사용되므로 생사로는 진행 여부를 판정할 수 없다). ### 캐시 stale 관리 diff --git a/lang-packs/_bundled/g7-core-ja/CHANGELOG.md b/lang-packs/_bundled/g7-core-ja/CHANGELOG.md index 2eeaa53e..02686918 100644 --- a/lang-packs/_bundled/g7-core-ja/CHANGELOG.md +++ b/lang-packs/_bundled/g7-core-ja/CHANGELOG.md @@ -13,6 +13,7 @@ - 레이아웃 편집기 툴바에서 운영자 추가 에셋을 잠시 끄고 켜는 항목의 일본어 번역을 추가했습니다 — 추가한 파일이 화면을 깨뜨렸을 때 그 파일 없이 화면을 다시 여는 안내가 함께 표시됩니다. - 확장을 제거할 때 운영자가 넣어 둔 파일의 사본을 보관했다는 안내의 일본어 번역을 추가했습니다 — 모듈·플러그인·템플릿 제거 결과 화면에서 보관 경로가 일본어로 표시됩니다. - 운영자 추가 에셋의 저장·올리기·삭제가 활동 로그에 남을 때 표시되는 문구의 일본어 번역을 추가했습니다. +- 초기 화면 파일 생성이 거듭 실패할 때 관리자 대시보드에 표시되는 안내의 일본어 번역을 추가했습니다 — 폴더 권한·디스크 공간·캐시 저장소 중 어느 쪽이 원인인지에 따라 다른 안내가 일본어 로케일에서 표시됩니다. ## [1.0.8] - 2026-08-24 diff --git a/lang-packs/_bundled/g7-core-ja/backend/ja/extensions.php b/lang-packs/_bundled/g7-core-ja/backend/ja/extensions.php index 7281efe3..37966306 100644 --- a/lang-packs/_bundled/g7-core-ja/backend/ja/extensions.php +++ b/lang-packs/_bundled/g7-core-ja/backend/ja/extensions.php @@ -33,6 +33,10 @@ return [ 'auto_deactivated_listed' => '自動無効化された拡張の一覧です。', 'recover_action' => '再度有効化', 'dismiss_action' => '通知を閉じる', + 'static_publish_failed_title' => '初期画面ファイルの生成に失敗', + 'static_publish_failed_parent_not_writable' => '初期画面ファイルを保存するフォルダに書き込めず、:count 回連続で失敗しました。サイトは正常に動作しますが、最初の画面の表示が遅くなります。サーバーで `php artisan ext-static:status` を実行して原因を確認してください。', + 'static_publish_failed_write_failed' => '初期画面ファイルの生成が :count 回連続で失敗しました。ディスクの空き容量を確認してください。サイトは正常に動作しますが、最初の画面の表示が遅くなります。', + 'static_publish_failed_lock_unavailable' => '初期画面ファイルの生成が :count 回連続でスキップされました。キャッシュストアの状態を確認してください。サイトは正常に動作しますが、最初の画面の表示が遅くなります。', ], 'badges' => [ 'incompatible' => 'コアアップグレード必要', diff --git a/lang/en/extensions.php b/lang/en/extensions.php index 95820932..85b55fd9 100644 --- a/lang/en/extensions.php +++ b/lang/en/extensions.php @@ -36,6 +36,10 @@ return [ 'auto_deactivated_listed' => 'Auto-deactivated extensions listed.', 'recover_action' => 'Re-activate', 'dismiss_action' => 'Dismiss alert', + 'static_publish_failed_title' => 'Failed to generate startup files', + 'static_publish_failed_parent_not_writable' => 'Could not write to the folder for startup files — :count consecutive failures. The site works normally but the first screen loads more slowly. Run `php artisan ext-static:status` on the server to see the cause.', + 'static_publish_failed_write_failed' => 'Generating startup files failed :count times in a row. Check available disk space. The site works normally but the first screen loads more slowly.', + 'static_publish_failed_lock_unavailable' => 'Startup file generation was skipped :count times in a row. Check the cache store. The site works normally but the first screen loads more slowly.', ], 'badges' => [ diff --git a/lang/ko/extensions.php b/lang/ko/extensions.php index 819bbeaa..100ce54b 100644 --- a/lang/ko/extensions.php +++ b/lang/ko/extensions.php @@ -36,6 +36,10 @@ return [ 'auto_deactivated_listed' => '자동 비활성화된 확장 목록입니다.', 'recover_action' => '다시 활성화', 'dismiss_action' => '알림 닫기', + 'static_publish_failed_title' => '초기 화면 파일 생성 실패', + 'static_publish_failed_parent_not_writable' => '초기 화면 파일을 저장할 폴더에 쓸 수 없어 :count회 연속 실패했습니다. 사이트는 정상 동작하지만 첫 화면이 느려집니다. 서버에서 `php artisan ext-static:status` 로 원인을 확인하세요.', + 'static_publish_failed_write_failed' => '초기 화면 파일을 만드는 중 :count회 연속 실패했습니다. 디스크 여유 공간을 확인하세요. 사이트는 정상 동작하지만 첫 화면이 느려집니다.', + 'static_publish_failed_lock_unavailable' => '초기 화면 파일 생성이 :count회 연속 건너뛰어졌습니다. 캐시 저장소 상태를 확인하세요. 사이트는 정상 동작하지만 첫 화면이 느려집니다.', ], 'badges' => [ diff --git a/public/build/core/template-engine.min.js b/public/build/core/template-engine.min.js index 9257943b..9fb99553 100644 --- a/public/build/core/template-engine.min.js +++ b/public/build/core/template-engine.min.js @@ -1,23 +1,23 @@ -var Tk=Object.defineProperty;var kk=(Xt,ea,ta)=>ea in Xt?Tk(Xt,ea,{enumerable:!0,configurable:!0,writable:!0,value:ta}):Xt[ea]=ta;var M=(Xt,ea,ta)=>kk(Xt,typeof ea!="symbol"?ea+"":ea,ta);(function(Xt){"use strict";function ea(s,e){for(var n=0;nr[i]})}}}return Object.freeze(Object.defineProperty(s,Symbol.toStringTag,{value:"Module"}))}function ta(s){return s&&s.__esModule&&Object.prototype.hasOwnProperty.call(s,"default")?s.default:s}var pd={exports:{}},We={};var Eg;function Ow(){if(Eg)return We;Eg=1;var s=Symbol.for("react.transitional.element"),e=Symbol.for("react.portal"),n=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),l=Symbol.for("react.consumer"),c=Symbol.for("react.context"),d=Symbol.for("react.forward_ref"),f=Symbol.for("react.suspense"),h=Symbol.for("react.memo"),m=Symbol.for("react.lazy"),y=Symbol.for("react.activity"),S=Symbol.iterator;function v(H){return H===null||typeof H!="object"?null:(H=S&&H[S]||H["@@iterator"],typeof H=="function"?H:null)}var _={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},x=Object.assign,A={};function L(H,T,ce){this.props=H,this.context=T,this.refs=A,this.updater=ce||_}L.prototype.isReactComponent={},L.prototype.setState=function(H,T){if(typeof H!="object"&&typeof H!="function"&&H!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,H,T,"setState")},L.prototype.forceUpdate=function(H){this.updater.enqueueForceUpdate(this,H,"forceUpdate")};function $(){}$.prototype=L.prototype;function k(H,T,ce){this.props=H,this.context=T,this.refs=A,this.updater=ce||_}var O=k.prototype=new $;O.constructor=k,x(O,L.prototype),O.isPureReactComponent=!0;var P=Array.isArray;function G(){}var B={H:null,A:null,T:null,S:null},W=Object.prototype.hasOwnProperty;function pe(H,T,ce){var de=ce.ref;return{$$typeof:s,type:H,key:T,ref:de!==void 0?de:null,props:ce}}function Se(H,T){return pe(H.type,T,H.props)}function we(H){return typeof H=="object"&&H!==null&&H.$$typeof===s}function Ue(H){var T={"=":"=0",":":"=2"};return"$"+H.replace(/[=:]/g,function(ce){return T[ce]})}var Fe=/\/+/g;function qe(H,T){return typeof H=="object"&&H!==null&&H.key!=null?Ue(""+H.key):T.toString(36)}function wt(H){switch(H.status){case"fulfilled":return H.value;case"rejected":throw H.reason;default:switch(typeof H.status=="string"?H.then(G,G):(H.status="pending",H.then(function(T){H.status==="pending"&&(H.status="fulfilled",H.value=T)},function(T){H.status==="pending"&&(H.status="rejected",H.reason=T)})),H.status){case"fulfilled":return H.value;case"rejected":throw H.reason}}throw H}function J(H,T,ce,de,be){var ie=typeof H;(ie==="undefined"||ie==="boolean")&&(H=null);var xe=!1;if(H===null)xe=!0;else switch(ie){case"bigint":case"string":case"number":xe=!0;break;case"object":switch(H.$$typeof){case s:case e:xe=!0;break;case m:return xe=H._init,J(xe(H._payload),T,ce,de,be)}}if(xe)return be=be(H),xe=de===""?"."+qe(H,0):de,P(be)?(ce="",xe!=null&&(ce=xe.replace(Fe,"$&/")+"/"),J(be,T,ce,"",function(Me){return Me})):be!=null&&(we(be)&&(be=Se(be,ce+(be.key==null||H&&H.key===be.key?"":(""+be.key).replace(Fe,"$&/")+"/")+xe)),T.push(be)),1;xe=0;var _e=de===""?".":de+":";if(P(H))for(var Te=0;Te>>1,ge=J[Z];if(0>>1;Zi(ce,Le))dei(be,ce)?(J[Z]=be,J[de]=Le,Z=de):(J[Z]=ce,J[T]=Le,Z=T);else if(dei(be,Le))J[Z]=be,J[de]=Le,Z=de;else break e}}return fe}function i(J,fe){var Le=J.sortIndex-fe.sortIndex;return Le!==0?Le:J.id-fe.id}if(s.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var l=performance;s.unstable_now=function(){return l.now()}}else{var c=Date,d=c.now();s.unstable_now=function(){return c.now()-d}}var f=[],h=[],m=1,y=null,S=3,v=!1,_=!1,x=!1,A=!1,L=typeof setTimeout=="function"?setTimeout:null,$=typeof clearTimeout=="function"?clearTimeout:null,k=typeof setImmediate<"u"?setImmediate:null;function O(J){for(var fe=n(h);fe!==null;){if(fe.callback===null)r(h);else if(fe.startTime<=J)r(h),fe.sortIndex=fe.expirationTime,e(f,fe);else break;fe=n(h)}}function P(J){if(x=!1,O(J),!_)if(n(f)!==null)_=!0,G||(G=!0,Ue());else{var fe=n(h);fe!==null&&wt(P,fe.startTime-J)}}var G=!1,B=-1,W=5,pe=-1;function Se(){return A?!0:!(s.unstable_now()-peJ&&Se());){var Z=y.callback;if(typeof Z=="function"){y.callback=null,S=y.priorityLevel;var ge=Z(y.expirationTime<=J);if(J=s.unstable_now(),typeof ge=="function"){y.callback=ge,O(J),fe=!0;break t}y===n(f)&&r(f),O(J)}else r(f);y=n(f)}if(y!==null)fe=!0;else{var H=n(h);H!==null&&wt(P,H.startTime-J),fe=!1}}break e}finally{y=null,S=Le,v=!1}fe=void 0}}finally{fe?Ue():G=!1}}}var Ue;if(typeof k=="function")Ue=function(){k(we)};else if(typeof MessageChannel<"u"){var Fe=new MessageChannel,qe=Fe.port2;Fe.port1.onmessage=we,Ue=function(){qe.postMessage(null)}}else Ue=function(){L(we,0)};function wt(J,fe){B=L(function(){J(s.unstable_now())},fe)}s.unstable_IdlePriority=5,s.unstable_ImmediatePriority=1,s.unstable_LowPriority=4,s.unstable_NormalPriority=3,s.unstable_Profiling=null,s.unstable_UserBlockingPriority=2,s.unstable_cancelCallback=function(J){J.callback=null},s.unstable_forceFrameRate=function(J){0>J||125Z?(J.sortIndex=Le,e(h,J),n(f)===null&&J===n(h)&&(x?($(B),B=-1):x=!0,wt(P,Le-Z))):(J.sortIndex=ge,e(f,J),_||v||(_=!0,G||(G=!0,Ue()))),J},s.unstable_shouldYield=Se,s.unstable_wrapCallback=function(J){var fe=S;return function(){var Le=S;S=fe;try{return J.apply(this,arguments)}finally{S=Le}}}})(bd)),bd}var xg;function $w(){return xg||(xg=1,yd.exports=Lw()),yd.exports}var vd={exports:{}},Cn={};var Tg;function Mw(){if(Tg)return Cn;Tg=1;var s=gd();function e(f){var h="https://react.dev/errors/"+f;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(s)}catch(e){console.error(e)}}return s(),vd.exports=Mw(),vd.exports}var Dg;function Nw(){if(Dg)return oo;Dg=1;var s=$w(),e=gd(),n=Rg();function r(t){var a="https://react.dev/errors/"+t;if(1ge||(t.current=Z[ge],Z[ge]=null,ge--)}function ce(t,a){ge++,Z[ge]=t.current,t.current=a}var de=H(null),be=H(null),ie=H(null),xe=H(null);function _e(t,a){switch(ce(ie,a),ce(be,t),ce(de,null),a.nodeType){case 9:case 11:t=(t=a.documentElement)&&(t=t.namespaceURI)?JS(t):0;break;default:if(t=a.tagName,a=a.namespaceURI)a=JS(a),t=QS(a,t);else switch(t){case"svg":t=1;break;case"math":t=2;break;default:t=0}}T(de),ce(de,t)}function Te(){T(de),T(be),T(ie)}function Me(t){t.memoizedState!==null&&ce(xe,t);var a=de.current,o=QS(a,t.type);a!==o&&(ce(be,t),ce(de,o))}function pt(t){be.current===t&&(T(de),T(be)),xe.current===t&&(T(xe),Ul._currentValue=Le)}var Ct,Ot;function ht(t){if(Ct===void 0)try{throw Error()}catch(o){var a=o.stack.trim().match(/\n( *(at )?)/);Ct=a&&a[1]||"",Ot=-1ea in Xt?Tk(Xt,ea,{enumerable:!0,configurable:!0,writable:!0,value:ta}):Xt[ea]=ta;var M=(Xt,ea,ta)=>kk(Xt,typeof ea!="symbol"?ea+"":ea,ta);(function(Xt){"use strict";function ea(s,e){for(var n=0;nr[i]})}}}return Object.freeze(Object.defineProperty(s,Symbol.toStringTag,{value:"Module"}))}function ta(s){return s&&s.__esModule&&Object.prototype.hasOwnProperty.call(s,"default")?s.default:s}var gd={exports:{}},We={};var Eg;function Ow(){if(Eg)return We;Eg=1;var s=Symbol.for("react.transitional.element"),e=Symbol.for("react.portal"),n=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),l=Symbol.for("react.consumer"),c=Symbol.for("react.context"),d=Symbol.for("react.forward_ref"),f=Symbol.for("react.suspense"),h=Symbol.for("react.memo"),m=Symbol.for("react.lazy"),y=Symbol.for("react.activity"),S=Symbol.iterator;function v(H){return H===null||typeof H!="object"?null:(H=S&&H[S]||H["@@iterator"],typeof H=="function"?H:null)}var _={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},x=Object.assign,A={};function L(H,T,ce){this.props=H,this.context=T,this.refs=A,this.updater=ce||_}L.prototype.isReactComponent={},L.prototype.setState=function(H,T){if(typeof H!="object"&&typeof H!="function"&&H!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,H,T,"setState")},L.prototype.forceUpdate=function(H){this.updater.enqueueForceUpdate(this,H,"forceUpdate")};function $(){}$.prototype=L.prototype;function k(H,T,ce){this.props=H,this.context=T,this.refs=A,this.updater=ce||_}var O=k.prototype=new $;O.constructor=k,x(O,L.prototype),O.isPureReactComponent=!0;var P=Array.isArray;function G(){}var B={H:null,A:null,T:null,S:null},W=Object.prototype.hasOwnProperty;function pe(H,T,ce){var de=ce.ref;return{$$typeof:s,type:H,key:T,ref:de!==void 0?de:null,props:ce}}function Se(H,T){return pe(H.type,T,H.props)}function we(H){return typeof H=="object"&&H!==null&&H.$$typeof===s}function Ue(H){var T={"=":"=0",":":"=2"};return"$"+H.replace(/[=:]/g,function(ce){return T[ce]})}var Fe=/\/+/g;function qe(H,T){return typeof H=="object"&&H!==null&&H.key!=null?Ue(""+H.key):T.toString(36)}function wt(H){switch(H.status){case"fulfilled":return H.value;case"rejected":throw H.reason;default:switch(typeof H.status=="string"?H.then(G,G):(H.status="pending",H.then(function(T){H.status==="pending"&&(H.status="fulfilled",H.value=T)},function(T){H.status==="pending"&&(H.status="rejected",H.reason=T)})),H.status){case"fulfilled":return H.value;case"rejected":throw H.reason}}throw H}function J(H,T,ce,de,be){var ie=typeof H;(ie==="undefined"||ie==="boolean")&&(H=null);var xe=!1;if(H===null)xe=!0;else switch(ie){case"bigint":case"string":case"number":xe=!0;break;case"object":switch(H.$$typeof){case s:case e:xe=!0;break;case m:return xe=H._init,J(xe(H._payload),T,ce,de,be)}}if(xe)return be=be(H),xe=de===""?"."+qe(H,0):de,P(be)?(ce="",xe!=null&&(ce=xe.replace(Fe,"$&/")+"/"),J(be,T,ce,"",function(Me){return Me})):be!=null&&(we(be)&&(be=Se(be,ce+(be.key==null||H&&H.key===be.key?"":(""+be.key).replace(Fe,"$&/")+"/")+xe)),T.push(be)),1;xe=0;var _e=de===""?".":de+":";if(P(H))for(var Te=0;Te>>1,ge=J[Z];if(0>>1;Zi(ce,Le))dei(be,ce)?(J[Z]=be,J[de]=Le,Z=de):(J[Z]=ce,J[T]=Le,Z=T);else if(dei(be,Le))J[Z]=be,J[de]=Le,Z=de;else break e}}return fe}function i(J,fe){var Le=J.sortIndex-fe.sortIndex;return Le!==0?Le:J.id-fe.id}if(s.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var l=performance;s.unstable_now=function(){return l.now()}}else{var c=Date,d=c.now();s.unstable_now=function(){return c.now()-d}}var f=[],h=[],m=1,y=null,S=3,v=!1,_=!1,x=!1,A=!1,L=typeof setTimeout=="function"?setTimeout:null,$=typeof clearTimeout=="function"?clearTimeout:null,k=typeof setImmediate<"u"?setImmediate:null;function O(J){for(var fe=n(h);fe!==null;){if(fe.callback===null)r(h);else if(fe.startTime<=J)r(h),fe.sortIndex=fe.expirationTime,e(f,fe);else break;fe=n(h)}}function P(J){if(x=!1,O(J),!_)if(n(f)!==null)_=!0,G||(G=!0,Ue());else{var fe=n(h);fe!==null&&wt(P,fe.startTime-J)}}var G=!1,B=-1,W=5,pe=-1;function Se(){return A?!0:!(s.unstable_now()-peJ&&Se());){var Z=y.callback;if(typeof Z=="function"){y.callback=null,S=y.priorityLevel;var ge=Z(y.expirationTime<=J);if(J=s.unstable_now(),typeof ge=="function"){y.callback=ge,O(J),fe=!0;break t}y===n(f)&&r(f),O(J)}else r(f);y=n(f)}if(y!==null)fe=!0;else{var H=n(h);H!==null&&wt(P,H.startTime-J),fe=!1}}break e}finally{y=null,S=Le,v=!1}fe=void 0}}finally{fe?Ue():G=!1}}}var Ue;if(typeof k=="function")Ue=function(){k(we)};else if(typeof MessageChannel<"u"){var Fe=new MessageChannel,qe=Fe.port2;Fe.port1.onmessage=we,Ue=function(){qe.postMessage(null)}}else Ue=function(){L(we,0)};function wt(J,fe){B=L(function(){J(s.unstable_now())},fe)}s.unstable_IdlePriority=5,s.unstable_ImmediatePriority=1,s.unstable_LowPriority=4,s.unstable_NormalPriority=3,s.unstable_Profiling=null,s.unstable_UserBlockingPriority=2,s.unstable_cancelCallback=function(J){J.callback=null},s.unstable_forceFrameRate=function(J){0>J||125Z?(J.sortIndex=Le,e(h,J),n(f)===null&&J===n(h)&&(x?($(B),B=-1):x=!0,wt(P,Le-Z))):(J.sortIndex=ge,e(f,J),_||v||(_=!0,G||(G=!0,Ue()))),J},s.unstable_shouldYield=Se,s.unstable_wrapCallback=function(J){var fe=S;return function(){var Le=S;S=fe;try{return J.apply(this,arguments)}finally{S=Le}}}})(vd)),vd}var xg;function $w(){return xg||(xg=1,bd.exports=Lw()),bd.exports}var Sd={exports:{}},Cn={};var Tg;function Mw(){if(Tg)return Cn;Tg=1;var s=md();function e(f){var h="https://react.dev/errors/"+f;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(s)}catch(e){console.error(e)}}return s(),Sd.exports=Mw(),Sd.exports}var Dg;function Nw(){if(Dg)return oo;Dg=1;var s=$w(),e=md(),n=Rg();function r(t){var a="https://react.dev/errors/"+t;if(1ge||(t.current=Z[ge],Z[ge]=null,ge--)}function ce(t,a){ge++,Z[ge]=t.current,t.current=a}var de=H(null),be=H(null),ie=H(null),xe=H(null);function _e(t,a){switch(ce(ie,a),ce(be,t),ce(de,null),a.nodeType){case 9:case 11:t=(t=a.documentElement)&&(t=t.namespaceURI)?JS(t):0;break;default:if(t=a.tagName,a=a.namespaceURI)a=JS(a),t=QS(a,t);else switch(t){case"svg":t=1;break;case"math":t=2;break;default:t=0}}T(de),ce(de,t)}function Te(){T(de),T(be),T(ie)}function Me(t){t.memoizedState!==null&&ce(xe,t);var a=de.current,o=QS(a,t.type);a!==o&&(ce(be,t),ce(de,o))}function pt(t){be.current===t&&(T(de),T(be)),xe.current===t&&(T(xe),Ul._currentValue=Le)}var Ct,Ot;function ht(t){if(Ct===void 0)try{throw Error()}catch(o){var a=o.stack.trim().match(/\n( *(at )?)/);Ct=a&&a[1]||"",Ot=-1)":-1p||z[u]!==X[p]){var re=` `+z[u].replace(" at new "," at ");return t.displayName&&re.includes("")&&(re=re.replace("",t.displayName)),re}while(1<=u&&0<=p);break}}}finally{rn=!1,Error.prepareStackTrace=o}return(o=t?t.displayName||t.name:"")?ht(o):""}function It(t,a){switch(t.tag){case 26:case 27:case 5:return ht(t.type);case 16:return ht("Lazy");case 13:return t.child!==a&&a!==null?ht("Suspense Fallback"):ht("Suspense");case 19:return ht("SuspenseList");case 0:case 15:return Kt(t.type,!1);case 11:return Kt(t.type.render,!1);case 1:return Kt(t.type,!0);case 31:return ht("Activity");default:return""}}function Fr(t){try{var a="",o=null;do a+=It(t,o),o=t,t=t.return;while(t);return a}catch(u){return` Error generating stack: `+u.message+` -`+u.stack}}var hn=Object.prototype.hasOwnProperty,an=s.unstable_scheduleCallback,pn=s.unstable_cancelCallback,Wn=s.unstable_shouldYield,Vr=s.unstable_requestPaint,qt=s.unstable_now,ki=s.unstable_getCurrentPriorityLevel,la=s.unstable_ImmediatePriority,gn=s.unstable_UserBlockingPriority,Dn=s.unstable_NormalPriority,nt=s.unstable_LowPriority,In=s.unstable_IdlePriority,mn=s.log,ca=s.unstable_setDisableYieldValue,lr=null,sn=null;function _n(t){if(typeof mn=="function"&&ca(t),sn&&typeof sn.setStrictMode=="function")try{sn.setStrictMode(lr,t)}catch{}}var on=Math.clz32?Math.clz32:ue,F=Math.log,se=Math.LN2;function ue(t){return t>>>=0,t===0?32:31-(F(t)/se|0)|0}var ee=256,ve=262144,he=4194304;function Ee(t){var a=t&42;if(a!==0)return a;switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return t&261888;case 262144:case 524288:case 1048576:case 2097152:return t&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function Ae(t,a,o){var u=t.pendingLanes;if(u===0)return 0;var p=0,g=t.suspendedLanes,w=t.pingedLanes;t=t.warmLanes;var R=u&134217727;return R!==0?(u=R&~g,u!==0?p=Ee(u):(w&=R,w!==0?p=Ee(w):o||(o=R&~t,o!==0&&(p=Ee(o))))):(R=u&~g,R!==0?p=Ee(R):w!==0?p=Ee(w):o||(o=u&~t,o!==0&&(p=Ee(o)))),p===0?0:a!==0&&a!==p&&(a&g)===0&&(g=p&-p,o=a&-a,g>=o||g===32&&(o&4194048)!==0)?a:p}function Ve(t,a){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&a)===0}function ke(t,a){switch(t){case 1:case 2:case 4:case 8:case 64:return a+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return a+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Ne(){var t=he;return he<<=1,(he&62914560)===0&&(he=4194304),t}function Re(t){for(var a=[],o=0;31>o;o++)a.push(t);return a}function et(t,a){t.pendingLanes|=a,a!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function He(t,a,o,u,p,g){var w=t.pendingLanes;t.pendingLanes=o,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=o,t.entangledLanes&=o,t.errorRecoveryDisabledLanes&=o,t.shellSuspendCounter=0;var R=t.entanglements,z=t.expirationTimes,X=t.hiddenUpdates;for(o=w&~o;0"u")return null;try{return t.activeElement||t.body}catch{return t.body}}var ch=/[\n"\\]/g;function Hn(t){return t.replace(ch,function(a){return"\\"+a.charCodeAt(0).toString(16)+" "})}function Ts(t,a,o,u,p,g,w,R){t.name="",w!=null&&typeof w!="function"&&typeof w!="symbol"&&typeof w!="boolean"?t.type=w:t.removeAttribute("type"),a!=null?w==="number"?(a===0&&t.value===""||t.value!=a)&&(t.value=""+xn(a)):t.value!==""+xn(a)&&(t.value=""+xn(a)):w!=="submit"&&w!=="reset"||t.removeAttribute("value"),a!=null?da(t,w,xn(a)):o!=null?da(t,w,xn(o)):u!=null&&t.removeAttribute("value"),p==null&&g!=null&&(t.defaultChecked=!!g),p!=null&&(t.checked=p&&typeof p!="function"&&typeof p!="symbol"),R!=null&&typeof R!="function"&&typeof R!="symbol"&&typeof R!="boolean"?t.name=""+xn(R):t.removeAttribute("name")}function Oi(t,a,o,u,p,g,w,R){if(g!=null&&typeof g!="function"&&typeof g!="symbol"&&typeof g!="boolean"&&(t.type=g),a!=null||o!=null){if(!(g!=="submit"&&g!=="reset"||a!=null)){Yo(t);return}o=o!=null?""+xn(o):"",a=a!=null?""+xn(a):o,R||a===t.value||(t.value=a),t.defaultValue=a}u=u??p,u=typeof u!="function"&&typeof u!="symbol"&&!!u,t.checked=R?t.checked:!!u,t.defaultChecked=!!u,w!=null&&typeof w!="function"&&typeof w!="symbol"&&typeof w!="boolean"&&(t.name=w),Yo(t)}function da(t,a,o){a==="number"&&qa(t.ownerDocument)===t||t.defaultValue===""+o||(t.defaultValue=""+o)}function Ga(t,a,o,u){if(t=t.options,a){a={};for(var p=0;p"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),el=!1;if(Or)try{var $i={};Object.defineProperty($i,"passive",{get:function(){el=!0}}),window.addEventListener("test",$i,$i),window.removeEventListener("test",$i,$i)}catch{el=!1}var Yr=null,tl=null,Rs=null;function eu(){if(Rs)return Rs;var t,a=tl,o=a.length,u,p="value"in Yr?Yr.value:Yr.textContent,g=p.length;for(t=0;t=ne),Ke=" ",ct=!1;function gt(t,a){switch(t){case"keyup":return D.indexOf(a.keyCode)!==-1;case"keydown":return a.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function zt(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var $r=!1;function Th(t,a){switch(t){case"compositionend":return zt(a);case"keypress":return a.which!==32?null:(ct=!0,Ke);case"textInput":return t=a.data,t===Ke&&ct?null:t;default:return null}}function ou(t,a){if($r)return t==="compositionend"||!I&>(t,a)?(t=eu(),Rs=tl=Yr=null,$r=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(a.ctrlKey||a.altKey||a.metaKey)||a.ctrlKey&&a.altKey){if(a.char&&1=a)return{node:o,offset:a-t};t=u}e:{for(;o;){if(o.nextSibling){o=o.nextSibling;break e}o=o.parentNode}o=void 0}o=gb(o)}}function yb(t,a){return t&&a?t===a?!0:t&&t.nodeType===3?!1:a&&a.nodeType===3?yb(t,a.parentNode):"contains"in t?t.contains(a):t.compareDocumentPosition?!!(t.compareDocumentPosition(a)&16):!1:!1}function bb(t){t=t!=null&&t.ownerDocument!=null&&t.ownerDocument.defaultView!=null?t.ownerDocument.defaultView:window;for(var a=qa(t.document);a instanceof t.HTMLIFrameElement;){try{var o=typeof a.contentWindow.location.href=="string"}catch{o=!1}if(o)t=a.contentWindow;else break;a=qa(t.document)}return a}function Lh(t){var a=t&&t.nodeName&&t.nodeName.toLowerCase();return a&&(a==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||a==="textarea"||t.contentEditable==="true")}var sT=Or&&"documentMode"in document&&11>=document.documentMode,$s=null,$h=null,dl=null,Mh=!1;function vb(t,a,o){var u=o.window===o?o.document:o.nodeType===9?o:o.ownerDocument;Mh||$s==null||$s!==qa(u)||(u=$s,"selectionStart"in u&&Lh(u)?u={start:u.selectionStart,end:u.selectionEnd}:(u=(u.ownerDocument&&u.ownerDocument.defaultView||window).getSelection(),u={anchorNode:u.anchorNode,anchorOffset:u.anchorOffset,focusNode:u.focusNode,focusOffset:u.focusOffset}),dl&&ul(dl,u)||(dl=u,u=Zu($h,"onSelect"),0>=w,p-=w,Xr=1<<32-on(a)+p|o<Qe?(ot=Ie,Ie=null):ot=Ie.sibling;var yt=Q(V,Ie,Y[Qe],oe);if(yt===null){Ie===null&&(Ie=ot);break}t&&Ie&&yt.alternate===null&&a(V,Ie),q=g(yt,q,Qe),mt===null?Pe=yt:mt.sibling=yt,mt=yt,Ie=ot}if(Qe===Y.length)return o(V,Ie),ut&&ga(V,Qe),Pe;if(Ie===null){for(;QeQe?(ot=Ie,Ie=null):ot=Ie.sibling;var mi=Q(V,Ie,yt.value,oe);if(mi===null){Ie===null&&(Ie=ot);break}t&&Ie&&mi.alternate===null&&a(V,Ie),q=g(mi,q,Qe),mt===null?Pe=mi:mt.sibling=mi,mt=mi,Ie=ot}if(yt.done)return o(V,Ie),ut&&ga(V,Qe),Pe;if(Ie===null){for(;!yt.done;Qe++,yt=Y.next())yt=le(V,yt.value,oe),yt!==null&&(q=g(yt,q,Qe),mt===null?Pe=yt:mt.sibling=yt,mt=yt);return ut&&ga(V,Qe),Pe}for(Ie=u(Ie);!yt.done;Qe++,yt=Y.next())yt=te(Ie,V,Qe,yt.value,oe),yt!==null&&(t&&yt.alternate!==null&&Ie.delete(yt.key===null?Qe:yt.key),q=g(yt,q,Qe),mt===null?Pe=yt:mt.sibling=yt,mt=yt);return t&&Ie.forEach(function(xk){return a(V,xk)}),ut&&ga(V,Qe),Pe}function kt(V,q,Y,oe){if(typeof Y=="object"&&Y!==null&&Y.type===x&&Y.key===null&&(Y=Y.props.children),typeof Y=="object"&&Y!==null){switch(Y.$$typeof){case v:e:{for(var Pe=Y.key;q!==null;){if(q.key===Pe){if(Pe=Y.type,Pe===x){if(q.tag===7){o(V,q.sibling),oe=p(q,Y.props.children),oe.return=V,V=oe;break e}}else if(q.elementType===Pe||typeof Pe=="object"&&Pe!==null&&Pe.$$typeof===W&&Yi(Pe)===q.type){o(V,q.sibling),oe=p(q,Y.props),yl(oe,Y),oe.return=V,V=oe;break e}o(V,q);break}else a(V,q);q=q.sibling}Y.type===x?(oe=Gi(Y.props.children,V.mode,oe,Y.key),oe.return=V,V=oe):(oe=mu(Y.type,Y.key,Y.props,null,V.mode,oe),yl(oe,Y),oe.return=V,V=oe)}return w(V);case _:e:{for(Pe=Y.key;q!==null;){if(q.key===Pe)if(q.tag===4&&q.stateNode.containerInfo===Y.containerInfo&&q.stateNode.implementation===Y.implementation){o(V,q.sibling),oe=p(q,Y.children||[]),oe.return=V,V=oe;break e}else{o(V,q);break}else a(V,q);q=q.sibling}oe=Ph(Y,V.mode,oe),oe.return=V,V=oe}return w(V);case W:return Y=Yi(Y),kt(V,q,Y,oe)}if(wt(Y))return De(V,q,Y,oe);if(Ue(Y)){if(Pe=Ue(Y),typeof Pe!="function")throw Error(r(150));return Y=Pe.call(Y),Be(V,q,Y,oe)}if(typeof Y.then=="function")return kt(V,q,Eu(Y),oe);if(Y.$$typeof===k)return kt(V,q,vu(V,Y),oe);_u(V,Y)}return typeof Y=="string"&&Y!==""||typeof Y=="number"||typeof Y=="bigint"?(Y=""+Y,q!==null&&q.tag===6?(o(V,q.sibling),oe=p(q,Y),oe.return=V,V=oe):(o(V,q),oe=Uh(Y,V.mode,oe),oe.return=V,V=oe),w(V)):o(V,q)}return function(V,q,Y,oe){try{ml=0;var Pe=kt(V,q,Y,oe);return Gs=null,Pe}catch(Ie){if(Ie===qs||Ie===wu)throw Ie;var mt=Xn(29,Ie,null,V.mode);return mt.lanes=oe,mt.return=V,mt}}}var Ji=Bb(!0),qb=Bb(!1),Za=!1;function Zh(t){t.updateQueue={baseState:t.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function ep(t,a){t=t.updateQueue,a.updateQueue===t&&(a.updateQueue={baseState:t.baseState,firstBaseUpdate:t.firstBaseUpdate,lastBaseUpdate:t.lastBaseUpdate,shared:t.shared,callbacks:null})}function ei(t){return{lane:t,tag:0,payload:null,callback:null,next:null}}function ti(t,a,o){var u=t.updateQueue;if(u===null)return null;if(u=u.shared,(vt&2)!==0){var p=u.pending;return p===null?a.next=a:(a.next=p.next,p.next=a),u.pending=a,a=gu(t),xb(t,null,o),a}return pu(t,u,a,o),gu(t)}function bl(t,a,o){if(a=a.updateQueue,a!==null&&(a=a.shared,(o&4194048)!==0)){var u=a.lanes;u&=t.pendingLanes,o|=u,a.lanes=o,Ce(t,o)}}function tp(t,a){var o=t.updateQueue,u=t.alternate;if(u!==null&&(u=u.updateQueue,o===u)){var p=null,g=null;if(o=o.firstBaseUpdate,o!==null){do{var w={lane:o.lane,tag:o.tag,payload:o.payload,callback:null,next:null};g===null?p=g=w:g=g.next=w,o=o.next}while(o!==null);g===null?p=g=a:g=g.next=a}else p=g=a;o={baseState:u.baseState,firstBaseUpdate:p,lastBaseUpdate:g,shared:u.shared,callbacks:u.callbacks},t.updateQueue=o;return}t=o.lastBaseUpdate,t===null?o.firstBaseUpdate=a:t.next=a,o.lastBaseUpdate=a}var np=!1;function vl(){if(np){var t=Bs;if(t!==null)throw t}}function Sl(t,a,o,u){np=!1;var p=t.updateQueue;Za=!1;var g=p.firstBaseUpdate,w=p.lastBaseUpdate,R=p.shared.pending;if(R!==null){p.shared.pending=null;var z=R,X=z.next;z.next=null,w===null?g=X:w.next=X,w=z;var re=t.alternate;re!==null&&(re=re.updateQueue,R=re.lastBaseUpdate,R!==w&&(R===null?re.firstBaseUpdate=X:R.next=X,re.lastBaseUpdate=z))}if(g!==null){var le=p.baseState;w=0,re=X=z=null,R=g;do{var Q=R.lane&-536870913,te=Q!==R.lane;if(te?(st&Q)===Q:(u&Q)===Q){Q!==0&&Q===Ps&&(np=!0),re!==null&&(re=re.next={lane:0,tag:R.tag,payload:R.payload,callback:null,next:null});e:{var De=t,Be=R;Q=a;var kt=o;switch(Be.tag){case 1:if(De=Be.payload,typeof De=="function"){le=De.call(kt,le,Q);break e}le=De;break e;case 3:De.flags=De.flags&-65537|128;case 0:if(De=Be.payload,Q=typeof De=="function"?De.call(kt,le,Q):De,Q==null)break e;le=y({},le,Q);break e;case 2:Za=!0}}Q=R.callback,Q!==null&&(t.flags|=64,te&&(t.flags|=8192),te=p.callbacks,te===null?p.callbacks=[Q]:te.push(Q))}else te={lane:Q,tag:R.tag,payload:R.payload,callback:R.callback,next:null},re===null?(X=re=te,z=le):re=re.next=te,w|=Q;if(R=R.next,R===null){if(R=p.shared.pending,R===null)break;te=R,R=te.next,te.next=null,p.lastBaseUpdate=te,p.shared.pending=null}}while(!0);re===null&&(z=le),p.baseState=z,p.firstBaseUpdate=X,p.lastBaseUpdate=re,g===null&&(p.shared.lanes=0),si|=w,t.lanes=w,t.memoizedState=le}}function Gb(t,a){if(typeof t!="function")throw Error(r(191,t));t.call(a)}function Fb(t,a){var o=t.callbacks;if(o!==null)for(t.callbacks=null,t=0;tg?g:8;var w=J.T,R={};J.T=R,wp(t,!1,a,o);try{var z=p(),X=J.S;if(X!==null&&X(R,z),z!==null&&typeof z=="object"&&typeof z.then=="function"){var re=gT(z,u);El(t,a,re,tr(t))}else El(t,a,u,tr(t))}catch(le){El(t,a,{then:function(){},status:"rejected",reason:le},tr())}finally{fe.p=g,w!==null&&R.types!==null&&(w.types=R.types),J.T=w}}function wT(){}function vp(t,a,o,u){if(t.tag!==5)throw Error(r(476));var p=Ev(t).queue;Cv(t,p,a,Le,o===null?wT:function(){return _v(t),o(u)})}function Ev(t){var a=t.memoizedState;if(a!==null)return a;a={memoizedState:Le,baseState:Le,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:va,lastRenderedState:Le},next:null};var o={};return a.next={memoizedState:o,baseState:o,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:va,lastRenderedState:o},next:null},t.memoizedState=a,t=t.alternate,t!==null&&(t.memoizedState=a),a}function _v(t){var a=Ev(t);a.next===null&&(a=t.alternate.memoizedState),El(t,a.next.queue,{},tr())}function Sp(){return vn(Ul)}function Av(){return Yt().memoizedState}function xv(){return Yt().memoizedState}function CT(t){for(var a=t.return;a!==null;){switch(a.tag){case 24:case 3:var o=tr();t=ei(o);var u=ti(a,t,o);u!==null&&(qn(u,a,o),bl(u,a,o)),a={cache:Yh()},t.payload=a;return}a=a.return}}function ET(t,a,o){var u=tr();o={lane:u,revertLane:0,gesture:null,action:o,hasEagerState:!1,eagerState:null,next:null},Mu(t)?kv(a,o):(o=Hh(t,a,o,u),o!==null&&(qn(o,t,u),Rv(o,a,u)))}function Tv(t,a,o){var u=tr();El(t,a,o,u)}function El(t,a,o,u){var p={lane:u,revertLane:0,gesture:null,action:o,hasEagerState:!1,eagerState:null,next:null};if(Mu(t))kv(a,p);else{var g=t.alternate;if(t.lanes===0&&(g===null||g.lanes===0)&&(g=a.lastRenderedReducer,g!==null))try{var w=a.lastRenderedState,R=g(w,o);if(p.hasEagerState=!0,p.eagerState=R,Yn(R,w))return pu(t,a,p,0),Dt===null&&hu(),!1}catch{}if(o=Hh(t,a,p,u),o!==null)return qn(o,t,u),Rv(o,a,u),!0}return!1}function wp(t,a,o,u){if(u={lane:2,revertLane:Zp(),gesture:null,action:u,hasEagerState:!1,eagerState:null,next:null},Mu(t)){if(a)throw Error(r(479))}else a=Hh(t,o,u,2),a!==null&&qn(a,t,2)}function Mu(t){var a=t.alternate;return t===Xe||a!==null&&a===Xe}function kv(t,a){Vs=Tu=!0;var o=t.pending;o===null?a.next=a:(a.next=o.next,o.next=a),t.pending=a}function Rv(t,a,o){if((o&4194048)!==0){var u=a.lanes;u&=t.pendingLanes,o|=u,a.lanes=o,Ce(t,o)}}var _l={readContext:vn,use:Du,useCallback:Gt,useContext:Gt,useEffect:Gt,useImperativeHandle:Gt,useLayoutEffect:Gt,useInsertionEffect:Gt,useMemo:Gt,useReducer:Gt,useRef:Gt,useState:Gt,useDebugValue:Gt,useDeferredValue:Gt,useTransition:Gt,useSyncExternalStore:Gt,useId:Gt,useHostTransitionStatus:Gt,useFormState:Gt,useActionState:Gt,useOptimistic:Gt,useMemoCache:Gt,useCacheRefresh:Gt};_l.useEffectEvent=Gt;var Dv={readContext:vn,use:Du,useCallback:function(t,a){return Ln().memoizedState=[t,a===void 0?null:a],t},useContext:vn,useEffect:hv,useImperativeHandle:function(t,a,o){o=o!=null?o.concat([t]):null,Lu(4194308,4,yv.bind(null,a,t),o)},useLayoutEffect:function(t,a){return Lu(4194308,4,t,a)},useInsertionEffect:function(t,a){Lu(4,2,t,a)},useMemo:function(t,a){var o=Ln();a=a===void 0?null:a;var u=t();if(Qi){_n(!0);try{t()}finally{_n(!1)}}return o.memoizedState=[u,a],u},useReducer:function(t,a,o){var u=Ln();if(o!==void 0){var p=o(a);if(Qi){_n(!0);try{o(a)}finally{_n(!1)}}}else p=a;return u.memoizedState=u.baseState=p,t={pending:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:p},u.queue=t,t=t.dispatch=ET.bind(null,Xe,t),[u.memoizedState,t]},useRef:function(t){var a=Ln();return t={current:t},a.memoizedState=t},useState:function(t){t=pp(t);var a=t.queue,o=Tv.bind(null,Xe,a);return a.dispatch=o,[t.memoizedState,o]},useDebugValue:yp,useDeferredValue:function(t,a){var o=Ln();return bp(o,t,a)},useTransition:function(){var t=pp(!1);return t=Cv.bind(null,Xe,t.queue,!0,!1),Ln().memoizedState=t,[!1,t]},useSyncExternalStore:function(t,a,o){var u=Xe,p=Ln();if(ut){if(o===void 0)throw Error(r(407));o=o()}else{if(o=a(),Dt===null)throw Error(r(349));(st&127)!==0||Jb(u,a,o)}p.memoizedState=o;var g={value:o,getSnapshot:a};return p.queue=g,hv(Zb.bind(null,u,g,t),[t]),u.flags|=2048,Ws(9,{destroy:void 0},Qb.bind(null,u,g,o,a),null),o},useId:function(){var t=Ln(),a=Dt.identifierPrefix;if(ut){var o=Jr,u=Xr;o=(u&~(1<<32-on(u)-1)).toString(32)+o,a="_"+a+"R_"+o,o=ku++,0<\/script>",g=g.removeChild(g.firstChild);break;case"select":g=typeof u.is=="string"?w.createElement("select",{is:u.is}):w.createElement("select"),u.multiple?g.multiple=!0:u.size&&(g.size=u.size);break;default:g=typeof u.is=="string"?w.createElement(p,{is:u.is}):w.createElement(p)}}g[Ht]=a,g[An]=u;e:for(w=a.child;w!==null;){if(w.tag===5||w.tag===6)g.appendChild(w.stateNode);else if(w.tag!==4&&w.tag!==27&&w.child!==null){w.child.return=w,w=w.child;continue}if(w===a)break e;for(;w.sibling===null;){if(w.return===null||w.return===a)break e;w=w.return}w.sibling.return=w.return,w=w.sibling}a.stateNode=g;e:switch(wn(g,p,u),p){case"button":case"input":case"select":case"textarea":u=!!u.autoFocus;break e;case"img":u=!0;break e;default:u=!1}u&&wa(a)}}return $t(a),Np(a,a.type,t===null?null:t.memoizedProps,a.pendingProps,o),null;case 6:if(t&&a.stateNode!=null)t.memoizedProps!==u&&wa(a);else{if(typeof u!="string"&&a.stateNode===null)throw Error(r(166));if(t=ie.current,zs(a)){if(t=a.stateNode,o=a.memoizedProps,u=null,p=bn,p!==null)switch(p.tag){case 27:case 5:u=p.memoizedProps}t[Ht]=a,t=!!(t.nodeValue===o||u!==null&&u.suppressHydrationWarning===!0||YS(t.nodeValue,o)),t||Ja(a,!0)}else t=ed(t).createTextNode(u),t[Ht]=a,a.stateNode=t}return $t(a),null;case 31:if(o=a.memoizedState,t===null||t.memoizedState!==null){if(u=zs(a),o!==null){if(t===null){if(!u)throw Error(r(318));if(t=a.memoizedState,t=t!==null?t.dehydrated:null,!t)throw Error(r(557));t[Ht]=a}else Fi(),(a.flags&128)===0&&(a.memoizedState=null),a.flags|=4;$t(a),t=!1}else o=Fh(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=o),t=!0;if(!t)return a.flags&256?(Qn(a),a):(Qn(a),null);if((a.flags&128)!==0)throw Error(r(558))}return $t(a),null;case 13:if(u=a.memoizedState,t===null||t.memoizedState!==null&&t.memoizedState.dehydrated!==null){if(p=zs(a),u!==null&&u.dehydrated!==null){if(t===null){if(!p)throw Error(r(318));if(p=a.memoizedState,p=p!==null?p.dehydrated:null,!p)throw Error(r(317));p[Ht]=a}else Fi(),(a.flags&128)===0&&(a.memoizedState=null),a.flags|=4;$t(a),p=!1}else p=Fh(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=p),p=!0;if(!p)return a.flags&256?(Qn(a),a):(Qn(a),null)}return Qn(a),(a.flags&128)!==0?(a.lanes=o,a):(o=u!==null,t=t!==null&&t.memoizedState!==null,o&&(u=a.child,p=null,u.alternate!==null&&u.alternate.memoizedState!==null&&u.alternate.memoizedState.cachePool!==null&&(p=u.alternate.memoizedState.cachePool.pool),g=null,u.memoizedState!==null&&u.memoizedState.cachePool!==null&&(g=u.memoizedState.cachePool.pool),g!==p&&(u.flags|=2048)),o!==t&&o&&(a.child.flags|=8192),zu(a,a.updateQueue),$t(a),null);case 4:return Te(),t===null&&rg(a.stateNode.containerInfo),$t(a),null;case 10:return ya(a.type),$t(a),null;case 19:if(T(Wt),u=a.memoizedState,u===null)return $t(a),null;if(p=(a.flags&128)!==0,g=u.rendering,g===null)if(p)xl(u,!1);else{if(Ft!==0||t!==null&&(t.flags&128)!==0)for(t=a.child;t!==null;){if(g=xu(t),g!==null){for(a.flags|=128,xl(u,!1),t=g.updateQueue,a.updateQueue=t,zu(a,t),a.subtreeFlags=0,t=o,o=a.child;o!==null;)Tb(o,t),o=o.sibling;return ce(Wt,Wt.current&1|2),ut&&ga(a,u.treeForkCount),a.child}t=t.sibling}u.tail!==null&&qt()>Gu&&(a.flags|=128,p=!0,xl(u,!1),a.lanes=4194304)}else{if(!p)if(t=xu(g),t!==null){if(a.flags|=128,p=!0,t=t.updateQueue,a.updateQueue=t,zu(a,t),xl(u,!0),u.tail===null&&u.tailMode==="hidden"&&!g.alternate&&!ut)return $t(a),null}else 2*qt()-u.renderingStartTime>Gu&&o!==536870912&&(a.flags|=128,p=!0,xl(u,!1),a.lanes=4194304);u.isBackwards?(g.sibling=a.child,a.child=g):(t=u.last,t!==null?t.sibling=g:a.child=g,u.last=g)}return u.tail!==null?(t=u.tail,u.rendering=t,u.tail=t.sibling,u.renderingStartTime=qt(),t.sibling=null,o=Wt.current,ce(Wt,p?o&1|2:o&1),ut&&ga(a,u.treeForkCount),t):($t(a),null);case 22:case 23:return Qn(a),ap(),u=a.memoizedState!==null,t!==null?t.memoizedState!==null!==u&&(a.flags|=8192):u&&(a.flags|=8192),u?(o&536870912)!==0&&(a.flags&128)===0&&($t(a),a.subtreeFlags&6&&(a.flags|=8192)):$t(a),o=a.updateQueue,o!==null&&zu(a,o.retryQueue),o=null,t!==null&&t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(o=t.memoizedState.cachePool.pool),u=null,a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(u=a.memoizedState.cachePool.pool),u!==o&&(a.flags|=2048),t!==null&&T(Wi),null;case 24:return o=null,t!==null&&(o=t.memoizedState.cache),a.memoizedState.cache!==o&&(a.flags|=2048),ya(Qt),$t(a),null;case 25:return null;case 30:return null}throw Error(r(156,a.tag))}function kT(t,a){switch(qh(a),a.tag){case 1:return t=a.flags,t&65536?(a.flags=t&-65537|128,a):null;case 3:return ya(Qt),Te(),t=a.flags,(t&65536)!==0&&(t&128)===0?(a.flags=t&-65537|128,a):null;case 26:case 27:case 5:return pt(a),null;case 31:if(a.memoizedState!==null){if(Qn(a),a.alternate===null)throw Error(r(340));Fi()}return t=a.flags,t&65536?(a.flags=t&-65537|128,a):null;case 13:if(Qn(a),t=a.memoizedState,t!==null&&t.dehydrated!==null){if(a.alternate===null)throw Error(r(340));Fi()}return t=a.flags,t&65536?(a.flags=t&-65537|128,a):null;case 19:return T(Wt),null;case 4:return Te(),null;case 10:return ya(a.type),null;case 22:case 23:return Qn(a),ap(),t!==null&&T(Wi),t=a.flags,t&65536?(a.flags=t&-65537|128,a):null;case 24:return ya(Qt),null;case 25:return null;default:return null}}function eS(t,a){switch(qh(a),a.tag){case 3:ya(Qt),Te();break;case 26:case 27:case 5:pt(a);break;case 4:Te();break;case 31:a.memoizedState!==null&&Qn(a);break;case 13:Qn(a);break;case 19:T(Wt);break;case 10:ya(a.type);break;case 22:case 23:Qn(a),ap(),t!==null&&T(Wi);break;case 24:ya(Qt)}}function Tl(t,a){try{var o=a.updateQueue,u=o!==null?o.lastEffect:null;if(u!==null){var p=u.next;o=p;do{if((o.tag&t)===t){u=void 0;var g=o.create,w=o.inst;u=g(),w.destroy=u}o=o.next}while(o!==p)}}catch(R){_t(a,a.return,R)}}function ai(t,a,o){try{var u=a.updateQueue,p=u!==null?u.lastEffect:null;if(p!==null){var g=p.next;u=g;do{if((u.tag&t)===t){var w=u.inst,R=w.destroy;if(R!==void 0){w.destroy=void 0,p=a;var z=o,X=R;try{X()}catch(re){_t(p,z,re)}}}u=u.next}while(u!==g)}}catch(re){_t(a,a.return,re)}}function tS(t){var a=t.updateQueue;if(a!==null){var o=t.stateNode;try{Fb(a,o)}catch(u){_t(t,t.return,u)}}}function nS(t,a,o){o.props=Zi(t.type,t.memoizedProps),o.state=t.memoizedState;try{o.componentWillUnmount()}catch(u){_t(t,a,u)}}function kl(t,a){try{var o=t.ref;if(o!==null){switch(t.tag){case 26:case 27:case 5:var u=t.stateNode;break;case 30:u=t.stateNode;break;default:u=t.stateNode}typeof o=="function"?t.refCleanup=o(u):o.current=u}}catch(p){_t(t,a,p)}}function Qr(t,a){var o=t.ref,u=t.refCleanup;if(o!==null)if(typeof u=="function")try{u()}catch(p){_t(t,a,p)}finally{t.refCleanup=null,t=t.alternate,t!=null&&(t.refCleanup=null)}else if(typeof o=="function")try{o(null)}catch(p){_t(t,a,p)}else o.current=null}function rS(t){var a=t.type,o=t.memoizedProps,u=t.stateNode;try{e:switch(a){case"button":case"input":case"select":case"textarea":o.autoFocus&&u.focus();break e;case"img":o.src?u.src=o.src:o.srcSet&&(u.srcset=o.srcSet)}}catch(p){_t(t,t.return,p)}}function Ip(t,a,o){try{var u=t.stateNode;XT(u,t.type,o,a),u[An]=a}catch(p){_t(t,t.return,p)}}function aS(t){return t.tag===5||t.tag===3||t.tag===26||t.tag===27&&di(t.type)||t.tag===4}function jp(t){e:for(;;){for(;t.sibling===null;){if(t.return===null||aS(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;t.tag!==5&&t.tag!==6&&t.tag!==18;){if(t.tag===27&&di(t.type)||t.flags&2||t.child===null||t.tag===4)continue e;t.child.return=t,t=t.child}if(!(t.flags&2))return t.stateNode}}function Hp(t,a,o){var u=t.tag;if(u===5||u===6)t=t.stateNode,a?(o.nodeType===9?o.body:o.nodeName==="HTML"?o.ownerDocument.body:o).insertBefore(t,a):(a=o.nodeType===9?o.body:o.nodeName==="HTML"?o.ownerDocument.body:o,a.appendChild(t),o=o._reactRootContainer,o!=null||a.onclick!==null||(a.onclick=Dr));else if(u!==4&&(u===27&&di(t.type)&&(o=t.stateNode,a=null),t=t.child,t!==null))for(Hp(t,a,o),t=t.sibling;t!==null;)Hp(t,a,o),t=t.sibling}function Uu(t,a,o){var u=t.tag;if(u===5||u===6)t=t.stateNode,a?o.insertBefore(t,a):o.appendChild(t);else if(u!==4&&(u===27&&di(t.type)&&(o=t.stateNode),t=t.child,t!==null))for(Uu(t,a,o),t=t.sibling;t!==null;)Uu(t,a,o),t=t.sibling}function iS(t){var a=t.stateNode,o=t.memoizedProps;try{for(var u=t.type,p=a.attributes;p.length;)a.removeAttributeNode(p[0]);wn(a,u,o),a[Ht]=t,a[An]=o}catch(g){_t(t,t.return,g)}}var Ca=!1,tn=!1,zp=!1,sS=typeof WeakSet=="function"?WeakSet:Set,fn=null;function RT(t,a){if(t=t.containerInfo,sg=od,t=bb(t),Lh(t)){if("selectionStart"in t)var o={start:t.selectionStart,end:t.selectionEnd};else e:{o=(o=t.ownerDocument)&&o.defaultView||window;var u=o.getSelection&&o.getSelection();if(u&&u.rangeCount!==0){o=u.anchorNode;var p=u.anchorOffset,g=u.focusNode;u=u.focusOffset;try{o.nodeType,g.nodeType}catch{o=null;break e}var w=0,R=-1,z=-1,X=0,re=0,le=t,Q=null;t:for(;;){for(var te;le!==o||p!==0&&le.nodeType!==3||(R=w+p),le!==g||u!==0&&le.nodeType!==3||(z=w+u),le.nodeType===3&&(w+=le.nodeValue.length),(te=le.firstChild)!==null;)Q=le,le=te;for(;;){if(le===t)break t;if(Q===o&&++X===p&&(R=w),Q===g&&++re===u&&(z=w),(te=le.nextSibling)!==null)break;le=Q,Q=le.parentNode}le=te}o=R===-1||z===-1?null:{start:R,end:z}}else o=null}o=o||{start:0,end:0}}else o=null;for(og={focusedElem:t,selectionRange:o},od=!1,fn=a;fn!==null;)if(a=fn,t=a.child,(a.subtreeFlags&1028)!==0&&t!==null)t.return=a,fn=t;else for(;fn!==null;){switch(a=fn,g=a.alternate,t=a.flags,a.tag){case 0:if((t&4)!==0&&(t=a.updateQueue,t=t!==null?t.events:null,t!==null))for(o=0;o title"))),wn(g,u,o),g[Ht]=t,Jt(g),u=g;break e;case"link":var w=fw("link","href",p).get(u+(o.href||""));if(w){for(var R=0;Rkt&&(w=kt,kt=Be,Be=w);var V=mb(R,Be),q=mb(R,kt);if(V&&q&&(te.rangeCount!==1||te.anchorNode!==V.node||te.anchorOffset!==V.offset||te.focusNode!==q.node||te.focusOffset!==q.offset)){var Y=le.createRange();Y.setStart(V.node,V.offset),te.removeAllRanges(),Be>kt?(te.addRange(Y),te.extend(q.node,q.offset)):(Y.setEnd(q.node,q.offset),te.addRange(Y))}}}}for(le=[],te=R;te=te.parentNode;)te.nodeType===1&&le.push({element:te,left:te.scrollLeft,top:te.scrollTop});for(typeof R.focus=="function"&&R.focus(),R=0;Ro?32:o,J.T=null,o=Vp,Vp=null;var g=li,w=Ta;if(cn=0,Zs=li=null,Ta=0,(vt&6)!==0)throw Error(r(331));var R=vt;if(vt|=4,yS(g.current),pS(g,g.current,w,o),vt=R,Ml(0,!1),sn&&typeof sn.onPostCommitFiberRoot=="function")try{sn.onPostCommitFiberRoot(lr,g)}catch{}return!0}finally{fe.p=p,J.T=u,NS(t,a)}}function jS(t,a,o){a=dr(o,a),a=Ap(t.stateNode,a,2),t=ti(t,a,2),t!==null&&(et(t,2),Zr(t))}function _t(t,a,o){if(t.tag===3)jS(t,t,o);else for(;a!==null;){if(a.tag===3){jS(a,t,o);break}else if(a.tag===1){var u=a.stateNode;if(typeof a.type.getDerivedStateFromError=="function"||typeof u.componentDidCatch=="function"&&(oi===null||!oi.has(u))){t=dr(o,t),o=Hv(2),u=ti(a,o,2),u!==null&&(zv(o,u,a,t),et(u,2),Zr(u));break}}a=a.return}}function Xp(t,a,o){var u=t.pingCache;if(u===null){u=t.pingCache=new LT;var p=new Set;u.set(a,p)}else p=u.get(a),p===void 0&&(p=new Set,u.set(a,p));p.has(o)||(Bp=!0,p.add(o),t=jT.bind(null,t,a,o),a.then(t,t))}function jT(t,a,o){var u=t.pingCache;u!==null&&u.delete(a),t.pingedLanes|=t.suspendedLanes&o,t.warmLanes&=~o,Dt===t&&(st&o)===o&&(Ft===4||Ft===3&&(st&62914560)===st&&300>qt()-qu?(vt&2)===0&&eo(t,0):qp|=o,Qs===st&&(Qs=0)),Zr(t)}function HS(t,a){a===0&&(a=Ne()),t=qi(t,a),t!==null&&(et(t,a),Zr(t))}function HT(t){var a=t.memoizedState,o=0;a!==null&&(o=a.retryLane),HS(t,o)}function zT(t,a){var o=0;switch(t.tag){case 31:case 13:var u=t.stateNode,p=t.memoizedState;p!==null&&(o=p.retryLane);break;case 19:u=t.stateNode;break;case 22:u=t.stateNode._retryCache;break;default:throw Error(r(314))}u!==null&&u.delete(a),HS(t,o)}function UT(t,a){return an(t,a)}var Xu=null,no=null,Jp=!1,Ju=!1,Qp=!1,ui=0;function Zr(t){t!==no&&t.next===null&&(no===null?Xu=no=t:no=no.next=t),Ju=!0,Jp||(Jp=!0,BT())}function Ml(t,a){if(!Qp&&Ju){Qp=!0;do for(var o=!1,u=Xu;u!==null;){if(t!==0){var p=u.pendingLanes;if(p===0)var g=0;else{var w=u.suspendedLanes,R=u.pingedLanes;g=(1<<31-on(42|t)+1)-1,g&=p&~(w&~R),g=g&201326741?g&201326741|1:g?g|2:0}g!==0&&(o=!0,BS(u,g))}else g=st,g=Ae(u,u===Dt?g:0,u.cancelPendingCommit!==null||u.timeoutHandle!==-1),(g&3)===0||Ve(u,g)||(o=!0,BS(u,g));u=u.next}while(o);Qp=!1}}function PT(){zS()}function zS(){Ju=Jp=!1;var t=0;ui!==0&&QT()&&(t=ui);for(var a=qt(),o=null,u=Xu;u!==null;){var p=u.next,g=US(u,a);g===0?(u.next=null,o===null?Xu=p:o.next=p,p===null&&(no=o)):(o=u,(t!==0||(g&3)!==0)&&(Ju=!0)),u=p}cn!==0&&cn!==5||Ml(t),ui!==0&&(ui=0)}function US(t,a){for(var o=t.suspendedLanes,u=t.pingedLanes,p=t.expirationTimes,g=t.pendingLanes&-62914561;0R)break;var re=z.transferSize,le=z.initiatorType;re&&XS(le)&&(z=z.responseEnd,w+=re*(z"u"?null:document;function lw(t,a,o){var u=ro;if(u&&typeof a=="string"&&a){var p=Hn(a);p='link[rel="'+t+'"][href="'+p+'"]',typeof o=="string"&&(p+='[crossorigin="'+o+'"]'),ow.has(p)||(ow.add(p),t={rel:t,crossOrigin:o,href:a},u.querySelector(p)===null&&(a=u.createElement("link"),wn(a,"link",t),Jt(a),u.head.appendChild(a)))}}function ok(t){ka.D(t),lw("dns-prefetch",t,null)}function lk(t,a){ka.C(t,a),lw("preconnect",t,a)}function ck(t,a,o){ka.L(t,a,o);var u=ro;if(u&&t&&a){var p='link[rel="preload"][as="'+Hn(a)+'"]';a==="image"&&o&&o.imageSrcSet?(p+='[imagesrcset="'+Hn(o.imageSrcSet)+'"]',typeof o.imageSizes=="string"&&(p+='[imagesizes="'+Hn(o.imageSizes)+'"]')):p+='[href="'+Hn(t)+'"]';var g=p;switch(a){case"style":g=ao(t);break;case"script":g=io(t)}yr.has(g)||(t=y({rel:"preload",href:a==="image"&&o&&o.imageSrcSet?void 0:t,as:a},o),yr.set(g,t),u.querySelector(p)!==null||a==="style"&&u.querySelector(Hl(g))||a==="script"&&u.querySelector(zl(g))||(a=u.createElement("link"),wn(a,"link",t),Jt(a),u.head.appendChild(a)))}}function uk(t,a){ka.m(t,a);var o=ro;if(o&&t){var u=a&&typeof a.as=="string"?a.as:"script",p='link[rel="modulepreload"][as="'+Hn(u)+'"][href="'+Hn(t)+'"]',g=p;switch(u){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":g=io(t)}if(!yr.has(g)&&(t=y({rel:"modulepreload",href:t},a),yr.set(g,t),o.querySelector(p)===null)){switch(u){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(o.querySelector(zl(g)))return}u=o.createElement("link"),wn(u,"link",t),Jt(u),o.head.appendChild(u)}}}function dk(t,a,o){ka.S(t,a,o);var u=ro;if(u&&t){var p=Pa(u).hoistableStyles,g=ao(t);a=a||"default";var w=p.get(g);if(!w){var R={loading:0,preload:null};if(w=u.querySelector(Hl(g)))R.loading=5;else{t=y({rel:"stylesheet",href:t,"data-precedence":a},o),(o=yr.get(g))&&pg(t,o);var z=w=u.createElement("link");Jt(z),wn(z,"link",t),z._p=new Promise(function(X,re){z.onload=X,z.onerror=re}),z.addEventListener("load",function(){R.loading|=1}),z.addEventListener("error",function(){R.loading|=2}),R.loading|=4,nd(w,a,u)}w={type:"stylesheet",instance:w,count:1,state:R},p.set(g,w)}}}function fk(t,a){ka.X(t,a);var o=ro;if(o&&t){var u=Pa(o).hoistableScripts,p=io(t),g=u.get(p);g||(g=o.querySelector(zl(p)),g||(t=y({src:t,async:!0},a),(a=yr.get(p))&&gg(t,a),g=o.createElement("script"),Jt(g),wn(g,"link",t),o.head.appendChild(g)),g={type:"script",instance:g,count:1,state:null},u.set(p,g))}}function hk(t,a){ka.M(t,a);var o=ro;if(o&&t){var u=Pa(o).hoistableScripts,p=io(t),g=u.get(p);g||(g=o.querySelector(zl(p)),g||(t=y({src:t,async:!0,type:"module"},a),(a=yr.get(p))&&gg(t,a),g=o.createElement("script"),Jt(g),wn(g,"link",t),o.head.appendChild(g)),g={type:"script",instance:g,count:1,state:null},u.set(p,g))}}function cw(t,a,o,u){var p=(p=ie.current)?td(p):null;if(!p)throw Error(r(446));switch(t){case"meta":case"title":return null;case"style":return typeof o.precedence=="string"&&typeof o.href=="string"?(a=ao(o.href),o=Pa(p).hoistableStyles,u=o.get(a),u||(u={type:"style",instance:null,count:0,state:null},o.set(a,u)),u):{type:"void",instance:null,count:0,state:null};case"link":if(o.rel==="stylesheet"&&typeof o.href=="string"&&typeof o.precedence=="string"){t=ao(o.href);var g=Pa(p).hoistableStyles,w=g.get(t);if(w||(p=p.ownerDocument||p,w={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},g.set(t,w),(g=p.querySelector(Hl(t)))&&!g._p&&(w.instance=g,w.state.loading=5),yr.has(t)||(o={rel:"preload",as:"style",href:o.href,crossOrigin:o.crossOrigin,integrity:o.integrity,media:o.media,hrefLang:o.hrefLang,referrerPolicy:o.referrerPolicy},yr.set(t,o),g||pk(p,t,o,w.state))),a&&u===null)throw Error(r(528,""));return w}if(a&&u!==null)throw Error(r(529,""));return null;case"script":return a=o.async,o=o.src,typeof o=="string"&&a&&typeof a!="function"&&typeof a!="symbol"?(a=io(o),o=Pa(p).hoistableScripts,u=o.get(a),u||(u={type:"script",instance:null,count:0,state:null},o.set(a,u)),u):{type:"void",instance:null,count:0,state:null};default:throw Error(r(444,t))}}function ao(t){return'href="'+Hn(t)+'"'}function Hl(t){return'link[rel="stylesheet"]['+t+"]"}function uw(t){return y({},t,{"data-precedence":t.precedence,precedence:null})}function pk(t,a,o,u){t.querySelector('link[rel="preload"][as="style"]['+a+"]")?u.loading=1:(a=t.createElement("link"),u.preload=a,a.addEventListener("load",function(){return u.loading|=1}),a.addEventListener("error",function(){return u.loading|=2}),wn(a,"link",o),Jt(a),t.head.appendChild(a))}function io(t){return'[src="'+Hn(t)+'"]'}function zl(t){return"script[async]"+t}function dw(t,a,o){if(a.count++,a.instance===null)switch(a.type){case"style":var u=t.querySelector('style[data-href~="'+Hn(o.href)+'"]');if(u)return a.instance=u,Jt(u),u;var p=y({},o,{"data-href":o.href,"data-precedence":o.precedence,href:null,precedence:null});return u=(t.ownerDocument||t).createElement("style"),Jt(u),wn(u,"style",p),nd(u,o.precedence,t),a.instance=u;case"stylesheet":p=ao(o.href);var g=t.querySelector(Hl(p));if(g)return a.state.loading|=4,a.instance=g,Jt(g),g;u=uw(o),(p=yr.get(p))&&pg(u,p),g=(t.ownerDocument||t).createElement("link"),Jt(g);var w=g;return w._p=new Promise(function(R,z){w.onload=R,w.onerror=z}),wn(g,"link",u),a.state.loading|=4,nd(g,o.precedence,t),a.instance=g;case"script":return g=io(o.src),(p=t.querySelector(zl(g)))?(a.instance=p,Jt(p),p):(u=o,(p=yr.get(g))&&(u=y({},o),gg(u,p)),t=t.ownerDocument||t,p=t.createElement("script"),Jt(p),wn(p,"link",u),t.head.appendChild(p),a.instance=p);case"void":return null;default:throw Error(r(443,a.type))}else a.type==="stylesheet"&&(a.state.loading&4)===0&&(u=a.instance,a.state.loading|=4,nd(u,o.precedence,t));return a.instance}function nd(t,a,o){for(var u=o.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),p=u.length?u[u.length-1]:null,g=p,w=0;w title"):null)}function gk(t,a,o){if(o===1||a.itemProp!=null)return!1;switch(t){case"meta":case"title":return!0;case"style":if(typeof a.precedence!="string"||typeof a.href!="string"||a.href==="")break;return!0;case"link":if(typeof a.rel!="string"||typeof a.href!="string"||a.href===""||a.onLoad||a.onError)break;return a.rel==="stylesheet"?(t=a.disabled,typeof a.precedence=="string"&&t==null):!0;case"script":if(a.async&&typeof a.async!="function"&&typeof a.async!="symbol"&&!a.onLoad&&!a.onError&&a.src&&typeof a.src=="string")return!0}return!1}function pw(t){return!(t.type==="stylesheet"&&(t.state.loading&3)===0)}function mk(t,a,o,u){if(o.type==="stylesheet"&&(typeof u.media!="string"||matchMedia(u.media).matches!==!1)&&(o.state.loading&4)===0){if(o.instance===null){var p=ao(u.href),g=a.querySelector(Hl(p));if(g){a=g._p,a!==null&&typeof a=="object"&&typeof a.then=="function"&&(t.count++,t=ad.bind(t),a.then(t,t)),o.state.loading|=4,o.instance=g,Jt(g);return}g=a.ownerDocument||a,u=uw(u),(p=yr.get(p))&&pg(u,p),g=g.createElement("link"),Jt(g);var w=g;w._p=new Promise(function(R,z){w.onload=R,w.onerror=z}),wn(g,"link",u),o.instance=g}t.stylesheets===null&&(t.stylesheets=new Map),t.stylesheets.set(o,a),(a=o.state.preload)&&(o.state.loading&3)===0&&(t.count++,o=ad.bind(t),a.addEventListener("load",o),a.addEventListener("error",o))}}var mg=0;function yk(t,a){return t.stylesheets&&t.count===0&&sd(t,t.stylesheets),0mg?50:800)+a);return t.unsuspend=o,function(){t.unsuspend=null,clearTimeout(u),clearTimeout(p)}}:null}function ad(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)sd(this,this.stylesheets);else if(this.unsuspend){var t=this.unsuspend;this.unsuspend=null,t()}}}var id=null;function sd(t,a){t.stylesheets=null,t.unsuspend!==null&&(t.count++,id=new Map,a.forEach(bk,t),id=null,ad.call(t))}function bk(t,a){if(!(a.state.loading&4)){var o=id.get(t);if(o)var u=o.get(null);else{o=new Map,id.set(t,o);for(var p=t.querySelectorAll("link[data-precedence],style[data-precedence]"),g=0;g"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(s)}catch(e){console.error(e)}}return s(),md.exports=Nw(),md.exports}var Sd=Iw();const wd=ta(Sd),lo=[],jw=50;let Cd=!1;function Lg(){try{return window.G7Core?.devTools}catch{return}}function ns(s,e,n){const r=Lg();if(Cd&&r?.isEnabled?.()){r.trackLog?.(s,e,n);return}Cd||(s==="error"||s==="warn")&&lo.length{n.isDebugEnabled()&&console.log(e,...r),ns("log",s,r)},warn:(...r)=>{n.isDebugEnabled()&&console.warn(e,...r),ns("warn",s,r)},error:(...r)=>{n.isDebugEnabled()&&console.error(e,...r),ns("error",s,r)}}}co.getInstance();const $g="extension",rs="extensionless",Mg="file";function Hw(){const s=globalThis?.G7Config;if(globalThis?.__g7AssetUrlMode===rs)return rs;const n=s?.assetUrlMode;return n===rs||n===$g?n:s?.settings?.general?.asset_url_mode===rs?rs:$g}function _d(){return Hw()===rs}function zw(s,e,n){return Ad("templates",s,e,n)}function Uw(s,e){const n=e.replace(/^\/+/,"").replace(/\/+$/,""),r=encodeURIComponent(s),i=uo(`templates/${s}/assets/${n}`);return i!==null?i:`/api/templates/assets/${r}/${n}`}function Pw(s,e,n){return Ad("modules",s,e,n)}function Bw(s,e,n){return Ad("plugins",s,e,n)}function Ad(s,e,n,r){const i=n.replace(/^\/+/,""),l=encodeURIComponent(e);if(!_d())return`/api/${s}/assets/${l}/${i}${Fw(r)}`;let c=`${Mg}=${encodeURIComponent(i)}`;return r!=null&&r!==""&&(c+=`&v=${r}`),`/api/${s}/assets/${l}?${c}`}function jr(s,e,n,r){const i=s.replace(/\/+$/,""),l=e.replace(/^\.+/,""),c=_d()?i:`${i}.${l}`,d=[];return r&&d.push(r.replace(/^[?&]+/,"")),n!=null&&n!==""&&d.push(`v=${n}`),d.length>0?`${c}?${d.join("&")}`:c}function Ng(){const s=globalThis?.G7Config?.staticBase;return typeof s=="string"&&s!==""?s.replace(/\/+$/,""):null}function qw(){const s=Ng();if(!s)return null;const e=s.match(/\/(\d+)$/);return e?Number(e[1]):null}function uo(s,e){const n=Ng();if(!n)return null;const r=s.replace(/^\/+/,"");return e!==void 0&&e>0&&e!==qw()?`${n.replace(/\/\d+$/,"")}/${e}/${r}`:`${n}/${r}`}function xd(s){if(!s)return null;const e=globalThis?.location?.origin,r=(e&&s.startsWith(e)?s.slice(e.length):s).match(/^\/build\/ext\/(\d+)\/(.+)$/);if(!r)return null;const i=r[1],l=r[2].split("?")[0],c=l.match(/^(templates|modules|plugins)\/([^/]+)\/assets\/(.+)$/);if(c){const[,h,m,y]=c;return`/api/${h}/assets/${m}/${y}?v=${i}`}const d=l.match(/^bundles\/(modules|plugins)\.(js|css)$/);if(d)return`/api/${d[1]}/bundle.${d[2]}?v=${i}`;const f=l.match(/^templates\/([^/]+)\/(routes\.json|components\.json|lang\/([a-zA-Z-]+)\.json)$/);if(f){const[,h,m]=f,y=m.replace(/\.json$/,"");return`/api/templates/${h}/${y}.json?v=${i}`}return null}function Tn(s){if(!s||!_d())return s;const e=globalThis?.location?.origin,n=e&&s.startsWith(e)?s.slice(e.length):s;if(!n.startsWith("/api/"))return s;const[r,i]=Gw(n),l=r.match(/^\/api\/(modules|plugins)\/bundle\.(js|css)$/);if(l)return Ig(`/api/${l[1]}/bundle/${l[2]}`,i);const c=r.match(/^\/api\/(templates|modules|plugins)\/assets\/([^/]+)\/(.+)$/);if(c){const[,f,h,m]=c,y=`${Mg}=${encodeURIComponent(decodeURIComponent(m))}`;return`/api/${f}/assets/${h}?${y}${i?`&${i}`:""}`}const d=r.match(/^(\/api\/.+)\.(json|js|css)$/);return d?Ig(d[1],i):s}function Gw(s){const e=s.indexOf("?");return e===-1?[s,""]:[s.slice(0,e),s.slice(e+1)]}function Ig(s,e){return e?`${s}?${e}`:s}function Fw(s){return s==null||s===""?"":`?v=${s}`}const na=dt("networkResilience"),Td=2,kd=300,Rd=2e3,Vw=15e3;function Dd(s){return s?.name==="AbortError"}function jg(s){return Dd(s)?!1:s instanceof TypeError}let Gl=!1,Hg=!1;function Fl(){return Gl}function Kw(){typeof window>"u"||Hg||(Hg=!0,window.addEventListener("pagehide",()=>{Gl=!0}),window.addEventListener("pageshow",s=>{s.persisted&&(Gl=!1)}),window.addEventListener("beforeunload",()=>{Gl=!0}))}function Od(s,e,n){const r=Math.min(e*Math.pow(2,s),n),i=r*.25*(Math.random()*2-1);return Math.max(0,Math.round(r+i))}function Ld(s){return new Promise(e=>setTimeout(e,s))}async function $d(s,e={}){const{retries:n=Td,baseDelayMs:r=kd,maxDelayMs:i=Rd,timeoutMs:l=Vw,label:c=s,init:d}=e,f=n+1;let h;for(let m=0;m0?new AbortController:null;try{const _={...d};if(v){const A=d?.signal;A&&(A.aborted?v.abort():A.addEventListener("abort",()=>v.abort(),{once:!0})),_.signal=v.signal,S=setTimeout(()=>{y=!0,v.abort()},l)}return await fetch(s,_)}catch(_){if(h=_,Dd(_)&&!y||!(y||jg(_)))throw _;if(Fl())throw na.warn(`Document unloading, aborting retries: ${c}`),_;if(m===f-1)throw na.warn(`All ${f} attempts failed: ${c}`,_),_;const L=Od(m,r,i);na.warn(`Network failure (attempt ${m+1}/${f}), retrying in ${L}ms: ${c}`),await Ld(L)}finally{S!==void 0&&clearTimeout(S)}}throw h}async function ra(s,e={},n={}){const{retries:r=Td,baseDelayMs:i=kd,maxDelayMs:l=Rd,label:c=s}=n,d=r+1;for(let f=0;f{const i=document.createElement("script");i.src=s,i.async=!1;for(const[l,c]of Object.entries(e))l==="id"?i.id=c:i.setAttribute(l,c);i.onload=()=>n(),i.onerror=()=>r(new Error(`Failed to load script: ${s}`)),document.head.appendChild(i)})}async function yi(s,e={},n={}){const{retries:r=Td,baseDelayMs:i=kd,maxDelayMs:l=Rd,label:c=s}=n,d=r+1;for(let f=0;f{s.onload=()=>e(),s.onerror=()=>n(new Error(`Failed to load stylesheet: ${s.href}`))})}async function Vl(s,e,n={}){if(!s)return $d(e,n);try{const r=await fetch(s,n.init);if(r.ok)return r;console.warn(`[fetchStaticFirst] Static fast path miss (${r.status}) — falling back to API: ${s}`)}catch(r){console.warn(`[fetchStaticFirst] Static fast path fetch failed — falling back to API: ${s}`,r)}return $d(e,n)}const Hr=dt("ComponentRegistry");class un extends Error{constructor(n,r,i){super(n);M(this,"code");M(this,"details");this.code=r,this.details=i,this.name="ComponentRegistryError"}}const Kn=class Kn{constructor(){M(this,"registry",{});M(this,"manifest",null);M(this,"cacheVersion",0);M(this,"loadingState","idle");M(this,"error",null);M(this,"templateId",null);M(this,"templateType",null)}static getInstance(){return Kn.instance||(Kn.instance=new Kn),Kn.instance}static createIsolatedInstance(){return new Kn}static resetInstance(){Kn.instance=null}async loadComponents(e,n,r=0){if(this.loadingState==="loading")throw new un("Components are already being loaded","LOADING_IN_PROGRESS");if(this.loadingState==="loaded"&&this.templateId===e&&this.templateType===n){Hr.log("Components already loaded for template:",e,n);return}this.loadingState="loading",this.templateId=e,this.templateType=n,this.cacheVersion=r,this.error=null;try{await this.loadManifest(),await this.loadComponentBundle(),this.loadingState="loaded",Hr.log("Successfully loaded components:",Object.keys(this.registry).length)}catch(i){throw this.loadingState="error",this.error=i instanceof Error?i:new Error(String(i)),new un(`Failed to load components: ${this.error.message}`,"LOAD_FAILED",{originalError:this.error})}}async loadManifest(){try{if(!this.templateId)throw new un("Template ID not set","TEMPLATE_ID_NOT_SET");const e=`${this.templateId}:${this.templateType}:v${this.cacheVersion||0}`;if(Kn.manifestCache.has(e)){this.manifest=Kn.manifestCache.get(e),Hr.log("Manifest loaded from cache:",this.manifest.templateId);return}const n=jr(`/api/templates/${this.templateId}/components`,"json",this.cacheVersion>0?this.cacheVersion:null),r=await Vl(this.cacheVersion>0?uo(`templates/${this.templateId}/components.json`,this.cacheVersion):null,n,{label:"components.json"});if(!r.ok)throw new un(`Failed to fetch manifest: ${r.status} ${r.statusText}`,"MANIFEST_FETCH_FAILED",{status:r.status,statusText:r.statusText});const i=await r.json();this.validateManifest(i),this.manifest=i,Kn.manifestCache.set(e,i),Hr.log("Manifest loaded and cached:",i.templateId)}catch(e){throw e instanceof un?e:new un("Failed to load component manifest","MANIFEST_LOAD_FAILED",{originalError:e})}}validateManifest(e){if(!e.version)throw new un("Manifest missing required field: version","MANIFEST_INVALID",{field:"version"});if(!e.templateId)throw new un("Manifest missing required field: templateId","MANIFEST_INVALID",{field:"templateId"});if(!e.components||typeof e.components!="object")throw new un("Manifest missing required field: components","MANIFEST_INVALID",{field:"components"});const n=["basic","composite","layout"];for(const r of n){if(!Array.isArray(e.components[r]))throw new un(`Manifest field 'components.${r}' must be an array`,"MANIFEST_INVALID",{field:`components.${r}`,value:e.components[r]});e.components[r].forEach((i,l)=>{if(!i.name||typeof i.name!="string")throw new un(`Invalid component metadata at ${r}[${l}]: missing or invalid 'name'`,"MANIFEST_INVALID",{type:r,index:l,metadata:i});if(!i.type||typeof i.type!="string")throw new un(`Invalid component metadata at ${r}[${l}]: missing or invalid 'type'`,"MANIFEST_INVALID",{type:r,index:l,metadata:i})})}Hr.log("Manifest validation passed")}async loadComponentBundle(){try{if(!this.templateId)throw new un("Template ID not set","TEMPLATE_ID_NOT_SET");const e=this.getGlobalVariableName(),n=window[e];if(!n||typeof n!="object")throw new un(`Component bundle not loaded. Expected global variable: ${e}. Ensure admin.blade.php includes the IIFE bundle script.`,"BUNDLE_NOT_LOADED",{expectedVariable:e});await this.registerComponentsFromManifest(n),Hr.log("Component bundle loaded from global variable:",e)}catch(e){throw e instanceof un?e:new un("Failed to load component bundle","BUNDLE_LOAD_FAILED",{originalError:e})}}getGlobalVariableName(){if(!this.templateId)throw new un("Template ID not set","TEMPLATE_ID_NOT_SET");return this.templateId.split(/[-_]/).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}async registerComponentsFromManifest(e){if(!this.manifest)throw new un("Manifest not loaded","MANIFEST_NOT_LOADED");const n=["basic","composite","layout"];for(const r of n){const i=this.manifest.components[r]||[];for(const l of i){const c=l.name,d=e[c];if(!d){Hr.warn(`Component '${c}' not found in bundle`);continue}this.registerComponent(c,d,l)}}}registerComponent(e,n,r){this.registry[e]&&Hr.warn(`Component '${e}' already registered, overwriting`);const i=Ye.memo(n);this.registry[e]={component:i,metadata:r},Hr.log(`[ComponentRegistry] Registered component: ${e} (${r.type})`)}getComponent(e){const n=this.registry[e];return n?n.component:null}getMetadata(e){const n=this.registry[e];return n?n.metadata:null}hasComponent(e){return e in this.registry}getComponentsByType(e){return Object.entries(this.registry).filter(([n,r])=>r.metadata.type===e).map(([n,r])=>n)}getAllComponents(){return Object.keys(this.registry)}getComponentMap(){const e={};for(const[n,r]of Object.entries(this.registry))e[n]=r.component;return e}getLoadingState(){return this.loadingState}getError(){return this.error}getTemplateId(){return this.templateId}getManifest(){return this.manifest}clear(){this.registry={},this.manifest=null,this.loadingState="idle",this.error=null,this.templateId=null,this.templateType=null,Hr.log("Registry cleared")}};M(Kn,"instance",null),M(Kn,"manifestCache",new Map);let br=Kn;const zg=dt("TranslationEngine");class Md extends Error{constructor(n,r,i){super(n);M(this,"key");M(this,"locale");this.key=r,this.locale=i,this.name="TranslationError"}}const Nn=class Nn{constructor(e={}){M(this,"cache",new Map);M(this,"translations",new Map);M(this,"options");M(this,"cacheVersion",0);this.options={defaultLocale:e.defaultLocale||"ko",fallbackLocale:e.fallbackLocale||"en",cacheTTL:e.cacheTTL||3e5}}static getInstance(e={}){return Nn.instance||(Nn.instance=new Nn(e)),Nn.instance}static resetInstance(){Nn.instance=null}setCacheVersion(e){this.cacheVersion!==e&&(zg.log("Cache version updated:",this.cacheVersion,"->",e),this.cacheVersion=e,this.cache.clear())}getCacheVersion(){return this.cacheVersion}async loadTranslations(e,n,r="/api",i=!1){const l=`${e}:${n}`;if(!i){const c=this.getFromCache(l);if(c)return this.translations.set(l,c),c}try{const c=[];i&&c.push(`_=${Date.now()}`);const d=jr(`${r}/templates/${e}/lang/${n}`,"json",this.cacheVersion>0?this.cacheVersion:null,c.length>0?c.join("&"):void 0),f=!i&&this.cacheVersion>0?uo(`templates/${e}/lang/${n}.json`,this.cacheVersion):null,h=f!==null?await Vl(f,d,{label:`lang/${n}.json`}):await fetch(d);if(!h.ok)throw new Md(`Failed to load translations: ${h.statusText}`,void 0,n);const y=await h.json();return this.saveToCache(l,y),this.translations.set(l,y),y}catch(c){throw new Md(`Failed to fetch translations for ${n}: ${c instanceof Error?c.message:String(c)}`,void 0,n)}}resolveTranslations(e,n,r){let i=e;const l=5;let c=0;for(;c"="+this.translate(m,n,void 0,r)),i===d)break;c++}return i.replace(Nn.TRANSLATION_PATTERN,(d,f,h)=>{const{cleanedParams:m,trailing:y}=this.separateTrailingText(h);return this.translate(f,n,m,r)+y})}translate(e,n,r,i){const l=this.getTranslation(e,n),c=r&&this.cleanParamsStr(r);if(c){const d=this.parseParams(c,i);return this.replaceParams(l,d)}return l}getTranslation(e,n){const{templateId:r,locale:i}=n,l=`${r}:${i}`,c=this.translations.get(l);if(c){const d=this.getNestedValue(c,e);if(d!==null)return d}if(i!==this.options.fallbackLocale){const d=`${r}:${this.options.fallbackLocale}`,f=this.translations.get(d);if(f){const h=this.getNestedValue(f,e);if(h!==null)return h}}return e}getNestedValue(e,n){const r=n.split(".");let i=e;for(const l of r){if(i==null||typeof i!="object")return null;i=i[l]}return typeof i=="string"?i:null}setTranslationValue(e,n,r,i){const l=`${e}:${n}`,c=this.translations.get(l)??{},d=r.split(".");let f=c;for(let h=0;h(l.push(f),`__PLACEHOLDER_${l.length-1}__`)).matchAll(Nn.PARAM_PATTERN);for(const f of d){const[,h,m]=f,y=m.replace(/__PLACEHOLDER_(\d+)__/g,(S,v)=>l[parseInt(v,10)]);r[h.trim()]=this.resolveParamValue(y.trim(),n)}return r}resolveParamValue(e,n){if(e.startsWith("{{")&&e.endsWith("}}")){const r=e.slice(2,-2).trim();if(/[|&()[\]!?:+\-*/%<>=\s]/.test(r)&&n)try{const l=Xd.evaluateExpression(r,n);return String(l??"")}catch(l){return zg.error("Expression evaluation failed:",r,l),""}else{const l=this.getNestedDataValue(n,r);return String(l??"")}}return e}separateTrailingText(e){if(!e)return{cleanedParams:void 0,trailing:""};if(e.trimEnd().endsWith("}}"))return{cleanedParams:e,trailing:""};if(!(e.startsWith("|")?e.slice(1):e).includes("="))return{cleanedParams:void 0,trailing:e};const r=e.match(/(\s+[^\p{L}\w=|&\s][^\p{L}\w=]*\s*)$/u);return r?{cleanedParams:e.slice(0,-r[1].length),trailing:r[1]}:{cleanedParams:e,trailing:""}}cleanParamsStr(e){return this.separateTrailingText(e).cleanedParams||""}getNestedDataValue(e,n){if(!e)return;const r=n.split(".");let i=e;for(const l of r){if(i==null)return;i=i[l]}return i}replaceParams(e,n){let r=e;for(const[i,l]of Object.entries(n)){const c=new RegExp(`\\{\\{${i}\\}\\}`,"g");r=r.replace(c,String(l));const d=new RegExp(`\\{${i}\\}`,"g");r=r.replace(d,String(l))}return r}getFromCache(e){const n=this.cache.get(e);return n?Date.now()-n.timestamp>this.options.cacheTTL?(this.cache.delete(e),null):n.data:null}saveToCache(e,n){this.cache.set(e,{data:n,timestamp:Date.now()})}clearCache(){this.cache.clear(),this.translations.clear()}pruneCache(){const e=Date.now(),n=[];for(const[r,i]of this.cache.entries())e-i.timestamp>this.options.cacheTTL&&n.push(r);for(const r of n)this.cache.delete(r)}getCacheStats(){const e=Date.now();let n=0;for(const r of this.cache.values())e-r.timestamp>this.options.cacheTTL&&n++;return{size:this.cache.size,expired:n}}};M(Nn,"instance",null),M(Nn,"TRANSLATION_PATTERN",/\$t:(?:defer:)?([a-zA-Z0-9._-]+)(\|(?:(?!\$t:).)+)?/g),M(Nn,"NESTED_TRANSLATION_PARAM_PATTERN",/=(\$t:([a-zA-Z0-9._-]+))(?=[|&\s]|$)/g),M(Nn,"PARAM_PATTERN",/([^=|&]+)=([^|&]+)/g);let Ra=Nn,Nd=null;function Jw(s){return Nd||(Nd=new Ra(s)),Nd}const Ug=Object.freeze(Object.defineProperty({__proto__:null,TranslationEngine:Ra,TranslationError:Md,getTranslationEngine:Jw},Symbol.toStringTag,{value:"Module"})),as=dt("PipeRegistry");function Pg(s,e){const n=s.getFullYear(),r=String(s.getMonth()+1).padStart(2,"0"),i=String(s.getDate()).padStart(2,"0"),l=String(s.getHours()).padStart(2,"0"),c=String(s.getMinutes()).padStart(2,"0"),d=String(s.getSeconds()).padStart(2,"0");return e.replace("YYYY",String(n)).replace("YY",String(n).slice(-2)).replace("MM",r).replace("M",String(s.getMonth()+1)).replace("DD",i).replace("D",String(s.getDate())).replace("HH",l).replace("H",String(s.getHours())).replace("mm",c).replace("m",String(s.getMinutes())).replace("ss",d).replace("s",String(s.getSeconds()))}function Qw(s,e="ko"){const r=new Date().getTime()-s.getTime(),i=Math.floor(r/1e3),l=Math.floor(i/60),c=Math.floor(l/60),d=Math.floor(c/24),f=Math.floor(d/7),h=Math.floor(d/30),m=Math.floor(d/365);return e==="ko"?i<60?"방금 전":l<60?`${l}분 전`:c<24?`${c}시간 전`:d<7?`${d}일 전`:f<4?`${f}주 전`:h<12?`${h}개월 전`:`${m}년 전`:i<60?"just now":l<60?`${l} minute${l===1?"":"s"} ago`:c<24?`${c} hour${c===1?"":"s"} ago`:d<7?`${d} day${d===1?"":"s"} ago`:f<4?`${f} week${f===1?"":"s"} ago`:h<12?`${h} month${h===1?"":"s"} ago`:`${m} year${m===1?"":"s"} ago`}function Id(s){if(s==null)return null;if(s instanceof Date)return s;if(typeof s=="number")return new Date(s);if(typeof s=="string"){const e=new Date(s);return isNaN(e.getTime())?null:e}return null}const fo={date:{fn:(s,e="YYYY-MM-DD")=>{const n=Id(s);return n?Pg(n,e):""},description:"날짜 포맷 (기본: YYYY-MM-DD)"},datetime:{fn:(s,e="YYYY-MM-DD HH:mm")=>{const n=Id(s);return n?Pg(n,e):""},description:"날짜+시간 포맷 (기본: YYYY-MM-DD HH:mm)"},relativeTime:{fn:(s,e="ko")=>{const n=Id(s);return n?Qw(n,e):""},description:'상대 시간 표시 (예: "3분 전")'},number:{fn:(s,e)=>{const n=Number(s);if(isNaN(n))return String(s??"");const r={};return e!==void 0&&(r.minimumFractionDigits=e,r.maximumFractionDigits=e),n.toLocaleString(void 0,r)},description:"숫자 포맷 (천단위 구분, 선택적 소수점)"},truncate:{fn:(s,e=100,n="...")=>typeof s!="string"?String(s??""):s.length<=e?s:s.slice(0,e)+n,description:'문자열 자르기 (기본: 100자, 접미사: "...")'},uppercase:{fn:s=>typeof s!="string"?String(s??""):s.toUpperCase(),description:"대문자 변환"},lowercase:{fn:s=>typeof s!="string"?String(s??""):s.toLowerCase(),description:"소문자 변환"},stripHtml:{fn:s=>typeof s!="string"?String(s??""):s.replace(/<[^>]*>/g,""),description:"HTML 태그 제거"},default:{fn:(s,e="")=>s==null||s===""?e:s,description:"기본값 설정 (null, undefined, 빈문자열 시)"},fallback:{fn:(s,e)=>s??e,description:"폴백 값 설정 (null, undefined 시만)"},first:{fn:s=>{if(Array.isArray(s))return s[0]},description:"배열의 첫 번째 요소"},last:{fn:s=>{if(Array.isArray(s))return s[s.length-1]},description:"배열의 마지막 요소"},join:{fn:(s,e=", ")=>Array.isArray(s)?s.join(e):"",description:'배열을 문자열로 결합 (기본 구분자: ", ")'},length:{fn:s=>Array.isArray(s)||typeof s=="string"?s.length:0,description:"배열/문자열 길이"},filterBy:{fn:(s,e,n)=>Array.isArray(s)?Array.isArray(e)?s.filter(r=>{const i=n?r?.[n]:r;return e.includes(i)}):s:[],description:"배열 필터링 (allowList에 포함된 항목만 반환)"},keys:{fn:s=>s==null||typeof s!="object"?[]:Object.keys(s),description:"객체의 키 배열"},values:{fn:s=>s==null||typeof s!="object"?[]:Object.values(s),description:"객체의 값 배열"},json:{fn:(s,e)=>{try{return JSON.stringify(s,null,e)}catch{return""}},description:"JSON 문자열로 변환"},localized:{fn:(s,e)=>s==null?"":typeof s=="string"?s:typeof s!="object"?String(s):s[e||"ko"]||s.ko||s.en||Object.values(s)[0]||"",description:"다국어 객체에서 로케일에 맞는 값 추출"}},is=new Map,xi=class xi{static getInstance(){return xi.instance||(xi.instance=new xi),xi.instance}register(e,n,r){if(fo[e]){as.warn(`[PipeRegistry] 내장 파이프를 덮어쓸 수 없습니다: ${e}`);return}is.set(e,{fn:n,description:r}),as.log(`[PipeRegistry] 커스텀 파이프 등록됨: ${e}`)}unregister(e){if(fo[e])return as.warn(`[PipeRegistry] 내장 파이프는 해제할 수 없습니다: ${e}`),!1;const n=is.delete(e);return n&&as.log(`[PipeRegistry] 커스텀 파이프 해제됨: ${e}`),n}get(e){const n=fo[e];return n?n.fn:is.get(e)?.fn}has(e){return!!fo[e]||is.has(e)}execute(e,n,r=[]){const i=this.get(e);if(!i)return as.warn(`[PipeRegistry] 알 수 없는 파이프: ${e}`),n;try{return i(n,...r)}catch(l){return as.error(`[PipeRegistry] 파이프 실행 오류 (${e}):`,l),n}}list(){const e=[];for(const[n,r]of Object.entries(fo))e.push({name:n,description:r.description,type:"built-in"});for(const[n,r]of is.entries())e.push({name:n,description:r.description,type:"custom"});return e.sort((n,r)=>n.name.localeCompare(r.name))}clearCustomPipes(){is.clear()}};M(xi,"instance",null);let Kl=xi;Kl.getInstance();function Zw(s){const e=s.trim(),n=e.indexOf("(");if(n===-1)return{name:e,args:[]};const r=e.slice(0,n).trim(),i=e.slice(n+1,-1);if(!i.trim())return{name:r,args:[]};const l=[];let c="",d=null,f=0;for(let h=0;h0?i[h-1]:"")==="\\"){c+=m;continue}if((m==='"'||m==="'")&&!d){d=m;continue}if(m===d){d=null;continue}if(d){c+=m;continue}if(m==="("||m==="["||m==="{"){f++,c+=m;continue}if(m===")"||m==="]"||m==="}"){f--,c+=m;continue}if(m===","&&f===0){l.push(Bg(c.trim())),c="";continue}c+=m}return c.trim()&&l.push(Bg(c.trim())),{name:r,args:l}}function Bg(s){if(s==="null")return null;if(s==="undefined")return;if(s==="true")return!0;if(s==="false")return!1;const e=Number(s);return!isNaN(e)&&s!==""?e:s}function e0(s){const e=[];let n="",r=null,i=0;for(let l=0;l0?s[l-1]:"",f=l0?s[r-1]:"",c=r0){r--;continue}return null}}return r===0?e.trim():null}function n0(s){const e=[];if(typeof s!="string")return e;for(let n=0;n0){i--;continue}if(s[c+1]==="}"){l=c;break}break}}l!==-1&&(e.push({start:n,end:l+2,expr:s.slice(n+2,l)}),n=l+1)}return e}function ho(s){return/[?:|&!+\-*/<>=()[\]{}]/.test(s)}function qg(s){const e=typeof s=="string"?s.trim():"";return e===""?"empty":jd.has(e)?"literal":Gn(e)?"pipe":ho(e)?"expression":"path"}function Hd(s,e,n,r){const i=typeof s=="string"?s.trim():"",l=qg(i),c=r?.skipCache?{skipCache:!0}:void 0;if(l==="empty"){r?.onEmpty?.(s);return}if(l==="literal")return jd.get(i);try{return l==="pipe"?n.evaluatePipeExpression(i,e,c,r?.trackingInfo):l==="expression"?n.evaluateExpression(i,e,r?.trackingInfo):n.resolve(i,e,c,r?.trackingInfo)}catch(d){if(r?.onError)return r.onError(d,i);throw d}}const nr="raw:";function Gg(s){return s.startsWith(nr)?s.slice(nr.length):s}const po="﷐",bi="﷑",Oa="﷒";function go(s){return po+s+bi}function Wl(s){return s.length>=2&&s.charCodeAt(0)===64976&&s.charCodeAt(s.length-1)===64977}function Yl(s){return s.includes(po)}function zd(s){return s.slice(1,-1)}function ss(s){if(typeof s=="string")return go(s);if(Array.isArray(s))return s.map(ss);if(s&&typeof s=="object"){const e={};for(const[n,r]of Object.entries(s))e[n]=ss(r);return e}return s}function La(s){if(typeof s=="string")return Wl(s)?zd(s):Yl(s)||s.includes(bi)?s.split(po).join("").split(bi).join(""):s;if(Array.isArray(s)){let e=!1;const n=s.map(r=>{const i=La(r);return i!==r&&(e=!0),i});return e?n:s}if(s&&typeof s=="object"){if(s.$$typeof!==void 0)return s;let e=!1;const n={};for(const[r,i]of Object.entries(s)){const l=La(i);l!==i&&(e=!0),n[r]=l}return e?n:s}return s}const mo=new Set(["constructor","__proto__","prototype","__lookupGetter__","__lookupSetter__","__defineGetter__","__defineSetter__"]),r0=new Set(["Function","eval","globalThis","window","self","document","require","module","process","Reflect","Proxy","WebAssembly","import","constructor"]);function Fg(s,e){if(s!==null&&(typeof s=="object"||typeof s=="function")&&Vg.has(s))throw new Error(`Object.${e} on a built-in global object is not allowed`);return s}const a0=Object.freeze({keys:Object.keys,values:Object.values,entries:Object.entries,assign:(s,...e)=>{const n=Fg(s,"assign");for(const r of e)if(r!=null)for(const i of Object.keys(r)){if(mo.has(i))throw new Error(`Access to "${i}" is forbidden`);Kd(n,i,r[i])}return n},freeze:s=>Object.freeze(Fg(s,"freeze")),fromEntries:Object.fromEntries,create:Object.create,isFrozen:Object.isFrozen}),Ud={Math,JSON,Date,Array,Object:a0,Number,String,Boolean,Set,Map,WeakSet,WeakMap,parseInt,parseFloat,isNaN,isFinite},Pd={Date,Set,Map,WeakSet,WeakMap,Array,Number,String,Boolean,Object},Vg=new Set([...Object.values(Ud),...Object.values(Pd)].filter(s=>s!==null&&(typeof s=="object"||typeof s=="function"))),Xl=new Set(["function"]),vr=Symbol("short-circuit");class Bd{constructor(e){M(this,"value");this.value=e}}class qd{}class Gd{}function i0(s){return/[A-Za-z_$]/.test(s)}function s0(s){return/[A-Za-z0-9_$]/.test(s)}function vi(s){return s>="0"&&s<="9"}function o0(s,e,n){let r=e+1;for(;r>>=0,t===0?32:31-(F(t)/se|0)|0}var ee=256,ve=262144,he=4194304;function Ee(t){var a=t&42;if(a!==0)return a;switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return t&261888;case 262144:case 524288:case 1048576:case 2097152:return t&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function Ae(t,a,o){var u=t.pendingLanes;if(u===0)return 0;var p=0,g=t.suspendedLanes,w=t.pingedLanes;t=t.warmLanes;var R=u&134217727;return R!==0?(u=R&~g,u!==0?p=Ee(u):(w&=R,w!==0?p=Ee(w):o||(o=R&~t,o!==0&&(p=Ee(o))))):(R=u&~g,R!==0?p=Ee(R):w!==0?p=Ee(w):o||(o=u&~t,o!==0&&(p=Ee(o)))),p===0?0:a!==0&&a!==p&&(a&g)===0&&(g=p&-p,o=a&-a,g>=o||g===32&&(o&4194048)!==0)?a:p}function Ve(t,a){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&a)===0}function ke(t,a){switch(t){case 1:case 2:case 4:case 8:case 64:return a+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return a+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Ne(){var t=he;return he<<=1,(he&62914560)===0&&(he=4194304),t}function Re(t){for(var a=[],o=0;31>o;o++)a.push(t);return a}function et(t,a){t.pendingLanes|=a,a!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function He(t,a,o,u,p,g){var w=t.pendingLanes;t.pendingLanes=o,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=o,t.entangledLanes&=o,t.errorRecoveryDisabledLanes&=o,t.shellSuspendCounter=0;var R=t.entanglements,z=t.expirationTimes,X=t.hiddenUpdates;for(o=w&~o;0"u")return null;try{return t.activeElement||t.body}catch{return t.body}}var ch=/[\n"\\]/g;function Hn(t){return t.replace(ch,function(a){return"\\"+a.charCodeAt(0).toString(16)+" "})}function Ts(t,a,o,u,p,g,w,R){t.name="",w!=null&&typeof w!="function"&&typeof w!="symbol"&&typeof w!="boolean"?t.type=w:t.removeAttribute("type"),a!=null?w==="number"?(a===0&&t.value===""||t.value!=a)&&(t.value=""+xn(a)):t.value!==""+xn(a)&&(t.value=""+xn(a)):w!=="submit"&&w!=="reset"||t.removeAttribute("value"),a!=null?da(t,w,xn(a)):o!=null?da(t,w,xn(o)):u!=null&&t.removeAttribute("value"),p==null&&g!=null&&(t.defaultChecked=!!g),p!=null&&(t.checked=p&&typeof p!="function"&&typeof p!="symbol"),R!=null&&typeof R!="function"&&typeof R!="symbol"&&typeof R!="boolean"?t.name=""+xn(R):t.removeAttribute("name")}function Oi(t,a,o,u,p,g,w,R){if(g!=null&&typeof g!="function"&&typeof g!="symbol"&&typeof g!="boolean"&&(t.type=g),a!=null||o!=null){if(!(g!=="submit"&&g!=="reset"||a!=null)){Yo(t);return}o=o!=null?""+xn(o):"",a=a!=null?""+xn(a):o,R||a===t.value||(t.value=a),t.defaultValue=a}u=u??p,u=typeof u!="function"&&typeof u!="symbol"&&!!u,t.checked=R?t.checked:!!u,t.defaultChecked=!!u,w!=null&&typeof w!="function"&&typeof w!="symbol"&&typeof w!="boolean"&&(t.name=w),Yo(t)}function da(t,a,o){a==="number"&&qa(t.ownerDocument)===t||t.defaultValue===""+o||(t.defaultValue=""+o)}function Ga(t,a,o,u){if(t=t.options,a){a={};for(var p=0;p"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),el=!1;if(Or)try{var $i={};Object.defineProperty($i,"passive",{get:function(){el=!0}}),window.addEventListener("test",$i,$i),window.removeEventListener("test",$i,$i)}catch{el=!1}var Yr=null,tl=null,Rs=null;function tu(){if(Rs)return Rs;var t,a=tl,o=a.length,u,p="value"in Yr?Yr.value:Yr.textContent,g=p.length;for(t=0;t=ne),Ke=" ",ct=!1;function gt(t,a){switch(t){case"keyup":return D.indexOf(a.keyCode)!==-1;case"keydown":return a.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function zt(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var $r=!1;function Th(t,a){switch(t){case"compositionend":return zt(a);case"keypress":return a.which!==32?null:(ct=!0,Ke);case"textInput":return t=a.data,t===Ke&&ct?null:t;default:return null}}function lu(t,a){if($r)return t==="compositionend"||!I&>(t,a)?(t=tu(),Rs=tl=Yr=null,$r=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(a.ctrlKey||a.altKey||a.metaKey)||a.ctrlKey&&a.altKey){if(a.char&&1=a)return{node:o,offset:a-t};t=u}e:{for(;o;){if(o.nextSibling){o=o.nextSibling;break e}o=o.parentNode}o=void 0}o=gb(o)}}function yb(t,a){return t&&a?t===a?!0:t&&t.nodeType===3?!1:a&&a.nodeType===3?yb(t,a.parentNode):"contains"in t?t.contains(a):t.compareDocumentPosition?!!(t.compareDocumentPosition(a)&16):!1:!1}function bb(t){t=t!=null&&t.ownerDocument!=null&&t.ownerDocument.defaultView!=null?t.ownerDocument.defaultView:window;for(var a=qa(t.document);a instanceof t.HTMLIFrameElement;){try{var o=typeof a.contentWindow.location.href=="string"}catch{o=!1}if(o)t=a.contentWindow;else break;a=qa(t.document)}return a}function Lh(t){var a=t&&t.nodeName&&t.nodeName.toLowerCase();return a&&(a==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||a==="textarea"||t.contentEditable==="true")}var sT=Or&&"documentMode"in document&&11>=document.documentMode,$s=null,$h=null,dl=null,Mh=!1;function vb(t,a,o){var u=o.window===o?o.document:o.nodeType===9?o:o.ownerDocument;Mh||$s==null||$s!==qa(u)||(u=$s,"selectionStart"in u&&Lh(u)?u={start:u.selectionStart,end:u.selectionEnd}:(u=(u.ownerDocument&&u.ownerDocument.defaultView||window).getSelection(),u={anchorNode:u.anchorNode,anchorOffset:u.anchorOffset,focusNode:u.focusNode,focusOffset:u.focusOffset}),dl&&ul(dl,u)||(dl=u,u=ed($h,"onSelect"),0>=w,p-=w,Xr=1<<32-on(a)+p|o<Qe?(ot=Ie,Ie=null):ot=Ie.sibling;var yt=Q(V,Ie,Y[Qe],oe);if(yt===null){Ie===null&&(Ie=ot);break}t&&Ie&&yt.alternate===null&&a(V,Ie),q=g(yt,q,Qe),mt===null?Pe=yt:mt.sibling=yt,mt=yt,Ie=ot}if(Qe===Y.length)return o(V,Ie),ut&&ga(V,Qe),Pe;if(Ie===null){for(;QeQe?(ot=Ie,Ie=null):ot=Ie.sibling;var mi=Q(V,Ie,yt.value,oe);if(mi===null){Ie===null&&(Ie=ot);break}t&&Ie&&mi.alternate===null&&a(V,Ie),q=g(mi,q,Qe),mt===null?Pe=mi:mt.sibling=mi,mt=mi,Ie=ot}if(yt.done)return o(V,Ie),ut&&ga(V,Qe),Pe;if(Ie===null){for(;!yt.done;Qe++,yt=Y.next())yt=le(V,yt.value,oe),yt!==null&&(q=g(yt,q,Qe),mt===null?Pe=yt:mt.sibling=yt,mt=yt);return ut&&ga(V,Qe),Pe}for(Ie=u(Ie);!yt.done;Qe++,yt=Y.next())yt=te(Ie,V,Qe,yt.value,oe),yt!==null&&(t&&yt.alternate!==null&&Ie.delete(yt.key===null?Qe:yt.key),q=g(yt,q,Qe),mt===null?Pe=yt:mt.sibling=yt,mt=yt);return t&&Ie.forEach(function(xk){return a(V,xk)}),ut&&ga(V,Qe),Pe}function kt(V,q,Y,oe){if(typeof Y=="object"&&Y!==null&&Y.type===x&&Y.key===null&&(Y=Y.props.children),typeof Y=="object"&&Y!==null){switch(Y.$$typeof){case v:e:{for(var Pe=Y.key;q!==null;){if(q.key===Pe){if(Pe=Y.type,Pe===x){if(q.tag===7){o(V,q.sibling),oe=p(q,Y.props.children),oe.return=V,V=oe;break e}}else if(q.elementType===Pe||typeof Pe=="object"&&Pe!==null&&Pe.$$typeof===W&&Yi(Pe)===q.type){o(V,q.sibling),oe=p(q,Y.props),yl(oe,Y),oe.return=V,V=oe;break e}o(V,q);break}else a(V,q);q=q.sibling}Y.type===x?(oe=Gi(Y.props.children,V.mode,oe,Y.key),oe.return=V,V=oe):(oe=yu(Y.type,Y.key,Y.props,null,V.mode,oe),yl(oe,Y),oe.return=V,V=oe)}return w(V);case _:e:{for(Pe=Y.key;q!==null;){if(q.key===Pe)if(q.tag===4&&q.stateNode.containerInfo===Y.containerInfo&&q.stateNode.implementation===Y.implementation){o(V,q.sibling),oe=p(q,Y.children||[]),oe.return=V,V=oe;break e}else{o(V,q);break}else a(V,q);q=q.sibling}oe=Ph(Y,V.mode,oe),oe.return=V,V=oe}return w(V);case W:return Y=Yi(Y),kt(V,q,Y,oe)}if(wt(Y))return De(V,q,Y,oe);if(Ue(Y)){if(Pe=Ue(Y),typeof Pe!="function")throw Error(r(150));return Y=Pe.call(Y),Be(V,q,Y,oe)}if(typeof Y.then=="function")return kt(V,q,_u(Y),oe);if(Y.$$typeof===k)return kt(V,q,Su(V,Y),oe);Au(V,Y)}return typeof Y=="string"&&Y!==""||typeof Y=="number"||typeof Y=="bigint"?(Y=""+Y,q!==null&&q.tag===6?(o(V,q.sibling),oe=p(q,Y),oe.return=V,V=oe):(o(V,q),oe=Uh(Y,V.mode,oe),oe.return=V,V=oe),w(V)):o(V,q)}return function(V,q,Y,oe){try{ml=0;var Pe=kt(V,q,Y,oe);return Gs=null,Pe}catch(Ie){if(Ie===qs||Ie===Cu)throw Ie;var mt=Xn(29,Ie,null,V.mode);return mt.lanes=oe,mt.return=V,mt}}}var Ji=Bb(!0),qb=Bb(!1),Za=!1;function Zh(t){t.updateQueue={baseState:t.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function ep(t,a){t=t.updateQueue,a.updateQueue===t&&(a.updateQueue={baseState:t.baseState,firstBaseUpdate:t.firstBaseUpdate,lastBaseUpdate:t.lastBaseUpdate,shared:t.shared,callbacks:null})}function ei(t){return{lane:t,tag:0,payload:null,callback:null,next:null}}function ti(t,a,o){var u=t.updateQueue;if(u===null)return null;if(u=u.shared,(vt&2)!==0){var p=u.pending;return p===null?a.next=a:(a.next=p.next,p.next=a),u.pending=a,a=mu(t),xb(t,null,o),a}return gu(t,u,a,o),mu(t)}function bl(t,a,o){if(a=a.updateQueue,a!==null&&(a=a.shared,(o&4194048)!==0)){var u=a.lanes;u&=t.pendingLanes,o|=u,a.lanes=o,Ce(t,o)}}function tp(t,a){var o=t.updateQueue,u=t.alternate;if(u!==null&&(u=u.updateQueue,o===u)){var p=null,g=null;if(o=o.firstBaseUpdate,o!==null){do{var w={lane:o.lane,tag:o.tag,payload:o.payload,callback:null,next:null};g===null?p=g=w:g=g.next=w,o=o.next}while(o!==null);g===null?p=g=a:g=g.next=a}else p=g=a;o={baseState:u.baseState,firstBaseUpdate:p,lastBaseUpdate:g,shared:u.shared,callbacks:u.callbacks},t.updateQueue=o;return}t=o.lastBaseUpdate,t===null?o.firstBaseUpdate=a:t.next=a,o.lastBaseUpdate=a}var np=!1;function vl(){if(np){var t=Bs;if(t!==null)throw t}}function Sl(t,a,o,u){np=!1;var p=t.updateQueue;Za=!1;var g=p.firstBaseUpdate,w=p.lastBaseUpdate,R=p.shared.pending;if(R!==null){p.shared.pending=null;var z=R,X=z.next;z.next=null,w===null?g=X:w.next=X,w=z;var re=t.alternate;re!==null&&(re=re.updateQueue,R=re.lastBaseUpdate,R!==w&&(R===null?re.firstBaseUpdate=X:R.next=X,re.lastBaseUpdate=z))}if(g!==null){var le=p.baseState;w=0,re=X=z=null,R=g;do{var Q=R.lane&-536870913,te=Q!==R.lane;if(te?(st&Q)===Q:(u&Q)===Q){Q!==0&&Q===Ps&&(np=!0),re!==null&&(re=re.next={lane:0,tag:R.tag,payload:R.payload,callback:null,next:null});e:{var De=t,Be=R;Q=a;var kt=o;switch(Be.tag){case 1:if(De=Be.payload,typeof De=="function"){le=De.call(kt,le,Q);break e}le=De;break e;case 3:De.flags=De.flags&-65537|128;case 0:if(De=Be.payload,Q=typeof De=="function"?De.call(kt,le,Q):De,Q==null)break e;le=y({},le,Q);break e;case 2:Za=!0}}Q=R.callback,Q!==null&&(t.flags|=64,te&&(t.flags|=8192),te=p.callbacks,te===null?p.callbacks=[Q]:te.push(Q))}else te={lane:Q,tag:R.tag,payload:R.payload,callback:R.callback,next:null},re===null?(X=re=te,z=le):re=re.next=te,w|=Q;if(R=R.next,R===null){if(R=p.shared.pending,R===null)break;te=R,R=te.next,te.next=null,p.lastBaseUpdate=te,p.shared.pending=null}}while(!0);re===null&&(z=le),p.baseState=z,p.firstBaseUpdate=X,p.lastBaseUpdate=re,g===null&&(p.shared.lanes=0),si|=w,t.lanes=w,t.memoizedState=le}}function Gb(t,a){if(typeof t!="function")throw Error(r(191,t));t.call(a)}function Fb(t,a){var o=t.callbacks;if(o!==null)for(t.callbacks=null,t=0;tg?g:8;var w=J.T,R={};J.T=R,wp(t,!1,a,o);try{var z=p(),X=J.S;if(X!==null&&X(R,z),z!==null&&typeof z=="object"&&typeof z.then=="function"){var re=gT(z,u);El(t,a,re,tr(t))}else El(t,a,u,tr(t))}catch(le){El(t,a,{then:function(){},status:"rejected",reason:le},tr())}finally{fe.p=g,w!==null&&R.types!==null&&(w.types=R.types),J.T=w}}function wT(){}function vp(t,a,o,u){if(t.tag!==5)throw Error(r(476));var p=Ev(t).queue;Cv(t,p,a,Le,o===null?wT:function(){return _v(t),o(u)})}function Ev(t){var a=t.memoizedState;if(a!==null)return a;a={memoizedState:Le,baseState:Le,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:va,lastRenderedState:Le},next:null};var o={};return a.next={memoizedState:o,baseState:o,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:va,lastRenderedState:o},next:null},t.memoizedState=a,t=t.alternate,t!==null&&(t.memoizedState=a),a}function _v(t){var a=Ev(t);a.next===null&&(a=t.alternate.memoizedState),El(t,a.next.queue,{},tr())}function Sp(){return vn(Ul)}function Av(){return Yt().memoizedState}function xv(){return Yt().memoizedState}function CT(t){for(var a=t.return;a!==null;){switch(a.tag){case 24:case 3:var o=tr();t=ei(o);var u=ti(a,t,o);u!==null&&(qn(u,a,o),bl(u,a,o)),a={cache:Yh()},t.payload=a;return}a=a.return}}function ET(t,a,o){var u=tr();o={lane:u,revertLane:0,gesture:null,action:o,hasEagerState:!1,eagerState:null,next:null},Nu(t)?kv(a,o):(o=Hh(t,a,o,u),o!==null&&(qn(o,t,u),Rv(o,a,u)))}function Tv(t,a,o){var u=tr();El(t,a,o,u)}function El(t,a,o,u){var p={lane:u,revertLane:0,gesture:null,action:o,hasEagerState:!1,eagerState:null,next:null};if(Nu(t))kv(a,p);else{var g=t.alternate;if(t.lanes===0&&(g===null||g.lanes===0)&&(g=a.lastRenderedReducer,g!==null))try{var w=a.lastRenderedState,R=g(w,o);if(p.hasEagerState=!0,p.eagerState=R,Yn(R,w))return gu(t,a,p,0),Dt===null&&pu(),!1}catch{}if(o=Hh(t,a,p,u),o!==null)return qn(o,t,u),Rv(o,a,u),!0}return!1}function wp(t,a,o,u){if(u={lane:2,revertLane:Zp(),gesture:null,action:u,hasEagerState:!1,eagerState:null,next:null},Nu(t)){if(a)throw Error(r(479))}else a=Hh(t,o,u,2),a!==null&&qn(a,t,2)}function Nu(t){var a=t.alternate;return t===Xe||a!==null&&a===Xe}function kv(t,a){Vs=ku=!0;var o=t.pending;o===null?a.next=a:(a.next=o.next,o.next=a),t.pending=a}function Rv(t,a,o){if((o&4194048)!==0){var u=a.lanes;u&=t.pendingLanes,o|=u,a.lanes=o,Ce(t,o)}}var _l={readContext:vn,use:Ou,useCallback:Gt,useContext:Gt,useEffect:Gt,useImperativeHandle:Gt,useLayoutEffect:Gt,useInsertionEffect:Gt,useMemo:Gt,useReducer:Gt,useRef:Gt,useState:Gt,useDebugValue:Gt,useDeferredValue:Gt,useTransition:Gt,useSyncExternalStore:Gt,useId:Gt,useHostTransitionStatus:Gt,useFormState:Gt,useActionState:Gt,useOptimistic:Gt,useMemoCache:Gt,useCacheRefresh:Gt};_l.useEffectEvent=Gt;var Dv={readContext:vn,use:Ou,useCallback:function(t,a){return Ln().memoizedState=[t,a===void 0?null:a],t},useContext:vn,useEffect:hv,useImperativeHandle:function(t,a,o){o=o!=null?o.concat([t]):null,$u(4194308,4,yv.bind(null,a,t),o)},useLayoutEffect:function(t,a){return $u(4194308,4,t,a)},useInsertionEffect:function(t,a){$u(4,2,t,a)},useMemo:function(t,a){var o=Ln();a=a===void 0?null:a;var u=t();if(Qi){_n(!0);try{t()}finally{_n(!1)}}return o.memoizedState=[u,a],u},useReducer:function(t,a,o){var u=Ln();if(o!==void 0){var p=o(a);if(Qi){_n(!0);try{o(a)}finally{_n(!1)}}}else p=a;return u.memoizedState=u.baseState=p,t={pending:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:p},u.queue=t,t=t.dispatch=ET.bind(null,Xe,t),[u.memoizedState,t]},useRef:function(t){var a=Ln();return t={current:t},a.memoizedState=t},useState:function(t){t=pp(t);var a=t.queue,o=Tv.bind(null,Xe,a);return a.dispatch=o,[t.memoizedState,o]},useDebugValue:yp,useDeferredValue:function(t,a){var o=Ln();return bp(o,t,a)},useTransition:function(){var t=pp(!1);return t=Cv.bind(null,Xe,t.queue,!0,!1),Ln().memoizedState=t,[!1,t]},useSyncExternalStore:function(t,a,o){var u=Xe,p=Ln();if(ut){if(o===void 0)throw Error(r(407));o=o()}else{if(o=a(),Dt===null)throw Error(r(349));(st&127)!==0||Jb(u,a,o)}p.memoizedState=o;var g={value:o,getSnapshot:a};return p.queue=g,hv(Zb.bind(null,u,g,t),[t]),u.flags|=2048,Ws(9,{destroy:void 0},Qb.bind(null,u,g,o,a),null),o},useId:function(){var t=Ln(),a=Dt.identifierPrefix;if(ut){var o=Jr,u=Xr;o=(u&~(1<<32-on(u)-1)).toString(32)+o,a="_"+a+"R_"+o,o=Ru++,0<\/script>",g=g.removeChild(g.firstChild);break;case"select":g=typeof u.is=="string"?w.createElement("select",{is:u.is}):w.createElement("select"),u.multiple?g.multiple=!0:u.size&&(g.size=u.size);break;default:g=typeof u.is=="string"?w.createElement(p,{is:u.is}):w.createElement(p)}}g[Ht]=a,g[An]=u;e:for(w=a.child;w!==null;){if(w.tag===5||w.tag===6)g.appendChild(w.stateNode);else if(w.tag!==4&&w.tag!==27&&w.child!==null){w.child.return=w,w=w.child;continue}if(w===a)break e;for(;w.sibling===null;){if(w.return===null||w.return===a)break e;w=w.return}w.sibling.return=w.return,w=w.sibling}a.stateNode=g;e:switch(wn(g,p,u),p){case"button":case"input":case"select":case"textarea":u=!!u.autoFocus;break e;case"img":u=!0;break e;default:u=!1}u&&wa(a)}}return $t(a),Np(a,a.type,t===null?null:t.memoizedProps,a.pendingProps,o),null;case 6:if(t&&a.stateNode!=null)t.memoizedProps!==u&&wa(a);else{if(typeof u!="string"&&a.stateNode===null)throw Error(r(166));if(t=ie.current,zs(a)){if(t=a.stateNode,o=a.memoizedProps,u=null,p=bn,p!==null)switch(p.tag){case 27:case 5:u=p.memoizedProps}t[Ht]=a,t=!!(t.nodeValue===o||u!==null&&u.suppressHydrationWarning===!0||YS(t.nodeValue,o)),t||Ja(a,!0)}else t=td(t).createTextNode(u),t[Ht]=a,a.stateNode=t}return $t(a),null;case 31:if(o=a.memoizedState,t===null||t.memoizedState!==null){if(u=zs(a),o!==null){if(t===null){if(!u)throw Error(r(318));if(t=a.memoizedState,t=t!==null?t.dehydrated:null,!t)throw Error(r(557));t[Ht]=a}else Fi(),(a.flags&128)===0&&(a.memoizedState=null),a.flags|=4;$t(a),t=!1}else o=Fh(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=o),t=!0;if(!t)return a.flags&256?(Qn(a),a):(Qn(a),null);if((a.flags&128)!==0)throw Error(r(558))}return $t(a),null;case 13:if(u=a.memoizedState,t===null||t.memoizedState!==null&&t.memoizedState.dehydrated!==null){if(p=zs(a),u!==null&&u.dehydrated!==null){if(t===null){if(!p)throw Error(r(318));if(p=a.memoizedState,p=p!==null?p.dehydrated:null,!p)throw Error(r(317));p[Ht]=a}else Fi(),(a.flags&128)===0&&(a.memoizedState=null),a.flags|=4;$t(a),p=!1}else p=Fh(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=p),p=!0;if(!p)return a.flags&256?(Qn(a),a):(Qn(a),null)}return Qn(a),(a.flags&128)!==0?(a.lanes=o,a):(o=u!==null,t=t!==null&&t.memoizedState!==null,o&&(u=a.child,p=null,u.alternate!==null&&u.alternate.memoizedState!==null&&u.alternate.memoizedState.cachePool!==null&&(p=u.alternate.memoizedState.cachePool.pool),g=null,u.memoizedState!==null&&u.memoizedState.cachePool!==null&&(g=u.memoizedState.cachePool.pool),g!==p&&(u.flags|=2048)),o!==t&&o&&(a.child.flags|=8192),Uu(a,a.updateQueue),$t(a),null);case 4:return Te(),t===null&&rg(a.stateNode.containerInfo),$t(a),null;case 10:return ya(a.type),$t(a),null;case 19:if(T(Wt),u=a.memoizedState,u===null)return $t(a),null;if(p=(a.flags&128)!==0,g=u.rendering,g===null)if(p)xl(u,!1);else{if(Ft!==0||t!==null&&(t.flags&128)!==0)for(t=a.child;t!==null;){if(g=Tu(t),g!==null){for(a.flags|=128,xl(u,!1),t=g.updateQueue,a.updateQueue=t,Uu(a,t),a.subtreeFlags=0,t=o,o=a.child;o!==null;)Tb(o,t),o=o.sibling;return ce(Wt,Wt.current&1|2),ut&&ga(a,u.treeForkCount),a.child}t=t.sibling}u.tail!==null&&qt()>Fu&&(a.flags|=128,p=!0,xl(u,!1),a.lanes=4194304)}else{if(!p)if(t=Tu(g),t!==null){if(a.flags|=128,p=!0,t=t.updateQueue,a.updateQueue=t,Uu(a,t),xl(u,!0),u.tail===null&&u.tailMode==="hidden"&&!g.alternate&&!ut)return $t(a),null}else 2*qt()-u.renderingStartTime>Fu&&o!==536870912&&(a.flags|=128,p=!0,xl(u,!1),a.lanes=4194304);u.isBackwards?(g.sibling=a.child,a.child=g):(t=u.last,t!==null?t.sibling=g:a.child=g,u.last=g)}return u.tail!==null?(t=u.tail,u.rendering=t,u.tail=t.sibling,u.renderingStartTime=qt(),t.sibling=null,o=Wt.current,ce(Wt,p?o&1|2:o&1),ut&&ga(a,u.treeForkCount),t):($t(a),null);case 22:case 23:return Qn(a),ap(),u=a.memoizedState!==null,t!==null?t.memoizedState!==null!==u&&(a.flags|=8192):u&&(a.flags|=8192),u?(o&536870912)!==0&&(a.flags&128)===0&&($t(a),a.subtreeFlags&6&&(a.flags|=8192)):$t(a),o=a.updateQueue,o!==null&&Uu(a,o.retryQueue),o=null,t!==null&&t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(o=t.memoizedState.cachePool.pool),u=null,a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(u=a.memoizedState.cachePool.pool),u!==o&&(a.flags|=2048),t!==null&&T(Wi),null;case 24:return o=null,t!==null&&(o=t.memoizedState.cache),a.memoizedState.cache!==o&&(a.flags|=2048),ya(Qt),$t(a),null;case 25:return null;case 30:return null}throw Error(r(156,a.tag))}function kT(t,a){switch(qh(a),a.tag){case 1:return t=a.flags,t&65536?(a.flags=t&-65537|128,a):null;case 3:return ya(Qt),Te(),t=a.flags,(t&65536)!==0&&(t&128)===0?(a.flags=t&-65537|128,a):null;case 26:case 27:case 5:return pt(a),null;case 31:if(a.memoizedState!==null){if(Qn(a),a.alternate===null)throw Error(r(340));Fi()}return t=a.flags,t&65536?(a.flags=t&-65537|128,a):null;case 13:if(Qn(a),t=a.memoizedState,t!==null&&t.dehydrated!==null){if(a.alternate===null)throw Error(r(340));Fi()}return t=a.flags,t&65536?(a.flags=t&-65537|128,a):null;case 19:return T(Wt),null;case 4:return Te(),null;case 10:return ya(a.type),null;case 22:case 23:return Qn(a),ap(),t!==null&&T(Wi),t=a.flags,t&65536?(a.flags=t&-65537|128,a):null;case 24:return ya(Qt),null;case 25:return null;default:return null}}function eS(t,a){switch(qh(a),a.tag){case 3:ya(Qt),Te();break;case 26:case 27:case 5:pt(a);break;case 4:Te();break;case 31:a.memoizedState!==null&&Qn(a);break;case 13:Qn(a);break;case 19:T(Wt);break;case 10:ya(a.type);break;case 22:case 23:Qn(a),ap(),t!==null&&T(Wi);break;case 24:ya(Qt)}}function Tl(t,a){try{var o=a.updateQueue,u=o!==null?o.lastEffect:null;if(u!==null){var p=u.next;o=p;do{if((o.tag&t)===t){u=void 0;var g=o.create,w=o.inst;u=g(),w.destroy=u}o=o.next}while(o!==p)}}catch(R){_t(a,a.return,R)}}function ai(t,a,o){try{var u=a.updateQueue,p=u!==null?u.lastEffect:null;if(p!==null){var g=p.next;u=g;do{if((u.tag&t)===t){var w=u.inst,R=w.destroy;if(R!==void 0){w.destroy=void 0,p=a;var z=o,X=R;try{X()}catch(re){_t(p,z,re)}}}u=u.next}while(u!==g)}}catch(re){_t(a,a.return,re)}}function tS(t){var a=t.updateQueue;if(a!==null){var o=t.stateNode;try{Fb(a,o)}catch(u){_t(t,t.return,u)}}}function nS(t,a,o){o.props=Zi(t.type,t.memoizedProps),o.state=t.memoizedState;try{o.componentWillUnmount()}catch(u){_t(t,a,u)}}function kl(t,a){try{var o=t.ref;if(o!==null){switch(t.tag){case 26:case 27:case 5:var u=t.stateNode;break;case 30:u=t.stateNode;break;default:u=t.stateNode}typeof o=="function"?t.refCleanup=o(u):o.current=u}}catch(p){_t(t,a,p)}}function Qr(t,a){var o=t.ref,u=t.refCleanup;if(o!==null)if(typeof u=="function")try{u()}catch(p){_t(t,a,p)}finally{t.refCleanup=null,t=t.alternate,t!=null&&(t.refCleanup=null)}else if(typeof o=="function")try{o(null)}catch(p){_t(t,a,p)}else o.current=null}function rS(t){var a=t.type,o=t.memoizedProps,u=t.stateNode;try{e:switch(a){case"button":case"input":case"select":case"textarea":o.autoFocus&&u.focus();break e;case"img":o.src?u.src=o.src:o.srcSet&&(u.srcset=o.srcSet)}}catch(p){_t(t,t.return,p)}}function Ip(t,a,o){try{var u=t.stateNode;XT(u,t.type,o,a),u[An]=a}catch(p){_t(t,t.return,p)}}function aS(t){return t.tag===5||t.tag===3||t.tag===26||t.tag===27&&di(t.type)||t.tag===4}function jp(t){e:for(;;){for(;t.sibling===null;){if(t.return===null||aS(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;t.tag!==5&&t.tag!==6&&t.tag!==18;){if(t.tag===27&&di(t.type)||t.flags&2||t.child===null||t.tag===4)continue e;t.child.return=t,t=t.child}if(!(t.flags&2))return t.stateNode}}function Hp(t,a,o){var u=t.tag;if(u===5||u===6)t=t.stateNode,a?(o.nodeType===9?o.body:o.nodeName==="HTML"?o.ownerDocument.body:o).insertBefore(t,a):(a=o.nodeType===9?o.body:o.nodeName==="HTML"?o.ownerDocument.body:o,a.appendChild(t),o=o._reactRootContainer,o!=null||a.onclick!==null||(a.onclick=Dr));else if(u!==4&&(u===27&&di(t.type)&&(o=t.stateNode,a=null),t=t.child,t!==null))for(Hp(t,a,o),t=t.sibling;t!==null;)Hp(t,a,o),t=t.sibling}function Pu(t,a,o){var u=t.tag;if(u===5||u===6)t=t.stateNode,a?o.insertBefore(t,a):o.appendChild(t);else if(u!==4&&(u===27&&di(t.type)&&(o=t.stateNode),t=t.child,t!==null))for(Pu(t,a,o),t=t.sibling;t!==null;)Pu(t,a,o),t=t.sibling}function iS(t){var a=t.stateNode,o=t.memoizedProps;try{for(var u=t.type,p=a.attributes;p.length;)a.removeAttributeNode(p[0]);wn(a,u,o),a[Ht]=t,a[An]=o}catch(g){_t(t,t.return,g)}}var Ca=!1,tn=!1,zp=!1,sS=typeof WeakSet=="function"?WeakSet:Set,fn=null;function RT(t,a){if(t=t.containerInfo,sg=ld,t=bb(t),Lh(t)){if("selectionStart"in t)var o={start:t.selectionStart,end:t.selectionEnd};else e:{o=(o=t.ownerDocument)&&o.defaultView||window;var u=o.getSelection&&o.getSelection();if(u&&u.rangeCount!==0){o=u.anchorNode;var p=u.anchorOffset,g=u.focusNode;u=u.focusOffset;try{o.nodeType,g.nodeType}catch{o=null;break e}var w=0,R=-1,z=-1,X=0,re=0,le=t,Q=null;t:for(;;){for(var te;le!==o||p!==0&&le.nodeType!==3||(R=w+p),le!==g||u!==0&&le.nodeType!==3||(z=w+u),le.nodeType===3&&(w+=le.nodeValue.length),(te=le.firstChild)!==null;)Q=le,le=te;for(;;){if(le===t)break t;if(Q===o&&++X===p&&(R=w),Q===g&&++re===u&&(z=w),(te=le.nextSibling)!==null)break;le=Q,Q=le.parentNode}le=te}o=R===-1||z===-1?null:{start:R,end:z}}else o=null}o=o||{start:0,end:0}}else o=null;for(og={focusedElem:t,selectionRange:o},ld=!1,fn=a;fn!==null;)if(a=fn,t=a.child,(a.subtreeFlags&1028)!==0&&t!==null)t.return=a,fn=t;else for(;fn!==null;){switch(a=fn,g=a.alternate,t=a.flags,a.tag){case 0:if((t&4)!==0&&(t=a.updateQueue,t=t!==null?t.events:null,t!==null))for(o=0;o title"))),wn(g,u,o),g[Ht]=t,Jt(g),u=g;break e;case"link":var w=fw("link","href",p).get(u+(o.href||""));if(w){for(var R=0;Rkt&&(w=kt,kt=Be,Be=w);var V=mb(R,Be),q=mb(R,kt);if(V&&q&&(te.rangeCount!==1||te.anchorNode!==V.node||te.anchorOffset!==V.offset||te.focusNode!==q.node||te.focusOffset!==q.offset)){var Y=le.createRange();Y.setStart(V.node,V.offset),te.removeAllRanges(),Be>kt?(te.addRange(Y),te.extend(q.node,q.offset)):(Y.setEnd(q.node,q.offset),te.addRange(Y))}}}}for(le=[],te=R;te=te.parentNode;)te.nodeType===1&&le.push({element:te,left:te.scrollLeft,top:te.scrollTop});for(typeof R.focus=="function"&&R.focus(),R=0;Ro?32:o,J.T=null,o=Vp,Vp=null;var g=li,w=Ta;if(cn=0,Zs=li=null,Ta=0,(vt&6)!==0)throw Error(r(331));var R=vt;if(vt|=4,yS(g.current),pS(g,g.current,w,o),vt=R,Ml(0,!1),sn&&typeof sn.onPostCommitFiberRoot=="function")try{sn.onPostCommitFiberRoot(lr,g)}catch{}return!0}finally{fe.p=p,J.T=u,NS(t,a)}}function jS(t,a,o){a=dr(o,a),a=Ap(t.stateNode,a,2),t=ti(t,a,2),t!==null&&(et(t,2),Zr(t))}function _t(t,a,o){if(t.tag===3)jS(t,t,o);else for(;a!==null;){if(a.tag===3){jS(a,t,o);break}else if(a.tag===1){var u=a.stateNode;if(typeof a.type.getDerivedStateFromError=="function"||typeof u.componentDidCatch=="function"&&(oi===null||!oi.has(u))){t=dr(o,t),o=Hv(2),u=ti(a,o,2),u!==null&&(zv(o,u,a,t),et(u,2),Zr(u));break}}a=a.return}}function Xp(t,a,o){var u=t.pingCache;if(u===null){u=t.pingCache=new LT;var p=new Set;u.set(a,p)}else p=u.get(a),p===void 0&&(p=new Set,u.set(a,p));p.has(o)||(Bp=!0,p.add(o),t=jT.bind(null,t,a,o),a.then(t,t))}function jT(t,a,o){var u=t.pingCache;u!==null&&u.delete(a),t.pingedLanes|=t.suspendedLanes&o,t.warmLanes&=~o,Dt===t&&(st&o)===o&&(Ft===4||Ft===3&&(st&62914560)===st&&300>qt()-Gu?(vt&2)===0&&eo(t,0):qp|=o,Qs===st&&(Qs=0)),Zr(t)}function HS(t,a){a===0&&(a=Ne()),t=qi(t,a),t!==null&&(et(t,a),Zr(t))}function HT(t){var a=t.memoizedState,o=0;a!==null&&(o=a.retryLane),HS(t,o)}function zT(t,a){var o=0;switch(t.tag){case 31:case 13:var u=t.stateNode,p=t.memoizedState;p!==null&&(o=p.retryLane);break;case 19:u=t.stateNode;break;case 22:u=t.stateNode._retryCache;break;default:throw Error(r(314))}u!==null&&u.delete(a),HS(t,o)}function UT(t,a){return an(t,a)}var Ju=null,no=null,Jp=!1,Qu=!1,Qp=!1,ui=0;function Zr(t){t!==no&&t.next===null&&(no===null?Ju=no=t:no=no.next=t),Qu=!0,Jp||(Jp=!0,BT())}function Ml(t,a){if(!Qp&&Qu){Qp=!0;do for(var o=!1,u=Ju;u!==null;){if(t!==0){var p=u.pendingLanes;if(p===0)var g=0;else{var w=u.suspendedLanes,R=u.pingedLanes;g=(1<<31-on(42|t)+1)-1,g&=p&~(w&~R),g=g&201326741?g&201326741|1:g?g|2:0}g!==0&&(o=!0,BS(u,g))}else g=st,g=Ae(u,u===Dt?g:0,u.cancelPendingCommit!==null||u.timeoutHandle!==-1),(g&3)===0||Ve(u,g)||(o=!0,BS(u,g));u=u.next}while(o);Qp=!1}}function PT(){zS()}function zS(){Qu=Jp=!1;var t=0;ui!==0&&QT()&&(t=ui);for(var a=qt(),o=null,u=Ju;u!==null;){var p=u.next,g=US(u,a);g===0?(u.next=null,o===null?Ju=p:o.next=p,p===null&&(no=o)):(o=u,(t!==0||(g&3)!==0)&&(Qu=!0)),u=p}cn!==0&&cn!==5||Ml(t),ui!==0&&(ui=0)}function US(t,a){for(var o=t.suspendedLanes,u=t.pingedLanes,p=t.expirationTimes,g=t.pendingLanes&-62914561;0R)break;var re=z.transferSize,le=z.initiatorType;re&&XS(le)&&(z=z.responseEnd,w+=re*(z"u"?null:document;function lw(t,a,o){var u=ro;if(u&&typeof a=="string"&&a){var p=Hn(a);p='link[rel="'+t+'"][href="'+p+'"]',typeof o=="string"&&(p+='[crossorigin="'+o+'"]'),ow.has(p)||(ow.add(p),t={rel:t,crossOrigin:o,href:a},u.querySelector(p)===null&&(a=u.createElement("link"),wn(a,"link",t),Jt(a),u.head.appendChild(a)))}}function ok(t){ka.D(t),lw("dns-prefetch",t,null)}function lk(t,a){ka.C(t,a),lw("preconnect",t,a)}function ck(t,a,o){ka.L(t,a,o);var u=ro;if(u&&t&&a){var p='link[rel="preload"][as="'+Hn(a)+'"]';a==="image"&&o&&o.imageSrcSet?(p+='[imagesrcset="'+Hn(o.imageSrcSet)+'"]',typeof o.imageSizes=="string"&&(p+='[imagesizes="'+Hn(o.imageSizes)+'"]')):p+='[href="'+Hn(t)+'"]';var g=p;switch(a){case"style":g=ao(t);break;case"script":g=io(t)}yr.has(g)||(t=y({rel:"preload",href:a==="image"&&o&&o.imageSrcSet?void 0:t,as:a},o),yr.set(g,t),u.querySelector(p)!==null||a==="style"&&u.querySelector(Hl(g))||a==="script"&&u.querySelector(zl(g))||(a=u.createElement("link"),wn(a,"link",t),Jt(a),u.head.appendChild(a)))}}function uk(t,a){ka.m(t,a);var o=ro;if(o&&t){var u=a&&typeof a.as=="string"?a.as:"script",p='link[rel="modulepreload"][as="'+Hn(u)+'"][href="'+Hn(t)+'"]',g=p;switch(u){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":g=io(t)}if(!yr.has(g)&&(t=y({rel:"modulepreload",href:t},a),yr.set(g,t),o.querySelector(p)===null)){switch(u){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(o.querySelector(zl(g)))return}u=o.createElement("link"),wn(u,"link",t),Jt(u),o.head.appendChild(u)}}}function dk(t,a,o){ka.S(t,a,o);var u=ro;if(u&&t){var p=Pa(u).hoistableStyles,g=ao(t);a=a||"default";var w=p.get(g);if(!w){var R={loading:0,preload:null};if(w=u.querySelector(Hl(g)))R.loading=5;else{t=y({rel:"stylesheet",href:t,"data-precedence":a},o),(o=yr.get(g))&&pg(t,o);var z=w=u.createElement("link");Jt(z),wn(z,"link",t),z._p=new Promise(function(X,re){z.onload=X,z.onerror=re}),z.addEventListener("load",function(){R.loading|=1}),z.addEventListener("error",function(){R.loading|=2}),R.loading|=4,rd(w,a,u)}w={type:"stylesheet",instance:w,count:1,state:R},p.set(g,w)}}}function fk(t,a){ka.X(t,a);var o=ro;if(o&&t){var u=Pa(o).hoistableScripts,p=io(t),g=u.get(p);g||(g=o.querySelector(zl(p)),g||(t=y({src:t,async:!0},a),(a=yr.get(p))&&gg(t,a),g=o.createElement("script"),Jt(g),wn(g,"link",t),o.head.appendChild(g)),g={type:"script",instance:g,count:1,state:null},u.set(p,g))}}function hk(t,a){ka.M(t,a);var o=ro;if(o&&t){var u=Pa(o).hoistableScripts,p=io(t),g=u.get(p);g||(g=o.querySelector(zl(p)),g||(t=y({src:t,async:!0,type:"module"},a),(a=yr.get(p))&&gg(t,a),g=o.createElement("script"),Jt(g),wn(g,"link",t),o.head.appendChild(g)),g={type:"script",instance:g,count:1,state:null},u.set(p,g))}}function cw(t,a,o,u){var p=(p=ie.current)?nd(p):null;if(!p)throw Error(r(446));switch(t){case"meta":case"title":return null;case"style":return typeof o.precedence=="string"&&typeof o.href=="string"?(a=ao(o.href),o=Pa(p).hoistableStyles,u=o.get(a),u||(u={type:"style",instance:null,count:0,state:null},o.set(a,u)),u):{type:"void",instance:null,count:0,state:null};case"link":if(o.rel==="stylesheet"&&typeof o.href=="string"&&typeof o.precedence=="string"){t=ao(o.href);var g=Pa(p).hoistableStyles,w=g.get(t);if(w||(p=p.ownerDocument||p,w={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},g.set(t,w),(g=p.querySelector(Hl(t)))&&!g._p&&(w.instance=g,w.state.loading=5),yr.has(t)||(o={rel:"preload",as:"style",href:o.href,crossOrigin:o.crossOrigin,integrity:o.integrity,media:o.media,hrefLang:o.hrefLang,referrerPolicy:o.referrerPolicy},yr.set(t,o),g||pk(p,t,o,w.state))),a&&u===null)throw Error(r(528,""));return w}if(a&&u!==null)throw Error(r(529,""));return null;case"script":return a=o.async,o=o.src,typeof o=="string"&&a&&typeof a!="function"&&typeof a!="symbol"?(a=io(o),o=Pa(p).hoistableScripts,u=o.get(a),u||(u={type:"script",instance:null,count:0,state:null},o.set(a,u)),u):{type:"void",instance:null,count:0,state:null};default:throw Error(r(444,t))}}function ao(t){return'href="'+Hn(t)+'"'}function Hl(t){return'link[rel="stylesheet"]['+t+"]"}function uw(t){return y({},t,{"data-precedence":t.precedence,precedence:null})}function pk(t,a,o,u){t.querySelector('link[rel="preload"][as="style"]['+a+"]")?u.loading=1:(a=t.createElement("link"),u.preload=a,a.addEventListener("load",function(){return u.loading|=1}),a.addEventListener("error",function(){return u.loading|=2}),wn(a,"link",o),Jt(a),t.head.appendChild(a))}function io(t){return'[src="'+Hn(t)+'"]'}function zl(t){return"script[async]"+t}function dw(t,a,o){if(a.count++,a.instance===null)switch(a.type){case"style":var u=t.querySelector('style[data-href~="'+Hn(o.href)+'"]');if(u)return a.instance=u,Jt(u),u;var p=y({},o,{"data-href":o.href,"data-precedence":o.precedence,href:null,precedence:null});return u=(t.ownerDocument||t).createElement("style"),Jt(u),wn(u,"style",p),rd(u,o.precedence,t),a.instance=u;case"stylesheet":p=ao(o.href);var g=t.querySelector(Hl(p));if(g)return a.state.loading|=4,a.instance=g,Jt(g),g;u=uw(o),(p=yr.get(p))&&pg(u,p),g=(t.ownerDocument||t).createElement("link"),Jt(g);var w=g;return w._p=new Promise(function(R,z){w.onload=R,w.onerror=z}),wn(g,"link",u),a.state.loading|=4,rd(g,o.precedence,t),a.instance=g;case"script":return g=io(o.src),(p=t.querySelector(zl(g)))?(a.instance=p,Jt(p),p):(u=o,(p=yr.get(g))&&(u=y({},o),gg(u,p)),t=t.ownerDocument||t,p=t.createElement("script"),Jt(p),wn(p,"link",u),t.head.appendChild(p),a.instance=p);case"void":return null;default:throw Error(r(443,a.type))}else a.type==="stylesheet"&&(a.state.loading&4)===0&&(u=a.instance,a.state.loading|=4,rd(u,o.precedence,t));return a.instance}function rd(t,a,o){for(var u=o.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),p=u.length?u[u.length-1]:null,g=p,w=0;w title"):null)}function gk(t,a,o){if(o===1||a.itemProp!=null)return!1;switch(t){case"meta":case"title":return!0;case"style":if(typeof a.precedence!="string"||typeof a.href!="string"||a.href==="")break;return!0;case"link":if(typeof a.rel!="string"||typeof a.href!="string"||a.href===""||a.onLoad||a.onError)break;return a.rel==="stylesheet"?(t=a.disabled,typeof a.precedence=="string"&&t==null):!0;case"script":if(a.async&&typeof a.async!="function"&&typeof a.async!="symbol"&&!a.onLoad&&!a.onError&&a.src&&typeof a.src=="string")return!0}return!1}function pw(t){return!(t.type==="stylesheet"&&(t.state.loading&3)===0)}function mk(t,a,o,u){if(o.type==="stylesheet"&&(typeof u.media!="string"||matchMedia(u.media).matches!==!1)&&(o.state.loading&4)===0){if(o.instance===null){var p=ao(u.href),g=a.querySelector(Hl(p));if(g){a=g._p,a!==null&&typeof a=="object"&&typeof a.then=="function"&&(t.count++,t=id.bind(t),a.then(t,t)),o.state.loading|=4,o.instance=g,Jt(g);return}g=a.ownerDocument||a,u=uw(u),(p=yr.get(p))&&pg(u,p),g=g.createElement("link"),Jt(g);var w=g;w._p=new Promise(function(R,z){w.onload=R,w.onerror=z}),wn(g,"link",u),o.instance=g}t.stylesheets===null&&(t.stylesheets=new Map),t.stylesheets.set(o,a),(a=o.state.preload)&&(o.state.loading&3)===0&&(t.count++,o=id.bind(t),a.addEventListener("load",o),a.addEventListener("error",o))}}var mg=0;function yk(t,a){return t.stylesheets&&t.count===0&&od(t,t.stylesheets),0mg?50:800)+a);return t.unsuspend=o,function(){t.unsuspend=null,clearTimeout(u),clearTimeout(p)}}:null}function id(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)od(this,this.stylesheets);else if(this.unsuspend){var t=this.unsuspend;this.unsuspend=null,t()}}}var sd=null;function od(t,a){t.stylesheets=null,t.unsuspend!==null&&(t.count++,sd=new Map,a.forEach(bk,t),sd=null,id.call(t))}function bk(t,a){if(!(a.state.loading&4)){var o=sd.get(t);if(o)var u=o.get(null);else{o=new Map,sd.set(t,o);for(var p=t.querySelectorAll("link[data-precedence],style[data-precedence]"),g=0;g"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(s)}catch(e){console.error(e)}}return s(),yd.exports=Nw(),yd.exports}var wd=Iw();const Cd=ta(wd),lo=[],jw=50;let Ed=!1;function Lg(){try{return window.G7Core?.devTools}catch{return}}function ns(s,e,n){const r=Lg();if(Ed&&r?.isEnabled?.()){r.trackLog?.(s,e,n);return}Ed||(s==="error"||s==="warn")&&lo.length{n.isDebugEnabled()&&console.log(e,...r),ns("log",s,r)},warn:(...r)=>{n.isDebugEnabled()&&console.warn(e,...r),ns("warn",s,r)},error:(...r)=>{n.isDebugEnabled()&&console.error(e,...r),ns("error",s,r)}}}co.getInstance();const $g="extension",rs="extensionless",Mg="file";function Hw(){const s=globalThis?.G7Config;if(globalThis?.__g7AssetUrlMode===rs)return rs;const n=s?.assetUrlMode;return n===rs||n===$g?n:s?.settings?.general?.asset_url_mode===rs?rs:$g}function Ad(){return Hw()===rs}function zw(s,e,n){return xd("templates",s,e,n)}function Uw(s,e){const n=e.replace(/^\/+/,"").replace(/\/+$/,""),r=encodeURIComponent(s),i=uo(`templates/${s}/assets/${n}`);return i!==null?i:`/api/templates/assets/${r}/${n}`}function Pw(s,e,n){return xd("modules",s,e,n)}function Bw(s,e,n){return xd("plugins",s,e,n)}function xd(s,e,n,r){const i=n.replace(/^\/+/,""),l=encodeURIComponent(e);if(!Ad())return`/api/${s}/assets/${l}/${i}${Fw(r)}`;let c=`${Mg}=${encodeURIComponent(i)}`;return r!=null&&r!==""&&(c+=`&v=${r}`),`/api/${s}/assets/${l}?${c}`}function jr(s,e,n,r){const i=s.replace(/\/+$/,""),l=e.replace(/^\.+/,""),c=Ad()?i:`${i}.${l}`,d=[];return r&&d.push(r.replace(/^[?&]+/,"")),n!=null&&n!==""&&d.push(`v=${n}`),d.length>0?`${c}?${d.join("&")}`:c}function Ng(){const s=globalThis?.G7Config?.staticBase;return typeof s=="string"&&s!==""?s.replace(/\/+$/,""):null}function qw(){const s=Ng();if(!s)return null;const e=s.match(/\/(\d+)$/);return e?Number(e[1]):null}function uo(s,e){const n=Ng();if(!n)return null;const r=s.replace(/^\/+/,"");return e!==void 0&&e>0&&e!==qw()?`${n.replace(/\/\d+$/,"")}/${e}/${r}`:`${n}/${r}`}function Td(s){if(!s)return null;const e=globalThis?.location?.origin,r=(e&&s.startsWith(e)?s.slice(e.length):s).match(/^\/build\/ext\/(\d+)\/(.+)$/);if(!r)return null;const i=r[1],l=r[2].split("?")[0],c=l.match(/^(templates|modules|plugins)\/([^/]+)\/assets\/(.+)$/);if(c){const[,h,m,y]=c;return`/api/${h}/assets/${m}/${y}?v=${i}`}const d=l.match(/^bundles\/(modules|plugins)\.(js|css)$/);if(d)return`/api/${d[1]}/bundle.${d[2]}?v=${i}`;const f=l.match(/^templates\/([^/]+)\/(routes\.json|components\.json|lang\/([a-zA-Z-]+)\.json)$/);if(f){const[,h,m]=f,y=m.replace(/\.json$/,"");return`/api/templates/${h}/${y}.json?v=${i}`}return null}function Tn(s){if(!s||!Ad())return s;const e=globalThis?.location?.origin,n=e&&s.startsWith(e)?s.slice(e.length):s;if(!n.startsWith("/api/"))return s;const[r,i]=Gw(n),l=r.match(/^\/api\/(modules|plugins)\/bundle\.(js|css)$/);if(l)return Ig(`/api/${l[1]}/bundle/${l[2]}`,i);const c=r.match(/^\/api\/(templates|modules|plugins)\/assets\/([^/]+)\/(.+)$/);if(c){const[,f,h,m]=c,y=`${Mg}=${encodeURIComponent(decodeURIComponent(m))}`;return`/api/${f}/assets/${h}?${y}${i?`&${i}`:""}`}const d=r.match(/^(\/api\/.+)\.(json|js|css)$/);return d?Ig(d[1],i):s}function Gw(s){const e=s.indexOf("?");return e===-1?[s,""]:[s.slice(0,e),s.slice(e+1)]}function Ig(s,e){return e?`${s}?${e}`:s}function Fw(s){return s==null||s===""?"":`?v=${s}`}const na=dt("networkResilience"),kd=2,Rd=300,Dd=2e3,Vw=15e3;function Od(s){return s?.name==="AbortError"}function jg(s){return Od(s)?!1:s instanceof TypeError}let Gl=!1,Hg=!1;function Fl(){return Gl}function Kw(){typeof window>"u"||Hg||(Hg=!0,window.addEventListener("pagehide",()=>{Gl=!0}),window.addEventListener("pageshow",s=>{s.persisted&&(Gl=!1)}),window.addEventListener("beforeunload",()=>{Gl=!0}))}function Ld(s,e,n){const r=Math.min(e*Math.pow(2,s),n),i=r*.25*(Math.random()*2-1);return Math.max(0,Math.round(r+i))}function $d(s){return new Promise(e=>setTimeout(e,s))}async function Vl(s,e={}){const{retries:n=kd,baseDelayMs:r=Rd,maxDelayMs:i=Dd,timeoutMs:l=Vw,label:c=s,init:d}=e,f=n+1;let h;for(let m=0;m0?new AbortController:null;try{const _={...d};if(v){const A=d?.signal;A&&(A.aborted?v.abort():A.addEventListener("abort",()=>v.abort(),{once:!0})),_.signal=v.signal,S=setTimeout(()=>{y=!0,v.abort()},l)}return await fetch(s,_)}catch(_){if(h=_,Od(_)&&!y||!(y||jg(_)))throw _;if(Fl())throw na.warn(`Document unloading, aborting retries: ${c}`),_;if(m===f-1)throw na.warn(`All ${f} attempts failed: ${c}`,_),_;const L=Ld(m,r,i);na.warn(`Network failure (attempt ${m+1}/${f}), retrying in ${L}ms: ${c}`),await $d(L)}finally{S!==void 0&&clearTimeout(S)}}throw h}async function ra(s,e={},n={}){const{retries:r=kd,baseDelayMs:i=Rd,maxDelayMs:l=Dd,label:c=s}=n,d=r+1;for(let f=0;f{const i=document.createElement("script");i.src=s,i.async=!1;for(const[l,c]of Object.entries(e))l==="id"?i.id=c:i.setAttribute(l,c);i.onload=()=>n(),i.onerror=()=>r(new Error(`Failed to load script: ${s}`)),document.head.appendChild(i)})}async function yi(s,e={},n={}){const{retries:r=kd,baseDelayMs:i=Rd,maxDelayMs:l=Dd,label:c=s}=n,d=r+1;for(let f=0;f{s.onload=()=>e(),s.onerror=()=>n(new Error(`Failed to load stylesheet: ${s.href}`))})}async function Kl(s,e,n={}){if(!s)return Vl(e,n);try{const r=await fetch(s,n.init);if(r.ok){const i=await r.text();try{return JSON.parse(i),new Response(i,{status:r.status,statusText:r.statusText,headers:r.headers})}catch{return console.warn(`[fetchStaticFirst] Static fast path returned malformed JSON — falling back to API: ${s}`),Vl(e,n)}}console.warn(`[fetchStaticFirst] Static fast path miss (${r.status}) — falling back to API: ${s}`)}catch(r){console.warn(`[fetchStaticFirst] Static fast path fetch failed — falling back to API: ${s}`,r)}return Vl(e,n)}const Hr=dt("ComponentRegistry");class un extends Error{constructor(n,r,i){super(n);M(this,"code");M(this,"details");this.code=r,this.details=i,this.name="ComponentRegistryError"}}const Kn=class Kn{constructor(){M(this,"registry",{});M(this,"manifest",null);M(this,"cacheVersion",0);M(this,"loadingState","idle");M(this,"error",null);M(this,"templateId",null);M(this,"templateType",null)}static getInstance(){return Kn.instance||(Kn.instance=new Kn),Kn.instance}static createIsolatedInstance(){return new Kn}static resetInstance(){Kn.instance=null}async loadComponents(e,n,r=0){if(this.loadingState==="loading")throw new un("Components are already being loaded","LOADING_IN_PROGRESS");if(this.loadingState==="loaded"&&this.templateId===e&&this.templateType===n){Hr.log("Components already loaded for template:",e,n);return}this.loadingState="loading",this.templateId=e,this.templateType=n,this.cacheVersion=r,this.error=null;try{await this.loadManifest(),await this.loadComponentBundle(),this.loadingState="loaded",Hr.log("Successfully loaded components:",Object.keys(this.registry).length)}catch(i){throw this.loadingState="error",this.error=i instanceof Error?i:new Error(String(i)),new un(`Failed to load components: ${this.error.message}`,"LOAD_FAILED",{originalError:this.error})}}async loadManifest(){try{if(!this.templateId)throw new un("Template ID not set","TEMPLATE_ID_NOT_SET");const e=`${this.templateId}:${this.templateType}:v${this.cacheVersion||0}`;if(Kn.manifestCache.has(e)){this.manifest=Kn.manifestCache.get(e),Hr.log("Manifest loaded from cache:",this.manifest.templateId);return}const n=jr(`/api/templates/${this.templateId}/components`,"json",this.cacheVersion>0?this.cacheVersion:null),r=await Kl(this.cacheVersion>0?uo(`templates/${this.templateId}/components.json`,this.cacheVersion):null,n,{label:"components.json"});if(!r.ok)throw new un(`Failed to fetch manifest: ${r.status} ${r.statusText}`,"MANIFEST_FETCH_FAILED",{status:r.status,statusText:r.statusText});const i=await r.json();this.validateManifest(i),this.manifest=i,Kn.manifestCache.set(e,i),Hr.log("Manifest loaded and cached:",i.templateId)}catch(e){throw e instanceof un?e:new un("Failed to load component manifest","MANIFEST_LOAD_FAILED",{originalError:e})}}validateManifest(e){if(!e.version)throw new un("Manifest missing required field: version","MANIFEST_INVALID",{field:"version"});if(!e.templateId)throw new un("Manifest missing required field: templateId","MANIFEST_INVALID",{field:"templateId"});if(!e.components||typeof e.components!="object")throw new un("Manifest missing required field: components","MANIFEST_INVALID",{field:"components"});const n=["basic","composite","layout"];for(const r of n){if(!Array.isArray(e.components[r]))throw new un(`Manifest field 'components.${r}' must be an array`,"MANIFEST_INVALID",{field:`components.${r}`,value:e.components[r]});e.components[r].forEach((i,l)=>{if(!i.name||typeof i.name!="string")throw new un(`Invalid component metadata at ${r}[${l}]: missing or invalid 'name'`,"MANIFEST_INVALID",{type:r,index:l,metadata:i});if(!i.type||typeof i.type!="string")throw new un(`Invalid component metadata at ${r}[${l}]: missing or invalid 'type'`,"MANIFEST_INVALID",{type:r,index:l,metadata:i})})}Hr.log("Manifest validation passed")}async loadComponentBundle(){try{if(!this.templateId)throw new un("Template ID not set","TEMPLATE_ID_NOT_SET");const e=this.getGlobalVariableName(),n=window[e];if(!n||typeof n!="object")throw new un(`Component bundle not loaded. Expected global variable: ${e}. Ensure admin.blade.php includes the IIFE bundle script.`,"BUNDLE_NOT_LOADED",{expectedVariable:e});await this.registerComponentsFromManifest(n),Hr.log("Component bundle loaded from global variable:",e)}catch(e){throw e instanceof un?e:new un("Failed to load component bundle","BUNDLE_LOAD_FAILED",{originalError:e})}}getGlobalVariableName(){if(!this.templateId)throw new un("Template ID not set","TEMPLATE_ID_NOT_SET");return this.templateId.split(/[-_]/).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}async registerComponentsFromManifest(e){if(!this.manifest)throw new un("Manifest not loaded","MANIFEST_NOT_LOADED");const n=["basic","composite","layout"];for(const r of n){const i=this.manifest.components[r]||[];for(const l of i){const c=l.name,d=e[c];if(!d){Hr.warn(`Component '${c}' not found in bundle`);continue}this.registerComponent(c,d,l)}}}registerComponent(e,n,r){this.registry[e]&&Hr.warn(`Component '${e}' already registered, overwriting`);const i=Ye.memo(n);this.registry[e]={component:i,metadata:r},Hr.log(`[ComponentRegistry] Registered component: ${e} (${r.type})`)}getComponent(e){const n=this.registry[e];return n?n.component:null}getMetadata(e){const n=this.registry[e];return n?n.metadata:null}hasComponent(e){return e in this.registry}getComponentsByType(e){return Object.entries(this.registry).filter(([n,r])=>r.metadata.type===e).map(([n,r])=>n)}getAllComponents(){return Object.keys(this.registry)}getComponentMap(){const e={};for(const[n,r]of Object.entries(this.registry))e[n]=r.component;return e}getLoadingState(){return this.loadingState}getError(){return this.error}getTemplateId(){return this.templateId}getManifest(){return this.manifest}clear(){this.registry={},this.manifest=null,this.loadingState="idle",this.error=null,this.templateId=null,this.templateType=null,Hr.log("Registry cleared")}};M(Kn,"instance",null),M(Kn,"manifestCache",new Map);let br=Kn;const zg=dt("TranslationEngine");class Md extends Error{constructor(n,r,i){super(n);M(this,"key");M(this,"locale");this.key=r,this.locale=i,this.name="TranslationError"}}const Nn=class Nn{constructor(e={}){M(this,"cache",new Map);M(this,"translations",new Map);M(this,"options");M(this,"cacheVersion",0);this.options={defaultLocale:e.defaultLocale||"ko",fallbackLocale:e.fallbackLocale||"en",cacheTTL:e.cacheTTL||3e5}}static getInstance(e={}){return Nn.instance||(Nn.instance=new Nn(e)),Nn.instance}static resetInstance(){Nn.instance=null}setCacheVersion(e){this.cacheVersion!==e&&(zg.log("Cache version updated:",this.cacheVersion,"->",e),this.cacheVersion=e,this.cache.clear())}getCacheVersion(){return this.cacheVersion}async loadTranslations(e,n,r="/api",i=!1){const l=`${e}:${n}`;if(!i){const c=this.getFromCache(l);if(c)return this.translations.set(l,c),c}try{const c=[];i&&c.push(`_=${Date.now()}`);const d=jr(`${r}/templates/${e}/lang/${n}`,"json",this.cacheVersion>0?this.cacheVersion:null,c.length>0?c.join("&"):void 0),f=!i&&this.cacheVersion>0?uo(`templates/${e}/lang/${n}.json`,this.cacheVersion):null,h=f!==null?await Kl(f,d,{label:`lang/${n}.json`}):await fetch(d);if(!h.ok)throw new Md(`Failed to load translations: ${h.statusText}`,void 0,n);const y=await h.json();return this.saveToCache(l,y),this.translations.set(l,y),y}catch(c){throw new Md(`Failed to fetch translations for ${n}: ${c instanceof Error?c.message:String(c)}`,void 0,n)}}resolveTranslations(e,n,r){let i=e;const l=5;let c=0;for(;c"="+this.translate(m,n,void 0,r)),i===d)break;c++}return i.replace(Nn.TRANSLATION_PATTERN,(d,f,h)=>{const{cleanedParams:m,trailing:y}=this.separateTrailingText(h);return this.translate(f,n,m,r)+y})}translate(e,n,r,i){const l=this.getTranslation(e,n),c=r&&this.cleanParamsStr(r);if(c){const d=this.parseParams(c,i);return this.replaceParams(l,d)}return l}getTranslation(e,n){const{templateId:r,locale:i}=n,l=`${r}:${i}`,c=this.translations.get(l);if(c){const d=this.getNestedValue(c,e);if(d!==null)return d}if(i!==this.options.fallbackLocale){const d=`${r}:${this.options.fallbackLocale}`,f=this.translations.get(d);if(f){const h=this.getNestedValue(f,e);if(h!==null)return h}}return e}getNestedValue(e,n){const r=n.split(".");let i=e;for(const l of r){if(i==null||typeof i!="object")return null;i=i[l]}return typeof i=="string"?i:null}setTranslationValue(e,n,r,i){const l=`${e}:${n}`,c=this.translations.get(l)??{},d=r.split(".");let f=c;for(let h=0;h(l.push(f),`__PLACEHOLDER_${l.length-1}__`)).matchAll(Nn.PARAM_PATTERN);for(const f of d){const[,h,m]=f,y=m.replace(/__PLACEHOLDER_(\d+)__/g,(S,v)=>l[parseInt(v,10)]);r[h.trim()]=this.resolveParamValue(y.trim(),n)}return r}resolveParamValue(e,n){if(e.startsWith("{{")&&e.endsWith("}}")){const r=e.slice(2,-2).trim();if(/[|&()[\]!?:+\-*/%<>=\s]/.test(r)&&n)try{const l=Xd.evaluateExpression(r,n);return String(l??"")}catch(l){return zg.error("Expression evaluation failed:",r,l),""}else{const l=this.getNestedDataValue(n,r);return String(l??"")}}return e}separateTrailingText(e){if(!e)return{cleanedParams:void 0,trailing:""};if(e.trimEnd().endsWith("}}"))return{cleanedParams:e,trailing:""};if(!(e.startsWith("|")?e.slice(1):e).includes("="))return{cleanedParams:void 0,trailing:e};const r=e.match(/(\s+[^\p{L}\w=|&\s][^\p{L}\w=]*\s*)$/u);return r?{cleanedParams:e.slice(0,-r[1].length),trailing:r[1]}:{cleanedParams:e,trailing:""}}cleanParamsStr(e){return this.separateTrailingText(e).cleanedParams||""}getNestedDataValue(e,n){if(!e)return;const r=n.split(".");let i=e;for(const l of r){if(i==null)return;i=i[l]}return i}replaceParams(e,n){let r=e;for(const[i,l]of Object.entries(n)){const c=new RegExp(`\\{\\{${i}\\}\\}`,"g");r=r.replace(c,String(l));const d=new RegExp(`\\{${i}\\}`,"g");r=r.replace(d,String(l))}return r}getFromCache(e){const n=this.cache.get(e);return n?Date.now()-n.timestamp>this.options.cacheTTL?(this.cache.delete(e),null):n.data:null}saveToCache(e,n){this.cache.set(e,{data:n,timestamp:Date.now()})}clearCache(){this.cache.clear(),this.translations.clear()}pruneCache(){const e=Date.now(),n=[];for(const[r,i]of this.cache.entries())e-i.timestamp>this.options.cacheTTL&&n.push(r);for(const r of n)this.cache.delete(r)}getCacheStats(){const e=Date.now();let n=0;for(const r of this.cache.values())e-r.timestamp>this.options.cacheTTL&&n++;return{size:this.cache.size,expired:n}}};M(Nn,"instance",null),M(Nn,"TRANSLATION_PATTERN",/\$t:(?:defer:)?([a-zA-Z0-9._-]+)(\|(?:(?!\$t:).)+)?/g),M(Nn,"NESTED_TRANSLATION_PARAM_PATTERN",/=(\$t:([a-zA-Z0-9._-]+))(?=[|&\s]|$)/g),M(Nn,"PARAM_PATTERN",/([^=|&]+)=([^|&]+)/g);let Ra=Nn,Nd=null;function Jw(s){return Nd||(Nd=new Ra(s)),Nd}const Ug=Object.freeze(Object.defineProperty({__proto__:null,TranslationEngine:Ra,TranslationError:Md,getTranslationEngine:Jw},Symbol.toStringTag,{value:"Module"})),as=dt("PipeRegistry");function Pg(s,e){const n=s.getFullYear(),r=String(s.getMonth()+1).padStart(2,"0"),i=String(s.getDate()).padStart(2,"0"),l=String(s.getHours()).padStart(2,"0"),c=String(s.getMinutes()).padStart(2,"0"),d=String(s.getSeconds()).padStart(2,"0");return e.replace("YYYY",String(n)).replace("YY",String(n).slice(-2)).replace("MM",r).replace("M",String(s.getMonth()+1)).replace("DD",i).replace("D",String(s.getDate())).replace("HH",l).replace("H",String(s.getHours())).replace("mm",c).replace("m",String(s.getMinutes())).replace("ss",d).replace("s",String(s.getSeconds()))}function Qw(s,e="ko"){const r=new Date().getTime()-s.getTime(),i=Math.floor(r/1e3),l=Math.floor(i/60),c=Math.floor(l/60),d=Math.floor(c/24),f=Math.floor(d/7),h=Math.floor(d/30),m=Math.floor(d/365);return e==="ko"?i<60?"방금 전":l<60?`${l}분 전`:c<24?`${c}시간 전`:d<7?`${d}일 전`:f<4?`${f}주 전`:h<12?`${h}개월 전`:`${m}년 전`:i<60?"just now":l<60?`${l} minute${l===1?"":"s"} ago`:c<24?`${c} hour${c===1?"":"s"} ago`:d<7?`${d} day${d===1?"":"s"} ago`:f<4?`${f} week${f===1?"":"s"} ago`:h<12?`${h} month${h===1?"":"s"} ago`:`${m} year${m===1?"":"s"} ago`}function Id(s){if(s==null)return null;if(s instanceof Date)return s;if(typeof s=="number")return new Date(s);if(typeof s=="string"){const e=new Date(s);return isNaN(e.getTime())?null:e}return null}const fo={date:{fn:(s,e="YYYY-MM-DD")=>{const n=Id(s);return n?Pg(n,e):""},description:"날짜 포맷 (기본: YYYY-MM-DD)"},datetime:{fn:(s,e="YYYY-MM-DD HH:mm")=>{const n=Id(s);return n?Pg(n,e):""},description:"날짜+시간 포맷 (기본: YYYY-MM-DD HH:mm)"},relativeTime:{fn:(s,e="ko")=>{const n=Id(s);return n?Qw(n,e):""},description:'상대 시간 표시 (예: "3분 전")'},number:{fn:(s,e)=>{const n=Number(s);if(isNaN(n))return String(s??"");const r={};return e!==void 0&&(r.minimumFractionDigits=e,r.maximumFractionDigits=e),n.toLocaleString(void 0,r)},description:"숫자 포맷 (천단위 구분, 선택적 소수점)"},truncate:{fn:(s,e=100,n="...")=>typeof s!="string"?String(s??""):s.length<=e?s:s.slice(0,e)+n,description:'문자열 자르기 (기본: 100자, 접미사: "...")'},uppercase:{fn:s=>typeof s!="string"?String(s??""):s.toUpperCase(),description:"대문자 변환"},lowercase:{fn:s=>typeof s!="string"?String(s??""):s.toLowerCase(),description:"소문자 변환"},stripHtml:{fn:s=>typeof s!="string"?String(s??""):s.replace(/<[^>]*>/g,""),description:"HTML 태그 제거"},default:{fn:(s,e="")=>s==null||s===""?e:s,description:"기본값 설정 (null, undefined, 빈문자열 시)"},fallback:{fn:(s,e)=>s??e,description:"폴백 값 설정 (null, undefined 시만)"},first:{fn:s=>{if(Array.isArray(s))return s[0]},description:"배열의 첫 번째 요소"},last:{fn:s=>{if(Array.isArray(s))return s[s.length-1]},description:"배열의 마지막 요소"},join:{fn:(s,e=", ")=>Array.isArray(s)?s.join(e):"",description:'배열을 문자열로 결합 (기본 구분자: ", ")'},length:{fn:s=>Array.isArray(s)||typeof s=="string"?s.length:0,description:"배열/문자열 길이"},filterBy:{fn:(s,e,n)=>Array.isArray(s)?Array.isArray(e)?s.filter(r=>{const i=n?r?.[n]:r;return e.includes(i)}):s:[],description:"배열 필터링 (allowList에 포함된 항목만 반환)"},keys:{fn:s=>s==null||typeof s!="object"?[]:Object.keys(s),description:"객체의 키 배열"},values:{fn:s=>s==null||typeof s!="object"?[]:Object.values(s),description:"객체의 값 배열"},json:{fn:(s,e)=>{try{return JSON.stringify(s,null,e)}catch{return""}},description:"JSON 문자열로 변환"},localized:{fn:(s,e)=>s==null?"":typeof s=="string"?s:typeof s!="object"?String(s):s[e||"ko"]||s.ko||s.en||Object.values(s)[0]||"",description:"다국어 객체에서 로케일에 맞는 값 추출"}},is=new Map,xi=class xi{static getInstance(){return xi.instance||(xi.instance=new xi),xi.instance}register(e,n,r){if(fo[e]){as.warn(`[PipeRegistry] 내장 파이프를 덮어쓸 수 없습니다: ${e}`);return}is.set(e,{fn:n,description:r}),as.log(`[PipeRegistry] 커스텀 파이프 등록됨: ${e}`)}unregister(e){if(fo[e])return as.warn(`[PipeRegistry] 내장 파이프는 해제할 수 없습니다: ${e}`),!1;const n=is.delete(e);return n&&as.log(`[PipeRegistry] 커스텀 파이프 해제됨: ${e}`),n}get(e){const n=fo[e];return n?n.fn:is.get(e)?.fn}has(e){return!!fo[e]||is.has(e)}execute(e,n,r=[]){const i=this.get(e);if(!i)return as.warn(`[PipeRegistry] 알 수 없는 파이프: ${e}`),n;try{return i(n,...r)}catch(l){return as.error(`[PipeRegistry] 파이프 실행 오류 (${e}):`,l),n}}list(){const e=[];for(const[n,r]of Object.entries(fo))e.push({name:n,description:r.description,type:"built-in"});for(const[n,r]of is.entries())e.push({name:n,description:r.description,type:"custom"});return e.sort((n,r)=>n.name.localeCompare(r.name))}clearCustomPipes(){is.clear()}};M(xi,"instance",null);let Wl=xi;Wl.getInstance();function Zw(s){const e=s.trim(),n=e.indexOf("(");if(n===-1)return{name:e,args:[]};const r=e.slice(0,n).trim(),i=e.slice(n+1,-1);if(!i.trim())return{name:r,args:[]};const l=[];let c="",d=null,f=0;for(let h=0;h0?i[h-1]:"")==="\\"){c+=m;continue}if((m==='"'||m==="'")&&!d){d=m;continue}if(m===d){d=null;continue}if(d){c+=m;continue}if(m==="("||m==="["||m==="{"){f++,c+=m;continue}if(m===")"||m==="]"||m==="}"){f--,c+=m;continue}if(m===","&&f===0){l.push(Bg(c.trim())),c="";continue}c+=m}return c.trim()&&l.push(Bg(c.trim())),{name:r,args:l}}function Bg(s){if(s==="null")return null;if(s==="undefined")return;if(s==="true")return!0;if(s==="false")return!1;const e=Number(s);return!isNaN(e)&&s!==""?e:s}function e0(s){const e=[];let n="",r=null,i=0;for(let l=0;l0?s[l-1]:"",f=l0?s[r-1]:"",c=r0){r--;continue}return null}}return r===0?e.trim():null}function n0(s){const e=[];if(typeof s!="string")return e;for(let n=0;n0){i--;continue}if(s[c+1]==="}"){l=c;break}break}}l!==-1&&(e.push({start:n,end:l+2,expr:s.slice(n+2,l)}),n=l+1)}return e}function ho(s){return/[?:|&!+\-*/<>=()[\]{}]/.test(s)}function qg(s){const e=typeof s=="string"?s.trim():"";return e===""?"empty":jd.has(e)?"literal":Gn(e)?"pipe":ho(e)?"expression":"path"}function Hd(s,e,n,r){const i=typeof s=="string"?s.trim():"",l=qg(i),c=r?.skipCache?{skipCache:!0}:void 0;if(l==="empty"){r?.onEmpty?.(s);return}if(l==="literal")return jd.get(i);try{return l==="pipe"?n.evaluatePipeExpression(i,e,c,r?.trackingInfo):l==="expression"?n.evaluateExpression(i,e,r?.trackingInfo):n.resolve(i,e,c,r?.trackingInfo)}catch(d){if(r?.onError)return r.onError(d,i);throw d}}const nr="raw:";function Gg(s){return s.startsWith(nr)?s.slice(nr.length):s}const po="﷐",bi="﷑",Oa="﷒";function go(s){return po+s+bi}function Yl(s){return s.length>=2&&s.charCodeAt(0)===64976&&s.charCodeAt(s.length-1)===64977}function Xl(s){return s.includes(po)}function zd(s){return s.slice(1,-1)}function ss(s){if(typeof s=="string")return go(s);if(Array.isArray(s))return s.map(ss);if(s&&typeof s=="object"){const e={};for(const[n,r]of Object.entries(s))e[n]=ss(r);return e}return s}function La(s){if(typeof s=="string")return Yl(s)?zd(s):Xl(s)||s.includes(bi)?s.split(po).join("").split(bi).join(""):s;if(Array.isArray(s)){let e=!1;const n=s.map(r=>{const i=La(r);return i!==r&&(e=!0),i});return e?n:s}if(s&&typeof s=="object"){if(s.$$typeof!==void 0)return s;let e=!1;const n={};for(const[r,i]of Object.entries(s)){const l=La(i);l!==i&&(e=!0),n[r]=l}return e?n:s}return s}const mo=new Set(["constructor","__proto__","prototype","__lookupGetter__","__lookupSetter__","__defineGetter__","__defineSetter__"]),r0=new Set(["Function","eval","globalThis","window","self","document","require","module","process","Reflect","Proxy","WebAssembly","import","constructor"]);function Fg(s,e){if(s!==null&&(typeof s=="object"||typeof s=="function")&&Vg.has(s))throw new Error(`Object.${e} on a built-in global object is not allowed`);return s}const a0=Object.freeze({keys:Object.keys,values:Object.values,entries:Object.entries,assign:(s,...e)=>{const n=Fg(s,"assign");for(const r of e)if(r!=null)for(const i of Object.keys(r)){if(mo.has(i))throw new Error(`Access to "${i}" is forbidden`);Kd(n,i,r[i])}return n},freeze:s=>Object.freeze(Fg(s,"freeze")),fromEntries:Object.fromEntries,create:Object.create,isFrozen:Object.isFrozen}),Ud={Math,JSON,Date,Array,Object:a0,Number,String,Boolean,Set,Map,WeakSet,WeakMap,parseInt,parseFloat,isNaN,isFinite},Pd={Date,Set,Map,WeakSet,WeakMap,Array,Number,String,Boolean,Object},Vg=new Set([...Object.values(Ud),...Object.values(Pd)].filter(s=>s!==null&&(typeof s=="object"||typeof s=="function"))),Jl=new Set(["function"]),vr=Symbol("short-circuit");class Bd{constructor(e){M(this,"value");this.value=e}}class qd{}class Gd{}function i0(s){return/[A-Za-z_$]/.test(s)}function s0(s){return/[A-Za-z0-9_$]/.test(s)}function vi(s){return s>="0"&&s<="9"}function o0(s,e,n){let r=e+1;for(;r0;){const h=s[n];if(h==="{")f++,n++;else if(h==="}"){if(f--,f===0)break;n++}else h==='"'||h==="'"?n=o0(s,n,h):h==="`"?n=Kg(s,n).end:n++}if(f!==0)throw new Error("Unterminated ${...} in template literal");i.push(s.slice(d,n)),n++;continue}l+=c,n++}throw new Error(`Unterminated template literal at position ${e}`)}function l0(s){const e=[];let n=0;const r=s.length,i=l=>n+l=r)throw new Error(`Unterminated string literal at position ${h}`);n++,e.push({type:"str",value:y,pos:h});continue}if(i0(l)){const h=n;for(n++;n"?(e.push({type:"punct",value:"=>",pos:c}),n+=2):i(1)==="="?i(2)==="="?(e.push({type:"punct",value:"===",pos:c}),n+=3):(e.push({type:"punct",value:"==",pos:c}),n+=2):(e.push({type:"punct",value:"=",pos:c}),n+=1);continue}case"!":{i(1)==="="?i(2)==="="?(e.push({type:"punct",value:"!==",pos:c}),n+=3):(e.push({type:"punct",value:"!=",pos:c}),n+=2):(e.push({type:"punct",value:"!",pos:c}),n+=1);continue}case"<":{if(i(1)==="=")e.push({type:"punct",value:"<=",pos:c}),n+=2;else{if(i(1)==="<")throw new Error("Bitwise/shift operators are not allowed");e.push({type:"punct",value:"<",pos:c}),n+=1}continue}case">":{if(i(1)==="=")e.push({type:"punct",value:">=",pos:c}),n+=2;else{if(i(1)===">")throw new Error("Bitwise/shift operators are not allowed");e.push({type:"punct",value:">",pos:c}),n+=1}continue}case"&":{if(i(1)==="&")e.push({type:"punct",value:"&&",pos:c}),n+=2;else throw new Error("Bitwise operators are not allowed");continue}case"|":{if(i(1)==="|")e.push({type:"punct",value:"||",pos:c}),n+=2;else throw new Error("Bitwise operators are not allowed");continue}case"?":{i(1)==="."&&!vi(i(2))?(e.push({type:"punct",value:"?.",pos:c}),n+=2):i(1)==="?"?(e.push({type:"punct",value:"??",pos:c}),n+=2):(e.push({type:"punct",value:"?",pos:c}),n+=1);continue}case"+":{if(i(1)==="+")throw new Error("Increment operator is not allowed");if(i(1)==="=")throw new Error("Assignment operators are not allowed");e.push({type:"punct",value:"+",pos:c}),n+=1;continue}case"-":{if(i(1)==="-")throw new Error("Decrement operator is not allowed");if(i(1)==="=")throw new Error("Assignment operators are not allowed");e.push({type:"punct",value:"-",pos:c}),n+=1;continue}case"*":{if(i(1)==="=")throw new Error("Assignment operators are not allowed");if(i(1)==="*")throw new Error("Exponentiation operator is not supported");e.push({type:"punct",value:"*",pos:c}),n+=1;continue}case"/":{if(i(1)==="=")throw new Error("Assignment operators are not allowed");e.push({type:"punct",value:"/",pos:c}),n+=1;continue}case"%":{if(i(1)==="=")throw new Error("Assignment operators are not allowed");e.push({type:"punct",value:"%",pos:c}),n+=1;continue}case"~":case"^":throw new Error("Bitwise operators are not allowed");case".":case":":case"(":case")":case"[":case"]":case"{":case"}":case",":e.push({type:"punct",value:l,pos:c}),n+=1;continue;case";":e.push({type:"punct",value:";",pos:c}),n+=1;continue;default:throw new Error(`Unexpected character "${l}" at position ${c}`)}}return e}const c0={"??":1,"||":1,"&&":2,"===":3,"!==":3,"==":3,"!=":3,"<":4,">":4,"<=":4,">=":4,"+":5,"-":5,"*":6,"/":6,"%":6},u0=new Set(["??","||","&&"]);class d0{constructor(e){M(this,"tokens");M(this,"pos",0);this.tokens=e}atEnd(){return this.pos>=this.tokens.length}peek(e=0){const n=this.pos+e;return n"}"`);this.pos++}parseExpression(){const e=this.tryParseArrow();return e||this.parseTernary()}tryParseArrow(){const e=this.pos,n=this.peek();if(!n)return null;if(n.type==="ident"&&this.isPunct("=>",1)&&!Xl.has(String(n.value))){this.pos+=1,this.pos+=1;const{body:r,isBlock:i}=this.parseArrowBody();return{type:"Arrow",params:[{name:String(n.value),default:null}],body:r,isBlock:i}}if(n.type==="punct"&&n.value==="("){this.pos+=1;const r=this.tryParseParamList();if(r&&this.isPunct(")")&&(this.pos+=1,this.isPunct("=>"))){this.pos+=1;const{body:i,isBlock:l}=this.parseArrowBody();return{type:"Arrow",params:r,body:i,isBlock:l}}return this.pos=e,null}return this.pos=e,null}tryParseParamList(){const e=[];if(this.isPunct(")"))return e;for(;;){const n=this.peek();let r=null,i;if(n&&n.type==="punct"&&n.value==="["){const c=this.tryParseArrayPattern();if(!c)return null;i=c}else if(n&&n.type==="ident"&&!Xl.has(String(n.value)))r=String(n.value),this.pos+=1;else return null;let l=null;if(this.isPunct("=")&&(this.pos+=1,l=this.parseExpression()),e.push(i?{name:r,elements:i,default:l}:{name:r,default:l}),this.isPunct(",")){this.pos+=1;continue}break}return e}tryParseArrayPattern(){const e=this.pos;this.pos+=1;const n=[];for(;;){if(this.isPunct("]"))return this.pos+=1,n;if(this.isPunct(",")){n.push(null),this.pos+=1;continue}const r=this.peek();if(!r||r.type!=="ident"||Xl.has(String(r.value)))return this.pos=e,null;if(n.push(String(r.value)),this.pos+=1,this.isPunct(",")){this.pos+=1;continue}return this.isPunct("]")?(this.pos+=1,n):(this.pos=e,null)}}parseArrowBody(){return this.isPunct("{")?{body:this.parseBlock(),isBlock:!0}:{body:this.parseExpression(),isBlock:!1}}parseBlock(){this.expectPunct("{");const e=[];for(;!this.isPunct("}");){if(this.atEnd())throw new Error("Unterminated block");e.push(this.parseStatement())}return this.expectPunct("}"),{type:"Block",body:e}}parseStatement(){const e=this.peek();if(!e)throw new Error("Unexpected end of statement");if(e.type==="punct"&&e.value==="{")return this.parseBlock();if(e.type==="punct"&&e.value===";")return this.pos+=1,{type:"Empty"};if(e.type==="ident")switch(String(e.value)){case"const":case"let":return this.parseVarDecl();case"if":return this.parseIf();case"for":return this.parseForOf();case"return":return this.parseReturn();case"try":return this.parseTry();case"break":return this.pos+=1,this.consumeSemicolon(),{type:"Break"};case"continue":return this.pos+=1,this.consumeSemicolon(),{type:"Continue"}}const n=this.parseExpression();return this.consumeSemicolon(),{type:"ExprStmt",expression:n}}consumeSemicolon(){this.isPunct(";")&&(this.pos+=1)}parseVarDecl(){this.pos+=1;const e=[];for(;;){const n=this.peek();if(!n||n.type!=="ident")throw new Error("Expected variable name in declaration");const r=String(n.value);this.pos+=1,this.expectPunct("=");const i=this.parseExpression();if(e.push({name:r,init:i}),this.isPunct(",")){this.pos+=1;continue}break}return this.consumeSemicolon(),{type:"VarDecl",declarations:e}}parseIf(){this.pos+=1,this.expectPunct("(");const e=this.parseExpression();this.expectPunct(")");const n=this.parseStatement();let r=null;const i=this.peek();return i&&i.type==="ident"&&i.value==="else"&&(this.pos+=1,r=this.parseStatement()),{type:"If",test:e,consequent:n,alternate:r}}parseForOf(){this.pos+=1,this.expectPunct("(");const e=this.peek();if(!e||e.type!=="ident"||e.value!=="const"&&e.value!=="let")throw new Error('Only "for (const x of …)" / "for (let x of …)" loops are supported');this.pos+=1;const n=this.peek();if(!n||n.type!=="ident")throw new Error("Expected loop variable name");const r=String(n.value);this.pos+=1;const i=this.peek();if(!i||i.type!=="ident"||i.value!=="of")throw new Error("Only for-of loops are supported (for-in / C-style for are not allowed)");this.pos+=1;const l=this.parseExpression();this.expectPunct(")");const c=this.parseStatement();return{type:"ForOf",name:r,iterable:l,body:c}}parseReturn(){if(this.pos+=1,this.isPunct(";")||this.isPunct("}")||this.atEnd())return this.consumeSemicolon(),{type:"Return",argument:null};const e=this.parseExpression();return this.consumeSemicolon(),{type:"Return",argument:e}}parseTry(){this.pos+=1;const e=this.parseBlock();let n=null,r=null,i=null;const l=this.peek();if(l&&l.type==="ident"&&l.value==="catch"){if(this.pos+=1,this.isPunct("(")){this.pos+=1;const d=this.peek();d&&d.type==="ident"&&(n=String(d.value),this.pos+=1),this.expectPunct(")")}r=this.parseBlock()}const c=this.peek();if(c&&c.type==="ident"&&c.value==="finally"&&(this.pos+=1,i=this.parseBlock()),!r&&!i)throw new Error("Missing catch or finally after try");return{type:"Try",block:e,handlerParam:n,handler:r,finalizer:i}}parseFunctionExpression(){this.pos+=1;let e=null;const n=this.peek();n&&n.type==="ident"&&n.value!==void 0&&!this.isPunct("(")&&(e=String(n.value),this.pos+=1),this.expectPunct("(");const r=this.tryParseParamList();if(!r)throw new Error("Invalid function parameter list");this.expectPunct(")");const i=this.parseBlock();return{type:"Function",name:e,params:r,body:i}}parseTernary(){const e=this.parseBinary(0);if(this.isPunct("?")){this.pos+=1;const n=this.parseExpression();this.expectPunct(":");const r=this.parseExpression();return{type:"Conditional",test:e,consequent:n,alternate:r}}return e}parseBinary(e){let n=this.parseUnary();for(;;){const r=this.peek();if(!r||r.type!=="punct")break;const i=String(r.value),l=c0[i];if(l===void 0||lWg(l));return{type:"Template",quasis:n,expressions:i}}if(e.type==="ident"&&e.value==="new")return this.parseNew();if(e.type==="ident"&&e.value==="function")return this.parseFunctionExpression();if(e.type==="ident"){const n=String(e.value);if(Xl.has(n))throw new Error(`Keyword "${n}" is not allowed`);switch(this.pos+=1,n){case"true":return{type:"Literal",value:!0};case"false":return{type:"Literal",value:!1};case"null":return{type:"Literal",value:null};case"undefined":return{type:"Literal",value:void 0};default:return{type:"Identifier",name:n}}}if(e.type==="punct"){if(e.value==="("){this.pos+=1;const n=this.parseExpression();return this.expectPunct(")"),n}if(e.value==="[")return this.parseArrayLiteral();if(e.value==="{")return this.parseObjectLiteral()}throw new Error(`Unexpected token "${e.value}"`)}parseArrayLiteral(){this.expectPunct("[");const e=[];for(;!this.isPunct("]");){if(this.isPunct(",")){this.pos+=1,e.push({type:"Literal",value:void 0});continue}if(this.isPunct("...")?(this.pos+=1,e.push({type:"Spread",argument:this.parseExpression()})):e.push(this.parseExpression()),this.isPunct(",")){this.pos+=1;continue}break}return this.expectPunct("]"),{type:"Array",elements:e}}parseObjectLiteral(){this.expectPunct("{");const e=[];for(;!this.isPunct("}");){if(this.isPunct("..."))this.pos+=1,e.push({kind:"spread",value:this.parseExpression()});else{let n,r=!1;const i=this.peek();if(!i)throw new Error("Unexpected end of expression in object literal");if(i.type==="punct"&&i.value==="[")this.pos+=1,n=this.parseExpression(),this.expectPunct("]"),r=!0;else if(i.type==="str")this.pos+=1,n={type:"Literal",value:i.value};else if(i.type==="num")this.pos+=1,n={type:"Literal",value:String(i.value)};else if(i.type==="ident")this.pos+=1,n={type:"Literal",value:String(i.value)};else throw new Error(`Unexpected token "${i.value}" in object literal`);if(this.isPunct(":")){this.pos+=1;const l=this.parseExpression();e.push({kind:"init",key:n,computed:r,value:l})}else{if(r||n.type!=="Literal"||typeof n.value!="string")throw new Error("Invalid shorthand property in object literal");if(i.type!=="ident")throw new Error("Invalid shorthand property in object literal");e.push({kind:"init",key:n,computed:!1,value:{type:"Identifier",name:n.value}})}}if(this.isPunct(",")){this.pos+=1;continue}break}return this.expectPunct("}"),{type:"Object",properties:e}}}function Wg(s){const e=l0(s),n=new d0(e),r=n.parseExpression();if(!n.atEnd()){const i=n.peek();throw i&&i.type==="punct"&&i.value===","?new Error("The comma/sequence operator is not allowed"):new Error(`Unexpected token "${i?i.value:""}" after expression`)}return r}function f0(s,e){let n=e;for(;n;){if(Object.prototype.hasOwnProperty.call(n.vars,s))return n.vars[s];n=n.parent}if(Object.prototype.hasOwnProperty.call(Ud,s))return Ud[s];if(r0.has(s))throw new Error(`Reference to forbidden global "${s}" is not allowed`)}function Fd(s){const e=typeof s=="symbol"?s:String(s);if(typeof e=="string"&&mo.has(e))throw new Error(`Access to "${e}" is forbidden`);return e}function Vd(s,e){return s.type==="Member"?Yg(s,e):s.type==="Call"?Xg(s,e):Ze(s,e)}function Yg(s,e){const n=Vd(s.object,e);if(n===vr||s.optional&&n==null)return vr;let r;s.computed?r=Ze(s.property,e):r=s.property.value;const i=Fd(r);if(n!=null)return n[i]}function Xg(s,e){let n,r;if(s.callee.type==="Member"){const l=s.callee,c=Vd(l.object,e);if(c===vr||l.optional&&c==null)return vr;let d;l.computed?d=Ze(l.property,e):d=l.property.value;const f=Fd(d);c==null?n=void 0:(n=c[f],r=c)}else if(n=Vd(s.callee,e),n===vr)return vr;if(s.optional&&n==null)return vr;if(typeof n!="function")throw new Error("Attempted to call a non-function value");const i=Jg(s.args,e);return n.apply(r,i)}function Jg(s,e){const n=[];for(const r of s)if(r.type==="Spread"){const i=Ze(r.argument,e);if(i!=null)for(const l of i)n.push(l)}else n.push(Ze(r,e));return n}function Qg(s,e,n){for(let r=0;r":return n>r;case"<=":return n<=r;case">=":return n>=r;default:throw new Error(`Unknown binary operator "${s.operator}"`)}}case"Logical":{const n=Ze(s.left,e);switch(s.operator){case"&&":return n&&Ze(s.right,e);case"||":return n||Ze(s.right,e);case"??":return n??Ze(s.right,e);default:throw new Error(`Unknown logical operator "${s.operator}"`)}}case"Conditional":return Ze(s.test,e)?Ze(s.consequent,e):Ze(s.alternate,e);case"Array":{const n=[];for(const r of s.elements)if(r.type==="Spread"){const i=Ze(r.argument,e);if(i!=null)for(const l of i)n.push(l)}else n.push(Ze(r,e));return n}case"Object":{const n={};for(const r of s.properties)if(r.kind==="spread"){const i=Ze(r.value,e);if(i!=null&&typeof i=="object")for(const l of Object.keys(i))Kd(n,l,i[l])}else{let i;r.computed?i=Ze(r.key,e):i=r.key.value;const l=Ze(r.value,e);Kd(n,String(i),l)}return n}case"Arrow":{const n=e,r=s.params,i=s.body,l=s.isBlock;return function(...d){const f={vars:{},parent:n};return Qg(r,d,f),l?Zg(i,f):Ze(i,f)}}case"Function":{const n=e,r=s.params,i=s.body,l=s.name,c=function(...f){const h={vars:{},parent:n};return l&&(h.vars[l]=c),Qg(r,f,h),Zg(i,h)};return c}case"Delete":{const n=s.argument,r=Ze(n.object,e);let i;n.computed?i=Ze(n.property,e):i=n.property.value;const l=Fd(i);if(r==null||typeof r!="object"&&typeof r!="function")return!0;if(Vg.has(r))throw new Error("delete on a built-in global object is not allowed");return delete r[l]}case"Block":{const n={vars:{},parent:e};for(const r of s.body)Ze(r,n);return}case"VarDecl":{for(const n of s.declarations)e.vars[n.name]=Ze(n.init,e);return}case"If":{Ze(s.test,e)?Ze(s.consequent,e):s.alternate&&Ze(s.alternate,e);return}case"ForOf":{const n=Ze(s.iterable,e);if(n!=null)for(const r of n){const i={vars:{},parent:e};i.vars[s.name]=r;try{Ze(s.body,i)}catch(l){if(l instanceof Gd)continue;if(l instanceof qd)break;throw l}}return}case"Return":throw new Bd(s.argument?Ze(s.argument,e):void 0);case"ExprStmt":Ze(s.expression,e);return;case"Break":throw new qd;case"Continue":throw new Gd;case"Empty":return;case"Try":{try{try{Ze(s.block,e)}catch(n){if(n instanceof Bd||n instanceof qd||n instanceof Gd)throw n;if(s.handler){const r={vars:{},parent:e};s.handlerParam&&(r.vars[s.handlerParam]=n),Ze(s.handler,r)}else throw n}}finally{s.finalizer&&Ze(s.finalizer,e)}return}case"New":{const n=Pd[s.ctor];if(typeof n!="function")throw new Error("new on non-whitelisted constructor");const r=Jg(s.args,e);return new n(...r)}case"Template":{let n=s.quasis[0]??"";for(let r=0;r0}getFromRenderCycleCache(e){if(this.isRenderCycleCacheActive())return this.renderCycleCache.get(e)}saveToRenderCycleCache(e,n){this.isRenderCycleCacheActive()&&this.renderCycleCache.set(e,n)}resolveBindings(e,n,r,i){const l={...this.defaultOptions,...r},c=yo(),d=n._computed&&!n.$computed?{...n,$computed:n._computed}:n,f=(S,v)=>{const _=v.trim();let x=!1,A=_;if(_.startsWith(nr)&&(x=!0,A=_.slice(nr.length)),Gn(A))try{const B=this.evaluatePipeExpression(A,d,l,{...i,method:"resolveBindings",displayExpression:`{{${_}}}`}),W=this.formatValue(B);return x?go(W):W}catch(B){return $a.error("Pipe expression evaluation failed:",A,B),S}if(ho(A)){const B=c?.isEnabled()?performance.now():0;try{let W,pe=!1;if(l.skipCache)W=this.evaluateExpression(A,d);else{const we=`expr:${A}`,Ue=this.getFromRenderCycleCache(we);Ue!==void 0?(W=Ue,pe=!0):(W=this.evaluateExpression(A,d),this.saveToRenderCycleCache(we,W))}if(c?.isEnabled()){const we=performance.now()-B;c.trackExpressionEval({expression:`{{${_}}}`,result:this.sanitizeResultForTracking(W),resultType:this.getResultType(W),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:pe,duration:we,method:"resolveBindings",skipCache:l.skipCache})}const Se=this.formatValue(W);return x?go(Se):Se}catch(W){return $a.error("Expression evaluation failed:",A,W),S}}if(l.skipCache){const B=c?.isEnabled()?performance.now():0,W=this.resolvePath(A,d,l);if(c?.isEnabled()){const Se=performance.now()-B;c.trackExpressionEval({expression:`{{${_}}}`,result:this.sanitizeResultForTracking(W),resultType:this.getResultType(W),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:!1,duration:Se,method:"resolveBindings",skipCache:!0})}const pe=this.formatValue(W);return x?go(pe):pe}const $=A.startsWith("_global")||A.startsWith("_local")||A.startsWith("_isolated")||A.startsWith("$parent"),k=c?.isEnabled()?performance.now():0;let O,P=!1;if($){const B=this.getFromRenderCycleCache(A);B!==void 0?(O=B,P=!0):(O=this.resolvePath(A,d,l),this.saveToRenderCycleCache(A,O))}else{const B=this.getFromCache(A);B!==void 0?(O=B,P=!0):(O=this.resolvePath(A,d,l),this.saveToCache(A,O))}if(c?.isEnabled()){const B=performance.now()-k;c.trackExpressionEval({expression:`{{${_}}}`,result:this.sanitizeResultForTracking(O),resultType:this.getResultType(O),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:P,duration:B,method:"resolveBindings",skipCache:l.skipCache})}const G=this.formatValue(O);return x?go(G):G},h=n0(e);if(h.length===0)return e;let m="",y=0;for(const S of h)m+=e.slice(y,S.start),m+=f(e.slice(S.start,S.end),S.expr),y=S.end;return m+e.slice(y)}evaluatePipeExpression(e,n,r,i){const l={...this.defaultOptions,...r},c=yo(),d=c?.isEnabled()?performance.now():0,f=n._computed&&!n.$computed?{...n,$computed:n._computed}:n,[h,m]=e0(e);let y,S=!1;const v=ho(h),_=h.startsWith("_global")||h.startsWith("_local")||h.startsWith("_isolated")||h.startsWith("$parent");if(l.skipCache)v?y=this.evaluateExpression(h,f):y=this.resolvePath(h,f,l);else if(v){const A=this.getFromRenderCycleCache(`expr:${h}`);A!==void 0?(y=A,S=!0):(y=this.evaluateExpression(h,f),this.saveToRenderCycleCache(`expr:${h}`,y))}else if(_){const A=this.getFromRenderCycleCache(h);A!==void 0?(y=A,S=!0):(y=this.resolvePath(h,f,l),this.saveToRenderCycleCache(h,y))}else{const A=this.getFromCache(h);A!==void 0?(y=A,S=!0):(y=this.resolvePath(h,f,l),this.saveToCache(h,y))}const x=t0(y,m);if(c?.isEnabled()){const A=performance.now()-d;c.trackExpressionEval({expression:i?.displayExpression??`{{${e}}}`,result:this.sanitizeResultForTracking(x),resultType:this.getResultType(x),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:S,duration:A,method:i?.method??"evaluatePipeExpression",skipCache:l.skipCache})}return x}resolve(e,n,r,i){const l={...this.defaultOptions,...r},c=yo(),d=c?.isEnabled()?performance.now():0;if(l.skipCache){const y=this.resolvePath(e,n,l);return c?.isEnabled()&&c.trackExpressionEval({expression:e,result:this.sanitizeResultForTracking(y),resultType:this.getResultType(y),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:!1,duration:performance.now()-d,method:"resolve",skipCache:!0}),y}const f=e.startsWith("_global")||e.startsWith("_local")||e.startsWith("_isolated")||e.startsWith("$parent");let h=!1;if(f){const y=this.getFromRenderCycleCache(e);if(y!==void 0)return h=!0,c?.isEnabled()&&c.trackExpressionEval({expression:e,result:this.sanitizeResultForTracking(y),resultType:this.getResultType(y),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:!0,duration:performance.now()-d,method:"resolve",skipCache:l.skipCache}),y}else{const y=this.getFromCache(e);if(y!==void 0)return h=!0,c?.isEnabled()&&c.trackExpressionEval({expression:e,result:this.sanitizeResultForTracking(y),resultType:this.getResultType(y),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:!0,duration:performance.now()-d,method:"resolve",skipCache:l.skipCache}),y}const m=this.resolvePath(e,n,l);return f?this.saveToRenderCycleCache(e,m):this.saveToCache(e,m),c?.isEnabled()&&c.trackExpressionEval({expression:e,result:this.sanitizeResultForTracking(m),resultType:this.getResultType(m),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:h,duration:performance.now()-d,method:"resolve",skipCache:l.skipCache}),m}resolvePath(e,n,r,i=0,l=new WeakSet){if(typeof e!="string"||e.trim()===""){$a.warn("resolvePath: 빈 경로가 전달되었습니다 — undefined 로 해석합니다.");return}if(r.maxDepth&&i>r.maxDepth){if(r.detectCircular)throw new Yd(`Maximum depth exceeded (${r.maxDepth}). Possible circular reference.`,e,n);return r.defaultValue}const c=this.parsePath(e);let d=n;for(let f=0;foa.CACHE_EXPIRY){this.cache.delete(e),r?.isEnabled()&&r.recordCacheMiss();return}return r?.isEnabled()&&r.recordCacheHit(),n.value}saveToCache(e,n){this.cache.set(e,{value:n,timestamp:Date.now()})}isActionDefinition(e){return typeof e.handler!="string"?!1:e.params!==void 0||Array.isArray(e.actions)||typeof e.target=="string"||e.onSuccess!==void 0||e.onError!==void 0}resolveObject(e,n,r){if(this.isSwitchExpression(e)){const d=e;return this.resolveSwitch(d,n,r)}if(this.isActionDefinition(e))return{...e};if("iteration"in e)return{...e};const i={},c=[...["cellChildren","expandChildren","expandContext","render"],...r?.skipBindingKeys||[]];for(const[d,f]of Object.entries(e)){if(c.includes(d)){i[d]=f;continue}try{this.resolveObjectEntry(i,d,f,n,r)}catch(h){$a.warn(`resolveObject: 값 해석 실패 (key: ${d}):`,h),i[d]=void 0}}return i}resolveObjectEntry(e,n,r,i,l){if(typeof r=="string"){const c=Da(r);if(c!==null){const d=c.trim();let f=!1,h=d;d.startsWith(nr)&&(f=!0,h=d.slice(nr.length));let m;switch(qg(h)){case"empty":$a.warn(`resolveObject: 빈 바인딩 \`{{}}\` (key: ${n}) — undefined 로 해석합니다.`),m=void 0;break;case"literal":m=jd.get(h);break;case"pipe":m=this.evaluatePipeExpression(h,i,l);break;case"expression":m=this.evaluateExpression(h,i,l);break;default:m=this.resolve(h,i,l)}e[n]=f&&m!=null?ss(m):m}else e[n]=this.resolveBindings(r,i,l)}else Array.isArray(r)?e[n]=r.map(c=>typeof c=="string"?this.resolveBindings(c,i,l):typeof c=="object"&&c!==null?this.resolveObject(c,i,l):c):r&&typeof r=="object"?e[n]=this.resolveObject(r,i,l):e[n]=r}clearCache(){this.cache.clear()}invalidateCacheByKeys(e){for(const n of this.cache.keys())for(const r of e)if(n===r||n.startsWith(`${r}.`)||n.startsWith(`${r}[`)){this.cache.delete(n);break}}pruneCache(){const e=Date.now();for(const[n,r]of this.cache.entries())e-r.timestamp>oa.CACHE_EXPIRY&&this.cache.delete(n)}getCacheStats(){const e=Date.now();let n=0;for(const r of this.cache.values())e-r.timestamp>oa.CACHE_EXPIRY&&n++;return{size:this.cache.size,expired:n}}evaluateExpression(e,n,r){const i=yo(),l=i?.isEnabled()?performance.now():0;i?.isEnabled()&&i.trackBindingEval();try{let c=this.preprocessOptionalChaining(e);c=this.preprocessTranslationTokens(c);const d=this.extractVariablesFromExpression(c),f={...n};for(const A of d)A in f||(f[A]=void 0);n._computed&&!f.$computed&&(f.$computed=n._computed);let h=n.$templateId,m=n.$locale;if(typeof window<"u"&&(!h||!m)){const A=window.__templateApp?.getConfig?.();h??(h=A?.templateId),m??(m=A?.locale)}const y=m||"ko";f.$localized=(A,L)=>{if(A==null&&!L)return"";if(typeof A=="string")return A;if(A&&typeof A=="object"&&A[y])return A[y];if(L&&typeof L=="string"){const $=f.$t?f.$t(L):L;if($&&$!==L)return $}return A&&typeof A=="object"?A.ko||A.en||Object.values(A)[0]||"":A==null?"":String(A)};const S=typeof window<"u"?window.G7Core:void 0;f.$uuid=()=>S?.uuid?S.uuid():typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,A=>{const L=Math.random()*16|0;return(A==="x"?L:L&3|8).toString(16)});const v={templateId:h||"",locale:y};f.$t=A=>{if(!A||typeof A!="string")return"";try{return Ra.getInstance().translate(A,v)}catch(L){return $a.warn("$t() translation failed for key:",A,L),A}},f.$get=(A,L,$=void 0)=>{if(A==null)return $;const k=Array.isArray(L)?L:[L];if(k.length===0)return A;let O=A;for(const P of k){if(O==null||P==null)return $;O=O[P]}return O??$};const _=!1,x=Wd(c,f);if(i?.isEnabled()){const A=performance.now()-l;i.trackExpressionEval({expression:e,result:this.sanitizeResultForTracking(x),resultType:this.getResultType(x),componentId:r?.componentId,componentName:r?.componentName,propName:r?.propName,fromCache:_,duration:A,method:"evaluateExpression",skipCache:r?.skipCache})}return x}catch(c){throw new Error(`Failed to evaluate expression "${e}": ${c instanceof Error?c.message:String(c)}`)}}getResultType(e){return e===null?"null":e===void 0?"undefined":Array.isArray(e)?"array":typeof e}sanitizeResultForTracking(e){if(e==null||typeof e!="object")return e;try{if(Array.isArray(e))return e.length>10?`[Array(${e.length})]`:e.slice(0,10);const n=Object.keys(e);return n.length>20?`{Object(${n.length} keys)}`:(JSON.stringify(e),e)}catch{return"[Complex Object]"}}preprocessTranslationTokens(e){return e=e.replace(/(['"])(\$t:([a-zA-Z_][a-zA-Z0-9_.\-]*))\1/g,(n,r,i,l)=>`$t('${l}')`),e.replace(/(['"]\s*)?(\$t:[a-zA-Z_][a-zA-Z0-9_.\-]*)(?!\s*['"])/g,(n,r,i)=>r?n:`"${i}"`)}preprocessOptionalChaining(e){const n=[];let r=e.replace(/(['"])(?:(?!\1|\\).|\\.)*\1/g,l=>(n.push(l),`__STRING_LITERAL_${n.length-1}__`));const i=[];return r=r.replace(/\$t:[a-zA-Z_][a-zA-Z0-9_.\-]*(?:\|[^'"\s,)]+)?/g,l=>(i.push(l),`__TRANSLATION_TOKEN_${i.length-1}__`)),r=r.replace(/([a-zA-Z_$][a-zA-Z0-9_$]*)\.(?!\?)/g,"$1?."),r=r.replace(/__TRANSLATION_TOKEN_(\d+)__/g,(l,c)=>i[parseInt(c,10)]),r=r.replace(/__STRING_LITERAL_(\d+)__/g,(l,c)=>n[parseInt(c,10)]),r}extractVariablesFromExpression(e){const n=new Set(["true","false","null","undefined","NaN","Infinity","if","else","for","while","do","switch","case","break","continue","return","function","class","const","let","var","new","delete","typeof","instanceof","this","super","import","export","default","try","catch","finally","throw","Math","Date","JSON","Array","Object","String","Number","Boolean","RegExp","Set","Map","WeakSet","WeakMap","Symbol","Promise","BigInt","Error","parseInt","parseFloat","isNaN","isFinite","encodeURI","decodeURI","encodeURIComponent","decodeURIComponent"]),r=/(^|[^.\w$])([a-zA-Z_$][a-zA-Z0-9_$]*)/g,i=new Set;let l;for(;(l=r.exec(e))!==null;){const c=l[2];n.has(c)||i.add(c)}return Array.from(i)}isSwitchExpression(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&"$switch"in e&&"$cases"in e}resolveSwitch(e,n,r){const i={...r,skipCache:!0};let l;try{l=this.resolveBindings(e.$switch,n,i)?.toString()?.trim()??""}catch(d){$a.warn("resolveSwitch: $switch 키 평가 실패:",e.$switch,d),l=""}let c;if(l&&e.$cases&&l in e.$cases)c=e.$cases[l];else if("$default"in e)c=e.$default;else return;return typeof c=="string"?c.includes("{{")?this.resolveBindings(c,n,i):c:c!==null&&typeof c=="object"?this.resolveObject(c,n,i):c}};M(oa,"PATH_SEGMENT_PATTERN",/([^.[\]]+)|\[(\d+)\]/g),M(oa,"CACHE_EXPIRY",3e4);let kn=oa;const Xd=new kn,Jl={mobile:{min:0,max:767},tablet:{min:768,max:1023},desktop:{min:1024,max:1/0},portable:{min:0,max:1023}},Ql=new Map;function h0(s,e){let n=null;return((...r)=>{n!==null&&clearTimeout(n),n=setTimeout(()=>{s(...r)},e)})}class p0{constructor(){M(this,"subscribers",new Set);M(this,"currentWidth",1024);M(this,"debouncedHandler",null);M(this,"isInitialized",!1);this.initialize()}initialize(){typeof window>"u"||(this.currentWidth=window.innerWidth,this.isInitialized=!0,this.debouncedHandler=h0(()=>{this.currentWidth=window.innerWidth,this.notifySubscribers()},150),window.addEventListener("resize",this.debouncedHandler))}notifySubscribers(){this.subscribers.forEach(e=>{e(this.currentWidth)})}subscribe(e){return this.subscribers.add(e),e(this.currentWidth),()=>{this.subscribers.delete(e)}}getWidth(){return this.currentWidth}parseRange(e){if(Ql.has(e))return Ql.get(e)??null;let n=null;if(Jl[e])n={...Jl[e]};else{const r=e.match(/^(-?\d*)-(-?\d*)$/);if(r){const[,i,l]=r,c=i===""?0:parseInt(i,10),d=l===""?1/0:parseInt(l,10);!isNaN(c)&&!isNaN(d)&&c<=d&&(n={min:c,max:d})}}return Ql.set(e,n),n}getMatchingKey(e,n){const r=[];for(const i of Object.keys(e)){const l=this.parseRange(i);l&&n>=l.min&&n<=l.max&&r.push({key:i,range:l,isPreset:!!Jl[i]})}return r.length===0?null:(r.sort((i,l)=>{if(i.isPreset!==l.isPreset)return i.isPreset?1:-1;const c=i.range.max-i.range.min,d=l.range.max-l.range.min;return c-d}),r[0].key)}matches(e){const n=this.parseRange(e);return n?this.currentWidth>=n.min&&this.currentWidth<=n.max:!1}clearSubscribers(){this.subscribers.clear()}destroy(){this.debouncedHandler&&typeof window<"u"&&window.removeEventListener("resize",this.debouncedHandler),this.clearSubscribers(),Ql.clear()}_setWidthForTesting(e){this.currentWidth=e,this.notifySubscribers()}}const Si=new p0,bo=dt("ConditionEvaluator");function g0(s,e,n,r){return Hd(Gg(s),e,n,{skipCache:!0,onEmpty:()=>{bo.warn(`${r}: 빈 바인딩 \`{{}}\` — undefined 로 해석합니다.`)}})}function em(s,e,n){if(!s)return!0;try{const r=Da(s);let i;if(r!==null?i=g0(r,e,n,"evaluateStringCondition"):i=n.resolveBindings(s,e,{skipCache:!0}),typeof i=="string"){const l=i.toLowerCase().trim();if(l==="false"||l==="0"||l===""||l==="null"||l==="undefined")return!1}return!!i}catch(r){return bo.warn(`evaluateStringCondition: 조건 평가 실패: ${s}`,r),!1}}function Zl(s,e,n){if(typeof s=="string")return em(s,e,n);if("and"in s){if(!Array.isArray(s.and)||s.and.length===0)return bo.warn("evaluateConditionExpression: AND 그룹이 비어있습니다"),!0;for(const r of s.and)if(!Zl(r,e,n))return!1;return!0}if("or"in s){if(!Array.isArray(s.or)||s.or.length===0)return bo.warn("evaluateConditionExpression: OR 그룹이 비어있습니다"),!1;for(const r of s.or)if(Zl(r,e,n))return!0;return!1}return bo.warn("evaluateConditionExpression: 알 수 없는 조건 형식",s),!1}function tm(s,e,n){if(!Array.isArray(s)||s.length===0)return{matched:!1,branchIndex:-1};for(let r=0;r{rr.warn(`evaluateIfCondition: 빈 바인딩 \`{{}}\` (컴포넌트: ${r||"unknown"}) — undefined 로 해석합니다.`)}}):l=n.resolveBindings(s,e,{skipCache:!0}),typeof l=="string"){const c=l.toLowerCase().trim();if(c==="false"||c==="0"||c===""||c==="null"||c==="undefined")return!1}return!!l}catch(i){return rr.warn(`evaluateIfCondition: 조건 평가 실패 (컴포넌트: ${r||"unknown"}):`,i),!1}}function os(s,e,n,r){if(s.if!==void 0)return im(s.if,e,n,r);if(s.condition!==void 0)return im(s.condition,e,n,r);if(s.conditions===void 0)return!0;const i=s.conditions;try{return m0(i)?Zl(i,e,n):y0(i)?tm(i,e,n).matched:(rr.warn(`evaluateRenderCondition: 알 수 없는 conditions 형식 (컴포넌트: ${r||"unknown"})`),!0)}catch(l){return rr.warn(`evaluateRenderCondition: conditions 평가 실패 (컴포넌트: ${r||"unknown"}):`,l),!1}}function sm(s){if(!s.responsive)return s;const e=Si.getWidth(),n=Si.getMatchingKey(s.responsive,e);if(!n)return s;const r=s.responsive[n];return{...s,props:{...s.props,...r.props},children:r.children??s.children,text:r.text??s.text,if:r.if??s.if,iteration:r.iteration??s.iteration}}function vo(s,e,n,r,i){if(!s||s.length===0)return[];const l=i?.bindingEngine??new kn,c=i?.translationEngine??Ra.getInstance(),d=i?.translationContext??{templateId:"",locale:"ko"},f=v0(e,i?.componentContext),h=(v,_)=>{if(typeof v=="string")return Wl(v)||Yl(v)||!/\$t:[a-zA-Z0-9._-]+/.test(v)?v:c.resolveTranslations(v,d,_);if(Array.isArray(v))return v.map(x=>h(x,_));if(v&&typeof v=="object"){const x={};for(const[A,L]of Object.entries(v))x[A]=h(L,_);return x}return v},m=(v,_)=>{if(typeof v=="string"){if(Wl(v))return zd(v);if(Yl(v)){const A=[],L=v.replace(new RegExp(`${po}([^${bi}]*)${bi}`,"g"),(k,O)=>(A.push(O),`${Oa}${A.length-1}${Oa}`));let $=L;return/\$t:[a-zA-Z0-9._-]+/.test(L)&&($=c.resolveTranslations(L,d,_)),$.replace(new RegExp(`${Oa}(\\d+)${Oa}`,"g"),(k,O)=>A[parseInt(O)])}if(v.startsWith("$t:defer:")){const A="$t:"+v.slice(9);return c.resolveTranslations(A,d,_)}if(v.startsWith("$t:"))return c.resolveTranslations(v,d,_);if(/\$t:[a-zA-Z0-9._-]+/.test(v)){const A=v.trim();if(!(A.startsWith("{")&&A.endsWith("}")||A.startsWith("[")&&A.endsWith("]"))&&!v.includes("{{"))return c.resolveTranslations(v,d,_)}const x=am(v);if(x!==null){let A=!1,L=x;x.startsWith(nr)&&(A=!0,L=x.slice(nr.length));let $=!1,k=Hd(L,_,l,{skipCache:!0,onError:O=>{rr.warn("renderItemChildren: 표현식 평가 실패:",O),$=!0},onEmpty:()=>{rr.warn("renderItemChildren: 빈 바인딩 `{{}}` 은 해석하지 않습니다.")}});return $?void 0:(A||(k=h(k,_)),A&&k!=null?ss(k):k)}if(v.includes("{{")){const A=l.resolveBindings(v,_,{skipCache:!0});return typeof A=="string"&&/\$t:[a-zA-Z0-9._-]+/.test(A)?c.resolveTranslations(A,d,_):A}return v}if(Array.isArray(v))return v.map(x=>m(x,_));if(v&&typeof v=="object"){if(l.isSwitchExpression(v))return l.resolveSwitch(v,_,{skipCache:!0});if(l.isActionDefinition(v))return{...v};const x={};for(const[A,L]of Object.entries(v))x[A]=m(L,_);return x}return v},y=(v,_)=>{if(!v)return{};const x={};for(const[A,L]of Object.entries(v))x[A]=m(L,_);return x},S=(v,_,x)=>{const A=sm(v),L=A.iteration;if(!L)return[];const $=Jd(L.source,x,l);if(!Array.isArray($))return rr.warn(`renderItemChildren: iteration.source가 배열이 아닙니다: ${L.source}`),[];const k=nm();if(k?.isEnabled()){const P=`${_}-iteration`;k.trackIteration(P,L.source,L.item_var,L.index_var,$.length)}const O=n[A.name];return O?$.flatMap((P,G)=>{const B={...x,[L.item_var]:P,[`${L.item_var}_index`]:G,...L.index_var?{[L.index_var]:G}:{}},W=os({if:A.if,condition:A.condition,conditions:A.conditions},B,l,A.id);if(A.if&&k?.isEnabled()){const wt=`${_}-iter-${G}-if`;k.trackIfCondition(wt,A.if,W,A.name)}if(!W)return[];const pe=A.id?String(La(m(A.id,B))):void 0,Se=`${_}-iter-${G}`,we=i?.getRemountKey?i.getRemountKey(pe,Se):Se,Ue=y(A.props,B),Fe=Qd(Ue,A.actions,B,{actionDispatcher:i?.actionDispatcher,componentContext:i?.componentContext});let qe=null;return A.text!==void 0?qe=m(A.text,B):A.children&&A.children.length>0&&(qe=vo(A.children,B,n,we,i)),k?.isEnabled()&&k.trackRender(A.name),[Ye.createElement(O,{key:we,...La(Fe)},La(qe))]}):(rr.warn(`renderItemChildren: 컴포넌트를 찾을 수 없습니다: ${A.name}`),[])};return s.flatMap((v,_)=>{const x=sm(v),A=x.id?String(La(m(x.id,f))):void 0,L=r?`${r}-${A||_}`:A||`child-${_}`,$=i?.getRemountKey?i.getRemountKey(A,L):L;if(x.iteration)return S(x,$,f);const k=os({if:x.if,condition:x.condition,conditions:x.conditions},f,l,x.id),O=nm();if(x.if&&O?.isEnabled()){const pe=`${$}-if`;O.trackIfCondition(pe,x.if,k,x.name)}if(!k)return[];const P=n[x.name];if(!P)return rr.warn(`renderItemChildren: 컴포넌트를 찾을 수 없습니다: ${x.name}`),[];const G=y(x.props,f),B=Qd(G,x.actions,f,{actionDispatcher:i?.actionDispatcher,componentContext:i?.componentContext});let W=null;return x.text!==void 0?W=m(x.text,f):x.children&&x.children.length>0&&(W=vo(x.children,f,n,$,i)),O?.isEnabled()&&O.trackRender(x.name),[Ye.createElement(P,{key:$,...La(B)},La(W))]})}function ls(s,e,n,r){let i,l;return n instanceof kn?(i=n,l=r):(i=rm,l=n),i.resolveBindings(s,e,l)}function S0(s,e,n,r){const i=n??rm,l={skipCache:!0,...r};let c;try{c=i.resolveBindings(s.key,e,{skipCache:l.skipCache})?.toString()?.trim()??""}catch(h){rr.warn("resolveClassMap: key 평가 실패:",s.key,h),c=""}let d="";c&&s.variants&&c in s.variants?d=s.variants[c]:s.default&&(d=s.default);const f=[];return s.base?.trim()&&f.push(s.base.trim()),d?.trim()&&f.push(d.trim()),f.join(" ")}function om(s,e){return function(){return s.apply(e,arguments)}}const{toString:w0}=Object.prototype,{getPrototypeOf:ec}=Object,{iterator:tc,toStringTag:lm}=Symbol,nc=(s=>e=>{const n=w0.call(e);return s[n]||(s[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),Sr=s=>(s=s.toLowerCase(),e=>nc(e)===s),rc=s=>e=>typeof e===s,{isArray:cs}=Array,us=rc("undefined");function So(s){return s!==null&&!us(s)&&s.constructor!==null&&!us(s.constructor)&&$n(s.constructor.isBuffer)&&s.constructor.isBuffer(s)}const cm=Sr("ArrayBuffer");function C0(s){let e;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?e=ArrayBuffer.isView(s):e=s&&s.buffer&&cm(s.buffer),e}const E0=rc("string"),$n=rc("function"),um=rc("number"),wo=s=>s!==null&&typeof s=="object",_0=s=>s===!0||s===!1,ac=s=>{if(nc(s)!=="object")return!1;const e=ec(s);return(e===null||e===Object.prototype||Object.getPrototypeOf(e)===null)&&!(lm in s)&&!(tc in s)},A0=s=>{if(!wo(s)||So(s))return!1;try{return Object.keys(s).length===0&&Object.getPrototypeOf(s)===Object.prototype}catch{return!1}},x0=Sr("Date"),T0=Sr("File"),k0=s=>!!(s&&typeof s.uri<"u"),R0=s=>s&&typeof s.getParts<"u",D0=Sr("Blob"),O0=Sr("FileList"),L0=s=>wo(s)&&$n(s.pipe);function $0(){return typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}}const dm=$0(),fm=typeof dm.FormData<"u"?dm.FormData:void 0,M0=s=>{if(!s)return!1;if(fm&&s instanceof fm)return!0;const e=ec(s);if(!e||e===Object.prototype||!$n(s.append))return!1;const n=nc(s);return n==="formdata"||n==="object"&&$n(s.toString)&&s.toString()==="[object FormData]"},N0=Sr("URLSearchParams"),[I0,j0,H0,z0]=["ReadableStream","Request","Response","Headers"].map(Sr),U0=s=>s.trim?s.trim():s.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function Co(s,e,{allOwnKeys:n=!1}={}){if(s===null||typeof s>"u")return;let r,i;if(typeof s!="object"&&(s=[s]),cs(s))for(r=0,i=s.length;r0;)if(i=n[r],e===i.toLowerCase())return i;return null}const wi=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,pm=s=>!us(s)&&s!==wi;function Zd(...s){const{caseless:e,skipUndefined:n}=pm(this)&&this||{},r={},i=(l,c)=>{if(c==="__proto__"||c==="constructor"||c==="prototype")return;const d=e&&hm(r,c)||c,f=ef(r,d)?r[d]:void 0;ac(f)&&ac(l)?r[d]=Zd(f,l):ac(l)?r[d]=Zd({},l):cs(l)?r[d]=l.slice():(!n||!us(l))&&(r[d]=l)};for(let l=0,c=s.length;l(Co(e,(i,l)=>{n&&$n(i)?Object.defineProperty(s,l,{__proto__:null,value:om(i,n),writable:!0,enumerable:!0,configurable:!0}):Object.defineProperty(s,l,{__proto__:null,value:i,writable:!0,enumerable:!0,configurable:!0})},{allOwnKeys:r}),s),B0=s=>(s.charCodeAt(0)===65279&&(s=s.slice(1)),s),q0=(s,e,n,r)=>{s.prototype=Object.create(e.prototype,r),Object.defineProperty(s.prototype,"constructor",{__proto__:null,value:s,writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(s,"super",{__proto__:null,value:e.prototype}),n&&Object.assign(s.prototype,n)},G0=(s,e,n,r)=>{let i,l,c;const d={};if(e=e||{},s==null)return e;do{for(i=Object.getOwnPropertyNames(s),l=i.length;l-- >0;)c=i[l],(!r||r(c,s,e))&&!d[c]&&(e[c]=s[c],d[c]=!0);s=n!==!1&&ec(s)}while(s&&(!n||n(s,e))&&s!==Object.prototype);return e},F0=(s,e,n)=>{s=String(s),(n===void 0||n>s.length)&&(n=s.length),n-=e.length;const r=s.indexOf(e,n);return r!==-1&&r===n},V0=s=>{if(!s)return null;if(cs(s))return s;let e=s.length;if(!um(e))return null;const n=new Array(e);for(;e-- >0;)n[e]=s[e];return n},K0=(s=>e=>s&&e instanceof s)(typeof Uint8Array<"u"&&ec(Uint8Array)),W0=(s,e)=>{const r=(s&&s[tc]).call(s);let i;for(;(i=r.next())&&!i.done;){const l=i.value;e.call(s,l[0],l[1])}},Y0=(s,e)=>{let n;const r=[];for(;(n=s.exec(e))!==null;)r.push(n);return r},X0=Sr("HTMLFormElement"),J0=s=>s.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,r,i){return r.toUpperCase()+i}),ef=(({hasOwnProperty:s})=>(e,n)=>s.call(e,n))(Object.prototype),Q0=Sr("RegExp"),gm=(s,e)=>{const n=Object.getOwnPropertyDescriptors(s),r={};Co(n,(i,l)=>{let c;(c=e(i,l,s))!==!1&&(r[l]=c||i)}),Object.defineProperties(s,r)},Z0=s=>{gm(s,(e,n)=>{if($n(s)&&["arguments","caller","callee"].includes(n))return!1;const r=s[n];if($n(r)){if(e.enumerable=!1,"writable"in e){e.writable=!1;return}e.set||(e.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},eC=(s,e)=>{const n={},r=i=>{i.forEach(l=>{n[l]=!0})};return cs(s)?r(s):r(String(s).split(e)),n},tC=()=>{},nC=(s,e)=>s!=null&&Number.isFinite(s=+s)?s:e;function rC(s){return!!(s&&$n(s.append)&&s[lm]==="FormData"&&s[tc])}const aC=s=>{const e=new WeakSet,n=r=>{if(wo(r)){if(e.has(r))return;if(So(r))return r;if(!("toJSON"in r)){e.add(r);const i=cs(r)?[]:{};return Co(r,(l,c)=>{const d=n(l);!us(d)&&(i[c]=d)}),e.delete(r),i}}return r};return n(s)},iC=Sr("AsyncFunction"),sC=s=>s&&(wo(s)||$n(s))&&$n(s.then)&&$n(s.catch),mm=((s,e)=>s?setImmediate:e?((n,r)=>(wi.addEventListener("message",({source:i,data:l})=>{i===wi&&l===n&&r.length&&r.shift()()},!1),i=>{r.push(i),wi.postMessage(n,"*")}))(`axios@${Math.random()}`,[]):n=>setTimeout(n))(typeof setImmediate=="function",$n(wi.postMessage)),oC=typeof queueMicrotask<"u"?queueMicrotask.bind(wi):typeof process<"u"&&process.nextTick||mm,K={isArray:cs,isArrayBuffer:cm,isBuffer:So,isFormData:M0,isArrayBufferView:C0,isString:E0,isNumber:um,isBoolean:_0,isObject:wo,isPlainObject:ac,isEmptyObject:A0,isReadableStream:I0,isRequest:j0,isResponse:H0,isHeaders:z0,isUndefined:us,isDate:x0,isFile:T0,isReactNativeBlob:k0,isReactNative:R0,isBlob:D0,isRegExp:Q0,isFunction:$n,isStream:L0,isURLSearchParams:N0,isTypedArray:K0,isFileList:O0,forEach:Co,merge:Zd,extend:P0,trim:U0,stripBOM:B0,inherits:q0,toFlatObject:G0,kindOf:nc,kindOfTest:Sr,endsWith:F0,toArray:V0,forEachEntry:W0,matchAll:Y0,isHTMLForm:X0,hasOwnProperty:ef,hasOwnProp:ef,reduceDescriptors:gm,freezeMethods:Z0,toObjectSet:eC,toCamelCase:J0,noop:tC,toFiniteNumber:nC,findKey:hm,global:wi,isContextDefined:pm,isSpecCompliantForm:rC,toJSONObject:aC,isAsyncFn:iC,isThenable:sC,setImmediate:mm,asap:oC,isIterable:s=>s!=null&&$n(s[tc])},lC=K.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),cC=s=>{const e={};let n,r,i;return s&&s.split(` -`).forEach(function(c){i=c.indexOf(":"),n=c.substring(0,i).trim().toLowerCase(),r=c.substring(i+1).trim(),!(!n||e[n]&&lC[n])&&(n==="set-cookie"?e[n]?e[n].push(r):e[n]=[r]:e[n]=e[n]?e[n]+", "+r:r)}),e};function uC(s){let e=0,n=s.length;for(;ee;){const r=s.charCodeAt(n-1);if(r!==9&&r!==32)break;n-=1}return e===0&&n===s.length?s:s.slice(e,n)}const dC=new RegExp("[\\u0000-\\u0008\\u000a-\\u001f\\u007f]+","g"),fC=new RegExp("[^\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+","g");function tf(s,e){return K.isArray(s)?s.map(n=>tf(n,e)):uC(String(s).replace(e,""))}const hC=s=>tf(s,dC),pC=s=>tf(s,fC);function ym(s){const e=Object.create(null);return K.forEach(s.toJSON(),(n,r)=>{e[r]=pC(n)}),e}const bm=Symbol("internals");function Eo(s){return s&&String(s).trim().toLowerCase()}function ic(s){return s===!1||s==null?s:K.isArray(s)?s.map(ic):hC(String(s))}function gC(s){const e=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(s);)e[r[1]]=r[2];return e}const mC=s=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(s.trim());function nf(s,e,n,r,i){if(K.isFunction(r))return r.call(this,e,n);if(i&&(e=n),!!K.isString(e)){if(K.isString(r))return e.indexOf(r)!==-1;if(K.isRegExp(r))return r.test(e)}}function yC(s){return s.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(e,n,r)=>n.toUpperCase()+r)}function bC(s,e){const n=K.toCamelCase(" "+e);["get","set","has"].forEach(r=>{Object.defineProperty(s,r+n,{__proto__:null,value:function(i,l,c){return this[r].call(this,e,i,l,c)},configurable:!0})})}let Rn=class{constructor(e){e&&this.set(e)}set(e,n,r){const i=this;function l(d,f,h){const m=Eo(f);if(!m)throw new Error("header name must be a non-empty string");const y=K.findKey(i,m);(!y||i[y]===void 0||h===!0||h===void 0&&i[y]!==!1)&&(i[y||f]=ic(d))}const c=(d,f)=>K.forEach(d,(h,m)=>l(h,m,f));if(K.isPlainObject(e)||e instanceof this.constructor)c(e,n);else if(K.isString(e)&&(e=e.trim())&&!mC(e))c(cC(e),n);else if(K.isObject(e)&&K.isIterable(e)){let d={},f,h;for(const m of e){if(!K.isArray(m))throw TypeError("Object iterator must return a key-value pair");d[h=m[0]]=(f=d[h])?K.isArray(f)?[...f,m[1]]:[f,m[1]]:m[1]}c(d,n)}else e!=null&&l(n,e,r);return this}get(e,n){if(e=Eo(e),e){const r=K.findKey(this,e);if(r){const i=this[r];if(!n)return i;if(n===!0)return gC(i);if(K.isFunction(n))return n.call(this,i,r);if(K.isRegExp(n))return n.exec(i);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,n){if(e=Eo(e),e){const r=K.findKey(this,e);return!!(r&&this[r]!==void 0&&(!n||nf(this,this[r],r,n)))}return!1}delete(e,n){const r=this;let i=!1;function l(c){if(c=Eo(c),c){const d=K.findKey(r,c);d&&(!n||nf(r,r[d],d,n))&&(delete r[d],i=!0)}}return K.isArray(e)?e.forEach(l):l(e),i}clear(e){const n=Object.keys(this);let r=n.length,i=!1;for(;r--;){const l=n[r];(!e||nf(this,this[l],l,e,!0))&&(delete this[l],i=!0)}return i}normalize(e){const n=this,r={};return K.forEach(this,(i,l)=>{const c=K.findKey(r,l);if(c){n[c]=ic(i),delete n[l];return}const d=e?yC(l):String(l).trim();d!==l&&delete n[l],n[d]=ic(i),r[d]=!0}),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const n=Object.create(null);return K.forEach(this,(r,i)=>{r!=null&&r!==!1&&(n[i]=e&&K.isArray(r)?r.join(", "):r)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([e,n])=>e+": "+n).join(` -`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...n){const r=new this(e);return n.forEach(i=>r.set(i)),r}static accessor(e){const r=(this[bm]=this[bm]={accessors:{}}).accessors,i=this.prototype;function l(c){const d=Eo(c);r[d]||(bC(i,c),r[d]=!0)}return K.isArray(e)?e.forEach(l):l(e),this}};Rn.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),K.reduceDescriptors(Rn.prototype,({value:s},e)=>{let n=e[0].toUpperCase()+e.slice(1);return{get:()=>s,set(r){this[n]=r}}}),K.freezeMethods(Rn);const vC="[REDACTED ****]";function SC(s){if(K.hasOwnProp(s,"toJSON"))return!0;let e=Object.getPrototypeOf(s);for(;e&&e!==Object.prototype;){if(K.hasOwnProp(e,"toJSON"))return!0;e=Object.getPrototypeOf(e)}return!1}function wC(s,e){const n=new Set(e.map(l=>String(l).toLowerCase())),r=[],i=l=>{if(l===null||typeof l!="object"||K.isBuffer(l))return l;if(r.indexOf(l)!==-1)return;l instanceof Rn&&(l=l.toJSON()),r.push(l);let c;if(K.isArray(l))c=[],l.forEach((d,f)=>{const h=i(d);K.isUndefined(h)||(c[f]=h)});else{if(!K.isPlainObject(l)&&SC(l))return r.pop(),l;c=Object.create(null);for(const[d,f]of Object.entries(l)){const h=n.has(d.toLowerCase())?vC:i(f);K.isUndefined(h)||(c[d]=h)}}return r.pop(),c};return i(s)}let Oe=class kw extends Error{static from(e,n,r,i,l,c){const d=new kw(e.message,n||e.code,r,i,l);return d.cause=e,d.name=e.name,e.status!=null&&d.status==null&&(d.status=e.status),c&&Object.assign(d,c),d}constructor(e,n,r,i,l){super(e),Object.defineProperty(this,"message",{__proto__:null,value:e,enumerable:!0,writable:!0,configurable:!0}),this.name="AxiosError",this.isAxiosError=!0,n&&(this.code=n),r&&(this.config=r),i&&(this.request=i),l&&(this.response=l,this.status=l.status)}toJSON(){const e=this.config,n=e&&K.hasOwnProp(e,"redact")?e.redact:void 0,r=K.isArray(n)&&n.length>0?wC(e,n):K.toJSONObject(e);return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:r,code:this.code,status:this.status}}};Oe.ERR_BAD_OPTION_VALUE="ERR_BAD_OPTION_VALUE",Oe.ERR_BAD_OPTION="ERR_BAD_OPTION",Oe.ECONNABORTED="ECONNABORTED",Oe.ETIMEDOUT="ETIMEDOUT",Oe.ECONNREFUSED="ECONNREFUSED",Oe.ERR_NETWORK="ERR_NETWORK",Oe.ERR_FR_TOO_MANY_REDIRECTS="ERR_FR_TOO_MANY_REDIRECTS",Oe.ERR_DEPRECATED="ERR_DEPRECATED",Oe.ERR_BAD_RESPONSE="ERR_BAD_RESPONSE",Oe.ERR_BAD_REQUEST="ERR_BAD_REQUEST",Oe.ERR_CANCELED="ERR_CANCELED",Oe.ERR_NOT_SUPPORT="ERR_NOT_SUPPORT",Oe.ERR_INVALID_URL="ERR_INVALID_URL",Oe.ERR_FORM_DATA_DEPTH_EXCEEDED="ERR_FORM_DATA_DEPTH_EXCEEDED";const CC=null;function rf(s){return K.isPlainObject(s)||K.isArray(s)}function vm(s){return K.endsWith(s,"[]")?s.slice(0,-2):s}function af(s,e,n){return s?s.concat(e).map(function(i,l){return i=vm(i),!n&&l?"["+i+"]":i}).join(n?".":""):e}function EC(s){return K.isArray(s)&&!s.some(rf)}const _C=K.toFlatObject(K,{},null,function(e){return/^is[A-Z]/.test(e)});function sc(s,e,n){if(!K.isObject(s))throw new TypeError("target must be an object");e=e||new FormData,n=K.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(A,L){return!K.isUndefined(L[A])});const r=n.metaTokens,i=n.visitor||y,l=n.dots,c=n.indexes,d=n.Blob||typeof Blob<"u"&&Blob,f=n.maxDepth===void 0?100:n.maxDepth,h=d&&K.isSpecCompliantForm(e);if(!K.isFunction(i))throw new TypeError("visitor must be a function");function m(x){if(x===null)return"";if(K.isDate(x))return x.toISOString();if(K.isBoolean(x))return x.toString();if(!h&&K.isBlob(x))throw new Oe("Blob is not supported. Use a Buffer instead.");return K.isArrayBuffer(x)||K.isTypedArray(x)?h&&typeof Blob=="function"?new Blob([x]):Buffer.from(x):x}function y(x,A,L){let $=x;if(K.isReactNative(e)&&K.isReactNativeBlob(x))return e.append(af(L,A,l),m(x)),!1;if(x&&!L&&typeof x=="object"){if(K.endsWith(A,"{}"))A=r?A:A.slice(0,-2),x=JSON.stringify(x);else if(K.isArray(x)&&EC(x)||(K.isFileList(x)||K.endsWith(A,"[]"))&&($=K.toArray(x)))return A=vm(A),$.forEach(function(O,P){!(K.isUndefined(O)||O===null)&&e.append(c===!0?af([A],P,l):c===null?A:A+"[]",m(O))}),!1}return rf(x)?!0:(e.append(af(L,A,l),m(x)),!1)}const S=[],v=Object.assign(_C,{defaultVisitor:y,convertValue:m,isVisitable:rf});function _(x,A,L=0){if(!K.isUndefined(x)){if(L>f)throw new Oe("Object is too deeply nested ("+L+" levels). Max depth: "+f,Oe.ERR_FORM_DATA_DEPTH_EXCEEDED);if(S.indexOf(x)!==-1)throw Error("Circular reference detected in "+A.join("."));S.push(x),K.forEach(x,function(k,O){(!(K.isUndefined(k)||k===null)&&i.call(e,k,K.isString(O)?O.trim():O,A,v))===!0&&_(k,A?A.concat(O):[O],L+1)}),S.pop()}}if(!K.isObject(s))throw new TypeError("data must be an object");return _(s),e}function Sm(s){const e={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+"};return encodeURIComponent(s).replace(/[!'()~]|%20/g,function(r){return e[r]})}function sf(s,e){this._pairs=[],s&&sc(s,this,e)}const wm=sf.prototype;wm.append=function(e,n){this._pairs.push([e,n])},wm.toString=function(e){const n=e?function(r){return e.call(this,r,Sm)}:Sm;return this._pairs.map(function(i){return n(i[0])+"="+n(i[1])},"").join("&")};function AC(s){return encodeURIComponent(s).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function Cm(s,e,n){if(!e)return s;const r=n&&n.encode||AC,i=K.isFunction(n)?{serialize:n}:n,l=i&&i.serialize;let c;if(l?c=l(e,i):c=K.isURLSearchParams(e)?e.toString():new sf(e,i).toString(r),c){const d=s.indexOf("#");d!==-1&&(s=s.slice(0,d)),s+=(s.indexOf("?")===-1?"?":"&")+c}return s}class Em{constructor(){this.handlers=[]}use(e,n,r){return this.handlers.push({fulfilled:e,rejected:n,synchronous:r?r.synchronous:!1,runWhen:r?r.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(e){K.forEach(this.handlers,function(r){r!==null&&e(r)})}}const of={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1,legacyInterceptorReqResOrdering:!0},xC={isBrowser:!0,classes:{URLSearchParams:typeof URLSearchParams<"u"?URLSearchParams:sf,FormData:typeof FormData<"u"?FormData:null,Blob:typeof Blob<"u"?Blob:null},protocols:["http","https","file","blob","url","data"]},lf=typeof window<"u"&&typeof document<"u",cf=typeof navigator=="object"&&navigator||void 0,TC=lf&&(!cf||["ReactNative","NativeScript","NS"].indexOf(cf.product)<0),kC=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",RC=lf&&window.location.href||"http://localhost",En={...Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:lf,hasStandardBrowserEnv:TC,hasStandardBrowserWebWorkerEnv:kC,navigator:cf,origin:RC},Symbol.toStringTag,{value:"Module"})),...xC};function DC(s,e){return sc(s,new En.classes.URLSearchParams,{visitor:function(n,r,i,l){return En.isNode&&K.isBuffer(n)?(this.append(r,n.toString("base64")),!1):l.defaultVisitor.apply(this,arguments)},...e})}function OC(s){return K.matchAll(/\w+|\[(\w*)]/g,s).map(e=>e[0]==="[]"?"":e[1]||e[0])}function LC(s){const e={},n=Object.keys(s);let r;const i=n.length;let l;for(r=0;r=n.length;return c=!c&&K.isArray(i)?i.length:c,f?(K.hasOwnProp(i,c)?i[c]=K.isArray(i[c])?i[c].concat(r):[i[c],r]:i[c]=r,!d):((!K.hasOwnProp(i,c)||!K.isObject(i[c]))&&(i[c]=[]),e(n,r,i[c],l)&&K.isArray(i[c])&&(i[c]=LC(i[c])),!d)}if(K.isFormData(s)&&K.isFunction(s.entries)){const n={};return K.forEachEntry(s,(r,i)=>{e(OC(r),i,n,0)}),n}return null}const ds=(s,e)=>s!=null&&K.hasOwnProp(s,e)?s[e]:void 0;function $C(s,e,n){if(K.isString(s))try{return(e||JSON.parse)(s),K.trim(s)}catch(r){if(r.name!=="SyntaxError")throw r}return(n||JSON.stringify)(s)}const _o={transitional:of,adapter:["xhr","http","fetch"],transformRequest:[function(e,n){const r=n.getContentType()||"",i=r.indexOf("application/json")>-1,l=K.isObject(e);if(l&&K.isHTMLForm(e)&&(e=new FormData(e)),K.isFormData(e))return i?JSON.stringify(_m(e)):e;if(K.isArrayBuffer(e)||K.isBuffer(e)||K.isStream(e)||K.isFile(e)||K.isBlob(e)||K.isReadableStream(e))return e;if(K.isArrayBufferView(e))return e.buffer;if(K.isURLSearchParams(e))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();let d;if(l){const f=ds(this,"formSerializer");if(r.indexOf("application/x-www-form-urlencoded")>-1)return DC(e,f).toString();if((d=K.isFileList(e))||r.indexOf("multipart/form-data")>-1){const h=ds(this,"env"),m=h&&h.FormData;return sc(d?{"files[]":e}:e,m&&new m,f)}}return l||i?(n.setContentType("application/json",!1),$C(e)):e}],transformResponse:[function(e){const n=ds(this,"transitional")||_o.transitional,r=n&&n.forcedJSONParsing,i=ds(this,"responseType"),l=i==="json";if(K.isResponse(e)||K.isReadableStream(e))return e;if(e&&K.isString(e)&&(r&&!i||l)){const d=!(n&&n.silentJSONParsing)&&l;try{return JSON.parse(e,ds(this,"parseReviver"))}catch(f){if(d)throw f.name==="SyntaxError"?Oe.from(f,Oe.ERR_BAD_RESPONSE,this,null,ds(this,"response")):f}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:En.classes.FormData,Blob:En.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};K.forEach(["delete","get","head","post","put","patch","query"],s=>{_o.headers[s]={}});function uf(s,e){const n=this||_o,r=e||n,i=Rn.from(r.headers);let l=r.data;return K.forEach(s,function(d){l=d.call(n,l,i.normalize(),e?e.status:void 0)}),i.normalize(),l}function Am(s){return!!(s&&s.__CANCEL__)}let Ao=class extends Oe{constructor(e,n,r){super(e??"canceled",Oe.ERR_CANCELED,n,r),this.name="CanceledError",this.__CANCEL__=!0}};function xm(s,e,n){const r=n.config.validateStatus;!n.status||!r||r(n.status)?s(n):e(new Oe("Request failed with status code "+n.status,n.status>=400&&n.status<500?Oe.ERR_BAD_REQUEST:Oe.ERR_BAD_RESPONSE,n.config,n.request,n))}function MC(s){const e=/^([-+\w]{1,25}):(?:\/\/)?/.exec(s);return e&&e[1]||""}function NC(s,e){s=s||10;const n=new Array(s),r=new Array(s);let i=0,l=0,c;return e=e!==void 0?e:1e3,function(f){const h=Date.now(),m=r[l];c||(c=h),n[i]=f,r[i]=h;let y=l,S=0;for(;y!==i;)S+=n[y++],y=y%s;if(i=(i+1)%s,i===l&&(l=(l+1)%s),h-c{n=m,i=null,l&&(clearTimeout(l),l=null),s(...h)};return[(...h)=>{const m=Date.now(),y=m-n;y>=r?c(h,m):(i=h,l||(l=setTimeout(()=>{l=null,c(i)},r-y)))},()=>i&&c(i)]}const oc=(s,e,n=3)=>{let r=0;const i=NC(50,250);return IC(l=>{if(!l||typeof l.loaded!="number")return;const c=l.loaded,d=l.lengthComputable?l.total:void 0,f=d!=null?Math.min(c,d):c,h=Math.max(0,f-r),m=i(h);r=Math.max(r,f);const y={loaded:f,total:d,progress:d?f/d:void 0,bytes:h,rate:m||void 0,estimated:m&&d?(d-f)/m:void 0,event:l,lengthComputable:d!=null,[e?"download":"upload"]:!0};s(y)},n)},Tm=(s,e)=>{const n=s!=null;return[r=>e[0]({lengthComputable:n,total:s,loaded:r}),e[1]]},km=s=>(...e)=>K.asap(()=>s(...e)),jC=En.hasStandardBrowserEnv?((s,e)=>n=>(n=new URL(n,En.origin),s.protocol===n.protocol&&s.host===n.host&&(e||s.port===n.port)))(new URL(En.origin),En.navigator&&/(msie|trident)/i.test(En.navigator.userAgent)):()=>!0,HC=En.hasStandardBrowserEnv?{write(s,e,n,r,i,l,c){if(typeof document>"u")return;const d=[`${s}=${encodeURIComponent(e)}`];K.isNumber(n)&&d.push(`expires=${new Date(n).toUTCString()}`),K.isString(r)&&d.push(`path=${r}`),K.isString(i)&&d.push(`domain=${i}`),l===!0&&d.push("secure"),K.isString(c)&&d.push(`SameSite=${c}`),document.cookie=d.join("; ")},read(s){if(typeof document>"u")return null;const e=document.cookie.split(";");for(let n=0;ns instanceof Rn?{...s}:s;function Ci(s,e){e=e||{};const n=Object.create(null);Object.defineProperty(n,"hasOwnProperty",{__proto__:null,value:Object.prototype.hasOwnProperty,enumerable:!1,writable:!0,configurable:!0});function r(h,m,y,S){return K.isPlainObject(h)&&K.isPlainObject(m)?K.merge.call({caseless:S},h,m):K.isPlainObject(m)?K.merge({},m):K.isArray(m)?m.slice():m}function i(h,m,y,S){if(K.isUndefined(m)){if(!K.isUndefined(h))return r(void 0,h,y,S)}else return r(h,m,y,S)}function l(h,m){if(!K.isUndefined(m))return r(void 0,m)}function c(h,m){if(K.isUndefined(m)){if(!K.isUndefined(h))return r(void 0,h)}else return r(void 0,m)}function d(h,m,y){if(K.hasOwnProp(e,y))return r(h,m);if(K.hasOwnProp(s,y))return r(void 0,h)}const f={url:l,method:l,data:l,baseURL:c,transformRequest:c,transformResponse:c,paramsSerializer:c,timeout:c,timeoutMessage:c,withCredentials:c,withXSRFToken:c,adapter:c,responseType:c,xsrfCookieName:c,xsrfHeaderName:c,onUploadProgress:c,onDownloadProgress:c,decompress:c,maxContentLength:c,maxBodyLength:c,beforeRedirect:c,transport:c,httpAgent:c,httpsAgent:c,cancelToken:c,socketPath:c,allowedSocketPaths:c,responseEncoding:c,validateStatus:d,headers:(h,m,y)=>i(Dm(h),Dm(m),y,!0)};return K.forEach(Object.keys({...s,...e}),function(m){if(m==="__proto__"||m==="constructor"||m==="prototype")return;const y=K.hasOwnProp(f,m)?f[m]:i,S=K.hasOwnProp(s,m)?s[m]:void 0,v=K.hasOwnProp(e,m)?e[m]:void 0,_=y(S,v,m);K.isUndefined(_)&&y!==d||(n[m]=_)}),n}const PC=["content-type","content-length"];function BC(s,e,n){if(n!=="content-only"){s.set(e);return}Object.entries(e).forEach(([r,i])=>{PC.includes(r.toLowerCase())&&s.set(r,i)})}const qC=s=>encodeURIComponent(s).replace(/%([0-9A-F]{2})/gi,(e,n)=>String.fromCharCode(parseInt(n,16))),Om=s=>{const e=Ci({},s),n=S=>K.hasOwnProp(e,S)?e[S]:void 0,r=n("data");let i=n("withXSRFToken");const l=n("xsrfHeaderName"),c=n("xsrfCookieName");let d=n("headers");const f=n("auth"),h=n("baseURL"),m=n("allowAbsoluteUrls"),y=n("url");if(e.headers=d=Rn.from(d),e.url=Cm(Rm(h,y,m),s.params,s.paramsSerializer),f&&d.set("Authorization","Basic "+btoa((f.username||"")+":"+(f.password?qC(f.password):""))),K.isFormData(r)&&(En.hasStandardBrowserEnv||En.hasStandardBrowserWebWorkerEnv?d.setContentType(void 0):K.isFunction(r.getHeaders)&&BC(d,r.getHeaders(),n("formDataHeaderPolicy"))),En.hasStandardBrowserEnv&&(K.isFunction(i)&&(i=i(e)),i===!0||i==null&&jC(e.url))){const v=l&&c&&HC.read(c);v&&d.set(l,v)}return e},GC=typeof XMLHttpRequest<"u"&&function(s){return new Promise(function(n,r){const i=Om(s);let l=i.data;const c=Rn.from(i.headers).normalize();let{responseType:d,onUploadProgress:f,onDownloadProgress:h}=i,m,y,S,v,_;function x(){v&&v(),_&&_(),i.cancelToken&&i.cancelToken.unsubscribe(m),i.signal&&i.signal.removeEventListener("abort",m)}let A=new XMLHttpRequest;A.open(i.method.toUpperCase(),i.url,!0),A.timeout=i.timeout;function L(){if(!A)return;const k=Rn.from("getAllResponseHeaders"in A&&A.getAllResponseHeaders()),P={data:!d||d==="text"||d==="json"?A.responseText:A.response,status:A.status,statusText:A.statusText,headers:k,config:s,request:A};xm(function(B){n(B),x()},function(B){r(B),x()},P),A=null}"onloadend"in A?A.onloadend=L:A.onreadystatechange=function(){!A||A.readyState!==4||A.status===0&&!(A.responseURL&&A.responseURL.startsWith("file:"))||setTimeout(L)},A.onabort=function(){A&&(r(new Oe("Request aborted",Oe.ECONNABORTED,s,A)),x(),A=null)},A.onerror=function(O){const P=O&&O.message?O.message:"Network Error",G=new Oe(P,Oe.ERR_NETWORK,s,A);G.event=O||null,r(G),x(),A=null},A.ontimeout=function(){let O=i.timeout?"timeout of "+i.timeout+"ms exceeded":"timeout exceeded";const P=i.transitional||of;i.timeoutErrorMessage&&(O=i.timeoutErrorMessage),r(new Oe(O,P.clarifyTimeoutError?Oe.ETIMEDOUT:Oe.ECONNABORTED,s,A)),x(),A=null},l===void 0&&c.setContentType(null),"setRequestHeader"in A&&K.forEach(ym(c),function(O,P){A.setRequestHeader(P,O)}),K.isUndefined(i.withCredentials)||(A.withCredentials=!!i.withCredentials),d&&d!=="json"&&(A.responseType=i.responseType),h&&([S,_]=oc(h,!0),A.addEventListener("progress",S)),f&&A.upload&&([y,v]=oc(f),A.upload.addEventListener("progress",y),A.upload.addEventListener("loadend",v)),(i.cancelToken||i.signal)&&(m=k=>{A&&(r(!k||k.type?new Ao(null,s,A):k),A.abort(),x(),A=null)},i.cancelToken&&i.cancelToken.subscribe(m),i.signal&&(i.signal.aborted?m():i.signal.addEventListener("abort",m)));const $=MC(i.url);if($&&!En.protocols.includes($)){r(new Oe("Unsupported protocol "+$+":",Oe.ERR_BAD_REQUEST,s));return}A.send(l||null)})},FC=(s,e)=>{if(s=s?s.filter(Boolean):[],!e&&!s.length)return;const n=new AbortController;let r=!1;const i=function(f){if(!r){r=!0,c();const h=f instanceof Error?f:this.reason;n.abort(h instanceof Oe?h:new Ao(h instanceof Error?h.message:h))}};let l=e&&setTimeout(()=>{l=null,i(new Oe(`timeout of ${e}ms exceeded`,Oe.ETIMEDOUT))},e);const c=()=>{s&&(l&&clearTimeout(l),l=null,s.forEach(f=>{f.unsubscribe?f.unsubscribe(i):f.removeEventListener("abort",i)}),s=null)};s.forEach(f=>f.addEventListener("abort",i));const{signal:d}=n;return d.unsubscribe=()=>K.asap(c),d},VC=function*(s,e){let n=s.byteLength;if(n{const i=KC(s,e);let l=0,c,d=f=>{c||(c=!0,r&&r(f))};return new ReadableStream({async pull(f){try{const{done:h,value:m}=await i.next();if(h){d(),f.close();return}let y=m.byteLength;if(n){let S=l+=y;n(S)}f.enqueue(new Uint8Array(m))}catch(h){throw d(h),h}},cancel(f){return d(f),i.return()}},{highWaterMark:2})};function YC(s){if(!s||typeof s!="string"||!s.startsWith("data:"))return 0;const e=s.indexOf(",");if(e<0)return 0;const n=s.slice(5,e),r=s.slice(e+1);if(/;base64/i.test(n)){let c=r.length;const d=r.length;for(let v=0;v=48&&_<=57||_>=65&&_<=70||_>=97&&_<=102)&&(x>=48&&x<=57||x>=65&&x<=70||x>=97&&x<=102)&&(c-=2,v+=2)}let f=0,h=d-1;const m=v=>v>=2&&r.charCodeAt(v-2)===37&&r.charCodeAt(v-1)===51&&(r.charCodeAt(v)===68||r.charCodeAt(v)===100);h>=0&&(r.charCodeAt(h)===61?(f++,h--):m(h)&&(f++,h-=3)),f===1&&h>=0&&(r.charCodeAt(h)===61||m(h))&&f++;const S=Math.floor(c/4)*3-(f||0);return S>0?S:0}if(typeof Buffer<"u"&&typeof Buffer.byteLength=="function")return Buffer.byteLength(r,"utf8");let l=0;for(let c=0,d=r.length;c=55296&&f<=56319&&c+1=56320&&h<=57343?(l+=4,c++):l+=3}else l+=3}return l}const df="1.16.1",$m=64*1024,{isFunction:lc}=K,Mm=(s,...e)=>{try{return!!s(...e)}catch{return!1}},XC=s=>{const e=K.global!==void 0&&K.global!==null?K.global:globalThis,{ReadableStream:n,TextEncoder:r}=e;s=K.merge.call({skipUndefined:!0},{Request:e.Request,Response:e.Response},s);const{fetch:i,Request:l,Response:c}=s,d=i?lc(i):typeof fetch=="function",f=lc(l),h=lc(c);if(!d)return!1;const m=d&&lc(n),y=d&&(typeof r=="function"?(L=>$=>L.encode($))(new r):async L=>new Uint8Array(await new l(L).arrayBuffer())),S=f&&m&&Mm(()=>{let L=!1;const $=new l(En.origin,{body:new n,method:"POST",get duplex(){return L=!0,"half"}}),k=$.headers.has("Content-Type");return $.body!=null&&$.body.cancel(),L&&!k}),v=h&&m&&Mm(()=>K.isReadableStream(new c("").body)),_={stream:v&&(L=>L.body)};d&&["text","arrayBuffer","blob","formData","stream"].forEach(L=>{!_[L]&&(_[L]=($,k)=>{let O=$&&$[L];if(O)return O.call($);throw new Oe(`Response type '${L}' is not supported`,Oe.ERR_NOT_SUPPORT,k)})});const x=async L=>{if(L==null)return 0;if(K.isBlob(L))return L.size;if(K.isSpecCompliantForm(L))return(await new l(En.origin,{method:"POST",body:L}).arrayBuffer()).byteLength;if(K.isArrayBufferView(L)||K.isArrayBuffer(L))return L.byteLength;if(K.isURLSearchParams(L)&&(L=L+""),K.isString(L))return(await y(L)).byteLength},A=async(L,$)=>{const k=K.toFiniteNumber(L.getContentLength());return k??x($)};return async L=>{let{url:$,method:k,data:O,signal:P,cancelToken:G,timeout:B,onDownloadProgress:W,onUploadProgress:pe,responseType:Se,headers:we,withCredentials:Ue="same-origin",fetchOptions:Fe,maxContentLength:qe,maxBodyLength:wt}=Om(L);const J=K.isNumber(qe)&&qe>-1,fe=K.isNumber(wt)&&wt>-1;let Le=i||fetch;Se=Se?(Se+"").toLowerCase():"text";let Z=FC([P,G&&G.toAbortSignal()],B),ge=null;const H=Z&&Z.unsubscribe&&(()=>{Z.unsubscribe()});let T;try{if(J&&typeof $=="string"&&$.startsWith("data:")&&YC($)>qe)throw new Oe("maxContentLength size of "+qe+" exceeded",Oe.ERR_BAD_RESPONSE,L,ge);if(fe&&k!=="get"&&k!=="head"){const _e=await A(we,O);if(typeof _e=="number"&&isFinite(_e)&&_e>wt)throw new Oe("Request body larger than maxBodyLength limit",Oe.ERR_BAD_REQUEST,L,ge)}if(pe&&S&&k!=="get"&&k!=="head"&&(T=await A(we,O))!==0){let _e=new l($,{method:"POST",body:O,duplex:"half"}),Te;if(K.isFormData(O)&&(Te=_e.headers.get("content-type"))&&we.setContentType(Te),_e.body){const[Me,pt]=Tm(T,oc(km(pe)));O=Lm(_e.body,$m,Me,pt)}}K.isString(Ue)||(Ue=Ue?"include":"omit");const ce=f&&"credentials"in l.prototype;if(K.isFormData(O)){const _e=we.getContentType();_e&&/^multipart\/form-data/i.test(_e)&&!/boundary=/i.test(_e)&&we.delete("content-type")}we.set("User-Agent","axios/"+df,!1);const de={...Fe,signal:Z,method:k.toUpperCase(),headers:ym(we.normalize()),body:O,duplex:"half",credentials:ce?Ue:void 0};ge=f&&new l($,de);let be=await(f?Le(ge,Fe):Le($,de));if(J){const _e=K.toFiniteNumber(be.headers.get("content-length"));if(_e!=null&&_e>qe)throw new Oe("maxContentLength size of "+qe+" exceeded",Oe.ERR_BAD_RESPONSE,L,ge)}const ie=v&&(Se==="stream"||Se==="response");if(v&&be.body&&(W||J||ie&&H)){const _e={};["status","statusText","headers"].forEach(ht=>{_e[ht]=be[ht]});const Te=K.toFiniteNumber(be.headers.get("content-length")),[Me,pt]=W&&Tm(Te,oc(km(W),!0))||[];let Ct=0;const Ot=ht=>{if(J&&(Ct=ht,Ct>qe))throw new Oe("maxContentLength size of "+qe+" exceeded",Oe.ERR_BAD_RESPONSE,L,ge);Me&&Me(ht)};be=new c(Lm(be.body,$m,Ot,()=>{pt&&pt(),H&&H()}),_e)}Se=Se||"text";let xe=await _[K.findKey(_,Se)||"text"](be,L);if(J&&!v&&!ie){let _e;if(xe!=null&&(typeof xe.byteLength=="number"?_e=xe.byteLength:typeof xe.size=="number"?_e=xe.size:typeof xe=="string"&&(_e=typeof r=="function"?new r().encode(xe).byteLength:xe.length)),typeof _e=="number"&&_e>qe)throw new Oe("maxContentLength size of "+qe+" exceeded",Oe.ERR_BAD_RESPONSE,L,ge)}return!ie&&H&&H(),await new Promise((_e,Te)=>{xm(_e,Te,{data:xe,headers:Rn.from(be.headers),status:be.status,statusText:be.statusText,config:L,request:ge})})}catch(ce){if(H&&H(),Z&&Z.aborted&&Z.reason instanceof Oe){const de=Z.reason;throw de.config=L,ge&&(de.request=ge),ce!==de&&(de.cause=ce),de}throw ce&&ce.name==="TypeError"&&/Load failed|fetch/i.test(ce.message)?Object.assign(new Oe("Network Error",Oe.ERR_NETWORK,L,ge,ce&&ce.response),{cause:ce.cause||ce}):Oe.from(ce,ce&&ce.code,L,ge,ce&&ce.response)}}},JC=new Map,Nm=s=>{let e=s&&s.env||{};const{fetch:n,Request:r,Response:i}=e,l=[r,i,n];let c=l.length,d=c,f,h,m=JC;for(;d--;)f=l[d],h=m.get(f),h===void 0&&m.set(f,h=d?new Map:XC(e)),m=h;return h};Nm();const ff={http:CC,xhr:GC,fetch:{get:Nm}};K.forEach(ff,(s,e)=>{if(s){try{Object.defineProperty(s,"name",{__proto__:null,value:e})}catch{}Object.defineProperty(s,"adapterName",{__proto__:null,value:e})}});const Im=s=>`- ${s}`,QC=s=>K.isFunction(s)||s===null||s===!1;function ZC(s,e){s=K.isArray(s)?s:[s];const{length:n}=s;let r,i;const l={};for(let c=0;c`adapter ${f} `+(h===!1?"is not supported by the environment":"is not available in the build"));let d=n?c.length>1?`since : +`;break;case"t":y+=" ";break;case"r":y+="\r";break;case"b":y+="\b";break;case"f":y+="\f";break;case"v":y+="\v";break;case"0":y+="\0";break;case"\\":y+="\\";break;case"'":y+="'";break;case'"':y+='"';break;case"`":y+="`";break;default:y+=S;break}n++}else y+=s[n],n++;if(n>=r)throw new Error(`Unterminated string literal at position ${h}`);n++,e.push({type:"str",value:y,pos:h});continue}if(i0(l)){const h=n;for(n++;n"?(e.push({type:"punct",value:"=>",pos:c}),n+=2):i(1)==="="?i(2)==="="?(e.push({type:"punct",value:"===",pos:c}),n+=3):(e.push({type:"punct",value:"==",pos:c}),n+=2):(e.push({type:"punct",value:"=",pos:c}),n+=1);continue}case"!":{i(1)==="="?i(2)==="="?(e.push({type:"punct",value:"!==",pos:c}),n+=3):(e.push({type:"punct",value:"!=",pos:c}),n+=2):(e.push({type:"punct",value:"!",pos:c}),n+=1);continue}case"<":{if(i(1)==="=")e.push({type:"punct",value:"<=",pos:c}),n+=2;else{if(i(1)==="<")throw new Error("Bitwise/shift operators are not allowed");e.push({type:"punct",value:"<",pos:c}),n+=1}continue}case">":{if(i(1)==="=")e.push({type:"punct",value:">=",pos:c}),n+=2;else{if(i(1)===">")throw new Error("Bitwise/shift operators are not allowed");e.push({type:"punct",value:">",pos:c}),n+=1}continue}case"&":{if(i(1)==="&")e.push({type:"punct",value:"&&",pos:c}),n+=2;else throw new Error("Bitwise operators are not allowed");continue}case"|":{if(i(1)==="|")e.push({type:"punct",value:"||",pos:c}),n+=2;else throw new Error("Bitwise operators are not allowed");continue}case"?":{i(1)==="."&&!vi(i(2))?(e.push({type:"punct",value:"?.",pos:c}),n+=2):i(1)==="?"?(e.push({type:"punct",value:"??",pos:c}),n+=2):(e.push({type:"punct",value:"?",pos:c}),n+=1);continue}case"+":{if(i(1)==="+")throw new Error("Increment operator is not allowed");if(i(1)==="=")throw new Error("Assignment operators are not allowed");e.push({type:"punct",value:"+",pos:c}),n+=1;continue}case"-":{if(i(1)==="-")throw new Error("Decrement operator is not allowed");if(i(1)==="=")throw new Error("Assignment operators are not allowed");e.push({type:"punct",value:"-",pos:c}),n+=1;continue}case"*":{if(i(1)==="=")throw new Error("Assignment operators are not allowed");if(i(1)==="*")throw new Error("Exponentiation operator is not supported");e.push({type:"punct",value:"*",pos:c}),n+=1;continue}case"/":{if(i(1)==="=")throw new Error("Assignment operators are not allowed");e.push({type:"punct",value:"/",pos:c}),n+=1;continue}case"%":{if(i(1)==="=")throw new Error("Assignment operators are not allowed");e.push({type:"punct",value:"%",pos:c}),n+=1;continue}case"~":case"^":throw new Error("Bitwise operators are not allowed");case".":case":":case"(":case")":case"[":case"]":case"{":case"}":case",":e.push({type:"punct",value:l,pos:c}),n+=1;continue;case";":e.push({type:"punct",value:";",pos:c}),n+=1;continue;default:throw new Error(`Unexpected character "${l}" at position ${c}`)}}return e}const c0={"??":1,"||":1,"&&":2,"===":3,"!==":3,"==":3,"!=":3,"<":4,">":4,"<=":4,">=":4,"+":5,"-":5,"*":6,"/":6,"%":6},u0=new Set(["??","||","&&"]);class d0{constructor(e){M(this,"tokens");M(this,"pos",0);this.tokens=e}atEnd(){return this.pos>=this.tokens.length}peek(e=0){const n=this.pos+e;return n"}"`);this.pos++}parseExpression(){const e=this.tryParseArrow();return e||this.parseTernary()}tryParseArrow(){const e=this.pos,n=this.peek();if(!n)return null;if(n.type==="ident"&&this.isPunct("=>",1)&&!Jl.has(String(n.value))){this.pos+=1,this.pos+=1;const{body:r,isBlock:i}=this.parseArrowBody();return{type:"Arrow",params:[{name:String(n.value),default:null}],body:r,isBlock:i}}if(n.type==="punct"&&n.value==="("){this.pos+=1;const r=this.tryParseParamList();if(r&&this.isPunct(")")&&(this.pos+=1,this.isPunct("=>"))){this.pos+=1;const{body:i,isBlock:l}=this.parseArrowBody();return{type:"Arrow",params:r,body:i,isBlock:l}}return this.pos=e,null}return this.pos=e,null}tryParseParamList(){const e=[];if(this.isPunct(")"))return e;for(;;){const n=this.peek();let r=null,i;if(n&&n.type==="punct"&&n.value==="["){const c=this.tryParseArrayPattern();if(!c)return null;i=c}else if(n&&n.type==="ident"&&!Jl.has(String(n.value)))r=String(n.value),this.pos+=1;else return null;let l=null;if(this.isPunct("=")&&(this.pos+=1,l=this.parseExpression()),e.push(i?{name:r,elements:i,default:l}:{name:r,default:l}),this.isPunct(",")){this.pos+=1;continue}break}return e}tryParseArrayPattern(){const e=this.pos;this.pos+=1;const n=[];for(;;){if(this.isPunct("]"))return this.pos+=1,n;if(this.isPunct(",")){n.push(null),this.pos+=1;continue}const r=this.peek();if(!r||r.type!=="ident"||Jl.has(String(r.value)))return this.pos=e,null;if(n.push(String(r.value)),this.pos+=1,this.isPunct(",")){this.pos+=1;continue}return this.isPunct("]")?(this.pos+=1,n):(this.pos=e,null)}}parseArrowBody(){return this.isPunct("{")?{body:this.parseBlock(),isBlock:!0}:{body:this.parseExpression(),isBlock:!1}}parseBlock(){this.expectPunct("{");const e=[];for(;!this.isPunct("}");){if(this.atEnd())throw new Error("Unterminated block");e.push(this.parseStatement())}return this.expectPunct("}"),{type:"Block",body:e}}parseStatement(){const e=this.peek();if(!e)throw new Error("Unexpected end of statement");if(e.type==="punct"&&e.value==="{")return this.parseBlock();if(e.type==="punct"&&e.value===";")return this.pos+=1,{type:"Empty"};if(e.type==="ident")switch(String(e.value)){case"const":case"let":return this.parseVarDecl();case"if":return this.parseIf();case"for":return this.parseForOf();case"return":return this.parseReturn();case"try":return this.parseTry();case"break":return this.pos+=1,this.consumeSemicolon(),{type:"Break"};case"continue":return this.pos+=1,this.consumeSemicolon(),{type:"Continue"}}const n=this.parseExpression();return this.consumeSemicolon(),{type:"ExprStmt",expression:n}}consumeSemicolon(){this.isPunct(";")&&(this.pos+=1)}parseVarDecl(){this.pos+=1;const e=[];for(;;){const n=this.peek();if(!n||n.type!=="ident")throw new Error("Expected variable name in declaration");const r=String(n.value);this.pos+=1,this.expectPunct("=");const i=this.parseExpression();if(e.push({name:r,init:i}),this.isPunct(",")){this.pos+=1;continue}break}return this.consumeSemicolon(),{type:"VarDecl",declarations:e}}parseIf(){this.pos+=1,this.expectPunct("(");const e=this.parseExpression();this.expectPunct(")");const n=this.parseStatement();let r=null;const i=this.peek();return i&&i.type==="ident"&&i.value==="else"&&(this.pos+=1,r=this.parseStatement()),{type:"If",test:e,consequent:n,alternate:r}}parseForOf(){this.pos+=1,this.expectPunct("(");const e=this.peek();if(!e||e.type!=="ident"||e.value!=="const"&&e.value!=="let")throw new Error('Only "for (const x of …)" / "for (let x of …)" loops are supported');this.pos+=1;const n=this.peek();if(!n||n.type!=="ident")throw new Error("Expected loop variable name");const r=String(n.value);this.pos+=1;const i=this.peek();if(!i||i.type!=="ident"||i.value!=="of")throw new Error("Only for-of loops are supported (for-in / C-style for are not allowed)");this.pos+=1;const l=this.parseExpression();this.expectPunct(")");const c=this.parseStatement();return{type:"ForOf",name:r,iterable:l,body:c}}parseReturn(){if(this.pos+=1,this.isPunct(";")||this.isPunct("}")||this.atEnd())return this.consumeSemicolon(),{type:"Return",argument:null};const e=this.parseExpression();return this.consumeSemicolon(),{type:"Return",argument:e}}parseTry(){this.pos+=1;const e=this.parseBlock();let n=null,r=null,i=null;const l=this.peek();if(l&&l.type==="ident"&&l.value==="catch"){if(this.pos+=1,this.isPunct("(")){this.pos+=1;const d=this.peek();d&&d.type==="ident"&&(n=String(d.value),this.pos+=1),this.expectPunct(")")}r=this.parseBlock()}const c=this.peek();if(c&&c.type==="ident"&&c.value==="finally"&&(this.pos+=1,i=this.parseBlock()),!r&&!i)throw new Error("Missing catch or finally after try");return{type:"Try",block:e,handlerParam:n,handler:r,finalizer:i}}parseFunctionExpression(){this.pos+=1;let e=null;const n=this.peek();n&&n.type==="ident"&&n.value!==void 0&&!this.isPunct("(")&&(e=String(n.value),this.pos+=1),this.expectPunct("(");const r=this.tryParseParamList();if(!r)throw new Error("Invalid function parameter list");this.expectPunct(")");const i=this.parseBlock();return{type:"Function",name:e,params:r,body:i}}parseTernary(){const e=this.parseBinary(0);if(this.isPunct("?")){this.pos+=1;const n=this.parseExpression();this.expectPunct(":");const r=this.parseExpression();return{type:"Conditional",test:e,consequent:n,alternate:r}}return e}parseBinary(e){let n=this.parseUnary();for(;;){const r=this.peek();if(!r||r.type!=="punct")break;const i=String(r.value),l=c0[i];if(l===void 0||lWg(l));return{type:"Template",quasis:n,expressions:i}}if(e.type==="ident"&&e.value==="new")return this.parseNew();if(e.type==="ident"&&e.value==="function")return this.parseFunctionExpression();if(e.type==="ident"){const n=String(e.value);if(Jl.has(n))throw new Error(`Keyword "${n}" is not allowed`);switch(this.pos+=1,n){case"true":return{type:"Literal",value:!0};case"false":return{type:"Literal",value:!1};case"null":return{type:"Literal",value:null};case"undefined":return{type:"Literal",value:void 0};default:return{type:"Identifier",name:n}}}if(e.type==="punct"){if(e.value==="("){this.pos+=1;const n=this.parseExpression();return this.expectPunct(")"),n}if(e.value==="[")return this.parseArrayLiteral();if(e.value==="{")return this.parseObjectLiteral()}throw new Error(`Unexpected token "${e.value}"`)}parseArrayLiteral(){this.expectPunct("[");const e=[];for(;!this.isPunct("]");){if(this.isPunct(",")){this.pos+=1,e.push({type:"Literal",value:void 0});continue}if(this.isPunct("...")?(this.pos+=1,e.push({type:"Spread",argument:this.parseExpression()})):e.push(this.parseExpression()),this.isPunct(",")){this.pos+=1;continue}break}return this.expectPunct("]"),{type:"Array",elements:e}}parseObjectLiteral(){this.expectPunct("{");const e=[];for(;!this.isPunct("}");){if(this.isPunct("..."))this.pos+=1,e.push({kind:"spread",value:this.parseExpression()});else{let n,r=!1;const i=this.peek();if(!i)throw new Error("Unexpected end of expression in object literal");if(i.type==="punct"&&i.value==="[")this.pos+=1,n=this.parseExpression(),this.expectPunct("]"),r=!0;else if(i.type==="str")this.pos+=1,n={type:"Literal",value:i.value};else if(i.type==="num")this.pos+=1,n={type:"Literal",value:String(i.value)};else if(i.type==="ident")this.pos+=1,n={type:"Literal",value:String(i.value)};else throw new Error(`Unexpected token "${i.value}" in object literal`);if(this.isPunct(":")){this.pos+=1;const l=this.parseExpression();e.push({kind:"init",key:n,computed:r,value:l})}else{if(r||n.type!=="Literal"||typeof n.value!="string")throw new Error("Invalid shorthand property in object literal");if(i.type!=="ident")throw new Error("Invalid shorthand property in object literal");e.push({kind:"init",key:n,computed:!1,value:{type:"Identifier",name:n.value}})}}if(this.isPunct(",")){this.pos+=1;continue}break}return this.expectPunct("}"),{type:"Object",properties:e}}}function Wg(s){const e=l0(s),n=new d0(e),r=n.parseExpression();if(!n.atEnd()){const i=n.peek();throw i&&i.type==="punct"&&i.value===","?new Error("The comma/sequence operator is not allowed"):new Error(`Unexpected token "${i?i.value:""}" after expression`)}return r}function f0(s,e){let n=e;for(;n;){if(Object.prototype.hasOwnProperty.call(n.vars,s))return n.vars[s];n=n.parent}if(Object.prototype.hasOwnProperty.call(Ud,s))return Ud[s];if(r0.has(s))throw new Error(`Reference to forbidden global "${s}" is not allowed`)}function Fd(s){const e=typeof s=="symbol"?s:String(s);if(typeof e=="string"&&mo.has(e))throw new Error(`Access to "${e}" is forbidden`);return e}function Vd(s,e){return s.type==="Member"?Yg(s,e):s.type==="Call"?Xg(s,e):Ze(s,e)}function Yg(s,e){const n=Vd(s.object,e);if(n===vr||s.optional&&n==null)return vr;let r;s.computed?r=Ze(s.property,e):r=s.property.value;const i=Fd(r);if(n!=null)return n[i]}function Xg(s,e){let n,r;if(s.callee.type==="Member"){const l=s.callee,c=Vd(l.object,e);if(c===vr||l.optional&&c==null)return vr;let d;l.computed?d=Ze(l.property,e):d=l.property.value;const f=Fd(d);c==null?n=void 0:(n=c[f],r=c)}else if(n=Vd(s.callee,e),n===vr)return vr;if(s.optional&&n==null)return vr;if(typeof n!="function")throw new Error("Attempted to call a non-function value");const i=Jg(s.args,e);return n.apply(r,i)}function Jg(s,e){const n=[];for(const r of s)if(r.type==="Spread"){const i=Ze(r.argument,e);if(i!=null)for(const l of i)n.push(l)}else n.push(Ze(r,e));return n}function Qg(s,e,n){for(let r=0;r":return n>r;case"<=":return n<=r;case">=":return n>=r;default:throw new Error(`Unknown binary operator "${s.operator}"`)}}case"Logical":{const n=Ze(s.left,e);switch(s.operator){case"&&":return n&&Ze(s.right,e);case"||":return n||Ze(s.right,e);case"??":return n??Ze(s.right,e);default:throw new Error(`Unknown logical operator "${s.operator}"`)}}case"Conditional":return Ze(s.test,e)?Ze(s.consequent,e):Ze(s.alternate,e);case"Array":{const n=[];for(const r of s.elements)if(r.type==="Spread"){const i=Ze(r.argument,e);if(i!=null)for(const l of i)n.push(l)}else n.push(Ze(r,e));return n}case"Object":{const n={};for(const r of s.properties)if(r.kind==="spread"){const i=Ze(r.value,e);if(i!=null&&typeof i=="object")for(const l of Object.keys(i))Kd(n,l,i[l])}else{let i;r.computed?i=Ze(r.key,e):i=r.key.value;const l=Ze(r.value,e);Kd(n,String(i),l)}return n}case"Arrow":{const n=e,r=s.params,i=s.body,l=s.isBlock;return function(...d){const f={vars:{},parent:n};return Qg(r,d,f),l?Zg(i,f):Ze(i,f)}}case"Function":{const n=e,r=s.params,i=s.body,l=s.name,c=function(...f){const h={vars:{},parent:n};return l&&(h.vars[l]=c),Qg(r,f,h),Zg(i,h)};return c}case"Delete":{const n=s.argument,r=Ze(n.object,e);let i;n.computed?i=Ze(n.property,e):i=n.property.value;const l=Fd(i);if(r==null||typeof r!="object"&&typeof r!="function")return!0;if(Vg.has(r))throw new Error("delete on a built-in global object is not allowed");return delete r[l]}case"Block":{const n={vars:{},parent:e};for(const r of s.body)Ze(r,n);return}case"VarDecl":{for(const n of s.declarations)e.vars[n.name]=Ze(n.init,e);return}case"If":{Ze(s.test,e)?Ze(s.consequent,e):s.alternate&&Ze(s.alternate,e);return}case"ForOf":{const n=Ze(s.iterable,e);if(n!=null)for(const r of n){const i={vars:{},parent:e};i.vars[s.name]=r;try{Ze(s.body,i)}catch(l){if(l instanceof Gd)continue;if(l instanceof qd)break;throw l}}return}case"Return":throw new Bd(s.argument?Ze(s.argument,e):void 0);case"ExprStmt":Ze(s.expression,e);return;case"Break":throw new qd;case"Continue":throw new Gd;case"Empty":return;case"Try":{try{try{Ze(s.block,e)}catch(n){if(n instanceof Bd||n instanceof qd||n instanceof Gd)throw n;if(s.handler){const r={vars:{},parent:e};s.handlerParam&&(r.vars[s.handlerParam]=n),Ze(s.handler,r)}else throw n}}finally{s.finalizer&&Ze(s.finalizer,e)}return}case"New":{const n=Pd[s.ctor];if(typeof n!="function")throw new Error("new on non-whitelisted constructor");const r=Jg(s.args,e);return new n(...r)}case"Template":{let n=s.quasis[0]??"";for(let r=0;r0}getFromRenderCycleCache(e){if(this.isRenderCycleCacheActive())return this.renderCycleCache.get(e)}saveToRenderCycleCache(e,n){this.isRenderCycleCacheActive()&&this.renderCycleCache.set(e,n)}resolveBindings(e,n,r,i){const l={...this.defaultOptions,...r},c=yo(),d=n._computed&&!n.$computed?{...n,$computed:n._computed}:n,f=(S,v)=>{const _=v.trim();let x=!1,A=_;if(_.startsWith(nr)&&(x=!0,A=_.slice(nr.length)),Gn(A))try{const B=this.evaluatePipeExpression(A,d,l,{...i,method:"resolveBindings",displayExpression:`{{${_}}}`}),W=this.formatValue(B);return x?go(W):W}catch(B){return $a.error("Pipe expression evaluation failed:",A,B),S}if(ho(A)){const B=c?.isEnabled()?performance.now():0;try{let W,pe=!1;if(l.skipCache)W=this.evaluateExpression(A,d);else{const we=`expr:${A}`,Ue=this.getFromRenderCycleCache(we);Ue!==void 0?(W=Ue,pe=!0):(W=this.evaluateExpression(A,d),this.saveToRenderCycleCache(we,W))}if(c?.isEnabled()){const we=performance.now()-B;c.trackExpressionEval({expression:`{{${_}}}`,result:this.sanitizeResultForTracking(W),resultType:this.getResultType(W),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:pe,duration:we,method:"resolveBindings",skipCache:l.skipCache})}const Se=this.formatValue(W);return x?go(Se):Se}catch(W){return $a.error("Expression evaluation failed:",A,W),S}}if(l.skipCache){const B=c?.isEnabled()?performance.now():0,W=this.resolvePath(A,d,l);if(c?.isEnabled()){const Se=performance.now()-B;c.trackExpressionEval({expression:`{{${_}}}`,result:this.sanitizeResultForTracking(W),resultType:this.getResultType(W),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:!1,duration:Se,method:"resolveBindings",skipCache:!0})}const pe=this.formatValue(W);return x?go(pe):pe}const $=A.startsWith("_global")||A.startsWith("_local")||A.startsWith("_isolated")||A.startsWith("$parent"),k=c?.isEnabled()?performance.now():0;let O,P=!1;if($){const B=this.getFromRenderCycleCache(A);B!==void 0?(O=B,P=!0):(O=this.resolvePath(A,d,l),this.saveToRenderCycleCache(A,O))}else{const B=this.getFromCache(A);B!==void 0?(O=B,P=!0):(O=this.resolvePath(A,d,l),this.saveToCache(A,O))}if(c?.isEnabled()){const B=performance.now()-k;c.trackExpressionEval({expression:`{{${_}}}`,result:this.sanitizeResultForTracking(O),resultType:this.getResultType(O),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:P,duration:B,method:"resolveBindings",skipCache:l.skipCache})}const G=this.formatValue(O);return x?go(G):G},h=n0(e);if(h.length===0)return e;let m="",y=0;for(const S of h)m+=e.slice(y,S.start),m+=f(e.slice(S.start,S.end),S.expr),y=S.end;return m+e.slice(y)}evaluatePipeExpression(e,n,r,i){const l={...this.defaultOptions,...r},c=yo(),d=c?.isEnabled()?performance.now():0,f=n._computed&&!n.$computed?{...n,$computed:n._computed}:n,[h,m]=e0(e);let y,S=!1;const v=ho(h),_=h.startsWith("_global")||h.startsWith("_local")||h.startsWith("_isolated")||h.startsWith("$parent");if(l.skipCache)v?y=this.evaluateExpression(h,f):y=this.resolvePath(h,f,l);else if(v){const A=this.getFromRenderCycleCache(`expr:${h}`);A!==void 0?(y=A,S=!0):(y=this.evaluateExpression(h,f),this.saveToRenderCycleCache(`expr:${h}`,y))}else if(_){const A=this.getFromRenderCycleCache(h);A!==void 0?(y=A,S=!0):(y=this.resolvePath(h,f,l),this.saveToRenderCycleCache(h,y))}else{const A=this.getFromCache(h);A!==void 0?(y=A,S=!0):(y=this.resolvePath(h,f,l),this.saveToCache(h,y))}const x=t0(y,m);if(c?.isEnabled()){const A=performance.now()-d;c.trackExpressionEval({expression:i?.displayExpression??`{{${e}}}`,result:this.sanitizeResultForTracking(x),resultType:this.getResultType(x),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:S,duration:A,method:i?.method??"evaluatePipeExpression",skipCache:l.skipCache})}return x}resolve(e,n,r,i){const l={...this.defaultOptions,...r},c=yo(),d=c?.isEnabled()?performance.now():0;if(l.skipCache){const y=this.resolvePath(e,n,l);return c?.isEnabled()&&c.trackExpressionEval({expression:e,result:this.sanitizeResultForTracking(y),resultType:this.getResultType(y),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:!1,duration:performance.now()-d,method:"resolve",skipCache:!0}),y}const f=e.startsWith("_global")||e.startsWith("_local")||e.startsWith("_isolated")||e.startsWith("$parent");let h=!1;if(f){const y=this.getFromRenderCycleCache(e);if(y!==void 0)return h=!0,c?.isEnabled()&&c.trackExpressionEval({expression:e,result:this.sanitizeResultForTracking(y),resultType:this.getResultType(y),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:!0,duration:performance.now()-d,method:"resolve",skipCache:l.skipCache}),y}else{const y=this.getFromCache(e);if(y!==void 0)return h=!0,c?.isEnabled()&&c.trackExpressionEval({expression:e,result:this.sanitizeResultForTracking(y),resultType:this.getResultType(y),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:!0,duration:performance.now()-d,method:"resolve",skipCache:l.skipCache}),y}const m=this.resolvePath(e,n,l);return f?this.saveToRenderCycleCache(e,m):this.saveToCache(e,m),c?.isEnabled()&&c.trackExpressionEval({expression:e,result:this.sanitizeResultForTracking(m),resultType:this.getResultType(m),componentId:i?.componentId,componentName:i?.componentName,propName:i?.propName,fromCache:h,duration:performance.now()-d,method:"resolve",skipCache:l.skipCache}),m}resolvePath(e,n,r,i=0,l=new WeakSet){if(typeof e!="string"||e.trim()===""){$a.warn("resolvePath: 빈 경로가 전달되었습니다 — undefined 로 해석합니다.");return}if(r.maxDepth&&i>r.maxDepth){if(r.detectCircular)throw new Yd(`Maximum depth exceeded (${r.maxDepth}). Possible circular reference.`,e,n);return r.defaultValue}const c=this.parsePath(e);let d=n;for(let f=0;foa.CACHE_EXPIRY){this.cache.delete(e),r?.isEnabled()&&r.recordCacheMiss();return}return r?.isEnabled()&&r.recordCacheHit(),n.value}saveToCache(e,n){this.cache.set(e,{value:n,timestamp:Date.now()})}isActionDefinition(e){return typeof e.handler!="string"?!1:e.params!==void 0||Array.isArray(e.actions)||typeof e.target=="string"||e.onSuccess!==void 0||e.onError!==void 0}resolveObject(e,n,r){if(this.isSwitchExpression(e)){const d=e;return this.resolveSwitch(d,n,r)}if(this.isActionDefinition(e))return{...e};if("iteration"in e)return{...e};const i={},c=[...["cellChildren","expandChildren","expandContext","render"],...r?.skipBindingKeys||[]];for(const[d,f]of Object.entries(e)){if(c.includes(d)){i[d]=f;continue}try{this.resolveObjectEntry(i,d,f,n,r)}catch(h){$a.warn(`resolveObject: 값 해석 실패 (key: ${d}):`,h),i[d]=void 0}}return i}resolveObjectEntry(e,n,r,i,l){if(typeof r=="string"){const c=Da(r);if(c!==null){const d=c.trim();let f=!1,h=d;d.startsWith(nr)&&(f=!0,h=d.slice(nr.length));let m;switch(qg(h)){case"empty":$a.warn(`resolveObject: 빈 바인딩 \`{{}}\` (key: ${n}) — undefined 로 해석합니다.`),m=void 0;break;case"literal":m=jd.get(h);break;case"pipe":m=this.evaluatePipeExpression(h,i,l);break;case"expression":m=this.evaluateExpression(h,i,l);break;default:m=this.resolve(h,i,l)}e[n]=f&&m!=null?ss(m):m}else e[n]=this.resolveBindings(r,i,l)}else Array.isArray(r)?e[n]=r.map(c=>typeof c=="string"?this.resolveBindings(c,i,l):typeof c=="object"&&c!==null?this.resolveObject(c,i,l):c):r&&typeof r=="object"?e[n]=this.resolveObject(r,i,l):e[n]=r}clearCache(){this.cache.clear()}invalidateCacheByKeys(e){for(const n of this.cache.keys())for(const r of e)if(n===r||n.startsWith(`${r}.`)||n.startsWith(`${r}[`)){this.cache.delete(n);break}}pruneCache(){const e=Date.now();for(const[n,r]of this.cache.entries())e-r.timestamp>oa.CACHE_EXPIRY&&this.cache.delete(n)}getCacheStats(){const e=Date.now();let n=0;for(const r of this.cache.values())e-r.timestamp>oa.CACHE_EXPIRY&&n++;return{size:this.cache.size,expired:n}}evaluateExpression(e,n,r){const i=yo(),l=i?.isEnabled()?performance.now():0;i?.isEnabled()&&i.trackBindingEval();try{let c=this.preprocessOptionalChaining(e);c=this.preprocessTranslationTokens(c);const d=this.extractVariablesFromExpression(c),f={...n};for(const A of d)A in f||(f[A]=void 0);n._computed&&!f.$computed&&(f.$computed=n._computed);let h=n.$templateId,m=n.$locale;if(typeof window<"u"&&(!h||!m)){const A=window.__templateApp?.getConfig?.();h??(h=A?.templateId),m??(m=A?.locale)}const y=m||"ko";f.$localized=(A,L)=>{if(A==null&&!L)return"";if(typeof A=="string")return A;if(A&&typeof A=="object"&&A[y])return A[y];if(L&&typeof L=="string"){const $=f.$t?f.$t(L):L;if($&&$!==L)return $}return A&&typeof A=="object"?A.ko||A.en||Object.values(A)[0]||"":A==null?"":String(A)};const S=typeof window<"u"?window.G7Core:void 0;f.$uuid=()=>S?.uuid?S.uuid():typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,A=>{const L=Math.random()*16|0;return(A==="x"?L:L&3|8).toString(16)});const v={templateId:h||"",locale:y};f.$t=A=>{if(!A||typeof A!="string")return"";try{return Ra.getInstance().translate(A,v)}catch(L){return $a.warn("$t() translation failed for key:",A,L),A}},f.$get=(A,L,$=void 0)=>{if(A==null)return $;const k=Array.isArray(L)?L:[L];if(k.length===0)return A;let O=A;for(const P of k){if(O==null||P==null)return $;O=O[P]}return O??$};const _=!1,x=Wd(c,f);if(i?.isEnabled()){const A=performance.now()-l;i.trackExpressionEval({expression:e,result:this.sanitizeResultForTracking(x),resultType:this.getResultType(x),componentId:r?.componentId,componentName:r?.componentName,propName:r?.propName,fromCache:_,duration:A,method:"evaluateExpression",skipCache:r?.skipCache})}return x}catch(c){throw new Error(`Failed to evaluate expression "${e}": ${c instanceof Error?c.message:String(c)}`)}}getResultType(e){return e===null?"null":e===void 0?"undefined":Array.isArray(e)?"array":typeof e}sanitizeResultForTracking(e){if(e==null||typeof e!="object")return e;try{if(Array.isArray(e))return e.length>10?`[Array(${e.length})]`:e.slice(0,10);const n=Object.keys(e);return n.length>20?`{Object(${n.length} keys)}`:(JSON.stringify(e),e)}catch{return"[Complex Object]"}}preprocessTranslationTokens(e){return e=e.replace(/(['"])(\$t:([a-zA-Z_][a-zA-Z0-9_.\-]*))\1/g,(n,r,i,l)=>`$t('${l}')`),e.replace(/(['"]\s*)?(\$t:[a-zA-Z_][a-zA-Z0-9_.\-]*)(?!\s*['"])/g,(n,r,i)=>r?n:`"${i}"`)}preprocessOptionalChaining(e){const n=[];let r=e.replace(/(['"])(?:(?!\1|\\).|\\.)*\1/g,l=>(n.push(l),`__STRING_LITERAL_${n.length-1}__`));const i=[];return r=r.replace(/\$t:[a-zA-Z_][a-zA-Z0-9_.\-]*(?:\|[^'"\s,)]+)?/g,l=>(i.push(l),`__TRANSLATION_TOKEN_${i.length-1}__`)),r=r.replace(/([a-zA-Z_$][a-zA-Z0-9_$]*)\.(?!\?)/g,"$1?."),r=r.replace(/__TRANSLATION_TOKEN_(\d+)__/g,(l,c)=>i[parseInt(c,10)]),r=r.replace(/__STRING_LITERAL_(\d+)__/g,(l,c)=>n[parseInt(c,10)]),r}extractVariablesFromExpression(e){const n=new Set(["true","false","null","undefined","NaN","Infinity","if","else","for","while","do","switch","case","break","continue","return","function","class","const","let","var","new","delete","typeof","instanceof","this","super","import","export","default","try","catch","finally","throw","Math","Date","JSON","Array","Object","String","Number","Boolean","RegExp","Set","Map","WeakSet","WeakMap","Symbol","Promise","BigInt","Error","parseInt","parseFloat","isNaN","isFinite","encodeURI","decodeURI","encodeURIComponent","decodeURIComponent"]),r=/(^|[^.\w$])([a-zA-Z_$][a-zA-Z0-9_$]*)/g,i=new Set;let l;for(;(l=r.exec(e))!==null;){const c=l[2];n.has(c)||i.add(c)}return Array.from(i)}isSwitchExpression(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&"$switch"in e&&"$cases"in e}resolveSwitch(e,n,r){const i={...r,skipCache:!0};let l;try{l=this.resolveBindings(e.$switch,n,i)?.toString()?.trim()??""}catch(d){$a.warn("resolveSwitch: $switch 키 평가 실패:",e.$switch,d),l=""}let c;if(l&&e.$cases&&l in e.$cases)c=e.$cases[l];else if("$default"in e)c=e.$default;else return;return typeof c=="string"?c.includes("{{")?this.resolveBindings(c,n,i):c:c!==null&&typeof c=="object"?this.resolveObject(c,n,i):c}};M(oa,"PATH_SEGMENT_PATTERN",/([^.[\]]+)|\[(\d+)\]/g),M(oa,"CACHE_EXPIRY",3e4);let kn=oa;const Xd=new kn,Ql={mobile:{min:0,max:767},tablet:{min:768,max:1023},desktop:{min:1024,max:1/0},portable:{min:0,max:1023}},Zl=new Map;function h0(s,e){let n=null;return((...r)=>{n!==null&&clearTimeout(n),n=setTimeout(()=>{s(...r)},e)})}class p0{constructor(){M(this,"subscribers",new Set);M(this,"currentWidth",1024);M(this,"debouncedHandler",null);M(this,"isInitialized",!1);this.initialize()}initialize(){typeof window>"u"||(this.currentWidth=window.innerWidth,this.isInitialized=!0,this.debouncedHandler=h0(()=>{this.currentWidth=window.innerWidth,this.notifySubscribers()},150),window.addEventListener("resize",this.debouncedHandler))}notifySubscribers(){this.subscribers.forEach(e=>{e(this.currentWidth)})}subscribe(e){return this.subscribers.add(e),e(this.currentWidth),()=>{this.subscribers.delete(e)}}getWidth(){return this.currentWidth}parseRange(e){if(Zl.has(e))return Zl.get(e)??null;let n=null;if(Ql[e])n={...Ql[e]};else{const r=e.match(/^(-?\d*)-(-?\d*)$/);if(r){const[,i,l]=r,c=i===""?0:parseInt(i,10),d=l===""?1/0:parseInt(l,10);!isNaN(c)&&!isNaN(d)&&c<=d&&(n={min:c,max:d})}}return Zl.set(e,n),n}getMatchingKey(e,n){const r=[];for(const i of Object.keys(e)){const l=this.parseRange(i);l&&n>=l.min&&n<=l.max&&r.push({key:i,range:l,isPreset:!!Ql[i]})}return r.length===0?null:(r.sort((i,l)=>{if(i.isPreset!==l.isPreset)return i.isPreset?1:-1;const c=i.range.max-i.range.min,d=l.range.max-l.range.min;return c-d}),r[0].key)}matches(e){const n=this.parseRange(e);return n?this.currentWidth>=n.min&&this.currentWidth<=n.max:!1}clearSubscribers(){this.subscribers.clear()}destroy(){this.debouncedHandler&&typeof window<"u"&&window.removeEventListener("resize",this.debouncedHandler),this.clearSubscribers(),Zl.clear()}_setWidthForTesting(e){this.currentWidth=e,this.notifySubscribers()}}const Si=new p0,bo=dt("ConditionEvaluator");function g0(s,e,n,r){return Hd(Gg(s),e,n,{skipCache:!0,onEmpty:()=>{bo.warn(`${r}: 빈 바인딩 \`{{}}\` — undefined 로 해석합니다.`)}})}function em(s,e,n){if(!s)return!0;try{const r=Da(s);let i;if(r!==null?i=g0(r,e,n,"evaluateStringCondition"):i=n.resolveBindings(s,e,{skipCache:!0}),typeof i=="string"){const l=i.toLowerCase().trim();if(l==="false"||l==="0"||l===""||l==="null"||l==="undefined")return!1}return!!i}catch(r){return bo.warn(`evaluateStringCondition: 조건 평가 실패: ${s}`,r),!1}}function ec(s,e,n){if(typeof s=="string")return em(s,e,n);if("and"in s){if(!Array.isArray(s.and)||s.and.length===0)return bo.warn("evaluateConditionExpression: AND 그룹이 비어있습니다"),!0;for(const r of s.and)if(!ec(r,e,n))return!1;return!0}if("or"in s){if(!Array.isArray(s.or)||s.or.length===0)return bo.warn("evaluateConditionExpression: OR 그룹이 비어있습니다"),!1;for(const r of s.or)if(ec(r,e,n))return!0;return!1}return bo.warn("evaluateConditionExpression: 알 수 없는 조건 형식",s),!1}function tm(s,e,n){if(!Array.isArray(s)||s.length===0)return{matched:!1,branchIndex:-1};for(let r=0;r{rr.warn(`evaluateIfCondition: 빈 바인딩 \`{{}}\` (컴포넌트: ${r||"unknown"}) — undefined 로 해석합니다.`)}}):l=n.resolveBindings(s,e,{skipCache:!0}),typeof l=="string"){const c=l.toLowerCase().trim();if(c==="false"||c==="0"||c===""||c==="null"||c==="undefined")return!1}return!!l}catch(i){return rr.warn(`evaluateIfCondition: 조건 평가 실패 (컴포넌트: ${r||"unknown"}):`,i),!1}}function os(s,e,n,r){if(s.if!==void 0)return im(s.if,e,n,r);if(s.condition!==void 0)return im(s.condition,e,n,r);if(s.conditions===void 0)return!0;const i=s.conditions;try{return m0(i)?ec(i,e,n):y0(i)?tm(i,e,n).matched:(rr.warn(`evaluateRenderCondition: 알 수 없는 conditions 형식 (컴포넌트: ${r||"unknown"})`),!0)}catch(l){return rr.warn(`evaluateRenderCondition: conditions 평가 실패 (컴포넌트: ${r||"unknown"}):`,l),!1}}function sm(s){if(!s.responsive)return s;const e=Si.getWidth(),n=Si.getMatchingKey(s.responsive,e);if(!n)return s;const r=s.responsive[n];return{...s,props:{...s.props,...r.props},children:r.children??s.children,text:r.text??s.text,if:r.if??s.if,iteration:r.iteration??s.iteration}}function vo(s,e,n,r,i){if(!s||s.length===0)return[];const l=i?.bindingEngine??new kn,c=i?.translationEngine??Ra.getInstance(),d=i?.translationContext??{templateId:"",locale:"ko"},f=v0(e,i?.componentContext),h=(v,_)=>{if(typeof v=="string")return Yl(v)||Xl(v)||!/\$t:[a-zA-Z0-9._-]+/.test(v)?v:c.resolveTranslations(v,d,_);if(Array.isArray(v))return v.map(x=>h(x,_));if(v&&typeof v=="object"){const x={};for(const[A,L]of Object.entries(v))x[A]=h(L,_);return x}return v},m=(v,_)=>{if(typeof v=="string"){if(Yl(v))return zd(v);if(Xl(v)){const A=[],L=v.replace(new RegExp(`${po}([^${bi}]*)${bi}`,"g"),(k,O)=>(A.push(O),`${Oa}${A.length-1}${Oa}`));let $=L;return/\$t:[a-zA-Z0-9._-]+/.test(L)&&($=c.resolveTranslations(L,d,_)),$.replace(new RegExp(`${Oa}(\\d+)${Oa}`,"g"),(k,O)=>A[parseInt(O)])}if(v.startsWith("$t:defer:")){const A="$t:"+v.slice(9);return c.resolveTranslations(A,d,_)}if(v.startsWith("$t:"))return c.resolveTranslations(v,d,_);if(/\$t:[a-zA-Z0-9._-]+/.test(v)){const A=v.trim();if(!(A.startsWith("{")&&A.endsWith("}")||A.startsWith("[")&&A.endsWith("]"))&&!v.includes("{{"))return c.resolveTranslations(v,d,_)}const x=am(v);if(x!==null){let A=!1,L=x;x.startsWith(nr)&&(A=!0,L=x.slice(nr.length));let $=!1,k=Hd(L,_,l,{skipCache:!0,onError:O=>{rr.warn("renderItemChildren: 표현식 평가 실패:",O),$=!0},onEmpty:()=>{rr.warn("renderItemChildren: 빈 바인딩 `{{}}` 은 해석하지 않습니다.")}});return $?void 0:(A||(k=h(k,_)),A&&k!=null?ss(k):k)}if(v.includes("{{")){const A=l.resolveBindings(v,_,{skipCache:!0});return typeof A=="string"&&/\$t:[a-zA-Z0-9._-]+/.test(A)?c.resolveTranslations(A,d,_):A}return v}if(Array.isArray(v))return v.map(x=>m(x,_));if(v&&typeof v=="object"){if(l.isSwitchExpression(v))return l.resolveSwitch(v,_,{skipCache:!0});if(l.isActionDefinition(v))return{...v};const x={};for(const[A,L]of Object.entries(v))x[A]=m(L,_);return x}return v},y=(v,_)=>{if(!v)return{};const x={};for(const[A,L]of Object.entries(v))x[A]=m(L,_);return x},S=(v,_,x)=>{const A=sm(v),L=A.iteration;if(!L)return[];const $=Jd(L.source,x,l);if(!Array.isArray($))return rr.warn(`renderItemChildren: iteration.source가 배열이 아닙니다: ${L.source}`),[];const k=nm();if(k?.isEnabled()){const P=`${_}-iteration`;k.trackIteration(P,L.source,L.item_var,L.index_var,$.length)}const O=n[A.name];return O?$.flatMap((P,G)=>{const B={...x,[L.item_var]:P,[`${L.item_var}_index`]:G,...L.index_var?{[L.index_var]:G}:{}},W=os({if:A.if,condition:A.condition,conditions:A.conditions},B,l,A.id);if(A.if&&k?.isEnabled()){const wt=`${_}-iter-${G}-if`;k.trackIfCondition(wt,A.if,W,A.name)}if(!W)return[];const pe=A.id?String(La(m(A.id,B))):void 0,Se=`${_}-iter-${G}`,we=i?.getRemountKey?i.getRemountKey(pe,Se):Se,Ue=y(A.props,B),Fe=Qd(Ue,A.actions,B,{actionDispatcher:i?.actionDispatcher,componentContext:i?.componentContext});let qe=null;return A.text!==void 0?qe=m(A.text,B):A.children&&A.children.length>0&&(qe=vo(A.children,B,n,we,i)),k?.isEnabled()&&k.trackRender(A.name),[Ye.createElement(O,{key:we,...La(Fe)},La(qe))]}):(rr.warn(`renderItemChildren: 컴포넌트를 찾을 수 없습니다: ${A.name}`),[])};return s.flatMap((v,_)=>{const x=sm(v),A=x.id?String(La(m(x.id,f))):void 0,L=r?`${r}-${A||_}`:A||`child-${_}`,$=i?.getRemountKey?i.getRemountKey(A,L):L;if(x.iteration)return S(x,$,f);const k=os({if:x.if,condition:x.condition,conditions:x.conditions},f,l,x.id),O=nm();if(x.if&&O?.isEnabled()){const pe=`${$}-if`;O.trackIfCondition(pe,x.if,k,x.name)}if(!k)return[];const P=n[x.name];if(!P)return rr.warn(`renderItemChildren: 컴포넌트를 찾을 수 없습니다: ${x.name}`),[];const G=y(x.props,f),B=Qd(G,x.actions,f,{actionDispatcher:i?.actionDispatcher,componentContext:i?.componentContext});let W=null;return x.text!==void 0?W=m(x.text,f):x.children&&x.children.length>0&&(W=vo(x.children,f,n,$,i)),O?.isEnabled()&&O.trackRender(x.name),[Ye.createElement(P,{key:$,...La(B)},La(W))]})}function ls(s,e,n,r){let i,l;return n instanceof kn?(i=n,l=r):(i=rm,l=n),i.resolveBindings(s,e,l)}function S0(s,e,n,r){const i=n??rm,l={skipCache:!0,...r};let c;try{c=i.resolveBindings(s.key,e,{skipCache:l.skipCache})?.toString()?.trim()??""}catch(h){rr.warn("resolveClassMap: key 평가 실패:",s.key,h),c=""}let d="";c&&s.variants&&c in s.variants?d=s.variants[c]:s.default&&(d=s.default);const f=[];return s.base?.trim()&&f.push(s.base.trim()),d?.trim()&&f.push(d.trim()),f.join(" ")}function om(s,e){return function(){return s.apply(e,arguments)}}const{toString:w0}=Object.prototype,{getPrototypeOf:tc}=Object,{iterator:nc,toStringTag:lm}=Symbol,rc=(s=>e=>{const n=w0.call(e);return s[n]||(s[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),Sr=s=>(s=s.toLowerCase(),e=>rc(e)===s),ac=s=>e=>typeof e===s,{isArray:cs}=Array,us=ac("undefined");function So(s){return s!==null&&!us(s)&&s.constructor!==null&&!us(s.constructor)&&$n(s.constructor.isBuffer)&&s.constructor.isBuffer(s)}const cm=Sr("ArrayBuffer");function C0(s){let e;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?e=ArrayBuffer.isView(s):e=s&&s.buffer&&cm(s.buffer),e}const E0=ac("string"),$n=ac("function"),um=ac("number"),wo=s=>s!==null&&typeof s=="object",_0=s=>s===!0||s===!1,ic=s=>{if(rc(s)!=="object")return!1;const e=tc(s);return(e===null||e===Object.prototype||Object.getPrototypeOf(e)===null)&&!(lm in s)&&!(nc in s)},A0=s=>{if(!wo(s)||So(s))return!1;try{return Object.keys(s).length===0&&Object.getPrototypeOf(s)===Object.prototype}catch{return!1}},x0=Sr("Date"),T0=Sr("File"),k0=s=>!!(s&&typeof s.uri<"u"),R0=s=>s&&typeof s.getParts<"u",D0=Sr("Blob"),O0=Sr("FileList"),L0=s=>wo(s)&&$n(s.pipe);function $0(){return typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}}const dm=$0(),fm=typeof dm.FormData<"u"?dm.FormData:void 0,M0=s=>{if(!s)return!1;if(fm&&s instanceof fm)return!0;const e=tc(s);if(!e||e===Object.prototype||!$n(s.append))return!1;const n=rc(s);return n==="formdata"||n==="object"&&$n(s.toString)&&s.toString()==="[object FormData]"},N0=Sr("URLSearchParams"),[I0,j0,H0,z0]=["ReadableStream","Request","Response","Headers"].map(Sr),U0=s=>s.trim?s.trim():s.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function Co(s,e,{allOwnKeys:n=!1}={}){if(s===null||typeof s>"u")return;let r,i;if(typeof s!="object"&&(s=[s]),cs(s))for(r=0,i=s.length;r0;)if(i=n[r],e===i.toLowerCase())return i;return null}const wi=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,pm=s=>!us(s)&&s!==wi;function Zd(...s){const{caseless:e,skipUndefined:n}=pm(this)&&this||{},r={},i=(l,c)=>{if(c==="__proto__"||c==="constructor"||c==="prototype")return;const d=e&&hm(r,c)||c,f=ef(r,d)?r[d]:void 0;ic(f)&&ic(l)?r[d]=Zd(f,l):ic(l)?r[d]=Zd({},l):cs(l)?r[d]=l.slice():(!n||!us(l))&&(r[d]=l)};for(let l=0,c=s.length;l(Co(e,(i,l)=>{n&&$n(i)?Object.defineProperty(s,l,{__proto__:null,value:om(i,n),writable:!0,enumerable:!0,configurable:!0}):Object.defineProperty(s,l,{__proto__:null,value:i,writable:!0,enumerable:!0,configurable:!0})},{allOwnKeys:r}),s),B0=s=>(s.charCodeAt(0)===65279&&(s=s.slice(1)),s),q0=(s,e,n,r)=>{s.prototype=Object.create(e.prototype,r),Object.defineProperty(s.prototype,"constructor",{__proto__:null,value:s,writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(s,"super",{__proto__:null,value:e.prototype}),n&&Object.assign(s.prototype,n)},G0=(s,e,n,r)=>{let i,l,c;const d={};if(e=e||{},s==null)return e;do{for(i=Object.getOwnPropertyNames(s),l=i.length;l-- >0;)c=i[l],(!r||r(c,s,e))&&!d[c]&&(e[c]=s[c],d[c]=!0);s=n!==!1&&tc(s)}while(s&&(!n||n(s,e))&&s!==Object.prototype);return e},F0=(s,e,n)=>{s=String(s),(n===void 0||n>s.length)&&(n=s.length),n-=e.length;const r=s.indexOf(e,n);return r!==-1&&r===n},V0=s=>{if(!s)return null;if(cs(s))return s;let e=s.length;if(!um(e))return null;const n=new Array(e);for(;e-- >0;)n[e]=s[e];return n},K0=(s=>e=>s&&e instanceof s)(typeof Uint8Array<"u"&&tc(Uint8Array)),W0=(s,e)=>{const r=(s&&s[nc]).call(s);let i;for(;(i=r.next())&&!i.done;){const l=i.value;e.call(s,l[0],l[1])}},Y0=(s,e)=>{let n;const r=[];for(;(n=s.exec(e))!==null;)r.push(n);return r},X0=Sr("HTMLFormElement"),J0=s=>s.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,r,i){return r.toUpperCase()+i}),ef=(({hasOwnProperty:s})=>(e,n)=>s.call(e,n))(Object.prototype),Q0=Sr("RegExp"),gm=(s,e)=>{const n=Object.getOwnPropertyDescriptors(s),r={};Co(n,(i,l)=>{let c;(c=e(i,l,s))!==!1&&(r[l]=c||i)}),Object.defineProperties(s,r)},Z0=s=>{gm(s,(e,n)=>{if($n(s)&&["arguments","caller","callee"].includes(n))return!1;const r=s[n];if($n(r)){if(e.enumerable=!1,"writable"in e){e.writable=!1;return}e.set||(e.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},eC=(s,e)=>{const n={},r=i=>{i.forEach(l=>{n[l]=!0})};return cs(s)?r(s):r(String(s).split(e)),n},tC=()=>{},nC=(s,e)=>s!=null&&Number.isFinite(s=+s)?s:e;function rC(s){return!!(s&&$n(s.append)&&s[lm]==="FormData"&&s[nc])}const aC=s=>{const e=new WeakSet,n=r=>{if(wo(r)){if(e.has(r))return;if(So(r))return r;if(!("toJSON"in r)){e.add(r);const i=cs(r)?[]:{};return Co(r,(l,c)=>{const d=n(l);!us(d)&&(i[c]=d)}),e.delete(r),i}}return r};return n(s)},iC=Sr("AsyncFunction"),sC=s=>s&&(wo(s)||$n(s))&&$n(s.then)&&$n(s.catch),mm=((s,e)=>s?setImmediate:e?((n,r)=>(wi.addEventListener("message",({source:i,data:l})=>{i===wi&&l===n&&r.length&&r.shift()()},!1),i=>{r.push(i),wi.postMessage(n,"*")}))(`axios@${Math.random()}`,[]):n=>setTimeout(n))(typeof setImmediate=="function",$n(wi.postMessage)),oC=typeof queueMicrotask<"u"?queueMicrotask.bind(wi):typeof process<"u"&&process.nextTick||mm,K={isArray:cs,isArrayBuffer:cm,isBuffer:So,isFormData:M0,isArrayBufferView:C0,isString:E0,isNumber:um,isBoolean:_0,isObject:wo,isPlainObject:ic,isEmptyObject:A0,isReadableStream:I0,isRequest:j0,isResponse:H0,isHeaders:z0,isUndefined:us,isDate:x0,isFile:T0,isReactNativeBlob:k0,isReactNative:R0,isBlob:D0,isRegExp:Q0,isFunction:$n,isStream:L0,isURLSearchParams:N0,isTypedArray:K0,isFileList:O0,forEach:Co,merge:Zd,extend:P0,trim:U0,stripBOM:B0,inherits:q0,toFlatObject:G0,kindOf:rc,kindOfTest:Sr,endsWith:F0,toArray:V0,forEachEntry:W0,matchAll:Y0,isHTMLForm:X0,hasOwnProperty:ef,hasOwnProp:ef,reduceDescriptors:gm,freezeMethods:Z0,toObjectSet:eC,toCamelCase:J0,noop:tC,toFiniteNumber:nC,findKey:hm,global:wi,isContextDefined:pm,isSpecCompliantForm:rC,toJSONObject:aC,isAsyncFn:iC,isThenable:sC,setImmediate:mm,asap:oC,isIterable:s=>s!=null&&$n(s[nc])},lC=K.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),cC=s=>{const e={};let n,r,i;return s&&s.split(` +`).forEach(function(c){i=c.indexOf(":"),n=c.substring(0,i).trim().toLowerCase(),r=c.substring(i+1).trim(),!(!n||e[n]&&lC[n])&&(n==="set-cookie"?e[n]?e[n].push(r):e[n]=[r]:e[n]=e[n]?e[n]+", "+r:r)}),e};function uC(s){let e=0,n=s.length;for(;ee;){const r=s.charCodeAt(n-1);if(r!==9&&r!==32)break;n-=1}return e===0&&n===s.length?s:s.slice(e,n)}const dC=new RegExp("[\\u0000-\\u0008\\u000a-\\u001f\\u007f]+","g"),fC=new RegExp("[^\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+","g");function tf(s,e){return K.isArray(s)?s.map(n=>tf(n,e)):uC(String(s).replace(e,""))}const hC=s=>tf(s,dC),pC=s=>tf(s,fC);function ym(s){const e=Object.create(null);return K.forEach(s.toJSON(),(n,r)=>{e[r]=pC(n)}),e}const bm=Symbol("internals");function Eo(s){return s&&String(s).trim().toLowerCase()}function sc(s){return s===!1||s==null?s:K.isArray(s)?s.map(sc):hC(String(s))}function gC(s){const e=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(s);)e[r[1]]=r[2];return e}const mC=s=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(s.trim());function nf(s,e,n,r,i){if(K.isFunction(r))return r.call(this,e,n);if(i&&(e=n),!!K.isString(e)){if(K.isString(r))return e.indexOf(r)!==-1;if(K.isRegExp(r))return r.test(e)}}function yC(s){return s.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(e,n,r)=>n.toUpperCase()+r)}function bC(s,e){const n=K.toCamelCase(" "+e);["get","set","has"].forEach(r=>{Object.defineProperty(s,r+n,{__proto__:null,value:function(i,l,c){return this[r].call(this,e,i,l,c)},configurable:!0})})}let Rn=class{constructor(e){e&&this.set(e)}set(e,n,r){const i=this;function l(d,f,h){const m=Eo(f);if(!m)throw new Error("header name must be a non-empty string");const y=K.findKey(i,m);(!y||i[y]===void 0||h===!0||h===void 0&&i[y]!==!1)&&(i[y||f]=sc(d))}const c=(d,f)=>K.forEach(d,(h,m)=>l(h,m,f));if(K.isPlainObject(e)||e instanceof this.constructor)c(e,n);else if(K.isString(e)&&(e=e.trim())&&!mC(e))c(cC(e),n);else if(K.isObject(e)&&K.isIterable(e)){let d={},f,h;for(const m of e){if(!K.isArray(m))throw TypeError("Object iterator must return a key-value pair");d[h=m[0]]=(f=d[h])?K.isArray(f)?[...f,m[1]]:[f,m[1]]:m[1]}c(d,n)}else e!=null&&l(n,e,r);return this}get(e,n){if(e=Eo(e),e){const r=K.findKey(this,e);if(r){const i=this[r];if(!n)return i;if(n===!0)return gC(i);if(K.isFunction(n))return n.call(this,i,r);if(K.isRegExp(n))return n.exec(i);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,n){if(e=Eo(e),e){const r=K.findKey(this,e);return!!(r&&this[r]!==void 0&&(!n||nf(this,this[r],r,n)))}return!1}delete(e,n){const r=this;let i=!1;function l(c){if(c=Eo(c),c){const d=K.findKey(r,c);d&&(!n||nf(r,r[d],d,n))&&(delete r[d],i=!0)}}return K.isArray(e)?e.forEach(l):l(e),i}clear(e){const n=Object.keys(this);let r=n.length,i=!1;for(;r--;){const l=n[r];(!e||nf(this,this[l],l,e,!0))&&(delete this[l],i=!0)}return i}normalize(e){const n=this,r={};return K.forEach(this,(i,l)=>{const c=K.findKey(r,l);if(c){n[c]=sc(i),delete n[l];return}const d=e?yC(l):String(l).trim();d!==l&&delete n[l],n[d]=sc(i),r[d]=!0}),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const n=Object.create(null);return K.forEach(this,(r,i)=>{r!=null&&r!==!1&&(n[i]=e&&K.isArray(r)?r.join(", "):r)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([e,n])=>e+": "+n).join(` +`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...n){const r=new this(e);return n.forEach(i=>r.set(i)),r}static accessor(e){const r=(this[bm]=this[bm]={accessors:{}}).accessors,i=this.prototype;function l(c){const d=Eo(c);r[d]||(bC(i,c),r[d]=!0)}return K.isArray(e)?e.forEach(l):l(e),this}};Rn.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),K.reduceDescriptors(Rn.prototype,({value:s},e)=>{let n=e[0].toUpperCase()+e.slice(1);return{get:()=>s,set(r){this[n]=r}}}),K.freezeMethods(Rn);const vC="[REDACTED ****]";function SC(s){if(K.hasOwnProp(s,"toJSON"))return!0;let e=Object.getPrototypeOf(s);for(;e&&e!==Object.prototype;){if(K.hasOwnProp(e,"toJSON"))return!0;e=Object.getPrototypeOf(e)}return!1}function wC(s,e){const n=new Set(e.map(l=>String(l).toLowerCase())),r=[],i=l=>{if(l===null||typeof l!="object"||K.isBuffer(l))return l;if(r.indexOf(l)!==-1)return;l instanceof Rn&&(l=l.toJSON()),r.push(l);let c;if(K.isArray(l))c=[],l.forEach((d,f)=>{const h=i(d);K.isUndefined(h)||(c[f]=h)});else{if(!K.isPlainObject(l)&&SC(l))return r.pop(),l;c=Object.create(null);for(const[d,f]of Object.entries(l)){const h=n.has(d.toLowerCase())?vC:i(f);K.isUndefined(h)||(c[d]=h)}}return r.pop(),c};return i(s)}let Oe=class kw extends Error{static from(e,n,r,i,l,c){const d=new kw(e.message,n||e.code,r,i,l);return d.cause=e,d.name=e.name,e.status!=null&&d.status==null&&(d.status=e.status),c&&Object.assign(d,c),d}constructor(e,n,r,i,l){super(e),Object.defineProperty(this,"message",{__proto__:null,value:e,enumerable:!0,writable:!0,configurable:!0}),this.name="AxiosError",this.isAxiosError=!0,n&&(this.code=n),r&&(this.config=r),i&&(this.request=i),l&&(this.response=l,this.status=l.status)}toJSON(){const e=this.config,n=e&&K.hasOwnProp(e,"redact")?e.redact:void 0,r=K.isArray(n)&&n.length>0?wC(e,n):K.toJSONObject(e);return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:r,code:this.code,status:this.status}}};Oe.ERR_BAD_OPTION_VALUE="ERR_BAD_OPTION_VALUE",Oe.ERR_BAD_OPTION="ERR_BAD_OPTION",Oe.ECONNABORTED="ECONNABORTED",Oe.ETIMEDOUT="ETIMEDOUT",Oe.ECONNREFUSED="ECONNREFUSED",Oe.ERR_NETWORK="ERR_NETWORK",Oe.ERR_FR_TOO_MANY_REDIRECTS="ERR_FR_TOO_MANY_REDIRECTS",Oe.ERR_DEPRECATED="ERR_DEPRECATED",Oe.ERR_BAD_RESPONSE="ERR_BAD_RESPONSE",Oe.ERR_BAD_REQUEST="ERR_BAD_REQUEST",Oe.ERR_CANCELED="ERR_CANCELED",Oe.ERR_NOT_SUPPORT="ERR_NOT_SUPPORT",Oe.ERR_INVALID_URL="ERR_INVALID_URL",Oe.ERR_FORM_DATA_DEPTH_EXCEEDED="ERR_FORM_DATA_DEPTH_EXCEEDED";const CC=null;function rf(s){return K.isPlainObject(s)||K.isArray(s)}function vm(s){return K.endsWith(s,"[]")?s.slice(0,-2):s}function af(s,e,n){return s?s.concat(e).map(function(i,l){return i=vm(i),!n&&l?"["+i+"]":i}).join(n?".":""):e}function EC(s){return K.isArray(s)&&!s.some(rf)}const _C=K.toFlatObject(K,{},null,function(e){return/^is[A-Z]/.test(e)});function oc(s,e,n){if(!K.isObject(s))throw new TypeError("target must be an object");e=e||new FormData,n=K.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(A,L){return!K.isUndefined(L[A])});const r=n.metaTokens,i=n.visitor||y,l=n.dots,c=n.indexes,d=n.Blob||typeof Blob<"u"&&Blob,f=n.maxDepth===void 0?100:n.maxDepth,h=d&&K.isSpecCompliantForm(e);if(!K.isFunction(i))throw new TypeError("visitor must be a function");function m(x){if(x===null)return"";if(K.isDate(x))return x.toISOString();if(K.isBoolean(x))return x.toString();if(!h&&K.isBlob(x))throw new Oe("Blob is not supported. Use a Buffer instead.");return K.isArrayBuffer(x)||K.isTypedArray(x)?h&&typeof Blob=="function"?new Blob([x]):Buffer.from(x):x}function y(x,A,L){let $=x;if(K.isReactNative(e)&&K.isReactNativeBlob(x))return e.append(af(L,A,l),m(x)),!1;if(x&&!L&&typeof x=="object"){if(K.endsWith(A,"{}"))A=r?A:A.slice(0,-2),x=JSON.stringify(x);else if(K.isArray(x)&&EC(x)||(K.isFileList(x)||K.endsWith(A,"[]"))&&($=K.toArray(x)))return A=vm(A),$.forEach(function(O,P){!(K.isUndefined(O)||O===null)&&e.append(c===!0?af([A],P,l):c===null?A:A+"[]",m(O))}),!1}return rf(x)?!0:(e.append(af(L,A,l),m(x)),!1)}const S=[],v=Object.assign(_C,{defaultVisitor:y,convertValue:m,isVisitable:rf});function _(x,A,L=0){if(!K.isUndefined(x)){if(L>f)throw new Oe("Object is too deeply nested ("+L+" levels). Max depth: "+f,Oe.ERR_FORM_DATA_DEPTH_EXCEEDED);if(S.indexOf(x)!==-1)throw Error("Circular reference detected in "+A.join("."));S.push(x),K.forEach(x,function(k,O){(!(K.isUndefined(k)||k===null)&&i.call(e,k,K.isString(O)?O.trim():O,A,v))===!0&&_(k,A?A.concat(O):[O],L+1)}),S.pop()}}if(!K.isObject(s))throw new TypeError("data must be an object");return _(s),e}function Sm(s){const e={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+"};return encodeURIComponent(s).replace(/[!'()~]|%20/g,function(r){return e[r]})}function sf(s,e){this._pairs=[],s&&oc(s,this,e)}const wm=sf.prototype;wm.append=function(e,n){this._pairs.push([e,n])},wm.toString=function(e){const n=e?function(r){return e.call(this,r,Sm)}:Sm;return this._pairs.map(function(i){return n(i[0])+"="+n(i[1])},"").join("&")};function AC(s){return encodeURIComponent(s).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function Cm(s,e,n){if(!e)return s;const r=n&&n.encode||AC,i=K.isFunction(n)?{serialize:n}:n,l=i&&i.serialize;let c;if(l?c=l(e,i):c=K.isURLSearchParams(e)?e.toString():new sf(e,i).toString(r),c){const d=s.indexOf("#");d!==-1&&(s=s.slice(0,d)),s+=(s.indexOf("?")===-1?"?":"&")+c}return s}class Em{constructor(){this.handlers=[]}use(e,n,r){return this.handlers.push({fulfilled:e,rejected:n,synchronous:r?r.synchronous:!1,runWhen:r?r.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(e){K.forEach(this.handlers,function(r){r!==null&&e(r)})}}const of={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1,legacyInterceptorReqResOrdering:!0},xC={isBrowser:!0,classes:{URLSearchParams:typeof URLSearchParams<"u"?URLSearchParams:sf,FormData:typeof FormData<"u"?FormData:null,Blob:typeof Blob<"u"?Blob:null},protocols:["http","https","file","blob","url","data"]},lf=typeof window<"u"&&typeof document<"u",cf=typeof navigator=="object"&&navigator||void 0,TC=lf&&(!cf||["ReactNative","NativeScript","NS"].indexOf(cf.product)<0),kC=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",RC=lf&&window.location.href||"http://localhost",En={...Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:lf,hasStandardBrowserEnv:TC,hasStandardBrowserWebWorkerEnv:kC,navigator:cf,origin:RC},Symbol.toStringTag,{value:"Module"})),...xC};function DC(s,e){return oc(s,new En.classes.URLSearchParams,{visitor:function(n,r,i,l){return En.isNode&&K.isBuffer(n)?(this.append(r,n.toString("base64")),!1):l.defaultVisitor.apply(this,arguments)},...e})}function OC(s){return K.matchAll(/\w+|\[(\w*)]/g,s).map(e=>e[0]==="[]"?"":e[1]||e[0])}function LC(s){const e={},n=Object.keys(s);let r;const i=n.length;let l;for(r=0;r=n.length;return c=!c&&K.isArray(i)?i.length:c,f?(K.hasOwnProp(i,c)?i[c]=K.isArray(i[c])?i[c].concat(r):[i[c],r]:i[c]=r,!d):((!K.hasOwnProp(i,c)||!K.isObject(i[c]))&&(i[c]=[]),e(n,r,i[c],l)&&K.isArray(i[c])&&(i[c]=LC(i[c])),!d)}if(K.isFormData(s)&&K.isFunction(s.entries)){const n={};return K.forEachEntry(s,(r,i)=>{e(OC(r),i,n,0)}),n}return null}const ds=(s,e)=>s!=null&&K.hasOwnProp(s,e)?s[e]:void 0;function $C(s,e,n){if(K.isString(s))try{return(e||JSON.parse)(s),K.trim(s)}catch(r){if(r.name!=="SyntaxError")throw r}return(n||JSON.stringify)(s)}const _o={transitional:of,adapter:["xhr","http","fetch"],transformRequest:[function(e,n){const r=n.getContentType()||"",i=r.indexOf("application/json")>-1,l=K.isObject(e);if(l&&K.isHTMLForm(e)&&(e=new FormData(e)),K.isFormData(e))return i?JSON.stringify(_m(e)):e;if(K.isArrayBuffer(e)||K.isBuffer(e)||K.isStream(e)||K.isFile(e)||K.isBlob(e)||K.isReadableStream(e))return e;if(K.isArrayBufferView(e))return e.buffer;if(K.isURLSearchParams(e))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();let d;if(l){const f=ds(this,"formSerializer");if(r.indexOf("application/x-www-form-urlencoded")>-1)return DC(e,f).toString();if((d=K.isFileList(e))||r.indexOf("multipart/form-data")>-1){const h=ds(this,"env"),m=h&&h.FormData;return oc(d?{"files[]":e}:e,m&&new m,f)}}return l||i?(n.setContentType("application/json",!1),$C(e)):e}],transformResponse:[function(e){const n=ds(this,"transitional")||_o.transitional,r=n&&n.forcedJSONParsing,i=ds(this,"responseType"),l=i==="json";if(K.isResponse(e)||K.isReadableStream(e))return e;if(e&&K.isString(e)&&(r&&!i||l)){const d=!(n&&n.silentJSONParsing)&&l;try{return JSON.parse(e,ds(this,"parseReviver"))}catch(f){if(d)throw f.name==="SyntaxError"?Oe.from(f,Oe.ERR_BAD_RESPONSE,this,null,ds(this,"response")):f}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:En.classes.FormData,Blob:En.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};K.forEach(["delete","get","head","post","put","patch","query"],s=>{_o.headers[s]={}});function uf(s,e){const n=this||_o,r=e||n,i=Rn.from(r.headers);let l=r.data;return K.forEach(s,function(d){l=d.call(n,l,i.normalize(),e?e.status:void 0)}),i.normalize(),l}function Am(s){return!!(s&&s.__CANCEL__)}let Ao=class extends Oe{constructor(e,n,r){super(e??"canceled",Oe.ERR_CANCELED,n,r),this.name="CanceledError",this.__CANCEL__=!0}};function xm(s,e,n){const r=n.config.validateStatus;!n.status||!r||r(n.status)?s(n):e(new Oe("Request failed with status code "+n.status,n.status>=400&&n.status<500?Oe.ERR_BAD_REQUEST:Oe.ERR_BAD_RESPONSE,n.config,n.request,n))}function MC(s){const e=/^([-+\w]{1,25}):(?:\/\/)?/.exec(s);return e&&e[1]||""}function NC(s,e){s=s||10;const n=new Array(s),r=new Array(s);let i=0,l=0,c;return e=e!==void 0?e:1e3,function(f){const h=Date.now(),m=r[l];c||(c=h),n[i]=f,r[i]=h;let y=l,S=0;for(;y!==i;)S+=n[y++],y=y%s;if(i=(i+1)%s,i===l&&(l=(l+1)%s),h-c{n=m,i=null,l&&(clearTimeout(l),l=null),s(...h)};return[(...h)=>{const m=Date.now(),y=m-n;y>=r?c(h,m):(i=h,l||(l=setTimeout(()=>{l=null,c(i)},r-y)))},()=>i&&c(i)]}const lc=(s,e,n=3)=>{let r=0;const i=NC(50,250);return IC(l=>{if(!l||typeof l.loaded!="number")return;const c=l.loaded,d=l.lengthComputable?l.total:void 0,f=d!=null?Math.min(c,d):c,h=Math.max(0,f-r),m=i(h);r=Math.max(r,f);const y={loaded:f,total:d,progress:d?f/d:void 0,bytes:h,rate:m||void 0,estimated:m&&d?(d-f)/m:void 0,event:l,lengthComputable:d!=null,[e?"download":"upload"]:!0};s(y)},n)},Tm=(s,e)=>{const n=s!=null;return[r=>e[0]({lengthComputable:n,total:s,loaded:r}),e[1]]},km=s=>(...e)=>K.asap(()=>s(...e)),jC=En.hasStandardBrowserEnv?((s,e)=>n=>(n=new URL(n,En.origin),s.protocol===n.protocol&&s.host===n.host&&(e||s.port===n.port)))(new URL(En.origin),En.navigator&&/(msie|trident)/i.test(En.navigator.userAgent)):()=>!0,HC=En.hasStandardBrowserEnv?{write(s,e,n,r,i,l,c){if(typeof document>"u")return;const d=[`${s}=${encodeURIComponent(e)}`];K.isNumber(n)&&d.push(`expires=${new Date(n).toUTCString()}`),K.isString(r)&&d.push(`path=${r}`),K.isString(i)&&d.push(`domain=${i}`),l===!0&&d.push("secure"),K.isString(c)&&d.push(`SameSite=${c}`),document.cookie=d.join("; ")},read(s){if(typeof document>"u")return null;const e=document.cookie.split(";");for(let n=0;ns instanceof Rn?{...s}:s;function Ci(s,e){e=e||{};const n=Object.create(null);Object.defineProperty(n,"hasOwnProperty",{__proto__:null,value:Object.prototype.hasOwnProperty,enumerable:!1,writable:!0,configurable:!0});function r(h,m,y,S){return K.isPlainObject(h)&&K.isPlainObject(m)?K.merge.call({caseless:S},h,m):K.isPlainObject(m)?K.merge({},m):K.isArray(m)?m.slice():m}function i(h,m,y,S){if(K.isUndefined(m)){if(!K.isUndefined(h))return r(void 0,h,y,S)}else return r(h,m,y,S)}function l(h,m){if(!K.isUndefined(m))return r(void 0,m)}function c(h,m){if(K.isUndefined(m)){if(!K.isUndefined(h))return r(void 0,h)}else return r(void 0,m)}function d(h,m,y){if(K.hasOwnProp(e,y))return r(h,m);if(K.hasOwnProp(s,y))return r(void 0,h)}const f={url:l,method:l,data:l,baseURL:c,transformRequest:c,transformResponse:c,paramsSerializer:c,timeout:c,timeoutMessage:c,withCredentials:c,withXSRFToken:c,adapter:c,responseType:c,xsrfCookieName:c,xsrfHeaderName:c,onUploadProgress:c,onDownloadProgress:c,decompress:c,maxContentLength:c,maxBodyLength:c,beforeRedirect:c,transport:c,httpAgent:c,httpsAgent:c,cancelToken:c,socketPath:c,allowedSocketPaths:c,responseEncoding:c,validateStatus:d,headers:(h,m,y)=>i(Dm(h),Dm(m),y,!0)};return K.forEach(Object.keys({...s,...e}),function(m){if(m==="__proto__"||m==="constructor"||m==="prototype")return;const y=K.hasOwnProp(f,m)?f[m]:i,S=K.hasOwnProp(s,m)?s[m]:void 0,v=K.hasOwnProp(e,m)?e[m]:void 0,_=y(S,v,m);K.isUndefined(_)&&y!==d||(n[m]=_)}),n}const PC=["content-type","content-length"];function BC(s,e,n){if(n!=="content-only"){s.set(e);return}Object.entries(e).forEach(([r,i])=>{PC.includes(r.toLowerCase())&&s.set(r,i)})}const qC=s=>encodeURIComponent(s).replace(/%([0-9A-F]{2})/gi,(e,n)=>String.fromCharCode(parseInt(n,16))),Om=s=>{const e=Ci({},s),n=S=>K.hasOwnProp(e,S)?e[S]:void 0,r=n("data");let i=n("withXSRFToken");const l=n("xsrfHeaderName"),c=n("xsrfCookieName");let d=n("headers");const f=n("auth"),h=n("baseURL"),m=n("allowAbsoluteUrls"),y=n("url");if(e.headers=d=Rn.from(d),e.url=Cm(Rm(h,y,m),s.params,s.paramsSerializer),f&&d.set("Authorization","Basic "+btoa((f.username||"")+":"+(f.password?qC(f.password):""))),K.isFormData(r)&&(En.hasStandardBrowserEnv||En.hasStandardBrowserWebWorkerEnv?d.setContentType(void 0):K.isFunction(r.getHeaders)&&BC(d,r.getHeaders(),n("formDataHeaderPolicy"))),En.hasStandardBrowserEnv&&(K.isFunction(i)&&(i=i(e)),i===!0||i==null&&jC(e.url))){const v=l&&c&&HC.read(c);v&&d.set(l,v)}return e},GC=typeof XMLHttpRequest<"u"&&function(s){return new Promise(function(n,r){const i=Om(s);let l=i.data;const c=Rn.from(i.headers).normalize();let{responseType:d,onUploadProgress:f,onDownloadProgress:h}=i,m,y,S,v,_;function x(){v&&v(),_&&_(),i.cancelToken&&i.cancelToken.unsubscribe(m),i.signal&&i.signal.removeEventListener("abort",m)}let A=new XMLHttpRequest;A.open(i.method.toUpperCase(),i.url,!0),A.timeout=i.timeout;function L(){if(!A)return;const k=Rn.from("getAllResponseHeaders"in A&&A.getAllResponseHeaders()),P={data:!d||d==="text"||d==="json"?A.responseText:A.response,status:A.status,statusText:A.statusText,headers:k,config:s,request:A};xm(function(B){n(B),x()},function(B){r(B),x()},P),A=null}"onloadend"in A?A.onloadend=L:A.onreadystatechange=function(){!A||A.readyState!==4||A.status===0&&!(A.responseURL&&A.responseURL.startsWith("file:"))||setTimeout(L)},A.onabort=function(){A&&(r(new Oe("Request aborted",Oe.ECONNABORTED,s,A)),x(),A=null)},A.onerror=function(O){const P=O&&O.message?O.message:"Network Error",G=new Oe(P,Oe.ERR_NETWORK,s,A);G.event=O||null,r(G),x(),A=null},A.ontimeout=function(){let O=i.timeout?"timeout of "+i.timeout+"ms exceeded":"timeout exceeded";const P=i.transitional||of;i.timeoutErrorMessage&&(O=i.timeoutErrorMessage),r(new Oe(O,P.clarifyTimeoutError?Oe.ETIMEDOUT:Oe.ECONNABORTED,s,A)),x(),A=null},l===void 0&&c.setContentType(null),"setRequestHeader"in A&&K.forEach(ym(c),function(O,P){A.setRequestHeader(P,O)}),K.isUndefined(i.withCredentials)||(A.withCredentials=!!i.withCredentials),d&&d!=="json"&&(A.responseType=i.responseType),h&&([S,_]=lc(h,!0),A.addEventListener("progress",S)),f&&A.upload&&([y,v]=lc(f),A.upload.addEventListener("progress",y),A.upload.addEventListener("loadend",v)),(i.cancelToken||i.signal)&&(m=k=>{A&&(r(!k||k.type?new Ao(null,s,A):k),A.abort(),x(),A=null)},i.cancelToken&&i.cancelToken.subscribe(m),i.signal&&(i.signal.aborted?m():i.signal.addEventListener("abort",m)));const $=MC(i.url);if($&&!En.protocols.includes($)){r(new Oe("Unsupported protocol "+$+":",Oe.ERR_BAD_REQUEST,s));return}A.send(l||null)})},FC=(s,e)=>{if(s=s?s.filter(Boolean):[],!e&&!s.length)return;const n=new AbortController;let r=!1;const i=function(f){if(!r){r=!0,c();const h=f instanceof Error?f:this.reason;n.abort(h instanceof Oe?h:new Ao(h instanceof Error?h.message:h))}};let l=e&&setTimeout(()=>{l=null,i(new Oe(`timeout of ${e}ms exceeded`,Oe.ETIMEDOUT))},e);const c=()=>{s&&(l&&clearTimeout(l),l=null,s.forEach(f=>{f.unsubscribe?f.unsubscribe(i):f.removeEventListener("abort",i)}),s=null)};s.forEach(f=>f.addEventListener("abort",i));const{signal:d}=n;return d.unsubscribe=()=>K.asap(c),d},VC=function*(s,e){let n=s.byteLength;if(n{const i=KC(s,e);let l=0,c,d=f=>{c||(c=!0,r&&r(f))};return new ReadableStream({async pull(f){try{const{done:h,value:m}=await i.next();if(h){d(),f.close();return}let y=m.byteLength;if(n){let S=l+=y;n(S)}f.enqueue(new Uint8Array(m))}catch(h){throw d(h),h}},cancel(f){return d(f),i.return()}},{highWaterMark:2})};function YC(s){if(!s||typeof s!="string"||!s.startsWith("data:"))return 0;const e=s.indexOf(",");if(e<0)return 0;const n=s.slice(5,e),r=s.slice(e+1);if(/;base64/i.test(n)){let c=r.length;const d=r.length;for(let v=0;v=48&&_<=57||_>=65&&_<=70||_>=97&&_<=102)&&(x>=48&&x<=57||x>=65&&x<=70||x>=97&&x<=102)&&(c-=2,v+=2)}let f=0,h=d-1;const m=v=>v>=2&&r.charCodeAt(v-2)===37&&r.charCodeAt(v-1)===51&&(r.charCodeAt(v)===68||r.charCodeAt(v)===100);h>=0&&(r.charCodeAt(h)===61?(f++,h--):m(h)&&(f++,h-=3)),f===1&&h>=0&&(r.charCodeAt(h)===61||m(h))&&f++;const S=Math.floor(c/4)*3-(f||0);return S>0?S:0}if(typeof Buffer<"u"&&typeof Buffer.byteLength=="function")return Buffer.byteLength(r,"utf8");let l=0;for(let c=0,d=r.length;c=55296&&f<=56319&&c+1=56320&&h<=57343?(l+=4,c++):l+=3}else l+=3}return l}const df="1.16.1",$m=64*1024,{isFunction:cc}=K,Mm=(s,...e)=>{try{return!!s(...e)}catch{return!1}},XC=s=>{const e=K.global!==void 0&&K.global!==null?K.global:globalThis,{ReadableStream:n,TextEncoder:r}=e;s=K.merge.call({skipUndefined:!0},{Request:e.Request,Response:e.Response},s);const{fetch:i,Request:l,Response:c}=s,d=i?cc(i):typeof fetch=="function",f=cc(l),h=cc(c);if(!d)return!1;const m=d&&cc(n),y=d&&(typeof r=="function"?(L=>$=>L.encode($))(new r):async L=>new Uint8Array(await new l(L).arrayBuffer())),S=f&&m&&Mm(()=>{let L=!1;const $=new l(En.origin,{body:new n,method:"POST",get duplex(){return L=!0,"half"}}),k=$.headers.has("Content-Type");return $.body!=null&&$.body.cancel(),L&&!k}),v=h&&m&&Mm(()=>K.isReadableStream(new c("").body)),_={stream:v&&(L=>L.body)};d&&["text","arrayBuffer","blob","formData","stream"].forEach(L=>{!_[L]&&(_[L]=($,k)=>{let O=$&&$[L];if(O)return O.call($);throw new Oe(`Response type '${L}' is not supported`,Oe.ERR_NOT_SUPPORT,k)})});const x=async L=>{if(L==null)return 0;if(K.isBlob(L))return L.size;if(K.isSpecCompliantForm(L))return(await new l(En.origin,{method:"POST",body:L}).arrayBuffer()).byteLength;if(K.isArrayBufferView(L)||K.isArrayBuffer(L))return L.byteLength;if(K.isURLSearchParams(L)&&(L=L+""),K.isString(L))return(await y(L)).byteLength},A=async(L,$)=>{const k=K.toFiniteNumber(L.getContentLength());return k??x($)};return async L=>{let{url:$,method:k,data:O,signal:P,cancelToken:G,timeout:B,onDownloadProgress:W,onUploadProgress:pe,responseType:Se,headers:we,withCredentials:Ue="same-origin",fetchOptions:Fe,maxContentLength:qe,maxBodyLength:wt}=Om(L);const J=K.isNumber(qe)&&qe>-1,fe=K.isNumber(wt)&&wt>-1;let Le=i||fetch;Se=Se?(Se+"").toLowerCase():"text";let Z=FC([P,G&&G.toAbortSignal()],B),ge=null;const H=Z&&Z.unsubscribe&&(()=>{Z.unsubscribe()});let T;try{if(J&&typeof $=="string"&&$.startsWith("data:")&&YC($)>qe)throw new Oe("maxContentLength size of "+qe+" exceeded",Oe.ERR_BAD_RESPONSE,L,ge);if(fe&&k!=="get"&&k!=="head"){const _e=await A(we,O);if(typeof _e=="number"&&isFinite(_e)&&_e>wt)throw new Oe("Request body larger than maxBodyLength limit",Oe.ERR_BAD_REQUEST,L,ge)}if(pe&&S&&k!=="get"&&k!=="head"&&(T=await A(we,O))!==0){let _e=new l($,{method:"POST",body:O,duplex:"half"}),Te;if(K.isFormData(O)&&(Te=_e.headers.get("content-type"))&&we.setContentType(Te),_e.body){const[Me,pt]=Tm(T,lc(km(pe)));O=Lm(_e.body,$m,Me,pt)}}K.isString(Ue)||(Ue=Ue?"include":"omit");const ce=f&&"credentials"in l.prototype;if(K.isFormData(O)){const _e=we.getContentType();_e&&/^multipart\/form-data/i.test(_e)&&!/boundary=/i.test(_e)&&we.delete("content-type")}we.set("User-Agent","axios/"+df,!1);const de={...Fe,signal:Z,method:k.toUpperCase(),headers:ym(we.normalize()),body:O,duplex:"half",credentials:ce?Ue:void 0};ge=f&&new l($,de);let be=await(f?Le(ge,Fe):Le($,de));if(J){const _e=K.toFiniteNumber(be.headers.get("content-length"));if(_e!=null&&_e>qe)throw new Oe("maxContentLength size of "+qe+" exceeded",Oe.ERR_BAD_RESPONSE,L,ge)}const ie=v&&(Se==="stream"||Se==="response");if(v&&be.body&&(W||J||ie&&H)){const _e={};["status","statusText","headers"].forEach(ht=>{_e[ht]=be[ht]});const Te=K.toFiniteNumber(be.headers.get("content-length")),[Me,pt]=W&&Tm(Te,lc(km(W),!0))||[];let Ct=0;const Ot=ht=>{if(J&&(Ct=ht,Ct>qe))throw new Oe("maxContentLength size of "+qe+" exceeded",Oe.ERR_BAD_RESPONSE,L,ge);Me&&Me(ht)};be=new c(Lm(be.body,$m,Ot,()=>{pt&&pt(),H&&H()}),_e)}Se=Se||"text";let xe=await _[K.findKey(_,Se)||"text"](be,L);if(J&&!v&&!ie){let _e;if(xe!=null&&(typeof xe.byteLength=="number"?_e=xe.byteLength:typeof xe.size=="number"?_e=xe.size:typeof xe=="string"&&(_e=typeof r=="function"?new r().encode(xe).byteLength:xe.length)),typeof _e=="number"&&_e>qe)throw new Oe("maxContentLength size of "+qe+" exceeded",Oe.ERR_BAD_RESPONSE,L,ge)}return!ie&&H&&H(),await new Promise((_e,Te)=>{xm(_e,Te,{data:xe,headers:Rn.from(be.headers),status:be.status,statusText:be.statusText,config:L,request:ge})})}catch(ce){if(H&&H(),Z&&Z.aborted&&Z.reason instanceof Oe){const de=Z.reason;throw de.config=L,ge&&(de.request=ge),ce!==de&&(de.cause=ce),de}throw ce&&ce.name==="TypeError"&&/Load failed|fetch/i.test(ce.message)?Object.assign(new Oe("Network Error",Oe.ERR_NETWORK,L,ge,ce&&ce.response),{cause:ce.cause||ce}):Oe.from(ce,ce&&ce.code,L,ge,ce&&ce.response)}}},JC=new Map,Nm=s=>{let e=s&&s.env||{};const{fetch:n,Request:r,Response:i}=e,l=[r,i,n];let c=l.length,d=c,f,h,m=JC;for(;d--;)f=l[d],h=m.get(f),h===void 0&&m.set(f,h=d?new Map:XC(e)),m=h;return h};Nm();const ff={http:CC,xhr:GC,fetch:{get:Nm}};K.forEach(ff,(s,e)=>{if(s){try{Object.defineProperty(s,"name",{__proto__:null,value:e})}catch{}Object.defineProperty(s,"adapterName",{__proto__:null,value:e})}});const Im=s=>`- ${s}`,QC=s=>K.isFunction(s)||s===null||s===!1;function ZC(s,e){s=K.isArray(s)?s:[s];const{length:n}=s;let r,i;const l={};for(let c=0;c`adapter ${f} `+(h===!1?"is not supported by the environment":"is not available in the build"));let d=n?c.length>1?`since : `+c.map(Im).join(` -`):" "+Im(c[0]):"as no adapter specified";throw new Oe("There is no suitable adapter to dispatch the request "+d,"ERR_NOT_SUPPORT")}return i}const jm={getAdapter:ZC,adapters:ff};function hf(s){if(s.cancelToken&&s.cancelToken.throwIfRequested(),s.signal&&s.signal.aborted)throw new Ao(null,s)}function Hm(s){return hf(s),s.headers=Rn.from(s.headers),s.data=uf.call(s,s.transformRequest),["post","put","patch"].indexOf(s.method)!==-1&&s.headers.setContentType("application/x-www-form-urlencoded",!1),jm.getAdapter(s.adapter||_o.adapter,s)(s).then(function(r){hf(s),s.response=r;try{r.data=uf.call(s,s.transformResponse,r)}finally{delete s.response}return r.headers=Rn.from(r.headers),r},function(r){if(!Am(r)&&(hf(s),r&&r.response)){s.response=r.response;try{r.response.data=uf.call(s,s.transformResponse,r.response)}finally{delete s.response}r.response.headers=Rn.from(r.response.headers)}return Promise.reject(r)})}const cc={};["object","boolean","number","function","string","symbol"].forEach((s,e)=>{cc[s]=function(r){return typeof r===s||"a"+(e<1?"n ":" ")+s}});const zm={};cc.transitional=function(e,n,r){function i(l,c){return"[Axios v"+df+"] Transitional option '"+l+"'"+c+(r?". "+r:"")}return(l,c,d)=>{if(e===!1)throw new Oe(i(c," has been removed"+(n?" in "+n:"")),Oe.ERR_DEPRECATED);return n&&!zm[c]&&(zm[c]=!0,console.warn(i(c," has been deprecated since v"+n+" and will be removed in the near future"))),e?e(l,c,d):!0}},cc.spelling=function(e){return(n,r)=>(console.warn(`${r} is likely a misspelling of ${e}`),!0)};function eE(s,e,n){if(typeof s!="object")throw new Oe("options must be an object",Oe.ERR_BAD_OPTION_VALUE);const r=Object.keys(s);let i=r.length;for(;i-- >0;){const l=r[i],c=Object.prototype.hasOwnProperty.call(e,l)?e[l]:void 0;if(c){const d=s[l],f=d===void 0||c(d,l,s);if(f!==!0)throw new Oe("option "+l+" must be "+f,Oe.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new Oe("Unknown option "+l,Oe.ERR_BAD_OPTION)}}const uc={assertOptions:eE,validators:cc},ar=uc.validators;let Ei=class{constructor(e){this.defaults=e||{},this.interceptors={request:new Em,response:new Em}}async request(e,n){try{return await this._request(e,n)}catch(r){if(r instanceof Error){let i={};Error.captureStackTrace?Error.captureStackTrace(i):i=new Error;const l=(()=>{if(!i.stack)return"";const c=i.stack.indexOf(` +`):" "+Im(c[0]):"as no adapter specified";throw new Oe("There is no suitable adapter to dispatch the request "+d,"ERR_NOT_SUPPORT")}return i}const jm={getAdapter:ZC,adapters:ff};function hf(s){if(s.cancelToken&&s.cancelToken.throwIfRequested(),s.signal&&s.signal.aborted)throw new Ao(null,s)}function Hm(s){return hf(s),s.headers=Rn.from(s.headers),s.data=uf.call(s,s.transformRequest),["post","put","patch"].indexOf(s.method)!==-1&&s.headers.setContentType("application/x-www-form-urlencoded",!1),jm.getAdapter(s.adapter||_o.adapter,s)(s).then(function(r){hf(s),s.response=r;try{r.data=uf.call(s,s.transformResponse,r)}finally{delete s.response}return r.headers=Rn.from(r.headers),r},function(r){if(!Am(r)&&(hf(s),r&&r.response)){s.response=r.response;try{r.response.data=uf.call(s,s.transformResponse,r.response)}finally{delete s.response}r.response.headers=Rn.from(r.response.headers)}return Promise.reject(r)})}const uc={};["object","boolean","number","function","string","symbol"].forEach((s,e)=>{uc[s]=function(r){return typeof r===s||"a"+(e<1?"n ":" ")+s}});const zm={};uc.transitional=function(e,n,r){function i(l,c){return"[Axios v"+df+"] Transitional option '"+l+"'"+c+(r?". "+r:"")}return(l,c,d)=>{if(e===!1)throw new Oe(i(c," has been removed"+(n?" in "+n:"")),Oe.ERR_DEPRECATED);return n&&!zm[c]&&(zm[c]=!0,console.warn(i(c," has been deprecated since v"+n+" and will be removed in the near future"))),e?e(l,c,d):!0}},uc.spelling=function(e){return(n,r)=>(console.warn(`${r} is likely a misspelling of ${e}`),!0)};function eE(s,e,n){if(typeof s!="object")throw new Oe("options must be an object",Oe.ERR_BAD_OPTION_VALUE);const r=Object.keys(s);let i=r.length;for(;i-- >0;){const l=r[i],c=Object.prototype.hasOwnProperty.call(e,l)?e[l]:void 0;if(c){const d=s[l],f=d===void 0||c(d,l,s);if(f!==!0)throw new Oe("option "+l+" must be "+f,Oe.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new Oe("Unknown option "+l,Oe.ERR_BAD_OPTION)}}const dc={assertOptions:eE,validators:uc},ar=dc.validators;let Ei=class{constructor(e){this.defaults=e||{},this.interceptors={request:new Em,response:new Em}}async request(e,n){try{return await this._request(e,n)}catch(r){if(r instanceof Error){let i={};Error.captureStackTrace?Error.captureStackTrace(i):i=new Error;const l=(()=>{if(!i.stack)return"";const c=i.stack.indexOf(` `);return c===-1?"":i.stack.slice(c+1)})();try{if(!r.stack)r.stack=l;else if(l){const c=l.indexOf(` `),d=c===-1?-1:l.indexOf(` `,c+1),f=d===-1?"":l.slice(d+1);String(r.stack).endsWith(f)||(r.stack+=` -`+l)}}catch{}}throw r}}_request(e,n){typeof e=="string"?(n=n||{},n.url=e):n=e||{},n=Ci(this.defaults,n);const{transitional:r,paramsSerializer:i,headers:l}=n;r!==void 0&&uc.assertOptions(r,{silentJSONParsing:ar.transitional(ar.boolean),forcedJSONParsing:ar.transitional(ar.boolean),clarifyTimeoutError:ar.transitional(ar.boolean),legacyInterceptorReqResOrdering:ar.transitional(ar.boolean)},!1),i!=null&&(K.isFunction(i)?n.paramsSerializer={serialize:i}:uc.assertOptions(i,{encode:ar.function,serialize:ar.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),uc.assertOptions(n,{baseUrl:ar.spelling("baseURL"),withXsrfToken:ar.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let c=l&&K.merge(l.common,l[n.method]);l&&K.forEach(["delete","get","head","post","put","patch","query","common"],_=>{delete l[_]}),n.headers=Rn.concat(c,l);const d=[];let f=!0;this.interceptors.request.forEach(function(x){if(typeof x.runWhen=="function"&&x.runWhen(n)===!1)return;f=f&&x.synchronous;const A=n.transitional||of;A&&A.legacyInterceptorReqResOrdering?d.unshift(x.fulfilled,x.rejected):d.push(x.fulfilled,x.rejected)});const h=[];this.interceptors.response.forEach(function(x){h.push(x.fulfilled,x.rejected)});let m,y=0,S;if(!f){const _=[Hm.bind(this),void 0];for(_.unshift(...d),_.push(...h),S=_.length,m=Promise.resolve(n);y{if(!r._listeners)return;let l=r._listeners.length;for(;l-- >0;)r._listeners[l](i);r._listeners=null}),this.promise.then=i=>{let l;const c=new Promise(d=>{r.subscribe(d),l=d}).then(i);return c.cancel=function(){r.unsubscribe(l)},c},e(function(l,c,d){r.reason||(r.reason=new Ao(l,c,d),n(r.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const n=this._listeners.indexOf(e);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const e=new AbortController,n=r=>{e.abort(r)};return this.subscribe(n),e.signal.unsubscribe=()=>this.unsubscribe(n),e.signal}static source(){let e;return{token:new Rw(function(i){e=i}),cancel:e}}};function nE(s){return function(n){return s.apply(null,n)}}function rE(s){return K.isObject(s)&&s.isAxiosError===!0}const pf={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(pf).forEach(([s,e])=>{pf[e]=s});function Um(s){const e=new Ei(s),n=om(Ei.prototype.request,e);return K.extend(n,Ei.prototype,e,{allOwnKeys:!0}),K.extend(n,e,null,{allOwnKeys:!0}),n.create=function(i){return Um(Ci(s,i))},n}const Vt=Um(_o);Vt.Axios=Ei,Vt.CanceledError=Ao,Vt.CancelToken=tE,Vt.isCancel=Am,Vt.VERSION=df,Vt.toFormData=sc,Vt.AxiosError=Oe,Vt.Cancel=Vt.CanceledError,Vt.all=function(e){return Promise.all(e)},Vt.spread=nE,Vt.isAxiosError=rE,Vt.mergeConfig=Ci,Vt.AxiosHeaders=Rn,Vt.formToJSON=s=>_m(K.isHTMLForm(s)?new FormData(s):s),Vt.getAdapter=jm.getAdapter,Vt.HttpStatusCode=pf,Vt.default=Vt;const{Axios:Nk,AxiosError:Ik,CanceledError:jk,isCancel:Hk,CancelToken:zk,VERSION:Uk,all:Pk,Cancel:Bk,isAxiosError:qk,spread:Gk,toFormData:Fk,AxiosHeaders:Vk,HttpStatusCode:Kk,formToJSON:Wk,getAdapter:Yk,mergeConfig:Xk,create:Jk}=Vt,gf="g7.identity.redirectStash",dc=dt("IdentityGuardInterceptor");class St{static setLauncher(e){this.launcher=e}static hasLauncher(){return this.launcher!==null}static markDomainNoticeShown(){this.domainNoticeShown=!0}static consumeDomainNoticeShown(){const e=this.domainNoticeShown;return this.domainNoticeShown=!1,e}static resolveDeferred(e){const n=this.deferredResolver;if(!n){dc.warn("IdentityGuardInterceptor.resolveDeferred 호출됐지만 대기 중인 launcher 가 없습니다. 모달이 launcher 외부에서 열렸는지 확인하세요.");return}this.deferredResolver=null,n(e)}static createDeferred(){if(this.deferredResolver){const e=this.deferredResolver;this.deferredResolver=null,e({status:"cancelled"})}return new Promise(e=>{this.deferredResolver=e})}static isIdentityRequired(e,n){return e===428&&typeof n=="object"&&n!==null&&n.error_code==="identity_verification_required"}static async handle(e,n,r){this.domainNoticeShown=!1;const i=this.launcher??iE,c=!!(r&&(r.email||r.phone))?{...e.verification,target:r}:e.verification,d=await i(c);if(d.status!=="verified")return null;const f=c.return_request;if(!f)return null;const h=aE(f.url,d.token);return fetch(h,{method:f.method,headers:n?.headers??{Accept:"application/json","Content-Type":"application/json"},body:n?.body,credentials:n?.credentials??"same-origin"})}static redirectExternally(e){const n=e.redirect_url;if(!n)return dc.error("redirectExternally 호출 시 verification.redirect_url 이 없습니다. payload:",e),Promise.resolve({status:"failed",failureCode:"MISSING_REDIRECT_URL",reason:"verification.redirect_url is required for external_redirect flow"});if(typeof window<"u"){const r={return_url:window.location.href,payload:e,stashed_at:Date.now()};try{window.sessionStorage?.setItem(gf,JSON.stringify(r))}catch(i){dc.warn("sessionStorage 접근 실패 — stash 없이 redirect 합니다.",i)}window.location.href=n}return new Promise(()=>{})}static reset(){if(this.deferredResolver){const e=this.deferredResolver;this.deferredResolver=null;try{e({status:"cancelled"})}catch{}}this.launcher=null,this.domainNoticeShown=!1}}M(St,"launcher",null),M(St,"deferredResolver",null),M(St,"domainNoticeShown",!1);function aE(s,e){if(!e)return s;try{const n=typeof window<"u"?window.location.origin:"http://localhost",r=new URL(s,n);return r.searchParams.set("verification_token",e),/^https?:\/\//i.test(s)?r.toString():`${r.pathname}${r.search}${r.hash}`}catch{const n=s.includes("?")?"&":"?";return`${s}${n}verification_token=${encodeURIComponent(e)}`}}const iE=async s=>{if(typeof window>"u")return{status:"cancelled"};if(s.render_hint==="external_redirect"||s.redirect_url)return St.redirectExternally(s);const e=window.G7Core;if(!e?.dispatch)return console.error("[IdentityGuardInterceptor] defaultLauncher: G7Core 가 초기화되지 않아 본인인증 흐름을 시작할 수 없습니다."),{status:"failed",failureCode:"G7_NOT_READY"};try{await e.dispatch({handler:"toast",params:{message:"본인 확인이 필요합니다.",variant:"warning"}})}catch{}const n=window.location.href,r={return_url:n,payload:s,stashed_at:Date.now()};try{window.sessionStorage?.setItem(gf,JSON.stringify(r))}catch{}const i=`/identity/challenge?return=${encodeURIComponent(n)}`;try{await e.dispatch({handler:"navigate",params:{path:i}})}catch(l){dc.warn("navigate 실패 — window.location 으로 폴백",l),window.location.href=i}return new Promise(()=>{})},sE=dt("ApiClient");function mf(){return typeof window<"u"&&window.__G7_DEVTOOLS__?window.__G7_DEVTOOLS__:null}class oE{constructor(e={}){M(this,"client");M(this,"config");M(this,"TOKEN_KEY","auth_token");this.config={baseURL:e.baseURL||"/api",timeout:e.timeout||3e4,onTokenExpired:e.onTokenExpired,onUnauthorized:e.onUnauthorized,onError:e.onError},this.client=Vt.create({baseURL:this.config.baseURL,timeout:this.config.timeout,headers:{"Content-Type":"application/json",Accept:"application/json"},paramsSerializer:{serialize:n=>{const r=[];for(const[i,l]of Object.entries(n))if(l!=null)if(Array.isArray(l)){const c=i.endsWith("[]")?i:`${i}[]`;for(const d of l)r.push(`${encodeURIComponent(c)}=${encodeURIComponent(String(d))}`)}else r.push(`${encodeURIComponent(i)}=${encodeURIComponent(String(l))}`);return r.join("&")}}}),this.setupInterceptors()}setToken(e){typeof window<"u"&&localStorage.setItem(this.TOKEN_KEY,e)}getToken(){return typeof window<"u"?localStorage.getItem(this.TOKEN_KEY):null}removeToken(){typeof window<"u"&&localStorage.removeItem(this.TOKEN_KEY)}setupInterceptors(){this.client.interceptors.request.use(e=>{e.url?.startsWith("/api")&&e.baseURL==="/api"&&(e.baseURL="");const n=this.getToken();if(n&&e.headers&&!this.isCrossOriginRequest(e.url)&&(e.headers.Authorization=`Bearer ${n}`),typeof window<"u"&&e.headers){const i=localStorage.getItem("g7_locale");i&&(e.headers["Accept-Language"]=i)}const r=mf();if(r?.isEnabled()){const i=this.buildFullUrl(e),l=(e.method||"GET").toUpperCase(),c=r.trackRequest(i,l,{requestBody:e.data});e._devToolsRequestId=c}return e},e=>Promise.reject(e)),this.client.interceptors.response.use(e=>{const n=e.config,r=n._devToolsRequestId;if(r){const i=mf();i?.isEnabled()&&i.completeRequest(r,e.status,e.data),n._devToolsRequestId=null}return e},async e=>{const n=e.config,r=n?.url||"",l=["/auth/","/layouts/"].some(c=>r.includes(c));if(e.response?.status===401&&!n?._retry&&!l){if(n._retry=!0,await wr.getInstance().refreshToken()){const f=this.getToken();return f&&(n.headers.Authorization=`Bearer ${f}`),n._devToolsRequestId=null,this.client(n)}return this.completeDevToolsRequest(n,e),this.removeToken(),this.config.onUnauthorized&&this.config.onUnauthorized(),Promise.reject(e)}if(e.response?.status===401&&l)return this.completeDevToolsRequest(n,e),Promise.reject(e);if(St.isIdentityRequired(e.response?.status,e.response?.data)){this.completeDevToolsRequest(n,e);const c={},d=n?.headers??{};for(const[S,v]of Object.entries(d))typeof v=="string"&&(c[S]=v);let f;n?.data!==void 0&&n?.data!==null&&(f=typeof n.data=="string"?n.data:JSON.stringify(n.data),c["Content-Type"]=c["Content-Type"]??"application/json");const h=n?.identity_target,m=await St.handle(e.response.data,{headers:c,body:f,credentials:"same-origin"},h);if(!m)return Promise.reject(e);let y=null;try{y=await m.json()}catch{y=null}return m.ok?{...e.response,status:m.status,data:y}:Promise.reject(Object.assign(new Error("replay failed"),{response:{status:m.status,data:y}}))}return e.response?.status===403?(this.completeDevToolsRequest(n,e),this.callOnError(e),Promise.reject(e)):(this.completeDevToolsRequest(n,e),e.response&&this.callOnError(e),Promise.reject(e))})}async get(e,n){return(await this.client.get(e,n)).data}async post(e,n,r){return(await this.client.post(e,n,r)).data}async put(e,n,r){return(await this.client.put(e,n,r)).data}async patch(e,n,r){return(await this.client.patch(e,n,r)).data}async delete(e,n){return(await this.client.delete(e,n)).data}getInstance(){return this.client}setOnUnauthorized(e){this.config.onUnauthorized=e}setOnError(e){this.config.onError=e}completeDevToolsRequest(e,n){if(!e?._devToolsRequestId)return;const r=mf();if(!r?.isEnabled())return;const i=e._devToolsRequestId;e._devToolsRequestId=null,n.response?r.completeRequest(i,n.response.status,n.response.data):n.request?r.failRequest(i,n.message||"Network error"):r.failRequest(i,n.message||"Request error")}isCrossOriginRequest(e){if(!e||typeof window>"u"||!window.location||!/^(https?:)?\/\//i.test(e))return!1;try{return new URL(e,window.location.href).origin!==window.location.origin}catch{return!1}}buildFullUrl(e){let n=e.url||"";if(e.baseURL&&!n.startsWith("http")&&(n=`${e.baseURL}${n.startsWith("/")?"":"/"}${n}`),e.params&&typeof e.params=="object"){const r=e.params,i=[];for(const[l,c]of Object.entries(r))if(c!=null)if(Array.isArray(c)){const d=l.endsWith("[]")?l:`${l}[]`;for(const f of c)i.push(`${encodeURIComponent(d)}=${encodeURIComponent(String(f))}`)}else i.push(`${encodeURIComponent(l)}=${encodeURIComponent(String(c))}`);i.length>0&&(n+=(n.includes("?")?"&":"?")+i.join("&"))}return n}callOnError(e){if(!this.config.onError)return;const n={status:e.response?.status||0,message:e.response?.data?.message||e.message||"Unknown error",data:e.response?.data,statusText:e.response?.statusText};try{this.config.onError(n)}catch(r){sE.error("Error in onError handler:",r)}}}let yf=null;function zr(){return yf||(yf=new oE),yf}const xo=dt("AuthManager");function fs(s,e,n,r){try{window.G7Core?.devTools?.trackAuthEvent?.(s,e,n,r)}catch{}}const fc={admin:{type:"admin",loginPath:"/admin/login",defaultPath:"/admin",userEndpoint:"/admin/auth/user",loginEndpoint:"/auth/admin/login",logoutEndpoint:"/admin/auth/logout",refreshEndpoint:"/admin/auth/refresh"},user:{type:"user",loginPath:"/login",defaultPath:"/",userEndpoint:"/auth/user",loginEndpoint:"/auth/login",logoutEndpoint:"/auth/logout",refreshEndpoint:"/auth/refresh"}},kr=class kr{constructor(){M(this,"state");M(this,"config");M(this,"isRefreshing",!1);M(this,"refreshPromise",null);M(this,"eventHandlers",new Map);this.state={isAuthenticated:!1,user:null,type:null},this.config=new Map,this.config.set("admin",fc.admin),this.config.set("user",fc.user)}static getInstance(){return kr.instance||(kr.instance=new kr),kr.instance}on(e,n){this.eventHandlers.has(e)||this.eventHandlers.set(e,[]),this.eventHandlers.get(e).push(n)}emit(e,...n){const r=this.eventHandlers.get(e);r&&r.forEach(i=>i(...n))}isAuthenticated(){return this.state.isAuthenticated}getUser(){return this.state.user}getAuthType(){return this.state.type}async checkAuth(e){const n=zr();if(!n.getToken())return this.clearState(),!1;const i=this.config.get(e);if(!i)return xo.error(`Unknown auth type: ${e}`),!1;try{const l=await n.get(i.userEndpoint);return l.success&&l.data?(this.state={isAuthenticated:!0,user:l.data,type:e},this.emit("authStateChange",this.state),!0):(this.clearState(),!1)}catch(l){return l.response?.status===401&&await this.refreshToken()?this.checkAuth(e):(this.clearState(),!1)}}async preloadAuth(e){try{return await this.checkAuth(e)}catch(n){return xo.warn(`Preload auth failed for type ${e}:`,n),!1}}async login(e,n,r){const i=zr();if(!this.config.get(e))throw new Error(`Unknown auth type: ${e}`);const c=e==="admin"?fc.admin.loginEndpoint:fc.user.loginEndpoint;try{const d=r?.headers?{headers:r.headers}:void 0,f=await i.post(c,n,d);if(f.success&&f.data){i.setToken(f.data.token);const h=f.data.user.language,m=localStorage.getItem(kr.LOCALE_STORAGE_KEY),y=h&&h!==m;if(h)try{localStorage.setItem(kr.LOCALE_STORAGE_KEY,h)}catch(S){xo.warn("Failed to save user language to localStorage:",S)}return this.state={isAuthenticated:!0,user:f.data.user,type:e},this.emit("login",this.state),this.emit("authStateChange",this.state),fs("login",!0,void 0,{userId:f.data.user.uuid,email:f.data.user.email,type:e}),y&&window.__templateApp&&window.__templateApp.changeLocale(h),f.data.user}throw new Error("Login failed")}catch(d){this.clearState();const f=d.response?.data?.message,h=new Error(f||d.message||"Login failed");throw h.response=d.response,h.status=d.response?.status,fs("login",!1,h.message,{type:e,status:d.response?.status}),h}}async logout(){const e=zr(),n=this.state.type?this.config.get(this.state.type):null;try{n&&await e.post(n.logoutEndpoint)}catch(r){xo.warn("Logout API call failed:",r)}finally{e.removeToken();const r={...this.state};if(this.clearState(),this.emit("logout",r),this.emit("authStateChange",this.state),fs("logout",!0,void 0,{previousType:r.type}),n&&r.type){const i=window.location.pathname+window.location.search;window.location.href=this.getLoginRedirectUrl(r.type,i)}}}async refreshToken(){if(this.isRefreshing&&this.refreshPromise)return this.refreshPromise;this.isRefreshing=!0,this.refreshPromise=this.doRefreshToken();try{return await this.refreshPromise}finally{this.isRefreshing=!1,this.refreshPromise=null}}async doRefreshToken(){const e=this.state.type;if(!e)return!1;const n=this.config.get(e);if(!n)return!1;const r=zr();try{const i=await r.post(n.refreshEndpoint);return i.success&&i.data?.token?(r.setToken(i.data.token),this.emit("tokenRefreshed"),fs("token-refresh",!0,void 0,{type:e}),!0):(fs("token-refresh",!1,"No token in response",{type:e}),!1)}catch(i){return xo.error("Token refresh failed:",i),fs("token-refresh",!1,i instanceof Error?i.message:"Unknown error",{type:e}),!1}}getLoginRedirectUrl(e,n,r){const i=this.config.get(e);if(!i)return"/login";const l=encodeURIComponent(n);let c=`${i.loginPath}?redirect=${l}`;return r&&(c+=`&reason=${encodeURIComponent(r)}`),c}updateConfig(e,n){if(n.loginPath!==void 0){const i=n.loginPath;if(!i.startsWith("/")||i.startsWith("//"))throw new Error(`AuthManager.updateConfig: loginPath must be a same-origin path starting with '/' (got: ${i})`)}const r=this.config.get(e);r&&this.config.set(e,{...r,...n})}getRedirectUrl(e){const r=this.config.get(e)?.defaultPath||"/",l=new URLSearchParams(window.location.search).get("redirect");if(l)try{const c=decodeURIComponent(l);if(c.startsWith("/"))return c}catch{}return r}getConfig(e){return this.config.get(e)}clearState(){this.state={isAuthenticated:!1,user:null,type:null}}static resetInstance(){kr.instance=null}};M(kr,"instance"),M(kr,"LOCALE_STORAGE_KEY","g7_locale");let wr=kr;const Pm={401:{handler:"navigate",params:{path:"{{auth.loginPath}}"}},403:{handler:"toast",params:{type:"error",message:"{{error.message}}"}},404:{handler:"toast",params:{type:"error",message:"{{error.message}}"}},422:{handler:"toast",params:{type:"error",message:"{{error.message}}"}},default:{handler:"toast",params:{type:"error",message:"{{error.message}}"}}},aa={findHandler(s,e){if(s){if(s[e])return s[e];if(s[String(e)])return s[String(e)];if(s.default)return s.default}},normalizeOnError(s){return s?Array.isArray(s)?s:[s]:[]},injectErrorCode(s,e,n){if(s.handler!=="showErrorPage"||s.params?.errorCode!==void 0)return s;const r=typeof e=="string"?parseInt(e,10):e,i=isNaN(r)?n:r;return i===void 0?s:{...s,params:{...s.params,errorCode:i}}}},Cr=dt("ErrorHandlingResolver"),Ha=class Ha{constructor(){M(this,"templateErrorHandling",null);M(this,"layoutErrorHandling",null);M(this,"executeAction",null)}static getInstance(){return Ha.instance||(Ha.instance=new Ha),Ha.instance}static resetInstance(){Ha.instance=null}setTemplateConfig(e){this.templateErrorHandling=e,Cr.log("Template config set:",e)}setLayoutConfig(e){this.layoutErrorHandling=e,Cr.log("Layout config set:",e)}setActionExecutor(e){this.executeAction=e}resolve(e,n={}){const{errorHandling:r,onError:i}=n;Cr.log("Resolving error:",e,{hasActionErrorHandling:!!r,hasActionOnError:!!i,hasLayoutConfig:!!this.layoutErrorHandling,hasTemplateConfig:!!this.templateErrorHandling});let l=aa.findHandler(r,e);if(l){const c=this.getMatchedKey(r,e);return{handler:aa.injectErrorCode(l,c,e),level:"action",matchedKey:c}}if(i){const c=aa.normalizeOnError(i);if(c.length>0)return{handler:c.length===1?c[0]:{handler:"sequence",actions:c},level:"action",matchedKey:"onError"}}if(l=aa.findHandler(this.layoutErrorHandling||void 0,e),l){const c=this.getMatchedKey(this.layoutErrorHandling,e);return{handler:aa.injectErrorCode(l,c,e),level:"layout",matchedKey:c}}if(l=aa.findHandler(this.templateErrorHandling||void 0,e),l){const c=this.getMatchedKey(this.templateErrorHandling,e);return{handler:aa.injectErrorCode(l,c,e),level:"template",matchedKey:c}}if(l=aa.findHandler(Pm,e),l){const c=this.getMatchedKey(Pm,e);return{handler:aa.injectErrorCode(l,c,e),level:"system",matchedKey:c}}return{handler:null,level:null,matchedKey:null}}async execute(e,n){if(!this.executeAction){Cr.error("Action executor is not set");return}Cr.log("Executing handler:",e.handler,{errorContext:n});try{return await this.executeAction(e,{error:n})}catch(r){throw Cr.error("Failed to execute handler:",r),r}}async resolveAndExecute(e,n,r={}){const i=this.resolve(e,r);if(Cr.log("Resolve result:",{errorCode:e,handler:i.handler?.handler,level:i.level,matchedKey:i.matchedKey}),!i.handler)return Cr.warn("No handler found for error:",e),{handled:!1};try{return{handled:!0,result:await this.execute(i.handler,n)}}catch(l){return Cr.error("Handler execution failed:",l),{handled:!1}}}getMatchedKey(e,n){return e[n]?n:e[String(n)]?String(n):"default"}clearLayoutConfig(){this.layoutErrorHandling=null,Cr.log("Layout config cleared")}clearAllConfig(){this.templateErrorHandling=null,this.layoutErrorHandling=null,Cr.log("All config cleared")}getConfigStatus(){return{hasTemplate:this.templateErrorHandling!==null,hasLayout:this.layoutErrorHandling!==null,hasExecutor:this.executeAction!==null}}};M(Ha,"instance",null);let bf=Ha;function Er(){return bf.getInstance()}var vf={exports:{}},To={};var Bm;function lE(){if(Bm)return To;Bm=1;var s=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function n(r,i,l){var c=null;if(l!==void 0&&(c=""+l),i.key!==void 0&&(c=""+i.key),"key"in i){l={};for(var d in i)d!=="key"&&(l[d]=i[d])}else l=i;return i=l.ref,{$$typeof:s,type:r,key:c,ref:i!==void 0?i:null,props:l}}return To.Fragment=e,To.jsx=n,To.jsxs=n,To}var qm;function cE(){return qm||(qm=1,vf.exports=lE()),vf.exports}var ft=cE();const uE=ea({__proto__:null,default:ta(ft)},[ft]),Sf=dt("ParentContextProvider"),Gm=N.createContext(null);let hc=null;function wf(){hc?(Sf.log("[triggerModalParentUpdate] 모달 부모 컨텍스트 업데이트 트리거"),hc()):Sf.warn("[triggerModalParentUpdate] Provider가 아직 마운트되지 않음")}const Fm=({children:s})=>{const[e,n]=N.useState(0),r=N.useRef(!0),i=N.useCallback(()=>{const c=window.__g7LayoutContextStack||[];return c[c.length-1]?.dataContext},[]);N.useEffect(()=>(r.current=!0,hc=()=>{r.current&&(n(c=>c+1),Sf.log("[ParentContextProvider] 버전 업데이트됨"))},()=>{r.current=!1,hc=null}),[]);const l={version:e,getParentDataContext:i};return ft.jsx(Gm.Provider,{value:l,children:s})};function dE(){return N.useContext(Gm)}const j=dt("ActionDispatcher");function fE(s,e,n,r){return n||(jg(s)||Dd(s)?"$t:core.errors.network_request_failed":r||`Failed to execute action: ${e}`)}const Vm=new Set(["navigate","navigateBack","navigateForward","replaceUrl","refresh","logout"]),hE=new Set(["redirect"]);function Fn(){try{return window.G7Core?.devTools}catch{return}}class Ut extends Error{constructor(n,r,i){super(n);M(this,"action");M(this,"originalError");M(this,"unknownHandler",!1);this.action=r,this.originalError=i,this.name="ActionError"}}const Km={click:"onClick",change:"onChange",input:"onInput",submit:"onSubmit",focus:"onFocus",blur:"onBlur",keydown:"onKeyDown",keyup:"onKeyUp",keypress:"onKeyPress",mousedown:"onMouseDown",mouseup:"onMouseUp",mouseenter:"onMouseEnter",mouseleave:"onMouseLeave",scroll:"onScroll",dragstart:"onDragStart",drag:"onDrag",dragend:"onDragEnd",dragenter:"onDragEnter",dragover:"onDragOver",dragleave:"onDragLeave",drop:"onDrop"},xs=class xs{constructor(e={},n,r){M(this,"bindingEngine");M(this,"translationEngine");M(this,"translationContext");M(this,"customHandlers",new Map);M(this,"defaultContext");M(this,"globalStateUpdater");M(this,"errorHandlingSetup",!1);M(this,"debounceTimers",new Map);M(this,"pendingDebounceFlushers",new Map);M(this,"debounceAccumulatedValues",new Map);M(this,"globalHeaders",[]);M(this,"namedActions",{});M(this,"previewMode",!1);M(this,"intervals",new Map);this.bindingEngine=new kn,this.translationEngine=n,this.translationContext=r,this.defaultContext=e,this.registerDefaultHandlers(),this.setupErrorHandling()}setGlobalHeaders(e){this.globalHeaders=e||[]}setNamedActions(e){this.namedActions=e||{};const n=Fn();n?.isEnabled?.()&&n.setNamedActionDefinitions?.(this.namedActions),j.log("[setNamedActions] registered:",Object.keys(this.namedActions))}getNamedActions(){return this.namedActions}setPreviewMode(e){this.previewMode=e,j.log("Preview mode:",e?"enabled":"disabled")}isPreviewMode(){return this.previewMode}static getPreviewSuppressedHandlers(){return Vm}static getPreviewSuppressedLayoutFeatures(){return hE}resolveActionRef(e){if(!e.actionRef)return e;const n=this.namedActions[e.actionRef];if(!n)return j.warn(`[resolveActionRef] named action not found: "${e.actionRef}"`),e;const r=Fn();r?.isEnabled?.()&&r.trackNamedActionRef?.({actionRefName:e.actionRef,resolvedHandler:n.handler,timestamp:Date.now()});const{actionRef:i,type:l,key:c,event:d,...f}=e,h={...n,...Object.fromEntries(Object.entries(f).filter(([,m])=>m!==void 0)),type:l??n.type};return c!==void 0&&(h.key=c),d!==void 0&&(h.event=d),h}matchesPattern(e,n){if(n==="*")return!0;const r=n.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${r}$`).test(e)}getMatchingGlobalHeaders(e,n){const r={};for(const i of this.globalHeaders)this.matchesPattern(e,i.pattern)&&Object.entries(i.headers).forEach(([l,c])=>{const d=ls(c,n,{skipCache:!0});d!=null&&d!==""&&(r[l]=String(d))});return r}setupErrorHandling(){if(this.errorHandlingSetup)return;Er().setActionExecutor(async(n,r)=>{const i={type:"click",handler:n.handler,target:n.target,params:n.params,actions:n.actions},l={data:{...this.defaultContext.data,error:r.error}};return await this.dispatchAction(i,l)}),this.errorHandlingSetup=!0}registerDefaultHandlers(){this.registerHandler("refetchDataSource",async(n,r)=>{const i=n.params?.dataSourceId,l=n.params?.sync;if(!i){j.warn("refetchDataSource: dataSourceId is required");return}if(typeof window<"u"&&window.G7Core?.dataSource?.refetch){const c=window.G7Core?.state?.get?.()||{},d={...r.state?._global,...c},f=window.G7Core?.state?.getLocal?.()||{},h=r.data?._local||r.state||{},m={...f,...h},y=r.isolatedContext?.state;j.log("[refetchDataSource] localStateOverride:",m),await window.G7Core.dataSource.refetch(i,{...l?{sync:!0}:{},...d?{globalStateOverride:d}:{},...m?{localStateOverride:m}:{},...y?{isolatedStateOverride:y}:{}})}else j.warn("refetchDataSource: G7Core.dataSource.refetch is not available")}),this.registerHandler("appendDataSource",async(n,r)=>{const{dataSourceId:i,dataPath:l,newData:c}=n.params||{};if(!i){j.warn("appendDataSource: dataSourceId is required");return}if(c===void 0){j.warn("appendDataSource: newData is required");return}if(typeof window<"u"&&window.G7Core?.dataSource?.updateData){if(!Array.isArray(c)){j.warn("appendDataSource: newData must be an array, got:",typeof c,c);return}await window.G7Core.dataSource.updateData(i,l||null,c,"append")}else j.warn("appendDataSource: G7Core.dataSource.updateData is not available")}),this.registerHandler("updateDataSource",async(n,r)=>{const{dataSourceId:i,data:l,merge:c=!1}=n.params||{};if(!i){j.warn("updateDataSource: dataSourceId is required");return}if(l===void 0){j.warn("updateDataSource: data is required");return}typeof window<"u"&&window.G7Core?.dataSource?.set?(j.log(`[updateDataSource] Updating dataSource '${i}' with:`,l),window.G7Core.dataSource.set(i,l,{merge:c})):j.warn("updateDataSource: G7Core.dataSource.set is not available")}),this.registerHandler("scrollIntoView",async(n,r)=>{const{selector:i,behavior:l="smooth",block:c="nearest",inline:d="nearest",waitForElement:f=!1,timeout:h=2e3,delay:m=0,retryCount:y=0,retryInterval:S=50,scrollContainer:v}=n.params||{};if(!i){j.warn("scrollIntoView: selector is required");return}if(typeof window>"u"||typeof document>"u"){j.warn("scrollIntoView: window/document is not available");return}let _=null;if(f){if(_=await new Promise(x=>{const A=document.querySelector(i);if(A){x(A);return}const L=setTimeout(()=>{$.disconnect(),x(null)},h),$=new MutationObserver(()=>{const k=document.querySelector(i);k&&(clearTimeout(L),$.disconnect(),x(k))});$.observe(document.body,{childList:!0,subtree:!0})}),!_){j.warn(`scrollIntoView: element not found for selector "${i}" after ${h}ms timeout`);return}}else{m>0&&await new Promise(A=>setTimeout(A,m)),_=document.querySelector(i);let x=0;for(;!_&&xsetTimeout(A,S)),_=document.querySelector(i),x++;if(!_){j.warn(`scrollIntoView: element not found for selector "${i}" after ${x+1} attempts`);return}}if(v){const x=document.querySelector(v);if(!x){j.warn(`scrollIntoView: container not found for selector "${v}"`);return}const A=_.getBoundingClientRect(),L=x.getBoundingClientRect(),$=A.top-L.top+x.scrollTop,k=$+A.height;let O;switch(c){case"start":O=$;break;case"center":O=$-x.clientHeight/2+A.height/2;break;case"end":O=k-x.clientHeight;break;default:const P=A.topL.bottom;if(P)O=$;else if(G)O=k-x.clientHeight;else return;break}x.scrollTo({top:Math.max(0,O),behavior:l});return}_.scrollIntoView({behavior:l,block:c,inline:d})}),this.registerHandler("reloadExtensions",async(n,r)=>{if(typeof window>"u"){j.warn("reloadExtensions: window is not available");return}const i=window.__templateApp;if(!i){j.warn("reloadExtensions: TemplateApp not initialized");return}if(typeof i.reloadExtensionState=="function")try{await i.reloadExtensionState()}catch(d){throw j.error("reloadExtensions: reloadExtensionState failed",d),d}else j.warn("reloadExtensions: TemplateApp.reloadExtensionState unavailable");const{moduleInfo:l,pluginInfo:c}=n.params||{};if(l)try{await this.executeAction({handler:"reloadModuleHandlers",params:n.params},r)}catch(d){j.error("reloadExtensions: reloadModuleHandlers failed",d)}if(c)try{await this.executeAction({handler:"reloadPluginHandlers",params:n.params},r)}catch(d){j.error("reloadExtensions: reloadPluginHandlers failed",d)}j.log("reloadExtensions: done")}),this.registerHandler("reloadRoutes",async(n,r)=>{if(typeof window>"u"){j.warn("reloadRoutes: window is not available");return}const i=window.__templateApp;if(!i){j.warn("reloadRoutes: TemplateApp not initialized");return}if(typeof i.reloadExtensionState=="function")try{await i.reloadExtensionState(),j.log("reloadRoutes: delegated to reloadExtensionState")}catch(l){throw j.error("reloadRoutes: Failed to reload routes",l),l}else{const l=i.getRouter?.();l&&(await l.loadRoutes(),j.log("reloadRoutes: Routes reloaded (legacy fallback)"))}}),this.registerHandler("refresh",async(n,r)=>{if(typeof window>"u"){j.warn("refresh: window is not available");return}const i=Number(n.params?.delayMs??0);i>0&&await new Promise(l=>setTimeout(l,i)),window.location.reload()}),this.registerHandler("remount",async(n,r)=>{const{componentId:i}=n.params||{};if(!i){j.warn("remount: componentId parameter is required");return}if(!this.globalStateUpdater){j.warn("remount: globalStateUpdater is not set");return}const d=(window.G7Core?.state?.get()||{})._global?._remountKeys||{},f=d[i]||0;this.globalStateUpdater({_remountKeys:{...d,[i]:f+1}}),j.log(`remount: ${i} key incremented to ${f+1}`)}),this.registerHandler("reloadTranslations",async(n,r)=>{if(typeof window>"u"){j.warn("reloadTranslations: window is not available");return}const i=window.__templateApp;if(!i){j.warn("reloadTranslations: TemplateApp not initialized");return}if(typeof i.reloadExtensionState=="function")try{await i.reloadExtensionState(),j.log("reloadTranslations: delegated to reloadExtensionState")}catch(l){throw j.error("reloadTranslations: Failed to reload translations",l),l}}),this.registerHandler("reloadModuleHandlers",async(n,r)=>{if(typeof window>"u"){j.warn("reloadModuleHandlers: window is not available");return}const{moduleInfo:i,action:l}=n.params||{};if(!i){j.warn("reloadModuleHandlers: moduleInfo is required");return}const c=i.data||i;if(!c.identifier){j.warn("reloadModuleHandlers: moduleInfo with identifier is required");return}if(!l||l!=="add"&&l!=="remove"){j.warn('reloadModuleHandlers: action must be "add" or "remove"');return}const d=window.G7Config;if(!d){j.warn("reloadModuleHandlers: G7Config not available");return}const f=c.identifier;try{if(l==="add"){if(c.assets&&(d.moduleAssets=d.moduleAssets||{},d.moduleAssets[f]=c.assets,j.log(`reloadModuleHandlers: Added assets for ${f}`),c.assets.js)){const h=c.assets.js,m=`module-${f}`;if(document.getElementById(m)){j.warn(`reloadModuleHandlers: Script ${m} already loaded`);return}const y=document.createElement("script");if(y.id=m,y.src=h,y.async=!0,await new Promise((S,v)=>{y.onload=()=>{j.log(`reloadModuleHandlers: Script loaded successfully for ${f}`),S()},y.onerror=()=>{j.error(`reloadModuleHandlers: Failed to load script for ${f}`),v(new Error(`Failed to load module script: ${h}`))},document.head.appendChild(y)}),c.assets.css){const S=c.assets.css,v=`module-css-${f}`;if(!document.getElementById(v)){const _=document.createElement("link");_.id=v,_.rel="stylesheet",_.href=S,document.head.appendChild(_),j.log(`reloadModuleHandlers: CSS loaded for ${f}`)}}}}else if(l==="remove"){d.moduleAssets&&d.moduleAssets[f]&&(delete d.moduleAssets[f],j.log(`reloadModuleHandlers: Removed assets for ${f}`));const h=`module-${f}`,m=document.getElementById(h);m&&(m.remove(),j.log(`reloadModuleHandlers: Removed script for ${f}`));const y=`module-css-${f}`,S=document.getElementById(y);S&&(S.remove(),j.log(`reloadModuleHandlers: Removed CSS for ${f}`))}}catch(h){throw j.error(`reloadModuleHandlers: Failed to ${l} module assets`,h),h}}),this.registerHandler("reloadPluginHandlers",async(n,r)=>{if(typeof window>"u"){j.warn("reloadPluginHandlers: window is not available");return}const{pluginInfo:i,action:l}=n.params||{};if(!i){j.warn("reloadPluginHandlers: pluginInfo is required");return}const c=i.data||i;if(!c.identifier){j.warn("reloadPluginHandlers: pluginInfo with identifier is required");return}if(!l||l!=="add"&&l!=="remove"){j.warn('reloadPluginHandlers: action must be "add" or "remove"');return}const d=window.G7Config;if(!d){j.warn("reloadPluginHandlers: G7Config not available");return}const f=c.identifier;try{if(l==="add"){if(c.assets&&(d.pluginAssets=d.pluginAssets||{},d.pluginAssets[f]=c.assets,j.log(`reloadPluginHandlers: Added assets for ${f}`),c.assets.js)){const h=c.assets.js,m=`plugin-${f}`;if(document.getElementById(m)){j.warn(`reloadPluginHandlers: Script ${m} already loaded`);return}const y=document.createElement("script");if(y.id=m,y.src=h,y.async=!0,await new Promise((S,v)=>{y.onload=()=>{j.log(`reloadPluginHandlers: Script loaded successfully for ${f}`),S()},y.onerror=()=>{j.error(`reloadPluginHandlers: Failed to load script for ${f}`),v(new Error(`Failed to load plugin script: ${h}`))},document.head.appendChild(y)}),c.assets.css){const S=c.assets.css,v=`plugin-css-${f}`;if(!document.getElementById(v)){const _=document.createElement("link");_.id=v,_.rel="stylesheet",_.href=S,document.head.appendChild(_),j.log(`reloadPluginHandlers: CSS loaded for ${f}`)}}}}else if(l==="remove"){d.pluginAssets&&d.pluginAssets[f]&&(delete d.pluginAssets[f],j.log(`reloadPluginHandlers: Removed assets for ${f}`));const h=`plugin-${f}`,m=document.getElementById(h);m&&(m.remove(),j.log(`reloadPluginHandlers: Removed script for ${f}`));const y=`plugin-css-${f}`,S=document.getElementById(y);S&&(S.remove(),j.log(`reloadPluginHandlers: Removed CSS for ${f}`))}}catch(h){throw j.error(`reloadPluginHandlers: Failed to ${l} plugin assets`,h),h}});let e=!1;this.registerHandler("showErrorPage",async(n,r)=>{if(e){j.log("showErrorPage: Already active, skipping duplicate call");return}if(e=!0,typeof window>"u"){e=!1,j.warn("showErrorPage: window is not available");return}const i=window.__templateApp;if(!i){e=!1,j.warn("showErrorPage: TemplateApp not initialized");return}const l=i.getErrorPageHandler?.();if(!l){e=!1,j.warn("showErrorPage: ErrorPageHandler not available");return}const c=n.params?.errorCode||500,d=n.params?.target||"content";let f=n.params?.containerId;f||(f=d==="full"?"app":"main_content"),j.log("showErrorPage:",{errorCode:c,target:d,containerId:f});const h=(m,y=6e4)=>new Promise((S,v)=>{const _=document.getElementById(m);if(_){S(_);return}j.log(`showErrorPage: Waiting for container #${m}...`);let x;const A=new MutationObserver((L,$)=>{const k=document.getElementById(m);k&&(j.log(`showErrorPage: Container #${m} found`),$.disconnect(),clearTimeout(x),S(k))});A.observe(document.body,{childList:!0,subtree:!0}),x=setTimeout(()=>{A.disconnect(),v(new Error(`Container #${m} not found within ${y}ms`))},y)});try{await h(f);const m=Er(),y=m.layoutErrorHandling;m.clearLayoutConfig();try{await l.renderError(c,f)||j.warn(`showErrorPage: Failed to render error page for code ${c}`)}finally{m.setLayoutConfig(y)}}catch(m){throw j.error("showErrorPage: Error rendering error page:",m),m}finally{e=!1}}),this.registerHandler("emitEvent",async(n,r)=>{const i=n.params?.event,l=n.params?.data;if(!i){j.warn("emitEvent: event parameter is required");return}if(typeof window>"u"){j.warn("emitEvent: window is not available");return}const c=window.G7Core;if(!c?.componentEvent?.emit){j.warn("emitEvent: G7Core.componentEvent is not available");return}try{j.log(`emitEvent: Emitting "${i}"`,l);const d={...l,_context:{data:r.data,state:r.state}},f=await c.componentEvent.emit(i,d);if(!f||f.length===0?j.warn(`emitEvent: No listeners found for "${i}"`):j.log(`emitEvent: Event "${i}" completed with ${f.length} listener(s)`,f),this.globalStateUpdater){const h=(c?.state?.get()||{})._local||{},m={event:i,success:!0,data:f.length===1?f[0]:f,listeners:f.length};this.globalStateUpdater({_local:{...h,_eventResult:m}});const y=r.state&&typeof r.state=="object"&&!Array.isArray(r.state)?r.state:h;window.__g7SequenceLocalSync={...y,_eventResult:m}}}catch(d){if(j.error(`emitEvent: Event "${i}" failed`,d),this.globalStateUpdater){const f=c?.state?.get()||{};this.globalStateUpdater({_local:{...f._local,_eventResult:{event:i,success:!1,error:d instanceof Error?d.message:String(d)}}})}throw d}}),this.registerHandler("updateProductField",async(n,r)=>{const{productId:i,field:l,value:c}=n.params||{};if(!i||!l){j.warn("updateProductField: productId and field are required");return}if(typeof window>"u"){j.warn("updateProductField: window is not available");return}const d=window.G7Core;if(!d?.state?.get||!this.globalStateUpdater){j.warn("updateProductField: G7Core.state or globalStateUpdater is not available");return}try{const f=d.state.get()||{},m=(f.products?.data?.data||[]).map(S=>S.id===i?{...S,[l]:c,_modified:!0}:S),y=new Set(f._local?.modifiedProductIds||[]);y.add(i),this.globalStateUpdater({products:{...f.products,data:{...f.products?.data,data:m}},_local:{...f._local,modifiedProductIds:Array.from(y)}}),j.log(`updateProductField: Updated product ${i}, field: ${l}, value:`,c)}catch(f){throw j.error("updateProductField: Error updating product field",f),f}}),this.registerHandler("updateOptionField",async(n,r)=>{const{productId:i,optionId:l,field:c,value:d}=n.params||{};if(!i||!l||!c){j.warn("updateOptionField: productId, optionId and field are required");return}if(typeof window>"u"){j.warn("updateOptionField: window is not available");return}const f=window.G7Core;if(!f?.state?.get||!this.globalStateUpdater){j.warn("updateOptionField: G7Core.state or globalStateUpdater is not available");return}try{const h=f.state.get()||{},y=(h.products?.data?.data||[]).map(v=>{if(v.id===i&&v.options){const _=v.options.map(x=>x.id===l?{...x,[c]:d,_modified:!0}:x);return{...v,options:_,_modified:!0}}return v}),S=new Set(h._local?.modifiedProductIds||[]);S.add(i),this.globalStateUpdater({products:{...h.products,data:{...h.products?.data,data:y}},_local:{...h._local,modifiedProductIds:Array.from(S)}}),j.log(`updateOptionField: Updated product ${i} option ${l}, field: ${c}, value:`,d)}catch(h){throw j.error("updateOptionField: Error updating option field",h),h}}),this.registerHandler("setLocale",async(n,r)=>{const i=n.target;if(!i||typeof i!="string"){j.warn("setLocale: Invalid locale:",i);return}const l=window.__templateApp;if(l&&typeof l.changeLocale=="function")try{await l.changeLocale(i),j.log("setLocale: Locale changed to",i)}catch(c){j.error("setLocale: Failed to change locale:",c),window.location.reload()}else{j.warn("setLocale: TemplateApp not found, falling back to page reload");try{localStorage.setItem("g7_locale",i)}catch{}window.location.reload()}}),this.registerHandler("suppress",async()=>{j.log("suppress: Error intentionally suppressed")}),this.registerBuiltInHandlerMetadata()}registerBuiltInHandlerMetadata(){const e=Fn();if(!e?.isEnabled())return;const n=[{name:"refetchDataSource",description:"데이터 소스를 다시 fetch합니다"},{name:"appendDataSource",description:"데이터 소스에 새 데이터를 병합합니다 (무한 스크롤용)"},{name:"updateDataSource",description:"API 응답으로 데이터 소스를 직접 업데이트합니다 (refetch 대체)"},{name:"reloadRoutes",description:"라우트를 다시 로드합니다"},{name:"refresh",description:"현재 페이지를 새로고침합니다"},{name:"remount",description:"컴포넌트를 리마운트합니다"},{name:"reloadTranslations",description:"다국어 파일을 다시 로드합니다"},{name:"showErrorPage",description:"에러 페이지를 표시합니다"},{name:"emitEvent",description:"이벤트를 발생시킵니다"},{name:"updateProductField",description:"상품 필드를 인라인 수정합니다"},{name:"updateOptionField",description:"상품 옵션 필드를 인라인 수정합니다"},{name:"setLocale",description:"언어를 변경합니다 (DB 저장 + UI 리렌더링)"}];for(const r of n)e.trackHandlerRegistration(r.name,"built-in",r.description)}createHandler(e,n,r){j.log("createHandler called for:",e.handler,e.type);const i=window.__g7DevTools,l=Date.now(),c=r?.state?{...r.state}:null,d=`handler_${e.handler}_${l}`;return async f=>{if(j.log("Handler invoked for:",e.handler,"event:",f.type),i?.isEnabled?.()&&c){const m=window.G7Core?.state?.getLocal?.()??r?.state??{},y=Date.now()-l;for(const S of Object.keys(c)){const v=c[S],_=m[S];v!==_&&y>100&&(i.trackStaleClosureWarning?.({type:"event-handler-stale",location:`createHandler(${e.handler})`,capturedPath:`_local.${S}`,capturedValue:v,capturedAt:l,currentValue:_,actionId:d,stackTrace:new Error().stack}),j.warn(`[Stale Closure] _local.${S} changed after handler creation:`,`captured="${v}" → current="${_}" (${y}ms ago)`))}}try{f.type!=="change"&&f.preventDefault();let h={};if(f.type==="submit"&&f.target instanceof HTMLFormElement){const S=f.target;new FormData(S).forEach((_,x)=>{h[x]=_})}const m={...this.defaultContext,data:{...n,form:h,_local:r?.state||{},$event:f},event:f,...r&&{state:r.state,setState:r.setState},isolatedContext:r?.isolatedContext};if(e.confirm){let S=this.resolveValue(e.confirm,m.data);if(this.translationEngine&&this.translationContext&&S.startsWith("$t:")&&(S=this.translationEngine.resolveTranslations(S,this.translationContext,m.data)),!confirm(S))return}const y=window.__g7ActionContext;window.__g7ActionContext={...r,data:m.data};try{await this.executeAction(e,m)}finally{window.__g7ActionContext=y}}catch(h){if(j.error("Action execution failed:",h),e.onError){const m=h instanceof Ut&&h.originalError?h.originalError:h,y={...this.defaultContext,data:{...n,error:m,_local:r?.state||{},$event:f},event:f,...r&&{state:r.state,setState:r.setState}},S=Array.isArray(e.onError)?e.onError:[e.onError];for(const v of S)await this.executeAction(v,y)}}}}generateActionId(e,n){const r=e.handler,i=n||"no-target",l=Date.now(),c=Math.random().toString(36).substring(2,9);return`${r}_${i.replace(/[^a-zA-Z0-9]/g,"_")}_${l}_${c}`}async executeAction(e,n){if(e=this.resolveActionRef(e),typeof e.handler=="string"&&e.handler.includes("{{")){const f=this.evaluateExpression(e.handler,n.data);e={...e,handler:f==null?"":String(f)}}const r=Fn(),i=r?.isEnabled()?`action_${Date.now()}_${Math.random().toString(36).substring(2,11)}`:void 0,l=performance.now();let c;if(i&&r&&r.logAction({id:i,type:e.handler,params:this.sanitizeForDevTools(e.params),context:this.sanitizeForDevTools({hasState:!!n.state,hasSetState:!!n.setState,dataKeys:n.data?Object.keys(n.data):[]}),startTime:l,status:"started"}),e.if!==void 0)try{const f=this.resolveValue(e.if,n.data),h=f===!0||f==="true"||f&&f!=="false"&&f!=="0"&&f!==!1;if(j.log("[executeAction] if condition result:",e.handler,h),!h)return i&&r&&r.logAction({id:i,type:e.handler,startTime:l,endTime:performance.now(),duration:performance.now()-l,status:"success",result:{skipped:!0,reason:"if condition false"}}),{success:!0,data:void 0}}catch(f){return j.error("[executeAction] if condition error:",e.handler,f),i&&r&&r.logAction({id:i,type:e.handler,startTime:l,endTime:performance.now(),duration:performance.now()-l,status:"error",error:{name:"ConditionEvaluationError",message:f instanceof Error?f.message:String(f),stack:f instanceof Error?f.stack:void 0}}),{success:!0,data:void 0}}let d;try{const f=this.resolveParams(e.params,n.data);i&&(c=this.sanitizeForDevTools(f));const h=e.target?this.resolveValue(e.target,n.data):void 0;if(e.handler==="apiCall"&&n.setState){d=this.generateActionId(e,h);const y=n.state?.loadingActions||{};n.setState({loadingActions:{...y,[d]:!0}})}if(this.previewMode&&Vm.has(e.handler))return j.warn(`Preview mode: "${e.handler}" suppressed`,h||f),i&&r&&r.logAction({id:i,type:e.handler,startTime:l,endTime:performance.now(),duration:performance.now()-l,status:"skipped",metadata:{reason:"preview_mode_suppressed"}}),{success:!0,data:void 0};let m;switch(e.handler){case"ensureIdentityVerified":m=await this.handleEnsureIdentityVerified(f);break;case"resolveIdentityChallenge":m=this.handleResolveIdentityChallenge(f);break;case"navigate":const y=f.path||h;m=await this.handleNavigate(y,f,n);break;case"navigateBack":m=await this.handleNavigateBack();break;case"navigateForward":m=await this.handleNavigateForward();break;case"openWindow":{const _=f.path||h;m=await this.handleOpenWindow(_,f);break}case"replaceUrl":{const _=f.path||h||window.location.pathname;m=await this.handleReplaceUrl(_,f);break}case"apiCall":if(e.onSuccess&&r?.isEnabled()&&i){const _=window.G7Core,x={};if(_?.state?.get){const A=_.state.get();x._global=A}n.state&&(x._local=n.state),r.registerStateCaptureForHandler?.(i,["_global","_local"],x)}const S=e.auth_mode??(e.auth_required?"required":"none"),v=e.identity_target?this.resolveParams(e.identity_target,n.data):void 0;m=await this.handleApiCall(h,f,n,S,v);break;case"login":m=await this.handleLogin(h,f,n);break;case"logout":m=await this.handleLogout(h,n);break;case"setState":j.log("[executeAction] setState resolvedParams:",f),m=await this.handleSetState(e.render!==void 0?{...f,__render:e.render}:f,n);break;case"setError":m=await this.handleSetError(h,f,n);break;case"openModal":m=await this.handleOpenModal(h,n);break;case"closeModal":m=await this.handleCloseModal(n);break;case"showAlert":m=await this.handleShowAlert(h,n);break;case"toast":m=await this.handleToast(f,n);break;case"switch":m=await this.handleSwitch(e,n);break;case"conditions":m=await this.handleConditions(e,n);break;case"sequence":m=await this.handleSequence(e,n);break;case"parallel":m=await this.handleParallel(e,n);break;case"startInterval":m=this.handleStartInterval(f,n);break;case"stopInterval":m=this.handleStopInterval(f);break;case"loadScript":m=await this.handleLoadScript(f,e,n);break;case"callExternal":m=await this.handleCallExternal(f,e,n);break;case"callExternalEmbed":m=await this.handleCallExternalEmbed(f,e,n);break;case"saveToLocalStorage":m=await this.handleSaveToLocalStorage(f,n);break;case"loadFromLocalStorage":m=await this.handleLoadFromLocalStorage(f,n);break;default:m=await this.handleCustomAction({...e,target:h,params:f},n);break}if(e.resultTo&&m!==void 0){const{target:y,key:S,merge:v}=e.resultTo,_=this.resolveValue(S,n.data),x=v==="replace"?"replace":v==="shallow"?"shallow":"deep";if(y==="_local"&&n.setState){const A=this.buildNestedUpdate(_,m),L=x!=="deep"?{...A,__mergeMode:x}:A;n.setState(L),j.log(`[resultTo] Saved to _local.${_} (merge=${x}):`,m)}else if(y==="_local"&&this.globalStateUpdater){const $=(window.G7Core?.state?.get()||{})._local||{},k=this.buildNestedUpdate(_,m);let O;x==="replace"?O=k:x==="shallow"?O={...$,...k}:O=this.deepMergeWithState(k,$),this.globalStateUpdater({_local:O}),j.log(`[resultTo] Saved to _local.${_} via globalStateUpdater (merge=${x}):`,m)}else if(y==="_global"&&this.globalStateUpdater){const A=this.buildNestedUpdate(_,m);this.globalStateUpdater(A),j.log(`[resultTo] Saved to _global.${_}:`,m)}else if(y==="_isolated"&&n.isolatedContext){const A=this.buildNestedUpdate(_,m);n.isolatedContext.mergeState(A,x),j.log(`[resultTo] Saved to _isolated.${_} (merge=${x}):`,m)}else j.warn(`[resultTo] Cannot save result: target=${y}, setState=${!!n.setState}, globalStateUpdater=${!!this.globalStateUpdater}, isolatedContext=${!!n.isolatedContext}`)}if(e.onSuccess){if(r?.isEnabled()&&i&&e.handler==="apiCall"){const v=window.G7Core,_={};v?.state?.get&&(_._global=v.state.get()),n.state&&(_._local=n.state),r.detectStaleClosure?.(i,`${e.handler} → onSuccess`,_,"callback-state-capture",i)}const y={...n,data:{...n.data,result:m,response:m}},S=Array.isArray(e.onSuccess)?e.onSuccess:[e.onSuccess];S.length>1?await this.handleSequence({handler:"sequence",type:"click",actions:S},y):S.length===1&&await this.executeAction(S[0],y)}return i&&r&&r.logAction({id:i,type:e.handler,params:this.sanitizeForDevTools(e.params),resolvedParams:c,startTime:l,endTime:performance.now(),duration:performance.now()-l,status:"success",result:this.sanitizeForDevTools(m)}),{success:!0,data:m}}catch(f){const h=f instanceof Ut?f:new Ut(`Failed to execute action: ${e.handler}`,e,f instanceof Error?f:void 0),m=h.originalError?.response||{},y=m.data||{},S=h.originalError?.status||m.status||500;let v=fE(h.originalError??f,e.handler,y.message,h.message);this.translationEngine&&this.translationContext&&v.startsWith("$t:")&&(v=this.translationEngine.resolveTranslations(v,this.translationContext));const _={status:S,message:v,errors:y.errors||m.errors,data:y,statusText:h.originalError?.statusText,error_code:y.error_code??m.error_code};if(h.unknownHandler)throw j.warn(`Unknown action handler "${e.handler}" — skipped (extension not loaded?). Not surfaced to the user.`),h;const A=Er().resolve(S,{errorHandling:e.errorHandling,onError:e.onError});if(A.handler){if(r?.isEnabled()&&i&&e.handler==="apiCall"){const $=window.G7Core,k={};$?.state?.get&&(k._global=$.state.get()),n.state&&(k._local=n.state),r.detectStaleClosure?.(i,`${e.handler} → onError`,k,"callback-state-capture",i)}const L={...n,data:{...n.data,error:_}};try{const $={type:"click",handler:A.handler.handler,target:A.handler.target,params:A.handler.params,actions:A.handler.actions};return await this.executeAction($,L),{success:!1,error:h}}catch($){return j.error("Error executing error handler:",$),{success:!1,error:h}}}throw i&&r&&r.logAction({id:i,type:e.handler,params:this.sanitizeForDevTools(e.params),resolvedParams:c,startTime:l,endTime:performance.now(),duration:performance.now()-l,status:"error",error:{name:h.name,message:h.message,stack:h.stack}}),h}finally{if(e.handler==="apiCall"&&n.setState&&d){const f=n.state?.loadingActions||{},{[d]:h,...m}=f;n.setState({loadingActions:m})}}}async handleNavigate(e,n,r){let i=e;if(n.query||n.mergeQuery===!0)if(n.mergeQuery===!0)i=this.buildMergedQueryPath(e,n.query??{});else{const c=new URLSearchParams;for(const[f,h]of Object.entries(n.query))if(h!=null&&h!=="")if(Array.isArray(h)){const m=f.endsWith("[]")?f:`${f}[]`;for(const y of h)y!=null&&y!==""&&c.append(m,String(y))}else c.set(f,String(h));const d=c.toString();d&&(i=`${e}?${d}`)}if(j.log("handleNavigate:",{target:e,params:n,finalPath:i,replace:n.replace,windowLocationSearch:window.location.search}),n.replace===!0){const c=window.G7Core;if(c?.updateQueryParams){const d=typeof n.transition_overlay_target=="string"?n.transition_overlay_target:void 0;await c.updateQueryParams(i,d?{transitionOverlayTarget:d}:void 0),j.log("handleNavigate: Used updateQueryParams for replace mode",d?{transitionOverlayTarget:d}:void 0),this.applyScrollOption(n.scroll,n.scrollBehavior,"top");return}j.warn("handleNavigate: G7Core.updateQueryParams not available, falling back to React Router")}const l=this.resolveNavigateFallbackAction(i,n);if(l){j.warn(`handleNavigate: No route matched, falling back to "${l.handler}"`),await this.dispatchAction({type:"click",handler:l.handler,params:l.params},r),this.applyScrollOption(n.scroll,n.scrollBehavior,"top");return}if(!r.navigate)throw new Ut("Navigate function is not provided in context");r.navigate(i,{replace:n.replace===!0}),this.applyScrollOption(n.scroll,n.scrollBehavior,"top")}resolveNavigateFallbackAction(e,n){const r=n.fallback;if(r===!1||n.replace===!0)return null;const l=window.__templateApp?.getRouter?.();if(!l||typeof l.match!="function"||typeof l.getRoutes=="function"&&l.getRoutes().length===0)return null;const c=e.split("?")[0];return l.match(c)?null:this.resolveNavigateFallback(r,e,n)}resolveNavigateFallback(e,n,r){return e==null?{handler:"openWindow",params:{path:n,target:"_self"}}:typeof e=="string"?{handler:e,params:{path:n}}:typeof e=="object"&&typeof e.handler=="string"?{handler:e.handler,params:{path:n,...e.params||{}}}:(j.warn("resolveNavigateFallback: unrecognized fallback option, using openWindow",e),{handler:"openWindow",params:{path:n,target:"_blank"}})}applyScrollOption(e,n,r){const i=e===void 0?r:e;if(i==="preserve")return;const l=n==="smooth"?"smooth":"instant",c=y=>{if(typeof y!="object"||y===null)return!1;const S=y;return"container"in S||"to"in S||"block"in S||"offset"in S},d=(y,S,v=0)=>{y===window?window.scrollTo({top:S,left:v,behavior:l}):y.scrollTo({top:S,left:v,behavior:l})},f=(y,S,v,_)=>{if(S===window){y.scrollIntoView({behavior:l,block:v}),_&&window.scrollBy({top:-_,left:0,behavior:l});return}const x=S,A=y.getBoundingClientRect(),L=x.getBoundingClientRect(),$=x.scrollTop+(A.top-L.top);let k;v==="center"?k=$-(x.clientHeight-y.clientHeight)/2:v==="end"?k=$-(x.clientHeight-y.clientHeight):k=$,k-=_,x.scrollTo({top:Math.max(0,k),left:0,behavior:l})},h=()=>{window.scrollTo({top:0,left:0,behavior:l});const y=document.getElementById("app")??document.body;if(!y)return;y.querySelectorAll("*").forEach(v=>{if(v.scrollTop===0&&v.scrollLeft===0)return;const _=window.getComputedStyle(v),x=_.overflowY,A=_.overflowX;(x==="auto"||x==="scroll"||A==="auto"||A==="scroll")&&v.scrollTo({top:0,left:0,behavior:l})})},m=()=>{try{if(c(i)){const y=i,S=y.block??"start",v=typeof y.offset=="number"?y.offset:0;let _=window;if(typeof y.container=="string"&&y.container.length>0){const A=document.querySelector(y.container);if(!A){j.warn(`applyScrollOption: container not found: ${y.container}`);return}_=A}const x=y.to??"top";if(x==="top"){_===window?h():d(_,0);return}if(typeof x=="number"){d(_,x-v);return}if(typeof x=="object"&&x!==null&&("x"in x||"y"in x)){const{x:A=0,y:L=0}=x;d(_,L-v,A);return}if(typeof x=="string"&&(x.startsWith("#")||x.startsWith("."))){const A=document.querySelector(x);A?f(A,_,S,v):j.warn(`applyScrollOption: target element not found: ${x}`);return}j.warn('applyScrollOption: invalid "to" value in extended form',x);return}if(i==="top"){h();return}if(typeof i=="number"){window.scrollTo({top:i,left:0,behavior:l});return}if(typeof i=="object"&&i!==null&&("x"in i||"y"in i)){const{x:y=0,y:S=0}=i;window.scrollTo({top:S,left:y,behavior:l});return}if(typeof i=="string"&&(i.startsWith("#")||i.startsWith("."))){const y=document.querySelector(i);y&&y.scrollIntoView({behavior:l,block:"start"});return}}catch(y){j.warn("applyScrollOption: failed to apply scroll",y)}};typeof window.requestAnimationFrame=="function"?window.requestAnimationFrame(m):m()}async handleOpenWindow(e,n){let r=e;if(n.query){const l=new URLSearchParams;for(const[d,f]of Object.entries(n.query))f!=null&&f!==""&&l.set(d,String(f));const c=l.toString();c&&(r=`${e}?${c}`)}const i=n.target==="_self"?"_self":"_blank";j.log("handleOpenWindow:",{target:e,params:n,finalPath:r,windowTarget:i}),i==="_self"?window.location.assign(r):window.open(r,"_blank")}async handleNavigateBack(){j.log("handleNavigateBack"),window.history.back()}async handleNavigateForward(){j.log("handleNavigateForward"),window.history.forward()}async handleReplaceUrl(e,n){let r=e;if(n.query||n.mergeQuery===!0)if(n.mergeQuery===!0)r=this.buildMergedQueryPath(e,n.query??{});else{const i=new URLSearchParams;for(const[c,d]of Object.entries(n.query))if(d!=null&&d!=="")if(Array.isArray(d)){const f=c.endsWith("[]")?c:`${c}[]`;for(const h of d)h!=null&&h!==""&&i.append(f,String(h))}else i.set(c,String(d));const l=i.toString();l&&(r=`${e}?${l}`)}j.log("handleReplaceUrl:",{target:e,params:n,finalPath:r}),window.history.replaceState(null,"",r),this.applyScrollOption(n.scroll,n.scrollBehavior,"preserve")}buildMergedQueryPath(e,n){const r=new URLSearchParams(window.location.search);for(const[c,d]of Object.entries(n))if(d==null||d==="")r.delete(c);else if(Array.isArray(d)){const f=c.endsWith("[]")?c:`${c}[]`;r.delete(c),r.delete(f);for(const h of d)h!=null&&h!==""&&r.append(f,String(h))}else r.set(c,String(d));const i=r.toString(),l=e.split("?")[0];return i?`${l}?${i}`:l}async ensureCsrfToken(){try{await fetch("/sanctum/csrf-cookie",{credentials:"include"})}catch(e){throw new Ut("Failed to fetch CSRF token",void 0,e instanceof Error?e:void 0)}}getCsrfTokenFromCookie(){const r=`; ${document.cookie}`.split("; XSRF-TOKEN=");if(r.length===2){const i=r.pop()?.split(";").shift();return i?decodeURIComponent(i):null}return null}buildQueryString(e){const n=new URLSearchParams;for(const[r,i]of Object.entries(e))if(!(i==null||i===""))if(Array.isArray(i))for(const l of i)l!=null&&l!==""&&n.append(`${r}[]`,String(l));else typeof i=="object"?n.append(r,JSON.stringify(i)):n.append(r,String(i));return n.toString()}async handleEnsureIdentityVerified(e){const n=typeof e.purpose=="string"?e.purpose:"sensitive_action",r=e.target&&typeof e.target=="object"?e.target:void 0;return await St.handle({success:!1,error_code:"identity_verification_required",message:"",verification:{policy_key:e.policy_key??"",purpose:n,provider_id:e.provider_id??null,render_hint:e.render_hint??null,return_request:null}},void 0,r)!==null}handleResolveIdentityChallenge(e){const n=typeof e.result=="string"?e.result:"cancelled";let r;switch(n){case"verified":{const i=typeof e.token=="string"?e.token:"";if(!i){j.warn("resolveIdentityChallenge: result=verified 인데 token 이 비어있습니다. failed 로 강등합니다."),r={status:"failed",failureCode:"MISSING_TOKEN"};break}r={status:"verified",token:i,providerData:e.providerData&&typeof e.providerData=="object"?e.providerData:void 0};break}case"pending":{const i=typeof e.pollUrl=="string"?e.pollUrl:"",l=typeof e.expiresAt=="string"?e.expiresAt:"";if(!i||!l){j.warn("resolveIdentityChallenge: result=pending 인데 pollUrl/expiresAt 누락 — failed 로 강등합니다."),r={status:"failed",failureCode:"MALFORMED_PENDING"};break}r={status:"pending",pollUrl:i,pollIntervalMs:typeof e.pollIntervalMs=="number"?e.pollIntervalMs:void 0,expiresAt:l};break}case"failed":r={status:"failed",failureCode:typeof e.failureCode=="string"?e.failureCode:"UNKNOWN",reason:typeof e.reason=="string"?e.reason:void 0};break;default:r={status:"cancelled"};break}return St.resolveDeferred(r),!0}async handleApiCall(e,n,r,i="none",l){const{method:c="GET",body:d,headers:f,contentType:h}=n;c!=="GET"&&c!=="HEAD"&&await this.ensureCsrfToken();const m=this.getCsrfTokenFromCookie();let y={};if(i==="required"||i==="optional"){const W=zr().getToken();W&&(y={Authorization:`Bearer ${W}`})}let S=e;const v=n.query||(c==="GET"?d:null);if(v&&typeof v=="object"){const B=this.buildQueryString(v);if(B){const W=e.includes("?")?"&":"?";S=`${e}${W}${B}`}}const _=window.G7Core?.state?.getGlobal?.()||r.state?._global||{},x=window.G7Core?.state?.getLocal?.()||r.state?._local||{},A={_global:_,_local:x},L=this.getMatchingGlobalHeaders(e,A),$={};if(typeof window<"u"){const B=localStorage.getItem("g7_locale");B&&($["Accept-Language"]=B)}const k=h==="multipart/form-data",O={method:c,headers:{...k?{}:{"Content-Type":"application/json"},Accept:"application/json",...$,...m&&{"X-XSRF-TOKEN":m},...y,...L,...f},credentials:"include"};if(d&&c!=="GET")if(k){const B=new FormData;for(const[W,pe]of Object.entries(d))pe instanceof File||pe instanceof Blob?B.append(W,pe):pe!=null&&B.append(W,typeof pe=="object"?JSON.stringify(pe):String(pe));O.body=B}else O.body=JSON.stringify(d);const P=Fn();let G=null;P?.isEnabled()&&(G=P.trackRequest(S,c));try{let B=await fetch(S,O),W;try{W=await B.json()}catch{W=null}if(St.isIdentityRequired(B.status,W)){const pe=await St.handle(W,{body:O.body,headers:O.headers,credentials:O.credentials},l);if(pe){B=pe;try{W=await B.json()}catch{W=null}}}if(G&&P?.isEnabled()&&(P.completeRequest(G,B.status,W),G=null),!B.ok){const pe=W||{},Se=new Error(pe.message||`API call failed: ${B.statusText}`);throw Se.response=pe,Se.status=B.status,Se.statusText=B.statusText,new Ut(pe.message||`API call failed: ${B.statusText}`,void 0,Se)}return W}catch(B){throw G&&P?.isEnabled()&&P.failRequest(G,B instanceof Error?B.message:String(B)),B}}async handleLogin(e,n,r){const{body:i}=n;if(!i||!i.email||!i.password)throw new Ut("Login requires email and password in body params");const l=e==="user"?"user":"admin",c=l==="admin"?"/api/auth/admin/login":"/api/auth/login",d=window.G7Core?.state?.getGlobal?.()||r.state?._global||{},f=window.G7Core?.state?.getLocal?.()||r.state?._local||{},h={_global:d,_local:f},m=this.getMatchingGlobalHeaders(c,h),y=wr.getInstance();try{const S=Object.keys(m).length>0?{headers:m}:void 0;return{user:await y.login(l,{email:i.email,password:i.password},S)}}catch(S){const v=S.message||"Login failed",_=new Error(v);throw _.response=S.response?.data||{},_.status=S.status||S.response?.status||500,new Ut(v,void 0,_)}}async handleLogout(e,n){await wr.getInstance().logout()}async handleSetState(e,n){j.log("[handleSetState] START, params:",e);const{target:r="component",scope:i,merge:l,__render:c,...d}=e,f=Fn(),h=window.G7Core;if(typeof r=="string"&&(r.startsWith("$parent.")||r.startsWith("$root.")))return this.handleParentScopeSetState(r,d,l,n);const m=n.state&&Object.keys(n.state).length>0?n.state:h?.state?.get()||{},y=r==="global"?"_global":r.startsWith("_local.")?r:"_local",S=y==="_global"?m._global:y.startsWith("_local.")?this.getNestedProperty(m._local||{},y.slice(7)):m._local,v=f?.isEnabled()?f.startStateChange(y,S,d,{actionId:n.actionId,handlerType:"setState",source:`target=${r}`}):void 0,_=l==="replace"?"replace":l==="shallow"?"shallow":"deep",x=_!=="deep"?{...d,__mergeMode:_,...v?{__setStateId:v}:{}}:{...d,...v?{__setStateId:v}:{}};if(r==="global"){if(!this.globalStateUpdater){j.warn("Global state updater is not set"),v&&f&&f.completeStateChange(v);return}const A=h?.state?.get()||{},{__setStateId:L,__mergeMode:$,...k}=x,O=_==="deep"?this.deepMergeWithState(k,A):k,P={...O,...v?{__setStateId:v}:{},..._!=="deep"?{__mergeMode:_}:{}};return j.log("setState global:",P),this.globalStateUpdater(P,{render:c}),v&&f&&setTimeout(()=>f.completeStateChange(v),0),{__target:"global",..._!=="deep"?{__mergeMode:_}:{},...O}}else if(r==="isolated"){const A=n.isolatedContext;if(A){const{__mergeMode:L,__setStateId:$,...k}=x;return A.mergeState(k,_),j.log("[handleSetState] isolated state updated:",k,"mergeMode:",_),v&&f&&setTimeout(()=>f.completeStateChange(v),0),{__target:"isolated",...k}}else if(j.warn('[handleSetState] isolated target used but no IsolatedStateContext found. Make sure the component has "isolatedState" attribute. Falling back to local state.'),n.setState){const $=window.__g7PendingLocalState||n.state||{},k=_==="deep"?this.deepMergeWithState(x,$):x;return n.setState(k),v&&f&&setTimeout(()=>f.completeStateChange(v),0),k}else throw v&&f&&f.completeStateChange(v),new Ut("isolated target used but no IsolatedStateContext found and no setState function in context")}else if(r==="local"||r==="component"||r==="_local"){if(i==="parent"||i==="root"){const L=window.__g7LayoutContextStack||[];if(L.length>0){const $=i==="parent"?L[L.length-1]:L[0];if($?.setState){const{__mergeMode:k,__setStateId:O,...P}=x,G=_==="deep"?this.deepMergeWithState(P,$.state||{}):P;return j.log(`[handleSetState] scope=${i}: 타겟 컨텍스트에 상태 업데이트`,G),$.setState(G),v&&f&&setTimeout(()=>f.completeStateChange(v),0),G}}j.warn(`[handleSetState] scope=${i}: 레이아웃 컨텍스트 스택이 비어있습니다. current로 폴백합니다.`)}const A=n.setState&&!n._isDispatchFallbackContext;if(j.log("[handleSetState] isRealComponentContext:",A,"context.setState:",!!n.setState,"_isDispatchFallbackContext:",n._isDispatchFallbackContext),A){j.log("[handleSetState] Using COMPONENT setState path"),j.log("[handleSetState] resolvedPayload:",x),j.log("[handleSetState] context.state:",n.state),j.log("[handleSetState] mergeMode:",_);const $=window.__g7PendingLocalState||n.state||{},k=_==="deep"?this.deepMergeWithState(x,{}):x;j.log("[handleSetState] convertedPayload (변경 필드만, dot notation 변환):",k),n.setState(k);const O=_==="deep"?this.deepMergeWithState(x,$):_==="shallow"?{...n.state||{},...x}:x,{__mergeMode:P,__setStateId:G,...B}=O;window.__g7PendingLocalState=B,j.log("[handleSetState] __g7PendingLocalState updated:",B),this.globalStateUpdater&&(this.globalStateUpdater({_local:B},{render:!1}),j.log("[handleSetState] _global._local synced (render:false):",B));const{__mergeMode:W,__setStateId:pe,...Se}=x;if(_==="replace")window.__g7ForcedLocalFields=Se;else{const we=window.__g7ForcedLocalFields||{};window.__g7ForcedLocalFields=this.deepMergeWithState(Se,we)}return j.log("[handleSetState] __g7ForcedLocalFields updated:",Se),v&&f&&setTimeout(()=>f.completeStateChange(v),0),{__target:"local",...O}}else if(this.globalStateUpdater){j.log("[handleSetState] Using GLOBAL STATE UPDATER path for _local");const $=window.__g7PendingLocalState||m._local||{};j.log("[handleSetState] currentLocal (with pending):",$);const k=_==="deep"?this.deepMergeWithState(x,$):x;return j.log("[handleSetState] finalLocal (merged):",k),this.globalStateUpdater({_local:k},{render:c}),window.__g7PendingLocalState=k,j.log("[handleSetState] __g7PendingLocalState updated for globalStateUpdater path"),v&&f&&setTimeout(()=>f.completeStateChange(v),0),{__target:"local",...k}}else throw v&&f&&f.completeStateChange(v),new Ut("setState function is not provided in context and globalStateUpdater is not set")}else if(r.startsWith("_local.")){const A=r.slice(7),{__mergeMode:L,__setStateId:$,...k}=x,O=k.value!==void 0?k.value:Object.values(k)[0];if(n.setState){const G=window.__g7PendingLocalState||n.state||{},B=this.createNestedUpdate(A,O,G),W={...G,...B};if(n.setState(B),this.globalStateUpdater&&i!=="parent"&&i!=="root"){const pe=window.__templateApp?.getGlobalState?.()?._local,Se=pe&&typeof pe=="object"?{...pe,...B}:W;this.globalStateUpdater({_local:Se},{render:!1}),j.log("[handleSetState] _global._local synced for dot notation (render:false):",Se)}return v&&f&&setTimeout(()=>f.completeStateChange(v),0),W}else throw v&&f&&f.completeStateChange(v),new Ut("setState function is not provided in context")}else{if(!n.setState)throw v&&f&&f.completeStateChange(v),new Ut("setState function is not provided in context");const L=window.__g7PendingLocalState||n.state||{},$=_==="deep"?this.deepMergeWithState(x,L):x;return n.setState($),v&&f&&setTimeout(()=>f.completeStateChange(v),0),$}}async handleParentScopeSetState(e,n,r,i){const l=Fn(),c=window.G7Core,d=r==="replace"?"replace":r==="shallow"?"shallow":"deep",f=e.startsWith("$parent."),h=f?"$parent.":"$root.",m=e.slice(h.length);let y,S;if(m==="_local"||m==="_global")y=m,S=void 0;else if(m.startsWith("_local."))y="_local",S=m.slice(7);else if(m.startsWith("_global."))y="_global",S=m.slice(8);else{j.warn(`[handleParentScopeSetState] 지원하지 않는 타겟 형식: ${e}. _local 또는 _global으로 시작해야 합니다.`);return}const v=window.__g7LayoutContextStack||[];if(v.length===0){j.warn(`[handleParentScopeSetState] 레이아웃 컨텍스트 스택이 비어있습니다. target=${e}`);return}const _=f?v[v.length-1]:v[0];if(!_){j.warn(`[handleParentScopeSetState] 타겟 컨텍스트를 찾을 수 없습니다. target=${e}`);return}const x=y==="_global"?_.state?._global:_.state?._local,A=l?.isEnabled()?l.startStateChange(e,x,n,{actionId:i.actionId,handlerType:"setState",source:`target=${e}`}):void 0,{__mergeMode:L,__setStateId:$,...k}=n;if(y==="_global"){if(!this.globalStateUpdater){j.warn("[handleParentScopeSetState] globalStateUpdater가 설정되지 않았습니다."),A&&l&&l.completeStateChange(A);return}const O=c?.state?.get()||{};if(S){const P=k.value!==void 0?k.value:Object.values(k)[0],G=this.createNestedUpdate(S,P,O),B={...O,...G};j.log(`[handleParentScopeSetState] ${e}: 전역 상태 중첩 경로 업데이트`,B),this.globalStateUpdater(B)}else{const P=d==="deep"?this.deepMergeWithState(k,O):k;j.log(`[handleParentScopeSetState] ${e}: 전역 상태 업데이트 (mergeMode=${d})`,P),this.globalStateUpdater(d!=="deep"?{...P,__mergeMode:d}:P)}return A&&l&&setTimeout(()=>l.completeStateChange(A),0),{__target:e,...k}}else{if(!_.setState){j.warn(`[handleParentScopeSetState] 타겟 컨텍스트에 setState가 없습니다. target=${e}`),A&&l&&l.completeStateChange(A);return}const O=_.state||{};if(S){const P=k.value!==void 0?k.value:Object.values(k)[0],G=this.createNestedUpdate(S,P,O),B={...O,...G};return j.log(`[handleParentScopeSetState] ${e}: 로컬 상태 중첩 경로 업데이트`,G),_.setState(G),_.state=B,_.dataContext&&(_.dataContext._local=B),wf(),A&&l&&setTimeout(()=>l.completeStateChange(A),0),B}else{const P=d!=="deep"?{...k,__mergeMode:d}:k,G=d==="replace"?k:d==="shallow"?{...O,...k}:this.deepMergeWithState(k,O);return j.log(`[handleParentScopeSetState] ${e}: 로컬 상태 업데이트 (mergeMode=${d})`,G),_.setState(P),_.state=G,_.dataContext&&(_.dataContext._local=G),wf(),A&&l&&setTimeout(()=>l.completeStateChange(A),0),G}}}deepMergeWithState(e,n){const r=["errors"];let i=e;if("..."in e){const c=e["..."];if(c&&typeof c=="object"&&!Array.isArray(c)){const{"...":d,...f}=e;i={...c,...f}}else{const{"...":d,...f}=e;i=f}}const l={...n};for(const[c,d]of Object.entries(i)){if(r.includes(c)){l[c]=d;continue}if(c.includes(".")&&c!=="..."){const f=this.createNestedUpdate(c,d,l);this.deepMergeInto(l,f,l);continue}if(d!==null&&typeof d=="object"&&!Array.isArray(d)&&Object.getPrototypeOf(d)!==Object.prototype&&Object.getPrototypeOf(d)!==null){l[c]=d;continue}d!==null&&typeof d=="object"&&!Array.isArray(d)&&n[c]!==null&&typeof n[c]=="object"&&!Array.isArray(n[c])?l[c]=this.deepMergeWithState(d,n[c]):l[c]=d}return l}deepMergeInto(e,n,r){for(const[i,l]of Object.entries(n)){if(l===null){e[i]=l;continue}if(e[i]===null){e[i]=l;continue}typeof l=="object"&&!Array.isArray(l)&&e[i]!==void 0&&e[i]!==null&&typeof e[i]=="object"&&!Array.isArray(e[i])?(e[i]===r[i]&&(e[i]={...e[i]}),this.deepMergeInto(e[i],l,r[i]||{})):typeof l=="object"&&!Array.isArray(l)&&e[i]===void 0&&r[i]!==null&&typeof r[i]=="object"&&!Array.isArray(r[i])?e[i]={...r[i],...l}:e[i]=l}}createNestedUpdate(e,n,r){const i=e.split(".");if(i.length===1)return{[i[0]]:n};const l={};let c=l,d=r;for(let f=0;f{this.globalStateUpdater({_local:v})};m.push({state:y,setState:S,dataContext:{_local:y||n.data?._local,_global:l?n.data?._global:n.data?._global||i?.state?.get?.(),_computed:n.data?._computed}}),window.__g7LayoutContextStack=m,j.log(`[handleOpenModal] 레이아웃 컨텍스트 스택에 push, 스택 크기: ${m.length}, state:`,y,l?"(direct)":"(fallback via G7Core)")}else j.warn(`[handleOpenModal] 컨텍스트 스택에 push 실패 - setState: ${!!n.setState}, state: ${n.state!==void 0}, G7Core: ${!!i?.state?.getLocal}`);const f=[...r,e];this.globalStateUpdater({modalStack:f,activeModal:e});const h=Fn();if(h?.isEnabled()){const m=r.length>0?r[r.length-1]:void 0;h.trackModalOpen?.({modalId:e,modalName:e,scopeType:"isolated",parentModalId:m,initialState:n.state?{...n.state}:{}})}}async handleCloseModal(e){if(!this.globalStateUpdater){j.warn("Global state updater is not set for closeModal");return}const n=e?.data?._global?.modalStack||[],r=n.length>0?n[n.length-1]:null,i=n.slice(0,-1),l=i.length>0?i[i.length-1]:null,c=window.__g7LayoutContextStack||[];if(c.length>0){const d=c[c.length-1];d&&(d.dataContext=void 0),c.pop(),window.__g7LayoutContextStack=c,j.log(`[handleCloseModal] 레이아웃 컨텍스트 스택에서 pop, 스택 크기: ${c.length}`)}if(r){const d=Fn();d?.isEnabled()&&d.trackModalClose?.(r,e?.state)}this.globalStateUpdater({modalStack:i,activeModal:l})}async handleShowAlert(e,n){let r=e;this.translationEngine&&this.translationContext&&e.startsWith("$t:")&&(r=this.translationEngine.resolveTranslations(e,this.translationContext,n.data)),alert(r)}async handleToast(e,n){const{type:r="info",message:i,icon:l,duration:c}=e;if(r==="error"){const f=n.data?.error;if((f?.error_code==="identity_verification_required"||f?.data?.error_code==="identity_verification_required")&&St.consumeDomainNoticeShown()){j.log("[Toast] IDV 도메인 안내 표출됨 — 중복 가드 토스트 1건 skip");return}}let d=i;if(this.translationEngine&&this.translationContext&&i?.startsWith("$t:")&&(d=this.translationEngine.resolveTranslations(i,this.translationContext,n.data)),this.globalStateUpdater){const h={id:`toast_${Date.now()}_${Math.random().toString(36).substring(2,9)}`,type:r,message:d,...l&&{icon:l},...c&&{duration:c}},v=[...window.G7Core?.state?.get()?.toasts||[],h];this.globalStateUpdater({toasts:v})}else j.log(`[Toast ${r}] ${d}`)}async handleSwitch(e,n){const{cases:r}=e;if(!r){j.warn("switch handler requires cases property");return}const i=this.resolveParams(e.params,n.data);let l;if(i?.value!==void 0?(l=i.value,j.log("switch handler: using params.value as case key:",l)):(l=n.data?.$args?.[0],j.log("switch handler: using $args[0] as case key:",l)),l==null){if(r.default)return j.log("switch handler: case key is undefined, using default case"),await this.executeAction(r.default,n);j.warn("switch handler: case key is not defined and no default case");return}const c=String(l);let d=r[c];if(!d&&r.default&&(j.log(`switch handler: no case found for key "${c}", using default case`),d=r.default),!d){j.warn(`switch handler: no case found for key "${c}" and no default case`);return}return await this.executeAction(d,n)}async handleConditions(e,n){const{conditions:r}=e;if(!r||!Array.isArray(r)){j.warn("conditions handler requires conditions array");return}const i=n.data||{},l=tm(r,i,this.bindingEngine);if(!l.matched){j.log("conditions handler: no matching branch found");return}const c=r[l.branchIndex];if(j.log(`conditions handler: matched branch ${l.branchIndex}`),!c.then){j.warn('conditions handler: matched branch has no "then" action');return}return Array.isArray(c.then)?await this.handleSequence({...e,actions:c.then},n):await this.executeAction(c.then,n)}handleStartInterval(e,n){const r=typeof e.id=="string"?e.id:"",i=Number(e.intervalMs??1e3),l=Array.isArray(e.actions)?e.actions:[];if(r===""||!l.length||i<=0)return j.warn("startInterval requires non-empty id, positive intervalMs, and actions array"),{success:!1};const c=this.intervals.get(r);c&&(clearInterval(c),this.intervals.delete(r));const d=setInterval(()=>{for(const f of l)this.executeAction(f,n).catch(h=>{j.error(`[startInterval:${r}] tick action failed`,h)})},i);return this.intervals.set(r,d),{success:!0,id:r}}handleStopInterval(e){const n=typeof e.id=="string"?e.id:"";if(n==="")return j.warn("stopInterval requires id parameter"),{success:!1};const r=this.intervals.get(n);return r&&(clearInterval(r),this.intervals.delete(n)),{success:!0,id:n}}stopAllIntervals(){for(const e of this.intervals.values())clearInterval(e);this.intervals.clear()}async handleSequence(e,n){const r=e.actions||e.params?.actions;if(!r||!Array.isArray(r)||r.length===0)return j.warn("sequence handler requires non-empty actions array"),[];const i=Fn(),l=i?.isEnabled()&&i.startSequenceExecution?.({eventType:e.type})||"";window.__g7SequenceLocalSync=void 0;const c=[];let d,f=n.state?{...n.state}:{},h=n.isolatedContext?.state?{...n.isolatedContext.state}:{},m=n.data?._computed||{};const y=window.G7Core,S=()=>({_global:y?.state?.get()||{},_local:{...f},_isolated:Object.keys(h).length>0?{...h}:void 0});for(let v=0;v0){const k={},O={...n.data,_local:f,_computed:k,$computed:k,_isolated:h};for(const[P,G]of Object.entries($))if(typeof G=="string"){const B=G.trim();if(B.startsWith("{{")&&B.endsWith("}}"))try{const W=B.slice(2,-2).trim();k[P]=Gn(W)?this.bindingEngine.evaluatePipeExpression(W,O,{skipCache:!0}):this.bindingEngine.evaluateExpression(W,O,{skipCache:!0})}catch{k[P]=m[P]}}m=k,j.log("[handleSequence] _computed recalculated after setState:",m)}}if(_.handler!=="setState"){const $=window.__g7SequenceLocalSync;if($&&$!==f){f=$,window.__g7SequenceLocalSync=void 0,j.log("[handleSequence] currentState synchronized from __g7SequenceLocalSync after custom handler:",_.handler);const k=n.data?._computedDefinitions;if(k&&Object.keys(k).length>0){const O={},P={...n.data,_local:f,_computed:O,$computed:O,_isolated:h};for(const[G,B]of Object.entries(k))if(typeof B=="string"){const W=B.trim();if(W.startsWith("{{")&&W.endsWith("}}"))try{const pe=W.slice(2,-2).trim();O[G]=Gn(pe)?this.bindingEngine.evaluatePipeExpression(pe,P,{skipCache:!0}):this.bindingEngine.evaluateExpression(pe,P,{skipCache:!0})}catch{O[G]=m[G]}}m=O,j.log("[handleSequence] _computed recalculated after custom handler:",m)}}}l&&i?.isEnabled()&&i.captureSequenceActionAfter?.(l,v,S(),Date.now()-x,L.data)}catch(L){throw l&&i?.isEnabled()&&(i.captureSequenceActionAfter?.(l,v,S(),Date.now()-x,void 0,L),i.endSequenceExecution?.(l,L)),j.error(`sequence handler: action[${v}] failed:`,L),L}}return window.__g7SequenceLocalSync=void 0,l&&i?.isEnabled()&&i.endSequenceExecution?.(l),c}async handleParallel(e,n){const r=e.actions||e.params?.actions;if(!r||!Array.isArray(r)||r.length===0)return j.warn("parallel handler requires non-empty actions array"),[];j.log(`parallel handler: executing ${r.length} actions in parallel`);const i=n.isolatedContext?{...n.isolatedContext,state:{...n.isolatedContext.state}}:null,l=r.map((f,h)=>{const m={...n,isolatedContext:i};return this.executeAction(f,m).catch(y=>{throw j.error(`parallel handler: action[${h}] failed:`,y),y})}),c=await Promise.allSettled(l),d=c.filter(f=>f.status==="rejected").length;return d>0&&j.warn(`parallel handler: ${d}/${r.length} actions failed`),c}async handleLoadScript(e,n,r){const{src:i,id:l,async:c=!0,defer:d=!1}=e;if(!i)throw new Ut('loadScript handler requires "src" parameter',n);const f=l||`script_${i.replace(/[^a-zA-Z0-9]/g,"_")}`;return xs.loadedScripts.has(f)?(j.log(`loadScript: script already loaded, skipping: ${f}`),n.onLoad&&await this.executeAction(n.onLoad,r),!0):document.getElementById(f)?(j.log(`loadScript: script element already exists: ${f}`),xs.loadedScripts.add(f),n.onLoad&&await this.executeAction(n.onLoad,r),!0):(j.log(`loadScript: loading script: ${i}`),new Promise((m,y)=>{const S=document.createElement("script");S.id=f,S.src=i,S.async=c,S.defer=d,S.onload=async()=>{if(j.log(`loadScript: script loaded successfully: ${f}`),xs.loadedScripts.add(f),n.onLoad)try{await this.executeAction(n.onLoad,r)}catch(v){j.error("loadScript: onLoad action failed:",v)}m(!0)},S.onerror=v=>{j.error(`loadScript: failed to load script: ${i}`,v),y(new Ut(`Failed to load script: ${i}`,n))},document.head.appendChild(S)}))}async handleCallExternal(e,n,r){const i=e.constructor,l=e.args||{},c=e.method,d=e.methodArgs||[],f=e.callbackEvent,h=e.embedTarget,m=e.callbackSetState,y=e.callbackAction;if(!i)throw new Ut('callExternal handler requires "constructor" parameter',n);const S=this.getNestedProperty(window,i);if(!S||typeof S!="function")throw new Ut(`Constructor not found or not a function: ${i}. Make sure the script is loaded first using loadScript handler.`,n);j.log(`callExternal: calling constructor ${i}`);const v={...l};for(const[x,A]of Object.entries(l))A===!0&&(v[x]=L=>{if(j.log(`callExternal: callback triggered for ${x}`,L),f&&typeof window<"u"&&window.G7Core?.componentEvent&&window.G7Core.componentEvent.emit(f,L),m&&r.setState){const $=P=>{const G={};for(const[B,W]of Object.entries(P))typeof W=="string"?G[B]=this.getNestedProperty(L,W):typeof W=="object"&&W!==null&&(G[B]=$(W));return G},k=$(m);j.log("callExternal: callbackSetState mapping result",k);const O=this.deepMergeWithState(k,r.state||{});j.log("callExternal: merged with existing state",O),r.setState(O)}else f&&r.setState&&r.setState({[`${f.replace(/:/g,"_")}_result`]:L});if(y){const $={...r,data:{...r.data,$event:L}},k=Array.isArray(y)?y:[y];for(const O of k)try{this.executeAction(O,$)}catch(P){j.error("callExternal: callbackAction failed:",P)}}});const _=new S(v);if(c&&typeof _[c]=="function"){if(j.log(`callExternal: calling method ${c}`),c==="embed"&&h){const x=document.querySelector(h);if(x)return _[c](x,...d);throw new Ut(`Embed target element not found: ${h}`,n)}return _[c](...d)}return _}async handleCallExternalEmbed(e,n,r){const i=e.constructor,l=e.args||{},c=e.callbackSetState,d=e.callbackEvent,f=e.layerClassName,h=e.callbackAction;if(!i)throw new Ut('callExternalEmbed handler requires "constructor" parameter',n);const m=this.getNestedProperty(window,i);if(!m||typeof m!="function")throw new Ut(`Constructor not found or not a function: ${i}. Make sure the script is loaded first.`,n);j.log(`callExternalEmbed: creating layer for ${i}`);const{layer:y,closeLayer:S}=this.createEmbedLayer(f),v={...l};for(const[x,A]of Object.entries(l))A===!0&&(v[x]=L=>{if(j.log(`callExternalEmbed: callback triggered for ${x}`,L),S(),d&&typeof window<"u"&&window.G7Core?.componentEvent&&window.G7Core.componentEvent.emit(d,L),c&&r.setState){const $=P=>{const G={};for(const[B,W]of Object.entries(P))typeof W=="string"?G[B]=this.getNestedProperty(L,W):typeof W=="object"&&W!==null&&(G[B]=$(W));return G},k=$(c);j.log("callExternalEmbed: callbackSetState mapping result",k);const O=this.deepMergeWithState(k,r.state||{});j.log("callExternalEmbed: merged with existing state",O),r.setState(O)}if(h){const $={...r,data:{...r.data,$event:L}},k=Array.isArray(h)?h:[h];for(const O of k)try{this.executeAction(O,$)}catch(P){j.error("callExternalEmbed: callbackAction failed:",P)}}});const _=new m(v);if(typeof _.embed=="function")_.embed(y),j.log("callExternalEmbed: embedded in layer");else throw S(),new Ut(`Constructor ${i} does not have embed method`,n);return _}isImeComposing(e){return e?.isComposing===!0||e?.keyCode===229}createEmbedLayer(e){const n=document.createElement("div");n.id="g7-embed-overlay",n.style.cssText=` +`+l)}}catch{}}throw r}}_request(e,n){typeof e=="string"?(n=n||{},n.url=e):n=e||{},n=Ci(this.defaults,n);const{transitional:r,paramsSerializer:i,headers:l}=n;r!==void 0&&dc.assertOptions(r,{silentJSONParsing:ar.transitional(ar.boolean),forcedJSONParsing:ar.transitional(ar.boolean),clarifyTimeoutError:ar.transitional(ar.boolean),legacyInterceptorReqResOrdering:ar.transitional(ar.boolean)},!1),i!=null&&(K.isFunction(i)?n.paramsSerializer={serialize:i}:dc.assertOptions(i,{encode:ar.function,serialize:ar.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),dc.assertOptions(n,{baseUrl:ar.spelling("baseURL"),withXsrfToken:ar.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let c=l&&K.merge(l.common,l[n.method]);l&&K.forEach(["delete","get","head","post","put","patch","query","common"],_=>{delete l[_]}),n.headers=Rn.concat(c,l);const d=[];let f=!0;this.interceptors.request.forEach(function(x){if(typeof x.runWhen=="function"&&x.runWhen(n)===!1)return;f=f&&x.synchronous;const A=n.transitional||of;A&&A.legacyInterceptorReqResOrdering?d.unshift(x.fulfilled,x.rejected):d.push(x.fulfilled,x.rejected)});const h=[];this.interceptors.response.forEach(function(x){h.push(x.fulfilled,x.rejected)});let m,y=0,S;if(!f){const _=[Hm.bind(this),void 0];for(_.unshift(...d),_.push(...h),S=_.length,m=Promise.resolve(n);y{if(!r._listeners)return;let l=r._listeners.length;for(;l-- >0;)r._listeners[l](i);r._listeners=null}),this.promise.then=i=>{let l;const c=new Promise(d=>{r.subscribe(d),l=d}).then(i);return c.cancel=function(){r.unsubscribe(l)},c},e(function(l,c,d){r.reason||(r.reason=new Ao(l,c,d),n(r.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const n=this._listeners.indexOf(e);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const e=new AbortController,n=r=>{e.abort(r)};return this.subscribe(n),e.signal.unsubscribe=()=>this.unsubscribe(n),e.signal}static source(){let e;return{token:new Rw(function(i){e=i}),cancel:e}}};function nE(s){return function(n){return s.apply(null,n)}}function rE(s){return K.isObject(s)&&s.isAxiosError===!0}const pf={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(pf).forEach(([s,e])=>{pf[e]=s});function Um(s){const e=new Ei(s),n=om(Ei.prototype.request,e);return K.extend(n,Ei.prototype,e,{allOwnKeys:!0}),K.extend(n,e,null,{allOwnKeys:!0}),n.create=function(i){return Um(Ci(s,i))},n}const Vt=Um(_o);Vt.Axios=Ei,Vt.CanceledError=Ao,Vt.CancelToken=tE,Vt.isCancel=Am,Vt.VERSION=df,Vt.toFormData=oc,Vt.AxiosError=Oe,Vt.Cancel=Vt.CanceledError,Vt.all=function(e){return Promise.all(e)},Vt.spread=nE,Vt.isAxiosError=rE,Vt.mergeConfig=Ci,Vt.AxiosHeaders=Rn,Vt.formToJSON=s=>_m(K.isHTMLForm(s)?new FormData(s):s),Vt.getAdapter=jm.getAdapter,Vt.HttpStatusCode=pf,Vt.default=Vt;const{Axios:Nk,AxiosError:Ik,CanceledError:jk,isCancel:Hk,CancelToken:zk,VERSION:Uk,all:Pk,Cancel:Bk,isAxiosError:qk,spread:Gk,toFormData:Fk,AxiosHeaders:Vk,HttpStatusCode:Kk,formToJSON:Wk,getAdapter:Yk,mergeConfig:Xk,create:Jk}=Vt,gf="g7.identity.redirectStash",fc=dt("IdentityGuardInterceptor");class St{static setLauncher(e){this.launcher=e}static hasLauncher(){return this.launcher!==null}static markDomainNoticeShown(){this.domainNoticeShown=!0}static consumeDomainNoticeShown(){const e=this.domainNoticeShown;return this.domainNoticeShown=!1,e}static resolveDeferred(e){const n=this.deferredResolver;if(!n){fc.warn("IdentityGuardInterceptor.resolveDeferred 호출됐지만 대기 중인 launcher 가 없습니다. 모달이 launcher 외부에서 열렸는지 확인하세요.");return}this.deferredResolver=null,n(e)}static createDeferred(){if(this.deferredResolver){const e=this.deferredResolver;this.deferredResolver=null,e({status:"cancelled"})}return new Promise(e=>{this.deferredResolver=e})}static isIdentityRequired(e,n){return e===428&&typeof n=="object"&&n!==null&&n.error_code==="identity_verification_required"}static async handle(e,n,r){this.domainNoticeShown=!1;const i=this.launcher??iE,c=!!(r&&(r.email||r.phone))?{...e.verification,target:r}:e.verification,d=await i(c);if(d.status!=="verified")return null;const f=c.return_request;if(!f)return null;const h=aE(f.url,d.token);return fetch(h,{method:f.method,headers:n?.headers??{Accept:"application/json","Content-Type":"application/json"},body:n?.body,credentials:n?.credentials??"same-origin"})}static redirectExternally(e){const n=e.redirect_url;if(!n)return fc.error("redirectExternally 호출 시 verification.redirect_url 이 없습니다. payload:",e),Promise.resolve({status:"failed",failureCode:"MISSING_REDIRECT_URL",reason:"verification.redirect_url is required for external_redirect flow"});if(typeof window<"u"){const r={return_url:window.location.href,payload:e,stashed_at:Date.now()};try{window.sessionStorage?.setItem(gf,JSON.stringify(r))}catch(i){fc.warn("sessionStorage 접근 실패 — stash 없이 redirect 합니다.",i)}window.location.href=n}return new Promise(()=>{})}static reset(){if(this.deferredResolver){const e=this.deferredResolver;this.deferredResolver=null;try{e({status:"cancelled"})}catch{}}this.launcher=null,this.domainNoticeShown=!1}}M(St,"launcher",null),M(St,"deferredResolver",null),M(St,"domainNoticeShown",!1);function aE(s,e){if(!e)return s;try{const n=typeof window<"u"?window.location.origin:"http://localhost",r=new URL(s,n);return r.searchParams.set("verification_token",e),/^https?:\/\//i.test(s)?r.toString():`${r.pathname}${r.search}${r.hash}`}catch{const n=s.includes("?")?"&":"?";return`${s}${n}verification_token=${encodeURIComponent(e)}`}}const iE=async s=>{if(typeof window>"u")return{status:"cancelled"};if(s.render_hint==="external_redirect"||s.redirect_url)return St.redirectExternally(s);const e=window.G7Core;if(!e?.dispatch)return console.error("[IdentityGuardInterceptor] defaultLauncher: G7Core 가 초기화되지 않아 본인인증 흐름을 시작할 수 없습니다."),{status:"failed",failureCode:"G7_NOT_READY"};try{await e.dispatch({handler:"toast",params:{message:"본인 확인이 필요합니다.",variant:"warning"}})}catch{}const n=window.location.href,r={return_url:n,payload:s,stashed_at:Date.now()};try{window.sessionStorage?.setItem(gf,JSON.stringify(r))}catch{}const i=`/identity/challenge?return=${encodeURIComponent(n)}`;try{await e.dispatch({handler:"navigate",params:{path:i}})}catch(l){fc.warn("navigate 실패 — window.location 으로 폴백",l),window.location.href=i}return new Promise(()=>{})},sE=dt("ApiClient");function mf(){return typeof window<"u"&&window.__G7_DEVTOOLS__?window.__G7_DEVTOOLS__:null}class oE{constructor(e={}){M(this,"client");M(this,"config");M(this,"TOKEN_KEY","auth_token");this.config={baseURL:e.baseURL||"/api",timeout:e.timeout||3e4,onTokenExpired:e.onTokenExpired,onUnauthorized:e.onUnauthorized,onError:e.onError},this.client=Vt.create({baseURL:this.config.baseURL,timeout:this.config.timeout,headers:{"Content-Type":"application/json",Accept:"application/json"},paramsSerializer:{serialize:n=>{const r=[];for(const[i,l]of Object.entries(n))if(l!=null)if(Array.isArray(l)){const c=i.endsWith("[]")?i:`${i}[]`;for(const d of l)r.push(`${encodeURIComponent(c)}=${encodeURIComponent(String(d))}`)}else r.push(`${encodeURIComponent(i)}=${encodeURIComponent(String(l))}`);return r.join("&")}}}),this.setupInterceptors()}setToken(e){typeof window<"u"&&localStorage.setItem(this.TOKEN_KEY,e)}getToken(){return typeof window<"u"?localStorage.getItem(this.TOKEN_KEY):null}removeToken(){typeof window<"u"&&localStorage.removeItem(this.TOKEN_KEY)}setupInterceptors(){this.client.interceptors.request.use(e=>{e.url?.startsWith("/api")&&e.baseURL==="/api"&&(e.baseURL="");const n=this.getToken();if(n&&e.headers&&!this.isCrossOriginRequest(e.url)&&(e.headers.Authorization=`Bearer ${n}`),typeof window<"u"&&e.headers){const i=localStorage.getItem("g7_locale");i&&(e.headers["Accept-Language"]=i)}const r=mf();if(r?.isEnabled()){const i=this.buildFullUrl(e),l=(e.method||"GET").toUpperCase(),c=r.trackRequest(i,l,{requestBody:e.data});e._devToolsRequestId=c}return e},e=>Promise.reject(e)),this.client.interceptors.response.use(e=>{const n=e.config,r=n._devToolsRequestId;if(r){const i=mf();i?.isEnabled()&&i.completeRequest(r,e.status,e.data),n._devToolsRequestId=null}return e},async e=>{const n=e.config,r=n?.url||"",l=["/auth/","/layouts/"].some(c=>r.includes(c));if(e.response?.status===401&&!n?._retry&&!l){if(n._retry=!0,await wr.getInstance().refreshToken()){const f=this.getToken();return f&&(n.headers.Authorization=`Bearer ${f}`),n._devToolsRequestId=null,this.client(n)}return this.completeDevToolsRequest(n,e),this.removeToken(),this.config.onUnauthorized&&this.config.onUnauthorized(),Promise.reject(e)}if(e.response?.status===401&&l)return this.completeDevToolsRequest(n,e),Promise.reject(e);if(St.isIdentityRequired(e.response?.status,e.response?.data)){this.completeDevToolsRequest(n,e);const c={},d=n?.headers??{};for(const[S,v]of Object.entries(d))typeof v=="string"&&(c[S]=v);let f;n?.data!==void 0&&n?.data!==null&&(f=typeof n.data=="string"?n.data:JSON.stringify(n.data),c["Content-Type"]=c["Content-Type"]??"application/json");const h=n?.identity_target,m=await St.handle(e.response.data,{headers:c,body:f,credentials:"same-origin"},h);if(!m)return Promise.reject(e);let y=null;try{y=await m.json()}catch{y=null}return m.ok?{...e.response,status:m.status,data:y}:Promise.reject(Object.assign(new Error("replay failed"),{response:{status:m.status,data:y}}))}return e.response?.status===403?(this.completeDevToolsRequest(n,e),this.callOnError(e),Promise.reject(e)):(this.completeDevToolsRequest(n,e),e.response&&this.callOnError(e),Promise.reject(e))})}async get(e,n){return(await this.client.get(e,n)).data}async post(e,n,r){return(await this.client.post(e,n,r)).data}async put(e,n,r){return(await this.client.put(e,n,r)).data}async patch(e,n,r){return(await this.client.patch(e,n,r)).data}async delete(e,n){return(await this.client.delete(e,n)).data}getInstance(){return this.client}setOnUnauthorized(e){this.config.onUnauthorized=e}setOnError(e){this.config.onError=e}completeDevToolsRequest(e,n){if(!e?._devToolsRequestId)return;const r=mf();if(!r?.isEnabled())return;const i=e._devToolsRequestId;e._devToolsRequestId=null,n.response?r.completeRequest(i,n.response.status,n.response.data):n.request?r.failRequest(i,n.message||"Network error"):r.failRequest(i,n.message||"Request error")}isCrossOriginRequest(e){if(!e||typeof window>"u"||!window.location||!/^(https?:)?\/\//i.test(e))return!1;try{return new URL(e,window.location.href).origin!==window.location.origin}catch{return!1}}buildFullUrl(e){let n=e.url||"";if(e.baseURL&&!n.startsWith("http")&&(n=`${e.baseURL}${n.startsWith("/")?"":"/"}${n}`),e.params&&typeof e.params=="object"){const r=e.params,i=[];for(const[l,c]of Object.entries(r))if(c!=null)if(Array.isArray(c)){const d=l.endsWith("[]")?l:`${l}[]`;for(const f of c)i.push(`${encodeURIComponent(d)}=${encodeURIComponent(String(f))}`)}else i.push(`${encodeURIComponent(l)}=${encodeURIComponent(String(c))}`);i.length>0&&(n+=(n.includes("?")?"&":"?")+i.join("&"))}return n}callOnError(e){if(!this.config.onError)return;const n={status:e.response?.status||0,message:e.response?.data?.message||e.message||"Unknown error",data:e.response?.data,statusText:e.response?.statusText};try{this.config.onError(n)}catch(r){sE.error("Error in onError handler:",r)}}}let yf=null;function zr(){return yf||(yf=new oE),yf}const xo=dt("AuthManager");function fs(s,e,n,r){try{window.G7Core?.devTools?.trackAuthEvent?.(s,e,n,r)}catch{}}const hc={admin:{type:"admin",loginPath:"/admin/login",defaultPath:"/admin",userEndpoint:"/admin/auth/user",loginEndpoint:"/auth/admin/login",logoutEndpoint:"/admin/auth/logout",refreshEndpoint:"/admin/auth/refresh"},user:{type:"user",loginPath:"/login",defaultPath:"/",userEndpoint:"/auth/user",loginEndpoint:"/auth/login",logoutEndpoint:"/auth/logout",refreshEndpoint:"/auth/refresh"}},kr=class kr{constructor(){M(this,"state");M(this,"config");M(this,"isRefreshing",!1);M(this,"refreshPromise",null);M(this,"eventHandlers",new Map);this.state={isAuthenticated:!1,user:null,type:null},this.config=new Map,this.config.set("admin",hc.admin),this.config.set("user",hc.user)}static getInstance(){return kr.instance||(kr.instance=new kr),kr.instance}on(e,n){this.eventHandlers.has(e)||this.eventHandlers.set(e,[]),this.eventHandlers.get(e).push(n)}emit(e,...n){const r=this.eventHandlers.get(e);r&&r.forEach(i=>i(...n))}isAuthenticated(){return this.state.isAuthenticated}getUser(){return this.state.user}getAuthType(){return this.state.type}async checkAuth(e){const n=zr();if(!n.getToken())return this.clearState(),!1;const i=this.config.get(e);if(!i)return xo.error(`Unknown auth type: ${e}`),!1;try{const l=await n.get(i.userEndpoint);return l.success&&l.data?(this.state={isAuthenticated:!0,user:l.data,type:e},this.emit("authStateChange",this.state),!0):(this.clearState(),!1)}catch(l){return l.response?.status===401&&await this.refreshToken()?this.checkAuth(e):(this.clearState(),!1)}}async preloadAuth(e){try{return await this.checkAuth(e)}catch(n){return xo.warn(`Preload auth failed for type ${e}:`,n),!1}}async login(e,n,r){const i=zr();if(!this.config.get(e))throw new Error(`Unknown auth type: ${e}`);const c=e==="admin"?hc.admin.loginEndpoint:hc.user.loginEndpoint;try{const d=r?.headers?{headers:r.headers}:void 0,f=await i.post(c,n,d);if(f.success&&f.data){i.setToken(f.data.token);const h=f.data.user.language,m=localStorage.getItem(kr.LOCALE_STORAGE_KEY),y=h&&h!==m;if(h)try{localStorage.setItem(kr.LOCALE_STORAGE_KEY,h)}catch(S){xo.warn("Failed to save user language to localStorage:",S)}return this.state={isAuthenticated:!0,user:f.data.user,type:e},this.emit("login",this.state),this.emit("authStateChange",this.state),fs("login",!0,void 0,{userId:f.data.user.uuid,email:f.data.user.email,type:e}),y&&window.__templateApp&&window.__templateApp.changeLocale(h),f.data.user}throw new Error("Login failed")}catch(d){this.clearState();const f=d.response?.data?.message,h=new Error(f||d.message||"Login failed");throw h.response=d.response,h.status=d.response?.status,fs("login",!1,h.message,{type:e,status:d.response?.status}),h}}async logout(){const e=zr(),n=this.state.type?this.config.get(this.state.type):null;try{n&&await e.post(n.logoutEndpoint)}catch(r){xo.warn("Logout API call failed:",r)}finally{e.removeToken();const r={...this.state};if(this.clearState(),this.emit("logout",r),this.emit("authStateChange",this.state),fs("logout",!0,void 0,{previousType:r.type}),n&&r.type){const i=window.location.pathname+window.location.search;window.location.href=this.getLoginRedirectUrl(r.type,i)}}}async refreshToken(){if(this.isRefreshing&&this.refreshPromise)return this.refreshPromise;this.isRefreshing=!0,this.refreshPromise=this.doRefreshToken();try{return await this.refreshPromise}finally{this.isRefreshing=!1,this.refreshPromise=null}}async doRefreshToken(){const e=this.state.type;if(!e)return!1;const n=this.config.get(e);if(!n)return!1;const r=zr();try{const i=await r.post(n.refreshEndpoint);return i.success&&i.data?.token?(r.setToken(i.data.token),this.emit("tokenRefreshed"),fs("token-refresh",!0,void 0,{type:e}),!0):(fs("token-refresh",!1,"No token in response",{type:e}),!1)}catch(i){return xo.error("Token refresh failed:",i),fs("token-refresh",!1,i instanceof Error?i.message:"Unknown error",{type:e}),!1}}getLoginRedirectUrl(e,n,r){const i=this.config.get(e);if(!i)return"/login";const l=encodeURIComponent(n);let c=`${i.loginPath}?redirect=${l}`;return r&&(c+=`&reason=${encodeURIComponent(r)}`),c}updateConfig(e,n){if(n.loginPath!==void 0){const i=n.loginPath;if(!i.startsWith("/")||i.startsWith("//"))throw new Error(`AuthManager.updateConfig: loginPath must be a same-origin path starting with '/' (got: ${i})`)}const r=this.config.get(e);r&&this.config.set(e,{...r,...n})}getRedirectUrl(e){const r=this.config.get(e)?.defaultPath||"/",l=new URLSearchParams(window.location.search).get("redirect");if(l)try{const c=decodeURIComponent(l);if(c.startsWith("/"))return c}catch{}return r}getConfig(e){return this.config.get(e)}clearState(){this.state={isAuthenticated:!1,user:null,type:null}}static resetInstance(){kr.instance=null}};M(kr,"instance"),M(kr,"LOCALE_STORAGE_KEY","g7_locale");let wr=kr;const Pm={401:{handler:"navigate",params:{path:"{{auth.loginPath}}"}},403:{handler:"toast",params:{type:"error",message:"{{error.message}}"}},404:{handler:"toast",params:{type:"error",message:"{{error.message}}"}},422:{handler:"toast",params:{type:"error",message:"{{error.message}}"}},default:{handler:"toast",params:{type:"error",message:"{{error.message}}"}}},aa={findHandler(s,e){if(s){if(s[e])return s[e];if(s[String(e)])return s[String(e)];if(s.default)return s.default}},normalizeOnError(s){return s?Array.isArray(s)?s:[s]:[]},injectErrorCode(s,e,n){if(s.handler!=="showErrorPage"||s.params?.errorCode!==void 0)return s;const r=typeof e=="string"?parseInt(e,10):e,i=isNaN(r)?n:r;return i===void 0?s:{...s,params:{...s.params,errorCode:i}}}},Cr=dt("ErrorHandlingResolver"),Ha=class Ha{constructor(){M(this,"templateErrorHandling",null);M(this,"layoutErrorHandling",null);M(this,"executeAction",null)}static getInstance(){return Ha.instance||(Ha.instance=new Ha),Ha.instance}static resetInstance(){Ha.instance=null}setTemplateConfig(e){this.templateErrorHandling=e,Cr.log("Template config set:",e)}setLayoutConfig(e){this.layoutErrorHandling=e,Cr.log("Layout config set:",e)}setActionExecutor(e){this.executeAction=e}resolve(e,n={}){const{errorHandling:r,onError:i}=n;Cr.log("Resolving error:",e,{hasActionErrorHandling:!!r,hasActionOnError:!!i,hasLayoutConfig:!!this.layoutErrorHandling,hasTemplateConfig:!!this.templateErrorHandling});let l=aa.findHandler(r,e);if(l){const c=this.getMatchedKey(r,e);return{handler:aa.injectErrorCode(l,c,e),level:"action",matchedKey:c}}if(i){const c=aa.normalizeOnError(i);if(c.length>0)return{handler:c.length===1?c[0]:{handler:"sequence",actions:c},level:"action",matchedKey:"onError"}}if(l=aa.findHandler(this.layoutErrorHandling||void 0,e),l){const c=this.getMatchedKey(this.layoutErrorHandling,e);return{handler:aa.injectErrorCode(l,c,e),level:"layout",matchedKey:c}}if(l=aa.findHandler(this.templateErrorHandling||void 0,e),l){const c=this.getMatchedKey(this.templateErrorHandling,e);return{handler:aa.injectErrorCode(l,c,e),level:"template",matchedKey:c}}if(l=aa.findHandler(Pm,e),l){const c=this.getMatchedKey(Pm,e);return{handler:aa.injectErrorCode(l,c,e),level:"system",matchedKey:c}}return{handler:null,level:null,matchedKey:null}}async execute(e,n){if(!this.executeAction){Cr.error("Action executor is not set");return}Cr.log("Executing handler:",e.handler,{errorContext:n});try{return await this.executeAction(e,{error:n})}catch(r){throw Cr.error("Failed to execute handler:",r),r}}async resolveAndExecute(e,n,r={}){const i=this.resolve(e,r);if(Cr.log("Resolve result:",{errorCode:e,handler:i.handler?.handler,level:i.level,matchedKey:i.matchedKey}),!i.handler)return Cr.warn("No handler found for error:",e),{handled:!1};try{return{handled:!0,result:await this.execute(i.handler,n)}}catch(l){return Cr.error("Handler execution failed:",l),{handled:!1}}}getMatchedKey(e,n){return e[n]?n:e[String(n)]?String(n):"default"}clearLayoutConfig(){this.layoutErrorHandling=null,Cr.log("Layout config cleared")}clearAllConfig(){this.templateErrorHandling=null,this.layoutErrorHandling=null,Cr.log("All config cleared")}getConfigStatus(){return{hasTemplate:this.templateErrorHandling!==null,hasLayout:this.layoutErrorHandling!==null,hasExecutor:this.executeAction!==null}}};M(Ha,"instance",null);let bf=Ha;function Er(){return bf.getInstance()}var vf={exports:{}},To={};var Bm;function lE(){if(Bm)return To;Bm=1;var s=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function n(r,i,l){var c=null;if(l!==void 0&&(c=""+l),i.key!==void 0&&(c=""+i.key),"key"in i){l={};for(var d in i)d!=="key"&&(l[d]=i[d])}else l=i;return i=l.ref,{$$typeof:s,type:r,key:c,ref:i!==void 0?i:null,props:l}}return To.Fragment=e,To.jsx=n,To.jsxs=n,To}var qm;function cE(){return qm||(qm=1,vf.exports=lE()),vf.exports}var ft=cE();const uE=ea({__proto__:null,default:ta(ft)},[ft]),Sf=dt("ParentContextProvider"),Gm=N.createContext(null);let pc=null;function wf(){pc?(Sf.log("[triggerModalParentUpdate] 모달 부모 컨텍스트 업데이트 트리거"),pc()):Sf.warn("[triggerModalParentUpdate] Provider가 아직 마운트되지 않음")}const Fm=({children:s})=>{const[e,n]=N.useState(0),r=N.useRef(!0),i=N.useCallback(()=>{const c=window.__g7LayoutContextStack||[];return c[c.length-1]?.dataContext},[]);N.useEffect(()=>(r.current=!0,pc=()=>{r.current&&(n(c=>c+1),Sf.log("[ParentContextProvider] 버전 업데이트됨"))},()=>{r.current=!1,pc=null}),[]);const l={version:e,getParentDataContext:i};return ft.jsx(Gm.Provider,{value:l,children:s})};function dE(){return N.useContext(Gm)}const j=dt("ActionDispatcher");function fE(s,e,n,r){return n||(jg(s)||Od(s)?"$t:core.errors.network_request_failed":r||`Failed to execute action: ${e}`)}const Vm=new Set(["navigate","navigateBack","navigateForward","replaceUrl","refresh","logout"]),hE=new Set(["redirect"]);function Fn(){try{return window.G7Core?.devTools}catch{return}}class Ut extends Error{constructor(n,r,i){super(n);M(this,"action");M(this,"originalError");M(this,"unknownHandler",!1);this.action=r,this.originalError=i,this.name="ActionError"}}const Km={click:"onClick",change:"onChange",input:"onInput",submit:"onSubmit",focus:"onFocus",blur:"onBlur",keydown:"onKeyDown",keyup:"onKeyUp",keypress:"onKeyPress",mousedown:"onMouseDown",mouseup:"onMouseUp",mouseenter:"onMouseEnter",mouseleave:"onMouseLeave",scroll:"onScroll",dragstart:"onDragStart",drag:"onDrag",dragend:"onDragEnd",dragenter:"onDragEnter",dragover:"onDragOver",dragleave:"onDragLeave",drop:"onDrop"},xs=class xs{constructor(e={},n,r){M(this,"bindingEngine");M(this,"translationEngine");M(this,"translationContext");M(this,"customHandlers",new Map);M(this,"defaultContext");M(this,"globalStateUpdater");M(this,"errorHandlingSetup",!1);M(this,"debounceTimers",new Map);M(this,"pendingDebounceFlushers",new Map);M(this,"debounceAccumulatedValues",new Map);M(this,"globalHeaders",[]);M(this,"namedActions",{});M(this,"previewMode",!1);M(this,"intervals",new Map);this.bindingEngine=new kn,this.translationEngine=n,this.translationContext=r,this.defaultContext=e,this.registerDefaultHandlers(),this.setupErrorHandling()}setGlobalHeaders(e){this.globalHeaders=e||[]}setNamedActions(e){this.namedActions=e||{};const n=Fn();n?.isEnabled?.()&&n.setNamedActionDefinitions?.(this.namedActions),j.log("[setNamedActions] registered:",Object.keys(this.namedActions))}getNamedActions(){return this.namedActions}setPreviewMode(e){this.previewMode=e,j.log("Preview mode:",e?"enabled":"disabled")}isPreviewMode(){return this.previewMode}static getPreviewSuppressedHandlers(){return Vm}static getPreviewSuppressedLayoutFeatures(){return hE}resolveActionRef(e){if(!e.actionRef)return e;const n=this.namedActions[e.actionRef];if(!n)return j.warn(`[resolveActionRef] named action not found: "${e.actionRef}"`),e;const r=Fn();r?.isEnabled?.()&&r.trackNamedActionRef?.({actionRefName:e.actionRef,resolvedHandler:n.handler,timestamp:Date.now()});const{actionRef:i,type:l,key:c,event:d,...f}=e,h={...n,...Object.fromEntries(Object.entries(f).filter(([,m])=>m!==void 0)),type:l??n.type};return c!==void 0&&(h.key=c),d!==void 0&&(h.event=d),h}matchesPattern(e,n){if(n==="*")return!0;const r=n.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${r}$`).test(e)}getMatchingGlobalHeaders(e,n){const r={};for(const i of this.globalHeaders)this.matchesPattern(e,i.pattern)&&Object.entries(i.headers).forEach(([l,c])=>{const d=ls(c,n,{skipCache:!0});d!=null&&d!==""&&(r[l]=String(d))});return r}setupErrorHandling(){if(this.errorHandlingSetup)return;Er().setActionExecutor(async(n,r)=>{const i={type:"click",handler:n.handler,target:n.target,params:n.params,actions:n.actions},l={data:{...this.defaultContext.data,error:r.error}};return await this.dispatchAction(i,l)}),this.errorHandlingSetup=!0}registerDefaultHandlers(){this.registerHandler("refetchDataSource",async(n,r)=>{const i=n.params?.dataSourceId,l=n.params?.sync;if(!i){j.warn("refetchDataSource: dataSourceId is required");return}if(typeof window<"u"&&window.G7Core?.dataSource?.refetch){const c=window.G7Core?.state?.get?.()||{},d={...r.state?._global,...c},f=window.G7Core?.state?.getLocal?.()||{},h=r.data?._local||r.state||{},m={...f,...h},y=r.isolatedContext?.state;j.log("[refetchDataSource] localStateOverride:",m),await window.G7Core.dataSource.refetch(i,{...l?{sync:!0}:{},...d?{globalStateOverride:d}:{},...m?{localStateOverride:m}:{},...y?{isolatedStateOverride:y}:{}})}else j.warn("refetchDataSource: G7Core.dataSource.refetch is not available")}),this.registerHandler("appendDataSource",async(n,r)=>{const{dataSourceId:i,dataPath:l,newData:c}=n.params||{};if(!i){j.warn("appendDataSource: dataSourceId is required");return}if(c===void 0){j.warn("appendDataSource: newData is required");return}if(typeof window<"u"&&window.G7Core?.dataSource?.updateData){if(!Array.isArray(c)){j.warn("appendDataSource: newData must be an array, got:",typeof c,c);return}await window.G7Core.dataSource.updateData(i,l||null,c,"append")}else j.warn("appendDataSource: G7Core.dataSource.updateData is not available")}),this.registerHandler("updateDataSource",async(n,r)=>{const{dataSourceId:i,data:l,merge:c=!1}=n.params||{};if(!i){j.warn("updateDataSource: dataSourceId is required");return}if(l===void 0){j.warn("updateDataSource: data is required");return}typeof window<"u"&&window.G7Core?.dataSource?.set?(j.log(`[updateDataSource] Updating dataSource '${i}' with:`,l),window.G7Core.dataSource.set(i,l,{merge:c})):j.warn("updateDataSource: G7Core.dataSource.set is not available")}),this.registerHandler("scrollIntoView",async(n,r)=>{const{selector:i,behavior:l="smooth",block:c="nearest",inline:d="nearest",waitForElement:f=!1,timeout:h=2e3,delay:m=0,retryCount:y=0,retryInterval:S=50,scrollContainer:v}=n.params||{};if(!i){j.warn("scrollIntoView: selector is required");return}if(typeof window>"u"||typeof document>"u"){j.warn("scrollIntoView: window/document is not available");return}let _=null;if(f){if(_=await new Promise(x=>{const A=document.querySelector(i);if(A){x(A);return}const L=setTimeout(()=>{$.disconnect(),x(null)},h),$=new MutationObserver(()=>{const k=document.querySelector(i);k&&(clearTimeout(L),$.disconnect(),x(k))});$.observe(document.body,{childList:!0,subtree:!0})}),!_){j.warn(`scrollIntoView: element not found for selector "${i}" after ${h}ms timeout`);return}}else{m>0&&await new Promise(A=>setTimeout(A,m)),_=document.querySelector(i);let x=0;for(;!_&&xsetTimeout(A,S)),_=document.querySelector(i),x++;if(!_){j.warn(`scrollIntoView: element not found for selector "${i}" after ${x+1} attempts`);return}}if(v){const x=document.querySelector(v);if(!x){j.warn(`scrollIntoView: container not found for selector "${v}"`);return}const A=_.getBoundingClientRect(),L=x.getBoundingClientRect(),$=A.top-L.top+x.scrollTop,k=$+A.height;let O;switch(c){case"start":O=$;break;case"center":O=$-x.clientHeight/2+A.height/2;break;case"end":O=k-x.clientHeight;break;default:const P=A.topL.bottom;if(P)O=$;else if(G)O=k-x.clientHeight;else return;break}x.scrollTo({top:Math.max(0,O),behavior:l});return}_.scrollIntoView({behavior:l,block:c,inline:d})}),this.registerHandler("reloadExtensions",async(n,r)=>{if(typeof window>"u"){j.warn("reloadExtensions: window is not available");return}const i=window.__templateApp;if(!i){j.warn("reloadExtensions: TemplateApp not initialized");return}if(typeof i.reloadExtensionState=="function")try{await i.reloadExtensionState()}catch(d){throw j.error("reloadExtensions: reloadExtensionState failed",d),d}else j.warn("reloadExtensions: TemplateApp.reloadExtensionState unavailable");const{moduleInfo:l,pluginInfo:c}=n.params||{};if(l)try{await this.executeAction({handler:"reloadModuleHandlers",params:n.params},r)}catch(d){j.error("reloadExtensions: reloadModuleHandlers failed",d)}if(c)try{await this.executeAction({handler:"reloadPluginHandlers",params:n.params},r)}catch(d){j.error("reloadExtensions: reloadPluginHandlers failed",d)}j.log("reloadExtensions: done")}),this.registerHandler("reloadRoutes",async(n,r)=>{if(typeof window>"u"){j.warn("reloadRoutes: window is not available");return}const i=window.__templateApp;if(!i){j.warn("reloadRoutes: TemplateApp not initialized");return}if(typeof i.reloadExtensionState=="function")try{await i.reloadExtensionState(),j.log("reloadRoutes: delegated to reloadExtensionState")}catch(l){throw j.error("reloadRoutes: Failed to reload routes",l),l}else{const l=i.getRouter?.();l&&(await l.loadRoutes(),j.log("reloadRoutes: Routes reloaded (legacy fallback)"))}}),this.registerHandler("refresh",async(n,r)=>{if(typeof window>"u"){j.warn("refresh: window is not available");return}const i=Number(n.params?.delayMs??0);i>0&&await new Promise(l=>setTimeout(l,i)),window.location.reload()}),this.registerHandler("remount",async(n,r)=>{const{componentId:i}=n.params||{};if(!i){j.warn("remount: componentId parameter is required");return}if(!this.globalStateUpdater){j.warn("remount: globalStateUpdater is not set");return}const d=(window.G7Core?.state?.get()||{})._global?._remountKeys||{},f=d[i]||0;this.globalStateUpdater({_remountKeys:{...d,[i]:f+1}}),j.log(`remount: ${i} key incremented to ${f+1}`)}),this.registerHandler("reloadTranslations",async(n,r)=>{if(typeof window>"u"){j.warn("reloadTranslations: window is not available");return}const i=window.__templateApp;if(!i){j.warn("reloadTranslations: TemplateApp not initialized");return}if(typeof i.reloadExtensionState=="function")try{await i.reloadExtensionState(),j.log("reloadTranslations: delegated to reloadExtensionState")}catch(l){throw j.error("reloadTranslations: Failed to reload translations",l),l}}),this.registerHandler("reloadModuleHandlers",async(n,r)=>{if(typeof window>"u"){j.warn("reloadModuleHandlers: window is not available");return}const{moduleInfo:i,action:l}=n.params||{};if(!i){j.warn("reloadModuleHandlers: moduleInfo is required");return}const c=i.data||i;if(!c.identifier){j.warn("reloadModuleHandlers: moduleInfo with identifier is required");return}if(!l||l!=="add"&&l!=="remove"){j.warn('reloadModuleHandlers: action must be "add" or "remove"');return}const d=window.G7Config;if(!d){j.warn("reloadModuleHandlers: G7Config not available");return}const f=c.identifier;try{if(l==="add"){if(c.assets&&(d.moduleAssets=d.moduleAssets||{},d.moduleAssets[f]=c.assets,j.log(`reloadModuleHandlers: Added assets for ${f}`),c.assets.js)){const h=c.assets.js,m=`module-${f}`;if(document.getElementById(m)){j.warn(`reloadModuleHandlers: Script ${m} already loaded`);return}const y=document.createElement("script");if(y.id=m,y.src=h,y.async=!0,await new Promise((S,v)=>{y.onload=()=>{j.log(`reloadModuleHandlers: Script loaded successfully for ${f}`),S()},y.onerror=()=>{j.error(`reloadModuleHandlers: Failed to load script for ${f}`),v(new Error(`Failed to load module script: ${h}`))},document.head.appendChild(y)}),c.assets.css){const S=c.assets.css,v=`module-css-${f}`;if(!document.getElementById(v)){const _=document.createElement("link");_.id=v,_.rel="stylesheet",_.href=S,document.head.appendChild(_),j.log(`reloadModuleHandlers: CSS loaded for ${f}`)}}}}else if(l==="remove"){d.moduleAssets&&d.moduleAssets[f]&&(delete d.moduleAssets[f],j.log(`reloadModuleHandlers: Removed assets for ${f}`));const h=`module-${f}`,m=document.getElementById(h);m&&(m.remove(),j.log(`reloadModuleHandlers: Removed script for ${f}`));const y=`module-css-${f}`,S=document.getElementById(y);S&&(S.remove(),j.log(`reloadModuleHandlers: Removed CSS for ${f}`))}}catch(h){throw j.error(`reloadModuleHandlers: Failed to ${l} module assets`,h),h}}),this.registerHandler("reloadPluginHandlers",async(n,r)=>{if(typeof window>"u"){j.warn("reloadPluginHandlers: window is not available");return}const{pluginInfo:i,action:l}=n.params||{};if(!i){j.warn("reloadPluginHandlers: pluginInfo is required");return}const c=i.data||i;if(!c.identifier){j.warn("reloadPluginHandlers: pluginInfo with identifier is required");return}if(!l||l!=="add"&&l!=="remove"){j.warn('reloadPluginHandlers: action must be "add" or "remove"');return}const d=window.G7Config;if(!d){j.warn("reloadPluginHandlers: G7Config not available");return}const f=c.identifier;try{if(l==="add"){if(c.assets&&(d.pluginAssets=d.pluginAssets||{},d.pluginAssets[f]=c.assets,j.log(`reloadPluginHandlers: Added assets for ${f}`),c.assets.js)){const h=c.assets.js,m=`plugin-${f}`;if(document.getElementById(m)){j.warn(`reloadPluginHandlers: Script ${m} already loaded`);return}const y=document.createElement("script");if(y.id=m,y.src=h,y.async=!0,await new Promise((S,v)=>{y.onload=()=>{j.log(`reloadPluginHandlers: Script loaded successfully for ${f}`),S()},y.onerror=()=>{j.error(`reloadPluginHandlers: Failed to load script for ${f}`),v(new Error(`Failed to load plugin script: ${h}`))},document.head.appendChild(y)}),c.assets.css){const S=c.assets.css,v=`plugin-css-${f}`;if(!document.getElementById(v)){const _=document.createElement("link");_.id=v,_.rel="stylesheet",_.href=S,document.head.appendChild(_),j.log(`reloadPluginHandlers: CSS loaded for ${f}`)}}}}else if(l==="remove"){d.pluginAssets&&d.pluginAssets[f]&&(delete d.pluginAssets[f],j.log(`reloadPluginHandlers: Removed assets for ${f}`));const h=`plugin-${f}`,m=document.getElementById(h);m&&(m.remove(),j.log(`reloadPluginHandlers: Removed script for ${f}`));const y=`plugin-css-${f}`,S=document.getElementById(y);S&&(S.remove(),j.log(`reloadPluginHandlers: Removed CSS for ${f}`))}}catch(h){throw j.error(`reloadPluginHandlers: Failed to ${l} plugin assets`,h),h}});let e=!1;this.registerHandler("showErrorPage",async(n,r)=>{if(e){j.log("showErrorPage: Already active, skipping duplicate call");return}if(e=!0,typeof window>"u"){e=!1,j.warn("showErrorPage: window is not available");return}const i=window.__templateApp;if(!i){e=!1,j.warn("showErrorPage: TemplateApp not initialized");return}const l=i.getErrorPageHandler?.();if(!l){e=!1,j.warn("showErrorPage: ErrorPageHandler not available");return}const c=n.params?.errorCode||500,d=n.params?.target||"content";let f=n.params?.containerId;f||(f=d==="full"?"app":"main_content"),j.log("showErrorPage:",{errorCode:c,target:d,containerId:f});const h=(m,y=6e4)=>new Promise((S,v)=>{const _=document.getElementById(m);if(_){S(_);return}j.log(`showErrorPage: Waiting for container #${m}...`);let x;const A=new MutationObserver((L,$)=>{const k=document.getElementById(m);k&&(j.log(`showErrorPage: Container #${m} found`),$.disconnect(),clearTimeout(x),S(k))});A.observe(document.body,{childList:!0,subtree:!0}),x=setTimeout(()=>{A.disconnect(),v(new Error(`Container #${m} not found within ${y}ms`))},y)});try{await h(f);const m=Er(),y=m.layoutErrorHandling;m.clearLayoutConfig();try{await l.renderError(c,f)||j.warn(`showErrorPage: Failed to render error page for code ${c}`)}finally{m.setLayoutConfig(y)}}catch(m){throw j.error("showErrorPage: Error rendering error page:",m),m}finally{e=!1}}),this.registerHandler("emitEvent",async(n,r)=>{const i=n.params?.event,l=n.params?.data;if(!i){j.warn("emitEvent: event parameter is required");return}if(typeof window>"u"){j.warn("emitEvent: window is not available");return}const c=window.G7Core;if(!c?.componentEvent?.emit){j.warn("emitEvent: G7Core.componentEvent is not available");return}try{j.log(`emitEvent: Emitting "${i}"`,l);const d={...l,_context:{data:r.data,state:r.state}},f=await c.componentEvent.emit(i,d);if(!f||f.length===0?j.warn(`emitEvent: No listeners found for "${i}"`):j.log(`emitEvent: Event "${i}" completed with ${f.length} listener(s)`,f),this.globalStateUpdater){const h=(c?.state?.get()||{})._local||{},m={event:i,success:!0,data:f.length===1?f[0]:f,listeners:f.length};this.globalStateUpdater({_local:{...h,_eventResult:m}});const y=r.state&&typeof r.state=="object"&&!Array.isArray(r.state)?r.state:h;window.__g7SequenceLocalSync={...y,_eventResult:m}}}catch(d){if(j.error(`emitEvent: Event "${i}" failed`,d),this.globalStateUpdater){const f=c?.state?.get()||{};this.globalStateUpdater({_local:{...f._local,_eventResult:{event:i,success:!1,error:d instanceof Error?d.message:String(d)}}})}throw d}}),this.registerHandler("updateProductField",async(n,r)=>{const{productId:i,field:l,value:c}=n.params||{};if(!i||!l){j.warn("updateProductField: productId and field are required");return}if(typeof window>"u"){j.warn("updateProductField: window is not available");return}const d=window.G7Core;if(!d?.state?.get||!this.globalStateUpdater){j.warn("updateProductField: G7Core.state or globalStateUpdater is not available");return}try{const f=d.state.get()||{},m=(f.products?.data?.data||[]).map(S=>S.id===i?{...S,[l]:c,_modified:!0}:S),y=new Set(f._local?.modifiedProductIds||[]);y.add(i),this.globalStateUpdater({products:{...f.products,data:{...f.products?.data,data:m}},_local:{...f._local,modifiedProductIds:Array.from(y)}}),j.log(`updateProductField: Updated product ${i}, field: ${l}, value:`,c)}catch(f){throw j.error("updateProductField: Error updating product field",f),f}}),this.registerHandler("updateOptionField",async(n,r)=>{const{productId:i,optionId:l,field:c,value:d}=n.params||{};if(!i||!l||!c){j.warn("updateOptionField: productId, optionId and field are required");return}if(typeof window>"u"){j.warn("updateOptionField: window is not available");return}const f=window.G7Core;if(!f?.state?.get||!this.globalStateUpdater){j.warn("updateOptionField: G7Core.state or globalStateUpdater is not available");return}try{const h=f.state.get()||{},y=(h.products?.data?.data||[]).map(v=>{if(v.id===i&&v.options){const _=v.options.map(x=>x.id===l?{...x,[c]:d,_modified:!0}:x);return{...v,options:_,_modified:!0}}return v}),S=new Set(h._local?.modifiedProductIds||[]);S.add(i),this.globalStateUpdater({products:{...h.products,data:{...h.products?.data,data:y}},_local:{...h._local,modifiedProductIds:Array.from(S)}}),j.log(`updateOptionField: Updated product ${i} option ${l}, field: ${c}, value:`,d)}catch(h){throw j.error("updateOptionField: Error updating option field",h),h}}),this.registerHandler("setLocale",async(n,r)=>{const i=n.target;if(!i||typeof i!="string"){j.warn("setLocale: Invalid locale:",i);return}const l=window.__templateApp;if(l&&typeof l.changeLocale=="function")try{await l.changeLocale(i),j.log("setLocale: Locale changed to",i)}catch(c){j.error("setLocale: Failed to change locale:",c),window.location.reload()}else{j.warn("setLocale: TemplateApp not found, falling back to page reload");try{localStorage.setItem("g7_locale",i)}catch{}window.location.reload()}}),this.registerHandler("suppress",async()=>{j.log("suppress: Error intentionally suppressed")}),this.registerBuiltInHandlerMetadata()}registerBuiltInHandlerMetadata(){const e=Fn();if(!e?.isEnabled())return;const n=[{name:"refetchDataSource",description:"데이터 소스를 다시 fetch합니다"},{name:"appendDataSource",description:"데이터 소스에 새 데이터를 병합합니다 (무한 스크롤용)"},{name:"updateDataSource",description:"API 응답으로 데이터 소스를 직접 업데이트합니다 (refetch 대체)"},{name:"reloadRoutes",description:"라우트를 다시 로드합니다"},{name:"refresh",description:"현재 페이지를 새로고침합니다"},{name:"remount",description:"컴포넌트를 리마운트합니다"},{name:"reloadTranslations",description:"다국어 파일을 다시 로드합니다"},{name:"showErrorPage",description:"에러 페이지를 표시합니다"},{name:"emitEvent",description:"이벤트를 발생시킵니다"},{name:"updateProductField",description:"상품 필드를 인라인 수정합니다"},{name:"updateOptionField",description:"상품 옵션 필드를 인라인 수정합니다"},{name:"setLocale",description:"언어를 변경합니다 (DB 저장 + UI 리렌더링)"}];for(const r of n)e.trackHandlerRegistration(r.name,"built-in",r.description)}createHandler(e,n,r){j.log("createHandler called for:",e.handler,e.type);const i=window.__g7DevTools,l=Date.now(),c=r?.state?{...r.state}:null,d=`handler_${e.handler}_${l}`;return async f=>{if(j.log("Handler invoked for:",e.handler,"event:",f.type),i?.isEnabled?.()&&c){const m=window.G7Core?.state?.getLocal?.()??r?.state??{},y=Date.now()-l;for(const S of Object.keys(c)){const v=c[S],_=m[S];v!==_&&y>100&&(i.trackStaleClosureWarning?.({type:"event-handler-stale",location:`createHandler(${e.handler})`,capturedPath:`_local.${S}`,capturedValue:v,capturedAt:l,currentValue:_,actionId:d,stackTrace:new Error().stack}),j.warn(`[Stale Closure] _local.${S} changed after handler creation:`,`captured="${v}" → current="${_}" (${y}ms ago)`))}}try{f.type!=="change"&&f.preventDefault();let h={};if(f.type==="submit"&&f.target instanceof HTMLFormElement){const S=f.target;new FormData(S).forEach((_,x)=>{h[x]=_})}const m={...this.defaultContext,data:{...n,form:h,_local:r?.state||{},$event:f},event:f,...r&&{state:r.state,setState:r.setState},isolatedContext:r?.isolatedContext};if(e.confirm){let S=this.resolveValue(e.confirm,m.data);if(this.translationEngine&&this.translationContext&&S.startsWith("$t:")&&(S=this.translationEngine.resolveTranslations(S,this.translationContext,m.data)),!confirm(S))return}const y=window.__g7ActionContext;window.__g7ActionContext={...r,data:m.data};try{await this.executeAction(e,m)}finally{window.__g7ActionContext=y}}catch(h){if(j.error("Action execution failed:",h),e.onError){const m=h instanceof Ut&&h.originalError?h.originalError:h,y={...this.defaultContext,data:{...n,error:m,_local:r?.state||{},$event:f},event:f,...r&&{state:r.state,setState:r.setState}},S=Array.isArray(e.onError)?e.onError:[e.onError];for(const v of S)await this.executeAction(v,y)}}}}generateActionId(e,n){const r=e.handler,i=n||"no-target",l=Date.now(),c=Math.random().toString(36).substring(2,9);return`${r}_${i.replace(/[^a-zA-Z0-9]/g,"_")}_${l}_${c}`}async executeAction(e,n){if(e=this.resolveActionRef(e),typeof e.handler=="string"&&e.handler.includes("{{")){const f=this.evaluateExpression(e.handler,n.data);e={...e,handler:f==null?"":String(f)}}const r=Fn(),i=r?.isEnabled()?`action_${Date.now()}_${Math.random().toString(36).substring(2,11)}`:void 0,l=performance.now();let c;if(i&&r&&r.logAction({id:i,type:e.handler,params:this.sanitizeForDevTools(e.params),context:this.sanitizeForDevTools({hasState:!!n.state,hasSetState:!!n.setState,dataKeys:n.data?Object.keys(n.data):[]}),startTime:l,status:"started"}),e.if!==void 0)try{const f=this.resolveValue(e.if,n.data),h=f===!0||f==="true"||f&&f!=="false"&&f!=="0"&&f!==!1;if(j.log("[executeAction] if condition result:",e.handler,h),!h)return i&&r&&r.logAction({id:i,type:e.handler,startTime:l,endTime:performance.now(),duration:performance.now()-l,status:"success",result:{skipped:!0,reason:"if condition false"}}),{success:!0,data:void 0}}catch(f){return j.error("[executeAction] if condition error:",e.handler,f),i&&r&&r.logAction({id:i,type:e.handler,startTime:l,endTime:performance.now(),duration:performance.now()-l,status:"error",error:{name:"ConditionEvaluationError",message:f instanceof Error?f.message:String(f),stack:f instanceof Error?f.stack:void 0}}),{success:!0,data:void 0}}let d;try{const f=this.resolveParams(e.params,n.data);i&&(c=this.sanitizeForDevTools(f));const h=e.target?this.resolveValue(e.target,n.data):void 0;if(e.handler==="apiCall"&&n.setState){d=this.generateActionId(e,h);const y=n.state?.loadingActions||{};n.setState({loadingActions:{...y,[d]:!0}})}if(this.previewMode&&Vm.has(e.handler))return j.warn(`Preview mode: "${e.handler}" suppressed`,h||f),i&&r&&r.logAction({id:i,type:e.handler,startTime:l,endTime:performance.now(),duration:performance.now()-l,status:"skipped",metadata:{reason:"preview_mode_suppressed"}}),{success:!0,data:void 0};let m;switch(e.handler){case"ensureIdentityVerified":m=await this.handleEnsureIdentityVerified(f);break;case"resolveIdentityChallenge":m=this.handleResolveIdentityChallenge(f);break;case"navigate":const y=f.path||h;m=await this.handleNavigate(y,f,n);break;case"navigateBack":m=await this.handleNavigateBack();break;case"navigateForward":m=await this.handleNavigateForward();break;case"openWindow":{const _=f.path||h;m=await this.handleOpenWindow(_,f);break}case"replaceUrl":{const _=f.path||h||window.location.pathname;m=await this.handleReplaceUrl(_,f);break}case"apiCall":if(e.onSuccess&&r?.isEnabled()&&i){const _=window.G7Core,x={};if(_?.state?.get){const A=_.state.get();x._global=A}n.state&&(x._local=n.state),r.registerStateCaptureForHandler?.(i,["_global","_local"],x)}const S=e.auth_mode??(e.auth_required?"required":"none"),v=e.identity_target?this.resolveParams(e.identity_target,n.data):void 0;m=await this.handleApiCall(h,f,n,S,v);break;case"login":m=await this.handleLogin(h,f,n);break;case"logout":m=await this.handleLogout(h,n);break;case"setState":j.log("[executeAction] setState resolvedParams:",f),m=await this.handleSetState(e.render!==void 0?{...f,__render:e.render}:f,n);break;case"setError":m=await this.handleSetError(h,f,n);break;case"openModal":m=await this.handleOpenModal(h,n);break;case"closeModal":m=await this.handleCloseModal(n);break;case"showAlert":m=await this.handleShowAlert(h,n);break;case"toast":m=await this.handleToast(f,n);break;case"switch":m=await this.handleSwitch(e,n);break;case"conditions":m=await this.handleConditions(e,n);break;case"sequence":m=await this.handleSequence(e,n);break;case"parallel":m=await this.handleParallel(e,n);break;case"startInterval":m=this.handleStartInterval(f,n);break;case"stopInterval":m=this.handleStopInterval(f);break;case"loadScript":m=await this.handleLoadScript(f,e,n);break;case"callExternal":m=await this.handleCallExternal(f,e,n);break;case"callExternalEmbed":m=await this.handleCallExternalEmbed(f,e,n);break;case"saveToLocalStorage":m=await this.handleSaveToLocalStorage(f,n);break;case"loadFromLocalStorage":m=await this.handleLoadFromLocalStorage(f,n);break;default:m=await this.handleCustomAction({...e,target:h,params:f},n);break}if(e.resultTo&&m!==void 0){const{target:y,key:S,merge:v}=e.resultTo,_=this.resolveValue(S,n.data),x=v==="replace"?"replace":v==="shallow"?"shallow":"deep";if(y==="_local"&&n.setState){const A=this.buildNestedUpdate(_,m),L=x!=="deep"?{...A,__mergeMode:x}:A;n.setState(L),j.log(`[resultTo] Saved to _local.${_} (merge=${x}):`,m)}else if(y==="_local"&&this.globalStateUpdater){const $=(window.G7Core?.state?.get()||{})._local||{},k=this.buildNestedUpdate(_,m);let O;x==="replace"?O=k:x==="shallow"?O={...$,...k}:O=this.deepMergeWithState(k,$),this.globalStateUpdater({_local:O}),j.log(`[resultTo] Saved to _local.${_} via globalStateUpdater (merge=${x}):`,m)}else if(y==="_global"&&this.globalStateUpdater){const A=this.buildNestedUpdate(_,m);this.globalStateUpdater(A),j.log(`[resultTo] Saved to _global.${_}:`,m)}else if(y==="_isolated"&&n.isolatedContext){const A=this.buildNestedUpdate(_,m);n.isolatedContext.mergeState(A,x),j.log(`[resultTo] Saved to _isolated.${_} (merge=${x}):`,m)}else j.warn(`[resultTo] Cannot save result: target=${y}, setState=${!!n.setState}, globalStateUpdater=${!!this.globalStateUpdater}, isolatedContext=${!!n.isolatedContext}`)}if(e.onSuccess){if(r?.isEnabled()&&i&&e.handler==="apiCall"){const v=window.G7Core,_={};v?.state?.get&&(_._global=v.state.get()),n.state&&(_._local=n.state),r.detectStaleClosure?.(i,`${e.handler} → onSuccess`,_,"callback-state-capture",i)}const y={...n,data:{...n.data,result:m,response:m}},S=Array.isArray(e.onSuccess)?e.onSuccess:[e.onSuccess];S.length>1?await this.handleSequence({handler:"sequence",type:"click",actions:S},y):S.length===1&&await this.executeAction(S[0],y)}return i&&r&&r.logAction({id:i,type:e.handler,params:this.sanitizeForDevTools(e.params),resolvedParams:c,startTime:l,endTime:performance.now(),duration:performance.now()-l,status:"success",result:this.sanitizeForDevTools(m)}),{success:!0,data:m}}catch(f){const h=f instanceof Ut?f:new Ut(`Failed to execute action: ${e.handler}`,e,f instanceof Error?f:void 0),m=h.originalError?.response||{},y=m.data||{},S=h.originalError?.status||m.status||500;let v=fE(h.originalError??f,e.handler,y.message,h.message);this.translationEngine&&this.translationContext&&v.startsWith("$t:")&&(v=this.translationEngine.resolveTranslations(v,this.translationContext));const _={status:S,message:v,errors:y.errors||m.errors,data:y,statusText:h.originalError?.statusText,error_code:y.error_code??m.error_code};if(h.unknownHandler)throw j.warn(`Unknown action handler "${e.handler}" — skipped (extension not loaded?). Not surfaced to the user.`),h;const A=Er().resolve(S,{errorHandling:e.errorHandling,onError:e.onError});if(A.handler){if(r?.isEnabled()&&i&&e.handler==="apiCall"){const $=window.G7Core,k={};$?.state?.get&&(k._global=$.state.get()),n.state&&(k._local=n.state),r.detectStaleClosure?.(i,`${e.handler} → onError`,k,"callback-state-capture",i)}const L={...n,data:{...n.data,error:_}};try{const $={type:"click",handler:A.handler.handler,target:A.handler.target,params:A.handler.params,actions:A.handler.actions};return await this.executeAction($,L),{success:!1,error:h}}catch($){return j.error("Error executing error handler:",$),{success:!1,error:h}}}throw i&&r&&r.logAction({id:i,type:e.handler,params:this.sanitizeForDevTools(e.params),resolvedParams:c,startTime:l,endTime:performance.now(),duration:performance.now()-l,status:"error",error:{name:h.name,message:h.message,stack:h.stack}}),h}finally{if(e.handler==="apiCall"&&n.setState&&d){const f=n.state?.loadingActions||{},{[d]:h,...m}=f;n.setState({loadingActions:m})}}}async handleNavigate(e,n,r){let i=e;if(n.query||n.mergeQuery===!0)if(n.mergeQuery===!0)i=this.buildMergedQueryPath(e,n.query??{});else{const c=new URLSearchParams;for(const[f,h]of Object.entries(n.query))if(h!=null&&h!=="")if(Array.isArray(h)){const m=f.endsWith("[]")?f:`${f}[]`;for(const y of h)y!=null&&y!==""&&c.append(m,String(y))}else c.set(f,String(h));const d=c.toString();d&&(i=`${e}?${d}`)}if(j.log("handleNavigate:",{target:e,params:n,finalPath:i,replace:n.replace,windowLocationSearch:window.location.search}),n.replace===!0){const c=window.G7Core;if(c?.updateQueryParams){const d=typeof n.transition_overlay_target=="string"?n.transition_overlay_target:void 0;await c.updateQueryParams(i,d?{transitionOverlayTarget:d}:void 0),j.log("handleNavigate: Used updateQueryParams for replace mode",d?{transitionOverlayTarget:d}:void 0),this.applyScrollOption(n.scroll,n.scrollBehavior,"top");return}j.warn("handleNavigate: G7Core.updateQueryParams not available, falling back to React Router")}const l=this.resolveNavigateFallbackAction(i,n);if(l){j.warn(`handleNavigate: No route matched, falling back to "${l.handler}"`),await this.dispatchAction({type:"click",handler:l.handler,params:l.params},r),this.applyScrollOption(n.scroll,n.scrollBehavior,"top");return}if(!r.navigate)throw new Ut("Navigate function is not provided in context");r.navigate(i,{replace:n.replace===!0}),this.applyScrollOption(n.scroll,n.scrollBehavior,"top")}resolveNavigateFallbackAction(e,n){const r=n.fallback;if(r===!1||n.replace===!0)return null;const l=window.__templateApp?.getRouter?.();if(!l||typeof l.match!="function"||typeof l.getRoutes=="function"&&l.getRoutes().length===0)return null;const c=e.split("?")[0];return l.match(c)?null:this.resolveNavigateFallback(r,e,n)}resolveNavigateFallback(e,n,r){return e==null?{handler:"openWindow",params:{path:n,target:"_self"}}:typeof e=="string"?{handler:e,params:{path:n}}:typeof e=="object"&&typeof e.handler=="string"?{handler:e.handler,params:{path:n,...e.params||{}}}:(j.warn("resolveNavigateFallback: unrecognized fallback option, using openWindow",e),{handler:"openWindow",params:{path:n,target:"_blank"}})}applyScrollOption(e,n,r){const i=e===void 0?r:e;if(i==="preserve")return;const l=n==="smooth"?"smooth":"instant",c=y=>{if(typeof y!="object"||y===null)return!1;const S=y;return"container"in S||"to"in S||"block"in S||"offset"in S},d=(y,S,v=0)=>{y===window?window.scrollTo({top:S,left:v,behavior:l}):y.scrollTo({top:S,left:v,behavior:l})},f=(y,S,v,_)=>{if(S===window){y.scrollIntoView({behavior:l,block:v}),_&&window.scrollBy({top:-_,left:0,behavior:l});return}const x=S,A=y.getBoundingClientRect(),L=x.getBoundingClientRect(),$=x.scrollTop+(A.top-L.top);let k;v==="center"?k=$-(x.clientHeight-y.clientHeight)/2:v==="end"?k=$-(x.clientHeight-y.clientHeight):k=$,k-=_,x.scrollTo({top:Math.max(0,k),left:0,behavior:l})},h=()=>{window.scrollTo({top:0,left:0,behavior:l});const y=document.getElementById("app")??document.body;if(!y)return;y.querySelectorAll("*").forEach(v=>{if(v.scrollTop===0&&v.scrollLeft===0)return;const _=window.getComputedStyle(v),x=_.overflowY,A=_.overflowX;(x==="auto"||x==="scroll"||A==="auto"||A==="scroll")&&v.scrollTo({top:0,left:0,behavior:l})})},m=()=>{try{if(c(i)){const y=i,S=y.block??"start",v=typeof y.offset=="number"?y.offset:0;let _=window;if(typeof y.container=="string"&&y.container.length>0){const A=document.querySelector(y.container);if(!A){j.warn(`applyScrollOption: container not found: ${y.container}`);return}_=A}const x=y.to??"top";if(x==="top"){_===window?h():d(_,0);return}if(typeof x=="number"){d(_,x-v);return}if(typeof x=="object"&&x!==null&&("x"in x||"y"in x)){const{x:A=0,y:L=0}=x;d(_,L-v,A);return}if(typeof x=="string"&&(x.startsWith("#")||x.startsWith("."))){const A=document.querySelector(x);A?f(A,_,S,v):j.warn(`applyScrollOption: target element not found: ${x}`);return}j.warn('applyScrollOption: invalid "to" value in extended form',x);return}if(i==="top"){h();return}if(typeof i=="number"){window.scrollTo({top:i,left:0,behavior:l});return}if(typeof i=="object"&&i!==null&&("x"in i||"y"in i)){const{x:y=0,y:S=0}=i;window.scrollTo({top:S,left:y,behavior:l});return}if(typeof i=="string"&&(i.startsWith("#")||i.startsWith("."))){const y=document.querySelector(i);y&&y.scrollIntoView({behavior:l,block:"start"});return}}catch(y){j.warn("applyScrollOption: failed to apply scroll",y)}};typeof window.requestAnimationFrame=="function"?window.requestAnimationFrame(m):m()}async handleOpenWindow(e,n){let r=e;if(n.query){const l=new URLSearchParams;for(const[d,f]of Object.entries(n.query))f!=null&&f!==""&&l.set(d,String(f));const c=l.toString();c&&(r=`${e}?${c}`)}const i=n.target==="_self"?"_self":"_blank";j.log("handleOpenWindow:",{target:e,params:n,finalPath:r,windowTarget:i}),i==="_self"?window.location.assign(r):window.open(r,"_blank")}async handleNavigateBack(){j.log("handleNavigateBack"),window.history.back()}async handleNavigateForward(){j.log("handleNavigateForward"),window.history.forward()}async handleReplaceUrl(e,n){let r=e;if(n.query||n.mergeQuery===!0)if(n.mergeQuery===!0)r=this.buildMergedQueryPath(e,n.query??{});else{const i=new URLSearchParams;for(const[c,d]of Object.entries(n.query))if(d!=null&&d!=="")if(Array.isArray(d)){const f=c.endsWith("[]")?c:`${c}[]`;for(const h of d)h!=null&&h!==""&&i.append(f,String(h))}else i.set(c,String(d));const l=i.toString();l&&(r=`${e}?${l}`)}j.log("handleReplaceUrl:",{target:e,params:n,finalPath:r}),window.history.replaceState(null,"",r),this.applyScrollOption(n.scroll,n.scrollBehavior,"preserve")}buildMergedQueryPath(e,n){const r=new URLSearchParams(window.location.search);for(const[c,d]of Object.entries(n))if(d==null||d==="")r.delete(c);else if(Array.isArray(d)){const f=c.endsWith("[]")?c:`${c}[]`;r.delete(c),r.delete(f);for(const h of d)h!=null&&h!==""&&r.append(f,String(h))}else r.set(c,String(d));const i=r.toString(),l=e.split("?")[0];return i?`${l}?${i}`:l}async ensureCsrfToken(){try{await fetch("/sanctum/csrf-cookie",{credentials:"include"})}catch(e){throw new Ut("Failed to fetch CSRF token",void 0,e instanceof Error?e:void 0)}}getCsrfTokenFromCookie(){const r=`; ${document.cookie}`.split("; XSRF-TOKEN=");if(r.length===2){const i=r.pop()?.split(";").shift();return i?decodeURIComponent(i):null}return null}buildQueryString(e){const n=new URLSearchParams;for(const[r,i]of Object.entries(e))if(!(i==null||i===""))if(Array.isArray(i))for(const l of i)l!=null&&l!==""&&n.append(`${r}[]`,String(l));else typeof i=="object"?n.append(r,JSON.stringify(i)):n.append(r,String(i));return n.toString()}async handleEnsureIdentityVerified(e){const n=typeof e.purpose=="string"?e.purpose:"sensitive_action",r=e.target&&typeof e.target=="object"?e.target:void 0;return await St.handle({success:!1,error_code:"identity_verification_required",message:"",verification:{policy_key:e.policy_key??"",purpose:n,provider_id:e.provider_id??null,render_hint:e.render_hint??null,return_request:null}},void 0,r)!==null}handleResolveIdentityChallenge(e){const n=typeof e.result=="string"?e.result:"cancelled";let r;switch(n){case"verified":{const i=typeof e.token=="string"?e.token:"";if(!i){j.warn("resolveIdentityChallenge: result=verified 인데 token 이 비어있습니다. failed 로 강등합니다."),r={status:"failed",failureCode:"MISSING_TOKEN"};break}r={status:"verified",token:i,providerData:e.providerData&&typeof e.providerData=="object"?e.providerData:void 0};break}case"pending":{const i=typeof e.pollUrl=="string"?e.pollUrl:"",l=typeof e.expiresAt=="string"?e.expiresAt:"";if(!i||!l){j.warn("resolveIdentityChallenge: result=pending 인데 pollUrl/expiresAt 누락 — failed 로 강등합니다."),r={status:"failed",failureCode:"MALFORMED_PENDING"};break}r={status:"pending",pollUrl:i,pollIntervalMs:typeof e.pollIntervalMs=="number"?e.pollIntervalMs:void 0,expiresAt:l};break}case"failed":r={status:"failed",failureCode:typeof e.failureCode=="string"?e.failureCode:"UNKNOWN",reason:typeof e.reason=="string"?e.reason:void 0};break;default:r={status:"cancelled"};break}return St.resolveDeferred(r),!0}async handleApiCall(e,n,r,i="none",l){const{method:c="GET",body:d,headers:f,contentType:h}=n;c!=="GET"&&c!=="HEAD"&&await this.ensureCsrfToken();const m=this.getCsrfTokenFromCookie();let y={};if(i==="required"||i==="optional"){const W=zr().getToken();W&&(y={Authorization:`Bearer ${W}`})}let S=e;const v=n.query||(c==="GET"?d:null);if(v&&typeof v=="object"){const B=this.buildQueryString(v);if(B){const W=e.includes("?")?"&":"?";S=`${e}${W}${B}`}}const _=window.G7Core?.state?.getGlobal?.()||r.state?._global||{},x=window.G7Core?.state?.getLocal?.()||r.state?._local||{},A={_global:_,_local:x},L=this.getMatchingGlobalHeaders(e,A),$={};if(typeof window<"u"){const B=localStorage.getItem("g7_locale");B&&($["Accept-Language"]=B)}const k=h==="multipart/form-data",O={method:c,headers:{...k?{}:{"Content-Type":"application/json"},Accept:"application/json",...$,...m&&{"X-XSRF-TOKEN":m},...y,...L,...f},credentials:"include"};if(d&&c!=="GET")if(k){const B=new FormData;for(const[W,pe]of Object.entries(d))pe instanceof File||pe instanceof Blob?B.append(W,pe):pe!=null&&B.append(W,typeof pe=="object"?JSON.stringify(pe):String(pe));O.body=B}else O.body=JSON.stringify(d);const P=Fn();let G=null;P?.isEnabled()&&(G=P.trackRequest(S,c));try{let B=await fetch(S,O),W;try{W=await B.json()}catch{W=null}if(St.isIdentityRequired(B.status,W)){const pe=await St.handle(W,{body:O.body,headers:O.headers,credentials:O.credentials},l);if(pe){B=pe;try{W=await B.json()}catch{W=null}}}if(G&&P?.isEnabled()&&(P.completeRequest(G,B.status,W),G=null),!B.ok){const pe=W||{},Se=new Error(pe.message||`API call failed: ${B.statusText}`);throw Se.response=pe,Se.status=B.status,Se.statusText=B.statusText,new Ut(pe.message||`API call failed: ${B.statusText}`,void 0,Se)}return W}catch(B){throw G&&P?.isEnabled()&&P.failRequest(G,B instanceof Error?B.message:String(B)),B}}async handleLogin(e,n,r){const{body:i}=n;if(!i||!i.email||!i.password)throw new Ut("Login requires email and password in body params");const l=e==="user"?"user":"admin",c=l==="admin"?"/api/auth/admin/login":"/api/auth/login",d=window.G7Core?.state?.getGlobal?.()||r.state?._global||{},f=window.G7Core?.state?.getLocal?.()||r.state?._local||{},h={_global:d,_local:f},m=this.getMatchingGlobalHeaders(c,h),y=wr.getInstance();try{const S=Object.keys(m).length>0?{headers:m}:void 0;return{user:await y.login(l,{email:i.email,password:i.password},S)}}catch(S){const v=S.message||"Login failed",_=new Error(v);throw _.response=S.response?.data||{},_.status=S.status||S.response?.status||500,new Ut(v,void 0,_)}}async handleLogout(e,n){await wr.getInstance().logout()}async handleSetState(e,n){j.log("[handleSetState] START, params:",e);const{target:r="component",scope:i,merge:l,__render:c,...d}=e,f=Fn(),h=window.G7Core;if(typeof r=="string"&&(r.startsWith("$parent.")||r.startsWith("$root.")))return this.handleParentScopeSetState(r,d,l,n);const m=n.state&&Object.keys(n.state).length>0?n.state:h?.state?.get()||{},y=r==="global"?"_global":r.startsWith("_local.")?r:"_local",S=y==="_global"?m._global:y.startsWith("_local.")?this.getNestedProperty(m._local||{},y.slice(7)):m._local,v=f?.isEnabled()?f.startStateChange(y,S,d,{actionId:n.actionId,handlerType:"setState",source:`target=${r}`}):void 0,_=l==="replace"?"replace":l==="shallow"?"shallow":"deep",x=_!=="deep"?{...d,__mergeMode:_,...v?{__setStateId:v}:{}}:{...d,...v?{__setStateId:v}:{}};if(r==="global"){if(!this.globalStateUpdater){j.warn("Global state updater is not set"),v&&f&&f.completeStateChange(v);return}const A=h?.state?.get()||{},{__setStateId:L,__mergeMode:$,...k}=x,O=_==="deep"?this.deepMergeWithState(k,A):k,P={...O,...v?{__setStateId:v}:{},..._!=="deep"?{__mergeMode:_}:{}};return j.log("setState global:",P),this.globalStateUpdater(P,{render:c}),v&&f&&setTimeout(()=>f.completeStateChange(v),0),{__target:"global",..._!=="deep"?{__mergeMode:_}:{},...O}}else if(r==="isolated"){const A=n.isolatedContext;if(A){const{__mergeMode:L,__setStateId:$,...k}=x;return A.mergeState(k,_),j.log("[handleSetState] isolated state updated:",k,"mergeMode:",_),v&&f&&setTimeout(()=>f.completeStateChange(v),0),{__target:"isolated",...k}}else if(j.warn('[handleSetState] isolated target used but no IsolatedStateContext found. Make sure the component has "isolatedState" attribute. Falling back to local state.'),n.setState){const $=window.__g7PendingLocalState||n.state||{},k=_==="deep"?this.deepMergeWithState(x,$):x;return n.setState(k),v&&f&&setTimeout(()=>f.completeStateChange(v),0),k}else throw v&&f&&f.completeStateChange(v),new Ut("isolated target used but no IsolatedStateContext found and no setState function in context")}else if(r==="local"||r==="component"||r==="_local"){if(i==="parent"||i==="root"){const L=window.__g7LayoutContextStack||[];if(L.length>0){const $=i==="parent"?L[L.length-1]:L[0];if($?.setState){const{__mergeMode:k,__setStateId:O,...P}=x,G=_==="deep"?this.deepMergeWithState(P,$.state||{}):P;return j.log(`[handleSetState] scope=${i}: 타겟 컨텍스트에 상태 업데이트`,G),$.setState(G),v&&f&&setTimeout(()=>f.completeStateChange(v),0),G}}j.warn(`[handleSetState] scope=${i}: 레이아웃 컨텍스트 스택이 비어있습니다. current로 폴백합니다.`)}const A=n.setState&&!n._isDispatchFallbackContext;if(j.log("[handleSetState] isRealComponentContext:",A,"context.setState:",!!n.setState,"_isDispatchFallbackContext:",n._isDispatchFallbackContext),A){j.log("[handleSetState] Using COMPONENT setState path"),j.log("[handleSetState] resolvedPayload:",x),j.log("[handleSetState] context.state:",n.state),j.log("[handleSetState] mergeMode:",_);const $=window.__g7PendingLocalState||n.state||{},k=_==="deep"?this.deepMergeWithState(x,{}):x;j.log("[handleSetState] convertedPayload (변경 필드만, dot notation 변환):",k),n.setState(k);const O=_==="deep"?this.deepMergeWithState(x,$):_==="shallow"?{...n.state||{},...x}:x,{__mergeMode:P,__setStateId:G,...B}=O;window.__g7PendingLocalState=B,j.log("[handleSetState] __g7PendingLocalState updated:",B),this.globalStateUpdater&&(this.globalStateUpdater({_local:B},{render:!1}),j.log("[handleSetState] _global._local synced (render:false):",B));const{__mergeMode:W,__setStateId:pe,...Se}=x;if(_==="replace")window.__g7ForcedLocalFields=Se;else{const we=window.__g7ForcedLocalFields||{};window.__g7ForcedLocalFields=this.deepMergeWithState(Se,we)}return j.log("[handleSetState] __g7ForcedLocalFields updated:",Se),v&&f&&setTimeout(()=>f.completeStateChange(v),0),{__target:"local",...O}}else if(this.globalStateUpdater){j.log("[handleSetState] Using GLOBAL STATE UPDATER path for _local");const $=window.__g7PendingLocalState||m._local||{};j.log("[handleSetState] currentLocal (with pending):",$);const k=_==="deep"?this.deepMergeWithState(x,$):x;return j.log("[handleSetState] finalLocal (merged):",k),this.globalStateUpdater({_local:k},{render:c}),window.__g7PendingLocalState=k,j.log("[handleSetState] __g7PendingLocalState updated for globalStateUpdater path"),v&&f&&setTimeout(()=>f.completeStateChange(v),0),{__target:"local",...k}}else throw v&&f&&f.completeStateChange(v),new Ut("setState function is not provided in context and globalStateUpdater is not set")}else if(r.startsWith("_local.")){const A=r.slice(7),{__mergeMode:L,__setStateId:$,...k}=x,O=k.value!==void 0?k.value:Object.values(k)[0];if(n.setState){const G=window.__g7PendingLocalState||n.state||{},B=this.createNestedUpdate(A,O,G),W={...G,...B};if(n.setState(B),this.globalStateUpdater&&i!=="parent"&&i!=="root"){const pe=window.__templateApp?.getGlobalState?.()?._local,Se=pe&&typeof pe=="object"?{...pe,...B}:W;this.globalStateUpdater({_local:Se},{render:!1}),j.log("[handleSetState] _global._local synced for dot notation (render:false):",Se)}return v&&f&&setTimeout(()=>f.completeStateChange(v),0),W}else throw v&&f&&f.completeStateChange(v),new Ut("setState function is not provided in context")}else{if(!n.setState)throw v&&f&&f.completeStateChange(v),new Ut("setState function is not provided in context");const L=window.__g7PendingLocalState||n.state||{},$=_==="deep"?this.deepMergeWithState(x,L):x;return n.setState($),v&&f&&setTimeout(()=>f.completeStateChange(v),0),$}}async handleParentScopeSetState(e,n,r,i){const l=Fn(),c=window.G7Core,d=r==="replace"?"replace":r==="shallow"?"shallow":"deep",f=e.startsWith("$parent."),h=f?"$parent.":"$root.",m=e.slice(h.length);let y,S;if(m==="_local"||m==="_global")y=m,S=void 0;else if(m.startsWith("_local."))y="_local",S=m.slice(7);else if(m.startsWith("_global."))y="_global",S=m.slice(8);else{j.warn(`[handleParentScopeSetState] 지원하지 않는 타겟 형식: ${e}. _local 또는 _global으로 시작해야 합니다.`);return}const v=window.__g7LayoutContextStack||[];if(v.length===0){j.warn(`[handleParentScopeSetState] 레이아웃 컨텍스트 스택이 비어있습니다. target=${e}`);return}const _=f?v[v.length-1]:v[0];if(!_){j.warn(`[handleParentScopeSetState] 타겟 컨텍스트를 찾을 수 없습니다. target=${e}`);return}const x=y==="_global"?_.state?._global:_.state?._local,A=l?.isEnabled()?l.startStateChange(e,x,n,{actionId:i.actionId,handlerType:"setState",source:`target=${e}`}):void 0,{__mergeMode:L,__setStateId:$,...k}=n;if(y==="_global"){if(!this.globalStateUpdater){j.warn("[handleParentScopeSetState] globalStateUpdater가 설정되지 않았습니다."),A&&l&&l.completeStateChange(A);return}const O=c?.state?.get()||{};if(S){const P=k.value!==void 0?k.value:Object.values(k)[0],G=this.createNestedUpdate(S,P,O),B={...O,...G};j.log(`[handleParentScopeSetState] ${e}: 전역 상태 중첩 경로 업데이트`,B),this.globalStateUpdater(B)}else{const P=d==="deep"?this.deepMergeWithState(k,O):k;j.log(`[handleParentScopeSetState] ${e}: 전역 상태 업데이트 (mergeMode=${d})`,P),this.globalStateUpdater(d!=="deep"?{...P,__mergeMode:d}:P)}return A&&l&&setTimeout(()=>l.completeStateChange(A),0),{__target:e,...k}}else{if(!_.setState){j.warn(`[handleParentScopeSetState] 타겟 컨텍스트에 setState가 없습니다. target=${e}`),A&&l&&l.completeStateChange(A);return}const O=_.state||{};if(S){const P=k.value!==void 0?k.value:Object.values(k)[0],G=this.createNestedUpdate(S,P,O),B={...O,...G};return j.log(`[handleParentScopeSetState] ${e}: 로컬 상태 중첩 경로 업데이트`,G),_.setState(G),_.state=B,_.dataContext&&(_.dataContext._local=B),wf(),A&&l&&setTimeout(()=>l.completeStateChange(A),0),B}else{const P=d!=="deep"?{...k,__mergeMode:d}:k,G=d==="replace"?k:d==="shallow"?{...O,...k}:this.deepMergeWithState(k,O);return j.log(`[handleParentScopeSetState] ${e}: 로컬 상태 업데이트 (mergeMode=${d})`,G),_.setState(P),_.state=G,_.dataContext&&(_.dataContext._local=G),wf(),A&&l&&setTimeout(()=>l.completeStateChange(A),0),G}}}deepMergeWithState(e,n){const r=["errors"];let i=e;if("..."in e){const c=e["..."];if(c&&typeof c=="object"&&!Array.isArray(c)){const{"...":d,...f}=e;i={...c,...f}}else{const{"...":d,...f}=e;i=f}}const l={...n};for(const[c,d]of Object.entries(i)){if(r.includes(c)){l[c]=d;continue}if(c.includes(".")&&c!=="..."){const f=this.createNestedUpdate(c,d,l);this.deepMergeInto(l,f,l);continue}if(d!==null&&typeof d=="object"&&!Array.isArray(d)&&Object.getPrototypeOf(d)!==Object.prototype&&Object.getPrototypeOf(d)!==null){l[c]=d;continue}d!==null&&typeof d=="object"&&!Array.isArray(d)&&n[c]!==null&&typeof n[c]=="object"&&!Array.isArray(n[c])?l[c]=this.deepMergeWithState(d,n[c]):l[c]=d}return l}deepMergeInto(e,n,r){for(const[i,l]of Object.entries(n)){if(l===null){e[i]=l;continue}if(e[i]===null){e[i]=l;continue}typeof l=="object"&&!Array.isArray(l)&&e[i]!==void 0&&e[i]!==null&&typeof e[i]=="object"&&!Array.isArray(e[i])?(e[i]===r[i]&&(e[i]={...e[i]}),this.deepMergeInto(e[i],l,r[i]||{})):typeof l=="object"&&!Array.isArray(l)&&e[i]===void 0&&r[i]!==null&&typeof r[i]=="object"&&!Array.isArray(r[i])?e[i]={...r[i],...l}:e[i]=l}}createNestedUpdate(e,n,r){const i=e.split(".");if(i.length===1)return{[i[0]]:n};const l={};let c=l,d=r;for(let f=0;f{this.globalStateUpdater({_local:v})};m.push({state:y,setState:S,dataContext:{_local:y||n.data?._local,_global:l?n.data?._global:n.data?._global||i?.state?.get?.(),_computed:n.data?._computed}}),window.__g7LayoutContextStack=m,j.log(`[handleOpenModal] 레이아웃 컨텍스트 스택에 push, 스택 크기: ${m.length}, state:`,y,l?"(direct)":"(fallback via G7Core)")}else j.warn(`[handleOpenModal] 컨텍스트 스택에 push 실패 - setState: ${!!n.setState}, state: ${n.state!==void 0}, G7Core: ${!!i?.state?.getLocal}`);const f=[...r,e];this.globalStateUpdater({modalStack:f,activeModal:e});const h=Fn();if(h?.isEnabled()){const m=r.length>0?r[r.length-1]:void 0;h.trackModalOpen?.({modalId:e,modalName:e,scopeType:"isolated",parentModalId:m,initialState:n.state?{...n.state}:{}})}}async handleCloseModal(e){if(!this.globalStateUpdater){j.warn("Global state updater is not set for closeModal");return}const n=e?.data?._global?.modalStack||[],r=n.length>0?n[n.length-1]:null,i=n.slice(0,-1),l=i.length>0?i[i.length-1]:null,c=window.__g7LayoutContextStack||[];if(c.length>0){const d=c[c.length-1];d&&(d.dataContext=void 0),c.pop(),window.__g7LayoutContextStack=c,j.log(`[handleCloseModal] 레이아웃 컨텍스트 스택에서 pop, 스택 크기: ${c.length}`)}if(r){const d=Fn();d?.isEnabled()&&d.trackModalClose?.(r,e?.state)}this.globalStateUpdater({modalStack:i,activeModal:l})}async handleShowAlert(e,n){let r=e;this.translationEngine&&this.translationContext&&e.startsWith("$t:")&&(r=this.translationEngine.resolveTranslations(e,this.translationContext,n.data)),alert(r)}async handleToast(e,n){const{type:r="info",message:i,icon:l,duration:c}=e;if(r==="error"){const f=n.data?.error;if((f?.error_code==="identity_verification_required"||f?.data?.error_code==="identity_verification_required")&&St.consumeDomainNoticeShown()){j.log("[Toast] IDV 도메인 안내 표출됨 — 중복 가드 토스트 1건 skip");return}}let d=i;if(this.translationEngine&&this.translationContext&&i?.startsWith("$t:")&&(d=this.translationEngine.resolveTranslations(i,this.translationContext,n.data)),this.globalStateUpdater){const h={id:`toast_${Date.now()}_${Math.random().toString(36).substring(2,9)}`,type:r,message:d,...l&&{icon:l},...c&&{duration:c}},v=[...window.G7Core?.state?.get()?.toasts||[],h];this.globalStateUpdater({toasts:v})}else j.log(`[Toast ${r}] ${d}`)}async handleSwitch(e,n){const{cases:r}=e;if(!r){j.warn("switch handler requires cases property");return}const i=this.resolveParams(e.params,n.data);let l;if(i?.value!==void 0?(l=i.value,j.log("switch handler: using params.value as case key:",l)):(l=n.data?.$args?.[0],j.log("switch handler: using $args[0] as case key:",l)),l==null){if(r.default)return j.log("switch handler: case key is undefined, using default case"),await this.executeAction(r.default,n);j.warn("switch handler: case key is not defined and no default case");return}const c=String(l);let d=r[c];if(!d&&r.default&&(j.log(`switch handler: no case found for key "${c}", using default case`),d=r.default),!d){j.warn(`switch handler: no case found for key "${c}" and no default case`);return}return await this.executeAction(d,n)}async handleConditions(e,n){const{conditions:r}=e;if(!r||!Array.isArray(r)){j.warn("conditions handler requires conditions array");return}const i=n.data||{},l=tm(r,i,this.bindingEngine);if(!l.matched){j.log("conditions handler: no matching branch found");return}const c=r[l.branchIndex];if(j.log(`conditions handler: matched branch ${l.branchIndex}`),!c.then){j.warn('conditions handler: matched branch has no "then" action');return}return Array.isArray(c.then)?await this.handleSequence({...e,actions:c.then},n):await this.executeAction(c.then,n)}handleStartInterval(e,n){const r=typeof e.id=="string"?e.id:"",i=Number(e.intervalMs??1e3),l=Array.isArray(e.actions)?e.actions:[];if(r===""||!l.length||i<=0)return j.warn("startInterval requires non-empty id, positive intervalMs, and actions array"),{success:!1};const c=this.intervals.get(r);c&&(clearInterval(c),this.intervals.delete(r));const d=setInterval(()=>{for(const f of l)this.executeAction(f,n).catch(h=>{j.error(`[startInterval:${r}] tick action failed`,h)})},i);return this.intervals.set(r,d),{success:!0,id:r}}handleStopInterval(e){const n=typeof e.id=="string"?e.id:"";if(n==="")return j.warn("stopInterval requires id parameter"),{success:!1};const r=this.intervals.get(n);return r&&(clearInterval(r),this.intervals.delete(n)),{success:!0,id:n}}stopAllIntervals(){for(const e of this.intervals.values())clearInterval(e);this.intervals.clear()}async handleSequence(e,n){const r=e.actions||e.params?.actions;if(!r||!Array.isArray(r)||r.length===0)return j.warn("sequence handler requires non-empty actions array"),[];const i=Fn(),l=i?.isEnabled()&&i.startSequenceExecution?.({eventType:e.type})||"";window.__g7SequenceLocalSync=void 0;const c=[];let d,f=n.state?{...n.state}:{},h=n.isolatedContext?.state?{...n.isolatedContext.state}:{},m=n.data?._computed||{};const y=window.G7Core,S=()=>({_global:y?.state?.get()||{},_local:{...f},_isolated:Object.keys(h).length>0?{...h}:void 0});for(let v=0;v0){const k={},O={...n.data,_local:f,_computed:k,$computed:k,_isolated:h};for(const[P,G]of Object.entries($))if(typeof G=="string"){const B=G.trim();if(B.startsWith("{{")&&B.endsWith("}}"))try{const W=B.slice(2,-2).trim();k[P]=Gn(W)?this.bindingEngine.evaluatePipeExpression(W,O,{skipCache:!0}):this.bindingEngine.evaluateExpression(W,O,{skipCache:!0})}catch{k[P]=m[P]}}m=k,j.log("[handleSequence] _computed recalculated after setState:",m)}}if(_.handler!=="setState"){const $=window.__g7SequenceLocalSync;if($&&$!==f){f=$,window.__g7SequenceLocalSync=void 0,j.log("[handleSequence] currentState synchronized from __g7SequenceLocalSync after custom handler:",_.handler);const k=n.data?._computedDefinitions;if(k&&Object.keys(k).length>0){const O={},P={...n.data,_local:f,_computed:O,$computed:O,_isolated:h};for(const[G,B]of Object.entries(k))if(typeof B=="string"){const W=B.trim();if(W.startsWith("{{")&&W.endsWith("}}"))try{const pe=W.slice(2,-2).trim();O[G]=Gn(pe)?this.bindingEngine.evaluatePipeExpression(pe,P,{skipCache:!0}):this.bindingEngine.evaluateExpression(pe,P,{skipCache:!0})}catch{O[G]=m[G]}}m=O,j.log("[handleSequence] _computed recalculated after custom handler:",m)}}}l&&i?.isEnabled()&&i.captureSequenceActionAfter?.(l,v,S(),Date.now()-x,L.data)}catch(L){throw l&&i?.isEnabled()&&(i.captureSequenceActionAfter?.(l,v,S(),Date.now()-x,void 0,L),i.endSequenceExecution?.(l,L)),j.error(`sequence handler: action[${v}] failed:`,L),L}}return window.__g7SequenceLocalSync=void 0,l&&i?.isEnabled()&&i.endSequenceExecution?.(l),c}async handleParallel(e,n){const r=e.actions||e.params?.actions;if(!r||!Array.isArray(r)||r.length===0)return j.warn("parallel handler requires non-empty actions array"),[];j.log(`parallel handler: executing ${r.length} actions in parallel`);const i=n.isolatedContext?{...n.isolatedContext,state:{...n.isolatedContext.state}}:null,l=r.map((f,h)=>{const m={...n,isolatedContext:i};return this.executeAction(f,m).catch(y=>{throw j.error(`parallel handler: action[${h}] failed:`,y),y})}),c=await Promise.allSettled(l),d=c.filter(f=>f.status==="rejected").length;return d>0&&j.warn(`parallel handler: ${d}/${r.length} actions failed`),c}async handleLoadScript(e,n,r){const{src:i,id:l,async:c=!0,defer:d=!1}=e;if(!i)throw new Ut('loadScript handler requires "src" parameter',n);const f=l||`script_${i.replace(/[^a-zA-Z0-9]/g,"_")}`;return xs.loadedScripts.has(f)?(j.log(`loadScript: script already loaded, skipping: ${f}`),n.onLoad&&await this.executeAction(n.onLoad,r),!0):document.getElementById(f)?(j.log(`loadScript: script element already exists: ${f}`),xs.loadedScripts.add(f),n.onLoad&&await this.executeAction(n.onLoad,r),!0):(j.log(`loadScript: loading script: ${i}`),new Promise((m,y)=>{const S=document.createElement("script");S.id=f,S.src=i,S.async=c,S.defer=d,S.onload=async()=>{if(j.log(`loadScript: script loaded successfully: ${f}`),xs.loadedScripts.add(f),n.onLoad)try{await this.executeAction(n.onLoad,r)}catch(v){j.error("loadScript: onLoad action failed:",v)}m(!0)},S.onerror=v=>{j.error(`loadScript: failed to load script: ${i}`,v),y(new Ut(`Failed to load script: ${i}`,n))},document.head.appendChild(S)}))}async handleCallExternal(e,n,r){const i=e.constructor,l=e.args||{},c=e.method,d=e.methodArgs||[],f=e.callbackEvent,h=e.embedTarget,m=e.callbackSetState,y=e.callbackAction;if(!i)throw new Ut('callExternal handler requires "constructor" parameter',n);const S=this.getNestedProperty(window,i);if(!S||typeof S!="function")throw new Ut(`Constructor not found or not a function: ${i}. Make sure the script is loaded first using loadScript handler.`,n);j.log(`callExternal: calling constructor ${i}`);const v={...l};for(const[x,A]of Object.entries(l))A===!0&&(v[x]=L=>{if(j.log(`callExternal: callback triggered for ${x}`,L),f&&typeof window<"u"&&window.G7Core?.componentEvent&&window.G7Core.componentEvent.emit(f,L),m&&r.setState){const $=P=>{const G={};for(const[B,W]of Object.entries(P))typeof W=="string"?G[B]=this.getNestedProperty(L,W):typeof W=="object"&&W!==null&&(G[B]=$(W));return G},k=$(m);j.log("callExternal: callbackSetState mapping result",k);const O=this.deepMergeWithState(k,r.state||{});j.log("callExternal: merged with existing state",O),r.setState(O)}else f&&r.setState&&r.setState({[`${f.replace(/:/g,"_")}_result`]:L});if(y){const $={...r,data:{...r.data,$event:L}},k=Array.isArray(y)?y:[y];for(const O of k)try{this.executeAction(O,$)}catch(P){j.error("callExternal: callbackAction failed:",P)}}});const _=new S(v);if(c&&typeof _[c]=="function"){if(j.log(`callExternal: calling method ${c}`),c==="embed"&&h){const x=document.querySelector(h);if(x)return _[c](x,...d);throw new Ut(`Embed target element not found: ${h}`,n)}return _[c](...d)}return _}async handleCallExternalEmbed(e,n,r){const i=e.constructor,l=e.args||{},c=e.callbackSetState,d=e.callbackEvent,f=e.layerClassName,h=e.callbackAction;if(!i)throw new Ut('callExternalEmbed handler requires "constructor" parameter',n);const m=this.getNestedProperty(window,i);if(!m||typeof m!="function")throw new Ut(`Constructor not found or not a function: ${i}. Make sure the script is loaded first.`,n);j.log(`callExternalEmbed: creating layer for ${i}`);const{layer:y,closeLayer:S}=this.createEmbedLayer(f),v={...l};for(const[x,A]of Object.entries(l))A===!0&&(v[x]=L=>{if(j.log(`callExternalEmbed: callback triggered for ${x}`,L),S(),d&&typeof window<"u"&&window.G7Core?.componentEvent&&window.G7Core.componentEvent.emit(d,L),c&&r.setState){const $=P=>{const G={};for(const[B,W]of Object.entries(P))typeof W=="string"?G[B]=this.getNestedProperty(L,W):typeof W=="object"&&W!==null&&(G[B]=$(W));return G},k=$(c);j.log("callExternalEmbed: callbackSetState mapping result",k);const O=this.deepMergeWithState(k,r.state||{});j.log("callExternalEmbed: merged with existing state",O),r.setState(O)}if(h){const $={...r,data:{...r.data,$event:L}},k=Array.isArray(h)?h:[h];for(const O of k)try{this.executeAction(O,$)}catch(P){j.error("callExternalEmbed: callbackAction failed:",P)}}});const _=new m(v);if(typeof _.embed=="function")_.embed(y),j.log("callExternalEmbed: embedded in layer");else throw S(),new Ut(`Constructor ${i} does not have embed method`,n);return _}isImeComposing(e){return e?.isComposing===!0||e?.keyCode===229}createEmbedLayer(e){const n=document.createElement("div");n.id="g7-embed-overlay",n.style.cssText=` position: fixed; inset: 0; background-color: rgba(0, 0, 0, 0.5); @@ -50,11 +50,11 @@ Error generating stack: `+u.message+` justify-content: center; color: #666; transition: background-color 0.2s; - `,i.onmouseenter=()=>{i.style.backgroundColor="rgba(0, 0, 0, 0.2)"},i.onmouseleave=()=>{i.style.backgroundColor="rgba(0, 0, 0, 0.1)"};const l=()=>{n.parentNode&&n.parentNode.removeChild(n)};i.onclick=l;const c=d=>{this.isImeComposing(d)||d.key==="Escape"&&(l(),document.removeEventListener("keydown",c))};return document.addEventListener("keydown",c),n.onclick=d=>{d.target===n&&l()},r.appendChild(i),n.appendChild(r),document.body.appendChild(n),{overlay:n,layer:r,closeLayer:l}}getNestedProperty(e,n){return n.split(".").reduce((r,i)=>r&&r[i]!==void 0?r[i]:void 0,e)}async handleSaveToLocalStorage(e,n){const{key:r,value:i}=e;if(!r)return j.error("saveToLocalStorage: key parameter is required"),!1;try{const l=typeof i=="string"?i:JSON.stringify(i);return localStorage.setItem(r,l),j.log(`saveToLocalStorage: saved ${r}`,i),!0}catch(l){return j.error("saveToLocalStorage: failed to save",{key:r,error:l}),!1}}async handleLoadFromLocalStorage(e,n){const{key:r,target:i,stateKey:l,defaultValue:c}=e;if(!r)return j.error("loadFromLocalStorage: key parameter is required"),c;try{const d=localStorage.getItem(r);if(d===null)return j.log(`loadFromLocalStorage: no value found for ${r}, using default`),l&&n.setState&&n.setState({[l]:c}),c;let f;try{f=JSON.parse(d)}catch{f=d}return j.log(`loadFromLocalStorage: loaded ${r}`,f),l&&n.setState&&n.setState({[l]:f}),f}catch(d){return j.error("loadFromLocalStorage: failed to load",{key:r,error:d}),c}}async handleCustomAction(e,n){const r=this.customHandlers.get(e.handler);if(!r){if(this.previewMode){j.warn(`[Preview] Unknown action handler "${e.handler}" — skipped (preview mode)`);return}const i=new Ut(`Unknown action handler: ${e.handler}`,e);throw i.unknownHandler=!0,i}return await r(e,n)}resolveParams(e,n){if(!e)return{};const r={};for(const[i,l]of Object.entries(e))i.includes("{{")&&j.warn(`[resolveParams] setState params의 키에 표현식이 포함되어 있습니다: "${i}". 키는 해석되지 않습니다. 배열 항목 수정은 .map()/.filter() 패턴을 사용하세요.`),typeof l=="string"&&l.includes("{{")?r[i]=this.evaluateExpression(l,n):typeof l=="string"?r[i]=l:Array.isArray(l)?r[i]=l.map(c=>typeof c=="string"&&c.includes("{{")?this.evaluateExpression(c,n):c):typeof l=="object"&&l!==null&&!Array.isArray(l)&&Object.getPrototypeOf(l)!==Object.prototype&&Object.getPrototypeOf(l)!==null?r[i]=l:typeof l=="object"&&l!==null?r[i]=this.resolveParams(l,n):r[i]=l;return r}resolveValue(e,n){return n?this.bindingEngine.resolveBindings(e,n,{skipCache:!0}):e}evaluateExpressions(e,n){let r={};for(const[i,l]of Object.entries(e))if(i==="..."){let c=l;typeof l=="string"&&l.includes("{{")&&(c=this.evaluateExpression(l,n)),c&&typeof c=="object"&&!Array.isArray(c)&&(r={...r,...c})}else typeof l=="string"&&l.includes("{{")?r[i]=this.evaluateExpression(l,n):typeof l=="object"&&l!==null&&!Array.isArray(l)?r[i]=this.evaluateExpressions(l,n):r[i]=l;return r}evaluateExpressionsIfNeeded(e,n){const r={};for(const[i,l]of Object.entries(e))typeof l=="string"&&l.includes("{{")?r[i]=this.evaluateExpression(l,n):r[i]=l;return r}evaluateExpression(e,n){if(!n)return e;const r=Da(e);if(r===null){let c=n;if(e.includes("_global")){const f=window.G7Core?.state?.get()?._global;f&&(c={...n,_global:f})}if(e.includes("_computed")||e.includes("$computed")){const f=window.__g7ActionContext?.computedRef?.current;f&&Object.keys(f).length>0&&(c={...c,_computed:f,$computed:f})}return this.bindingEngine.resolveBindings(e,c,{skipCache:!0})}let i=r;i=i.replace(/\$args\.(\d+)/g,"$args[$1]");let l=n;if(i.includes("_global")){const d=window.G7Core?.state?.get()?._global;d&&(l={...n,_global:d})}if(i.includes("_computed")||i.includes("$computed")){const d=window.__g7ActionContext?.computedRef?.current;d&&Object.keys(d).length>0&&(l={...l,_computed:d,$computed:d})}i.includes("_global.modules")&&(j.log("[evaluateExpression] expression:",i),j.log("[evaluateExpression] dataContext._global:",l._global),j.log("[evaluateExpression] dataContext._global?.modules:",l._global?.modules));try{const c=Gn(i)?this.bindingEngine.evaluatePipeExpression(i,l,{skipCache:!0}):this.bindingEngine.evaluateExpression(i,l);return i.includes("_global.modules")&&j.log("[evaluateExpression] result:",c),typeof c=="string"&&c.startsWith("$t:")&&this.translationEngine&&this.translationContext?this.translationEngine.resolveTranslations(c,this.translationContext,n):c}catch(c){return j.error("Expression evaluation failed:",e,c),e}}setDefaultContext(e){this.defaultContext={...this.defaultContext,...e}}setGlobalStateUpdater(e){this.globalStateUpdater=e}getGlobalStateUpdater(){return this.globalStateUpdater}async dispatchAction(e,n){const r={...this.defaultContext,...n,data:{...this.defaultContext.data,...n?.data}};if(e.confirm){let i=this.resolveValue(e.confirm,r.data);if(this.translationEngine&&this.translationContext&&i.startsWith("$t:")&&(i=this.translationEngine.resolveTranslations(i,this.translationContext,r.data)),!confirm(i))return{success:!1}}try{return await this.executeAction(e,r)}catch(i){if(j.error("dispatchAction failed:",i),e.onError){const l=i instanceof Ut&&i.originalError?{message:i.originalError.message,response:i.originalError.response}:{message:i instanceof Error?i.message:String(i)},c={...r,data:{...r.data,error:l}},d=Array.isArray(e.onError)?e.onError:[e.onError];for(const f of d)await this.executeAction(f,c)}return{success:!1,error:i instanceof Error?i:new Error(String(i))}}}registerHandler(e,n,r){this.customHandlers.set(e,n);const i=Fn();i?.isEnabled()&&i.trackHandlerRegistration(e,r?.category??"custom",r?.description,r?.source)}unregisterHandler(e){this.customHandlers.delete(e);const n=Fn();n?.isEnabled()&&n.trackHandlerUnregistration(e)}getRegisteredHandlers(){return Array.from(this.customHandlers.keys())}getHandler(e){return this.customHandlers.get(e)}normalizeDebounceConfig(e){return typeof e=="number"?{delay:e,leading:!1,trailing:!0}:{delay:e.delay,leading:e.leading??!1,trailing:e.trailing??!0}}extractEventData(e){const n=e.target;if(n&&!("tagName"in n)){const l={type:e.type??"custom",target:{value:n.value,name:n.name??""}};return e._changedKeys&&(l._changedKeys=e._changedKeys),l}const i=n?{value:n.value,name:n.name??"",checked:n.checked??!1,type:n.type??"",tagName:n.tagName}:{};if(e.type==="scroll"&&n){const l=n;i.scrollHeight=l.scrollHeight??0,i.scrollTop=l.scrollTop??0,i.clientHeight=l.clientHeight??0,i.scrollLeft=l.scrollLeft??0,i.clientWidth=l.clientWidth??0,i.scrollWidth=l.scrollWidth??0}return{type:e.type,target:n?i:null}}executeDebouncedAction(e,n,r,i,l){const c={...r,$event:n,$args:l},d={type:n.type,target:n.target,preventDefault:()=>{},stopPropagation:()=>{}};this.createHandler(e,c,i)(d)}handleDebouncedAction(e,n,r,i,l,c){const d=this.normalizeDebounceConfig(e.debounce),f=l||`default-${e.handler}-${Date.now()}`,h=this.extractEventData(n),m=h._changedKeys;if(m&&Array.isArray(m)&&h?.target?.value&&typeof h.target.value=="object"&&!Array.isArray(h.target.value)){const _=this.debounceAccumulatedValues.get(f);if(_){const x={..._};for(const A of m)x[A]=h.target.value[A];h.target.value=x}this.debounceAccumulatedValues.set(f,h.target.value)}const y=this.debounceTimers.get(f);y&&(clearTimeout(y),this.debounceTimers.delete(f));const S=Fn();S?.isEnabled()&&S.trackAction({handler:typeof e.handler=="string"?e.handler:String(e.handler),type:e.type,status:"pending",params:e.params,debounce:{delay:d.delay,status:"pending",scheduledAt:Date.now()}});const v=!this.debounceTimers.has(f+"_leading");if(d.leading&&v&&(this.debounceTimers.set(f+"_leading",setTimeout(()=>{},0)),this.executeDebouncedAction(e,h,r,i,c),S?.isEnabled()&&S.trackAction({handler:typeof e.handler=="string"?e.handler:String(e.handler),type:e.type,status:"success",params:e.params,debounce:{delay:d.delay,status:"executed",executedAt:Date.now(),mode:"leading"}})),d.trailing){const _=()=>{this.executeDebouncedAction(e,h,r,i,c),S?.isEnabled()&&S.trackAction({handler:typeof e.handler=="string"?e.handler:String(e.handler),type:e.type,status:"success",params:e.params,debounce:{delay:d.delay,status:"executed",executedAt:Date.now(),mode:"trailing"}})},x=setTimeout(()=>{this.debounceTimers.delete(f),this.debounceTimers.delete(f+"_leading"),this.pendingDebounceFlushers.delete(f),this.debounceAccumulatedValues.delete(f),_()},d.delay);this.debounceTimers.set(f,x),this.pendingDebounceFlushers.set(f,_)}}clearDebounceTimers(e){if(e)for(const[n,r]of this.debounceTimers)n.startsWith(e+"-")&&(clearTimeout(r),this.debounceTimers.delete(n),this.pendingDebounceFlushers.delete(n),this.debounceAccumulatedValues.delete(n));else{for(const n of this.debounceTimers.values())clearTimeout(n);this.debounceTimers.clear(),this.pendingDebounceFlushers.clear(),this.debounceAccumulatedValues.clear()}}debouncedCall(e,n,r){const i=this.debounceTimers.get(e);i&&(clearTimeout(i),this.debounceTimers.delete(e));const l=setTimeout(()=>{this.debounceTimers.delete(e),this.pendingDebounceFlushers.delete(e),r()},n);this.debounceTimers.set(e,l),this.pendingDebounceFlushers.set(e,r)}flushPendingDebounceTimers(){if(this.pendingDebounceFlushers.size===0)return;const e=new Map(this.pendingDebounceFlushers);for(const[n,r]of e){const i=this.debounceTimers.get(n);i&&(clearTimeout(i),this.debounceTimers.delete(n)),this.debounceTimers.delete(n+"_leading"),this.pendingDebounceFlushers.delete(n),r()}this.globalStateUpdater&&this.globalStateUpdater({})}bindActionsToProps(e,n,r){const i={...e};if(e.actions&&Array.isArray(e.actions)){const l=new Map;for(const m of e.actions){const y=this.resolveActionRef(m),S=y.event?this.normalizeEventPropName(y.event):this.getEventHandlerName(y.type);l.has(S)||l.set(S,[]),l.get(S).push(y)}const c=e.name||e.id||"unknown",d=l.has("onDrop"),f=l.has("onDragOver"),h=l.has("onDragEnter");d&&!f&&(i.onDragOver=m=>{m.preventDefault()}),d&&!h&&(i.onDragEnter=m=>{m.preventDefault()});for(const[m,y]of l)i[m]=(...S)=>{for(const v of y){const _=S[0],x=_&&typeof _=="object"&&"preventDefault"in _;if(x&&(m==="onDragOver"||m==="onDrop")&&_.preventDefault(),x&&v.key&&"key"in _){if(this.isImeComposing(_)){j.log("Key filter skipped (IME composing):",v.key);continue}if(_.key!==v.key){j.log("Key filter not matched:",v.key,"actual:",_.key);continue}j.log("Key filter matched:",v.key)}if(v.debounce){const A=`${c}-${v.handler}-${m}`,L=_&&typeof _=="object"&&!("preventDefault"in _)&&"target"in _&&_.target!==null;let $;if(x)$=_;else if(L){const O={type:"custom",target:_.target,preventDefault:()=>{},stopPropagation:()=>{}};_._changedKeys&&(O._changedKeys=_._changedKeys),$=O}else $=new Event("custom");const k=v.event?{...n,$args:S}:n;this.handleDebouncedAction(v,$,k,r,A,S)}else if(this.flushPendingDebounceTimers(),v.event){const A={...n,$args:S},L=this.resolveEventForHandler(_,x);this.createHandler(v,A,r)(L)}else if(x)this.createHandler(v,n,r)(_);else if(_&&typeof _=="object"&&!("preventDefault"in _)&&"target"in _&&_.target!==null){const L={type:"custom",target:_.target,preventDefault:()=>{},stopPropagation:()=>{}};this.createHandler(v,n,r)(L)}}}}return i}getEventHandlerName(e){return Km[e]||`on${e.charAt(0).toUpperCase()}${e.slice(1)}`}normalizeEventPropName(e){return Km[e]??e}resolveEventForHandler(e,n){if(n)return e;if(!(e&&typeof e=="object"&&!("preventDefault"in e)&&"target"in e&&e.target!==null))return new Event("custom");const i={type:"custom",target:e.target,preventDefault:()=>{},stopPropagation:()=>{}};return e._changedKeys&&(i._changedKeys=e._changedKeys),i}sanitizeForDevTools(e,n=5){const r=new WeakSet,i=(l,c)=>{if(l==null||typeof l=="string"||typeof l=="number"||typeof l=="boolean")return l;if(c>n)return"[Max Depth Exceeded]";if(typeof l=="function")return`[Function: ${l.name||"anonymous"}]`;if(l instanceof Element)return`[Element: ${l.tagName}${l.className?"."+l.className.split(" ").join("."):""}]`;if(l instanceof Event)return`[Event: ${l.type}]`;if(Array.isArray(l)){if(r.has(l))return"[Circular Array]";r.add(l);const d=l.slice(0,10).map(f=>i(f,c+1));return l.length>10&&d.push(`... ${l.length-10} more items`),d}if(typeof l=="object"){if(r.has(l))return"[Circular Reference]";r.add(l);const d={},f=Object.keys(l),h=f.slice(0,20);for(const m of h)try{d[m]=i(l[m],c+1)}catch{d[m]="[Error accessing property]"}return f.length>20&&(d["..."]=`${f.length-20} more properties`),d}return String(l)};return i(e,0)}};M(xs,"loadedScripts",new Set);let ko=xs,pc=null;function Wm(s){return pc||(pc=new ko(s)),pc}function pE(s){pc=s}const Ym=dt("TransitionManager");class gE{constructor(){M(this,"isPending",!1);M(this,"subscribers",new Set)}setPending(e){this.isPending!==e&&(Ym.log("setPending:",{from:this.isPending,to:e,stack:new Error().stack}),this.isPending=e,this.notifySubscribers())}getIsPending(){return this.isPending}subscribe(e){return this.subscribers.add(e),()=>{this.subscribers.delete(e)}}notifySubscribers(){Ym.log("notifySubscribers:",{isPending:this.isPending,subscriberCount:this.subscribers.size}),this.subscribers.forEach(e=>{e(this.isPending)})}clearSubscribers(){this.subscribers.clear()}}const Ur=new gE,gc=dt("TransitionContext"),Xm=N.createContext({isTransitioning:!1}),Cf=({children:s})=>{const[e,n]=N.useState(()=>{const i=Ur.getIsPending();return gc.log("Initial state:",i),i});N.useEffect(()=>{gc.log("Subscribing to TransitionManager");const i=Ur.subscribe(l=>{gc.log("Received isPending update:",l),n(l)});return()=>{gc.log("Unsubscribing from TransitionManager"),i()}},[]);const r=N.useMemo(()=>({isTransitioning:e}),[e]);return ft.jsx(Xm.Provider,{value:r,children:s})},Jm=()=>N.useContext(Xm),mc="__g7LocalInitTracking";function Ef(){const s=globalThis;return s[mc]||(s[mc]={hash:"",timestamp:void 0,consumed:void 0}),s[mc]}function mE(){const s=globalThis;s[mc]={hash:"",timestamp:void 0,consumed:void 0}}function yE(s){Ef().consumed=s}function bE(s){return Ef().consumed===s}function vE(s){return s.globalTrackedKey!==s.trackingKey?"apply":s.instanceHandledKey===s.trackingKey?"skip":"prune"}function SE(s,e){return typeof s=="number"&&typeof e=="number"?Math.max(s,e):e??s}function wE(s,e){if(e===void 0)return s;if(!(s!==null&&typeof s=="object"&&e!==null&&typeof e=="object"&&!bE(s)))return e;const{_forceLocalInit:r,...i}=s,{_forceLocalInit:l,...c}=e,d={...i,...c},f=SE(r,l);return f!==void 0&&(d._forceLocalInit=f),d}function CE(s){return s<768?"mobile":s<1024?"tablet":"desktop"}function Qm(s){const e=CE(s);return{width:s,isMobile:e==="mobile",isTablet:e==="tablet",isDesktop:e==="desktop",matchedPreset:e}}const _f=N.createContext(Qm(1024)),yc=({children:s,overrideWidth:e})=>{const[n,r]=N.useState(()=>Si.getWidth());N.useEffect(()=>{const c=Si.subscribe(d=>{r(d)});return()=>{c()}},[]);const i=e??n,l=N.useMemo(()=>Qm(i),[i]);return ft.jsx(_f.Provider,{value:l,children:s})},Af=()=>N.useContext(_f);window.G7Core?.createLogger?.("Core:State");function EE(s,e,n,r){const{syncOnControlledChange:i=!0,isEqual:l}=r??{},c=s!==void 0;N.useRef(c);const[d,f]=N.useState(s!==void 0?s:e),h=d,m=N.useRef(s),y=N.useRef(!1);N.useEffect(()=>{if(y.current){m.current=s;return}i&&c&&s!==m.current&&(l?!l(d,s):d!==s)&&f(s),m.current=s},[s,c,i,l,d]);const S=N.useCallback(v=>{const _=typeof v=="function"?v(h):v;(l?l(h,_):h===_)||(y.current=!0,f(_),n?.(_),requestAnimationFrame(()=>{y.current=!1}))},[h,c,n,l]);return[h,S]}function _E(s,e){return s===e?!0:s.length!==e.length?!1:s.every((n,r)=>n===e[r])}function Zm(s,e){if(s===e)return!0;const n=Object.keys(s),r=Object.keys(e);return n.length!==r.length?!1:n.every(i=>s[i]===e[i])}const ey=N.createContext({}),AE=({children:s,value:e})=>ft.jsx(ey.Provider,{value:e,children:s}),xE=()=>N.useContext(ey),TE=(s,e)=>{if(!s)return;const n=e.split(".");let r=s;for(const i of n){if(r==null)return;r=r[i]}return r},kE=(s,e,n)=>{const r=e.split(".");if(r.length===1)return{...s,[r[0]]:n};const i={...s};let l=i;for(let c=0;c{hs.warn("IsolatedStateContext not available: setState called outside IsolatedStateProvider")},getState:()=>{},mergeState:()=>{hs.warn("IsolatedStateContext not available: mergeState called outside IsolatedStateProvider")},stateRef:{current:{}},scopeId:""},ty=N.createContext(RE);let DE=0;function OE(){return`isolated-${++DE}-${Date.now().toString(36)}`}function ny(s,e){if(e==null)return s;if(typeof e!="object"||Array.isArray(e))return e;const n={...s};for(const r of Object.keys(e)){const i=e[r],l=s?.[r];i!==null&&typeof i=="object"&&!Array.isArray(i)&&l!==null&&typeof l=="object"&&!Array.isArray(l)?n[r]=ny(l,i):n[r]=i}return n}function LE(s,e){return e?e.split(".").reduce((n,r)=>n?.[r],s):s}function $E(s,e,n){const r=e.split("."),i={...s};let l=i;for(let c=0;c{const i=N.useRef(e||OE()).current,[l,c]=N.useState(s),d=N.useRef(l);d.current=l;const f=N.useCallback(v=>LE(d.current,v),[]),h=N.useCallback((v,_)=>{c(x=>{const A=$E(x,v,_);return hs.log(`[${i}] setState: ${v} =`,_),A})},[i]),m=N.useCallback((v,_="deep")=>{c(x=>{let A;return _==="replace"?A=v:_==="shallow"?A={...x,...v}:A=ny(x,v),hs.log(`[${i}] mergeState (${_}):`,v),A})},[i]),y=N.useMemo(()=>({state:l,setState:h,getState:f,mergeState:m,stateRef:d,scopeId:i}),[l,h,f,m,i]),S=N.useMemo(()=>({state:d.current,setState:h,getState:f,mergeState:m}),[h,f,m]);return N.useEffect(()=>{const v=window.G7Core,_=window.__g7IsolatedStates||{};return window.__g7IsolatedStates||(window.__g7IsolatedStates=_),_[i]=S,v&&(v._isolatedStates||(v._isolatedStates={}),v._isolatedStates[i]=l),v?.devTools?.isEnabled?.()&&v.devTools.emit?.("isolated:created",{id:i,state:l}),hs.log(`[${i}] IsolatedStateProvider mounted with initial state:`,l),()=>{delete _[i],v?._isolatedStates&&delete v._isolatedStates[i],v?.devTools?.isEnabled?.()&&v.devTools.emit?.("isolated:destroyed",{id:i}),hs.log(`[${i}] IsolatedStateProvider unmounted`)}},[i,S]),N.useEffect(()=>{const v=window.G7Core,_=window.__g7IsolatedStates;_?.[i]&&(_[i].state=l),v?._isolatedStates&&(v._isolatedStates[i]=l),v?.devTools?.isEnabled?.()&&v.devTools.emit?.("isolated:updated",{id:i,state:l})},[l,i]),ft.jsx(ty.Provider,{value:y,children:n})},NE=()=>{const s=N.useContext(ty);return s.scopeId?s:null};var Ma=Rg();function IE(){for(var s=arguments.length,e=new Array(s),n=0;nr=>{e.forEach(i=>i(r))},e)}const bc=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function ps(s){const e=Object.prototype.toString.call(s);return e==="[object Window]"||e==="[object global]"}function xf(s){return"nodeType"in s}function Mn(s){var e,n;return s?ps(s)?s:xf(s)&&(e=(n=s.ownerDocument)==null?void 0:n.defaultView)!=null?e:window:window}function Tf(s){const{Document:e}=Mn(s);return s instanceof e}function Ro(s){return ps(s)?!1:s instanceof Mn(s).HTMLElement}function ry(s){return s instanceof Mn(s).SVGElement}function gs(s){return s?ps(s)?s.document:xf(s)?Tf(s)?s:Ro(s)||ry(s)?s.ownerDocument:document:document:document}const Pr=bc?N.useLayoutEffect:N.useEffect;function kf(s){const e=N.useRef(s);return Pr(()=>{e.current=s}),N.useCallback(function(){for(var n=arguments.length,r=new Array(n),i=0;i{s.current=setInterval(r,i)},[]),n=N.useCallback(()=>{s.current!==null&&(clearInterval(s.current),s.current=null)},[]);return[e,n]}function Do(s,e){e===void 0&&(e=[s]);const n=N.useRef(s);return Pr(()=>{n.current!==s&&(n.current=s)},e),n}function Oo(s,e){const n=N.useRef();return N.useMemo(()=>{const r=s(n.current);return n.current=r,r},[...e])}function vc(s){const e=kf(s),n=N.useRef(null),r=N.useCallback(i=>{i!==n.current&&e?.(i,n.current),n.current=i},[]);return[n,r]}function Rf(s){const e=N.useRef();return N.useEffect(()=>{e.current=s},[s]),e.current}let Df={};function Lo(s,e){return N.useMemo(()=>{if(e)return e;const n=Df[s]==null?0:Df[s]+1;return Df[s]=n,s+"-"+n},[s,e])}function ay(s){return function(e){for(var n=arguments.length,r=new Array(n>1?n-1:0),i=1;i{const d=Object.entries(c);for(const[f,h]of d){const m=l[f];m!=null&&(l[f]=m+s*h)}return l},{...e})}}const ms=ay(1),$o=ay(-1);function HE(s){return"clientX"in s&&"clientY"in s}function Of(s){if(!s)return!1;const{KeyboardEvent:e}=Mn(s.target);return e&&s instanceof e}function zE(s){if(!s)return!1;const{TouchEvent:e}=Mn(s.target);return e&&s instanceof e}function Lf(s){if(zE(s)){if(s.touches&&s.touches.length){const{clientX:e,clientY:n}=s.touches[0];return{x:e,y:n}}else if(s.changedTouches&&s.changedTouches.length){const{clientX:e,clientY:n}=s.changedTouches[0];return{x:e,y:n}}}return HE(s)?{x:s.clientX,y:s.clientY}:null}const Mo=Object.freeze({Translate:{toString(s){if(!s)return;const{x:e,y:n}=s;return"translate3d("+(e?Math.round(e):0)+"px, "+(n?Math.round(n):0)+"px, 0)"}},Scale:{toString(s){if(!s)return;const{scaleX:e,scaleY:n}=s;return"scaleX("+e+") scaleY("+n+")"}},Transform:{toString(s){if(s)return[Mo.Translate.toString(s),Mo.Scale.toString(s)].join(" ")}},Transition:{toString(s){let{property:e,duration:n,easing:r}=s;return e+" "+n+"ms "+r}}}),iy="a,frame,iframe,input:not([type=hidden]):not(:disabled),select:not(:disabled),textarea:not(:disabled),button:not(:disabled),*[tabindex]";function UE(s){return s.matches(iy)?s:s.querySelector(iy)}const PE={display:"none"};function BE(s){let{id:e,value:n}=s;return Ye.createElement("div",{id:e,style:PE},n)}function qE(s){let{id:e,announcement:n,ariaLiveType:r="assertive"}=s;const i={position:"fixed",top:0,left:0,width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0 0 0 0)",clipPath:"inset(100%)",whiteSpace:"nowrap"};return Ye.createElement("div",{id:e,style:i,role:"status","aria-live":r,"aria-atomic":!0},n)}function GE(){const[s,e]=N.useState("");return{announce:N.useCallback(r=>{r!=null&&e(r)},[]),announcement:s}}const sy=N.createContext(null);function FE(s){const e=N.useContext(sy);N.useEffect(()=>{if(!e)throw new Error("useDndMonitor must be used within a children of ");return e(s)},[s,e])}function VE(){const[s]=N.useState(()=>new Set),e=N.useCallback(r=>(s.add(r),()=>s.delete(r)),[s]);return[N.useCallback(r=>{let{type:i,event:l}=r;s.forEach(c=>{var d;return(d=c[i])==null?void 0:d.call(c,l)})},[s]),e]}const KE={draggable:` + `,i.onmouseenter=()=>{i.style.backgroundColor="rgba(0, 0, 0, 0.2)"},i.onmouseleave=()=>{i.style.backgroundColor="rgba(0, 0, 0, 0.1)"};const l=()=>{n.parentNode&&n.parentNode.removeChild(n)};i.onclick=l;const c=d=>{this.isImeComposing(d)||d.key==="Escape"&&(l(),document.removeEventListener("keydown",c))};return document.addEventListener("keydown",c),n.onclick=d=>{d.target===n&&l()},r.appendChild(i),n.appendChild(r),document.body.appendChild(n),{overlay:n,layer:r,closeLayer:l}}getNestedProperty(e,n){return n.split(".").reduce((r,i)=>r&&r[i]!==void 0?r[i]:void 0,e)}async handleSaveToLocalStorage(e,n){const{key:r,value:i}=e;if(!r)return j.error("saveToLocalStorage: key parameter is required"),!1;try{const l=typeof i=="string"?i:JSON.stringify(i);return localStorage.setItem(r,l),j.log(`saveToLocalStorage: saved ${r}`,i),!0}catch(l){return j.error("saveToLocalStorage: failed to save",{key:r,error:l}),!1}}async handleLoadFromLocalStorage(e,n){const{key:r,target:i,stateKey:l,defaultValue:c}=e;if(!r)return j.error("loadFromLocalStorage: key parameter is required"),c;try{const d=localStorage.getItem(r);if(d===null)return j.log(`loadFromLocalStorage: no value found for ${r}, using default`),l&&n.setState&&n.setState({[l]:c}),c;let f;try{f=JSON.parse(d)}catch{f=d}return j.log(`loadFromLocalStorage: loaded ${r}`,f),l&&n.setState&&n.setState({[l]:f}),f}catch(d){return j.error("loadFromLocalStorage: failed to load",{key:r,error:d}),c}}async handleCustomAction(e,n){const r=this.customHandlers.get(e.handler);if(!r){if(this.previewMode){j.warn(`[Preview] Unknown action handler "${e.handler}" — skipped (preview mode)`);return}const i=new Ut(`Unknown action handler: ${e.handler}`,e);throw i.unknownHandler=!0,i}return await r(e,n)}resolveParams(e,n){if(!e)return{};const r={};for(const[i,l]of Object.entries(e))i.includes("{{")&&j.warn(`[resolveParams] setState params의 키에 표현식이 포함되어 있습니다: "${i}". 키는 해석되지 않습니다. 배열 항목 수정은 .map()/.filter() 패턴을 사용하세요.`),typeof l=="string"&&l.includes("{{")?r[i]=this.evaluateExpression(l,n):typeof l=="string"?r[i]=l:Array.isArray(l)?r[i]=l.map(c=>typeof c=="string"&&c.includes("{{")?this.evaluateExpression(c,n):c):typeof l=="object"&&l!==null&&!Array.isArray(l)&&Object.getPrototypeOf(l)!==Object.prototype&&Object.getPrototypeOf(l)!==null?r[i]=l:typeof l=="object"&&l!==null?r[i]=this.resolveParams(l,n):r[i]=l;return r}resolveValue(e,n){return n?this.bindingEngine.resolveBindings(e,n,{skipCache:!0}):e}evaluateExpressions(e,n){let r={};for(const[i,l]of Object.entries(e))if(i==="..."){let c=l;typeof l=="string"&&l.includes("{{")&&(c=this.evaluateExpression(l,n)),c&&typeof c=="object"&&!Array.isArray(c)&&(r={...r,...c})}else typeof l=="string"&&l.includes("{{")?r[i]=this.evaluateExpression(l,n):typeof l=="object"&&l!==null&&!Array.isArray(l)?r[i]=this.evaluateExpressions(l,n):r[i]=l;return r}evaluateExpressionsIfNeeded(e,n){const r={};for(const[i,l]of Object.entries(e))typeof l=="string"&&l.includes("{{")?r[i]=this.evaluateExpression(l,n):r[i]=l;return r}evaluateExpression(e,n){if(!n)return e;const r=Da(e);if(r===null){let c=n;if(e.includes("_global")){const f=window.G7Core?.state?.get()?._global;f&&(c={...n,_global:f})}if(e.includes("_computed")||e.includes("$computed")){const f=window.__g7ActionContext?.computedRef?.current;f&&Object.keys(f).length>0&&(c={...c,_computed:f,$computed:f})}return this.bindingEngine.resolveBindings(e,c,{skipCache:!0})}let i=r;i=i.replace(/\$args\.(\d+)/g,"$args[$1]");let l=n;if(i.includes("_global")){const d=window.G7Core?.state?.get()?._global;d&&(l={...n,_global:d})}if(i.includes("_computed")||i.includes("$computed")){const d=window.__g7ActionContext?.computedRef?.current;d&&Object.keys(d).length>0&&(l={...l,_computed:d,$computed:d})}i.includes("_global.modules")&&(j.log("[evaluateExpression] expression:",i),j.log("[evaluateExpression] dataContext._global:",l._global),j.log("[evaluateExpression] dataContext._global?.modules:",l._global?.modules));try{const c=Gn(i)?this.bindingEngine.evaluatePipeExpression(i,l,{skipCache:!0}):this.bindingEngine.evaluateExpression(i,l);return i.includes("_global.modules")&&j.log("[evaluateExpression] result:",c),typeof c=="string"&&c.startsWith("$t:")&&this.translationEngine&&this.translationContext?this.translationEngine.resolveTranslations(c,this.translationContext,n):c}catch(c){return j.error("Expression evaluation failed:",e,c),e}}setDefaultContext(e){this.defaultContext={...this.defaultContext,...e}}setGlobalStateUpdater(e){this.globalStateUpdater=e}getGlobalStateUpdater(){return this.globalStateUpdater}async dispatchAction(e,n){const r={...this.defaultContext,...n,data:{...this.defaultContext.data,...n?.data}};if(e.confirm){let i=this.resolveValue(e.confirm,r.data);if(this.translationEngine&&this.translationContext&&i.startsWith("$t:")&&(i=this.translationEngine.resolveTranslations(i,this.translationContext,r.data)),!confirm(i))return{success:!1}}try{return await this.executeAction(e,r)}catch(i){if(j.error("dispatchAction failed:",i),e.onError){const l=i instanceof Ut&&i.originalError?{message:i.originalError.message,response:i.originalError.response}:{message:i instanceof Error?i.message:String(i)},c={...r,data:{...r.data,error:l}},d=Array.isArray(e.onError)?e.onError:[e.onError];for(const f of d)await this.executeAction(f,c)}return{success:!1,error:i instanceof Error?i:new Error(String(i))}}}registerHandler(e,n,r){this.customHandlers.set(e,n);const i=Fn();i?.isEnabled()&&i.trackHandlerRegistration(e,r?.category??"custom",r?.description,r?.source)}unregisterHandler(e){this.customHandlers.delete(e);const n=Fn();n?.isEnabled()&&n.trackHandlerUnregistration(e)}getRegisteredHandlers(){return Array.from(this.customHandlers.keys())}getHandler(e){return this.customHandlers.get(e)}normalizeDebounceConfig(e){return typeof e=="number"?{delay:e,leading:!1,trailing:!0}:{delay:e.delay,leading:e.leading??!1,trailing:e.trailing??!0}}extractEventData(e){const n=e.target;if(n&&!("tagName"in n)){const l={type:e.type??"custom",target:{value:n.value,name:n.name??""}};return e._changedKeys&&(l._changedKeys=e._changedKeys),l}const i=n?{value:n.value,name:n.name??"",checked:n.checked??!1,type:n.type??"",tagName:n.tagName}:{};if(e.type==="scroll"&&n){const l=n;i.scrollHeight=l.scrollHeight??0,i.scrollTop=l.scrollTop??0,i.clientHeight=l.clientHeight??0,i.scrollLeft=l.scrollLeft??0,i.clientWidth=l.clientWidth??0,i.scrollWidth=l.scrollWidth??0}return{type:e.type,target:n?i:null}}executeDebouncedAction(e,n,r,i,l){const c={...r,$event:n,$args:l},d={type:n.type,target:n.target,preventDefault:()=>{},stopPropagation:()=>{}};this.createHandler(e,c,i)(d)}handleDebouncedAction(e,n,r,i,l,c){const d=this.normalizeDebounceConfig(e.debounce),f=l||`default-${e.handler}-${Date.now()}`,h=this.extractEventData(n),m=h._changedKeys;if(m&&Array.isArray(m)&&h?.target?.value&&typeof h.target.value=="object"&&!Array.isArray(h.target.value)){const _=this.debounceAccumulatedValues.get(f);if(_){const x={..._};for(const A of m)x[A]=h.target.value[A];h.target.value=x}this.debounceAccumulatedValues.set(f,h.target.value)}const y=this.debounceTimers.get(f);y&&(clearTimeout(y),this.debounceTimers.delete(f));const S=Fn();S?.isEnabled()&&S.trackAction({handler:typeof e.handler=="string"?e.handler:String(e.handler),type:e.type,status:"pending",params:e.params,debounce:{delay:d.delay,status:"pending",scheduledAt:Date.now()}});const v=!this.debounceTimers.has(f+"_leading");if(d.leading&&v&&(this.debounceTimers.set(f+"_leading",setTimeout(()=>{},0)),this.executeDebouncedAction(e,h,r,i,c),S?.isEnabled()&&S.trackAction({handler:typeof e.handler=="string"?e.handler:String(e.handler),type:e.type,status:"success",params:e.params,debounce:{delay:d.delay,status:"executed",executedAt:Date.now(),mode:"leading"}})),d.trailing){const _=()=>{this.executeDebouncedAction(e,h,r,i,c),S?.isEnabled()&&S.trackAction({handler:typeof e.handler=="string"?e.handler:String(e.handler),type:e.type,status:"success",params:e.params,debounce:{delay:d.delay,status:"executed",executedAt:Date.now(),mode:"trailing"}})},x=setTimeout(()=>{this.debounceTimers.delete(f),this.debounceTimers.delete(f+"_leading"),this.pendingDebounceFlushers.delete(f),this.debounceAccumulatedValues.delete(f),_()},d.delay);this.debounceTimers.set(f,x),this.pendingDebounceFlushers.set(f,_)}}clearDebounceTimers(e){if(e)for(const[n,r]of this.debounceTimers)n.startsWith(e+"-")&&(clearTimeout(r),this.debounceTimers.delete(n),this.pendingDebounceFlushers.delete(n),this.debounceAccumulatedValues.delete(n));else{for(const n of this.debounceTimers.values())clearTimeout(n);this.debounceTimers.clear(),this.pendingDebounceFlushers.clear(),this.debounceAccumulatedValues.clear()}}debouncedCall(e,n,r){const i=this.debounceTimers.get(e);i&&(clearTimeout(i),this.debounceTimers.delete(e));const l=setTimeout(()=>{this.debounceTimers.delete(e),this.pendingDebounceFlushers.delete(e),r()},n);this.debounceTimers.set(e,l),this.pendingDebounceFlushers.set(e,r)}flushPendingDebounceTimers(){if(this.pendingDebounceFlushers.size===0)return;const e=new Map(this.pendingDebounceFlushers);for(const[n,r]of e){const i=this.debounceTimers.get(n);i&&(clearTimeout(i),this.debounceTimers.delete(n)),this.debounceTimers.delete(n+"_leading"),this.pendingDebounceFlushers.delete(n),r()}this.globalStateUpdater&&this.globalStateUpdater({})}bindActionsToProps(e,n,r){const i={...e};if(e.actions&&Array.isArray(e.actions)){const l=new Map;for(const m of e.actions){const y=this.resolveActionRef(m),S=y.event?this.normalizeEventPropName(y.event):this.getEventHandlerName(y.type);l.has(S)||l.set(S,[]),l.get(S).push(y)}const c=e.name||e.id||"unknown",d=l.has("onDrop"),f=l.has("onDragOver"),h=l.has("onDragEnter");d&&!f&&(i.onDragOver=m=>{m.preventDefault()}),d&&!h&&(i.onDragEnter=m=>{m.preventDefault()});for(const[m,y]of l)i[m]=(...S)=>{for(const v of y){const _=S[0],x=_&&typeof _=="object"&&"preventDefault"in _;if(x&&(m==="onDragOver"||m==="onDrop")&&_.preventDefault(),x&&v.key&&"key"in _){if(this.isImeComposing(_)){j.log("Key filter skipped (IME composing):",v.key);continue}if(_.key!==v.key){j.log("Key filter not matched:",v.key,"actual:",_.key);continue}j.log("Key filter matched:",v.key)}if(v.debounce){const A=`${c}-${v.handler}-${m}`,L=_&&typeof _=="object"&&!("preventDefault"in _)&&"target"in _&&_.target!==null;let $;if(x)$=_;else if(L){const O={type:"custom",target:_.target,preventDefault:()=>{},stopPropagation:()=>{}};_._changedKeys&&(O._changedKeys=_._changedKeys),$=O}else $=new Event("custom");const k=v.event?{...n,$args:S}:n;this.handleDebouncedAction(v,$,k,r,A,S)}else if(this.flushPendingDebounceTimers(),v.event){const A={...n,$args:S},L=this.resolveEventForHandler(_,x);this.createHandler(v,A,r)(L)}else if(x)this.createHandler(v,n,r)(_);else if(_&&typeof _=="object"&&!("preventDefault"in _)&&"target"in _&&_.target!==null){const L={type:"custom",target:_.target,preventDefault:()=>{},stopPropagation:()=>{}};this.createHandler(v,n,r)(L)}}}}return i}getEventHandlerName(e){return Km[e]||`on${e.charAt(0).toUpperCase()}${e.slice(1)}`}normalizeEventPropName(e){return Km[e]??e}resolveEventForHandler(e,n){if(n)return e;if(!(e&&typeof e=="object"&&!("preventDefault"in e)&&"target"in e&&e.target!==null))return new Event("custom");const i={type:"custom",target:e.target,preventDefault:()=>{},stopPropagation:()=>{}};return e._changedKeys&&(i._changedKeys=e._changedKeys),i}sanitizeForDevTools(e,n=5){const r=new WeakSet,i=(l,c)=>{if(l==null||typeof l=="string"||typeof l=="number"||typeof l=="boolean")return l;if(c>n)return"[Max Depth Exceeded]";if(typeof l=="function")return`[Function: ${l.name||"anonymous"}]`;if(l instanceof Element)return`[Element: ${l.tagName}${l.className?"."+l.className.split(" ").join("."):""}]`;if(l instanceof Event)return`[Event: ${l.type}]`;if(Array.isArray(l)){if(r.has(l))return"[Circular Array]";r.add(l);const d=l.slice(0,10).map(f=>i(f,c+1));return l.length>10&&d.push(`... ${l.length-10} more items`),d}if(typeof l=="object"){if(r.has(l))return"[Circular Reference]";r.add(l);const d={},f=Object.keys(l),h=f.slice(0,20);for(const m of h)try{d[m]=i(l[m],c+1)}catch{d[m]="[Error accessing property]"}return f.length>20&&(d["..."]=`${f.length-20} more properties`),d}return String(l)};return i(e,0)}};M(xs,"loadedScripts",new Set);let ko=xs,gc=null;function Wm(s){return gc||(gc=new ko(s)),gc}function pE(s){gc=s}const Ym=dt("TransitionManager");class gE{constructor(){M(this,"isPending",!1);M(this,"subscribers",new Set)}setPending(e){this.isPending!==e&&(Ym.log("setPending:",{from:this.isPending,to:e,stack:new Error().stack}),this.isPending=e,this.notifySubscribers())}getIsPending(){return this.isPending}subscribe(e){return this.subscribers.add(e),()=>{this.subscribers.delete(e)}}notifySubscribers(){Ym.log("notifySubscribers:",{isPending:this.isPending,subscriberCount:this.subscribers.size}),this.subscribers.forEach(e=>{e(this.isPending)})}clearSubscribers(){this.subscribers.clear()}}const Ur=new gE,mc=dt("TransitionContext"),Xm=N.createContext({isTransitioning:!1}),Cf=({children:s})=>{const[e,n]=N.useState(()=>{const i=Ur.getIsPending();return mc.log("Initial state:",i),i});N.useEffect(()=>{mc.log("Subscribing to TransitionManager");const i=Ur.subscribe(l=>{mc.log("Received isPending update:",l),n(l)});return()=>{mc.log("Unsubscribing from TransitionManager"),i()}},[]);const r=N.useMemo(()=>({isTransitioning:e}),[e]);return ft.jsx(Xm.Provider,{value:r,children:s})},Jm=()=>N.useContext(Xm),yc="__g7LocalInitTracking";function Ef(){const s=globalThis;return s[yc]||(s[yc]={hash:"",timestamp:void 0,consumed:void 0}),s[yc]}function mE(){const s=globalThis;s[yc]={hash:"",timestamp:void 0,consumed:void 0}}function yE(s){Ef().consumed=s}function bE(s){return Ef().consumed===s}function vE(s){return s.globalTrackedKey!==s.trackingKey?"apply":s.instanceHandledKey===s.trackingKey?"skip":"prune"}function SE(s,e){return typeof s=="number"&&typeof e=="number"?Math.max(s,e):e??s}function wE(s,e){if(e===void 0)return s;if(!(s!==null&&typeof s=="object"&&e!==null&&typeof e=="object"&&!bE(s)))return e;const{_forceLocalInit:r,...i}=s,{_forceLocalInit:l,...c}=e,d={...i,...c},f=SE(r,l);return f!==void 0&&(d._forceLocalInit=f),d}function CE(s){return s<768?"mobile":s<1024?"tablet":"desktop"}function Qm(s){const e=CE(s);return{width:s,isMobile:e==="mobile",isTablet:e==="tablet",isDesktop:e==="desktop",matchedPreset:e}}const _f=N.createContext(Qm(1024)),bc=({children:s,overrideWidth:e})=>{const[n,r]=N.useState(()=>Si.getWidth());N.useEffect(()=>{const c=Si.subscribe(d=>{r(d)});return()=>{c()}},[]);const i=e??n,l=N.useMemo(()=>Qm(i),[i]);return ft.jsx(_f.Provider,{value:l,children:s})},Af=()=>N.useContext(_f);window.G7Core?.createLogger?.("Core:State");function EE(s,e,n,r){const{syncOnControlledChange:i=!0,isEqual:l}=r??{},c=s!==void 0;N.useRef(c);const[d,f]=N.useState(s!==void 0?s:e),h=d,m=N.useRef(s),y=N.useRef(!1);N.useEffect(()=>{if(y.current){m.current=s;return}i&&c&&s!==m.current&&(l?!l(d,s):d!==s)&&f(s),m.current=s},[s,c,i,l,d]);const S=N.useCallback(v=>{const _=typeof v=="function"?v(h):v;(l?l(h,_):h===_)||(y.current=!0,f(_),n?.(_),requestAnimationFrame(()=>{y.current=!1}))},[h,c,n,l]);return[h,S]}function _E(s,e){return s===e?!0:s.length!==e.length?!1:s.every((n,r)=>n===e[r])}function Zm(s,e){if(s===e)return!0;const n=Object.keys(s),r=Object.keys(e);return n.length!==r.length?!1:n.every(i=>s[i]===e[i])}const ey=N.createContext({}),AE=({children:s,value:e})=>ft.jsx(ey.Provider,{value:e,children:s}),xE=()=>N.useContext(ey),TE=(s,e)=>{if(!s)return;const n=e.split(".");let r=s;for(const i of n){if(r==null)return;r=r[i]}return r},kE=(s,e,n)=>{const r=e.split(".");if(r.length===1)return{...s,[r[0]]:n};const i={...s};let l=i;for(let c=0;c{hs.warn("IsolatedStateContext not available: setState called outside IsolatedStateProvider")},getState:()=>{},mergeState:()=>{hs.warn("IsolatedStateContext not available: mergeState called outside IsolatedStateProvider")},stateRef:{current:{}},scopeId:""},ty=N.createContext(RE);let DE=0;function OE(){return`isolated-${++DE}-${Date.now().toString(36)}`}function ny(s,e){if(e==null)return s;if(typeof e!="object"||Array.isArray(e))return e;const n={...s};for(const r of Object.keys(e)){const i=e[r],l=s?.[r];i!==null&&typeof i=="object"&&!Array.isArray(i)&&l!==null&&typeof l=="object"&&!Array.isArray(l)?n[r]=ny(l,i):n[r]=i}return n}function LE(s,e){return e?e.split(".").reduce((n,r)=>n?.[r],s):s}function $E(s,e,n){const r=e.split("."),i={...s};let l=i;for(let c=0;c{const i=N.useRef(e||OE()).current,[l,c]=N.useState(s),d=N.useRef(l);d.current=l;const f=N.useCallback(v=>LE(d.current,v),[]),h=N.useCallback((v,_)=>{c(x=>{const A=$E(x,v,_);return hs.log(`[${i}] setState: ${v} =`,_),A})},[i]),m=N.useCallback((v,_="deep")=>{c(x=>{let A;return _==="replace"?A=v:_==="shallow"?A={...x,...v}:A=ny(x,v),hs.log(`[${i}] mergeState (${_}):`,v),A})},[i]),y=N.useMemo(()=>({state:l,setState:h,getState:f,mergeState:m,stateRef:d,scopeId:i}),[l,h,f,m,i]),S=N.useMemo(()=>({state:d.current,setState:h,getState:f,mergeState:m}),[h,f,m]);return N.useEffect(()=>{const v=window.G7Core,_=window.__g7IsolatedStates||{};return window.__g7IsolatedStates||(window.__g7IsolatedStates=_),_[i]=S,v&&(v._isolatedStates||(v._isolatedStates={}),v._isolatedStates[i]=l),v?.devTools?.isEnabled?.()&&v.devTools.emit?.("isolated:created",{id:i,state:l}),hs.log(`[${i}] IsolatedStateProvider mounted with initial state:`,l),()=>{delete _[i],v?._isolatedStates&&delete v._isolatedStates[i],v?.devTools?.isEnabled?.()&&v.devTools.emit?.("isolated:destroyed",{id:i}),hs.log(`[${i}] IsolatedStateProvider unmounted`)}},[i,S]),N.useEffect(()=>{const v=window.G7Core,_=window.__g7IsolatedStates;_?.[i]&&(_[i].state=l),v?._isolatedStates&&(v._isolatedStates[i]=l),v?.devTools?.isEnabled?.()&&v.devTools.emit?.("isolated:updated",{id:i,state:l})},[l,i]),ft.jsx(ty.Provider,{value:y,children:n})},NE=()=>{const s=N.useContext(ty);return s.scopeId?s:null};var Ma=Rg();function IE(){for(var s=arguments.length,e=new Array(s),n=0;nr=>{e.forEach(i=>i(r))},e)}const vc=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function ps(s){const e=Object.prototype.toString.call(s);return e==="[object Window]"||e==="[object global]"}function xf(s){return"nodeType"in s}function Mn(s){var e,n;return s?ps(s)?s:xf(s)&&(e=(n=s.ownerDocument)==null?void 0:n.defaultView)!=null?e:window:window}function Tf(s){const{Document:e}=Mn(s);return s instanceof e}function Ro(s){return ps(s)?!1:s instanceof Mn(s).HTMLElement}function ry(s){return s instanceof Mn(s).SVGElement}function gs(s){return s?ps(s)?s.document:xf(s)?Tf(s)?s:Ro(s)||ry(s)?s.ownerDocument:document:document:document}const Pr=vc?N.useLayoutEffect:N.useEffect;function kf(s){const e=N.useRef(s);return Pr(()=>{e.current=s}),N.useCallback(function(){for(var n=arguments.length,r=new Array(n),i=0;i{s.current=setInterval(r,i)},[]),n=N.useCallback(()=>{s.current!==null&&(clearInterval(s.current),s.current=null)},[]);return[e,n]}function Do(s,e){e===void 0&&(e=[s]);const n=N.useRef(s);return Pr(()=>{n.current!==s&&(n.current=s)},e),n}function Oo(s,e){const n=N.useRef();return N.useMemo(()=>{const r=s(n.current);return n.current=r,r},[...e])}function Sc(s){const e=kf(s),n=N.useRef(null),r=N.useCallback(i=>{i!==n.current&&e?.(i,n.current),n.current=i},[]);return[n,r]}function Rf(s){const e=N.useRef();return N.useEffect(()=>{e.current=s},[s]),e.current}let Df={};function Lo(s,e){return N.useMemo(()=>{if(e)return e;const n=Df[s]==null?0:Df[s]+1;return Df[s]=n,s+"-"+n},[s,e])}function ay(s){return function(e){for(var n=arguments.length,r=new Array(n>1?n-1:0),i=1;i{const d=Object.entries(c);for(const[f,h]of d){const m=l[f];m!=null&&(l[f]=m+s*h)}return l},{...e})}}const ms=ay(1),$o=ay(-1);function HE(s){return"clientX"in s&&"clientY"in s}function Of(s){if(!s)return!1;const{KeyboardEvent:e}=Mn(s.target);return e&&s instanceof e}function zE(s){if(!s)return!1;const{TouchEvent:e}=Mn(s.target);return e&&s instanceof e}function Lf(s){if(zE(s)){if(s.touches&&s.touches.length){const{clientX:e,clientY:n}=s.touches[0];return{x:e,y:n}}else if(s.changedTouches&&s.changedTouches.length){const{clientX:e,clientY:n}=s.changedTouches[0];return{x:e,y:n}}}return HE(s)?{x:s.clientX,y:s.clientY}:null}const Mo=Object.freeze({Translate:{toString(s){if(!s)return;const{x:e,y:n}=s;return"translate3d("+(e?Math.round(e):0)+"px, "+(n?Math.round(n):0)+"px, 0)"}},Scale:{toString(s){if(!s)return;const{scaleX:e,scaleY:n}=s;return"scaleX("+e+") scaleY("+n+")"}},Transform:{toString(s){if(s)return[Mo.Translate.toString(s),Mo.Scale.toString(s)].join(" ")}},Transition:{toString(s){let{property:e,duration:n,easing:r}=s;return e+" "+n+"ms "+r}}}),iy="a,frame,iframe,input:not([type=hidden]):not(:disabled),select:not(:disabled),textarea:not(:disabled),button:not(:disabled),*[tabindex]";function UE(s){return s.matches(iy)?s:s.querySelector(iy)}const PE={display:"none"};function BE(s){let{id:e,value:n}=s;return Ye.createElement("div",{id:e,style:PE},n)}function qE(s){let{id:e,announcement:n,ariaLiveType:r="assertive"}=s;const i={position:"fixed",top:0,left:0,width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0 0 0 0)",clipPath:"inset(100%)",whiteSpace:"nowrap"};return Ye.createElement("div",{id:e,style:i,role:"status","aria-live":r,"aria-atomic":!0},n)}function GE(){const[s,e]=N.useState("");return{announce:N.useCallback(r=>{r!=null&&e(r)},[]),announcement:s}}const sy=N.createContext(null);function FE(s){const e=N.useContext(sy);N.useEffect(()=>{if(!e)throw new Error("useDndMonitor must be used within a children of ");return e(s)},[s,e])}function VE(){const[s]=N.useState(()=>new Set),e=N.useCallback(r=>(s.add(r),()=>s.delete(r)),[s]);return[N.useCallback(r=>{let{type:i,event:l}=r;s.forEach(c=>{var d;return(d=c[i])==null?void 0:d.call(c,l)})},[s]),e]}const KE={draggable:` To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel. - `},WE={onDragStart(s){let{active:e}=s;return"Picked up draggable item "+e.id+"."},onDragOver(s){let{active:e,over:n}=s;return n?"Draggable item "+e.id+" was moved over droppable area "+n.id+".":"Draggable item "+e.id+" is no longer over a droppable area."},onDragEnd(s){let{active:e,over:n}=s;return n?"Draggable item "+e.id+" was dropped over droppable area "+n.id:"Draggable item "+e.id+" was dropped."},onDragCancel(s){let{active:e}=s;return"Dragging was cancelled. Draggable item "+e.id+" was dropped."}};function YE(s){let{announcements:e=WE,container:n,hiddenTextDescribedById:r,screenReaderInstructions:i=KE}=s;const{announce:l,announcement:c}=GE(),d=Lo("DndLiveRegion"),[f,h]=N.useState(!1);if(N.useEffect(()=>{h(!0)},[]),FE(N.useMemo(()=>({onDragStart(y){let{active:S}=y;l(e.onDragStart({active:S}))},onDragMove(y){let{active:S,over:v}=y;e.onDragMove&&l(e.onDragMove({active:S,over:v}))},onDragOver(y){let{active:S,over:v}=y;l(e.onDragOver({active:S,over:v}))},onDragEnd(y){let{active:S,over:v}=y;l(e.onDragEnd({active:S,over:v}))},onDragCancel(y){let{active:S,over:v}=y;l(e.onDragCancel({active:S,over:v}))}}),[l,e])),!f)return null;const m=Ye.createElement(Ye.Fragment,null,Ye.createElement(BE,{id:r,value:i.draggable}),Ye.createElement(qE,{id:d,announcement:c}));return n?Ma.createPortal(m,n):m}var nn;(function(s){s.DragStart="dragStart",s.DragMove="dragMove",s.DragEnd="dragEnd",s.DragCancel="dragCancel",s.DragOver="dragOver",s.RegisterDroppable="registerDroppable",s.SetDroppableDisabled="setDroppableDisabled",s.UnregisterDroppable="unregisterDroppable"})(nn||(nn={}));function Sc(){}function oy(s,e){return N.useMemo(()=>({sensor:s,options:e??{}}),[s,e])}function XE(){for(var s=arguments.length,e=new Array(s),n=0;n[...e].filter(r=>r!=null),[...e])}const _r=Object.freeze({x:0,y:0});function ly(s,e){return Math.sqrt(Math.pow(s.x-e.x,2)+Math.pow(s.y-e.y,2))}function cy(s,e){let{data:{value:n}}=s,{data:{value:r}}=e;return n-r}function JE(s,e){let{data:{value:n}}=s,{data:{value:r}}=e;return r-n}function uy(s){let{left:e,top:n,height:r,width:i}=s;return[{x:e,y:n},{x:e+i,y:n},{x:e,y:n+r},{x:e+i,y:n+r}]}function dy(s,e){if(!s||s.length===0)return null;const[n]=s;return n[e]}function fy(s,e,n){return e===void 0&&(e=s.left),n===void 0&&(n=s.top),{x:e+s.width*.5,y:n+s.height*.5}}const QE=s=>{let{collisionRect:e,droppableRects:n,droppableContainers:r}=s;const i=fy(e,e.left,e.top),l=[];for(const c of r){const{id:d}=c,f=n.get(d);if(f){const h=ly(fy(f),i);l.push({id:d,data:{droppableContainer:c,value:h}})}}return l.sort(cy)},ZE=s=>{let{collisionRect:e,droppableRects:n,droppableContainers:r}=s;const i=uy(e),l=[];for(const c of r){const{id:d}=c,f=n.get(d);if(f){const h=uy(f),m=i.reduce((S,v,_)=>S+ly(h[_],v),0),y=Number((m/4).toFixed(4));l.push({id:d,data:{droppableContainer:c,value:y}})}}return l.sort(cy)};function e_(s,e){const n=Math.max(e.top,s.top),r=Math.max(e.left,s.left),i=Math.min(e.left+e.width,s.left+s.width),l=Math.min(e.top+e.height,s.top+s.height),c=i-r,d=l-n;if(r{let{collisionRect:e,droppableRects:n,droppableContainers:r}=s;const i=[];for(const l of r){const{id:c}=l,d=n.get(c);if(d){const f=e_(d,e);f>0&&i.push({id:c,data:{droppableContainer:l,value:f}})}}return i.sort(JE)};function n_(s,e,n){return{...s,scaleX:e&&n?e.width/n.width:1,scaleY:e&&n?e.height/n.height:1}}function hy(s,e){return s&&e?{x:s.left-e.left,y:s.top-e.top}:_r}function r_(s){return function(n){for(var r=arguments.length,i=new Array(r>1?r-1:0),l=1;l({...c,top:c.top+s*d.y,bottom:c.bottom+s*d.y,left:c.left+s*d.x,right:c.right+s*d.x}),{...n})}}const a_=r_(1);function i_(s){if(s.startsWith("matrix3d(")){const e=s.slice(9,-1).split(/, /);return{x:+e[12],y:+e[13],scaleX:+e[0],scaleY:+e[5]}}else if(s.startsWith("matrix(")){const e=s.slice(7,-1).split(/, /);return{x:+e[4],y:+e[5],scaleX:+e[0],scaleY:+e[3]}}return null}function s_(s,e,n){const r=i_(e);if(!r)return s;const{scaleX:i,scaleY:l,x:c,y:d}=r,f=s.left-c-(1-i)*parseFloat(n),h=s.top-d-(1-l)*parseFloat(n.slice(n.indexOf(" ")+1)),m=i?s.width/i:s.width,y=l?s.height/l:s.height;return{width:m,height:y,top:h,right:f+m,bottom:h+y,left:f}}const o_={ignoreTransform:!1};function ys(s,e){e===void 0&&(e=o_);let n=s.getBoundingClientRect();if(e.ignoreTransform){const{transform:h,transformOrigin:m}=Mn(s).getComputedStyle(s);h&&(n=s_(n,h,m))}const{top:r,left:i,width:l,height:c,bottom:d,right:f}=n;return{top:r,left:i,width:l,height:c,bottom:d,right:f}}function py(s){return ys(s,{ignoreTransform:!0})}function l_(s){const e=s.innerWidth,n=s.innerHeight;return{top:0,left:0,right:e,bottom:n,width:e,height:n}}function c_(s,e){return e===void 0&&(e=Mn(s).getComputedStyle(s)),e.position==="fixed"}function u_(s,e){e===void 0&&(e=Mn(s).getComputedStyle(s));const n=/(auto|scroll|overlay)/;return["overflow","overflowX","overflowY"].some(i=>{const l=e[i];return typeof l=="string"?n.test(l):!1})}function wc(s,e){const n=[];function r(i){if(e!=null&&n.length>=e||!i)return n;if(Tf(i)&&i.scrollingElement!=null&&!n.includes(i.scrollingElement))return n.push(i.scrollingElement),n;if(!Ro(i)||ry(i)||n.includes(i))return n;const l=Mn(s).getComputedStyle(i);return i!==s&&u_(i,l)&&n.push(i),c_(i,l)?n:r(i.parentNode)}return s?r(s):n}function gy(s){const[e]=wc(s,1);return e??null}function $f(s){return!bc||!s?null:ps(s)?s:xf(s)?Tf(s)||s===gs(s).scrollingElement?window:Ro(s)?s:null:null}function my(s){return ps(s)?s.scrollX:s.scrollLeft}function yy(s){return ps(s)?s.scrollY:s.scrollTop}function Mf(s){return{x:my(s),y:yy(s)}}var dn;(function(s){s[s.Forward=1]="Forward",s[s.Backward=-1]="Backward"})(dn||(dn={}));function by(s){return!bc||!s?!1:s===document.scrollingElement}function vy(s){const e={x:0,y:0},n=by(s)?{height:window.innerHeight,width:window.innerWidth}:{height:s.clientHeight,width:s.clientWidth},r={x:s.scrollWidth-n.width,y:s.scrollHeight-n.height},i=s.scrollTop<=e.y,l=s.scrollLeft<=e.x,c=s.scrollTop>=r.y,d=s.scrollLeft>=r.x;return{isTop:i,isLeft:l,isBottom:c,isRight:d,maxScroll:r,minScroll:e}}const d_={x:.2,y:.2};function f_(s,e,n,r,i){let{top:l,left:c,right:d,bottom:f}=n;r===void 0&&(r=10),i===void 0&&(i=d_);const{isTop:h,isBottom:m,isLeft:y,isRight:S}=vy(s),v={x:0,y:0},_={x:0,y:0},x={height:e.height*i.y,width:e.width*i.x};return!h&&l<=e.top+x.height?(v.y=dn.Backward,_.y=r*Math.abs((e.top+x.height-l)/x.height)):!m&&f>=e.bottom-x.height&&(v.y=dn.Forward,_.y=r*Math.abs((e.bottom-x.height-f)/x.height)),!S&&d>=e.right-x.width?(v.x=dn.Forward,_.x=r*Math.abs((e.right-x.width-d)/x.width)):!y&&c<=e.left+x.width&&(v.x=dn.Backward,_.x=r*Math.abs((e.left+x.width-c)/x.width)),{direction:v,speed:_}}function h_(s){if(s===document.scrollingElement){const{innerWidth:l,innerHeight:c}=window;return{top:0,left:0,right:l,bottom:c,width:l,height:c}}const{top:e,left:n,right:r,bottom:i}=s.getBoundingClientRect();return{top:e,left:n,right:r,bottom:i,width:s.clientWidth,height:s.clientHeight}}function Sy(s){return s.reduce((e,n)=>ms(e,Mf(n)),_r)}function p_(s){return s.reduce((e,n)=>e+my(n),0)}function g_(s){return s.reduce((e,n)=>e+yy(n),0)}function m_(s,e){if(e===void 0&&(e=ys),!s)return;const{top:n,left:r,bottom:i,right:l}=e(s);gy(s)&&(i<=0||l<=0||n>=window.innerHeight||r>=window.innerWidth)&&s.scrollIntoView({block:"center",inline:"center"})}const y_=[["x",["left","right"],p_],["y",["top","bottom"],g_]];class Nf{constructor(e,n){this.rect=void 0,this.width=void 0,this.height=void 0,this.top=void 0,this.bottom=void 0,this.right=void 0,this.left=void 0;const r=wc(n),i=Sy(r);this.rect={...e},this.width=e.width,this.height=e.height;for(const[l,c,d]of y_)for(const f of c)Object.defineProperty(this,f,{get:()=>{const h=d(r),m=i[l]-h;return this.rect[f]+m},enumerable:!0});Object.defineProperty(this,"rect",{enumerable:!1})}}class No{constructor(e){this.target=void 0,this.listeners=[],this.removeAll=()=>{this.listeners.forEach(n=>{var r;return(r=this.target)==null?void 0:r.removeEventListener(...n)})},this.target=e}add(e,n,r){var i;(i=this.target)==null||i.addEventListener(e,n,r),this.listeners.push([e,n,r])}}function b_(s){const{EventTarget:e}=Mn(s);return s instanceof e?s:gs(s)}function If(s,e){const n=Math.abs(s.x),r=Math.abs(s.y);return typeof e=="number"?Math.sqrt(n**2+r**2)>e:"x"in e&&"y"in e?n>e.x&&r>e.y:"x"in e?n>e.x:"y"in e?r>e.y:!1}var ir;(function(s){s.Click="click",s.DragStart="dragstart",s.Keydown="keydown",s.ContextMenu="contextmenu",s.Resize="resize",s.SelectionChange="selectionchange",s.VisibilityChange="visibilitychange"})(ir||(ir={}));function wy(s){s.preventDefault()}function v_(s){s.stopPropagation()}var lt;(function(s){s.Space="Space",s.Down="ArrowDown",s.Right="ArrowRight",s.Left="ArrowLeft",s.Up="ArrowUp",s.Esc="Escape",s.Enter="Enter",s.Tab="Tab"})(lt||(lt={}));const Cy={start:[lt.Space,lt.Enter],cancel:[lt.Esc],end:[lt.Space,lt.Enter,lt.Tab]},S_=(s,e)=>{let{currentCoordinates:n}=e;switch(s.code){case lt.Right:return{...n,x:n.x+25};case lt.Left:return{...n,x:n.x-25};case lt.Down:return{...n,y:n.y+25};case lt.Up:return{...n,y:n.y-25}}};class jf{constructor(e){this.props=void 0,this.autoScrollEnabled=!1,this.referenceCoordinates=void 0,this.listeners=void 0,this.windowListeners=void 0,this.props=e;const{event:{target:n}}=e;this.props=e,this.listeners=new No(gs(n)),this.windowListeners=new No(Mn(n)),this.handleKeyDown=this.handleKeyDown.bind(this),this.handleCancel=this.handleCancel.bind(this),this.attach()}attach(){this.handleStart(),this.windowListeners.add(ir.Resize,this.handleCancel),this.windowListeners.add(ir.VisibilityChange,this.handleCancel),setTimeout(()=>this.listeners.add(ir.Keydown,this.handleKeyDown))}handleStart(){const{activeNode:e,onStart:n}=this.props,r=e.node.current;r&&m_(r),n(_r)}handleKeyDown(e){if(Of(e)){const{active:n,context:r,options:i}=this.props,{keyboardCodes:l=Cy,coordinateGetter:c=S_,scrollBehavior:d="smooth"}=i,{code:f}=e;if(l.end.includes(f)){this.handleEnd(e);return}if(l.cancel.includes(f)){this.handleCancel(e);return}const{collisionRect:h}=r.current,m=h?{x:h.left,y:h.top}:_r;this.referenceCoordinates||(this.referenceCoordinates=m);const y=c(e,{active:n,context:r.current,currentCoordinates:m});if(y){const S=$o(y,m),v={x:0,y:0},{scrollableAncestors:_}=r.current;for(const x of _){const A=e.code,{isTop:L,isRight:$,isLeft:k,isBottom:O,maxScroll:P,minScroll:G}=vy(x),B=h_(x),W={x:Math.min(A===lt.Right?B.right-B.width/2:B.right,Math.max(A===lt.Right?B.left:B.left+B.width/2,y.x)),y:Math.min(A===lt.Down?B.bottom-B.height/2:B.bottom,Math.max(A===lt.Down?B.top:B.top+B.height/2,y.y))},pe=A===lt.Right&&!$||A===lt.Left&&!k,Se=A===lt.Down&&!O||A===lt.Up&&!L;if(pe&&W.x!==y.x){const we=x.scrollLeft+S.x,Ue=A===lt.Right&&we<=P.x||A===lt.Left&&we>=G.x;if(Ue&&!S.y){x.scrollTo({left:we,behavior:d});return}Ue?v.x=x.scrollLeft-we:v.x=A===lt.Right?x.scrollLeft-P.x:x.scrollLeft-G.x,v.x&&x.scrollBy({left:-v.x,behavior:d});break}else if(Se&&W.y!==y.y){const we=x.scrollTop+S.y,Ue=A===lt.Down&&we<=P.y||A===lt.Up&&we>=G.y;if(Ue&&!S.x){x.scrollTo({top:we,behavior:d});return}Ue?v.y=x.scrollTop-we:v.y=A===lt.Down?x.scrollTop-P.y:x.scrollTop-G.y,v.y&&x.scrollBy({top:-v.y,behavior:d});break}}this.handleMove(e,ms($o(y,this.referenceCoordinates),v))}}}handleMove(e,n){const{onMove:r}=this.props;e.preventDefault(),r(n)}handleEnd(e){const{onEnd:n}=this.props;e.preventDefault(),this.detach(),n()}handleCancel(e){const{onCancel:n}=this.props;e.preventDefault(),this.detach(),n()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll()}}jf.activators=[{eventName:"onKeyDown",handler:(s,e,n)=>{let{keyboardCodes:r=Cy,onActivation:i}=e,{active:l}=n;const{code:c}=s.nativeEvent;if(r.start.includes(c)){const d=l.activatorNode.current;return d&&s.target!==d?!1:(s.preventDefault(),i?.({event:s.nativeEvent}),!0)}return!1}}];function Ey(s){return!!(s&&"distance"in s)}function _y(s){return!!(s&&"delay"in s)}class Hf{constructor(e,n,r){var i;r===void 0&&(r=b_(e.event.target)),this.props=void 0,this.events=void 0,this.autoScrollEnabled=!0,this.document=void 0,this.activated=!1,this.initialCoordinates=void 0,this.timeoutId=null,this.listeners=void 0,this.documentListeners=void 0,this.windowListeners=void 0,this.props=e,this.events=n;const{event:l}=e,{target:c}=l;this.props=e,this.events=n,this.document=gs(c),this.documentListeners=new No(this.document),this.listeners=new No(r),this.windowListeners=new No(Mn(c)),this.initialCoordinates=(i=Lf(l))!=null?i:_r,this.handleStart=this.handleStart.bind(this),this.handleMove=this.handleMove.bind(this),this.handleEnd=this.handleEnd.bind(this),this.handleCancel=this.handleCancel.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.removeTextSelection=this.removeTextSelection.bind(this),this.attach()}attach(){const{events:e,props:{options:{activationConstraint:n,bypassActivationConstraint:r}}}=this;if(this.listeners.add(e.move.name,this.handleMove,{passive:!1}),this.listeners.add(e.end.name,this.handleEnd),e.cancel&&this.listeners.add(e.cancel.name,this.handleCancel),this.windowListeners.add(ir.Resize,this.handleCancel),this.windowListeners.add(ir.DragStart,wy),this.windowListeners.add(ir.VisibilityChange,this.handleCancel),this.windowListeners.add(ir.ContextMenu,wy),this.documentListeners.add(ir.Keydown,this.handleKeydown),n){if(r!=null&&r({event:this.props.event,activeNode:this.props.activeNode,options:this.props.options}))return this.handleStart();if(_y(n)){this.timeoutId=setTimeout(this.handleStart,n.delay),this.handlePending(n);return}if(Ey(n)){this.handlePending(n);return}}this.handleStart()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll(),setTimeout(this.documentListeners.removeAll,50),this.timeoutId!==null&&(clearTimeout(this.timeoutId),this.timeoutId=null)}handlePending(e,n){const{active:r,onPending:i}=this.props;i(r,e,this.initialCoordinates,n)}handleStart(){const{initialCoordinates:e}=this,{onStart:n}=this.props;e&&(this.activated=!0,this.documentListeners.add(ir.Click,v_,{capture:!0}),this.removeTextSelection(),this.documentListeners.add(ir.SelectionChange,this.removeTextSelection),n(e))}handleMove(e){var n;const{activated:r,initialCoordinates:i,props:l}=this,{onMove:c,options:{activationConstraint:d}}=l;if(!i)return;const f=(n=Lf(e))!=null?n:_r,h=$o(i,f);if(!r&&d){if(Ey(d)){if(d.tolerance!=null&&If(h,d.tolerance))return this.handleCancel();if(If(h,d.distance))return this.handleStart()}if(_y(d)&&If(h,d.tolerance))return this.handleCancel();this.handlePending(d,h);return}e.cancelable&&e.preventDefault(),c(f)}handleEnd(){const{onAbort:e,onEnd:n}=this.props;this.detach(),this.activated||e(this.props.active),n()}handleCancel(){const{onAbort:e,onCancel:n}=this.props;this.detach(),this.activated||e(this.props.active),n()}handleKeydown(e){e.code===lt.Esc&&this.handleCancel()}removeTextSelection(){var e;(e=this.document.getSelection())==null||e.removeAllRanges()}}const w_={cancel:{name:"pointercancel"},move:{name:"pointermove"},end:{name:"pointerup"}};class zf extends Hf{constructor(e){const{event:n}=e,r=gs(n.target);super(e,w_,r)}}zf.activators=[{eventName:"onPointerDown",handler:(s,e)=>{let{nativeEvent:n}=s,{onActivation:r}=e;return!n.isPrimary||n.button!==0?!1:(r?.({event:n}),!0)}}];const C_={move:{name:"mousemove"},end:{name:"mouseup"}};var Uf;(function(s){s[s.RightClick=2]="RightClick"})(Uf||(Uf={}));class E_ extends Hf{constructor(e){super(e,C_,gs(e.event.target))}}E_.activators=[{eventName:"onMouseDown",handler:(s,e)=>{let{nativeEvent:n}=s,{onActivation:r}=e;return n.button===Uf.RightClick?!1:(r?.({event:n}),!0)}}];const Pf={cancel:{name:"touchcancel"},move:{name:"touchmove"},end:{name:"touchend"}};class __ extends Hf{constructor(e){super(e,Pf)}static setup(){return window.addEventListener(Pf.move.name,e,{capture:!1,passive:!1}),function(){window.removeEventListener(Pf.move.name,e)};function e(){}}}__.activators=[{eventName:"onTouchStart",handler:(s,e)=>{let{nativeEvent:n}=s,{onActivation:r}=e;const{touches:i}=n;return i.length>1?!1:(r?.({event:n}),!0)}}];var Io;(function(s){s[s.Pointer=0]="Pointer",s[s.DraggableRect=1]="DraggableRect"})(Io||(Io={}));var Cc;(function(s){s[s.TreeOrder=0]="TreeOrder",s[s.ReversedTreeOrder=1]="ReversedTreeOrder"})(Cc||(Cc={}));function A_(s){let{acceleration:e,activator:n=Io.Pointer,canScroll:r,draggingRect:i,enabled:l,interval:c=5,order:d=Cc.TreeOrder,pointerCoordinates:f,scrollableAncestors:h,scrollableAncestorRects:m,delta:y,threshold:S}=s;const v=T_({delta:y,disabled:!l}),[_,x]=jE(),A=N.useRef({x:0,y:0}),L=N.useRef({x:0,y:0}),$=N.useMemo(()=>{switch(n){case Io.Pointer:return f?{top:f.y,bottom:f.y,left:f.x,right:f.x}:null;case Io.DraggableRect:return i}},[n,i,f]),k=N.useRef(null),O=N.useCallback(()=>{const G=k.current;if(!G)return;const B=A.current.x*L.current.x,W=A.current.y*L.current.y;G.scrollBy(B,W)},[]),P=N.useMemo(()=>d===Cc.TreeOrder?[...h].reverse():h,[d,h]);N.useEffect(()=>{if(!l||!h.length||!$){x();return}for(const G of P){if(r?.(G)===!1)continue;const B=h.indexOf(G),W=m[B];if(!W)continue;const{direction:pe,speed:Se}=f_(G,W,$,e,S);for(const we of["x","y"])v[we][pe[we]]||(Se[we]=0,pe[we]=0);if(Se.x>0||Se.y>0){x(),k.current=G,_(O,c),A.current=Se,L.current=pe;return}}A.current={x:0,y:0},L.current={x:0,y:0},x()},[e,O,r,x,l,c,JSON.stringify($),JSON.stringify(v),_,h,P,m,JSON.stringify(S)])}const x_={x:{[dn.Backward]:!1,[dn.Forward]:!1},y:{[dn.Backward]:!1,[dn.Forward]:!1}};function T_(s){let{delta:e,disabled:n}=s;const r=Rf(e);return Oo(i=>{if(n||!r||!i)return x_;const l={x:Math.sign(e.x-r.x),y:Math.sign(e.y-r.y)};return{x:{[dn.Backward]:i.x[dn.Backward]||l.x===-1,[dn.Forward]:i.x[dn.Forward]||l.x===1},y:{[dn.Backward]:i.y[dn.Backward]||l.y===-1,[dn.Forward]:i.y[dn.Forward]||l.y===1}}},[n,e,r])}function k_(s,e){const n=e!=null?s.get(e):void 0,r=n?n.node.current:null;return Oo(i=>{var l;return e==null?null:(l=r??i)!=null?l:null},[r,e])}function R_(s,e){return N.useMemo(()=>s.reduce((n,r)=>{const{sensor:i}=r,l=i.activators.map(c=>({eventName:c.eventName,handler:e(c.handler,r)}));return[...n,...l]},[]),[s,e])}var jo;(function(s){s[s.Always=0]="Always",s[s.BeforeDragging=1]="BeforeDragging",s[s.WhileDragging=2]="WhileDragging"})(jo||(jo={}));var Bf;(function(s){s.Optimized="optimized"})(Bf||(Bf={}));const Ay=new Map;function D_(s,e){let{dragging:n,dependencies:r,config:i}=e;const[l,c]=N.useState(null),{frequency:d,measure:f,strategy:h}=i,m=N.useRef(s),y=A(),S=Do(y),v=N.useCallback(function(L){L===void 0&&(L=[]),!S.current&&c($=>$===null?L:$.concat(L.filter(k=>!$.includes(k))))},[S]),_=N.useRef(null),x=Oo(L=>{if(y&&!n)return Ay;if(!L||L===Ay||m.current!==s||l!=null){const $=new Map;for(let k of s){if(!k)continue;if(l&&l.length>0&&!l.includes(k.id)&&k.rect.current){$.set(k.id,k.rect.current);continue}const O=k.node.current,P=O?new Nf(f(O),O):null;k.rect.current=P,P&&$.set(k.id,P)}return $}return L},[s,l,n,y,f]);return N.useEffect(()=>{m.current=s},[s]),N.useEffect(()=>{y||v()},[n,y]),N.useEffect(()=>{l&&l.length>0&&c(null)},[JSON.stringify(l)]),N.useEffect(()=>{y||typeof d!="number"||_.current!==null||(_.current=setTimeout(()=>{v(),_.current=null},d))},[d,y,v,...r]),{droppableRects:x,measureDroppableContainers:v,measuringScheduled:l!=null};function A(){switch(h){case jo.Always:return!1;case jo.BeforeDragging:return n;default:return!n}}}function xy(s,e){return Oo(n=>s?n||(typeof e=="function"?e(s):s):null,[e,s])}function O_(s,e){return xy(s,e)}function L_(s){let{callback:e,disabled:n}=s;const r=kf(e),i=N.useMemo(()=>{if(n||typeof window>"u"||typeof window.MutationObserver>"u")return;const{MutationObserver:l}=window;return new l(r)},[r,n]);return N.useEffect(()=>()=>i?.disconnect(),[i]),i}function Ec(s){let{callback:e,disabled:n}=s;const r=kf(e),i=N.useMemo(()=>{if(n||typeof window>"u"||typeof window.ResizeObserver>"u")return;const{ResizeObserver:l}=window;return new l(r)},[n]);return N.useEffect(()=>()=>i?.disconnect(),[i]),i}function $_(s){return new Nf(ys(s),s)}function Ty(s,e,n){e===void 0&&(e=$_);const[r,i]=N.useState(null);function l(){i(f=>{if(!s)return null;if(s.isConnected===!1){var h;return(h=f??n)!=null?h:null}const m=e(s);return JSON.stringify(f)===JSON.stringify(m)?f:m})}const c=L_({callback(f){if(s)for(const h of f){const{type:m,target:y}=h;if(m==="childList"&&y instanceof HTMLElement&&y.contains(s)){l();break}}}}),d=Ec({callback:l});return Pr(()=>{l(),s?(d?.observe(s),c?.observe(document.body,{childList:!0,subtree:!0})):(d?.disconnect(),c?.disconnect())},[s]),r}function M_(s){const e=xy(s);return hy(s,e)}const ky=[];function N_(s){const e=N.useRef(s),n=Oo(r=>s?r&&r!==ky&&s&&e.current&&s.parentNode===e.current.parentNode?r:wc(s):ky,[s]);return N.useEffect(()=>{e.current=s},[s]),n}function I_(s){const[e,n]=N.useState(null),r=N.useRef(s),i=N.useCallback(l=>{const c=$f(l.target);c&&n(d=>d?(d.set(c,Mf(c)),new Map(d)):null)},[]);return N.useEffect(()=>{const l=r.current;if(s!==l){c(l);const d=s.map(f=>{const h=$f(f);return h?(h.addEventListener("scroll",i,{passive:!0}),[h,Mf(h)]):null}).filter(f=>f!=null);n(d.length?new Map(d):null),r.current=s}return()=>{c(s),c(l)};function c(d){d.forEach(f=>{const h=$f(f);h?.removeEventListener("scroll",i)})}},[i,s]),N.useMemo(()=>s.length?e?Array.from(e.values()).reduce((l,c)=>ms(l,c),_r):Sy(s):_r,[s,e])}function Ry(s,e){e===void 0&&(e=[]);const n=N.useRef(null);return N.useEffect(()=>{n.current=null},e),N.useEffect(()=>{const r=s!==_r;r&&!n.current&&(n.current=s),!r&&n.current&&(n.current=null)},[s]),n.current?$o(s,n.current):_r}function j_(s){N.useEffect(()=>{if(!bc)return;const e=s.map(n=>{let{sensor:r}=n;return r.setup==null?void 0:r.setup()});return()=>{for(const n of e)n?.()}},s.map(e=>{let{sensor:n}=e;return n}))}function H_(s,e){return N.useMemo(()=>s.reduce((n,r)=>{let{eventName:i,handler:l}=r;return n[i]=c=>{l(c,e)},n},{}),[s,e])}function Dy(s){return N.useMemo(()=>s?l_(s):null,[s])}const Oy=[];function z_(s,e){e===void 0&&(e=ys);const[n]=s,r=Dy(n?Mn(n):null),[i,l]=N.useState(Oy);function c(){l(()=>s.length?s.map(f=>by(f)?r:new Nf(e(f),f)):Oy)}const d=Ec({callback:c});return Pr(()=>{d?.disconnect(),c(),s.forEach(f=>d?.observe(f))},[s]),i}function U_(s){if(!s)return null;if(s.children.length>1)return s;const e=s.children[0];return Ro(e)?e:s}function P_(s){let{measure:e}=s;const[n,r]=N.useState(null),i=N.useCallback(h=>{for(const{target:m}of h)if(Ro(m)){r(y=>{const S=e(m);return y?{...y,width:S.width,height:S.height}:S});break}},[e]),l=Ec({callback:i}),c=N.useCallback(h=>{const m=U_(h);l?.disconnect(),m&&l?.observe(m),r(m?e(m):null)},[e,l]),[d,f]=vc(c);return N.useMemo(()=>({nodeRef:d,rect:n,setRef:f}),[n,d,f])}const B_=[{sensor:zf,options:{}},{sensor:jf,options:{}}],q_={current:{}},_c={draggable:{measure:py},droppable:{measure:py,strategy:jo.WhileDragging,frequency:Bf.Optimized},dragOverlay:{measure:ys}};class Ho extends Map{get(e){var n;return e!=null&&(n=super.get(e))!=null?n:void 0}toArray(){return Array.from(this.values())}getEnabled(){return this.toArray().filter(e=>{let{disabled:n}=e;return!n})}getNodeFor(e){var n,r;return(n=(r=this.get(e))==null?void 0:r.node.current)!=null?n:void 0}}const G_={activatorEvent:null,active:null,activeNode:null,activeNodeRect:null,collisions:null,containerNodeRect:null,draggableNodes:new Map,droppableRects:new Map,droppableContainers:new Ho,over:null,dragOverlay:{nodeRef:{current:null},rect:null,setRef:Sc},scrollableAncestors:[],scrollableAncestorRects:[],measuringConfiguration:_c,measureDroppableContainers:Sc,windowRect:null,measuringScheduled:!1},F_={activatorEvent:null,activators:[],active:null,activeNodeRect:null,ariaDescribedById:{draggable:""},dispatch:Sc,draggableNodes:new Map,over:null,measureDroppableContainers:Sc},Ac=N.createContext(F_),Ly=N.createContext(G_);function V_(){return{draggable:{active:null,initialCoordinates:{x:0,y:0},nodes:new Map,translate:{x:0,y:0}},droppable:{containers:new Ho}}}function K_(s,e){switch(e.type){case nn.DragStart:return{...s,draggable:{...s.draggable,initialCoordinates:e.initialCoordinates,active:e.active}};case nn.DragMove:return s.draggable.active==null?s:{...s,draggable:{...s.draggable,translate:{x:e.coordinates.x-s.draggable.initialCoordinates.x,y:e.coordinates.y-s.draggable.initialCoordinates.y}}};case nn.DragEnd:case nn.DragCancel:return{...s,draggable:{...s.draggable,active:null,initialCoordinates:{x:0,y:0},translate:{x:0,y:0}}};case nn.RegisterDroppable:{const{element:n}=e,{id:r}=n,i=new Ho(s.droppable.containers);return i.set(r,n),{...s,droppable:{...s.droppable,containers:i}}}case nn.SetDroppableDisabled:{const{id:n,key:r,disabled:i}=e,l=s.droppable.containers.get(n);if(!l||r!==l.key)return s;const c=new Ho(s.droppable.containers);return c.set(n,{...l,disabled:i}),{...s,droppable:{...s.droppable,containers:c}}}case nn.UnregisterDroppable:{const{id:n,key:r}=e,i=s.droppable.containers.get(n);if(!i||r!==i.key)return s;const l=new Ho(s.droppable.containers);return l.delete(n),{...s,droppable:{...s.droppable,containers:l}}}default:return s}}function W_(s){let{disabled:e}=s;const{active:n,activatorEvent:r,draggableNodes:i}=N.useContext(Ac),l=Rf(r),c=Rf(n?.id);return N.useEffect(()=>{if(!e&&!r&&l&&c!=null){if(!Of(l)||document.activeElement===l.target)return;const d=i.get(c);if(!d)return;const{activatorNode:f,node:h}=d;if(!f.current&&!h.current)return;requestAnimationFrame(()=>{for(const m of[f.current,h.current]){if(!m)continue;const y=UE(m);if(y){y.focus();break}}})}},[r,e,i,c,l]),null}function Y_(s,e){let{transform:n,...r}=e;return s!=null&&s.length?s.reduce((i,l)=>l({transform:i,...r}),n):n}function X_(s){return N.useMemo(()=>({draggable:{..._c.draggable,...s?.draggable},droppable:{..._c.droppable,...s?.droppable},dragOverlay:{..._c.dragOverlay,...s?.dragOverlay}}),[s?.draggable,s?.droppable,s?.dragOverlay])}function J_(s){let{activeNode:e,measure:n,initialRect:r,config:i=!0}=s;const l=N.useRef(!1),{x:c,y:d}=typeof i=="boolean"?{x:i,y:i}:i;Pr(()=>{if(!c&&!d||!e){l.current=!1;return}if(l.current||!r)return;const h=e?.node.current;if(!h||h.isConnected===!1)return;const m=n(h),y=hy(m,r);if(c||(y.x=0),d||(y.y=0),l.current=!0,Math.abs(y.x)>0||Math.abs(y.y)>0){const S=gy(h);S&&S.scrollBy({top:y.y,left:y.x})}},[e,c,d,r,n])}const $y=N.createContext({..._r,scaleX:1,scaleY:1});var Na;(function(s){s[s.Uninitialized=0]="Uninitialized",s[s.Initializing=1]="Initializing",s[s.Initialized=2]="Initialized"})(Na||(Na={}));const Q_=N.memo(function(e){var n,r,i,l;let{id:c,accessibility:d,autoScroll:f=!0,children:h,sensors:m=B_,collisionDetection:y=t_,measuring:S,modifiers:v,..._}=e;const x=N.useReducer(K_,void 0,V_),[A,L]=x,[$,k]=VE(),[O,P]=N.useState(Na.Uninitialized),G=O===Na.Initialized,{draggable:{active:B,nodes:W,translate:pe},droppable:{containers:Se}}=A,we=B!=null?W.get(B):null,Ue=N.useRef({initial:null,translated:null}),Fe=N.useMemo(()=>{var he;return B!=null?{id:B,data:(he=we?.data)!=null?he:q_,rect:Ue}:null},[B,we]),qe=N.useRef(null),[wt,J]=N.useState(null),[fe,Le]=N.useState(null),Z=Do(_,Object.values(_)),ge=Lo("DndDescribedBy",c),H=N.useMemo(()=>Se.getEnabled(),[Se]),T=X_(S),{droppableRects:ce,measureDroppableContainers:de,measuringScheduled:be}=D_(H,{dragging:G,dependencies:[pe.x,pe.y],config:T.droppable}),ie=k_(W,B),xe=N.useMemo(()=>fe?Lf(fe):null,[fe]),_e=ve(),Te=O_(ie,T.draggable.measure);J_({activeNode:B!=null?W.get(B):null,config:_e.layoutShiftCompensation,initialRect:Te,measure:T.draggable.measure});const Me=Ty(ie,T.draggable.measure,Te),pt=Ty(ie?ie.parentElement:null),Ct=N.useRef({activatorEvent:null,active:null,activeNode:ie,collisionRect:null,collisions:null,droppableRects:ce,draggableNodes:W,draggingNode:null,draggingNodeRect:null,droppableContainers:Se,over:null,scrollableAncestors:[],scrollAdjustedTranslate:null}),Ot=Se.getNodeFor((n=Ct.current.over)==null?void 0:n.id),ht=P_({measure:T.dragOverlay.measure}),rn=(r=ht.nodeRef.current)!=null?r:ie,Kt=G?(i=ht.rect)!=null?i:Me:null,It=!!(ht.nodeRef.current&&ht.rect),Fr=M_(It?null:Me),hn=Dy(rn?Mn(rn):null),an=N_(G?Ot??ie:null),pn=z_(an),Wn=Y_(v,{transform:{x:pe.x-Fr.x,y:pe.y-Fr.y,scaleX:1,scaleY:1},activatorEvent:fe,active:Fe,activeNodeRect:Me,containerNodeRect:pt,draggingNodeRect:Kt,over:Ct.current.over,overlayNodeRect:ht.rect,scrollableAncestors:an,scrollableAncestorRects:pn,windowRect:hn}),Vr=xe?ms(xe,pe):null,qt=I_(an),ki=Ry(qt),la=Ry(qt,[Me]),gn=ms(Wn,ki),Dn=Kt?a_(Kt,Wn):null,nt=Fe&&Dn?y({active:Fe,collisionRect:Dn,droppableRects:ce,droppableContainers:H,pointerCoordinates:Vr}):null,In=dy(nt,"id"),[mn,ca]=N.useState(null),lr=It?Wn:ms(Wn,la),sn=n_(lr,(l=mn?.rect)!=null?l:null,Me),_n=N.useRef(null),on=N.useCallback((he,Ee)=>{let{sensor:Ae,options:Ve}=Ee;if(qe.current==null)return;const ke=W.get(qe.current);if(!ke)return;const Ne=he.nativeEvent,Re=new Ae({active:qe.current,activeNode:ke,event:Ne,options:Ve,context:Ct,onAbort(He){if(!W.get(He))return;const{onDragAbort:Ce}=Z.current,je={id:He};Ce?.(je),$({type:"onDragAbort",event:je})},onPending(He,Ge,Ce,je){if(!W.get(He))return;const{onDragPending:At}=Z.current,Mt={id:He,constraint:Ge,initialCoordinates:Ce,offset:je};At?.(Mt),$({type:"onDragPending",event:Mt})},onStart(He){const Ge=qe.current;if(Ge==null)return;const Ce=W.get(Ge);if(!Ce)return;const{onDragStart:je}=Z.current,tt={activatorEvent:Ne,active:{id:Ge,data:Ce.data,rect:Ue}};Ma.unstable_batchedUpdates(()=>{je?.(tt),P(Na.Initializing),L({type:nn.DragStart,initialCoordinates:He,active:Ge}),$({type:"onDragStart",event:tt}),J(_n.current),Le(Ne)})},onMove(He){L({type:nn.DragMove,coordinates:He})},onEnd:et(nn.DragEnd),onCancel:et(nn.DragCancel)});_n.current=Re;function et(He){return async function(){const{active:Ce,collisions:je,over:tt,scrollAdjustedTranslate:At}=Ct.current;let Mt=null;if(Ce&&At){const{cancelDrop:On}=Z.current;Mt={activatorEvent:Ne,active:Ce,collisions:je,delta:At,over:tt},He===nn.DragEnd&&typeof On=="function"&&await Promise.resolve(On(Mt))&&(He=nn.DragCancel)}qe.current=null,Ma.unstable_batchedUpdates(()=>{L({type:He}),P(Na.Uninitialized),ca(null),J(null),Le(null),_n.current=null;const On=He===nn.DragEnd?"onDragEnd":"onDragCancel";if(Mt){const jt=Z.current[On];jt?.(Mt),$({type:On,event:Mt})}})}}},[W]),F=N.useCallback((he,Ee)=>(Ae,Ve)=>{const ke=Ae.nativeEvent,Ne=W.get(Ve);if(qe.current!==null||!Ne||ke.dndKit||ke.defaultPrevented)return;const Re={active:Ne};he(Ae,Ee.options,Re)===!0&&(ke.dndKit={capturedBy:Ee.sensor},qe.current=Ve,on(Ae,Ee))},[W,on]),se=R_(m,F);j_(m),Pr(()=>{Me&&O===Na.Initializing&&P(Na.Initialized)},[Me,O]),N.useEffect(()=>{const{onDragMove:he}=Z.current,{active:Ee,activatorEvent:Ae,collisions:Ve,over:ke}=Ct.current;if(!Ee||!Ae)return;const Ne={active:Ee,activatorEvent:Ae,collisions:Ve,delta:{x:gn.x,y:gn.y},over:ke};Ma.unstable_batchedUpdates(()=>{he?.(Ne),$({type:"onDragMove",event:Ne})})},[gn.x,gn.y]),N.useEffect(()=>{const{active:he,activatorEvent:Ee,collisions:Ae,droppableContainers:Ve,scrollAdjustedTranslate:ke}=Ct.current;if(!he||qe.current==null||!Ee||!ke)return;const{onDragOver:Ne}=Z.current,Re=Ve.get(In),et=Re&&Re.rect.current?{id:Re.id,rect:Re.rect.current,data:Re.data,disabled:Re.disabled}:null,He={active:he,activatorEvent:Ee,collisions:Ae,delta:{x:ke.x,y:ke.y},over:et};Ma.unstable_batchedUpdates(()=>{ca(et),Ne?.(He),$({type:"onDragOver",event:He})})},[In]),Pr(()=>{Ct.current={activatorEvent:fe,active:Fe,activeNode:ie,collisionRect:Dn,collisions:nt,droppableRects:ce,draggableNodes:W,draggingNode:rn,draggingNodeRect:Kt,droppableContainers:Se,over:mn,scrollableAncestors:an,scrollAdjustedTranslate:gn},Ue.current={initial:Kt,translated:Dn}},[Fe,ie,nt,Dn,W,rn,Kt,ce,Se,mn,an,gn]),A_({..._e,delta:pe,draggingRect:Dn,pointerCoordinates:Vr,scrollableAncestors:an,scrollableAncestorRects:pn});const ue=N.useMemo(()=>({active:Fe,activeNode:ie,activeNodeRect:Me,activatorEvent:fe,collisions:nt,containerNodeRect:pt,dragOverlay:ht,draggableNodes:W,droppableContainers:Se,droppableRects:ce,over:mn,measureDroppableContainers:de,scrollableAncestors:an,scrollableAncestorRects:pn,measuringConfiguration:T,measuringScheduled:be,windowRect:hn}),[Fe,ie,Me,fe,nt,pt,ht,W,Se,ce,mn,de,an,pn,T,be,hn]),ee=N.useMemo(()=>({activatorEvent:fe,activators:se,active:Fe,activeNodeRect:Me,ariaDescribedById:{draggable:ge},dispatch:L,draggableNodes:W,over:mn,measureDroppableContainers:de}),[fe,se,Fe,Me,L,ge,W,mn,de]);return Ye.createElement(sy.Provider,{value:k},Ye.createElement(Ac.Provider,{value:ee},Ye.createElement(Ly.Provider,{value:ue},Ye.createElement($y.Provider,{value:sn},h)),Ye.createElement(W_,{disabled:d?.restoreFocus===!1})),Ye.createElement(YE,{...d,hiddenTextDescribedById:ge}));function ve(){const he=wt?.autoScrollEnabled===!1,Ee=typeof f=="object"?f.enabled===!1:f===!1,Ae=G&&!he&&!Ee;return typeof f=="object"?{...f,enabled:Ae}:{enabled:Ae}}}),Z_=N.createContext(null),My="button",eA="Draggable";function tA(s){let{id:e,data:n,disabled:r=!1,attributes:i}=s;const l=Lo(eA),{activators:c,activatorEvent:d,active:f,activeNodeRect:h,ariaDescribedById:m,draggableNodes:y,over:S}=N.useContext(Ac),{role:v=My,roleDescription:_="draggable",tabIndex:x=0}=i??{},A=f?.id===e,L=N.useContext(A?$y:Z_),[$,k]=vc(),[O,P]=vc(),G=H_(c,e),B=Do(n);Pr(()=>(y.set(e,{id:e,key:l,node:$,activatorNode:O,data:B}),()=>{const pe=y.get(e);pe&&pe.key===l&&y.delete(e)}),[y,e]);const W=N.useMemo(()=>({role:v,tabIndex:x,"aria-disabled":r,"aria-pressed":A&&v===My?!0:void 0,"aria-roledescription":_,"aria-describedby":m.draggable}),[r,v,x,A,_,m.draggable]);return{active:f,activatorEvent:d,activeNodeRect:h,attributes:W,isDragging:A,listeners:r?void 0:G,node:$,over:S,setNodeRef:k,setActivatorNodeRef:P,transform:L}}function nA(){return N.useContext(Ly)}const rA="Droppable",aA={timeout:25};function iA(s){let{data:e,disabled:n=!1,id:r,resizeObserverConfig:i}=s;const l=Lo(rA),{active:c,dispatch:d,over:f,measureDroppableContainers:h}=N.useContext(Ac),m=N.useRef({disabled:n}),y=N.useRef(!1),S=N.useRef(null),v=N.useRef(null),{disabled:_,updateMeasurementsFor:x,timeout:A}={...aA,...i},L=Do(x??r),$=N.useCallback(()=>{if(!y.current){y.current=!0;return}v.current!=null&&clearTimeout(v.current),v.current=setTimeout(()=>{h(Array.isArray(L.current)?L.current:[L.current]),v.current=null},A)},[A]),k=Ec({callback:$,disabled:_||!c}),O=N.useCallback((W,pe)=>{k&&(pe&&(k.unobserve(pe),y.current=!1),W&&k.observe(W))},[k]),[P,G]=vc(O),B=Do(e);return N.useEffect(()=>{!k||!P.current||(k.disconnect(),y.current=!1,k.observe(P.current))},[P,k]),N.useEffect(()=>(d({type:nn.RegisterDroppable,element:{id:r,key:l,disabled:n,node:P,rect:S,data:B}}),()=>d({type:nn.UnregisterDroppable,key:l,id:r})),[r]),N.useEffect(()=>{n!==m.current.disabled&&(d({type:nn.SetDroppableDisabled,id:r,key:l,disabled:n}),m.current.disabled=n)},[r,l,n,d]),{active:c,rect:S,isOver:f?.id===r,node:P,over:f,setNodeRef:G}}function qf(s,e,n){const r=s.slice();return r.splice(n<0?r.length+n:n,0,r.splice(e,1)[0]),r}function sA(s,e){return s.reduce((n,r,i)=>{const l=e.get(r);return l&&(n[i]=l),n},Array(s.length))}function xc(s){return s!==null&&s>=0}function oA(s,e){if(s===e)return!0;if(s.length!==e.length)return!1;for(let n=0;n{var e;let{rects:n,activeNodeRect:r,activeIndex:i,overIndex:l,index:c}=s;const d=(e=n[i])!=null?e:r;if(!d)return null;const f=uA(n,c,i);if(c===i){const h=n[l];return h?{x:ii&&c<=l?{x:-d.width-f,y:0,...Tc}:c=l?{x:d.width+f,y:0,...Tc}:{x:0,y:0,...Tc}};function uA(s,e,n){const r=s[e],i=s[e-1],l=s[e+1];return!r||!i&&!l?0:n{let{rects:e,activeIndex:n,overIndex:r,index:i}=s;const l=qf(e,r,n),c=e[i],d=l[i];return!d||!c?null:{x:d.left-c.left,y:d.top-c.top,scaleX:d.width/c.width,scaleY:d.height/c.height}},kc={scaleX:1,scaleY:1},dA=s=>{var e;let{activeIndex:n,activeNodeRect:r,index:i,rects:l,overIndex:c}=s;const d=(e=l[n])!=null?e:r;if(!d)return null;if(i===n){const h=l[c];return h?{x:0,y:nn&&i<=c?{x:0,y:-d.height-f,...kc}:i=c?{x:0,y:d.height+f,...kc}:{x:0,y:0,...kc}};function fA(s,e,n){const r=s[e],i=s[e-1],l=s[e+1];return r?nr.map(G=>typeof G=="object"&&"id"in G?G.id:G),[r]),_=c!=null,x=c?v.indexOf(c.id):-1,A=h?v.indexOf(h.id):-1,L=N.useRef(v),$=!oA(v,L.current),k=A!==-1&&x===-1||$,O=lA(l);Pr(()=>{$&&_&&m(v)},[$,v,_,m]),N.useEffect(()=>{L.current=v},[v]);const P=N.useMemo(()=>({activeIndex:x,containerId:y,disabled:O,disableTransforms:k,items:v,overIndex:A,useDragOverlay:S,sortedRects:sA(v,f),strategy:i}),[x,y,O.draggable,O.droppable,k,v,A,f,S,i]);return Ye.createElement(Iy.Provider,{value:P},e)}const pA=s=>{let{id:e,items:n,activeIndex:r,overIndex:i}=s;return qf(n,r,i).indexOf(e)},gA=s=>{let{containerId:e,isSorting:n,wasDragging:r,index:i,items:l,newIndex:c,previousItems:d,previousContainerId:f,transition:h}=s;return!h||!r||d!==l&&i===c?!1:n?!0:c!==i&&e===f},mA={duration:200,easing:"ease"},jy="transform",yA=Mo.Transition.toString({property:jy,duration:0,easing:"linear"}),bA={roleDescription:"sortable"};function vA(s){let{disabled:e,index:n,node:r,rect:i}=s;const[l,c]=N.useState(null),d=N.useRef(n);return Pr(()=>{if(!e&&n!==d.current&&r.current){const f=i.current;if(f){const h=ys(r.current,{ignoreTransform:!0}),m={x:f.left-h.left,y:f.top-h.top,scaleX:f.width/h.width,scaleY:f.height/h.height};(m.x||m.y)&&c(m)}}n!==d.current&&(d.current=n)},[e,n,r,i]),N.useEffect(()=>{l&&c(null)},[l]),l}function SA(s){let{animateLayoutChanges:e=gA,attributes:n,disabled:r,data:i,getNewIndex:l=pA,id:c,strategy:d,resizeObserverConfig:f,transition:h=mA}=s;const{items:m,containerId:y,activeIndex:S,disabled:v,disableTransforms:_,sortedRects:x,overIndex:A,useDragOverlay:L,strategy:$}=N.useContext(Iy),k=wA(r,v),O=m.indexOf(c),P=N.useMemo(()=>({sortable:{containerId:y,index:O,items:m},...i}),[y,i,O,m]),G=N.useMemo(()=>m.slice(m.indexOf(c)),[m,c]),{rect:B,node:W,isOver:pe,setNodeRef:Se}=iA({id:c,data:P,disabled:k.droppable,resizeObserverConfig:{updateMeasurementsFor:G,...f}}),{active:we,activatorEvent:Ue,activeNodeRect:Fe,attributes:qe,setNodeRef:wt,listeners:J,isDragging:fe,over:Le,setActivatorNodeRef:Z,transform:ge}=tA({id:c,data:P,attributes:{...bA,...n},disabled:k.draggable}),H=IE(Se,wt),T=!!we,ce=T&&!_&&xc(S)&&xc(A),de=!L&&fe,be=de&&ce?ge:null,xe=ce?be??(d??$)({rects:x,activeNodeRect:Fe,activeIndex:S,overIndex:A,index:O}):null,_e=xc(S)&&xc(A)?l({id:c,items:m,activeIndex:S,overIndex:A}):O,Te=we?.id,Me=N.useRef({activeId:Te,items:m,newIndex:_e,containerId:y}),pt=m!==Me.current.items,Ct=e({active:we,containerId:y,isDragging:fe,isSorting:T,id:c,index:O,items:m,newIndex:Me.current.newIndex,previousItems:Me.current.items,previousContainerId:Me.current.containerId,transition:h,wasDragging:Me.current.activeId!=null}),Ot=vA({disabled:!Ct,index:O,node:W,rect:B});return N.useEffect(()=>{T&&Me.current.newIndex!==_e&&(Me.current.newIndex=_e),y!==Me.current.containerId&&(Me.current.containerId=y),m!==Me.current.items&&(Me.current.items=m)},[T,_e,y,m]),N.useEffect(()=>{if(Te===Me.current.activeId)return;if(Te!=null&&Me.current.activeId==null){Me.current.activeId=Te;return}const rn=setTimeout(()=>{Me.current.activeId=Te},50);return()=>clearTimeout(rn)},[Te]),{active:we,activeIndex:S,attributes:qe,data:P,rect:B,index:O,newIndex:_e,items:m,isOver:pe,isSorting:T,isDragging:fe,listeners:J,node:W,overIndex:A,over:Le,setNodeRef:H,setActivatorNodeRef:Z,setDroppableNodeRef:Se,setDraggableNodeRef:wt,transform:Ot??xe,transition:ht()};function ht(){if(Ot||pt&&Me.current.newIndex===O)return yA;if(!(de&&!Of(Ue)||!h)&&(T||Ct))return Mo.Transition.toString({...h,property:jy})}}function wA(s,e){var n,r;return typeof s=="boolean"?{draggable:s,droppable:!1}:{draggable:(n=s?.draggable)!=null?n:e.draggable,droppable:(r=s?.droppable)!=null?r:e.droppable}}function Rc(s){if(!s)return!1;const e=s.data.current;return!!(e&&"sortable"in e&&typeof e.sortable=="object"&&"containerId"in e.sortable&&"items"in e.sortable&&"index"in e.sortable)}const CA=[lt.Down,lt.Right,lt.Up,lt.Left],EA=(s,e)=>{let{context:{active:n,collisionRect:r,droppableRects:i,droppableContainers:l,over:c,scrollableAncestors:d}}=e;if(CA.includes(s.code)){if(s.preventDefault(),!n||!r)return;const f=[];l.getEnabled().forEach(y=>{if(!y||y!=null&&y.disabled)return;const S=i.get(y.id);if(S)switch(s.code){case lt.Down:r.topS.top&&f.push(y);break;case lt.Left:r.left>S.left&&f.push(y);break;case lt.Right:r.left1&&(m=h[1].id),m!=null){const y=l.get(n.id),S=l.get(m),v=S?i.get(S.id):null,_=S?.node.current;if(_&&v&&y&&S){const A=wc(_).some((G,B)=>d[B]!==G),L=Hy(y,S),$=_A(y,S),k=A||!L?{x:0,y:0}:{x:$?r.width-v.width:0,y:$?r.height-v.height:0},O={x:v.left,y:v.top};return k.x&&k.y?O:$o(O,k)}}}};function Hy(s,e){return!Rc(s)||!Rc(e)?!1:s.data.current.sortable.containerId===e.data.current.sortable.containerId}function _A(s,e){return!Rc(s)||!Rc(e)||!Hy(s,e)?!1:s.data.current.sortable.index{const d=N.useId(),f=N.useRef({inProgress:!1,lastSortTime:0,lastActiveId:null}),h=XE(oy(zf,{activationConstraint:{distance:5}}),oy(jf,{coordinateGetter:EA})),m=N.useCallback(v=>{f.current={inProgress:!0,lastSortTime:Date.now(),lastActiveId:v.active.id},l?.({activeId:v.active.id})},[l]),y=N.useCallback(v=>{const{active:_,over:x}=v,A=Date.now();if(!x||_.id===x.id){f.current.inProgress=!1;return}const{lastSortTime:L,lastActiveId:$,inProgress:k}=f.current;if($===_.id&&A-L<500&&!k)return;f.current={inProgress:!1,lastSortTime:A,lastActiveId:_.id};const O=s.findIndex(G=>String(G[e])===String(_.id)),P=s.findIndex(G=>String(G[e])===String(x.id));if(O!==-1&&P!==-1&&O!==P){const G=qf(s,O,P);i?.(G,{oldIndex:O,newIndex:P})}},[s,e,i]),S=s.map(v=>String(v[e]));return ft.jsx(Q_,{id:d,sensors:h,collisionDetection:QE,onDragStart:m,onDragEnd:y,children:ft.jsx(hA,{items:S,strategy:AA[n],children:r})},c!==void 0?`${d}-v${c}`:d)},zy=N.createContext(null),TA=({value:s,children:e})=>ft.jsx(zy.Provider,{value:s,children:e}),kA=()=>N.useContext(zy),RA=({id:s,handle:e,as:n="div",children:r})=>{const{attributes:i,listeners:l,setNodeRef:c,transform:d,transition:f,isDragging:h}=SA({id:s}),m={transform:Mo.Transform.toString(d),transition:f,opacity:h?.5:1,position:"relative"};return ft.jsx(n,{ref:c,style:m,...i,...e?{}:l,"data-sortable-item":!0,"data-sortable-id":String(s),"data-dragging":h,children:ft.jsx(TA,{value:{listeners:l,handle:e,isDragging:h},children:r})})},it=dt("DynamicRenderer");function ia(){try{return window.G7Core?.devTools}catch{return}}function Ff(s,e,n,r){if(typeof s=="string"){if(/\$t:[a-zA-Z_][a-zA-Z0-9_.\-]*/.test(s))try{return e.resolveTranslations(s,n,r)}catch{return s}return s}if(Array.isArray(s))return s.map(i=>Ff(i,e,n,r));if(s&&typeof s=="object"){const i={};for(const[l,c]of Object.entries(s))i[l]=Ff(c,e,n,r);return i}return s}function DA(s){const e=Object.keys(s);return e.length>0&&e.every(n=>/^\d+$/.test(n))}const Ar=(s,e)=>{const n=["errors"],r={...s};for(const i of Object.keys(e)){const l=e[i],c=s[i];if(l===null){r[i]=null;continue}if(n.includes(i)){r[i]=l;continue}if(Array.isArray(l)){r[i]=l;continue}if(Array.isArray(c)&&l!==null&&typeof l=="object"&&!Array.isArray(l)&&DA(l)){const d=Object.keys(l).map(h=>parseInt(h,10));if((d.length>0?Math.max(...d):0)>=c.length+d.length+10)r[i]={...l};else{const h=[...c];for(const[m,y]of Object.entries(l)){const S=parseInt(m,10);S>=0&&S=h.length&&(h[S]=y)}r[i]=h}}else l!==null&&typeof l=="object"&&c!==null&&typeof c=="object"&&!Array.isArray(c)?r[i]=Ar(c,l):r[i]=l}return r},Dc=(s,e)=>{let n=null;const r=()=>(n===null&&(n={...s}),n);for(const i of Object.keys(e)){if(!(i in s))continue;const l=e[i],c=s[i];if(l!==null&&typeof l=="object"&&!Array.isArray(l)&&c!==null&&typeof c=="object"&&!Array.isArray(c)){const d=Dc(c,l);if(d===c)continue;Object.keys(d).length===0?delete r()[i]:r()[i]=d}else delete r()[i]}return n??s},OA=s=>{const e={},n=s.split(";").filter(r=>r.trim());for(const r of n){const i=r.indexOf(":");if(i===-1)continue;const l=r.substring(0,i).trim(),c=r.substring(i+1).trim();if(l&&c){const d=l.replace(/-([a-z])/g,(f,h)=>h.toUpperCase());e[d]=c}}return e};class LA extends N.Component{constructor(e){super(e),this.state={hasError:!1,error:null}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}componentDidCatch(e,n){it.error(`컴포넌트 렌더링 에러 (ID: ${this.props.componentId}, Name: ${this.props.componentName}):`,e,n)}render(){return this.state.hasError?this.props.fallback?this.props.fallback:ft.jsxs("div",{className:"p-4 my-2 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg text-red-800 dark:text-red-400",children:[ft.jsx("div",{className:"font-semibold mb-1",children:"컴포넌트 로드 실패"}),ft.jsxs("div",{className:"text-xs opacity-80",children:[this.props.componentName&&`[${this.props.componentName}] `,"데이터를 표시할 수 없습니다."]}),this.state.error&&ft.jsxs("details",{className:"mt-2",children:[ft.jsx("summary",{className:"cursor-pointer text-xs opacity-70 hover:opacity-100",children:"상세 정보"}),ft.jsx("div",{className:"mt-1 p-2 bg-red-100 dark:bg-red-900/30 rounded text-xs font-mono whitespace-pre-wrap break-all",children:this.state.error.message})]})]}):this.props.children}}const Br=N.memo(({componentDef:s,dataContext:e,translationContext:n,registry:r,bindingEngine:i,translationEngine:l,actionDispatcher:c,parentComponentContext:d,parentFormContextProp:f,parentDataContext:h,isRootRenderer:m=!1,isInsideIteration:y=!1,isEditMode:S=!1,onComponentSelect:v,onComponentHover:_,onDragStart:x,onDragEnd:A,componentPath:L,layoutKey:$})=>{const[k,O]=N.useState({loadingActions:{}});N.useLayoutEffect(()=>{d||(i.startRenderCycle(),window.__g7SetLocalOverrideKeys||(window.__g7ForcedLocalFields=void 0),window.__g7PendingLocalState=null)});const P=N.useRef(null);N.useLayoutEffect(()=>{if(!d&&e._localInit&&typeof e._localInit=="object"){const{_forceLocalInit:F,_merge:se,...ue}=e._localInit,ee=`${JSON.stringify(ue)}:${F||"no-force"}`;if(P.current!==ee){P.current=ee;const ve=se||"shallow",Ee=window.G7Core?.state?.get?.()?._local||{},Ae=window.__g7PendingLocalState||{},Ve={...Ee,...Ae};ve==="replace"?window.__g7PendingLocalState={loadingActions:Ve.loadingActions||{},...ue,hasChanges:!1}:ve==="deep"?window.__g7PendingLocalState=Ar(Ve,{...ue,hasChanges:!1}):window.__g7PendingLocalState={...Ve,...ue,hasChanges:!1};const ke=window.__g7SetLocalOverrideKeys;ke&&typeof ke=="object"&&(ve==="replace"?window.__g7SetLocalOverrideKeys={...ue,hasChanges:!1}:window.__g7SetLocalOverrideKeys=Ar(ke,{...ue,hasChanges:!1}))}}}),N.useLayoutEffect(()=>{if(!d){const F=window.__g7SetLocalOverrideKeys;if(F){O(ve=>Dc(ve,F));const se=F,ue=window.__g7ForcedLocalFields,ee=window.__g7LastSetLocalSnapshot;queueMicrotask(()=>{window.__g7SetLocalOverrideKeys===se&&(window.__g7SetLocalOverrideKeys=void 0),window.__g7ForcedLocalFields===ue&&(window.__g7ForcedLocalFields=void 0),window.__g7LastSetLocalSnapshot===ee&&(window.__g7LastSetLocalSnapshot=void 0)})}}},[e._local]);const G=N.useRef($);N.useEffect(()=>{s._fromBase&&$&&G.current!==$&&(G.current=$,O({loadingActions:{}}))},[$,s._fromBase]);const B=N.useRef(""),W=N.useRef(!1),pe=N.useRef(null),Se=N.useRef(null),we=N.useRef({}),Ue=N.useRef({}),Fe=N.useRef(h),qe=NE(),wt=dE(),J=wt?.getParentDataContext()??h;N.useEffect(()=>{if(e._localInit&&typeof e._localInit=="object"){const{_forceLocalInit:F,...se}=e._localInit,ue=JSON.stringify(se),ee=F!==void 0,ve=Ef(),he=`${ue}:${F||"no-force"}`,Ee=vE({globalTrackedKey:ve.hash,instanceHandledKey:Se.current,trackingKey:he});if(Ee==="apply"){Se.current=he,ve.hash=he,ve.timestamp=F,B.current=ue,ee&&(W.current=!0);const{_merge:Ve,...ke}=se,Ne=Ve||"shallow";O(Re=>Ne==="replace"?{loadingActions:Re.loadingActions||{},...ke,hasChanges:!1}:Ne==="deep"?Ar(Re,{...ke,hasChanges:!1}):{...Re,...ke,hasChanges:!1}),e._globalSetState&&e._globalSetState(Re=>{const et=Re?._local||{};let He;return Ne==="replace"?He={...ke,hasChanges:!1}:Ne==="deep"?He=Ar(et,{...ke,hasChanges:!1}):He={...et,...ke,hasChanges:!1},{...Re,_local:He}}),i.invalidateCacheByKeys(["_local"]),it.log("_localInit applied (data changed):",Object.keys(se))}else if(Ee==="prune"){Se.current=he;const{_merge:Ve,...ke}=se;O(Re=>Dc(Re,ke)),Dc(k,ke)!==k&&(i.invalidateCacheByKeys(["_local"]),it.log("_localInit pruned (applied by another renderer):",Object.keys(ke)))}pe.current=e._localInit,yE(e._localInit)}},[e._localInit,h,i]);const{isTransitioning:fe}=Jm(),Le=xE(),Z=f??Le,{width:ge}=Af(),H=kA(),T=N.useMemo(()=>{let F=s;if(s.type==="iterator"&&s.data){const{data:ee,itemName:ve,indexName:he,...Ee}=s;F={...Ee,iteration:{source:ee,item_var:ve||"item",index_var:he}}}if(!F.responsive)return F;const se=Si.getMatchingKey(F.responsive,ge);if(!se)return F;const ue=F.responsive[se];return{...F,props:{...F.props,...ue.props},children:ue.children??F.children,text:ue.text??F.text,if:ue.if??F.if,iteration:ue.iteration??F.iteration,__responsiveChildrenKey:ue.children!==void 0?se:void 0}},[s,ge]),ce=N.useCallback(F=>{const se=F?.__setStateId;if(O(ue=>{const ee=window.__g7PendingLocalState,he=window.__g7SetLocalOverrideKeys||ee,Ee=he?Ar(ue,he):ue;if(typeof F=="function"){const Re=F(Ee);return Ar(Ee,Re)}const{__mergeMode:Ae,__setStateId:Ve,...ke}=F;let Ne;if(Ae==="replace"?Ne=ke:Ae==="shallow"?Ne={...Ee,...ke}:Ne=Ar(Ee,ke),Ae!==void 0){const Re=window.__g7ForcedLocalFields;Re&&(window.__g7ForcedLocalFields={...Re,...ke})}return Ne}),se){const ue=ia();if(ue?.isEnabled()){const ee=T.id||"unknown",ve=T.name||"Unknown";setTimeout(()=>{ue.trackComponentRender?.(ee,ve,0,["_local"],[]),ue.completeStateChange?.(se)},0)}}},[T.id,T.name]),de=d?.state??k,be=d?.setState??ce,ie=N.useMemo(()=>{const F=e._localInit&&e._localInit!==pe.current;let se;F&&e._local?se=e._local:se=e._local?Ar(e._local,de):de;const ue=window.__g7ForcedLocalFields;ue&&(se=Ar(se,ue));const ee={...e,_local:se},ve=e._computedDefinitions;if(ve&&Object.keys(ve).length>0){const he=new kn,Ee={...ee,...qe?{_isolated:qe.state}:{}},Ae={},Ve=ia(),ke=Ve?.isEnabled()??!1;for(const[Ne,Re]of Object.entries(ve)){const et=ke?Date.now():0,He=ke?e._computed?.[Ne]:void 0;let Ge;try{if(typeof Re=="string")if(Re.startsWith("{{")&&Re.endsWith("}}")){const Ce=Re.slice(2,-2).trim(),je=Gn(Ce)?he.evaluatePipeExpression(Ce,Ee,{skipCache:!0}):he.evaluateExpression(Ce,Ee,{skipCache:!0});Ae[Ne]=je}else Ae[Ne]=Re;else if(Re&&typeof Re=="object"&&"$switch"in Re){const Ce=he.resolveSwitch(Re,Ee,{skipCache:!0});Ae[Ne]=Ce}}catch(Ce){it.warn(`Failed to recalculate computed value: ${Ne}`,Ce),Ae[Ne]=e._computed?.[Ne],Ge=Ce instanceof Error?Ce.message:String(Ce)}if(ke&&(Ge||He!==Ae[Ne])){const je=Date.now()-et;Ve.trackComputedProperty?.(Ne,typeof Re=="string"?Re:JSON.stringify(Re),[{type:"_local",path:"_local",value:ee._local}],Ae[Ne],je,T.id,Ge),He!==Ae[Ne]&&Ve.trackComputedRecalc?.(Ne,"dependency-change",He,Ae[Ne],je,{type:"_local",path:"_local"},T.id)}}ee._computed=Ae}if(qe&&(ee._isolated=qe.state),J&&(ee.$parent=J),s.extensionPointProps){const he=i.resolveObject(s.extensionPointProps,ee,y?{skipCache:!0}:void 0);ee.extensionPointProps=S&&l?Ff(he,l,n,ee):he}return s.extensionPointCallbacks&&(ee.extensionPointCallbacks=s.extensionPointCallbacks),S&&(ee.$templateId===void 0&&n?.templateId&&(ee.$templateId=n.templateId),ee.$locale===void 0&&n?.locale&&(ee.$locale=n.locale)),ee},[e,de,qe?.state,J,wt?.version,s.extensionPointProps,s.extensionPointCallbacks]);we.current=ie._local,Ue.current=ie._computed||{},Fe.current=J,N.useEffect(()=>{const F=ia();if(!F?.isEnabled())return;const se=ie._local;se&&F.updateLocalState(se);const ue=ie._computed;ue&&F.updateComputedState(ue),J&&F.updateParentContext?.(J);const ee=T.id||`comp-${Date.now()}`,ve=T.name||"Unknown",he={global:Object.keys(e._global||{}),local:Object.keys(se||{}),context:d?Object.keys(d.state||{}):[]},Ee={type:d?"componentContext":"dynamicState",hasComponentContext:!!d,parentId:d?"parent":void 0};F.trackComponentStateSource?.(ee,ve,he,Ee),de&&Object.keys(de).length>0&&F.trackDynamicState?.(ee,de);const Ae=!!(T.expandChildren||T.props?.expandChildren);F.trackContextFlow?.(ee,ve,!!d,Ae,!0)},[ie._local,e,T.id,T.name,d,de,T.expandChildren,T.props?.expandChildren,J]);const xe=N.useMemo(()=>({state:{...ie._local},setState:be,stateRef:we,computedRef:Ue,isolatedContext:qe,parentDataContext:ie}),[ie._local,be,k,qe,ie]),_e=N.useMemo(()=>{const F=os({if:T.if,condition:T.condition,conditions:T.conditions},ie,i,T.id);if(T.if||T.condition!==void 0||T.conditions){const ue=ia();ue?.isEnabled()&&T.if&&ue.trackIfCondition(T.id||`if-${Date.now()}`,T.if,F)}return F},[T.if,T.conditions,ie,i,T.id]),Te=N.useMemo(()=>{if(!T.slot)return null;const F=T.slot;if(F.startsWith("{{")&&F.endsWith("}}")){const se=F.slice(2,-2).trim();try{const ue={componentId:T.id,componentName:T.name,propName:"slot"},ee=Gn(se)?i.evaluatePipeExpression(se,ie,void 0,ue):i.evaluateExpression(se,ie,ue);return it.log(`[Slot] 표현식 평가: "${se}" => "${ee}" (컴포넌트: ${T.id})`),typeof ee=="string"?ee:null}catch(ue){return it.warn(`slot 표현식 평가 실패 (컴포넌트: ${T.id}):`,ue),null}}return it.log(`[Slot] 정적 슬롯 ID: "${F}" (컴포넌트: ${T.id})`),F},[T.slot,T.id,ie,i]),Me=N.useMemo(()=>!Te||!T.id?"":`${T.id}-${Te}-${JSON.stringify(T.slotOrder??0)}`,[Te,T.id,T.slotOrder]),pt=N.useRef(null);N.useEffect(()=>{const F=window.__slotContextValue,se=F?.isEnabled??!1;if(T.slot&&it.log(`[Slot Registration] 컴포넌트: ${T.id}, isSlotEnabled: ${se}, shouldRender: ${_e}, resolvedSlotId: ${Te}`),!se||!_e){T.slot&&it.log(`[Slot Registration] 등록 스킵 - isSlotEnabled: ${se}, shouldRender: ${_e}`),pt.current&&T.id&&F&&(F.unregisterFromSlot(pt.current,T.id),pt.current=null);return}if(!Te||!T.id){T.slot&&it.log(`[Slot Registration] 등록 스킵 - resolvedSlotId: ${Te}, id: ${T.id}`),pt.current&&T.id&&F&&(F.unregisterFromSlot(pt.current,T.id),pt.current=null);return}pt.current&&pt.current!==Te&&F.unregisterFromSlot(pt.current,T.id);const ue={...T,slot:void 0,slotOrder:void 0};return F.registerToSlot(Te,T.id,{componentDef:ue,dataContext:e,order:T.slotOrder??0,parentFormContext:f??null,getParentComponentContext:()=>xe,translationContext:n,registrationKey:Me}),pt.current=Te,()=>{const ee=window.__slotContextValue;Te&&T.id&&ee&&ee.unregisterFromSlot(Te,T.id)}},[_e,Te,T,e,f,xe,n,Me]);const Ct=N.useCallback(F=>{if(typeof F=="string"){if(Wl(F))return zd(F);if(Yl(F)){const se=[],ue=F.replace(new RegExp(`${po}([^${bi}]*)${bi}`,"g"),(ve,he)=>(se.push(he),`${Oa}${se.length-1}${Oa}`));let ee=ue;return/\$t:[a-zA-Z0-9._-]+/.test(ue)&&(ee=l.resolveTranslations(ue,n,ie)),ee.replace(new RegExp(`${Oa}(\\d+)${Oa}`,"g"),(ve,he)=>se[parseInt(he)])}if(F.startsWith("$t:defer:"))return F;if(/\$t:[a-zA-Z0-9._-]+/.test(F)){const se=F.trim();return se.startsWith("{")&&se.endsWith("}")||se.startsWith("[")&&se.endsWith("]")?F:l.resolveTranslations(F,n,ie)}return F}if(Array.isArray(F))return F.map(se=>Ct(se));if(F&&typeof F=="object"){const se={};for(const[ue,ee]of Object.entries(F))se[ue]=Ct(ee);return se}return F},[l,n,ie]),Ot=N.useCallback(F=>ho(F),[]),ht=N.useCallback(F=>Da(F),[]),rn=N.useMemo(()=>{let F={...T.props||{}};const se=["cellChildren","expandChildren","expandContext","render"],ee=r.getMetadata(T.name)?.skipBindingKeys||[],ve=[...new Set([...se,...ee])],he=y?{skipCache:!0}:void 0,Ee={...he??{},skipBindingKeys:ve},Ae=Ce=>{if(he)return he;if(Ce.startsWith("_computed")||Ce.startsWith("$computed"))return{skipCache:!0}};for(const[Ce,je]of Object.entries(F))if(!ve.includes(Ce))if(typeof je=="string"){const tt=ht(je);if(tt!==null){let At=!1,Mt=tt;tt.startsWith(nr)&&(At=!0,Mt=tt.slice(nr.length));const On={componentId:T.id,componentName:T.name,propName:Ce};let jt;if(Gn(Mt))try{jt=i.evaluatePipeExpression(Mt,ie,Ae(Mt),On)}catch(Ht){it.warn(`파이프 표현식 평가 실패 (컴포넌트: ${T.id}, prop: ${Ce}):`,Ht),jt=void 0}else if(Ot(Mt))try{jt=i.evaluateExpression(Mt,ie,On)}catch(Ht){it.warn(`표현식 평가 실패 (컴포넌트: ${T.id}, prop: ${Ce}):`,Ht),jt=void 0}else jt=i.resolve(Mt,ie,Ae(Mt),On);F[Ce]=At&&jt!=null?ss(jt):jt}else{const At={componentId:T.id,componentName:T.name,propName:Ce};F[Ce]=i.resolveBindings(je,ie,he,At)}}else Array.isArray(je)?F[Ce]=je.map(tt=>typeof tt=="string"?i.resolveBindings(tt,ie,he):typeof tt=="object"&&tt!==null?i.resolveObject(tt,ie,Ee):tt):je&&typeof je=="object"&&(F[Ce]=i.resolveObject(je,ie,Ee));for(const[Ce,je]of Object.entries(F))F[Ce]=Ct(je);if(typeof F.style=="string"&&(F.style=OA(F.style)),F=Qd(F,S?void 0:T.actions,ie,{componentContext:xe,actionDispatcher:c}),T.classMap){const Ce=S0(T.classMap,ie,i,{skipCache:!0});if(Ce){const je=F.className||"";F.className=je?`${je} ${Ce}`:Ce}}T.style&&(F.style=T.style),T.actions&&T.actions.length>0&&T.type==="composite"&&Object.assign(F,de),T.component_layout&&(F.__componentLayoutDefs=T.component_layout);const Ve=T.expandChildren||T.props?.expandChildren,ke=T.props?.cellChildren,Ne=T.children&&T.children.length>0,Re=T.component_layout,et=T.slot,He=T.props?.modalId,Ge=T.type==="composite";return(Ve||ke||Ne||Re||et||He||Ge)&&(F.__componentContext=xe),F},[T.props,T.actions,T.style,T.classMap,T.id,ie,n,i,l,xe,de,Ct,Ot,ht,y]),Kt=N.useRef(null),It=N.useMemo(()=>Kt.current&&Zm(Kt.current,rn)?Kt.current:(Kt.current=rn,rn),[rn]),Fr=N.useMemo(()=>{const F=T.id;if(typeof F!="string"||!F.includes("{{"))return F;const se=i.resolveBindings(F,ie,{skipCache:!0});return typeof se=="string"?se:F},[T.id,ie,i]),hn=N.useMemo(()=>{const F=T.dataKey,se=T.trackChanges,ue=T.debounce;if(F){const ee=F.startsWith("_global."),ve=ee?F.slice(8):F,he=ee?e._global:ie._local;return{dataKey:ve,trackChanges:se??!1,debounce:ue,setState:ee?Ae=>{e._globalSetState?e._globalSetState(Ae):it.warn("_global.formData 사용 시 _globalSetState가 필요합니다.")}:be,state:he??{},_isGlobal:ee}}if(Z.dataKey)return Z},[T.dataKey,T.trackChanges,T.debounce,T.id,be,ie._local,e._global,e._globalSetState,Z]),an=N.useRef(new Set);N.useEffect(()=>{an.current.clear()},[e._global?._remountKeys]);const pn=N.useCallback((F,se)=>{const ue=e._global?._remountKeys;return F&&ue?.[F]&&!an.current.has(F)?(an.current.add(F),`${F}-remount-${ue[F]}`):F||se},[e._global?._remountKeys]),Wn=N.useMemo(()=>{if(T.text!==void 0){if(typeof T.text=="string"){const F=T.text;let se=F;const ue={componentId:T.id,componentName:T.name,propName:"text",skipCache:!0},ee=ht(F);if(ee!==null){let ve=!1,he=ee;if(ee.startsWith(nr)&&(ve=!0,he=ee.slice(nr.length)),Gn(he))try{se=i.evaluatePipeExpression(he,ie,{skipCache:!0},ue)}catch(Ee){it.warn(`text 파이프 표현식 평가 실패 (컴포넌트: ${T.id}):`,Ee),se=""}else if(Ot(he))try{se=i.evaluateExpression(he,ie,ue)}catch(Ee){it.warn(`text 표현식 평가 실패 (컴포넌트: ${T.id}):`,Ee),se=""}else se=i.resolve(he,ie,{skipCache:!0},ue);ve&&se!=null&&(se=ss(se))}else F.includes("{{")&&(se=i.resolveBindings(F,ie,{skipCache:!0},ue));return se=Ct(se),se??""}return T.text}return!T.children||T.children.length===0?null:T.children.map((F,se)=>{if(typeof F=="string")return F;const ue=T.__responsiveChildrenKey,ee=ue?`responsive.${ue}.children`:"children",ve=L?`${L}.${ee}.${se}`:`${se}`,he=F._fromBase?F.id||`child-${se}`:pn(F.id,`child-${se}`),Ee=!F._fromBase&&$?`${he}_${$}`:he;return ft.jsx(Br,{componentDef:F,dataContext:ie,translationContext:n,registry:r,bindingEngine:i,translationEngine:l,actionDispatcher:c,parentComponentContext:xe,parentFormContextProp:hn,isInsideIteration:y,isEditMode:S,onComponentSelect:v,onComponentHover:_,componentPath:ve,onDragStart:x,onDragEnd:A,layoutKey:$},Ee)})},[T.text,T.children,T.id,e,ie,n,r,i,l,c,xe,hn,ht,Ot,Ct,pn,y,S,v,_,L,x,A,$]),Vr=N.useMemo(()=>{if(!T.iteration)return null;try{const F=Jd(T.iteration.source,ie,i);if(!Array.isArray(F))return it.warn(`iteration source가 배열이 아닙니다 (컴포넌트: ${T.id}):`,F),null;const se=ia();return se?.isEnabled()&&se.trackIteration(T.id||`iteration-${Date.now()}`,T.iteration.source,T.iteration.item_var,T.iteration.index_var,F.length),F.map((ue,ee)=>{const ve={...ie,[T.iteration.item_var]:ue,[`${T.iteration.item_var}_index`]:ee};T.iteration.index_var&&(ve[T.iteration.index_var]=ee);const he=ee===0||ee===F.length-1;se?.isEnabled()&&he&&se.trackNestedContext?.({componentId:`${T.id||"unknown"}-iter-${ee}`,componentType:"iteration",parentContext:{available:Object.keys(ie),values:{}},ownContext:{added:[T.iteration.item_var,...T.iteration.index_var?[T.iteration.index_var]:[]],values:{[T.iteration.item_var]:ue,...T.iteration.index_var?{[T.iteration.index_var]:ee}:{}}},depth:1});const Ee={...T,iteration:void 0,responsive:void 0},Ae=L?`${L}.iteration.${ee}`:`iteration.${ee}`,Ve=`${pn(T.id,"item")}-${ee}`;return ft.jsx(Br,{componentDef:Ee,dataContext:ve,translationContext:n,registry:r,bindingEngine:i,translationEngine:l,actionDispatcher:c,parentComponentContext:xe,parentFormContextProp:hn,isInsideIteration:!0,isEditMode:S,onComponentSelect:v,onComponentHover:_,componentPath:Ae,onDragStart:x,onDragEnd:A,layoutKey:$},Ve)})}catch(F){return it.error(`iteration 렌더링 실패 (컴포넌트: ${T.id}):`,F),null}},[T.iteration,T.children,T.id,e,ie,n,r,i,l,c,xe,hn,pn,S,v,_,L,x,A,$]),[qt,ki]=N.useState(0),la=N.useMemo(()=>{if(!T.sortable||!T.itemTemplate)return null;const{sortable:F,itemTemplate:se}=T;try{const ue=Jd(F.source,ie,i);if(!Array.isArray(ue))return it.warn(`sortable source가 배열이 아닙니다 (컴포넌트: ${T.id}):`,ue),null;if(ue.length===0)return null;const ee=F.itemKey||"id",ve=F.strategy||"verticalList",he=F.itemVar||"$item",Ee=F.indexVar||"$index",Ae=F.handle,Ve=F.wrapperElement,ke=(et,He)=>{const Ge=T.actions?.filter(Ce=>Ce.event==="onSortEnd"||Ce.type==="onSortEnd");if(ki(Ce=>Ce+1),Ge&&Ge.length>0&&c){const Ce={...ie,$sortedItems:et,$sortEvent:He};Ge.forEach(je=>{try{const tt=c.createHandler(je,Ce,xe),At=new Event("sortend");tt(At)}catch(tt){it.error(`onSortEnd action failed: ${je.handler}`,tt)}})}},Ne=et=>{const He=T.actions?.filter(Ge=>Ge.event==="onSortStart"||Ge.type==="onSortStart");if(He&&He.length>0&&c){const Ge={...ie,$activeId:et.activeId};He.forEach(Ce=>{try{const je=c.createHandler(Ce,Ge,xe),tt=new Event("sortstart");je(tt)}catch(je){it.error(`onSortStart action failed: ${Ce.handler}`,je)}})}},Re=ue.map((et,He)=>{const Ge=String(et[ee]),Ce={...ie,[he]:et,[Ee]:He},je=L?`${L}.sortable.${He}`:`sortable.${He}`,tt=`${pn(T.id,"sortable-item")}-v${qt}-${Ge}`;return ft.jsx(RA,{id:Ge,handle:Ae,...Ve?{as:Ve}:{},children:(Ve&&se.children?se.children:[se]).map((At,Mt)=>ft.jsx(Br,{componentDef:At,dataContext:Ce,translationContext:n,registry:r,bindingEngine:i,translationEngine:l,actionDispatcher:c,parentComponentContext:xe,parentFormContextProp:void 0,isInsideIteration:!0,isEditMode:S,onComponentSelect:v,onComponentHover:_,componentPath:je,onDragStart:x,onDragEnd:A,layoutKey:$},`${tt}-child-${Mt}`))},tt)});return ft.jsx(xA,{items:ue,itemKey:ee,strategy:ve,onSortEnd:ke,onSortStart:Ne,sortVersion:qt,children:Re})}catch(ue){return it.error(`sortable 렌더링 실패 (컴포넌트: ${T.id}):`,ue),null}},[T.sortable,T.itemTemplate,T.actions,T.id,e,ie,n,r,i,l,c,xe,pn,S,v,_,L,x,A,qt,$]),gn=N.useRef(!1);N.useEffect(()=>{if(gn.current)return;gn.current=!0;const F=ia();if(F?.isEnabled()&&F.trackMount(s.id,{name:s.name,type:s.type||"component",props:It}),s.lifecycle?.onMount&&s.lifecycle.onMount.length>0)for(const ue of s.lifecycle.onMount)try{const ee=c.createHandler(ue,ie,xe),ve=new Event("mount");ee(ve),it.log(`Lifecycle onMount executed: ${ue.handler} (Component: ${s.id})`)}catch(ee){it.error(`Lifecycle onMount failed: ${ue.handler} (Component: ${s.id})`,ee)}const se=[];if(s.onComponentEvent&&s.onComponentEvent.length>0){const ue=window.G7Core;if(ue?.componentEvent?.on)for(const ee of s.onComponentEvent){if(!ee.event){it.warn(`onComponentEvent: event name is required (Component: ${s.id})`);continue}const ve=async Ee=>{try{const Ae={...ie,_eventData:Ee},ke=await c.createHandler({handler:ee.handler,params:ee.params,onSuccess:ee.onSuccess,onError:ee.onError},Ae,xe)(new CustomEvent(ee.event,{detail:Ee}));return it.log(`onComponentEvent "${ee.event}" handled: ${ee.handler} (Component: ${s.id})`,{eventData:Ee,result:ke}),ke}catch(Ae){throw it.error(`onComponentEvent "${ee.event}" failed: ${ee.handler} (Component: ${s.id})`,Ae),Ae}},he=ue.componentEvent.on(ee.event,ve);se.push(he),it.log(`onComponentEvent: Subscribed to "${ee.event}" (Component: ${s.id})`)}else it.warn(`onComponentEvent: G7Core.componentEvent is not available (Component: ${s.id})`)}return()=>{const ue=ia();ue?.isEnabled()&&ue.trackUnmount(s.id);for(const ee of se)try{ee()}catch(ve){it.error(`onComponentEvent: Failed to unsubscribe (Component: ${s.id})`,ve)}if(se.length>0&&it.log(`onComponentEvent: Unsubscribed ${se.length} event(s) (Component: ${s.id})`),s.lifecycle?.onUnmount&&s.lifecycle.onUnmount.length>0)for(const ee of s.lifecycle.onUnmount)try{const ve=c.createHandler(ee,ie,xe),he=new Event("unmount");ve(he),it.log(`Lifecycle onUnmount executed: ${ee.handler} (Component: ${s.id})`)}catch(ve){it.error(`Lifecycle onUnmount failed: ${ee.handler} (Component: ${s.id})`,ve)}}},[]);const Dn=N.useMemo(()=>{const F=It.dataKey,se=It.trackChanges,ue=It.debounce;return F?{dataKey:F,trackChanges:se??!1,debounce:ue,setState:be,state:de}:null},[It.dataKey,It.trackChanges,It.debounce,be,de]);N.useEffect(()=>{const F=T.dataKey||It.dataKey;if(!F)return;const se=ia();if(!se?.isEnabled())return;const ue=[],ee=he=>{if(he)for(const Ee of he){const Ae=Ee?.props?.name;if(Ae&&ue.push({name:Ae,type:Ee.name||Ee.type||"unknown"}),Ee?.children&&ee(Ee.children),Ee?.slots)for(const Ve of Object.values(Ee.slots))Array.isArray(Ve)&&ee(Ve)}};if(s.children&&ee(s.children),s.slots)for(const he of Object.values(s.slots))Array.isArray(he)&&ee(he);const ve=s.id||`form-${F}`;return se.trackForm(ve,F,ue),()=>{se.untrackForm(ve)}},[T,It.dataKey,s.id,s.children]);const nt=N.useRef(null),In=N.useRef(void 0);N.useEffect(()=>{const F=It?.name;if(!F||!Z.dataKey||!Z.setState||It?.autoBinding===!1)return;const se=`${Z.dataKey}.${F}`,ue=window.__g7AutoBindingPaths??new Map;return window.__g7AutoBindingPaths=ue,ue.set(se,(ue.get(se)??0)+1),()=>{const ee=ue.get(se)??0;ee<=1?ue.delete(se):ue.set(se,ee-1)}},[It?.name,It?.autoBinding,Z.dataKey,Z.setState]);const mn=N.useMemo(()=>{const{dataKey:F,trackChanges:se,debounce:ue,...ee}=It,ve=ee.name;if(!ve||!Z.dataKey||!Z.setState)return ee;if(ee.autoBinding===!1){const{autoBinding:Ge,...Ce}=ee;return Ce}const he=`${Z.dataKey}.${ve}`,Ee=TE(Z.state,he),Ae=Ee!==void 0?Ee:ee.value,ke=r.getMetadata(s.name)?.bindingType,Ne=typeof Ae=="boolean"&&(ke==="checked"||ke==="checkable"&&["checkbox","radio"].includes(ee?.type)),Re=Z.debounce,et=Ge=>{const Ce=Z.state||{},je=kE(Ce,he,Ge);if(Z.trackChanges&&(je.hasChanges=!0),window.__g7PendingLocalState=je,Z.setState(je),Z._isGlobal)return;const tt=window.G7Core,At={[he]:Ge};Z.trackChanges&&(At.hasChanges=!0),tt?.state?.setLocal?.(At,{render:!1})},He=(Ge,Ce)=>{Re&&Re>0?(nt.current&&clearTimeout(nt.current),nt.current=setTimeout(()=>{et(Ge),nt.current=null,Ce&&(Ce(),window.__g7PendingLocalState=null)},Re)):(et(Ge),Ce&&(Ce(),window.__g7PendingLocalState=null))};if(Ne)return{...ee,checked:Ae,onChange:Ce=>{const je=Ce.target.checked;et(je),ee.onChange&&ee.onChange(Ce)}};{const Ge=je=>{const tt=je?.target?.value!==void 0?je.target.value:je;Re&&Re>0&&(In.current=tt);const At=je?.target?{target:{value:tt,name:je.target.name,type:je.target.type,checked:je.target.checked},currentTarget:je.currentTarget?{value:tt,name:je.currentTarget.name}:void 0}:je;He(tt,()=>{ee.onChange&&ee.onChange(At)})};let Ce;return In.current!==void 0?nt.current!==null?Ce=In.current:String(Ae??"")===String(In.current)?(In.current=void 0,Ce=Ae??""):Ce=In.current:Ce=Ae??"",{...ee,value:Ce,onChange:Ge}}},[It,Z,Z.state,Z.debounce]),ca=N.useMemo(()=>{const F=ia();if(F?.isEnabled()&&F.trackRender(s.name),!_e)return T.iteration?Vr:null;if(T.sortable&&T.itemTemplate)return la;if(T.iteration)return Vr;if(T.type==="extension_point"){const{layout:ke,columns:Ne,gap:Re,className:et,...He}=T.props||{};let Ge=et||"";return ke==="grid"&&Ne?Ge=`${Ge} grid grid-cols-${Ne} gap-${Re||4}`.trim():ke==="flex"&&(Ge=`${Ge} flex flex-col gap-${Re||4}`.trim()),ft.jsx("div",{id:Fr,className:Ge||void 0,...He,children:Wn})}const se=r.getComponent(T.name);if(!se)return it.error(`컴포넌트를 찾을 수 없습니다: ${T.name} (ID: ${T.id})`,"componentDef:",JSON.stringify(T,null,2)),null;const ue=e._global?._remountKeys,ee={...mn,id:mn.id??Fr,...ue&&Object.keys(ue).length>0&&{__remountTrigger:JSON.stringify(ue)}};if(H?.listeners&&H.handle&&mn["data-drag-handle"]!==void 0&&(Object.assign(ee,H.listeners),ee.style={...ee.style,cursor:H.isDragging?"grabbing":"grab"}),S){const ke=T.id||`auto_${T.name||T.type||"unknown"}_${Math.random().toString(36).substring(2,8)}`,Ne=He=>{typeof He.preventDefault=="function"&&He.preventDefault(),v&&(He.stopPropagation(),v(ke,He))},Re={"data-editor-id":ke,"data-editor-name":T.name,"data-editor-type":T.type,onClick:Ne};L&&(Re["data-editor-path"]=L);const et=T.__editorSlotName??T.slot;typeof et=="string"&&(Re["data-editor-slot"]=et),_&&(Re.onMouseMove=He=>{He.stopPropagation(),_(ke,He)},Re.onMouseLeave=He=>{_(null,He)}),Object.assign(ee,Re),ee.editorAttrs=Re}const ve=T.type==="basic",he=T.type==="layout",Ae=ve||he?(()=>{const ke={};for(const[Ne,Re]of Object.entries(ee))Ne.startsWith("__")||Ne==="editorAttrs"&&ve||(ke[Ne]=Re);return ke})():ee;let Ve=ft.jsx(se,{...Ae,children:Wn});if(hn&&(Ve=ft.jsx(AE,{value:hn,children:Ve})),T.isolatedState){const ke=typeof T.isolatedState=="object"?T.isolatedState:{},Ne=e?._isolatedInit,Re=Ne?{...ke,...Ne}:ke;Ve=ft.jsx(ME,{initialState:Re,scopeId:T.isolatedScopeId,children:Ve})}return Ve},[_e,T.iteration,T.sortable,T.itemTemplate,T.type,T.name,T.id,T.props,T.isolatedState,T.isolatedScopeId,r,mn,Wn,Vr,la,H,Dn,S,v,_,x,A,L,e._global?._remountKeys]),lr=N.useMemo(()=>{const F=T.blur_until_loaded;if(!F||e?._global?.__isPreview)return!1;if(typeof F=="string"){const ee=ht(F);if(ee!==null)try{const ve={componentId:T.id,componentName:T.name,propName:"blur_until_loaded"};return!!i.evaluateExpression(ee,ie,ve)}catch(ve){return it.warn(`blur_until_loaded 표현식 평가 실패 (컴포넌트: ${T.id}):`,ve),!1}return!1}if(typeof F=="object"&&F!==null){if(!F.enabled)return!1;if(F.data_sources)return(Array.isArray(F.data_sources)?F.data_sources:[F.data_sources]).some(Ee=>e[Ee]===void 0);if(fe)return!0;const ee=["route","query","_global","_local","_dataSourceErrors"];return Object.keys(e).filter(he=>!ee.includes(he)&&!he.startsWith("_")).some(he=>e[he]===void 0)}if(fe)return!0;const se=["route","query","_global","_local","_dataSourceErrors"];return Object.keys(e).filter(ee=>!se.includes(ee)&&!ee.startsWith("_")).some(ee=>e[ee]===void 0)},[T.blur_until_loaded,T.id,fe,e,ie,i,ht]);if(lr){const F=T.blur_until_loaded;if(typeof F=="object"&&F?.data_sources){const ue=(Array.isArray(F.data_sources)?F.data_sources:[F.data_sources]).reduce((ve,he)=>(ve[he]=e[he]===void 0?"UNDEFINED":"LOADED",ve),{}),ee=Object.keys(e).filter(ve=>!ve.startsWith("_"));it.log(`[BLUR APPLIED] Component: ${T.id}, data_sources status:`,ue,"Available keys:",ee)}else it.log(`[BLUR APPLIED] Component: ${T.id}, blur_until_loaded:`,F)}const sn=N.useMemo(()=>{if(!T.blur_until_loaded)return{wrapperClasses:"",innerClasses:""};const F=rn?.className||"";if(!F)return{wrapperClasses:"",innerClasses:""};const se=[/^(sm:|md:|lg:|xl:|2xl:)?(col-span-|row-span-|col-start-|col-end-|row-start-|row-end-)/,/^(sm:|md:|lg:|xl:|2xl:)?(self-|place-self-|order-)/,/^(sm:|md:|lg:|xl:|2xl:)?(flex-shrink|flex-grow|flex-\d|basis-)/],ue=F.split(/\s+/).filter(Boolean),ee=[],ve=[];for(const he of ue)se.some(Ae=>Ae.test(he))?ee.push(he):ve.push(he);return{wrapperClasses:ee.join(" "),innerClasses:ve.join(" ")}},[T.blur_until_loaded,rn?.className]),_n=window.__slotContextValue;return Te&&_n?.isEnabled?null:ft.jsx(LA,{componentId:s.id,componentName:s.name,children:T.blur_until_loaded?ft.jsx("div",{className:[sn.wrapperClasses,lr?"opacity-50 blur-sm transition-all duration-300 pointer-events-none":void 0].filter(Boolean).join(" ")||void 0,children:ca}):ca})});Br.displayName="DynamicRenderer",typeof window<"u"&&(window.__DynamicRenderer=Br);function $A(s){const e={};try{const r=new URL(s,typeof window<"u"?window.location.origin:"http://localhost").searchParams,i=new Set;for(const l of r.keys()){if(i.has(l))continue;i.add(l);const c=r.getAll(l);c.length>1||l.endsWith("[]")?e[l]=c:e[l]=c[0]}}catch{}return e}function MA(s){try{return new URL(s,typeof window<"u"?window.location.origin:"http://localhost").pathname}catch{return s.split("?")[0]}}const Ti=class Ti{constructor(){M(this,"config",{enabled:!1,maxHistorySize:100,logLevel:"info",serverEndpoint:"/_boost/g7-debug/dump-state",autoCapture:!0});M(this,"stateHistory",[]);M(this,"snapshotIdCounter",0);M(this,"stateWatchers",new Map);M(this,"currentLocalState",{});M(this,"currentComputedState",{});M(this,"currentParentContext");M(this,"actionHistory",[]);M(this,"actionWatchers",new Set);M(this,"cacheStats",{hits:0,misses:0,entries:0});M(this,"cacheDecisions",[]);M(this,"cacheDecisionIdCounter",0);M(this,"maxCacheDecisions",200);M(this,"currentRenderCycleId",null);M(this,"isInActionExecution",!1);M(this,"isInIteration",!1);M(this,"mountedComponents",new Map);M(this,"eventListeners",new Map);M(this,"mountWatchers",new Set);M(this,"unmountWatchers",new Set);M(this,"renderCounts",new Map);M(this,"bindingEvalCount",0);M(this,"profilingData",[]);M(this,"isProfiling",!1);M(this,"profilingStartTime",0);M(this,"activeRequests",new Map);M(this,"requestHistory",[]);M(this,"pendingDataSources",new Set);M(this,"requestWatchers",new Set);M(this,"wsConnections",new Map);M(this,"wsMessageHistory",[]);M(this,"wsMessageWatchers",new Set);M(this,"ifConditions",new Map);M(this,"iterations",new Map);M(this,"conditionWatchers",new Set);M(this,"forms",new Map);M(this,"formWatchers",new Set);M(this,"expressionHistory",[]);M(this,"expressionWatchers",new Set);M(this,"expressionIdCounter",0);M(this,"dataSources",new Map);M(this,"dataPathTransforms",[]);M(this,"maxDataPathTransforms",100);M(this,"nestedContexts",[]);M(this,"nestedContextIdCounter",0);M(this,"maxNestedContexts",100);M(this,"formBindingIssues",[]);M(this,"formBindingValidations",[]);M(this,"formBindingIssueIdCounter",0);M(this,"maxFormBindingIssues",100);M(this,"computedProperties",new Map);M(this,"computedRecalcLogs",[]);M(this,"computedRecalcIdCounter",0);M(this,"maxComputedRecalcLogs",100);M(this,"handlers",new Map);M(this,"componentEventSubscriptions",new Map);M(this,"componentEventEmitHistory",[]);M(this,"componentEventIdCounter",0);M(this,"maxComponentEventHistory",100);M(this,"stateRenderingLogs",[]);M(this,"currentStateChangeContext",null);M(this,"stateRenderingIdCounter",0);M(this,"componentRenderCounts",new Map);M(this,"stateToComponentMap",new Map);M(this,"maxStateRenderingLogs",100);M(this,"componentStateSources",new Map);M(this,"contextFlowNodes",new Map);M(this,"dynamicStates",new Map);M(this,"styleIssues",[]);M(this,"componentStyles",new Map);M(this,"authEvents",[]);M(this,"authHeaderHistory",[]);M(this,"authEventIdCounter",0);M(this,"maxAuthEventHistory",50);M(this,"logHistory",[]);M(this,"logIdCounter",0);M(this,"maxLogHistory",500);M(this,"currentLayout",null);M(this,"layoutHistory",[]);M(this,"layoutIdCounter",0);M(this,"layoutStats",{totalLoads:0,cacheHits:0,apiLoads:0});M(this,"maxLayoutHistory",50);M(this,"executionDetails",new Map);M(this,"stateChangeHistory",[]);M(this,"dataSourceChangeHistory",[]);M(this,"changeAlerts",[]);M(this,"changeExpectations",new Map);M(this,"executionIdCounter",0);M(this,"stateChangeIdCounter",0);M(this,"alertIdCounter",0);M(this,"maxExecutionDetails",100);M(this,"maxStateChangeHistory",200);M(this,"maxChangeAlerts",100);M(this,"sequenceExecutions",[]);M(this,"sequenceExecutionStack",[]);M(this,"sequenceIdCounter",0);M(this,"maxSequenceExecutions",50);M(this,"staleClosureWarnings",[]);M(this,"staleClosureIdCounter",0);M(this,"maxStaleClosureWarnings",100);M(this,"stateCaptureRegistry",new Map);M(this,"modalStates",new Map);M(this,"modalStateIssues",[]);M(this,"modalStateRelations",[]);M(this,"modalStateChangeLogs",[]);M(this,"modalStateIssueIdCounter",0);M(this,"modalStateChangeLogIdCounter",0);M(this,"maxModalStateIssues",100);M(this,"maxModalStateChangeLogs",200);M(this,"namedActionDefinitions",{});M(this,"namedActionRefLogs",[]);M(this,"namedActionRefIdCounter",0);M(this,"maxNamedActionRefLogs",200);M(this,"debounceActionHistory",[]);M(this,"dataSourceUpdateHistory",[]);M(this,"debounceActionIdCounter",0);M(this,"dataSourceUpdateIdCounter",0)}static getInstance(){return Ti.instance||(Ti.instance=new Ti),Ti.instance}initialize(){if(this.config.enabled=this.checkDebugMode(),!this.config.enabled){console.log("[G7DevTools] 비활성화됨 (환경설정 > 고급 설정 > 디버그 모드를 켜세요)");return}console.log("[G7DevTools] 활성화됨"),this.setupGlobalErrorHandler()}checkDebugMode(){try{if(window.G7Config?.debug===!0)return!0;const r=window.G7Core?.state?.get?.();return r?.settings?.advanced?.debug_mode===!0||r?._global?.settings?.advanced?.debug_mode===!0}catch{return!1}}isEnabled(){return this.config.enabled}setupGlobalErrorHandler(){window.addEventListener("error",e=>{this.config.enabled&&this.logAction({id:this.generateId(),type:"globalError",startTime:Date.now(),status:"error",error:{name:"Error",message:e.message,stack:e.error?.stack}})}),window.addEventListener("unhandledrejection",e=>{this.config.enabled&&this.logAction({id:this.generateId(),type:"unhandledRejection",startTime:Date.now(),status:"error",error:{name:"UnhandledRejection",message:String(e.reason)}})})}captureStateSnapshot(e){if(!this.config.enabled)return;const n={id:++this.snapshotIdCounter,timestamp:Date.now(),source:e.source,prev:this.sanitizeObject(e.prev),next:this.sanitizeObject(e.next),diff:e.diff};this.stateHistory.push(n),this.stateHistory.length>this.config.maxHistorySize&&this.stateHistory.shift(),this.notifyStateWatchers(n)}getState(){try{const e=window.G7Core,n=e?.state?.get?.()||{},r={};if(e?._isolatedStates&&typeof e._isolatedStates=="object")for(const[i,l]of Object.entries(e._isolatedStates))r[i]=this.sanitizeObject(l);return{_global:n._global||n,_local:this.currentLocalState,_computed:this.currentComputedState,_isolated:Object.keys(r).length>0?r:void 0,$parent:this.currentParentContext}}catch{return{_global:{},_local:this.currentLocalState,_computed:this.currentComputedState}}}updateLocalState(e){this.config.enabled&&(this.currentLocalState=this.sanitizeObject(e))}updateComputedState(e){this.config.enabled&&(this.currentComputedState=this.sanitizeObject(e))}updateParentContext(e){this.config.enabled&&(this.currentParentContext=e?this.sanitizeObject(e):void 0)}getStateHistory(){return[...this.stateHistory]}getDualStorageMismatch(){const e=this.currentLocalState||{};let n={};try{n=(window.G7Core?.state?.get?.()||{})._local||{}}catch{n={}}const r=this.findMismatchedLeafPaths(e,n);return{hasMismatch:r.length>0,mismatchedPaths:r,storageA:e,storageB:n}}findMismatchedLeafPaths(e,n,r=""){const i=[],l=new Set([...Object.keys(e||{}),...Object.keys(n||{})]);for(const c of l){const d=r?`${r}.${c}`:c,f=e?.[c],h=n?.[c],m=f&&typeof f=="object"&&!Array.isArray(f),y=h&&typeof h=="object"&&!Array.isArray(h);if(m&&y)i.push(...this.findMismatchedLeafPaths(f,h,d));else{const S=f===void 0?"__undefined__":JSON.stringify(f),v=h===void 0?"__undefined__":JSON.stringify(h);S!==v&&i.push(d)}}return i}watchState(e,n){return this.stateWatchers.has(e)||this.stateWatchers.set(e,new Set),this.stateWatchers.get(e).add(n),()=>{this.stateWatchers.get(e)?.delete(n)}}notifyStateWatchers(e){if(this.stateWatchers.get("*")?.forEach(n=>{try{n(e.next,e.prev,"*")}catch(r){console.error("[G7DevTools] State watcher error:",r)}}),e.diff)for(const n of e.diff.changed)this.stateWatchers.get(n.path)?.forEach(r=>{try{r(n.newValue,n.oldValue,n.path)}catch(i){console.error("[G7DevTools] State watcher error:",i)}})}diffSnapshots(e,n){const r=this.stateHistory.find(l=>l.id===e),i=this.stateHistory.find(l=>l.id===n);return!r||!i?null:this.calculateDiff(r.next,i.next)}calculateDiff(e,n,r=""){const i={added:[],removed:[],changed:[]},l=new Set(Object.keys(e)),c=new Set(Object.keys(n));for(const d of c){const f=r?`${r}.${d}`:d;l.has(d)?JSON.stringify(e[d])!==JSON.stringify(n[d])&&i.changed.push({path:f,oldValue:e[d],newValue:n[d]}):i.added.push(f)}for(const d of l){const f=r?`${r}.${d}`:d;c.has(d)||i.removed.push(f)}return i}logAction(e){if(!this.config.enabled)return;const n=this.actionHistory.findIndex(r=>r.id===e.id);n>=0?this.actionHistory[n]={...this.actionHistory[n],...e}:(this.actionHistory.push(e),this.actionHistory.length>this.config.maxHistorySize&&this.actionHistory.shift()),this.isProfiling&&this.profilingData.push({type:"action",action:e.type,timestamp:performance.now(),duration:e.duration}),this.notifyActionWatchers(e)}getActionHistory(){return[...this.actionHistory]}watchActions(e){return this.actionWatchers.add(e),()=>{this.actionWatchers.delete(e)}}notifyActionWatchers(e){this.actionWatchers.forEach(n=>{try{n(e)}catch(r){console.error("[G7DevTools] Action watcher error:",r)}})}getActionMetrics(){const e=this.actionHistory.filter(l=>l.status==="success"),n=this.actionHistory.filter(l=>l.status==="error"),r={};for(const l of this.actionHistory)r[l.type]=(r[l.type]||0)+1;const i=e.reduce((l,c)=>l+(c.duration||0),0);return{totalActions:this.actionHistory.length,successCount:e.length,errorCount:n.length,averageDuration:e.length>0?i/e.length:0,actionsByType:r}}recordCacheHit(){this.config.enabled&&this.cacheStats.hits++}recordCacheMiss(){this.config.enabled&&this.cacheStats.misses++}updateCacheEntries(e){this.config.enabled&&(this.cacheStats.entries=e)}getCacheStats(){const e=this.cacheStats.hits+this.cacheStats.misses;return{...this.cacheStats,hitRate:e>0?this.cacheStats.hits/e:0}}resetCacheStats(){this.cacheStats={hits:0,misses:0,entries:0}}trackCacheDecision(e){if(!this.config.enabled)return;const n={id:`cache-${++this.cacheDecisionIdCounter}`,timestamp:Date.now(),expression:e.expression,decision:e.decision,reason:e.reason,context:{isInIteration:this.isInIteration,isInAction:this.isInActionExecution,renderCycleId:this.currentRenderCycleId||void 0,componentId:e.componentId,skipCacheOption:e.skipCacheOption},cachedValue:e.cachedValue!==void 0?this.safeClone(e.cachedValue):void 0,freshValue:e.freshValue!==void 0?this.safeClone(e.freshValue):void 0,valueMatch:e.cachedValue!==void 0&&e.freshValue!==void 0?JSON.stringify(e.cachedValue)===JSON.stringify(e.freshValue):void 0,duration:e.duration};this.cacheDecisions.push(n),this.cacheDecisions.length>this.maxCacheDecisions&&this.cacheDecisions.shift(),e.decision==="cache_hit"?this.cacheStats.hits++:(e.decision==="cache_miss"||e.decision==="skip_cache")&&this.cacheStats.misses++}startRenderCycle(e){return this.currentRenderCycleId=`render-${Date.now()}-${e||"root"}`,this.currentRenderCycleId}endRenderCycle(){this.currentRenderCycleId=null}startActionContext(){this.isInActionExecution=!0}endActionContext(){this.isInActionExecution=!1}startIterationContext(){this.isInIteration=!0}endIterationContext(){this.isInIteration=!1}getCacheDecisionTrackingInfo(){const e=this.getCacheDecisionStats();return{decisions:[...this.cacheDecisions],stats:e,timestamp:Date.now()}}getCacheDecisionStats(){const e=this.cacheDecisions;let n=0,r=0,i=0,l=0;const c={},d={};for(const h of e)h.decision==="cache_hit"?n++:h.decision==="cache_miss"?r++:h.decision==="skip_cache"?i++:h.decision==="invalidate"&&l++,c[h.reason]=(c[h.reason]||0)+1,h.context.componentId&&(d[h.context.componentId]=(d[h.context.componentId]||0)+1);const f=n+r+i;return{totalDecisions:e.length,cacheHits:n,cacheMisses:r,skipCacheCount:i,invalidateCount:l,byReason:c,byComponent:d,avgHitRate:f>0?n/f:0}}getRecentCacheDecisions(e=20,n){let r=[...this.cacheDecisions];return n&&(r=r.filter(i=>i.decision===n)),r.slice(-e)}clearCacheDecisionData(){this.cacheDecisions=[],this.cacheDecisionIdCounter=0}summarizePropsForLifecycle(e){if(!e||typeof e!="object")return e;const n={},r=["children","ref","key"];for(const[i,l]of Object.entries(e))if(!r.includes(i))if(l==null)n[i]=l;else if(Array.isArray(l))n[i]=`[Array(${l.length})]`;else if(typeof l=="object"){const c=Object.keys(l);c.length<=3?n[i]=`{${c.join(", ")}}`:n[i]=`{${c.slice(0,3).join(", ")}, ... +${c.length-3}}`}else typeof l=="string"&&l.length>50?n[i]=l.substring(0,50)+"...":typeof l=="function"?n[i]="[Function]":n[i]=l;return n}trackMount(e,n){if(!this.config.enabled)return;const r=this.summarizePropsForLifecycle(n.props),i={...n,props:r,id:e,mountTime:Date.now()};this.mountedComponents.set(e,i),this.mountWatchers.forEach(l=>{try{l({componentId:e,componentName:n.name,timestamp:i.mountTime})}catch(c){console.error("[G7DevTools] Mount watcher error:",c)}})}trackUnmount(e){if(!this.config.enabled)return;const n=this.mountedComponents.get(e),r=this.eventListeners.get(e)||[];r.length>0&&console.warn(`[G7DevTools] 컴포넌트 ${e} 언마운트 시 ${r.length}개 리스너 미정리`),n&&this.unmountWatchers.forEach(i=>{try{i({componentId:e,componentName:n.name,timestamp:Date.now(),orphanedListeners:r.length})}catch(l){console.error("[G7DevTools] Unmount watcher error:",l)}}),this.mountedComponents.delete(e)}trackListener(e,n,r){if(!this.config.enabled)return;const i=this.eventListeners.get(e)||[];i.push({type:n,target:r,addedAt:Date.now()}),this.eventListeners.set(e,i)}removeListener(e,n){if(!this.config.enabled)return;const r=this.eventListeners.get(e)||[],i=r.findIndex(l=>l.type===n);i>=0&&r.splice(i,1)}getMountedComponents(){return Array.from(this.mountedComponents.values())}getOrphanedListeners(){const e=[];for(const[n,r]of this.eventListeners)this.mountedComponents.has(n)||e.push(...r.map(i=>({...i,componentId:n})));return e}watchMount(e){return this.mountWatchers.add(e),()=>{this.mountWatchers.delete(e)}}watchUnmount(e){return this.unmountWatchers.add(e),()=>{this.unmountWatchers.delete(e)}}trackRender(e){if(!this.config.enabled)return;const n=this.renderCounts.get(e)||0;this.renderCounts.set(e,n+1),this.isProfiling&&this.profilingData.push({type:"render",component:e,timestamp:performance.now()})}trackBindingEval(e){this.config.enabled&&(this.bindingEvalCount++,this.isProfiling&&e&&this.profilingData.push({type:"binding",expression:e,timestamp:performance.now()}))}getRenderCount(){return new Map(this.renderCounts)}getBindingEvalCount(){return this.bindingEvalCount}getMemoryWarnings(){const e=[];try{const i=this.getState(),l=JSON.stringify(i).length;l>1e6&&e.push({type:"large-state",message:`상태 크기가 ${(l/1024/1024).toFixed(2)}MB입니다`,suggestion:"불필요한 데이터 정리 필요",severity:l>5e6?"error":"warning"})}catch{}this.stateHistory.length>this.config.maxHistorySize*.8&&e.push({type:"large-history",message:`상태 이력이 ${this.stateHistory.length}개입니다`,suggestion:"maxHistory 설정 조정 필요",severity:"warning"});const n=this.getOrphanedListeners().length;n>0&&e.push({type:"orphaned-listeners",message:`${n}개의 정리되지 않은 이벤트 리스너`,suggestion:"useEffect cleanup 또는 removeEventListener 확인",severity:n>10?"error":"warning"});const r=Array.from(this.renderCounts.entries()).filter(([,i])=>i>50);return r.length>0&&e.push({type:"excessive-renders",message:`${r.length}개 컴포넌트가 50회 이상 렌더링`,suggestion:"React.memo, useMemo, useCallback 사용 고려",severity:"warning"}),e}startProfiling(){this.config.enabled&&(this.isProfiling=!0,this.profilingData=[],this.profilingStartTime=performance.now(),console.log("[G7DevTools] 프로파일링 시작"))}stopProfiling(){this.isProfiling=!1;const e=performance.now()-this.profilingStartTime,n=this.analyzeProfile(e);return console.log("[G7DevTools] 프로파일링 완료",n),n}analyzeProfile(e){const n=this.profilingData.filter(h=>h.type==="render"),r=this.profilingData.filter(h=>h.type==="binding"),i=this.profilingData.filter(h=>h.type==="action"),l={};for(const h of n)h.component&&(l[h.component]||(l[h.component]={count:0,durations:[]}),l[h.component].count++,h.duration&&l[h.component].durations.push(h.duration));const c=Object.entries(l).map(([h,m])=>({name:h,renderCount:m.count,avgDuration:m.durations.length>0?m.durations.reduce((y,S)=>y+S,0)/m.durations.length:0})).sort((h,m)=>m.renderCount-h.renderCount).slice(0,10),d={};for(const h of r)h.expression&&(d[h.expression]=(d[h.expression]||0)+1);const f=Object.entries(d).sort(([,h],[,m])=>m-h).slice(0,10).map(([h])=>h);return{duration:e,entries:this.profilingData,summary:{totalRenders:n.length,totalBindings:r.length,totalActions:i.length,slowestComponents:c,hotPaths:f}}}resetPerformanceStats(){this.renderCounts.clear(),this.bindingEvalCount=0,this.profilingData=[]}trackRequest(e,n,r){if(!this.config.enabled)return"";const i=this.generateId(),l=MA(e),c=$A(e);return this.activeRequests.set(i,{id:i,url:l,fullUrl:e,queryParams:c,method:n,startTime:Date.now(),status:"pending",requestBody:r?.requestBody?this.sanitizeObject(r.requestBody):void 0,dataSourceId:r?.dataSourceId}),this.isProfiling&&this.profilingData.push({type:"network",timestamp:performance.now()}),i}completeRequest(e,n,r){if(!this.config.enabled)return;const i=this.activeRequests.get(e);if(!i)return;const l={...i,status:n>=200&&n<300?"success":"error",statusCode:n,duration:Date.now()-i.startTime,endTime:Date.now(),response:this.sanitizeObject(r)};this.requestHistory.push(l),this.activeRequests.delete(e),this.requestHistory.length>this.config.maxHistorySize&&this.requestHistory.shift(),this.notifyRequestWatchers(l)}failRequest(e,n){if(!this.config.enabled)return;const r=this.activeRequests.get(e);if(!r)return;const i={...r,status:"error",error:n,duration:Date.now()-r.startTime,endTime:Date.now()};this.requestHistory.push(i),this.activeRequests.delete(e),this.notifyRequestWatchers(i)}trackDataSource(e){this.config.enabled&&this.pendingDataSources.add(e)}completeDataSource(e){this.config.enabled&&this.pendingDataSources.delete(e)}getActiveRequests(){return Array.from(this.activeRequests.values())}getRequestHistory(){return[...this.requestHistory]}getPendingDataSources(){return Array.from(this.pendingDataSources)}watchRequest(e){return this.requestWatchers.add(e),()=>{this.requestWatchers.delete(e)}}notifyRequestWatchers(e){this.requestWatchers.forEach(n=>{try{n(e)}catch(r){console.error("[G7DevTools] Request watcher error:",r)}})}trackWebSocketConnection(e,n,r){this.config.enabled&&this.wsConnections.set(e,{id:e,url:n,state:r,connectedAt:r==="open"?Date.now():void 0})}trackWebSocketMessage(e,n,r,i){if(!this.config.enabled)return;const l={id:this.generateId(),connectionId:e,direction:n,type:r,payload:this.sanitizeObject(i),timestamp:Date.now(),sequence:this.wsMessageHistory.length};this.wsMessageHistory.push(l),this.wsMessageHistory.length>this.config.maxHistorySize&&this.wsMessageHistory.shift(),this.notifyWebSocketWatchers(l)}getWebSocketConnections(){return Array.from(this.wsConnections.values())}getWebSocketMessageHistory(){return[...this.wsMessageHistory]}getWebSocketConnectionState(){const e=Array.from(this.wsConnections.values());return e.some(n=>n.state==="open")?"connected":e.some(n=>n.state==="connecting")?"reconnecting":"disconnected"}watchWebSocketMessage(e){return this.wsMessageWatchers.add(e),()=>{this.wsMessageWatchers.delete(e)}}notifyWebSocketWatchers(e){this.wsMessageWatchers.forEach(n=>{try{n(e)}catch(r){console.error("[G7DevTools] WebSocket watcher error:",r)}})}trackIfCondition(e,n,r){if(!this.config.enabled)return;const i=this.ifConditions.get(e),l=i?.evaluatedValue;this.ifConditions.set(e,{id:e,expression:n,evaluatedValue:r,evaluationCount:(i?.evaluationCount||0)+1,lastEvaluated:Date.now()}),i&&l!==r&&this.notifyConditionWatchers({id:e,expression:n,oldValue:l,newValue:r,timestamp:Date.now()})}trackIteration(e,n){this.config.enabled&&this.iterations.set(e,{id:e,...n,lastRendered:Date.now()})}getIfConditions(){return Array.from(this.ifConditions.values())}getIterations(){return Array.from(this.iterations.values())}getScopeChain(e){const n=[],r=this.getState();return n.push({name:"_global",value:r._global,source:"global"}),n.push({name:"_local",value:r._local,source:"local"}),n.push({name:"_computed",value:r._computed,source:"computed"}),n}watchConditionChange(e){return this.conditionWatchers.add(e),()=>{this.conditionWatchers.delete(e)}}notifyConditionWatchers(e){this.conditionWatchers.forEach(n=>{try{n(e)}catch(r){console.error("[G7DevTools] Condition watcher error:",r)}})}trackForm(e,n,r){this.config.enabled&&this.forms.set(e,{id:e,dataKey:n,inputs:r,trackedAt:Date.now()})}trackFormChange(e,n,r){if(!this.config.enabled)return;const i={formId:e,inputName:n,value:r,timestamp:Date.now()};this.notifyFormWatchers(i)}untrackForm(e){this.forms.delete(e)}getForms(){return Array.from(this.forms.values())}getFormState(e){const n=this.getState();return this.getNestedValue(n,e)||{}}getBindingPath(e,n){return`${e}.${n}`}watchFormChange(e){return this.formWatchers.add(e),()=>{this.formWatchers.delete(e)}}notifyFormWatchers(e){this.formWatchers.forEach(n=>{try{n(e)}catch(r){console.error("[G7DevTools] Form watcher error:",r)}})}trackFormBindingIssue(e,n,r){if(!this.config.enabled)return;const i={id:`form-issue-${++this.formBindingIssueIdCounter}`,timestamp:Date.now(),type:e,severity:n,formId:r.formId,formDataKey:r.formDataKey,inputInfo:r.inputInfo,contextInfo:r.contextInfo,description:r.description,suggestion:r.suggestion,docLink:r.docLink};this.formBindingIssues.push(i),this.formBindingIssues.length>this.maxFormBindingIssues&&this.formBindingIssues.shift()}validateFormBinding(e,n,r,i){const l=r.map(f=>{const h=[];let m=!0;return f.name||(h.push("Input에 name 속성이 없습니다"),m=!1,this.trackFormBindingIssue("missing-input-name","error",{formId:e,formDataKey:n,inputInfo:{name:f.name,type:f.type},description:"Input에 name 속성이 없어 자동 바인딩이 동작하지 않습니다",suggestion:"Input에 name 속성을 추가하세요",docLink:"troubleshooting-components-form.md"})),n||(h.push("Form에 dataKey가 없습니다"),m=!1),{inputName:f.name||"(unnamed)",inputType:f.type,bindingPath:n&&f.name?`${n}.${f.name}`:"-",isValid:m,currentValue:f.value,issues:h}});if(n||this.trackFormBindingIssue("missing-datakey","error",{formId:e,description:"Form에 dataKey가 설정되지 않아 자동 바인딩이 동작하지 않습니다",suggestion:"Form 컴포넌트에 dataKey props를 설정하세요",docLink:"troubleshooting-components-form.md"}),i.isContextBroken){const f=i.breakReason?.includes("sortable")?"sortable-context-break":i.breakReason?.includes("modal")?"modal-context-isolation":"context-not-propagated";this.trackFormBindingIssue(f,"warning",{formId:e,formDataKey:n,contextInfo:{hasParentFormContext:i.hasParentContext,parentFormContextProp:i.parentContextProp,isInsideSortable:i.breakReason?.includes("sortable")||!1,isInsideModal:i.breakReason?.includes("modal")||!1,depth:0},description:i.breakReason||"Form 컨텍스트가 제대로 전파되지 않았습니다",suggestion:"parentFormContextProp={undefined}를 확인하거나 중첩 구조를 검토하세요",docLink:"troubleshooting-components-form.md"})}const c={formId:e,dataKey:n,timestamp:Date.now(),contextPropagation:i,inputBindings:l,isValid:l.every(f=>f.isValid)&&!!n&&!i.isContextBroken,issueCount:l.filter(f=>!f.isValid).length+(n?0:1)+(i.isContextBroken?1:0)},d=this.formBindingValidations.findIndex(f=>f.formId===e);return d>=0?this.formBindingValidations[d]=c:this.formBindingValidations.push(c),c}getFormBindingValidationTrackingInfo(){const e=this.getFormBindingValidationStats();return{issues:[...this.formBindingIssues],validations:[...this.formBindingValidations],stats:e,timestamp:Date.now()}}getFormBindingValidationStats(){const e={"missing-datakey":0,"missing-input-name":0,"context-not-propagated":0,"sortable-context-break":0,"modal-context-isolation":0,"duplicate-input-name":0,"value-type-mismatch":0,"binding-path-invalid":0},n={info:0,warning:0,error:0};for(const i of this.formBindingIssues)e[i.type]++,n[i.severity]++;const r=Object.entries(e).filter(([,i])=>i>0).sort((i,l)=>l[1]-i[1]).slice(0,5).map(([i,l])=>({type:i,count:l,description:this.getIssueTypeDescription(i)}));return{totalFormsValidated:this.formBindingValidations.length,validForms:this.formBindingValidations.filter(i=>i.isValid).length,formsWithIssues:this.formBindingValidations.filter(i=>!i.isValid).length,totalIssues:this.formBindingIssues.length,byIssueType:e,bySeverity:n,topIssues:r}}getIssueTypeDescription(e){return{"missing-datakey":"Form에 dataKey 누락","missing-input-name":"Input에 name 속성 누락","context-not-propagated":"Form 컨텍스트 전파 실패","sortable-context-break":"Sortable 컨테이너에서 컨텍스트 단절","modal-context-isolation":"모달에서 부모 Form 컨텍스트 격리","duplicate-input-name":"동일 Form 내 중복 Input name","value-type-mismatch":"값 타입과 Input 타입 불일치","binding-path-invalid":"바인딩 경로 유효하지 않음"}[e]||e}clearFormBindingIssues(){this.formBindingIssues=[],this.formBindingValidations=[],this.formBindingIssueIdCounter=0}trackComputedProperty(e,n,r,i,l,c,d){if(!this.config.enabled)return;const f=`computed-${e}-${c||"global"}`,h={id:f,name:e,expression:n,componentId:c,dependencies:r,currentValue:this.safeClone(i),lastComputedAt:Date.now(),computationTime:l,error:d};this.computedProperties.set(f,h)}trackComputedRecalc(e,n,r,i,l,c,d){if(!this.config.enabled)return;const f=`computed-${e}-${d||"global"}`,h=JSON.stringify(r)!==JSON.stringify(i),m={id:`recalc-${++this.computedRecalcIdCounter}`,computedId:f,computedName:e,timestamp:Date.now(),trigger:n,triggeredBy:c,previousValue:this.safeClone(r),newValue:this.safeClone(i),valueChanged:h,computationTime:l,cascadeCount:0};this.computedRecalcLogs.push(m),this.computedRecalcLogs.length>this.maxComputedRecalcLogs&&this.computedRecalcLogs.shift();const y=this.computedProperties.get(f);y&&(y.currentValue=this.safeClone(i),y.lastComputedAt=Date.now(),y.computationTime=l)}analyzeComputedDependencyChain(e,n){const r=new Set,i=[];let l=!1,c,d=0;const f=(m,y)=>{if(d=Math.max(d,y),r.has(m))return l=!0,c=[...i,m],{name:m,type:"computed",children:[],depth:y};r.add(m),i.push(m);const S=this.computedProperties.get(`computed-${m}-${n||"global"}`),v=[];if(S)for(const _ of S.dependencies)_.type==="computed"?v.push(f(_.path,y+1)):v.push({name:_.path,type:_.type,children:[],depth:y+1});return i.pop(),r.delete(m),{name:m,type:"computed",children:v,depth:y}},h=f(e,0);return{root:e,tree:h,hasCycle:l,cyclePath:c,maxDepth:d}}getComputedDependencyTrackingInfo(){const e=Array.from(this.computedProperties.values()),n=this.getComputedDependencyStats(),r=[];for(const i of e){const l=this.analyzeComputedDependencyChain(i.name,i.componentId);r.push(l)}return{properties:e,recalcLogs:[...this.computedRecalcLogs],dependencyChains:r,stats:n,timestamp:Date.now()}}getComputedDependencyStats(){const e={"state-change":0,"datasource-update":0,"dependency-change":0,manual:0,initial:0},n={},r={};let i=0,l=0;for(const h of this.computedRecalcLogs)e[h.trigger]++,h.valueChanged||l++,n[h.computedName]=(n[h.computedName]||0)+1,r[h.computedName]||(r[h.computedName]=[]),r[h.computedName].push(h.computationTime),i+=h.computationTime;const c=Object.entries(n).sort((h,m)=>m[1]-h[1]).slice(0,5).map(([h,m])=>({name:h,count:m})),d=Object.entries(r).map(([h,m])=>({name:h,avgTime:m.reduce((y,S)=>y+S,0)/m.length})).sort((h,m)=>m.avgTime-h.avgTime).slice(0,5);let f=0;for(const h of this.computedProperties.values())this.analyzeComputedDependencyChain(h.name,h.componentId).hasCycle&&f++;return{totalComputed:this.computedProperties.size,totalRecalculations:this.computedRecalcLogs.length,unnecessaryRecalculations:l,avgComputationTime:this.computedRecalcLogs.length>0?i/this.computedRecalcLogs.length:0,topRecalculated:c,slowestComputed:d,cycleDetectionCount:f,byTrigger:e}}clearComputedTracking(){this.computedProperties.clear(),this.computedRecalcLogs=[],this.computedRecalcIdCounter=0}trackModalOpen(e){if(!this.config.enabled)return;const n={modalId:e.modalId,modalName:e.modalName,openedAt:Date.now(),closedAt:null,scopeType:e.scopeType||"isolated",parentModalId:e.parentModalId,componentId:e.componentId,initialState:e.initialState?{...e.initialState}:{},currentState:e.initialState?{...e.initialState}:{},stateChangeCount:0,isolatedStateKeys:e.isolatedStateKeys||[],sharedStateKeys:e.sharedStateKeys||[]};this.modalStates.set(e.modalId,n),this.validateModalDefinitionExists(e.modalId,e.modalName),e.parentModalId&&(this.modalStateRelations.find(i=>i.parentModalId===e.parentModalId&&i.childModalId===e.modalId)||this.modalStateRelations.push({parentModalId:e.parentModalId,childModalId:e.modalId,sharedKeys:e.sharedStateKeys||[],isolatedKeys:e.isolatedStateKeys||[],relationType:"parent-child"}))}trackModalClose(e,n){if(!this.config.enabled)return;const r=this.modalStates.get(e);r&&(r.closedAt=Date.now(),n&&(r.currentState={...n}),this.detectStateLeakage(r))}validateModalDefinitionExists(e,n){const r=this.currentLayout;if(!r?.layoutJson)return;const i=r.layoutJson.modals;if(!i){this.recordModalStateIssue({type:"missing-definition",modalId:e,modalName:n,severity:"error",description:`모달 "${e}"이(가) modalStack에 추가되었으나, 현재 레이아웃에 modals 섹션이 없습니다. 레이아웃 경로: ${r.layoutPath}`,affectedStateKeys:[],expectedValue:`modals 섹션에 id="${e}" 정의 존재`,actualValue:"modals 섹션 없음"});return}const l=Array.isArray(i)?i:Object.values(i);l.some(d=>d?.id===e||d?.props?.id===e)||this.recordModalStateIssue({type:"missing-definition",modalId:e,modalName:n,severity:"error",description:`모달 "${e}"이(가) modalStack에 추가되었으나, 렌더링된 레이아웃의 modals 섹션에 해당 ID의 정의가 없습니다. partial 로딩 실패, 레이아웃 병합 문제, extends 상속 누락 등을 확인하세요. 레이아웃 경로: ${r.layoutPath}`,affectedStateKeys:[],expectedValue:`modals 배열에 id="${e}" 항목 존재`,actualValue:`modals 배열에 ${l.length}개 모달 정의 (${l.map(d=>d?.id||"unknown").join(", ")})`})}trackModalStateChange(e){if(!this.config.enabled)return;const n=this.modalStates.get(e.modalId);if(!n)return;n.stateChangeCount++,n.currentState[e.stateKey]=e.newValue;const r=this.checkIsolationViolation(n,e.stateKey),i={id:`modal-change-${++this.modalStateChangeLogIdCounter}`,modalId:e.modalId,modalName:n.modalName,timestamp:Date.now(),stateKey:e.stateKey,previousValue:e.previousValue,newValue:e.newValue,changeSource:e.changeSource||"user-action",violatesIsolation:r};this.modalStateChangeLogs.push(i),this.modalStateChangeLogs.length>this.maxModalStateChangeLogs&&this.modalStateChangeLogs.shift(),r&&this.recordModalStateIssue({type:"isolation-violation",modalId:e.modalId,modalName:n.modalName,severity:"warning",description:`모달 '${n.modalName}'에서 격리된 상태 키 '${e.stateKey}'가 변경됨`,affectedStateKeys:[e.stateKey]})}detectStateLeakage(e){if(e.scopeType==="isolated")for(const n of e.isolatedStateKeys){const r=e.initialState[n],i=e.currentState[n];if(r!==i&&e.parentModalId){const l=this.modalStates.get(e.parentModalId);l&&l.currentState.hasOwnProperty(n)&&this.recordModalStateIssue({type:"state-leakage",modalId:e.modalId,modalName:e.modalName,severity:"error",description:`모달 닫힘 후 상태 '${n}'가 부모 모달로 유출될 수 있음`,affectedStateKeys:[n],leakedValue:i,expectedValue:r})}}}checkIsolationViolation(e,n){return e.scopeType==="isolated",!1}recordModalStateIssue(e){const n={id:`modal-issue-${++this.modalStateIssueIdCounter}`,type:e.type,modalId:e.modalId,modalName:e.modalName,timestamp:Date.now(),severity:e.severity,description:e.description,affectedStateKeys:e.affectedStateKeys,leakedValue:e.leakedValue,expectedValue:e.expectedValue,actualValue:e.actualValue,stackInfo:e.stackInfo};this.modalStateIssues.push(n),this.modalStateIssues.length>this.maxModalStateIssues&&this.modalStateIssues.shift()}getModalStateScopeTrackingInfo(){const e=Array.from(this.modalStates.values()),n=this.getModalStateScopeStats();return{modals:e,issues:[...this.modalStateIssues],relations:[...this.modalStateRelations],changeLogs:[...this.modalStateChangeLogs],stats:n,timestamp:Date.now()}}getModalStateScopeStats(){const e=Array.from(this.modalStates.values()),n={warning:0,error:0},r={"state-leakage":0,"isolation-violation":0,"parent-mutation":0,"orphaned-state":0,"scope-mismatch":0,"cleanup-failure":0,"missing-definition":0};for(const l of this.modalStateIssues)n[l.severity]++,r[l.type]++;const i={isolated:0,shared:0,inherited:0};for(const l of e)i[l.scopeType]++;return{totalModals:e.length,openModals:e.filter(l=>l.closedAt===null).length,nestedModals:e.filter(l=>l.parentModalId!==void 0).length,totalIssues:this.modalStateIssues.length,issuesBySeverity:n,issuesByType:r,byScope:i,leakageDetectionCount:r["state-leakage"],cleanupFailureCount:r["cleanup-failure"]}}clearModalStateScopeTracking(){this.modalStates.clear(),this.modalStateIssues=[],this.modalStateRelations=[],this.modalStateChangeLogs=[],this.modalStateIssueIdCounter=0,this.modalStateChangeLogIdCounter=0}setNamedActionDefinitions(e){this.config.enabled&&(this.namedActionDefinitions=e||{})}trackNamedActionRef(e){if(!this.config.enabled)return;const n={...e,id:`named_action_ref_${++this.namedActionRefIdCounter}`};this.namedActionRefLogs.push(n),this.namedActionRefLogs.length>this.maxNamedActionRefLogs&&(this.namedActionRefLogs=this.namedActionRefLogs.slice(-this.maxNamedActionRefLogs))}getNamedActionTrackingInfo(){const e={};for(const r of this.namedActionRefLogs)e[r.actionRefName]=(e[r.actionRefName]||0)+1;const n=Object.keys(this.namedActionDefinitions).filter(r=>!e[r]);return{definitions:this.namedActionDefinitions,refLogs:[...this.namedActionRefLogs],stats:{totalDefinitions:Object.keys(this.namedActionDefinitions).length,totalRefs:this.namedActionRefLogs.length,refCountByName:e,unusedDefinitions:n},timestamp:Date.now()}}clearNamedActionTracking(){this.namedActionDefinitions={},this.namedActionRefLogs=[],this.namedActionRefIdCounter=0}trackExpressionEval(e){if(!this.config.enabled)return;const n={...e,id:`expr-${++this.expressionIdCounter}`,timestamp:Date.now(),warning:this.detectExpressionWarning(e)};this.expressionHistory.push(n),this.expressionHistory.length>500&&this.expressionHistory.shift(),this.isProfiling&&this.profilingData.push({type:"binding",expression:e.expression,timestamp:performance.now(),duration:e.duration}),this.notifyExpressionWatchers(n)}detectExpressionWarning(e){const{expression:n,result:r,resultType:i,method:l,duration:c}=e;if(i==="undefined"&&!n.includes("??")&&!n.includes("||")&&/^[a-zA-Z_$][a-zA-Z0-9_$.]*$/.test(n.replace(/{{|}}/g,"").trim()))return{type:"undefined-result",message:"표현식 결과가 undefined입니다",suggestion:`데이터가 로드되었는지 확인하거나 fallback 값을 추가하세요: ${n} ?? ''`};if(i==="null")return{type:"null-result",message:"표현식 결과가 null입니다",suggestion:`nullish coalescing 연산자를 사용하세요: ${n} ?? ''`};if(l==="resolveBindings"&&i==="string"){const d=String(r);if(d.includes("[object Object]")||/^\[.*\]$/.test(d))return{type:"array-to-string",message:"배열/객체가 문자열로 변환되었습니다",suggestion:"evaluateExpression()을 사용하여 원본 타입을 유지하세요"}}if(l==="resolveBindings"&&i==="string"&&String(r).includes("[object Object]"))return{type:"object-to-string",message:"객체가 [object Object]로 변환되었습니다",suggestion:"evaluateExpression()을 사용하거나 특정 속성에 접근하세요"};if(i==="undefined"&&n.includes(".")&&!n.includes("?.")){const d=n.replace(/{{|}}/g,"").trim().split(".");if(d.length>=2)return{type:"missing-optional-chain",message:"Optional chaining(?.) 누락 가능성",suggestion:`안전한 접근을 위해 ?. 사용을 고려하세요: ${d.join("?.")}`}}if((n.includes("{{item.")||n.includes("{{index}}"))&&Array.from(this.iterations.values()).some(h=>h.itemVar!=="item"))return{type:"wrong-iteration-var",message:"'item'/'index' 대신 iteration에서 정의한 변수명을 사용해야 합니다",suggestion:"iteration의 item_var/index_var에 정의된 변수명을 확인하세요"};if(c&&c>10)return{type:"slow-evaluation",message:`표현식 평가에 ${c.toFixed(2)}ms 소요됨`,suggestion:"복잡한 표현식을 단순화하거나 computed 값으로 분리하세요"}}getExpressions(){return[...this.expressionHistory]}getExpressionWarnings(){return this.expressionHistory.filter(e=>e.warning!=null)}searchExpressions(e){const n=e.toLowerCase();return this.expressionHistory.filter(r=>r.expression.toLowerCase().includes(n)||r.componentName?.toLowerCase().includes(n)||r.propName?.toLowerCase().includes(n))}getExpressionStats(){const e=this.expressionHistory,n=new Set(e.map(f=>f.expression)),r=e.filter(f=>f.warning!=null),i=e.filter(f=>f.fromCache),l=e.filter(f=>f.duration!=null).map(f=>f.duration),c={};for(const f of e)c[f.resultType]=(c[f.resultType]||0)+1;const d={};for(const f of r)f.warning&&(d[f.warning.type]=(d[f.warning.type]||0)+1);return{totalEvaluations:e.length,uniqueExpressions:n.size,warningCount:r.length,cacheHitRate:e.length>0?i.length/e.length:0,averageDuration:l.length>0?l.reduce((f,h)=>f+h,0)/l.length:0,byType:c,byWarning:d}}clearExpressions(){this.expressionHistory=[],this.expressionIdCounter=0}watchExpressions(e){return this.expressionWatchers.add(e),()=>{this.expressionWatchers.delete(e)}}notifyExpressionWatchers(e){this.expressionWatchers.forEach(n=>{try{n(e)}catch(r){console.error("[G7DevTools] Expression watcher error:",r)}})}setLogLevel(e){this.config.logLevel=e}setMaxHistory(e){this.config.maxHistorySize=Math.max(10,Math.min(1e3,e))}setServerEndpoint(e){this.config.serverEndpoint=e}getConfig(){return{...this.config}}generateId(){return`${Date.now()}-${Math.random().toString(36).substr(2,9)}`}sanitizeObject(e,n=new WeakSet){if(e===null||typeof e!="object")return e;if(n.has(e))return"[Circular]";if(n.add(e),Array.isArray(e))return e.map(i=>this.sanitizeObject(i,n));const r={};for(const i of Object.keys(e))try{r[i]=this.sanitizeObject(e[i],n)}catch{r[i]="[Unable to serialize]"}return r}getNestedValue(e,n){if(!n)return e;const r=n.split(".");let i=e;for(const l of r){if(i==null)return;i=i[l]}return i}getLifecycleInfo(){return{mountedComponents:Array.from(this.mountedComponents.values()),orphanedListeners:this.getOrphanedListeners()}}getPerformanceInfo(){return{renderCounts:this.renderCounts,bindingEvalCount:this.bindingEvalCount,memoryWarnings:this.getMemoryWarnings()}}getNetworkInfo(){return{activeRequests:Array.from(this.activeRequests.values()),requestHistory:[...this.requestHistory],pendingDataSources:Array.from(this.pendingDataSources)}}getConditionalInfo(){return{ifConditions:Array.from(this.ifConditions.values()),iterations:Array.from(this.iterations.values())}}getFormInfo(){return Array.from(this.forms.values())}getWebSocketInfo(){return{connections:Array.from(this.wsConnections.values()),messageHistory:[...this.wsMessageHistory],connectionState:this.getWebSocketConnectionState()}}getStateAtTime(e){const n=[...this.stateHistory].reverse().find(r=>r.timestamp<=e);if(n)return{_global:n.next,_local:{}}}reset(){this.stateHistory=[],this.actionHistory=[],this.cacheStats={hits:0,misses:0,entries:0},this.cacheDecisions=[],this.cacheDecisionIdCounter=0,this.currentRenderCycleId=null,this.isInActionExecution=!1,this.isInIteration=!1,this.mountedComponents.clear(),this.eventListeners.clear(),this.renderCounts.clear(),this.bindingEvalCount=0,this.profilingData=[],this.activeRequests.clear(),this.requestHistory=[],this.pendingDataSources.clear(),this.wsConnections.clear(),this.wsMessageHistory=[],this.ifConditions.clear(),this.iterations.clear(),this.forms.clear(),this.expressionHistory=[],this.expressionIdCounter=0,this.dataSources.clear(),this.dataPathTransforms=[],this.nestedContexts=[],this.nestedContextIdCounter=0,this.formBindingIssues=[],this.formBindingValidations=[],this.formBindingIssueIdCounter=0,this.computedProperties.clear(),this.computedRecalcLogs=[],this.computedRecalcIdCounter=0,this.modalStates.clear(),this.modalStateIssues=[],this.modalStateRelations=[],this.modalStateChangeLogs=[],this.modalStateIssueIdCounter=0,this.modalStateChangeLogIdCounter=0,this.logHistory=[],this.logIdCounter=0}getExpressionInfo(){return{expressions:this.getExpressions(),stats:this.getExpressionStats()}}trackLog(e,n,r){if(!this.config.enabled)return;const i=r.map(c=>{if(typeof c=="string")return c;try{return JSON.stringify(c)}catch{return String(c)}}).join(" "),l={id:`log-${++this.logIdCounter}`,level:e,prefix:n,message:i,args:this.sanitizeObject(r),timestamp:Date.now(),stack:e==="error"?new Error().stack:void 0};this.logHistory.push(l),this.logHistory.length>this.maxLogHistory&&this.logHistory.shift()}trackAction(e){if(!this.config.enabled)return;const n={id:`debounce-action-${++this.debounceActionIdCounter}`,...e,timestamp:Date.now()};this.debounceActionHistory.push(n),this.debounceActionHistory.length>100&&this.debounceActionHistory.shift()}trackDataSourceUpdate(e){if(!this.config.enabled)return;const n={id:`ds-update-${++this.dataSourceUpdateIdCounter}`,...e};this.dataSourceUpdateHistory.push(n),this.dataSourceUpdateHistory.length>100&&this.dataSourceUpdateHistory.shift()}getDebounceActionHistory(e){let n=[...this.debounceActionHistory];return e?.handler&&(n=n.filter(r=>r.handler.includes(e.handler))),e?.status&&(n=n.filter(r=>r.status===e.status)),e?.limit&&(n=n.slice(-e.limit)),n}getDataSourceUpdateHistory(e){let n=[...this.dataSourceUpdateHistory];return e?.dataSourceId&&(n=n.filter(r=>r.dataSourceId===e.dataSourceId)),e?.updateType&&(n=n.filter(r=>r.updateType===e.updateType)),e?.limit&&(n=n.slice(-e.limit)),n}getLogs(e){let n=[...this.logHistory];if(e?.level){const r=Array.isArray(e.level)?e.level:[e.level];n=n.filter(i=>r.includes(i.level))}if(e?.prefix){const r=e.prefix.toLowerCase();n=n.filter(i=>i.prefix.toLowerCase().includes(r))}if(e?.search){const r=e.search.toLowerCase();n=n.filter(i=>i.message.toLowerCase().includes(r))}return e?.since&&(n=n.filter(r=>r.timestamp>=e.since)),e?.limit&&(n=n.slice(-e.limit)),n}getLogStats(){const n=Date.now()-6e4,r={log:0,warn:0,error:0,debug:0,info:0},i={};let l=0,c=0;for(const d of this.logHistory)r[d.level]++,i[d.prefix]=(i[d.prefix]||0)+1,d.timestamp>=n&&(d.level==="error"&&l++,d.level==="warn"&&c++);return{totalLogs:this.logHistory.length,byLevel:r,byPrefix:i,recentErrors:l,recentWarnings:c}}clearLogs(){this.logHistory=[],this.logIdCounter=0}getLogInfo(){return{entries:this.getLogs(),stats:this.getLogStats()}}trackDataSourceDefinition(e){this.config.enabled&&this.dataSources.set(e.id,{...e,status:"idle"})}trackDataSourceLoading(e){if(!this.config.enabled)return;const n=this.dataSources.get(e);n&&this.dataSources.set(e,{...n,status:"loading"})}trackDataSourceLoaded(e,n,r){if(!this.config.enabled)return;const i=this.dataSources.get(e);if(!i)return;let l,c,d=r;n&&(Array.isArray(n)?(l=n.length,c=n.length>0&&typeof n[0]=="object"?Object.keys(n[0]):void 0):typeof n=="object"&&(Array.isArray(n.data)?(d=d||"data",l=n.data.length,c=n.data.length>0&&typeof n.data[0]=="object"?Object.keys(n.data[0]):void 0):Array.isArray(n.items)?(d=d||"items",l=n.items.length,c=n.items.length>0&&typeof n.items[0]=="object"?Object.keys(n.items[0]):void 0):c=Object.keys(n))),this.dataSources.set(e,{...i,status:"loaded",dataPath:d,itemCount:l,keys:c,lastLoadedAt:Date.now(),error:void 0})}trackDataSourceError(e,n){if(!this.config.enabled)return;const r=this.dataSources.get(e);r&&this.dataSources.set(e,{...r,status:"error",error:n,lastLoadedAt:Date.now()})}untrackDataSource(e){this.dataSources.delete(e)}getDataSources(){return Array.from(this.dataSources.values())}getDataSource(e){return this.dataSources.get(e)}clearDataSources(){this.dataSources.clear()}trackDataPathTransform(e){if(!this.config.enabled)return;let n=this.dataPathTransforms.find(r=>r.dataSourceId===e.dataSourceId);n||(n={dataSourceId:e.dataSourceId,timestamp:Date.now(),transformSteps:[],warnings:[]},this.dataPathTransforms.push(n),this.dataPathTransforms.length>this.maxDataPathTransforms&&this.dataPathTransforms.shift()),n.transformSteps.push({step:e.step,inputPath:e.inputPath,inputValue:this.safeClone(e.inputValue),outputPath:e.outputPath,outputValue:this.safeClone(e.outputValue),config:e.config}),e.warning&&n.warnings.push(e.warning)}setDataPathFinalBinding(e,n){if(!this.config.enabled)return;const r=this.dataPathTransforms.find(i=>i.dataSourceId===e);r&&(r.finalBinding={expression:n.expression,resolvedPath:n.resolvedPath,value:this.safeClone(n.value)})}getDataPathTransformTrackingInfo(){const e=this.getDataPathTransformStats();return{transforms:[...this.dataPathTransforms],stats:e,timestamp:Date.now()}}getDataPathTransformStats(){const e=this.dataPathTransforms,n={};let r=0;const i={};for(const c of e){n[c.dataSourceId]=(n[c.dataSourceId]||0)+1,r+=c.warnings.length;for(const d of c.warnings)i[d]=(i[d]||0)+1}const l=Object.entries(i).map(([c,d])=>({warning:c,count:d})).sort((c,d)=>d.count-c.count).slice(0,10);return{totalTransforms:e.length,byDataSource:n,warningsCount:r,commonWarnings:l}}getDataPathTransformForDataSource(e){return this.dataPathTransforms.find(n=>n.dataSourceId===e)}clearDataPathTransforms(){this.dataPathTransforms=[]}trackNestedContext(e){if(!this.config.enabled)return"";const n=`nested-${++this.nestedContextIdCounter}`,r=[...new Set([...e.parentContext.available,...e.ownContext.added])],i={...e.parentContext.values,...e.ownContext.values},l={id:n,timestamp:Date.now(),componentId:e.componentId,componentType:e.componentType,parentContext:{available:e.parentContext.available,values:this.safeClone(e.parentContext.values)},ownContext:{added:e.ownContext.added,values:this.safeClone(e.ownContext.values)},mergedContext:{all:r,values:this.safeClone(i)},accessAttempts:[],depth:e.depth,parentId:e.parentId};return this.nestedContexts.push(l),this.nestedContexts.length>this.maxNestedContexts&&this.nestedContexts.shift(),n}trackNestedContextAccess(e,n){if(!this.config.enabled)return;const r=this.nestedContexts.find(i=>i.id===e);r&&r.accessAttempts.push({path:n.path,found:n.found,value:n.found?this.safeClone(n.value):void 0,error:n.error})}getNestedContextTrackingInfo(){const e=this.getNestedContextStats();return{contexts:[...this.nestedContexts],stats:e,timestamp:Date.now()}}getNestedContextStats(){const e=this.nestedContexts,n={expandChildren:0,cellChildren:0,iteration:0,modal:0,slot:0};let r=0,i=0;const l={};for(const d of e){n[d.componentType]++,d.depth>r&&(r=d.depth);for(const f of d.accessAttempts)f.found||(i++,l[f.path]=(l[f.path]||0)+1)}const c=Object.entries(l).map(([d,f])=>({path:d,count:f})).sort((d,f)=>f.count-d.count).slice(0,10);return{totalContexts:e.length,byType:n,maxDepth:r,failedAccessCount:i,commonFailedPaths:c}}getNestedContextForComponent(e){return this.nestedContexts.find(n=>n.componentId===e)}clearNestedContexts(){this.nestedContexts=[],this.nestedContextIdCounter=0}trackHandlerRegistration(e,n="custom",r,i){this.isEnabled&&this.handlers.set(e,{name:e,category:n,description:r,registeredAt:Date.now(),source:i})}trackHandlerUnregistration(e){this.isEnabled&&this.handlers.delete(e)}getHandlers(){return Array.from(this.handlers.values())}getHandler(e){return this.handlers.get(e)}getHandlersByCategory(e){return Array.from(this.handlers.values()).filter(n=>n.category===e)}clearHandlers(){this.handlers.clear()}trackEventSubscribe(e){if(!this.isEnabled)return;const n=this.componentEventSubscriptions.get(e),r=Date.now();n?(n.subscriberCount++,n.lastSubscribedAt=r):this.componentEventSubscriptions.set(e,{eventName:e,subscriberCount:1,firstSubscribedAt:r,lastSubscribedAt:r})}trackEventUnsubscribe(e){if(!this.isEnabled)return;const n=this.componentEventSubscriptions.get(e);n&&(n.subscriberCount--,n.subscriberCount<=0&&this.componentEventSubscriptions.delete(e))}trackEventEmit(e,n,r,i,l){if(!this.isEnabled)return;const c={id:`evt_${++this.componentEventIdCounter}`,eventName:e,data:this.sanitizeForLogging(n),timestamp:Date.now(),listenerCount:r,results:i?this.sanitizeForLogging(i):void 0,hasError:!!l,errorMessage:l?.message};this.componentEventEmitHistory.push(c),this.componentEventEmitHistory.length>this.maxComponentEventHistory&&(this.componentEventEmitHistory=this.componentEventEmitHistory.slice(-this.maxComponentEventHistory))}trackEventOff(e){this.isEnabled&&this.componentEventSubscriptions.delete(e)}trackEventClear(){this.isEnabled&&this.componentEventSubscriptions.clear()}getComponentEventInfo(){const e=Array.from(this.componentEventSubscriptions.values());return{subscriptions:e,emitHistory:[...this.componentEventEmitHistory],totalSubscribers:e.reduce((n,r)=>n+r.subscriberCount,0),totalEmits:this.componentEventEmitHistory.length}}getEventEmitHistory(){return[...this.componentEventEmitHistory]}getEventSubscriptions(){return Array.from(this.componentEventSubscriptions.values())}clearComponentEvents(){this.componentEventSubscriptions.clear(),this.componentEventEmitHistory=[],this.componentEventIdCounter=0}sanitizeForLogging(e){if(e==null||typeof e!="object")return e;try{return JSON.parse(JSON.stringify(e))}catch{return"[Circular or Non-serializable]"}}startStateChange(e,n,r,i){if(!this.config.enabled)return"";const l=`setState_${++this.stateRenderingIdCounter}`;this.currentStateChangeContext={setStateId:l,startTime:performance.now(),changedPath:e,trigger:i||{},renderedComponents:[]};const c={id:`sr_${this.stateRenderingIdCounter}`,setStateId:l,statePath:e,oldValue:this.sanitizeForLogging(n),newValue:this.sanitizeForLogging(r),timestamp:Date.now(),triggeredBy:i||{},renderedComponents:[],totalRenderDuration:0,affectedBindingsCount:0};return this.stateRenderingLogs.push(c),this.stateRenderingLogs.length>this.maxStateRenderingLogs&&this.stateRenderingLogs.shift(),l}trackComponentRender(e,n,r,i=[],l=[],c){if(!this.config.enabled)return;const d=this.componentRenderCounts.get(n)||0;this.componentRenderCounts.set(n,d+1);for(const f of i)this.stateToComponentMap.has(f)||this.stateToComponentMap.set(f,new Set),this.stateToComponentMap.get(f).add(n);if(this.currentStateChangeContext){const f={componentId:e,componentName:n,renderDuration:r,accessedStatePaths:i,evaluatedBindings:l,renderOrder:this.currentStateChangeContext.renderedComponents.length,parentId:c};this.currentStateChangeContext.renderedComponents.push(f)}this.trackRender(n)}completeStateChange(e){if(!this.config.enabled||!this.currentStateChangeContext||this.currentStateChangeContext.setStateId!==e)return;const n=this.currentStateChangeContext,i=performance.now()-n.startTime,l=this.stateRenderingLogs.findIndex(c=>c.setStateId===e);if(l>=0){const c=this.stateRenderingLogs[l];c.renderedComponents=n.renderedComponents,c.totalRenderDuration=i,c.affectedBindingsCount=n.renderedComponents.reduce((d,f)=>d+f.evaluatedBindings.length,0)}this.currentStateChangeContext=null}getCurrentStateChangeContext(){return this.currentStateChangeContext}getStateRenderingLogs(){return[...this.stateRenderingLogs]}getStateRenderingInfo(){const e=this.stateRenderingLogs,n=Object.fromEntries(this.componentRenderCounts),r={};for(const[i,l]of this.stateToComponentMap)r[i]=Array.from(l);return{logs:e,componentRenderCounts:n,stateToComponentMap:r,stats:this.calculateStateRenderingStats()}}calculateStateRenderingStats(){const e=this.stateRenderingLogs;if(e.length===0)return{totalStateChanges:0,totalRenders:0,avgRenderDuration:0,avgComponentsPerChange:0,topRenderedComponents:[],topInfluentialPaths:[]};const n=e.reduce((d,f)=>d+f.renderedComponents.length,0),r=e.reduce((d,f)=>d+f.totalRenderDuration,0)/e.length,i=n/e.length,l=Array.from(this.componentRenderCounts.entries()).sort((d,f)=>f[1]-d[1]).slice(0,5).map(([d,f])=>({name:d,count:f})),c=Array.from(this.stateToComponentMap.entries()).sort((d,f)=>f[1].size-d[1].size).slice(0,5).map(([d,f])=>({path:d,affectedComponents:f.size}));return{totalStateChanges:e.length,totalRenders:n,avgRenderDuration:r,avgComponentsPerChange:i,topRenderedComponents:l,topInfluentialPaths:c}}getComponentsAffectedByState(e){const n=this.stateToComponentMap.get(e);return n?Array.from(n):[]}getComponentRenderHistory(e){return this.stateRenderingLogs.filter(n=>n.renderedComponents.some(r=>r.componentName===e))}clearStateRenderingLogs(){this.stateRenderingLogs=[],this.componentRenderCounts.clear(),this.stateToComponentMap.clear(),this.currentStateChangeContext=null,this.stateRenderingIdCounter=0}trackComponentStateSource(e,n,r,i){this.config.enabled&&this.componentStateSources.set(e,{componentId:e,componentName:n,stateSource:r,stateProvider:i})}trackDynamicState(e,n){this.config.enabled&&this.dynamicStates.set(e,n)}trackContextFlow(e,n,r,i,l,c){if(!this.config.enabled)return;const d={component:n,componentId:e,contextReceived:r,passedToChildren:i,usedInRender:l};if(this.contextFlowNodes.set(e,d),c){const f=this.contextFlowNodes.get(c);f&&(f.children||(f.children=[]),f.children.push(d))}}getStateHierarchyInfo(e=!0){const n=this.buildStateHierarchyLayers(),r=this.detectStateConflicts(n),i=Array.from(this.componentStateSources.values());return{layers:e?n.map(c=>({...c,values:this.summarizeValues(c.values,2)})):n,conflicts:r,componentStateSources:i,timestamp:Date.now()}}summarizeValues(e,n,r=0){if(e==null)return e;if(typeof e!="object")return typeof e=="string"&&e.length>100?e.substring(0,100)+`... (${e.length}자)`:e;if(r>=n){if(Array.isArray(e))return`[Array(${e.length})]`;const c=Object.keys(e);return`{${c.slice(0,5).join(", ")}${c.length>5?`, ... +${c.length-5}`:""}}`}if(Array.isArray(e))return e.length<=3?e.map(c=>this.summarizeValues(c,n,r+1)):{__type:"array",__length:e.length,__preview:e.slice(0,3).map(c=>this.summarizeValues(c,n,r+1))};const i={},l=Object.keys(e);for(const c of l)i[c]=this.summarizeValues(e[c],n,r+1);return i}buildStateHierarchyLayers(){const e=[];try{const r=window.G7Core?.state?.get?.();if(!r)return e;r._local&&e.push({name:"Global _local",type:"global",path:"_local",values:r._local,priority:1}),r._global&&e.push({name:"Global _global",type:"global",path:"_global",values:r._global,priority:1});for(const[l,c]of this.dynamicStates)c&&Object.keys(c).length>0&&e.push({name:`DynamicState (${l})`,type:"dynamicState",componentId:l,values:c,priority:2});const i=this.computeEffectiveState(r._local||{});e.push({name:"Effective _local (merged)",type:"effective",values:i,priority:3})}catch(n){console.warn("[G7DevTools] 상태 계층 빌드 실패:",n)}return e}computeEffectiveState(e){const n={...e};for(const[,r]of this.dynamicStates)r._local&&Object.assign(n,r._local);return n}detectStateConflicts(e){const n=[],r=e.find(l=>l.type==="global"&&l.path==="_local");if(!r)return n;const i=e.filter(l=>l.type==="dynamicState");for(const l of i){const c=l.values._local||l.values;for(const[d,f]of Object.entries(c)){const h=r.values[d];if(JSON.stringify(h)!==JSON.stringify(f)){const m=[],y=[];for(const S of this.componentStateSources.values())S.stateSource.local.some(_=>_===`_local.${d}`||_===d)&&(S.stateProvider.type==="dynamicState"?m.push(S.componentName):S.stateProvider.type==="globalState"&&y.push(S.componentName));n.push({path:`_local.${d}`,globalValue:h,dynamicStateValue:f,effectiveValue:f,usedBy:m,notUsedBy:y,severity:y.length>0?"warning":"info",description:y.length>0?`${y.join(", ")}은(는) globalState._local을 읽어 dynamicState 값을 사용하지 못함`:"dynamicState 값이 globalState와 다르지만 모든 컴포넌트가 dynamicState를 사용"})}}}return n}getContextFlowInfo(){const e=[],n=new Set(this.contextFlowNodes.keys());for(const r of this.contextFlowNodes.values())if(r.children)for(const i of r.children)n.delete(i.componentId);for(const r of n){const i=this.contextFlowNodes.get(r);i&&e.push(i)}return{rootComponent:e.length>0?e[0].component:"Unknown",contextFlow:e,timestamp:Date.now()}}clearStateHierarchyData(){this.componentStateSources.clear(),this.contextFlowNodes.clear(),this.dynamicStates.clear()}trackComponentStyle(e,n,r,i){if(!this.config.enabled)return;const l=this.analyzeTailwindClasses(r),c={componentId:e,componentName:n,classes:r,computedStyles:i,tailwindAnalysis:l};this.componentStyles.set(e,c),this.detectStyleIssues(c)}analyzeTailwindClasses(e){const n=[],r=[],i=[],l=[],c=["sm:","md:","lg:","xl:","2xl:"],d=[/bg-\w+-\d+/,/text-\w+-\d+/,/border-\w+-\d+/];for(const f of e){l.push(f),f.startsWith("dark:")&&n.push(f);for(const h of c)if(f.startsWith(h)){r.push(f);break}for(const h of d)if(h.test(f)){i.push(f);break}}return{usedClasses:l,darkClasses:n,responsiveClasses:r,dynamicClasses:i}}detectStyleIssues(e){const{componentId:n,componentName:r,computedStyles:i,tailwindAnalysis:l}=e;(i.opacity==="0"||i.visibility==="hidden"||i.display==="none"||i.width==="0px"&&i.height==="0px")&&this.addStyleIssue({id:this.generateId(),type:"invisible-element",componentId:n,componentName:r,property:i.opacity==="0"?"opacity":i.visibility==="hidden"?"visibility":i.display==="none"?"display":"width/height",currentValue:i.opacity==="0"?"0":i.visibility==="hidden"?"hidden":i.display==="none"?"none":"0px",severity:"warning",description:"요소가 화면에 보이지 않습니다.",suggestion:"opacity, visibility, display, width/height 값을 확인하세요."});const c=l.usedClasses.filter(f=>f.startsWith("bg-")&&!f.startsWith("dark:")),d=l.darkClasses.filter(f=>f.includes("bg-"));c.length>0&&d.length===0&&this.addStyleIssue({id:this.generateId(),type:"dark-mode-missing",componentId:n,componentName:r,property:"background-color",currentValue:c.join(", "),expectedValue:"dark:bg-* 클래스 필요",severity:"info",description:"다크 모드 배경색 클래스가 누락되었습니다.",suggestion:`${c[0]}에 대응하는 dark: 클래스를 추가하세요.`}),l.dynamicClasses.length>0&&this.addStyleIssue({id:this.generateId(),type:"tailwind-purging",componentId:n,componentName:r,property:"class",currentValue:l.dynamicClasses.join(", "),severity:"info",description:"동적으로 생성된 Tailwind 클래스가 있습니다.",suggestion:"tailwind.config.js의 safelist에 추가하거나 전체 클래스명을 상수로 정의하세요."})}addStyleIssue(e){this.styleIssues.some(r=>r.componentId===e.componentId&&r.type===e.type&&r.property===e.property)||this.styleIssues.push(e)}getStyleValidationInfo(){const e=Array.from(this.componentStyles.values());return{issues:[...this.styleIssues],componentStyles:e,stats:{totalComponents:e.length,invisibleCount:this.styleIssues.filter(n=>n.type==="invisible-element").length,tailwindIssueCount:this.styleIssues.filter(n=>n.type==="tailwind-purging").length,darkModeIssueCount:this.styleIssues.filter(n=>n.type==="dark-mode-missing").length},timestamp:Date.now()}}clearStyleValidationData(){this.styleIssues=[],this.componentStyles.clear()}trackAuthEvent(e,n,r,i){if(!this.config.enabled)return;const l={id:`auth_${++this.authEventIdCounter}`,type:e,timestamp:Date.now(),success:n,error:r,details:i};this.authEvents.push(l),this.authEvents.length>this.maxAuthEventHistory&&(this.authEvents=this.authEvents.slice(-this.maxAuthEventHistory))}trackAuthHeader(e,n,r,i,l){if(!this.config.enabled)return;const c={url:e,hasAuthHeader:n,headerType:r,tokenValid:i??!1,responseStatus:l,timestamp:Date.now()};this.authHeaderHistory.push(c),this.authHeaderHistory.length>this.maxAuthEventHistory&&(this.authHeaderHistory=this.authHeaderHistory.slice(-this.maxAuthEventHistory)),l===401&&this.trackAuthEvent("api-unauthorized",!1,`401 Unauthorized: ${e}`,{url:e})}getAuthState(){try{const e=window.G7Core,n=e?.api;let r=e?.auth;!r&&e?.AuthManager?.getInstance&&(r=e.AuthManager.getInstance());const i=n?.getToken?.()||r?.getAccessToken?.()||localStorage.getItem("auth_token")||localStorage.getItem("access_token"),l=r?.getRefreshToken?.()||localStorage.getItem("refresh_token");let c="unknown",d=r?.getUser?.();if(d&&(c="AuthManager"),!d){const v=e?.state?.get?.();d=v?._global?.user||v?._global?.currentUser||v?.user||v?.currentUser,d&&(c="G7Core.state")}const f=r?.isAuthenticated?.()??!1;let h="memory";localStorage.getItem("auth_token")||localStorage.getItem("access_token")?h="localStorage":(sessionStorage.getItem("auth_token")||sessionStorage.getItem("access_token"))&&(h="sessionStorage");const m=!!i&&(!!d||f);let y;i&&typeof i=="string"&&i.length>20?y=`${i.substring(0,10)}...${i.substring(i.length-6)}`:i&&(y="***");const S=d?{id:d.id,email:d.email,name:d.name,roles:d.roles?.map(v=>typeof v=="string"?{name:v}:{id:v.id,name:v.name,guard_name:v.guard_name}),permissions:d.permissions?.map(v=>typeof v=="string"?{name:v}:{id:v.id,name:v.name,guard_name:v.guard_name}),avatar:d.avatar||d.profile_photo_url||d.profile_image,created_at:d.created_at,updated_at:d.updated_at,last_login_at:d.last_login_at,email_verified_at:d.email_verified_at,...d.phone&&{phone:d.phone},...d.nickname&&{nickname:d.nickname},...d.status&&{status:d.status},...d.locale&&{locale:d.locale}}:void 0;return{isAuthenticated:m,user:S,tokens:{hasAccessToken:!!i,hasRefreshToken:!!l,storage:h,accessTokenPreview:y},lastActivity:Date.now(),source:c}}catch{return{isAuthenticated:!1,tokens:{hasAccessToken:!1,hasRefreshToken:!1,storage:"memory"},source:"unknown"}}}getAuthDebugInfo(){const e=[...this.authEvents];return{state:this.getAuthState(),events:e,headerAnalysis:[...this.authHeaderHistory],stats:{loginAttempts:e.filter(n=>n.type==="login").length,successfulLogins:e.filter(n=>n.type==="login"&&n.success).length,failedLogins:e.filter(n=>n.type==="login"&&!n.success).length,tokenRefreshes:e.filter(n=>n.type==="token-refresh").length,unauthorizedResponses:e.filter(n=>n.type==="api-unauthorized").length},timestamp:Date.now()}}clearAuthData(){this.authEvents=[],this.authHeaderHistory=[],this.authEventIdCounter=0}trackLayoutLoad(e,n,r,i="api"){if(!this.config.enabled)return;const l=Date.now();this.currentLayout={layoutPath:e,templateId:n,layoutJson:this.sanitizeObject(r),loadedAt:l,version:r.version,layoutName:r.layout_name,source:i};const c={id:`layout-${++this.layoutIdCounter}`,layoutPath:e,templateId:n,loadedAt:l,source:i,version:r.version};this.layoutHistory.push(c),this.layoutHistory.length>this.maxLayoutHistory&&this.layoutHistory.shift(),this.layoutStats.totalLoads++,i==="cache"?this.layoutStats.cacheHits++:this.layoutStats.apiLoads++}getCurrentLayout(){return this.currentLayout}getLayoutHistory(){return[...this.layoutHistory]}getLayoutDebugInfo(){return{current:this.currentLayout,history:[...this.layoutHistory],stats:{...this.layoutStats}}}clearLayoutData(){this.currentLayout=null,this.layoutHistory=[],this.layoutIdCounter=0,this.layoutStats={totalLoads:0,cacheHits:0,apiLoads:0}}startHandlerExecution(e){if(!this.config.enabled)return"";const n=`exec_${++this.executionIdCounter}_${Date.now()}`,r={handlerName:e,executionId:n,startTime:Date.now(),stateChanges:[],dataSourceChanges:[],alerts:[]};if(this.executionDetails.set(n,r),this.executionDetails.size>this.maxExecutionDetails){const i=Array.from(this.executionDetails.keys());i.slice(0,i.length-this.maxExecutionDetails).forEach(c=>this.executionDetails.delete(c))}return n}endHandlerExecution(e,n,r,i){if(!this.config.enabled||!e)return;const l=this.executionDetails.get(e);if(!l)return;l.endTime=Date.now(),l.duration=l.endTime-l.startTime,l.exitReason=n,l.exitLocation=r,l.exitDescription=i;const c=this.changeExpectations.get(e);c&&(l.expectedChanges=c,this.checkExpectations(e,l,c),this.changeExpectations.delete(e)),n==="normal"&&l.stateChanges.length===0&&l.dataSourceChanges.length===0&&this.addChangeAlert(e,{type:"no-state-change",severity:"warning",message:`핸들러 "${l.handlerName}"이(가) 상태 변경 없이 완료됨`,description:"핸들러가 성공적으로 완료되었지만 상태나 데이터소스 변경이 없습니다. 의도한 동작인지 확인하세요.",handlerName:l.handlerName,suggestion:'핸들러 내부 조건문을 확인하거나 DevTools의 "변경감지" 탭에서 exitLocation을 확인하세요.',docLink:"troubleshooting-state.md"}),(n==="early-return-condition"||n==="early-return-validation")&&this.addChangeAlert(e,{type:"early-return-detected",severity:"info",message:`핸들러 "${l.handlerName}"이(가) early return으로 종료됨`,description:i||`종료 위치: ${r||"알 수 없음"}`,handlerName:l.handlerName,suggestion:n==="early-return-validation"?"검증 실패로 인한 early return입니다. 입력 데이터를 확인하세요.":"조건부 early return입니다. 조건문의 평가 결과를 확인하세요."})}recordExitReason(e,n,r,i){if(!this.config.enabled||!e)return;const l=this.executionDetails.get(e);l&&(l.exitReason=n,l.exitLocation=r,l.exitDescription=i)}recordStateChange(e,n,r,i,l){if(!this.config.enabled)return;const c={id:`sc_${++this.stateChangeIdCounter}`,path:n,changeType:r,oldValue:this.safeClone(i),newValue:this.safeClone(l),timestamp:Date.now(),comparison:this.compareValues(i,l),executionId:e};if(this.stateChangeHistory.push(c),e){const d=this.executionDetails.get(e);d&&d.stateChanges.push(c)}this.stateChangeHistory.length>this.maxStateChangeHistory&&this.stateChangeHistory.splice(0,this.stateChangeHistory.length-this.maxStateChangeHistory),c.comparison.isDeepEqual&&typeof i=="object"&&i!==null&&this.addChangeAlert(e||"",{type:"object-reference-same",severity:"warning",message:`상태 "${n}"가 변경되었으나 값이 동일함`,description:"객체 참조가 동일하거나 깊은 비교 결과 변경이 없습니다. 변경 감지가 실패할 수 있습니다.",handlerName:e&&this.executionDetails.get(e)?.handlerName||"unknown",statePath:n,suggestion:"불변성을 유지하여 새 객체를 생성하세요. 예: { ...oldObject, newField: value }",docLink:"troubleshooting-state.md#object-mutation"})}recordDataSourceChange(e,n,r,i,l){if(!this.config.enabled)return;const c={dataSourceId:n,changeType:r,timestamp:Date.now(),previousStatus:i,newStatus:l,executionId:e};if(this.dataSourceChangeHistory.push(c),e){const d=this.executionDetails.get(e);d&&d.dataSourceChanges.push(c)}this.dataSourceChangeHistory.length>this.maxStateChangeHistory&&this.dataSourceChangeHistory.splice(0,this.dataSourceChangeHistory.length-this.maxStateChangeHistory)}expectChange(e,n,r){if(!this.config.enabled||!e)return;const i=this.executionDetails.get(e);if(!i)return;const l={expectedStatePaths:n,expectedDataSources:r,setAt:Date.now(),source:i.handlerName};this.changeExpectations.set(e,l)}checkExpectations(e,n,r){const i=new Set(n.stateChanges.map(c=>c.path)),l=new Set(n.dataSourceChanges.map(c=>c.dataSourceId));for(const c of r.expectedStatePaths)i.has(c)||this.addChangeAlert(e,{type:"expected-not-fulfilled",severity:"error",message:`기대한 상태 변경 "${c}"가 발생하지 않음`,description:`핸들러 "${n.handlerName}"이(가) "${c}" 변경을 예고했지만 실제로 변경되지 않았습니다.`,handlerName:n.handlerName,statePath:c,suggestion:"핸들러 내부 로직을 확인하세요. early return이나 조건부 분기로 인해 변경이 생략되었을 수 있습니다.",docLink:"troubleshooting-state.md"});for(const c of r.expectedDataSources)l.has(c)||this.addChangeAlert(e,{type:"expected-not-fulfilled",severity:"error",message:`기대한 데이터소스 갱신 "${c}"가 발생하지 않음`,description:`핸들러 "${n.handlerName}"이(가) "${c}" 갱신을 예고했지만 실제로 갱신되지 않았습니다.`,handlerName:n.handlerName,dataSourceId:c,suggestion:"refetchDataSource 호출이 실행되었는지 확인하세요.",docLink:"data-sources.md"})}addChangeAlert(e,n){const r={...n,id:`alert_${++this.alertIdCounter}`,timestamp:Date.now()};if(this.changeAlerts.push(r),e){const i=this.executionDetails.get(e);i&&i.alerts.push(r)}this.changeAlerts.length>this.maxChangeAlerts&&this.changeAlerts.splice(0,this.changeAlerts.length-this.maxChangeAlerts)}compareValues(e,n){const r=this.getValueType(e),i=this.getValueType(n),l=r!==i;let c=!1,d;return!l&&(r==="object"||r==="array")?(c=this.deepEqual(e,n),!c&&r==="object"&&(d=this.getChangedKeys(e,n))):c=e===n,{typeChanged:l,oldType:r,newType:i,isDeepEqual:c,changedKeys:d}}getValueType(e){return e===null?"null":e===void 0?"undefined":Array.isArray(e)?"array":typeof e}deepEqual(e,n){if(e===n)return!0;if(typeof e!=typeof n)return!1;if(e===null||n===null||typeof e!="object")return e===n;if(Array.isArray(e)!==Array.isArray(n))return!1;const r=Object.keys(e),i=Object.keys(n);if(r.length!==i.length)return!1;for(const l of r)if(!i.includes(l)||!this.deepEqual(e[l],n[l]))return!1;return!0}getChangedKeys(e,n){const r=[],i=new Set([...Object.keys(e),...Object.keys(n)]);for(const l of i)this.deepEqual(e[l],n[l])||r.push(l);return r}getChangeDetectionInfo(){const e=Array.from(this.executionDetails.values()),n={totalExecutions:e.length,executionsWithStateChange:e.filter(r=>r.stateChanges.length>0).length,executionsWithoutStateChange:e.filter(r=>r.stateChanges.length===0&&r.exitReason==="normal").length,earlyReturnCount:e.filter(r=>r.exitReason==="early-return-condition"||r.exitReason==="early-return-validation").length,alertCount:this.changeAlerts.length,alertsByType:this.getAlertsByType()};return{executionDetails:e,stateChangeHistory:[...this.stateChangeHistory],dataSourceChangeHistory:[...this.dataSourceChangeHistory],alerts:[...this.changeAlerts],stats:n,timestamp:Date.now()}}getAlertsByType(){const e={"no-state-change":0,"no-datasource-change":0,"expected-not-fulfilled":0,"object-reference-same":0,"early-return-detected":0,"async-timing-issue":0};for(const n of this.changeAlerts)e[n.type]++;return e}clearChangeDetectionData(){this.executionDetails.clear(),this.stateChangeHistory=[],this.dataSourceChangeHistory=[],this.changeAlerts=[],this.changeExpectations.clear(),this.executionIdCounter=0,this.stateChangeIdCounter=0,this.alertIdCounter=0}getRecentAlerts(e=10,n){let r=[...this.changeAlerts];return n&&(r=r.filter(i=>i.severity===n)),r.slice(-e)}getHandlerExecutions(e,n=10){return Array.from(this.executionDetails.values()).filter(i=>i.handlerName===e).slice(-n)}findExecutionInStack(e){return this.sequenceExecutionStack.find(n=>n.sequenceId===e)}startSequenceExecution(e){if(!this.config.enabled)return"";const n=`seq_${++this.sequenceIdCounter}_${Date.now()}`,r={sequenceId:n,startTime:Date.now(),totalDuration:0,trigger:e,actions:[],status:"running"};return this.sequenceExecutionStack.push(r),n}captureSequenceActionBefore(e,n,r,i,l){if(!this.config.enabled)return;const c=this.findExecutionInStack(e);if(!c)return;const d={index:n,handler:r,params:this.safeClone(i),stateBeforeAction:{_global:this.safeClone(l._global),_local:this.safeClone(l._local),_isolated:l._isolated?this.safeClone(l._isolated):void 0},stateAfterAction:{_global:{},_local:{}},duration:0,status:"success"};c.actions.push(d)}captureSequenceActionAfter(e,n,r,i,l,c){if(!this.config.enabled)return;const d=this.findExecutionInStack(e);if(!d)return;const f=d.actions.find(m=>m.index===n);if(!f)return;f.stateAfterAction={_global:this.safeClone(r._global),_local:this.safeClone(r._local),_isolated:r._isolated?this.safeClone(r._isolated):void 0},f.duration=i,f.result=this.safeClone(l),f.stateDiff={global:this.computeStateDiff(f.stateBeforeAction._global,f.stateAfterAction._global),local:this.computeStateDiff(f.stateBeforeAction._local,f.stateAfterAction._local)},f.stateBeforeAction._isolated&&f.stateAfterAction._isolated&&(f.stateDiff.isolated=this.computeStateDiff(f.stateBeforeAction._isolated,f.stateAfterAction._isolated));const h=window.__g7PendingLocalState;h&&(f.pendingState=this.safeClone(h)),c&&(f.status="error",f.error={name:c.name,message:c.message,stack:c.stack})}endSequenceExecution(e,n){if(!this.config.enabled)return;const r=this.sequenceExecutionStack.findIndex(l=>l.sequenceId===e);if(r===-1)return;const i=this.sequenceExecutionStack[r];if(i.endTime=Date.now(),i.totalDuration=i.endTime-i.startTime,n){i.status="error",i.error={name:n.name,message:n.message,stack:n.stack};const l=i.actions.find(c=>c.status==="error");l&&(i.failedAtIndex=l.index)}else i.status="success";this.sequenceExecutions.push(i),this.sequenceExecutions.length>this.maxSequenceExecutions&&this.sequenceExecutions.shift(),this.sequenceExecutionStack.splice(r,1)}computeStateDiff(e,n){const r=[],i=[],l=[],c=new Set(Object.keys(e)),d=new Set(Object.keys(n));for(const f of d)c.has(f)||r.push(f);for(const f of c)d.has(f)||i.push(f);for(const f of c)if(d.has(f)){const h=e[f],m=n[f];JSON.stringify(h)!==JSON.stringify(m)&&l.push({path:f,oldValue:h,newValue:m})}return{added:r,removed:i,changed:l}}getSequenceTrackingInfo(){const e=this.getSequenceStats(),n=this.sequenceExecutionStack.length>0?this.sequenceExecutionStack[this.sequenceExecutionStack.length-1]:void 0;return{executions:[...this.sequenceExecutions],currentExecution:n,stats:e}}getSequenceStats(){const e=this.sequenceExecutions,n=e.length,r=e.filter(h=>h.status==="success").length,i=e.filter(h=>h.status==="error").length,l=e.reduce((h,m)=>h+m.actions.length,0),c=n>0?e.reduce((h,m)=>h+m.totalDuration,0)/n:0,d={};for(const h of e)for(const m of h.actions)d[m.handler]=(d[m.handler]||0)+1;const f=Object.entries(d).sort(([,h],[,m])=>m-h).slice(0,5).map(([h,m])=>({handler:h,count:m}));return{totalExecutions:n,successCount:r,errorCount:i,totalActions:l,avgDuration:c,topHandlers:f}}clearSequenceData(){this.sequenceExecutions=[],this.sequenceExecutionStack=[],this.sequenceIdCounter=0}getSequenceExecution(e){const n=this.findExecutionInStack(e);return n||this.sequenceExecutions.find(r=>r.sequenceId===e)}getRecentSequences(e=10){return this.sequenceExecutions.slice(-e)}registerStateCaptureForHandler(e,n,r){if(!this.config.enabled)return;const i=new Map,l=Date.now();for(const c of n)i.set(c,{value:this.safeClone(r[c]),capturedAt:l});this.stateCaptureRegistry.set(e,i)}detectStaleClosure(e,n,r,i,l){if(!this.config.enabled)return[];const c=this.stateCaptureRegistry.get(e);if(!c)return[];const d=Date.now(),f=[];for(const[h,m]of c){const y=this.getValueByPath(r,h),S=d-m.capturedAt;if(!this.isDeepEqual(m.value,y)&&S>0){const v=this.createStaleClosureWarning(i,n,h,m.value,m.capturedAt,y,d,S,l);f.push(v),this.addStaleClosureWarning(v)}}return this.stateCaptureRegistry.delete(e),f}trackStaleClosureWarning(e){if(!this.config.enabled)return;const n=Date.now(),r=this.createStaleClosureWarning(e.type,e.location,e.capturedPath,e.capturedValue,e.capturedAt,e.currentValue,n,n-e.capturedAt,e.actionId,e.stackTrace);this.addStaleClosureWarning(r)}createStaleClosureWarning(e,n,r,i,l,c,d,f,h,m){const y=this.getStaleClosureSeverity(e,f),{description:S,suggestion:v,docLink:_}=this.getStaleClosureMessages(e,r,f);return{id:`stale_${++this.staleClosureIdCounter}_${Date.now()}`,timestamp:Date.now(),type:e,location:n,capturedState:{path:r,capturedValue:this.safeClone(i),capturedAt:l},currentState:{path:r,currentValue:this.safeClone(c),retrievedAt:d},timeDiff:f,severity:y,description:S,suggestion:v,docLink:_,actionId:h,stackTrace:m}}getStaleClosureSeverity(e,n){if(n>5e3)return"error";if(n>1e3)return"warning";switch(e){case"async-state-capture":case"sequence-state-mismatch":return"warning";case"callback-state-capture":case"timeout-state-capture":return"info";case"event-handler-stale":return"warning";default:return"info"}}getStaleClosureMessages(e,n,r){const i=r<1e3?`${r}ms`:`${(r/1e3).toFixed(1)}s`;switch(e){case"async-state-capture":return{description:`await 후 ${i} 경과 시점에 '${n}' 상태가 변경됨. 캡처된 상태 대신 최신 상태를 사용해야 함`,suggestion:"await 이후에는 G7Core.state.get()으로 최신 상태를 다시 조회하거나, useRef + getter 패턴을 사용하세요",docLink:"troubleshooting-state-closure.md"};case"callback-state-capture":return{description:`콜백에서 ${i} 전에 캡처된 '${n}' 상태를 사용 중. 최신 상태와 다름`,suggestion:"콜백에서 상태를 참조할 때는 stateRef.current 패턴 또는 G7Core.state.get()를 사용하세요",docLink:"troubleshooting-state-closure.md"};case"timeout-state-capture":return{description:`setTimeout/setInterval 콜백에서 '${n}' 상태가 ${i} 전 값 사용 중`,suggestion:"타이머 콜백 내에서는 G7Core.state.get()으로 최신 상태를 조회하세요",docLink:"troubleshooting-state-closure.md"};case"sequence-state-mismatch":return{description:`sequence 내 '${n}' 상태가 이전 액션 결과와 불일치. context.state 대신 캡처된 값 사용 의심`,suggestion:"sequence 내에서는 context.state 또는 $prev를 사용하여 최신 상태를 참조하세요",docLink:"troubleshooting-state-setstate.md"};case"event-handler-stale":return{description:`이벤트 핸들러에서 ${i} 전에 바인딩된 '${n}' 상태 사용 중`,suggestion:"이벤트 핸들러에서 상태를 참조할 때는 useRef 패턴 또는 G7Core.state.get()를 사용하세요",docLink:"troubleshooting-state-closure.md"};default:return{description:`'${n}' 상태에서 stale closure 감지됨 (${i} 경과)`,suggestion:"상태 참조 시 최신 값을 사용하는지 확인하세요"}}}addStaleClosureWarning(e){this.staleClosureWarnings.push(e),this.staleClosureWarnings.length>this.maxStaleClosureWarnings&&this.staleClosureWarnings.shift()}getValueByPath(e,n){const r=n.split(".");let i=e;for(const l of r){if(i==null)return;i=i[l]}return i}isDeepEqual(e,n){if(e===n)return!0;if(e===null||n===null)return e===n;if(typeof e!=typeof n)return!1;if(typeof e!="object")return e===n;try{return JSON.stringify(e)===JSON.stringify(n)}catch{return!1}}getStaleClosureTrackingInfo(){const e=this.getStaleClosureStats();return{warnings:[...this.staleClosureWarnings],stats:e,timestamp:Date.now()}}getStaleClosureStats(){const e=this.staleClosureWarnings,n={"async-state-capture":0,"callback-state-capture":0,"timeout-state-capture":0,"sequence-state-mismatch":0,"event-handler-stale":0};for(const f of e)n[f.type]++;const r={info:0,warning:0,error:0};for(const f of e)r[f.severity]++;const i={};for(const f of e)i[f.location]=(i[f.location]||0)+1;const l=Object.entries(i).sort(([,f],[,h])=>h-f).slice(0,5).map(([f,h])=>({location:f,count:h})),c={};for(const f of e)c[f.capturedState.path]=(c[f.capturedState.path]||0)+1;const d=Object.entries(c).sort(([,f],[,h])=>h-f).slice(0,5).map(([f,h])=>({path:f,count:h}));return{totalWarnings:e.length,warningsByType:n,warningsBySeverity:r,topLocations:l,topAffectedPaths:d}}clearStaleClosureData(){this.staleClosureWarnings=[],this.staleClosureIdCounter=0,this.stateCaptureRegistry.clear()}getRecentStaleClosureWarnings(e=10,n){let r=[...this.staleClosureWarnings];return n&&(r=r.filter(i=>i.severity===n)),r.slice(-e)}safeClone(e){if(e==null||typeof e!="object")return e;try{return JSON.parse(JSON.stringify(e))}catch{if(Array.isArray(e))return e.map(r=>{try{return JSON.parse(JSON.stringify(r))}catch{return"[Unserializable]"}});const n={};for(const r of Object.keys(e))try{n[r]=JSON.parse(JSON.stringify(e[r]))}catch{n[r]="[Unserializable]"}return n}}};M(Ti,"instance");let Ia=Ti;const Vn=dt("LayoutLoader");class xr extends Error{constructor(n,r,i){super(n);M(this,"code");M(this,"details");this.code=r,this.details=i,this.name="LayoutLoaderError"}}class Vf{constructor(e){M(this,"componentRegistry");M(this,"currentLayout",null);M(this,"layoutCache",new Map);M(this,"cacheVersion",0);this.componentRegistry=e}setCacheVersion(e){this.cacheVersion!==e&&(Vn.log("Cache version updated:",this.cacheVersion,"->",e),this.cacheVersion=e,this.layoutCache.clear())}getCacheVersion(){return this.cacheVersion}async loadLayout(e,n){const r=`${e}:${n}`;if(this.layoutCache.has(r)){Vn.log("Loading layout from cache:",n);const l=await this.layoutCache.get(r),c=JSON.parse(JSON.stringify(l));return this.currentLayout=c,Ia.getInstance().trackLayoutLoad(n,e,c,"cache"),c}const i=this.fetchLayout(e,n);return this.layoutCache.set(r,i),i.catch(()=>{this.layoutCache.get(r)===i&&this.layoutCache.delete(r)}),i}async fetchLayout(e,n,r=!1){try{const i=this.cacheVersion>0?this.cacheVersion:null;let l;if(n.startsWith("__preview__/")){const S=n.replace("__preview__/","");l=jr(`/api/layouts/preview/${S}`,"json",i)}else l=jr(`/api/layouts/${e}/${n}`,"json",i);Vn.log("Fetching layout from API:",l);const c=zr(),d=r?null:c.getToken(),f={Accept:"application/json"};d&&(f.Authorization=`Bearer ${d}`);const h=await $d(l,{init:{headers:f},label:`layout: ${n}`});let m;try{m=await h.json()}catch{m=null}if(!h.ok){if(h.status===401&&!r&&d){Vn.log("Token invalid, removing and retrying without token"),c.removeToken();try{return await this.fetchLayout(e,n,!0)}catch(v){throw v instanceof xr&&v.details?.status===401?new xr(v.message,v.code,{...v.details,hadToken:!0}):v}}const S=m?.message||m?.error;throw new xr(`Failed to fetch layout: ${h.status} ${h.statusText}`,"FETCH_FAILED",{status:h.status,statusText:h.statusText,url:l,apiMessage:S})}const y=m.data||m;return this.validateLayoutData(y),this.currentLayout=y,Ia.getInstance().trackLayoutLoad(n,e,y,"api"),Vn.log("Layout fetched and cached successfully:",y.layout_name),y}catch(i){const l=`${e}:${n}`;throw this.layoutCache.delete(l),i instanceof xr?i:new xr("Failed to load layout","LOAD_FAILED",{originalError:i})}}prefetchLayout(e,n){return this.loadLayout(e,n)}validateLayoutData(e){if(!e.version)throw new xr("Layout data missing required field: version","VALIDATION_FAILED",{field:"version"});if(!e.layout_name)throw new xr("Layout data missing required field: layout_name","VALIDATION_FAILED",{field:"layout_name"});if(!Array.isArray(e.components))throw new xr('Layout data field "components" must be an array',"VALIDATION_FAILED",{field:"components",value:e.components});Vn.log("Layout data validation passed")}renderLayout(e,n){try{const r=n||this.currentLayout;if(!r)throw new xr("No layout data to render","NO_LAYOUT_DATA");Vn.log("Rendering layout:",r.layout_name),e.innerHTML="",this.renderComponents(e,r.components),Vn.log("Layout rendered successfully")}catch(r){Vn.error("Render error:",r),this.renderErrorState(e,r)}}renderComponents(e,n){for(const r of n){const i=this.renderComponent(r);i&&e.appendChild(i)}}renderComponent(e){try{if(!this.componentRegistry.getComponent(e.type))return Vn.warn(`Component not found: ${e.type}`),this.createPlaceholderElement(e.type);const r=document.createElement("div");return r.setAttribute("data-component",e.type),e.props&&Object.entries(e.props).forEach(([i,l])=>{r.setAttribute(`data-prop-${i}`,JSON.stringify(l))}),e.children&&e.children.length>0?this.renderComponents(r,e.children):e.text&&(r.textContent=e.text),r}catch(n){return Vn.error(`Error rendering component ${e.type}:`,n),this.createErrorElement(e.type,n)}}createPlaceholderElement(e){const n=document.createElement("div");return n.className="component-placeholder",n.setAttribute("data-component-type",e),n.innerHTML=` + `},WE={onDragStart(s){let{active:e}=s;return"Picked up draggable item "+e.id+"."},onDragOver(s){let{active:e,over:n}=s;return n?"Draggable item "+e.id+" was moved over droppable area "+n.id+".":"Draggable item "+e.id+" is no longer over a droppable area."},onDragEnd(s){let{active:e,over:n}=s;return n?"Draggable item "+e.id+" was dropped over droppable area "+n.id:"Draggable item "+e.id+" was dropped."},onDragCancel(s){let{active:e}=s;return"Dragging was cancelled. Draggable item "+e.id+" was dropped."}};function YE(s){let{announcements:e=WE,container:n,hiddenTextDescribedById:r,screenReaderInstructions:i=KE}=s;const{announce:l,announcement:c}=GE(),d=Lo("DndLiveRegion"),[f,h]=N.useState(!1);if(N.useEffect(()=>{h(!0)},[]),FE(N.useMemo(()=>({onDragStart(y){let{active:S}=y;l(e.onDragStart({active:S}))},onDragMove(y){let{active:S,over:v}=y;e.onDragMove&&l(e.onDragMove({active:S,over:v}))},onDragOver(y){let{active:S,over:v}=y;l(e.onDragOver({active:S,over:v}))},onDragEnd(y){let{active:S,over:v}=y;l(e.onDragEnd({active:S,over:v}))},onDragCancel(y){let{active:S,over:v}=y;l(e.onDragCancel({active:S,over:v}))}}),[l,e])),!f)return null;const m=Ye.createElement(Ye.Fragment,null,Ye.createElement(BE,{id:r,value:i.draggable}),Ye.createElement(qE,{id:d,announcement:c}));return n?Ma.createPortal(m,n):m}var nn;(function(s){s.DragStart="dragStart",s.DragMove="dragMove",s.DragEnd="dragEnd",s.DragCancel="dragCancel",s.DragOver="dragOver",s.RegisterDroppable="registerDroppable",s.SetDroppableDisabled="setDroppableDisabled",s.UnregisterDroppable="unregisterDroppable"})(nn||(nn={}));function wc(){}function oy(s,e){return N.useMemo(()=>({sensor:s,options:e??{}}),[s,e])}function XE(){for(var s=arguments.length,e=new Array(s),n=0;n[...e].filter(r=>r!=null),[...e])}const _r=Object.freeze({x:0,y:0});function ly(s,e){return Math.sqrt(Math.pow(s.x-e.x,2)+Math.pow(s.y-e.y,2))}function cy(s,e){let{data:{value:n}}=s,{data:{value:r}}=e;return n-r}function JE(s,e){let{data:{value:n}}=s,{data:{value:r}}=e;return r-n}function uy(s){let{left:e,top:n,height:r,width:i}=s;return[{x:e,y:n},{x:e+i,y:n},{x:e,y:n+r},{x:e+i,y:n+r}]}function dy(s,e){if(!s||s.length===0)return null;const[n]=s;return n[e]}function fy(s,e,n){return e===void 0&&(e=s.left),n===void 0&&(n=s.top),{x:e+s.width*.5,y:n+s.height*.5}}const QE=s=>{let{collisionRect:e,droppableRects:n,droppableContainers:r}=s;const i=fy(e,e.left,e.top),l=[];for(const c of r){const{id:d}=c,f=n.get(d);if(f){const h=ly(fy(f),i);l.push({id:d,data:{droppableContainer:c,value:h}})}}return l.sort(cy)},ZE=s=>{let{collisionRect:e,droppableRects:n,droppableContainers:r}=s;const i=uy(e),l=[];for(const c of r){const{id:d}=c,f=n.get(d);if(f){const h=uy(f),m=i.reduce((S,v,_)=>S+ly(h[_],v),0),y=Number((m/4).toFixed(4));l.push({id:d,data:{droppableContainer:c,value:y}})}}return l.sort(cy)};function e_(s,e){const n=Math.max(e.top,s.top),r=Math.max(e.left,s.left),i=Math.min(e.left+e.width,s.left+s.width),l=Math.min(e.top+e.height,s.top+s.height),c=i-r,d=l-n;if(r{let{collisionRect:e,droppableRects:n,droppableContainers:r}=s;const i=[];for(const l of r){const{id:c}=l,d=n.get(c);if(d){const f=e_(d,e);f>0&&i.push({id:c,data:{droppableContainer:l,value:f}})}}return i.sort(JE)};function n_(s,e,n){return{...s,scaleX:e&&n?e.width/n.width:1,scaleY:e&&n?e.height/n.height:1}}function hy(s,e){return s&&e?{x:s.left-e.left,y:s.top-e.top}:_r}function r_(s){return function(n){for(var r=arguments.length,i=new Array(r>1?r-1:0),l=1;l({...c,top:c.top+s*d.y,bottom:c.bottom+s*d.y,left:c.left+s*d.x,right:c.right+s*d.x}),{...n})}}const a_=r_(1);function i_(s){if(s.startsWith("matrix3d(")){const e=s.slice(9,-1).split(/, /);return{x:+e[12],y:+e[13],scaleX:+e[0],scaleY:+e[5]}}else if(s.startsWith("matrix(")){const e=s.slice(7,-1).split(/, /);return{x:+e[4],y:+e[5],scaleX:+e[0],scaleY:+e[3]}}return null}function s_(s,e,n){const r=i_(e);if(!r)return s;const{scaleX:i,scaleY:l,x:c,y:d}=r,f=s.left-c-(1-i)*parseFloat(n),h=s.top-d-(1-l)*parseFloat(n.slice(n.indexOf(" ")+1)),m=i?s.width/i:s.width,y=l?s.height/l:s.height;return{width:m,height:y,top:h,right:f+m,bottom:h+y,left:f}}const o_={ignoreTransform:!1};function ys(s,e){e===void 0&&(e=o_);let n=s.getBoundingClientRect();if(e.ignoreTransform){const{transform:h,transformOrigin:m}=Mn(s).getComputedStyle(s);h&&(n=s_(n,h,m))}const{top:r,left:i,width:l,height:c,bottom:d,right:f}=n;return{top:r,left:i,width:l,height:c,bottom:d,right:f}}function py(s){return ys(s,{ignoreTransform:!0})}function l_(s){const e=s.innerWidth,n=s.innerHeight;return{top:0,left:0,right:e,bottom:n,width:e,height:n}}function c_(s,e){return e===void 0&&(e=Mn(s).getComputedStyle(s)),e.position==="fixed"}function u_(s,e){e===void 0&&(e=Mn(s).getComputedStyle(s));const n=/(auto|scroll|overlay)/;return["overflow","overflowX","overflowY"].some(i=>{const l=e[i];return typeof l=="string"?n.test(l):!1})}function Cc(s,e){const n=[];function r(i){if(e!=null&&n.length>=e||!i)return n;if(Tf(i)&&i.scrollingElement!=null&&!n.includes(i.scrollingElement))return n.push(i.scrollingElement),n;if(!Ro(i)||ry(i)||n.includes(i))return n;const l=Mn(s).getComputedStyle(i);return i!==s&&u_(i,l)&&n.push(i),c_(i,l)?n:r(i.parentNode)}return s?r(s):n}function gy(s){const[e]=Cc(s,1);return e??null}function $f(s){return!vc||!s?null:ps(s)?s:xf(s)?Tf(s)||s===gs(s).scrollingElement?window:Ro(s)?s:null:null}function my(s){return ps(s)?s.scrollX:s.scrollLeft}function yy(s){return ps(s)?s.scrollY:s.scrollTop}function Mf(s){return{x:my(s),y:yy(s)}}var dn;(function(s){s[s.Forward=1]="Forward",s[s.Backward=-1]="Backward"})(dn||(dn={}));function by(s){return!vc||!s?!1:s===document.scrollingElement}function vy(s){const e={x:0,y:0},n=by(s)?{height:window.innerHeight,width:window.innerWidth}:{height:s.clientHeight,width:s.clientWidth},r={x:s.scrollWidth-n.width,y:s.scrollHeight-n.height},i=s.scrollTop<=e.y,l=s.scrollLeft<=e.x,c=s.scrollTop>=r.y,d=s.scrollLeft>=r.x;return{isTop:i,isLeft:l,isBottom:c,isRight:d,maxScroll:r,minScroll:e}}const d_={x:.2,y:.2};function f_(s,e,n,r,i){let{top:l,left:c,right:d,bottom:f}=n;r===void 0&&(r=10),i===void 0&&(i=d_);const{isTop:h,isBottom:m,isLeft:y,isRight:S}=vy(s),v={x:0,y:0},_={x:0,y:0},x={height:e.height*i.y,width:e.width*i.x};return!h&&l<=e.top+x.height?(v.y=dn.Backward,_.y=r*Math.abs((e.top+x.height-l)/x.height)):!m&&f>=e.bottom-x.height&&(v.y=dn.Forward,_.y=r*Math.abs((e.bottom-x.height-f)/x.height)),!S&&d>=e.right-x.width?(v.x=dn.Forward,_.x=r*Math.abs((e.right-x.width-d)/x.width)):!y&&c<=e.left+x.width&&(v.x=dn.Backward,_.x=r*Math.abs((e.left+x.width-c)/x.width)),{direction:v,speed:_}}function h_(s){if(s===document.scrollingElement){const{innerWidth:l,innerHeight:c}=window;return{top:0,left:0,right:l,bottom:c,width:l,height:c}}const{top:e,left:n,right:r,bottom:i}=s.getBoundingClientRect();return{top:e,left:n,right:r,bottom:i,width:s.clientWidth,height:s.clientHeight}}function Sy(s){return s.reduce((e,n)=>ms(e,Mf(n)),_r)}function p_(s){return s.reduce((e,n)=>e+my(n),0)}function g_(s){return s.reduce((e,n)=>e+yy(n),0)}function m_(s,e){if(e===void 0&&(e=ys),!s)return;const{top:n,left:r,bottom:i,right:l}=e(s);gy(s)&&(i<=0||l<=0||n>=window.innerHeight||r>=window.innerWidth)&&s.scrollIntoView({block:"center",inline:"center"})}const y_=[["x",["left","right"],p_],["y",["top","bottom"],g_]];class Nf{constructor(e,n){this.rect=void 0,this.width=void 0,this.height=void 0,this.top=void 0,this.bottom=void 0,this.right=void 0,this.left=void 0;const r=Cc(n),i=Sy(r);this.rect={...e},this.width=e.width,this.height=e.height;for(const[l,c,d]of y_)for(const f of c)Object.defineProperty(this,f,{get:()=>{const h=d(r),m=i[l]-h;return this.rect[f]+m},enumerable:!0});Object.defineProperty(this,"rect",{enumerable:!1})}}class No{constructor(e){this.target=void 0,this.listeners=[],this.removeAll=()=>{this.listeners.forEach(n=>{var r;return(r=this.target)==null?void 0:r.removeEventListener(...n)})},this.target=e}add(e,n,r){var i;(i=this.target)==null||i.addEventListener(e,n,r),this.listeners.push([e,n,r])}}function b_(s){const{EventTarget:e}=Mn(s);return s instanceof e?s:gs(s)}function If(s,e){const n=Math.abs(s.x),r=Math.abs(s.y);return typeof e=="number"?Math.sqrt(n**2+r**2)>e:"x"in e&&"y"in e?n>e.x&&r>e.y:"x"in e?n>e.x:"y"in e?r>e.y:!1}var ir;(function(s){s.Click="click",s.DragStart="dragstart",s.Keydown="keydown",s.ContextMenu="contextmenu",s.Resize="resize",s.SelectionChange="selectionchange",s.VisibilityChange="visibilitychange"})(ir||(ir={}));function wy(s){s.preventDefault()}function v_(s){s.stopPropagation()}var lt;(function(s){s.Space="Space",s.Down="ArrowDown",s.Right="ArrowRight",s.Left="ArrowLeft",s.Up="ArrowUp",s.Esc="Escape",s.Enter="Enter",s.Tab="Tab"})(lt||(lt={}));const Cy={start:[lt.Space,lt.Enter],cancel:[lt.Esc],end:[lt.Space,lt.Enter,lt.Tab]},S_=(s,e)=>{let{currentCoordinates:n}=e;switch(s.code){case lt.Right:return{...n,x:n.x+25};case lt.Left:return{...n,x:n.x-25};case lt.Down:return{...n,y:n.y+25};case lt.Up:return{...n,y:n.y-25}}};class jf{constructor(e){this.props=void 0,this.autoScrollEnabled=!1,this.referenceCoordinates=void 0,this.listeners=void 0,this.windowListeners=void 0,this.props=e;const{event:{target:n}}=e;this.props=e,this.listeners=new No(gs(n)),this.windowListeners=new No(Mn(n)),this.handleKeyDown=this.handleKeyDown.bind(this),this.handleCancel=this.handleCancel.bind(this),this.attach()}attach(){this.handleStart(),this.windowListeners.add(ir.Resize,this.handleCancel),this.windowListeners.add(ir.VisibilityChange,this.handleCancel),setTimeout(()=>this.listeners.add(ir.Keydown,this.handleKeyDown))}handleStart(){const{activeNode:e,onStart:n}=this.props,r=e.node.current;r&&m_(r),n(_r)}handleKeyDown(e){if(Of(e)){const{active:n,context:r,options:i}=this.props,{keyboardCodes:l=Cy,coordinateGetter:c=S_,scrollBehavior:d="smooth"}=i,{code:f}=e;if(l.end.includes(f)){this.handleEnd(e);return}if(l.cancel.includes(f)){this.handleCancel(e);return}const{collisionRect:h}=r.current,m=h?{x:h.left,y:h.top}:_r;this.referenceCoordinates||(this.referenceCoordinates=m);const y=c(e,{active:n,context:r.current,currentCoordinates:m});if(y){const S=$o(y,m),v={x:0,y:0},{scrollableAncestors:_}=r.current;for(const x of _){const A=e.code,{isTop:L,isRight:$,isLeft:k,isBottom:O,maxScroll:P,minScroll:G}=vy(x),B=h_(x),W={x:Math.min(A===lt.Right?B.right-B.width/2:B.right,Math.max(A===lt.Right?B.left:B.left+B.width/2,y.x)),y:Math.min(A===lt.Down?B.bottom-B.height/2:B.bottom,Math.max(A===lt.Down?B.top:B.top+B.height/2,y.y))},pe=A===lt.Right&&!$||A===lt.Left&&!k,Se=A===lt.Down&&!O||A===lt.Up&&!L;if(pe&&W.x!==y.x){const we=x.scrollLeft+S.x,Ue=A===lt.Right&&we<=P.x||A===lt.Left&&we>=G.x;if(Ue&&!S.y){x.scrollTo({left:we,behavior:d});return}Ue?v.x=x.scrollLeft-we:v.x=A===lt.Right?x.scrollLeft-P.x:x.scrollLeft-G.x,v.x&&x.scrollBy({left:-v.x,behavior:d});break}else if(Se&&W.y!==y.y){const we=x.scrollTop+S.y,Ue=A===lt.Down&&we<=P.y||A===lt.Up&&we>=G.y;if(Ue&&!S.x){x.scrollTo({top:we,behavior:d});return}Ue?v.y=x.scrollTop-we:v.y=A===lt.Down?x.scrollTop-P.y:x.scrollTop-G.y,v.y&&x.scrollBy({top:-v.y,behavior:d});break}}this.handleMove(e,ms($o(y,this.referenceCoordinates),v))}}}handleMove(e,n){const{onMove:r}=this.props;e.preventDefault(),r(n)}handleEnd(e){const{onEnd:n}=this.props;e.preventDefault(),this.detach(),n()}handleCancel(e){const{onCancel:n}=this.props;e.preventDefault(),this.detach(),n()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll()}}jf.activators=[{eventName:"onKeyDown",handler:(s,e,n)=>{let{keyboardCodes:r=Cy,onActivation:i}=e,{active:l}=n;const{code:c}=s.nativeEvent;if(r.start.includes(c)){const d=l.activatorNode.current;return d&&s.target!==d?!1:(s.preventDefault(),i?.({event:s.nativeEvent}),!0)}return!1}}];function Ey(s){return!!(s&&"distance"in s)}function _y(s){return!!(s&&"delay"in s)}class Hf{constructor(e,n,r){var i;r===void 0&&(r=b_(e.event.target)),this.props=void 0,this.events=void 0,this.autoScrollEnabled=!0,this.document=void 0,this.activated=!1,this.initialCoordinates=void 0,this.timeoutId=null,this.listeners=void 0,this.documentListeners=void 0,this.windowListeners=void 0,this.props=e,this.events=n;const{event:l}=e,{target:c}=l;this.props=e,this.events=n,this.document=gs(c),this.documentListeners=new No(this.document),this.listeners=new No(r),this.windowListeners=new No(Mn(c)),this.initialCoordinates=(i=Lf(l))!=null?i:_r,this.handleStart=this.handleStart.bind(this),this.handleMove=this.handleMove.bind(this),this.handleEnd=this.handleEnd.bind(this),this.handleCancel=this.handleCancel.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.removeTextSelection=this.removeTextSelection.bind(this),this.attach()}attach(){const{events:e,props:{options:{activationConstraint:n,bypassActivationConstraint:r}}}=this;if(this.listeners.add(e.move.name,this.handleMove,{passive:!1}),this.listeners.add(e.end.name,this.handleEnd),e.cancel&&this.listeners.add(e.cancel.name,this.handleCancel),this.windowListeners.add(ir.Resize,this.handleCancel),this.windowListeners.add(ir.DragStart,wy),this.windowListeners.add(ir.VisibilityChange,this.handleCancel),this.windowListeners.add(ir.ContextMenu,wy),this.documentListeners.add(ir.Keydown,this.handleKeydown),n){if(r!=null&&r({event:this.props.event,activeNode:this.props.activeNode,options:this.props.options}))return this.handleStart();if(_y(n)){this.timeoutId=setTimeout(this.handleStart,n.delay),this.handlePending(n);return}if(Ey(n)){this.handlePending(n);return}}this.handleStart()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll(),setTimeout(this.documentListeners.removeAll,50),this.timeoutId!==null&&(clearTimeout(this.timeoutId),this.timeoutId=null)}handlePending(e,n){const{active:r,onPending:i}=this.props;i(r,e,this.initialCoordinates,n)}handleStart(){const{initialCoordinates:e}=this,{onStart:n}=this.props;e&&(this.activated=!0,this.documentListeners.add(ir.Click,v_,{capture:!0}),this.removeTextSelection(),this.documentListeners.add(ir.SelectionChange,this.removeTextSelection),n(e))}handleMove(e){var n;const{activated:r,initialCoordinates:i,props:l}=this,{onMove:c,options:{activationConstraint:d}}=l;if(!i)return;const f=(n=Lf(e))!=null?n:_r,h=$o(i,f);if(!r&&d){if(Ey(d)){if(d.tolerance!=null&&If(h,d.tolerance))return this.handleCancel();if(If(h,d.distance))return this.handleStart()}if(_y(d)&&If(h,d.tolerance))return this.handleCancel();this.handlePending(d,h);return}e.cancelable&&e.preventDefault(),c(f)}handleEnd(){const{onAbort:e,onEnd:n}=this.props;this.detach(),this.activated||e(this.props.active),n()}handleCancel(){const{onAbort:e,onCancel:n}=this.props;this.detach(),this.activated||e(this.props.active),n()}handleKeydown(e){e.code===lt.Esc&&this.handleCancel()}removeTextSelection(){var e;(e=this.document.getSelection())==null||e.removeAllRanges()}}const w_={cancel:{name:"pointercancel"},move:{name:"pointermove"},end:{name:"pointerup"}};class zf extends Hf{constructor(e){const{event:n}=e,r=gs(n.target);super(e,w_,r)}}zf.activators=[{eventName:"onPointerDown",handler:(s,e)=>{let{nativeEvent:n}=s,{onActivation:r}=e;return!n.isPrimary||n.button!==0?!1:(r?.({event:n}),!0)}}];const C_={move:{name:"mousemove"},end:{name:"mouseup"}};var Uf;(function(s){s[s.RightClick=2]="RightClick"})(Uf||(Uf={}));class E_ extends Hf{constructor(e){super(e,C_,gs(e.event.target))}}E_.activators=[{eventName:"onMouseDown",handler:(s,e)=>{let{nativeEvent:n}=s,{onActivation:r}=e;return n.button===Uf.RightClick?!1:(r?.({event:n}),!0)}}];const Pf={cancel:{name:"touchcancel"},move:{name:"touchmove"},end:{name:"touchend"}};class __ extends Hf{constructor(e){super(e,Pf)}static setup(){return window.addEventListener(Pf.move.name,e,{capture:!1,passive:!1}),function(){window.removeEventListener(Pf.move.name,e)};function e(){}}}__.activators=[{eventName:"onTouchStart",handler:(s,e)=>{let{nativeEvent:n}=s,{onActivation:r}=e;const{touches:i}=n;return i.length>1?!1:(r?.({event:n}),!0)}}];var Io;(function(s){s[s.Pointer=0]="Pointer",s[s.DraggableRect=1]="DraggableRect"})(Io||(Io={}));var Ec;(function(s){s[s.TreeOrder=0]="TreeOrder",s[s.ReversedTreeOrder=1]="ReversedTreeOrder"})(Ec||(Ec={}));function A_(s){let{acceleration:e,activator:n=Io.Pointer,canScroll:r,draggingRect:i,enabled:l,interval:c=5,order:d=Ec.TreeOrder,pointerCoordinates:f,scrollableAncestors:h,scrollableAncestorRects:m,delta:y,threshold:S}=s;const v=T_({delta:y,disabled:!l}),[_,x]=jE(),A=N.useRef({x:0,y:0}),L=N.useRef({x:0,y:0}),$=N.useMemo(()=>{switch(n){case Io.Pointer:return f?{top:f.y,bottom:f.y,left:f.x,right:f.x}:null;case Io.DraggableRect:return i}},[n,i,f]),k=N.useRef(null),O=N.useCallback(()=>{const G=k.current;if(!G)return;const B=A.current.x*L.current.x,W=A.current.y*L.current.y;G.scrollBy(B,W)},[]),P=N.useMemo(()=>d===Ec.TreeOrder?[...h].reverse():h,[d,h]);N.useEffect(()=>{if(!l||!h.length||!$){x();return}for(const G of P){if(r?.(G)===!1)continue;const B=h.indexOf(G),W=m[B];if(!W)continue;const{direction:pe,speed:Se}=f_(G,W,$,e,S);for(const we of["x","y"])v[we][pe[we]]||(Se[we]=0,pe[we]=0);if(Se.x>0||Se.y>0){x(),k.current=G,_(O,c),A.current=Se,L.current=pe;return}}A.current={x:0,y:0},L.current={x:0,y:0},x()},[e,O,r,x,l,c,JSON.stringify($),JSON.stringify(v),_,h,P,m,JSON.stringify(S)])}const x_={x:{[dn.Backward]:!1,[dn.Forward]:!1},y:{[dn.Backward]:!1,[dn.Forward]:!1}};function T_(s){let{delta:e,disabled:n}=s;const r=Rf(e);return Oo(i=>{if(n||!r||!i)return x_;const l={x:Math.sign(e.x-r.x),y:Math.sign(e.y-r.y)};return{x:{[dn.Backward]:i.x[dn.Backward]||l.x===-1,[dn.Forward]:i.x[dn.Forward]||l.x===1},y:{[dn.Backward]:i.y[dn.Backward]||l.y===-1,[dn.Forward]:i.y[dn.Forward]||l.y===1}}},[n,e,r])}function k_(s,e){const n=e!=null?s.get(e):void 0,r=n?n.node.current:null;return Oo(i=>{var l;return e==null?null:(l=r??i)!=null?l:null},[r,e])}function R_(s,e){return N.useMemo(()=>s.reduce((n,r)=>{const{sensor:i}=r,l=i.activators.map(c=>({eventName:c.eventName,handler:e(c.handler,r)}));return[...n,...l]},[]),[s,e])}var jo;(function(s){s[s.Always=0]="Always",s[s.BeforeDragging=1]="BeforeDragging",s[s.WhileDragging=2]="WhileDragging"})(jo||(jo={}));var Bf;(function(s){s.Optimized="optimized"})(Bf||(Bf={}));const Ay=new Map;function D_(s,e){let{dragging:n,dependencies:r,config:i}=e;const[l,c]=N.useState(null),{frequency:d,measure:f,strategy:h}=i,m=N.useRef(s),y=A(),S=Do(y),v=N.useCallback(function(L){L===void 0&&(L=[]),!S.current&&c($=>$===null?L:$.concat(L.filter(k=>!$.includes(k))))},[S]),_=N.useRef(null),x=Oo(L=>{if(y&&!n)return Ay;if(!L||L===Ay||m.current!==s||l!=null){const $=new Map;for(let k of s){if(!k)continue;if(l&&l.length>0&&!l.includes(k.id)&&k.rect.current){$.set(k.id,k.rect.current);continue}const O=k.node.current,P=O?new Nf(f(O),O):null;k.rect.current=P,P&&$.set(k.id,P)}return $}return L},[s,l,n,y,f]);return N.useEffect(()=>{m.current=s},[s]),N.useEffect(()=>{y||v()},[n,y]),N.useEffect(()=>{l&&l.length>0&&c(null)},[JSON.stringify(l)]),N.useEffect(()=>{y||typeof d!="number"||_.current!==null||(_.current=setTimeout(()=>{v(),_.current=null},d))},[d,y,v,...r]),{droppableRects:x,measureDroppableContainers:v,measuringScheduled:l!=null};function A(){switch(h){case jo.Always:return!1;case jo.BeforeDragging:return n;default:return!n}}}function xy(s,e){return Oo(n=>s?n||(typeof e=="function"?e(s):s):null,[e,s])}function O_(s,e){return xy(s,e)}function L_(s){let{callback:e,disabled:n}=s;const r=kf(e),i=N.useMemo(()=>{if(n||typeof window>"u"||typeof window.MutationObserver>"u")return;const{MutationObserver:l}=window;return new l(r)},[r,n]);return N.useEffect(()=>()=>i?.disconnect(),[i]),i}function _c(s){let{callback:e,disabled:n}=s;const r=kf(e),i=N.useMemo(()=>{if(n||typeof window>"u"||typeof window.ResizeObserver>"u")return;const{ResizeObserver:l}=window;return new l(r)},[n]);return N.useEffect(()=>()=>i?.disconnect(),[i]),i}function $_(s){return new Nf(ys(s),s)}function Ty(s,e,n){e===void 0&&(e=$_);const[r,i]=N.useState(null);function l(){i(f=>{if(!s)return null;if(s.isConnected===!1){var h;return(h=f??n)!=null?h:null}const m=e(s);return JSON.stringify(f)===JSON.stringify(m)?f:m})}const c=L_({callback(f){if(s)for(const h of f){const{type:m,target:y}=h;if(m==="childList"&&y instanceof HTMLElement&&y.contains(s)){l();break}}}}),d=_c({callback:l});return Pr(()=>{l(),s?(d?.observe(s),c?.observe(document.body,{childList:!0,subtree:!0})):(d?.disconnect(),c?.disconnect())},[s]),r}function M_(s){const e=xy(s);return hy(s,e)}const ky=[];function N_(s){const e=N.useRef(s),n=Oo(r=>s?r&&r!==ky&&s&&e.current&&s.parentNode===e.current.parentNode?r:Cc(s):ky,[s]);return N.useEffect(()=>{e.current=s},[s]),n}function I_(s){const[e,n]=N.useState(null),r=N.useRef(s),i=N.useCallback(l=>{const c=$f(l.target);c&&n(d=>d?(d.set(c,Mf(c)),new Map(d)):null)},[]);return N.useEffect(()=>{const l=r.current;if(s!==l){c(l);const d=s.map(f=>{const h=$f(f);return h?(h.addEventListener("scroll",i,{passive:!0}),[h,Mf(h)]):null}).filter(f=>f!=null);n(d.length?new Map(d):null),r.current=s}return()=>{c(s),c(l)};function c(d){d.forEach(f=>{const h=$f(f);h?.removeEventListener("scroll",i)})}},[i,s]),N.useMemo(()=>s.length?e?Array.from(e.values()).reduce((l,c)=>ms(l,c),_r):Sy(s):_r,[s,e])}function Ry(s,e){e===void 0&&(e=[]);const n=N.useRef(null);return N.useEffect(()=>{n.current=null},e),N.useEffect(()=>{const r=s!==_r;r&&!n.current&&(n.current=s),!r&&n.current&&(n.current=null)},[s]),n.current?$o(s,n.current):_r}function j_(s){N.useEffect(()=>{if(!vc)return;const e=s.map(n=>{let{sensor:r}=n;return r.setup==null?void 0:r.setup()});return()=>{for(const n of e)n?.()}},s.map(e=>{let{sensor:n}=e;return n}))}function H_(s,e){return N.useMemo(()=>s.reduce((n,r)=>{let{eventName:i,handler:l}=r;return n[i]=c=>{l(c,e)},n},{}),[s,e])}function Dy(s){return N.useMemo(()=>s?l_(s):null,[s])}const Oy=[];function z_(s,e){e===void 0&&(e=ys);const[n]=s,r=Dy(n?Mn(n):null),[i,l]=N.useState(Oy);function c(){l(()=>s.length?s.map(f=>by(f)?r:new Nf(e(f),f)):Oy)}const d=_c({callback:c});return Pr(()=>{d?.disconnect(),c(),s.forEach(f=>d?.observe(f))},[s]),i}function U_(s){if(!s)return null;if(s.children.length>1)return s;const e=s.children[0];return Ro(e)?e:s}function P_(s){let{measure:e}=s;const[n,r]=N.useState(null),i=N.useCallback(h=>{for(const{target:m}of h)if(Ro(m)){r(y=>{const S=e(m);return y?{...y,width:S.width,height:S.height}:S});break}},[e]),l=_c({callback:i}),c=N.useCallback(h=>{const m=U_(h);l?.disconnect(),m&&l?.observe(m),r(m?e(m):null)},[e,l]),[d,f]=Sc(c);return N.useMemo(()=>({nodeRef:d,rect:n,setRef:f}),[n,d,f])}const B_=[{sensor:zf,options:{}},{sensor:jf,options:{}}],q_={current:{}},Ac={draggable:{measure:py},droppable:{measure:py,strategy:jo.WhileDragging,frequency:Bf.Optimized},dragOverlay:{measure:ys}};class Ho extends Map{get(e){var n;return e!=null&&(n=super.get(e))!=null?n:void 0}toArray(){return Array.from(this.values())}getEnabled(){return this.toArray().filter(e=>{let{disabled:n}=e;return!n})}getNodeFor(e){var n,r;return(n=(r=this.get(e))==null?void 0:r.node.current)!=null?n:void 0}}const G_={activatorEvent:null,active:null,activeNode:null,activeNodeRect:null,collisions:null,containerNodeRect:null,draggableNodes:new Map,droppableRects:new Map,droppableContainers:new Ho,over:null,dragOverlay:{nodeRef:{current:null},rect:null,setRef:wc},scrollableAncestors:[],scrollableAncestorRects:[],measuringConfiguration:Ac,measureDroppableContainers:wc,windowRect:null,measuringScheduled:!1},F_={activatorEvent:null,activators:[],active:null,activeNodeRect:null,ariaDescribedById:{draggable:""},dispatch:wc,draggableNodes:new Map,over:null,measureDroppableContainers:wc},xc=N.createContext(F_),Ly=N.createContext(G_);function V_(){return{draggable:{active:null,initialCoordinates:{x:0,y:0},nodes:new Map,translate:{x:0,y:0}},droppable:{containers:new Ho}}}function K_(s,e){switch(e.type){case nn.DragStart:return{...s,draggable:{...s.draggable,initialCoordinates:e.initialCoordinates,active:e.active}};case nn.DragMove:return s.draggable.active==null?s:{...s,draggable:{...s.draggable,translate:{x:e.coordinates.x-s.draggable.initialCoordinates.x,y:e.coordinates.y-s.draggable.initialCoordinates.y}}};case nn.DragEnd:case nn.DragCancel:return{...s,draggable:{...s.draggable,active:null,initialCoordinates:{x:0,y:0},translate:{x:0,y:0}}};case nn.RegisterDroppable:{const{element:n}=e,{id:r}=n,i=new Ho(s.droppable.containers);return i.set(r,n),{...s,droppable:{...s.droppable,containers:i}}}case nn.SetDroppableDisabled:{const{id:n,key:r,disabled:i}=e,l=s.droppable.containers.get(n);if(!l||r!==l.key)return s;const c=new Ho(s.droppable.containers);return c.set(n,{...l,disabled:i}),{...s,droppable:{...s.droppable,containers:c}}}case nn.UnregisterDroppable:{const{id:n,key:r}=e,i=s.droppable.containers.get(n);if(!i||r!==i.key)return s;const l=new Ho(s.droppable.containers);return l.delete(n),{...s,droppable:{...s.droppable,containers:l}}}default:return s}}function W_(s){let{disabled:e}=s;const{active:n,activatorEvent:r,draggableNodes:i}=N.useContext(xc),l=Rf(r),c=Rf(n?.id);return N.useEffect(()=>{if(!e&&!r&&l&&c!=null){if(!Of(l)||document.activeElement===l.target)return;const d=i.get(c);if(!d)return;const{activatorNode:f,node:h}=d;if(!f.current&&!h.current)return;requestAnimationFrame(()=>{for(const m of[f.current,h.current]){if(!m)continue;const y=UE(m);if(y){y.focus();break}}})}},[r,e,i,c,l]),null}function Y_(s,e){let{transform:n,...r}=e;return s!=null&&s.length?s.reduce((i,l)=>l({transform:i,...r}),n):n}function X_(s){return N.useMemo(()=>({draggable:{...Ac.draggable,...s?.draggable},droppable:{...Ac.droppable,...s?.droppable},dragOverlay:{...Ac.dragOverlay,...s?.dragOverlay}}),[s?.draggable,s?.droppable,s?.dragOverlay])}function J_(s){let{activeNode:e,measure:n,initialRect:r,config:i=!0}=s;const l=N.useRef(!1),{x:c,y:d}=typeof i=="boolean"?{x:i,y:i}:i;Pr(()=>{if(!c&&!d||!e){l.current=!1;return}if(l.current||!r)return;const h=e?.node.current;if(!h||h.isConnected===!1)return;const m=n(h),y=hy(m,r);if(c||(y.x=0),d||(y.y=0),l.current=!0,Math.abs(y.x)>0||Math.abs(y.y)>0){const S=gy(h);S&&S.scrollBy({top:y.y,left:y.x})}},[e,c,d,r,n])}const $y=N.createContext({..._r,scaleX:1,scaleY:1});var Na;(function(s){s[s.Uninitialized=0]="Uninitialized",s[s.Initializing=1]="Initializing",s[s.Initialized=2]="Initialized"})(Na||(Na={}));const Q_=N.memo(function(e){var n,r,i,l;let{id:c,accessibility:d,autoScroll:f=!0,children:h,sensors:m=B_,collisionDetection:y=t_,measuring:S,modifiers:v,..._}=e;const x=N.useReducer(K_,void 0,V_),[A,L]=x,[$,k]=VE(),[O,P]=N.useState(Na.Uninitialized),G=O===Na.Initialized,{draggable:{active:B,nodes:W,translate:pe},droppable:{containers:Se}}=A,we=B!=null?W.get(B):null,Ue=N.useRef({initial:null,translated:null}),Fe=N.useMemo(()=>{var he;return B!=null?{id:B,data:(he=we?.data)!=null?he:q_,rect:Ue}:null},[B,we]),qe=N.useRef(null),[wt,J]=N.useState(null),[fe,Le]=N.useState(null),Z=Do(_,Object.values(_)),ge=Lo("DndDescribedBy",c),H=N.useMemo(()=>Se.getEnabled(),[Se]),T=X_(S),{droppableRects:ce,measureDroppableContainers:de,measuringScheduled:be}=D_(H,{dragging:G,dependencies:[pe.x,pe.y],config:T.droppable}),ie=k_(W,B),xe=N.useMemo(()=>fe?Lf(fe):null,[fe]),_e=ve(),Te=O_(ie,T.draggable.measure);J_({activeNode:B!=null?W.get(B):null,config:_e.layoutShiftCompensation,initialRect:Te,measure:T.draggable.measure});const Me=Ty(ie,T.draggable.measure,Te),pt=Ty(ie?ie.parentElement:null),Ct=N.useRef({activatorEvent:null,active:null,activeNode:ie,collisionRect:null,collisions:null,droppableRects:ce,draggableNodes:W,draggingNode:null,draggingNodeRect:null,droppableContainers:Se,over:null,scrollableAncestors:[],scrollAdjustedTranslate:null}),Ot=Se.getNodeFor((n=Ct.current.over)==null?void 0:n.id),ht=P_({measure:T.dragOverlay.measure}),rn=(r=ht.nodeRef.current)!=null?r:ie,Kt=G?(i=ht.rect)!=null?i:Me:null,It=!!(ht.nodeRef.current&&ht.rect),Fr=M_(It?null:Me),hn=Dy(rn?Mn(rn):null),an=N_(G?Ot??ie:null),pn=z_(an),Wn=Y_(v,{transform:{x:pe.x-Fr.x,y:pe.y-Fr.y,scaleX:1,scaleY:1},activatorEvent:fe,active:Fe,activeNodeRect:Me,containerNodeRect:pt,draggingNodeRect:Kt,over:Ct.current.over,overlayNodeRect:ht.rect,scrollableAncestors:an,scrollableAncestorRects:pn,windowRect:hn}),Vr=xe?ms(xe,pe):null,qt=I_(an),ki=Ry(qt),la=Ry(qt,[Me]),gn=ms(Wn,ki),Dn=Kt?a_(Kt,Wn):null,nt=Fe&&Dn?y({active:Fe,collisionRect:Dn,droppableRects:ce,droppableContainers:H,pointerCoordinates:Vr}):null,In=dy(nt,"id"),[mn,ca]=N.useState(null),lr=It?Wn:ms(Wn,la),sn=n_(lr,(l=mn?.rect)!=null?l:null,Me),_n=N.useRef(null),on=N.useCallback((he,Ee)=>{let{sensor:Ae,options:Ve}=Ee;if(qe.current==null)return;const ke=W.get(qe.current);if(!ke)return;const Ne=he.nativeEvent,Re=new Ae({active:qe.current,activeNode:ke,event:Ne,options:Ve,context:Ct,onAbort(He){if(!W.get(He))return;const{onDragAbort:Ce}=Z.current,je={id:He};Ce?.(je),$({type:"onDragAbort",event:je})},onPending(He,Ge,Ce,je){if(!W.get(He))return;const{onDragPending:At}=Z.current,Mt={id:He,constraint:Ge,initialCoordinates:Ce,offset:je};At?.(Mt),$({type:"onDragPending",event:Mt})},onStart(He){const Ge=qe.current;if(Ge==null)return;const Ce=W.get(Ge);if(!Ce)return;const{onDragStart:je}=Z.current,tt={activatorEvent:Ne,active:{id:Ge,data:Ce.data,rect:Ue}};Ma.unstable_batchedUpdates(()=>{je?.(tt),P(Na.Initializing),L({type:nn.DragStart,initialCoordinates:He,active:Ge}),$({type:"onDragStart",event:tt}),J(_n.current),Le(Ne)})},onMove(He){L({type:nn.DragMove,coordinates:He})},onEnd:et(nn.DragEnd),onCancel:et(nn.DragCancel)});_n.current=Re;function et(He){return async function(){const{active:Ce,collisions:je,over:tt,scrollAdjustedTranslate:At}=Ct.current;let Mt=null;if(Ce&&At){const{cancelDrop:On}=Z.current;Mt={activatorEvent:Ne,active:Ce,collisions:je,delta:At,over:tt},He===nn.DragEnd&&typeof On=="function"&&await Promise.resolve(On(Mt))&&(He=nn.DragCancel)}qe.current=null,Ma.unstable_batchedUpdates(()=>{L({type:He}),P(Na.Uninitialized),ca(null),J(null),Le(null),_n.current=null;const On=He===nn.DragEnd?"onDragEnd":"onDragCancel";if(Mt){const jt=Z.current[On];jt?.(Mt),$({type:On,event:Mt})}})}}},[W]),F=N.useCallback((he,Ee)=>(Ae,Ve)=>{const ke=Ae.nativeEvent,Ne=W.get(Ve);if(qe.current!==null||!Ne||ke.dndKit||ke.defaultPrevented)return;const Re={active:Ne};he(Ae,Ee.options,Re)===!0&&(ke.dndKit={capturedBy:Ee.sensor},qe.current=Ve,on(Ae,Ee))},[W,on]),se=R_(m,F);j_(m),Pr(()=>{Me&&O===Na.Initializing&&P(Na.Initialized)},[Me,O]),N.useEffect(()=>{const{onDragMove:he}=Z.current,{active:Ee,activatorEvent:Ae,collisions:Ve,over:ke}=Ct.current;if(!Ee||!Ae)return;const Ne={active:Ee,activatorEvent:Ae,collisions:Ve,delta:{x:gn.x,y:gn.y},over:ke};Ma.unstable_batchedUpdates(()=>{he?.(Ne),$({type:"onDragMove",event:Ne})})},[gn.x,gn.y]),N.useEffect(()=>{const{active:he,activatorEvent:Ee,collisions:Ae,droppableContainers:Ve,scrollAdjustedTranslate:ke}=Ct.current;if(!he||qe.current==null||!Ee||!ke)return;const{onDragOver:Ne}=Z.current,Re=Ve.get(In),et=Re&&Re.rect.current?{id:Re.id,rect:Re.rect.current,data:Re.data,disabled:Re.disabled}:null,He={active:he,activatorEvent:Ee,collisions:Ae,delta:{x:ke.x,y:ke.y},over:et};Ma.unstable_batchedUpdates(()=>{ca(et),Ne?.(He),$({type:"onDragOver",event:He})})},[In]),Pr(()=>{Ct.current={activatorEvent:fe,active:Fe,activeNode:ie,collisionRect:Dn,collisions:nt,droppableRects:ce,draggableNodes:W,draggingNode:rn,draggingNodeRect:Kt,droppableContainers:Se,over:mn,scrollableAncestors:an,scrollAdjustedTranslate:gn},Ue.current={initial:Kt,translated:Dn}},[Fe,ie,nt,Dn,W,rn,Kt,ce,Se,mn,an,gn]),A_({..._e,delta:pe,draggingRect:Dn,pointerCoordinates:Vr,scrollableAncestors:an,scrollableAncestorRects:pn});const ue=N.useMemo(()=>({active:Fe,activeNode:ie,activeNodeRect:Me,activatorEvent:fe,collisions:nt,containerNodeRect:pt,dragOverlay:ht,draggableNodes:W,droppableContainers:Se,droppableRects:ce,over:mn,measureDroppableContainers:de,scrollableAncestors:an,scrollableAncestorRects:pn,measuringConfiguration:T,measuringScheduled:be,windowRect:hn}),[Fe,ie,Me,fe,nt,pt,ht,W,Se,ce,mn,de,an,pn,T,be,hn]),ee=N.useMemo(()=>({activatorEvent:fe,activators:se,active:Fe,activeNodeRect:Me,ariaDescribedById:{draggable:ge},dispatch:L,draggableNodes:W,over:mn,measureDroppableContainers:de}),[fe,se,Fe,Me,L,ge,W,mn,de]);return Ye.createElement(sy.Provider,{value:k},Ye.createElement(xc.Provider,{value:ee},Ye.createElement(Ly.Provider,{value:ue},Ye.createElement($y.Provider,{value:sn},h)),Ye.createElement(W_,{disabled:d?.restoreFocus===!1})),Ye.createElement(YE,{...d,hiddenTextDescribedById:ge}));function ve(){const he=wt?.autoScrollEnabled===!1,Ee=typeof f=="object"?f.enabled===!1:f===!1,Ae=G&&!he&&!Ee;return typeof f=="object"?{...f,enabled:Ae}:{enabled:Ae}}}),Z_=N.createContext(null),My="button",eA="Draggable";function tA(s){let{id:e,data:n,disabled:r=!1,attributes:i}=s;const l=Lo(eA),{activators:c,activatorEvent:d,active:f,activeNodeRect:h,ariaDescribedById:m,draggableNodes:y,over:S}=N.useContext(xc),{role:v=My,roleDescription:_="draggable",tabIndex:x=0}=i??{},A=f?.id===e,L=N.useContext(A?$y:Z_),[$,k]=Sc(),[O,P]=Sc(),G=H_(c,e),B=Do(n);Pr(()=>(y.set(e,{id:e,key:l,node:$,activatorNode:O,data:B}),()=>{const pe=y.get(e);pe&&pe.key===l&&y.delete(e)}),[y,e]);const W=N.useMemo(()=>({role:v,tabIndex:x,"aria-disabled":r,"aria-pressed":A&&v===My?!0:void 0,"aria-roledescription":_,"aria-describedby":m.draggable}),[r,v,x,A,_,m.draggable]);return{active:f,activatorEvent:d,activeNodeRect:h,attributes:W,isDragging:A,listeners:r?void 0:G,node:$,over:S,setNodeRef:k,setActivatorNodeRef:P,transform:L}}function nA(){return N.useContext(Ly)}const rA="Droppable",aA={timeout:25};function iA(s){let{data:e,disabled:n=!1,id:r,resizeObserverConfig:i}=s;const l=Lo(rA),{active:c,dispatch:d,over:f,measureDroppableContainers:h}=N.useContext(xc),m=N.useRef({disabled:n}),y=N.useRef(!1),S=N.useRef(null),v=N.useRef(null),{disabled:_,updateMeasurementsFor:x,timeout:A}={...aA,...i},L=Do(x??r),$=N.useCallback(()=>{if(!y.current){y.current=!0;return}v.current!=null&&clearTimeout(v.current),v.current=setTimeout(()=>{h(Array.isArray(L.current)?L.current:[L.current]),v.current=null},A)},[A]),k=_c({callback:$,disabled:_||!c}),O=N.useCallback((W,pe)=>{k&&(pe&&(k.unobserve(pe),y.current=!1),W&&k.observe(W))},[k]),[P,G]=Sc(O),B=Do(e);return N.useEffect(()=>{!k||!P.current||(k.disconnect(),y.current=!1,k.observe(P.current))},[P,k]),N.useEffect(()=>(d({type:nn.RegisterDroppable,element:{id:r,key:l,disabled:n,node:P,rect:S,data:B}}),()=>d({type:nn.UnregisterDroppable,key:l,id:r})),[r]),N.useEffect(()=>{n!==m.current.disabled&&(d({type:nn.SetDroppableDisabled,id:r,key:l,disabled:n}),m.current.disabled=n)},[r,l,n,d]),{active:c,rect:S,isOver:f?.id===r,node:P,over:f,setNodeRef:G}}function qf(s,e,n){const r=s.slice();return r.splice(n<0?r.length+n:n,0,r.splice(e,1)[0]),r}function sA(s,e){return s.reduce((n,r,i)=>{const l=e.get(r);return l&&(n[i]=l),n},Array(s.length))}function Tc(s){return s!==null&&s>=0}function oA(s,e){if(s===e)return!0;if(s.length!==e.length)return!1;for(let n=0;n{var e;let{rects:n,activeNodeRect:r,activeIndex:i,overIndex:l,index:c}=s;const d=(e=n[i])!=null?e:r;if(!d)return null;const f=uA(n,c,i);if(c===i){const h=n[l];return h?{x:ii&&c<=l?{x:-d.width-f,y:0,...kc}:c=l?{x:d.width+f,y:0,...kc}:{x:0,y:0,...kc}};function uA(s,e,n){const r=s[e],i=s[e-1],l=s[e+1];return!r||!i&&!l?0:n{let{rects:e,activeIndex:n,overIndex:r,index:i}=s;const l=qf(e,r,n),c=e[i],d=l[i];return!d||!c?null:{x:d.left-c.left,y:d.top-c.top,scaleX:d.width/c.width,scaleY:d.height/c.height}},Rc={scaleX:1,scaleY:1},dA=s=>{var e;let{activeIndex:n,activeNodeRect:r,index:i,rects:l,overIndex:c}=s;const d=(e=l[n])!=null?e:r;if(!d)return null;if(i===n){const h=l[c];return h?{x:0,y:nn&&i<=c?{x:0,y:-d.height-f,...Rc}:i=c?{x:0,y:d.height+f,...Rc}:{x:0,y:0,...Rc}};function fA(s,e,n){const r=s[e],i=s[e-1],l=s[e+1];return r?nr.map(G=>typeof G=="object"&&"id"in G?G.id:G),[r]),_=c!=null,x=c?v.indexOf(c.id):-1,A=h?v.indexOf(h.id):-1,L=N.useRef(v),$=!oA(v,L.current),k=A!==-1&&x===-1||$,O=lA(l);Pr(()=>{$&&_&&m(v)},[$,v,_,m]),N.useEffect(()=>{L.current=v},[v]);const P=N.useMemo(()=>({activeIndex:x,containerId:y,disabled:O,disableTransforms:k,items:v,overIndex:A,useDragOverlay:S,sortedRects:sA(v,f),strategy:i}),[x,y,O.draggable,O.droppable,k,v,A,f,S,i]);return Ye.createElement(Iy.Provider,{value:P},e)}const pA=s=>{let{id:e,items:n,activeIndex:r,overIndex:i}=s;return qf(n,r,i).indexOf(e)},gA=s=>{let{containerId:e,isSorting:n,wasDragging:r,index:i,items:l,newIndex:c,previousItems:d,previousContainerId:f,transition:h}=s;return!h||!r||d!==l&&i===c?!1:n?!0:c!==i&&e===f},mA={duration:200,easing:"ease"},jy="transform",yA=Mo.Transition.toString({property:jy,duration:0,easing:"linear"}),bA={roleDescription:"sortable"};function vA(s){let{disabled:e,index:n,node:r,rect:i}=s;const[l,c]=N.useState(null),d=N.useRef(n);return Pr(()=>{if(!e&&n!==d.current&&r.current){const f=i.current;if(f){const h=ys(r.current,{ignoreTransform:!0}),m={x:f.left-h.left,y:f.top-h.top,scaleX:f.width/h.width,scaleY:f.height/h.height};(m.x||m.y)&&c(m)}}n!==d.current&&(d.current=n)},[e,n,r,i]),N.useEffect(()=>{l&&c(null)},[l]),l}function SA(s){let{animateLayoutChanges:e=gA,attributes:n,disabled:r,data:i,getNewIndex:l=pA,id:c,strategy:d,resizeObserverConfig:f,transition:h=mA}=s;const{items:m,containerId:y,activeIndex:S,disabled:v,disableTransforms:_,sortedRects:x,overIndex:A,useDragOverlay:L,strategy:$}=N.useContext(Iy),k=wA(r,v),O=m.indexOf(c),P=N.useMemo(()=>({sortable:{containerId:y,index:O,items:m},...i}),[y,i,O,m]),G=N.useMemo(()=>m.slice(m.indexOf(c)),[m,c]),{rect:B,node:W,isOver:pe,setNodeRef:Se}=iA({id:c,data:P,disabled:k.droppable,resizeObserverConfig:{updateMeasurementsFor:G,...f}}),{active:we,activatorEvent:Ue,activeNodeRect:Fe,attributes:qe,setNodeRef:wt,listeners:J,isDragging:fe,over:Le,setActivatorNodeRef:Z,transform:ge}=tA({id:c,data:P,attributes:{...bA,...n},disabled:k.draggable}),H=IE(Se,wt),T=!!we,ce=T&&!_&&Tc(S)&&Tc(A),de=!L&&fe,be=de&&ce?ge:null,xe=ce?be??(d??$)({rects:x,activeNodeRect:Fe,activeIndex:S,overIndex:A,index:O}):null,_e=Tc(S)&&Tc(A)?l({id:c,items:m,activeIndex:S,overIndex:A}):O,Te=we?.id,Me=N.useRef({activeId:Te,items:m,newIndex:_e,containerId:y}),pt=m!==Me.current.items,Ct=e({active:we,containerId:y,isDragging:fe,isSorting:T,id:c,index:O,items:m,newIndex:Me.current.newIndex,previousItems:Me.current.items,previousContainerId:Me.current.containerId,transition:h,wasDragging:Me.current.activeId!=null}),Ot=vA({disabled:!Ct,index:O,node:W,rect:B});return N.useEffect(()=>{T&&Me.current.newIndex!==_e&&(Me.current.newIndex=_e),y!==Me.current.containerId&&(Me.current.containerId=y),m!==Me.current.items&&(Me.current.items=m)},[T,_e,y,m]),N.useEffect(()=>{if(Te===Me.current.activeId)return;if(Te!=null&&Me.current.activeId==null){Me.current.activeId=Te;return}const rn=setTimeout(()=>{Me.current.activeId=Te},50);return()=>clearTimeout(rn)},[Te]),{active:we,activeIndex:S,attributes:qe,data:P,rect:B,index:O,newIndex:_e,items:m,isOver:pe,isSorting:T,isDragging:fe,listeners:J,node:W,overIndex:A,over:Le,setNodeRef:H,setActivatorNodeRef:Z,setDroppableNodeRef:Se,setDraggableNodeRef:wt,transform:Ot??xe,transition:ht()};function ht(){if(Ot||pt&&Me.current.newIndex===O)return yA;if(!(de&&!Of(Ue)||!h)&&(T||Ct))return Mo.Transition.toString({...h,property:jy})}}function wA(s,e){var n,r;return typeof s=="boolean"?{draggable:s,droppable:!1}:{draggable:(n=s?.draggable)!=null?n:e.draggable,droppable:(r=s?.droppable)!=null?r:e.droppable}}function Dc(s){if(!s)return!1;const e=s.data.current;return!!(e&&"sortable"in e&&typeof e.sortable=="object"&&"containerId"in e.sortable&&"items"in e.sortable&&"index"in e.sortable)}const CA=[lt.Down,lt.Right,lt.Up,lt.Left],EA=(s,e)=>{let{context:{active:n,collisionRect:r,droppableRects:i,droppableContainers:l,over:c,scrollableAncestors:d}}=e;if(CA.includes(s.code)){if(s.preventDefault(),!n||!r)return;const f=[];l.getEnabled().forEach(y=>{if(!y||y!=null&&y.disabled)return;const S=i.get(y.id);if(S)switch(s.code){case lt.Down:r.topS.top&&f.push(y);break;case lt.Left:r.left>S.left&&f.push(y);break;case lt.Right:r.left1&&(m=h[1].id),m!=null){const y=l.get(n.id),S=l.get(m),v=S?i.get(S.id):null,_=S?.node.current;if(_&&v&&y&&S){const A=Cc(_).some((G,B)=>d[B]!==G),L=Hy(y,S),$=_A(y,S),k=A||!L?{x:0,y:0}:{x:$?r.width-v.width:0,y:$?r.height-v.height:0},O={x:v.left,y:v.top};return k.x&&k.y?O:$o(O,k)}}}};function Hy(s,e){return!Dc(s)||!Dc(e)?!1:s.data.current.sortable.containerId===e.data.current.sortable.containerId}function _A(s,e){return!Dc(s)||!Dc(e)||!Hy(s,e)?!1:s.data.current.sortable.index{const d=N.useId(),f=N.useRef({inProgress:!1,lastSortTime:0,lastActiveId:null}),h=XE(oy(zf,{activationConstraint:{distance:5}}),oy(jf,{coordinateGetter:EA})),m=N.useCallback(v=>{f.current={inProgress:!0,lastSortTime:Date.now(),lastActiveId:v.active.id},l?.({activeId:v.active.id})},[l]),y=N.useCallback(v=>{const{active:_,over:x}=v,A=Date.now();if(!x||_.id===x.id){f.current.inProgress=!1;return}const{lastSortTime:L,lastActiveId:$,inProgress:k}=f.current;if($===_.id&&A-L<500&&!k)return;f.current={inProgress:!1,lastSortTime:A,lastActiveId:_.id};const O=s.findIndex(G=>String(G[e])===String(_.id)),P=s.findIndex(G=>String(G[e])===String(x.id));if(O!==-1&&P!==-1&&O!==P){const G=qf(s,O,P);i?.(G,{oldIndex:O,newIndex:P})}},[s,e,i]),S=s.map(v=>String(v[e]));return ft.jsx(Q_,{id:d,sensors:h,collisionDetection:QE,onDragStart:m,onDragEnd:y,children:ft.jsx(hA,{items:S,strategy:AA[n],children:r})},c!==void 0?`${d}-v${c}`:d)},zy=N.createContext(null),TA=({value:s,children:e})=>ft.jsx(zy.Provider,{value:s,children:e}),kA=()=>N.useContext(zy),RA=({id:s,handle:e,as:n="div",children:r})=>{const{attributes:i,listeners:l,setNodeRef:c,transform:d,transition:f,isDragging:h}=SA({id:s}),m={transform:Mo.Transform.toString(d),transition:f,opacity:h?.5:1,position:"relative"};return ft.jsx(n,{ref:c,style:m,...i,...e?{}:l,"data-sortable-item":!0,"data-sortable-id":String(s),"data-dragging":h,children:ft.jsx(TA,{value:{listeners:l,handle:e,isDragging:h},children:r})})},it=dt("DynamicRenderer");function ia(){try{return window.G7Core?.devTools}catch{return}}function Ff(s,e,n,r){if(typeof s=="string"){if(/\$t:[a-zA-Z_][a-zA-Z0-9_.\-]*/.test(s))try{return e.resolveTranslations(s,n,r)}catch{return s}return s}if(Array.isArray(s))return s.map(i=>Ff(i,e,n,r));if(s&&typeof s=="object"){const i={};for(const[l,c]of Object.entries(s))i[l]=Ff(c,e,n,r);return i}return s}function DA(s){const e=Object.keys(s);return e.length>0&&e.every(n=>/^\d+$/.test(n))}const Ar=(s,e)=>{const n=["errors"],r={...s};for(const i of Object.keys(e)){const l=e[i],c=s[i];if(l===null){r[i]=null;continue}if(n.includes(i)){r[i]=l;continue}if(Array.isArray(l)){r[i]=l;continue}if(Array.isArray(c)&&l!==null&&typeof l=="object"&&!Array.isArray(l)&&DA(l)){const d=Object.keys(l).map(h=>parseInt(h,10));if((d.length>0?Math.max(...d):0)>=c.length+d.length+10)r[i]={...l};else{const h=[...c];for(const[m,y]of Object.entries(l)){const S=parseInt(m,10);S>=0&&S=h.length&&(h[S]=y)}r[i]=h}}else l!==null&&typeof l=="object"&&c!==null&&typeof c=="object"&&!Array.isArray(c)?r[i]=Ar(c,l):r[i]=l}return r},Oc=(s,e)=>{let n=null;const r=()=>(n===null&&(n={...s}),n);for(const i of Object.keys(e)){if(!(i in s))continue;const l=e[i],c=s[i];if(l!==null&&typeof l=="object"&&!Array.isArray(l)&&c!==null&&typeof c=="object"&&!Array.isArray(c)){const d=Oc(c,l);if(d===c)continue;Object.keys(d).length===0?delete r()[i]:r()[i]=d}else delete r()[i]}return n??s},OA=s=>{const e={},n=s.split(";").filter(r=>r.trim());for(const r of n){const i=r.indexOf(":");if(i===-1)continue;const l=r.substring(0,i).trim(),c=r.substring(i+1).trim();if(l&&c){const d=l.replace(/-([a-z])/g,(f,h)=>h.toUpperCase());e[d]=c}}return e};class LA extends N.Component{constructor(e){super(e),this.state={hasError:!1,error:null}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}componentDidCatch(e,n){it.error(`컴포넌트 렌더링 에러 (ID: ${this.props.componentId}, Name: ${this.props.componentName}):`,e,n)}render(){return this.state.hasError?this.props.fallback?this.props.fallback:ft.jsxs("div",{className:"p-4 my-2 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg text-red-800 dark:text-red-400",children:[ft.jsx("div",{className:"font-semibold mb-1",children:"컴포넌트 로드 실패"}),ft.jsxs("div",{className:"text-xs opacity-80",children:[this.props.componentName&&`[${this.props.componentName}] `,"데이터를 표시할 수 없습니다."]}),this.state.error&&ft.jsxs("details",{className:"mt-2",children:[ft.jsx("summary",{className:"cursor-pointer text-xs opacity-70 hover:opacity-100",children:"상세 정보"}),ft.jsx("div",{className:"mt-1 p-2 bg-red-100 dark:bg-red-900/30 rounded text-xs font-mono whitespace-pre-wrap break-all",children:this.state.error.message})]})]}):this.props.children}}const Br=N.memo(({componentDef:s,dataContext:e,translationContext:n,registry:r,bindingEngine:i,translationEngine:l,actionDispatcher:c,parentComponentContext:d,parentFormContextProp:f,parentDataContext:h,isRootRenderer:m=!1,isInsideIteration:y=!1,isEditMode:S=!1,onComponentSelect:v,onComponentHover:_,onDragStart:x,onDragEnd:A,componentPath:L,layoutKey:$})=>{const[k,O]=N.useState({loadingActions:{}});N.useLayoutEffect(()=>{d||(i.startRenderCycle(),window.__g7SetLocalOverrideKeys||(window.__g7ForcedLocalFields=void 0),window.__g7PendingLocalState=null)});const P=N.useRef(null);N.useLayoutEffect(()=>{if(!d&&e._localInit&&typeof e._localInit=="object"){const{_forceLocalInit:F,_merge:se,...ue}=e._localInit,ee=`${JSON.stringify(ue)}:${F||"no-force"}`;if(P.current!==ee){P.current=ee;const ve=se||"shallow",Ee=window.G7Core?.state?.get?.()?._local||{},Ae=window.__g7PendingLocalState||{},Ve={...Ee,...Ae};ve==="replace"?window.__g7PendingLocalState={loadingActions:Ve.loadingActions||{},...ue,hasChanges:!1}:ve==="deep"?window.__g7PendingLocalState=Ar(Ve,{...ue,hasChanges:!1}):window.__g7PendingLocalState={...Ve,...ue,hasChanges:!1};const ke=window.__g7SetLocalOverrideKeys;ke&&typeof ke=="object"&&(ve==="replace"?window.__g7SetLocalOverrideKeys={...ue,hasChanges:!1}:window.__g7SetLocalOverrideKeys=Ar(ke,{...ue,hasChanges:!1}))}}}),N.useLayoutEffect(()=>{if(!d){const F=window.__g7SetLocalOverrideKeys;if(F){O(ve=>Oc(ve,F));const se=F,ue=window.__g7ForcedLocalFields,ee=window.__g7LastSetLocalSnapshot;queueMicrotask(()=>{window.__g7SetLocalOverrideKeys===se&&(window.__g7SetLocalOverrideKeys=void 0),window.__g7ForcedLocalFields===ue&&(window.__g7ForcedLocalFields=void 0),window.__g7LastSetLocalSnapshot===ee&&(window.__g7LastSetLocalSnapshot=void 0)})}}},[e._local]);const G=N.useRef($);N.useEffect(()=>{s._fromBase&&$&&G.current!==$&&(G.current=$,O({loadingActions:{}}))},[$,s._fromBase]);const B=N.useRef(""),W=N.useRef(!1),pe=N.useRef(null),Se=N.useRef(null),we=N.useRef({}),Ue=N.useRef({}),Fe=N.useRef(h),qe=NE(),wt=dE(),J=wt?.getParentDataContext()??h;N.useEffect(()=>{if(e._localInit&&typeof e._localInit=="object"){const{_forceLocalInit:F,...se}=e._localInit,ue=JSON.stringify(se),ee=F!==void 0,ve=Ef(),he=`${ue}:${F||"no-force"}`,Ee=vE({globalTrackedKey:ve.hash,instanceHandledKey:Se.current,trackingKey:he});if(Ee==="apply"){Se.current=he,ve.hash=he,ve.timestamp=F,B.current=ue,ee&&(W.current=!0);const{_merge:Ve,...ke}=se,Ne=Ve||"shallow";O(Re=>Ne==="replace"?{loadingActions:Re.loadingActions||{},...ke,hasChanges:!1}:Ne==="deep"?Ar(Re,{...ke,hasChanges:!1}):{...Re,...ke,hasChanges:!1}),e._globalSetState&&e._globalSetState(Re=>{const et=Re?._local||{};let He;return Ne==="replace"?He={...ke,hasChanges:!1}:Ne==="deep"?He=Ar(et,{...ke,hasChanges:!1}):He={...et,...ke,hasChanges:!1},{...Re,_local:He}}),i.invalidateCacheByKeys(["_local"]),it.log("_localInit applied (data changed):",Object.keys(se))}else if(Ee==="prune"){Se.current=he;const{_merge:Ve,...ke}=se;O(Re=>Oc(Re,ke)),Oc(k,ke)!==k&&(i.invalidateCacheByKeys(["_local"]),it.log("_localInit pruned (applied by another renderer):",Object.keys(ke)))}pe.current=e._localInit,yE(e._localInit)}},[e._localInit,h,i]);const{isTransitioning:fe}=Jm(),Le=xE(),Z=f??Le,{width:ge}=Af(),H=kA(),T=N.useMemo(()=>{let F=s;if(s.type==="iterator"&&s.data){const{data:ee,itemName:ve,indexName:he,...Ee}=s;F={...Ee,iteration:{source:ee,item_var:ve||"item",index_var:he}}}if(!F.responsive)return F;const se=Si.getMatchingKey(F.responsive,ge);if(!se)return F;const ue=F.responsive[se];return{...F,props:{...F.props,...ue.props},children:ue.children??F.children,text:ue.text??F.text,if:ue.if??F.if,iteration:ue.iteration??F.iteration,__responsiveChildrenKey:ue.children!==void 0?se:void 0}},[s,ge]),ce=N.useCallback(F=>{const se=F?.__setStateId;if(O(ue=>{const ee=window.__g7PendingLocalState,he=window.__g7SetLocalOverrideKeys||ee,Ee=he?Ar(ue,he):ue;if(typeof F=="function"){const Re=F(Ee);return Ar(Ee,Re)}const{__mergeMode:Ae,__setStateId:Ve,...ke}=F;let Ne;if(Ae==="replace"?Ne=ke:Ae==="shallow"?Ne={...Ee,...ke}:Ne=Ar(Ee,ke),Ae!==void 0){const Re=window.__g7ForcedLocalFields;Re&&(window.__g7ForcedLocalFields={...Re,...ke})}return Ne}),se){const ue=ia();if(ue?.isEnabled()){const ee=T.id||"unknown",ve=T.name||"Unknown";setTimeout(()=>{ue.trackComponentRender?.(ee,ve,0,["_local"],[]),ue.completeStateChange?.(se)},0)}}},[T.id,T.name]),de=d?.state??k,be=d?.setState??ce,ie=N.useMemo(()=>{const F=e._localInit&&e._localInit!==pe.current;let se;F&&e._local?se=e._local:se=e._local?Ar(e._local,de):de;const ue=window.__g7ForcedLocalFields;ue&&(se=Ar(se,ue));const ee={...e,_local:se},ve=e._computedDefinitions;if(ve&&Object.keys(ve).length>0){const he=new kn,Ee={...ee,...qe?{_isolated:qe.state}:{}},Ae={},Ve=ia(),ke=Ve?.isEnabled()??!1;for(const[Ne,Re]of Object.entries(ve)){const et=ke?Date.now():0,He=ke?e._computed?.[Ne]:void 0;let Ge;try{if(typeof Re=="string")if(Re.startsWith("{{")&&Re.endsWith("}}")){const Ce=Re.slice(2,-2).trim(),je=Gn(Ce)?he.evaluatePipeExpression(Ce,Ee,{skipCache:!0}):he.evaluateExpression(Ce,Ee,{skipCache:!0});Ae[Ne]=je}else Ae[Ne]=Re;else if(Re&&typeof Re=="object"&&"$switch"in Re){const Ce=he.resolveSwitch(Re,Ee,{skipCache:!0});Ae[Ne]=Ce}}catch(Ce){it.warn(`Failed to recalculate computed value: ${Ne}`,Ce),Ae[Ne]=e._computed?.[Ne],Ge=Ce instanceof Error?Ce.message:String(Ce)}if(ke&&(Ge||He!==Ae[Ne])){const je=Date.now()-et;Ve.trackComputedProperty?.(Ne,typeof Re=="string"?Re:JSON.stringify(Re),[{type:"_local",path:"_local",value:ee._local}],Ae[Ne],je,T.id,Ge),He!==Ae[Ne]&&Ve.trackComputedRecalc?.(Ne,"dependency-change",He,Ae[Ne],je,{type:"_local",path:"_local"},T.id)}}ee._computed=Ae}if(qe&&(ee._isolated=qe.state),J&&(ee.$parent=J),s.extensionPointProps){const he=i.resolveObject(s.extensionPointProps,ee,y?{skipCache:!0}:void 0);ee.extensionPointProps=S&&l?Ff(he,l,n,ee):he}return s.extensionPointCallbacks&&(ee.extensionPointCallbacks=s.extensionPointCallbacks),S&&(ee.$templateId===void 0&&n?.templateId&&(ee.$templateId=n.templateId),ee.$locale===void 0&&n?.locale&&(ee.$locale=n.locale)),ee},[e,de,qe?.state,J,wt?.version,s.extensionPointProps,s.extensionPointCallbacks]);we.current=ie._local,Ue.current=ie._computed||{},Fe.current=J,N.useEffect(()=>{const F=ia();if(!F?.isEnabled())return;const se=ie._local;se&&F.updateLocalState(se);const ue=ie._computed;ue&&F.updateComputedState(ue),J&&F.updateParentContext?.(J);const ee=T.id||`comp-${Date.now()}`,ve=T.name||"Unknown",he={global:Object.keys(e._global||{}),local:Object.keys(se||{}),context:d?Object.keys(d.state||{}):[]},Ee={type:d?"componentContext":"dynamicState",hasComponentContext:!!d,parentId:d?"parent":void 0};F.trackComponentStateSource?.(ee,ve,he,Ee),de&&Object.keys(de).length>0&&F.trackDynamicState?.(ee,de);const Ae=!!(T.expandChildren||T.props?.expandChildren);F.trackContextFlow?.(ee,ve,!!d,Ae,!0)},[ie._local,e,T.id,T.name,d,de,T.expandChildren,T.props?.expandChildren,J]);const xe=N.useMemo(()=>({state:{...ie._local},setState:be,stateRef:we,computedRef:Ue,isolatedContext:qe,parentDataContext:ie}),[ie._local,be,k,qe,ie]),_e=N.useMemo(()=>{const F=os({if:T.if,condition:T.condition,conditions:T.conditions},ie,i,T.id);if(T.if||T.condition!==void 0||T.conditions){const ue=ia();ue?.isEnabled()&&T.if&&ue.trackIfCondition(T.id||`if-${Date.now()}`,T.if,F)}return F},[T.if,T.conditions,ie,i,T.id]),Te=N.useMemo(()=>{if(!T.slot)return null;const F=T.slot;if(F.startsWith("{{")&&F.endsWith("}}")){const se=F.slice(2,-2).trim();try{const ue={componentId:T.id,componentName:T.name,propName:"slot"},ee=Gn(se)?i.evaluatePipeExpression(se,ie,void 0,ue):i.evaluateExpression(se,ie,ue);return it.log(`[Slot] 표현식 평가: "${se}" => "${ee}" (컴포넌트: ${T.id})`),typeof ee=="string"?ee:null}catch(ue){return it.warn(`slot 표현식 평가 실패 (컴포넌트: ${T.id}):`,ue),null}}return it.log(`[Slot] 정적 슬롯 ID: "${F}" (컴포넌트: ${T.id})`),F},[T.slot,T.id,ie,i]),Me=N.useMemo(()=>!Te||!T.id?"":`${T.id}-${Te}-${JSON.stringify(T.slotOrder??0)}`,[Te,T.id,T.slotOrder]),pt=N.useRef(null);N.useEffect(()=>{const F=window.__slotContextValue,se=F?.isEnabled??!1;if(T.slot&&it.log(`[Slot Registration] 컴포넌트: ${T.id}, isSlotEnabled: ${se}, shouldRender: ${_e}, resolvedSlotId: ${Te}`),!se||!_e){T.slot&&it.log(`[Slot Registration] 등록 스킵 - isSlotEnabled: ${se}, shouldRender: ${_e}`),pt.current&&T.id&&F&&(F.unregisterFromSlot(pt.current,T.id),pt.current=null);return}if(!Te||!T.id){T.slot&&it.log(`[Slot Registration] 등록 스킵 - resolvedSlotId: ${Te}, id: ${T.id}`),pt.current&&T.id&&F&&(F.unregisterFromSlot(pt.current,T.id),pt.current=null);return}pt.current&&pt.current!==Te&&F.unregisterFromSlot(pt.current,T.id);const ue={...T,slot:void 0,slotOrder:void 0};return F.registerToSlot(Te,T.id,{componentDef:ue,dataContext:e,order:T.slotOrder??0,parentFormContext:f??null,getParentComponentContext:()=>xe,translationContext:n,registrationKey:Me}),pt.current=Te,()=>{const ee=window.__slotContextValue;Te&&T.id&&ee&&ee.unregisterFromSlot(Te,T.id)}},[_e,Te,T,e,f,xe,n,Me]);const Ct=N.useCallback(F=>{if(typeof F=="string"){if(Yl(F))return zd(F);if(Xl(F)){const se=[],ue=F.replace(new RegExp(`${po}([^${bi}]*)${bi}`,"g"),(ve,he)=>(se.push(he),`${Oa}${se.length-1}${Oa}`));let ee=ue;return/\$t:[a-zA-Z0-9._-]+/.test(ue)&&(ee=l.resolveTranslations(ue,n,ie)),ee.replace(new RegExp(`${Oa}(\\d+)${Oa}`,"g"),(ve,he)=>se[parseInt(he)])}if(F.startsWith("$t:defer:"))return F;if(/\$t:[a-zA-Z0-9._-]+/.test(F)){const se=F.trim();return se.startsWith("{")&&se.endsWith("}")||se.startsWith("[")&&se.endsWith("]")?F:l.resolveTranslations(F,n,ie)}return F}if(Array.isArray(F))return F.map(se=>Ct(se));if(F&&typeof F=="object"){const se={};for(const[ue,ee]of Object.entries(F))se[ue]=Ct(ee);return se}return F},[l,n,ie]),Ot=N.useCallback(F=>ho(F),[]),ht=N.useCallback(F=>Da(F),[]),rn=N.useMemo(()=>{let F={...T.props||{}};const se=["cellChildren","expandChildren","expandContext","render"],ee=r.getMetadata(T.name)?.skipBindingKeys||[],ve=[...new Set([...se,...ee])],he=y?{skipCache:!0}:void 0,Ee={...he??{},skipBindingKeys:ve},Ae=Ce=>{if(he)return he;if(Ce.startsWith("_computed")||Ce.startsWith("$computed"))return{skipCache:!0}};for(const[Ce,je]of Object.entries(F))if(!ve.includes(Ce))if(typeof je=="string"){const tt=ht(je);if(tt!==null){let At=!1,Mt=tt;tt.startsWith(nr)&&(At=!0,Mt=tt.slice(nr.length));const On={componentId:T.id,componentName:T.name,propName:Ce};let jt;if(Gn(Mt))try{jt=i.evaluatePipeExpression(Mt,ie,Ae(Mt),On)}catch(Ht){it.warn(`파이프 표현식 평가 실패 (컴포넌트: ${T.id}, prop: ${Ce}):`,Ht),jt=void 0}else if(Ot(Mt))try{jt=i.evaluateExpression(Mt,ie,On)}catch(Ht){it.warn(`표현식 평가 실패 (컴포넌트: ${T.id}, prop: ${Ce}):`,Ht),jt=void 0}else jt=i.resolve(Mt,ie,Ae(Mt),On);F[Ce]=At&&jt!=null?ss(jt):jt}else{const At={componentId:T.id,componentName:T.name,propName:Ce};F[Ce]=i.resolveBindings(je,ie,he,At)}}else Array.isArray(je)?F[Ce]=je.map(tt=>typeof tt=="string"?i.resolveBindings(tt,ie,he):typeof tt=="object"&&tt!==null?i.resolveObject(tt,ie,Ee):tt):je&&typeof je=="object"&&(F[Ce]=i.resolveObject(je,ie,Ee));for(const[Ce,je]of Object.entries(F))F[Ce]=Ct(je);if(typeof F.style=="string"&&(F.style=OA(F.style)),F=Qd(F,S?void 0:T.actions,ie,{componentContext:xe,actionDispatcher:c}),T.classMap){const Ce=S0(T.classMap,ie,i,{skipCache:!0});if(Ce){const je=F.className||"";F.className=je?`${je} ${Ce}`:Ce}}T.style&&(F.style=T.style),T.actions&&T.actions.length>0&&T.type==="composite"&&Object.assign(F,de),T.component_layout&&(F.__componentLayoutDefs=T.component_layout);const Ve=T.expandChildren||T.props?.expandChildren,ke=T.props?.cellChildren,Ne=T.children&&T.children.length>0,Re=T.component_layout,et=T.slot,He=T.props?.modalId,Ge=T.type==="composite";return(Ve||ke||Ne||Re||et||He||Ge)&&(F.__componentContext=xe),F},[T.props,T.actions,T.style,T.classMap,T.id,ie,n,i,l,xe,de,Ct,Ot,ht,y]),Kt=N.useRef(null),It=N.useMemo(()=>Kt.current&&Zm(Kt.current,rn)?Kt.current:(Kt.current=rn,rn),[rn]),Fr=N.useMemo(()=>{const F=T.id;if(typeof F!="string"||!F.includes("{{"))return F;const se=i.resolveBindings(F,ie,{skipCache:!0});return typeof se=="string"?se:F},[T.id,ie,i]),hn=N.useMemo(()=>{const F=T.dataKey,se=T.trackChanges,ue=T.debounce;if(F){const ee=F.startsWith("_global."),ve=ee?F.slice(8):F,he=ee?e._global:ie._local;return{dataKey:ve,trackChanges:se??!1,debounce:ue,setState:ee?Ae=>{e._globalSetState?e._globalSetState(Ae):it.warn("_global.formData 사용 시 _globalSetState가 필요합니다.")}:be,state:he??{},_isGlobal:ee}}if(Z.dataKey)return Z},[T.dataKey,T.trackChanges,T.debounce,T.id,be,ie._local,e._global,e._globalSetState,Z]),an=N.useRef(new Set);N.useEffect(()=>{an.current.clear()},[e._global?._remountKeys]);const pn=N.useCallback((F,se)=>{const ue=e._global?._remountKeys;return F&&ue?.[F]&&!an.current.has(F)?(an.current.add(F),`${F}-remount-${ue[F]}`):F||se},[e._global?._remountKeys]),Wn=N.useMemo(()=>{if(T.text!==void 0){if(typeof T.text=="string"){const F=T.text;let se=F;const ue={componentId:T.id,componentName:T.name,propName:"text",skipCache:!0},ee=ht(F);if(ee!==null){let ve=!1,he=ee;if(ee.startsWith(nr)&&(ve=!0,he=ee.slice(nr.length)),Gn(he))try{se=i.evaluatePipeExpression(he,ie,{skipCache:!0},ue)}catch(Ee){it.warn(`text 파이프 표현식 평가 실패 (컴포넌트: ${T.id}):`,Ee),se=""}else if(Ot(he))try{se=i.evaluateExpression(he,ie,ue)}catch(Ee){it.warn(`text 표현식 평가 실패 (컴포넌트: ${T.id}):`,Ee),se=""}else se=i.resolve(he,ie,{skipCache:!0},ue);ve&&se!=null&&(se=ss(se))}else F.includes("{{")&&(se=i.resolveBindings(F,ie,{skipCache:!0},ue));return se=Ct(se),se??""}return T.text}return!T.children||T.children.length===0?null:T.children.map((F,se)=>{if(typeof F=="string")return F;const ue=T.__responsiveChildrenKey,ee=ue?`responsive.${ue}.children`:"children",ve=L?`${L}.${ee}.${se}`:`${se}`,he=F._fromBase?F.id||`child-${se}`:pn(F.id,`child-${se}`),Ee=!F._fromBase&&$?`${he}_${$}`:he;return ft.jsx(Br,{componentDef:F,dataContext:ie,translationContext:n,registry:r,bindingEngine:i,translationEngine:l,actionDispatcher:c,parentComponentContext:xe,parentFormContextProp:hn,isInsideIteration:y,isEditMode:S,onComponentSelect:v,onComponentHover:_,componentPath:ve,onDragStart:x,onDragEnd:A,layoutKey:$},Ee)})},[T.text,T.children,T.id,e,ie,n,r,i,l,c,xe,hn,ht,Ot,Ct,pn,y,S,v,_,L,x,A,$]),Vr=N.useMemo(()=>{if(!T.iteration)return null;try{const F=Jd(T.iteration.source,ie,i);if(!Array.isArray(F))return it.warn(`iteration source가 배열이 아닙니다 (컴포넌트: ${T.id}):`,F),null;const se=ia();return se?.isEnabled()&&se.trackIteration(T.id||`iteration-${Date.now()}`,T.iteration.source,T.iteration.item_var,T.iteration.index_var,F.length),F.map((ue,ee)=>{const ve={...ie,[T.iteration.item_var]:ue,[`${T.iteration.item_var}_index`]:ee};T.iteration.index_var&&(ve[T.iteration.index_var]=ee);const he=ee===0||ee===F.length-1;se?.isEnabled()&&he&&se.trackNestedContext?.({componentId:`${T.id||"unknown"}-iter-${ee}`,componentType:"iteration",parentContext:{available:Object.keys(ie),values:{}},ownContext:{added:[T.iteration.item_var,...T.iteration.index_var?[T.iteration.index_var]:[]],values:{[T.iteration.item_var]:ue,...T.iteration.index_var?{[T.iteration.index_var]:ee}:{}}},depth:1});const Ee={...T,iteration:void 0,responsive:void 0},Ae=L?`${L}.iteration.${ee}`:`iteration.${ee}`,Ve=`${pn(T.id,"item")}-${ee}`;return ft.jsx(Br,{componentDef:Ee,dataContext:ve,translationContext:n,registry:r,bindingEngine:i,translationEngine:l,actionDispatcher:c,parentComponentContext:xe,parentFormContextProp:hn,isInsideIteration:!0,isEditMode:S,onComponentSelect:v,onComponentHover:_,componentPath:Ae,onDragStart:x,onDragEnd:A,layoutKey:$},Ve)})}catch(F){return it.error(`iteration 렌더링 실패 (컴포넌트: ${T.id}):`,F),null}},[T.iteration,T.children,T.id,e,ie,n,r,i,l,c,xe,hn,pn,S,v,_,L,x,A,$]),[qt,ki]=N.useState(0),la=N.useMemo(()=>{if(!T.sortable||!T.itemTemplate)return null;const{sortable:F,itemTemplate:se}=T;try{const ue=Jd(F.source,ie,i);if(!Array.isArray(ue))return it.warn(`sortable source가 배열이 아닙니다 (컴포넌트: ${T.id}):`,ue),null;if(ue.length===0)return null;const ee=F.itemKey||"id",ve=F.strategy||"verticalList",he=F.itemVar||"$item",Ee=F.indexVar||"$index",Ae=F.handle,Ve=F.wrapperElement,ke=(et,He)=>{const Ge=T.actions?.filter(Ce=>Ce.event==="onSortEnd"||Ce.type==="onSortEnd");if(ki(Ce=>Ce+1),Ge&&Ge.length>0&&c){const Ce={...ie,$sortedItems:et,$sortEvent:He};Ge.forEach(je=>{try{const tt=c.createHandler(je,Ce,xe),At=new Event("sortend");tt(At)}catch(tt){it.error(`onSortEnd action failed: ${je.handler}`,tt)}})}},Ne=et=>{const He=T.actions?.filter(Ge=>Ge.event==="onSortStart"||Ge.type==="onSortStart");if(He&&He.length>0&&c){const Ge={...ie,$activeId:et.activeId};He.forEach(Ce=>{try{const je=c.createHandler(Ce,Ge,xe),tt=new Event("sortstart");je(tt)}catch(je){it.error(`onSortStart action failed: ${Ce.handler}`,je)}})}},Re=ue.map((et,He)=>{const Ge=String(et[ee]),Ce={...ie,[he]:et,[Ee]:He},je=L?`${L}.sortable.${He}`:`sortable.${He}`,tt=`${pn(T.id,"sortable-item")}-v${qt}-${Ge}`;return ft.jsx(RA,{id:Ge,handle:Ae,...Ve?{as:Ve}:{},children:(Ve&&se.children?se.children:[se]).map((At,Mt)=>ft.jsx(Br,{componentDef:At,dataContext:Ce,translationContext:n,registry:r,bindingEngine:i,translationEngine:l,actionDispatcher:c,parentComponentContext:xe,parentFormContextProp:void 0,isInsideIteration:!0,isEditMode:S,onComponentSelect:v,onComponentHover:_,componentPath:je,onDragStart:x,onDragEnd:A,layoutKey:$},`${tt}-child-${Mt}`))},tt)});return ft.jsx(xA,{items:ue,itemKey:ee,strategy:ve,onSortEnd:ke,onSortStart:Ne,sortVersion:qt,children:Re})}catch(ue){return it.error(`sortable 렌더링 실패 (컴포넌트: ${T.id}):`,ue),null}},[T.sortable,T.itemTemplate,T.actions,T.id,e,ie,n,r,i,l,c,xe,pn,S,v,_,L,x,A,qt,$]),gn=N.useRef(!1);N.useEffect(()=>{if(gn.current)return;gn.current=!0;const F=ia();if(F?.isEnabled()&&F.trackMount(s.id,{name:s.name,type:s.type||"component",props:It}),s.lifecycle?.onMount&&s.lifecycle.onMount.length>0)for(const ue of s.lifecycle.onMount)try{const ee=c.createHandler(ue,ie,xe),ve=new Event("mount");ee(ve),it.log(`Lifecycle onMount executed: ${ue.handler} (Component: ${s.id})`)}catch(ee){it.error(`Lifecycle onMount failed: ${ue.handler} (Component: ${s.id})`,ee)}const se=[];if(s.onComponentEvent&&s.onComponentEvent.length>0){const ue=window.G7Core;if(ue?.componentEvent?.on)for(const ee of s.onComponentEvent){if(!ee.event){it.warn(`onComponentEvent: event name is required (Component: ${s.id})`);continue}const ve=async Ee=>{try{const Ae={...ie,_eventData:Ee},ke=await c.createHandler({handler:ee.handler,params:ee.params,onSuccess:ee.onSuccess,onError:ee.onError},Ae,xe)(new CustomEvent(ee.event,{detail:Ee}));return it.log(`onComponentEvent "${ee.event}" handled: ${ee.handler} (Component: ${s.id})`,{eventData:Ee,result:ke}),ke}catch(Ae){throw it.error(`onComponentEvent "${ee.event}" failed: ${ee.handler} (Component: ${s.id})`,Ae),Ae}},he=ue.componentEvent.on(ee.event,ve);se.push(he),it.log(`onComponentEvent: Subscribed to "${ee.event}" (Component: ${s.id})`)}else it.warn(`onComponentEvent: G7Core.componentEvent is not available (Component: ${s.id})`)}return()=>{const ue=ia();ue?.isEnabled()&&ue.trackUnmount(s.id);for(const ee of se)try{ee()}catch(ve){it.error(`onComponentEvent: Failed to unsubscribe (Component: ${s.id})`,ve)}if(se.length>0&&it.log(`onComponentEvent: Unsubscribed ${se.length} event(s) (Component: ${s.id})`),s.lifecycle?.onUnmount&&s.lifecycle.onUnmount.length>0)for(const ee of s.lifecycle.onUnmount)try{const ve=c.createHandler(ee,ie,xe),he=new Event("unmount");ve(he),it.log(`Lifecycle onUnmount executed: ${ee.handler} (Component: ${s.id})`)}catch(ve){it.error(`Lifecycle onUnmount failed: ${ee.handler} (Component: ${s.id})`,ve)}}},[]);const Dn=N.useMemo(()=>{const F=It.dataKey,se=It.trackChanges,ue=It.debounce;return F?{dataKey:F,trackChanges:se??!1,debounce:ue,setState:be,state:de}:null},[It.dataKey,It.trackChanges,It.debounce,be,de]);N.useEffect(()=>{const F=T.dataKey||It.dataKey;if(!F)return;const se=ia();if(!se?.isEnabled())return;const ue=[],ee=he=>{if(he)for(const Ee of he){const Ae=Ee?.props?.name;if(Ae&&ue.push({name:Ae,type:Ee.name||Ee.type||"unknown"}),Ee?.children&&ee(Ee.children),Ee?.slots)for(const Ve of Object.values(Ee.slots))Array.isArray(Ve)&&ee(Ve)}};if(s.children&&ee(s.children),s.slots)for(const he of Object.values(s.slots))Array.isArray(he)&&ee(he);const ve=s.id||`form-${F}`;return se.trackForm(ve,F,ue),()=>{se.untrackForm(ve)}},[T,It.dataKey,s.id,s.children]);const nt=N.useRef(null),In=N.useRef(void 0);N.useEffect(()=>{const F=It?.name;if(!F||!Z.dataKey||!Z.setState||It?.autoBinding===!1)return;const se=`${Z.dataKey}.${F}`,ue=window.__g7AutoBindingPaths??new Map;return window.__g7AutoBindingPaths=ue,ue.set(se,(ue.get(se)??0)+1),()=>{const ee=ue.get(se)??0;ee<=1?ue.delete(se):ue.set(se,ee-1)}},[It?.name,It?.autoBinding,Z.dataKey,Z.setState]);const mn=N.useMemo(()=>{const{dataKey:F,trackChanges:se,debounce:ue,...ee}=It,ve=ee.name;if(!ve||!Z.dataKey||!Z.setState)return ee;if(ee.autoBinding===!1){const{autoBinding:Ge,...Ce}=ee;return Ce}const he=`${Z.dataKey}.${ve}`,Ee=TE(Z.state,he),Ae=Ee!==void 0?Ee:ee.value,ke=r.getMetadata(s.name)?.bindingType,Ne=typeof Ae=="boolean"&&(ke==="checked"||ke==="checkable"&&["checkbox","radio"].includes(ee?.type)),Re=Z.debounce,et=Ge=>{const Ce=Z.state||{},je=kE(Ce,he,Ge);if(Z.trackChanges&&(je.hasChanges=!0),window.__g7PendingLocalState=je,Z.setState(je),Z._isGlobal)return;const tt=window.G7Core,At={[he]:Ge};Z.trackChanges&&(At.hasChanges=!0),tt?.state?.setLocal?.(At,{render:!1})},He=(Ge,Ce)=>{Re&&Re>0?(nt.current&&clearTimeout(nt.current),nt.current=setTimeout(()=>{et(Ge),nt.current=null,Ce&&(Ce(),window.__g7PendingLocalState=null)},Re)):(et(Ge),Ce&&(Ce(),window.__g7PendingLocalState=null))};if(Ne)return{...ee,checked:Ae,onChange:Ce=>{const je=Ce.target.checked;et(je),ee.onChange&&ee.onChange(Ce)}};{const Ge=je=>{const tt=je?.target?.value!==void 0?je.target.value:je;Re&&Re>0&&(In.current=tt);const At=je?.target?{target:{value:tt,name:je.target.name,type:je.target.type,checked:je.target.checked},currentTarget:je.currentTarget?{value:tt,name:je.currentTarget.name}:void 0}:je;He(tt,()=>{ee.onChange&&ee.onChange(At)})};let Ce;return In.current!==void 0?nt.current!==null?Ce=In.current:String(Ae??"")===String(In.current)?(In.current=void 0,Ce=Ae??""):Ce=In.current:Ce=Ae??"",{...ee,value:Ce,onChange:Ge}}},[It,Z,Z.state,Z.debounce]),ca=N.useMemo(()=>{const F=ia();if(F?.isEnabled()&&F.trackRender(s.name),!_e)return T.iteration?Vr:null;if(T.sortable&&T.itemTemplate)return la;if(T.iteration)return Vr;if(T.type==="extension_point"){const{layout:ke,columns:Ne,gap:Re,className:et,...He}=T.props||{};let Ge=et||"";return ke==="grid"&&Ne?Ge=`${Ge} grid grid-cols-${Ne} gap-${Re||4}`.trim():ke==="flex"&&(Ge=`${Ge} flex flex-col gap-${Re||4}`.trim()),ft.jsx("div",{id:Fr,className:Ge||void 0,...He,children:Wn})}const se=r.getComponent(T.name);if(!se)return it.error(`컴포넌트를 찾을 수 없습니다: ${T.name} (ID: ${T.id})`,"componentDef:",JSON.stringify(T,null,2)),null;const ue=e._global?._remountKeys,ee={...mn,id:mn.id??Fr,...ue&&Object.keys(ue).length>0&&{__remountTrigger:JSON.stringify(ue)}};if(H?.listeners&&H.handle&&mn["data-drag-handle"]!==void 0&&(Object.assign(ee,H.listeners),ee.style={...ee.style,cursor:H.isDragging?"grabbing":"grab"}),S){const ke=T.id||`auto_${T.name||T.type||"unknown"}_${Math.random().toString(36).substring(2,8)}`,Ne=He=>{typeof He.preventDefault=="function"&&He.preventDefault(),v&&(He.stopPropagation(),v(ke,He))},Re={"data-editor-id":ke,"data-editor-name":T.name,"data-editor-type":T.type,onClick:Ne};L&&(Re["data-editor-path"]=L);const et=T.__editorSlotName??T.slot;typeof et=="string"&&(Re["data-editor-slot"]=et),_&&(Re.onMouseMove=He=>{He.stopPropagation(),_(ke,He)},Re.onMouseLeave=He=>{_(null,He)}),Object.assign(ee,Re),ee.editorAttrs=Re}const ve=T.type==="basic",he=T.type==="layout",Ae=ve||he?(()=>{const ke={};for(const[Ne,Re]of Object.entries(ee))Ne.startsWith("__")||Ne==="editorAttrs"&&ve||(ke[Ne]=Re);return ke})():ee;let Ve=ft.jsx(se,{...Ae,children:Wn});if(hn&&(Ve=ft.jsx(AE,{value:hn,children:Ve})),T.isolatedState){const ke=typeof T.isolatedState=="object"?T.isolatedState:{},Ne=e?._isolatedInit,Re=Ne?{...ke,...Ne}:ke;Ve=ft.jsx(ME,{initialState:Re,scopeId:T.isolatedScopeId,children:Ve})}return Ve},[_e,T.iteration,T.sortable,T.itemTemplate,T.type,T.name,T.id,T.props,T.isolatedState,T.isolatedScopeId,r,mn,Wn,Vr,la,H,Dn,S,v,_,x,A,L,e._global?._remountKeys]),lr=N.useMemo(()=>{const F=T.blur_until_loaded;if(!F||e?._global?.__isPreview)return!1;if(typeof F=="string"){const ee=ht(F);if(ee!==null)try{const ve={componentId:T.id,componentName:T.name,propName:"blur_until_loaded"};return!!i.evaluateExpression(ee,ie,ve)}catch(ve){return it.warn(`blur_until_loaded 표현식 평가 실패 (컴포넌트: ${T.id}):`,ve),!1}return!1}if(typeof F=="object"&&F!==null){if(!F.enabled)return!1;if(F.data_sources)return(Array.isArray(F.data_sources)?F.data_sources:[F.data_sources]).some(Ee=>e[Ee]===void 0);if(fe)return!0;const ee=["route","query","_global","_local","_dataSourceErrors"];return Object.keys(e).filter(he=>!ee.includes(he)&&!he.startsWith("_")).some(he=>e[he]===void 0)}if(fe)return!0;const se=["route","query","_global","_local","_dataSourceErrors"];return Object.keys(e).filter(ee=>!se.includes(ee)&&!ee.startsWith("_")).some(ee=>e[ee]===void 0)},[T.blur_until_loaded,T.id,fe,e,ie,i,ht]);if(lr){const F=T.blur_until_loaded;if(typeof F=="object"&&F?.data_sources){const ue=(Array.isArray(F.data_sources)?F.data_sources:[F.data_sources]).reduce((ve,he)=>(ve[he]=e[he]===void 0?"UNDEFINED":"LOADED",ve),{}),ee=Object.keys(e).filter(ve=>!ve.startsWith("_"));it.log(`[BLUR APPLIED] Component: ${T.id}, data_sources status:`,ue,"Available keys:",ee)}else it.log(`[BLUR APPLIED] Component: ${T.id}, blur_until_loaded:`,F)}const sn=N.useMemo(()=>{if(!T.blur_until_loaded)return{wrapperClasses:"",innerClasses:""};const F=rn?.className||"";if(!F)return{wrapperClasses:"",innerClasses:""};const se=[/^(sm:|md:|lg:|xl:|2xl:)?(col-span-|row-span-|col-start-|col-end-|row-start-|row-end-)/,/^(sm:|md:|lg:|xl:|2xl:)?(self-|place-self-|order-)/,/^(sm:|md:|lg:|xl:|2xl:)?(flex-shrink|flex-grow|flex-\d|basis-)/],ue=F.split(/\s+/).filter(Boolean),ee=[],ve=[];for(const he of ue)se.some(Ae=>Ae.test(he))?ee.push(he):ve.push(he);return{wrapperClasses:ee.join(" "),innerClasses:ve.join(" ")}},[T.blur_until_loaded,rn?.className]),_n=window.__slotContextValue;return Te&&_n?.isEnabled?null:ft.jsx(LA,{componentId:s.id,componentName:s.name,children:T.blur_until_loaded?ft.jsx("div",{className:[sn.wrapperClasses,lr?"opacity-50 blur-sm transition-all duration-300 pointer-events-none":void 0].filter(Boolean).join(" ")||void 0,children:ca}):ca})});Br.displayName="DynamicRenderer",typeof window<"u"&&(window.__DynamicRenderer=Br);function $A(s){const e={};try{const r=new URL(s,typeof window<"u"?window.location.origin:"http://localhost").searchParams,i=new Set;for(const l of r.keys()){if(i.has(l))continue;i.add(l);const c=r.getAll(l);c.length>1||l.endsWith("[]")?e[l]=c:e[l]=c[0]}}catch{}return e}function MA(s){try{return new URL(s,typeof window<"u"?window.location.origin:"http://localhost").pathname}catch{return s.split("?")[0]}}const Ti=class Ti{constructor(){M(this,"config",{enabled:!1,maxHistorySize:100,logLevel:"info",serverEndpoint:"/_boost/g7-debug/dump-state",autoCapture:!0});M(this,"stateHistory",[]);M(this,"snapshotIdCounter",0);M(this,"stateWatchers",new Map);M(this,"currentLocalState",{});M(this,"currentComputedState",{});M(this,"currentParentContext");M(this,"actionHistory",[]);M(this,"actionWatchers",new Set);M(this,"cacheStats",{hits:0,misses:0,entries:0});M(this,"cacheDecisions",[]);M(this,"cacheDecisionIdCounter",0);M(this,"maxCacheDecisions",200);M(this,"currentRenderCycleId",null);M(this,"isInActionExecution",!1);M(this,"isInIteration",!1);M(this,"mountedComponents",new Map);M(this,"eventListeners",new Map);M(this,"mountWatchers",new Set);M(this,"unmountWatchers",new Set);M(this,"renderCounts",new Map);M(this,"bindingEvalCount",0);M(this,"profilingData",[]);M(this,"isProfiling",!1);M(this,"profilingStartTime",0);M(this,"activeRequests",new Map);M(this,"requestHistory",[]);M(this,"pendingDataSources",new Set);M(this,"requestWatchers",new Set);M(this,"wsConnections",new Map);M(this,"wsMessageHistory",[]);M(this,"wsMessageWatchers",new Set);M(this,"ifConditions",new Map);M(this,"iterations",new Map);M(this,"conditionWatchers",new Set);M(this,"forms",new Map);M(this,"formWatchers",new Set);M(this,"expressionHistory",[]);M(this,"expressionWatchers",new Set);M(this,"expressionIdCounter",0);M(this,"dataSources",new Map);M(this,"dataPathTransforms",[]);M(this,"maxDataPathTransforms",100);M(this,"nestedContexts",[]);M(this,"nestedContextIdCounter",0);M(this,"maxNestedContexts",100);M(this,"formBindingIssues",[]);M(this,"formBindingValidations",[]);M(this,"formBindingIssueIdCounter",0);M(this,"maxFormBindingIssues",100);M(this,"computedProperties",new Map);M(this,"computedRecalcLogs",[]);M(this,"computedRecalcIdCounter",0);M(this,"maxComputedRecalcLogs",100);M(this,"handlers",new Map);M(this,"componentEventSubscriptions",new Map);M(this,"componentEventEmitHistory",[]);M(this,"componentEventIdCounter",0);M(this,"maxComponentEventHistory",100);M(this,"stateRenderingLogs",[]);M(this,"currentStateChangeContext",null);M(this,"stateRenderingIdCounter",0);M(this,"componentRenderCounts",new Map);M(this,"stateToComponentMap",new Map);M(this,"maxStateRenderingLogs",100);M(this,"componentStateSources",new Map);M(this,"contextFlowNodes",new Map);M(this,"dynamicStates",new Map);M(this,"styleIssues",[]);M(this,"componentStyles",new Map);M(this,"authEvents",[]);M(this,"authHeaderHistory",[]);M(this,"authEventIdCounter",0);M(this,"maxAuthEventHistory",50);M(this,"logHistory",[]);M(this,"logIdCounter",0);M(this,"maxLogHistory",500);M(this,"currentLayout",null);M(this,"layoutHistory",[]);M(this,"layoutIdCounter",0);M(this,"layoutStats",{totalLoads:0,cacheHits:0,apiLoads:0});M(this,"maxLayoutHistory",50);M(this,"executionDetails",new Map);M(this,"stateChangeHistory",[]);M(this,"dataSourceChangeHistory",[]);M(this,"changeAlerts",[]);M(this,"changeExpectations",new Map);M(this,"executionIdCounter",0);M(this,"stateChangeIdCounter",0);M(this,"alertIdCounter",0);M(this,"maxExecutionDetails",100);M(this,"maxStateChangeHistory",200);M(this,"maxChangeAlerts",100);M(this,"sequenceExecutions",[]);M(this,"sequenceExecutionStack",[]);M(this,"sequenceIdCounter",0);M(this,"maxSequenceExecutions",50);M(this,"staleClosureWarnings",[]);M(this,"staleClosureIdCounter",0);M(this,"maxStaleClosureWarnings",100);M(this,"stateCaptureRegistry",new Map);M(this,"modalStates",new Map);M(this,"modalStateIssues",[]);M(this,"modalStateRelations",[]);M(this,"modalStateChangeLogs",[]);M(this,"modalStateIssueIdCounter",0);M(this,"modalStateChangeLogIdCounter",0);M(this,"maxModalStateIssues",100);M(this,"maxModalStateChangeLogs",200);M(this,"namedActionDefinitions",{});M(this,"namedActionRefLogs",[]);M(this,"namedActionRefIdCounter",0);M(this,"maxNamedActionRefLogs",200);M(this,"debounceActionHistory",[]);M(this,"dataSourceUpdateHistory",[]);M(this,"debounceActionIdCounter",0);M(this,"dataSourceUpdateIdCounter",0)}static getInstance(){return Ti.instance||(Ti.instance=new Ti),Ti.instance}initialize(){if(this.config.enabled=this.checkDebugMode(),!this.config.enabled){console.log("[G7DevTools] 비활성화됨 (환경설정 > 고급 설정 > 디버그 모드를 켜세요)");return}console.log("[G7DevTools] 활성화됨"),this.setupGlobalErrorHandler()}checkDebugMode(){try{if(window.G7Config?.debug===!0)return!0;const r=window.G7Core?.state?.get?.();return r?.settings?.advanced?.debug_mode===!0||r?._global?.settings?.advanced?.debug_mode===!0}catch{return!1}}isEnabled(){return this.config.enabled}setupGlobalErrorHandler(){window.addEventListener("error",e=>{this.config.enabled&&this.logAction({id:this.generateId(),type:"globalError",startTime:Date.now(),status:"error",error:{name:"Error",message:e.message,stack:e.error?.stack}})}),window.addEventListener("unhandledrejection",e=>{this.config.enabled&&this.logAction({id:this.generateId(),type:"unhandledRejection",startTime:Date.now(),status:"error",error:{name:"UnhandledRejection",message:String(e.reason)}})})}captureStateSnapshot(e){if(!this.config.enabled)return;const n={id:++this.snapshotIdCounter,timestamp:Date.now(),source:e.source,prev:this.sanitizeObject(e.prev),next:this.sanitizeObject(e.next),diff:e.diff};this.stateHistory.push(n),this.stateHistory.length>this.config.maxHistorySize&&this.stateHistory.shift(),this.notifyStateWatchers(n)}getState(){try{const e=window.G7Core,n=e?.state?.get?.()||{},r={};if(e?._isolatedStates&&typeof e._isolatedStates=="object")for(const[i,l]of Object.entries(e._isolatedStates))r[i]=this.sanitizeObject(l);return{_global:n._global||n,_local:this.currentLocalState,_computed:this.currentComputedState,_isolated:Object.keys(r).length>0?r:void 0,$parent:this.currentParentContext}}catch{return{_global:{},_local:this.currentLocalState,_computed:this.currentComputedState}}}updateLocalState(e){this.config.enabled&&(this.currentLocalState=this.sanitizeObject(e))}updateComputedState(e){this.config.enabled&&(this.currentComputedState=this.sanitizeObject(e))}updateParentContext(e){this.config.enabled&&(this.currentParentContext=e?this.sanitizeObject(e):void 0)}getStateHistory(){return[...this.stateHistory]}getDualStorageMismatch(){const e=this.currentLocalState||{};let n={};try{n=(window.G7Core?.state?.get?.()||{})._local||{}}catch{n={}}const r=this.findMismatchedLeafPaths(e,n);return{hasMismatch:r.length>0,mismatchedPaths:r,storageA:e,storageB:n}}findMismatchedLeafPaths(e,n,r=""){const i=[],l=new Set([...Object.keys(e||{}),...Object.keys(n||{})]);for(const c of l){const d=r?`${r}.${c}`:c,f=e?.[c],h=n?.[c],m=f&&typeof f=="object"&&!Array.isArray(f),y=h&&typeof h=="object"&&!Array.isArray(h);if(m&&y)i.push(...this.findMismatchedLeafPaths(f,h,d));else{const S=f===void 0?"__undefined__":JSON.stringify(f),v=h===void 0?"__undefined__":JSON.stringify(h);S!==v&&i.push(d)}}return i}watchState(e,n){return this.stateWatchers.has(e)||this.stateWatchers.set(e,new Set),this.stateWatchers.get(e).add(n),()=>{this.stateWatchers.get(e)?.delete(n)}}notifyStateWatchers(e){if(this.stateWatchers.get("*")?.forEach(n=>{try{n(e.next,e.prev,"*")}catch(r){console.error("[G7DevTools] State watcher error:",r)}}),e.diff)for(const n of e.diff.changed)this.stateWatchers.get(n.path)?.forEach(r=>{try{r(n.newValue,n.oldValue,n.path)}catch(i){console.error("[G7DevTools] State watcher error:",i)}})}diffSnapshots(e,n){const r=this.stateHistory.find(l=>l.id===e),i=this.stateHistory.find(l=>l.id===n);return!r||!i?null:this.calculateDiff(r.next,i.next)}calculateDiff(e,n,r=""){const i={added:[],removed:[],changed:[]},l=new Set(Object.keys(e)),c=new Set(Object.keys(n));for(const d of c){const f=r?`${r}.${d}`:d;l.has(d)?JSON.stringify(e[d])!==JSON.stringify(n[d])&&i.changed.push({path:f,oldValue:e[d],newValue:n[d]}):i.added.push(f)}for(const d of l){const f=r?`${r}.${d}`:d;c.has(d)||i.removed.push(f)}return i}logAction(e){if(!this.config.enabled)return;const n=this.actionHistory.findIndex(r=>r.id===e.id);n>=0?this.actionHistory[n]={...this.actionHistory[n],...e}:(this.actionHistory.push(e),this.actionHistory.length>this.config.maxHistorySize&&this.actionHistory.shift()),this.isProfiling&&this.profilingData.push({type:"action",action:e.type,timestamp:performance.now(),duration:e.duration}),this.notifyActionWatchers(e)}getActionHistory(){return[...this.actionHistory]}watchActions(e){return this.actionWatchers.add(e),()=>{this.actionWatchers.delete(e)}}notifyActionWatchers(e){this.actionWatchers.forEach(n=>{try{n(e)}catch(r){console.error("[G7DevTools] Action watcher error:",r)}})}getActionMetrics(){const e=this.actionHistory.filter(l=>l.status==="success"),n=this.actionHistory.filter(l=>l.status==="error"),r={};for(const l of this.actionHistory)r[l.type]=(r[l.type]||0)+1;const i=e.reduce((l,c)=>l+(c.duration||0),0);return{totalActions:this.actionHistory.length,successCount:e.length,errorCount:n.length,averageDuration:e.length>0?i/e.length:0,actionsByType:r}}recordCacheHit(){this.config.enabled&&this.cacheStats.hits++}recordCacheMiss(){this.config.enabled&&this.cacheStats.misses++}updateCacheEntries(e){this.config.enabled&&(this.cacheStats.entries=e)}getCacheStats(){const e=this.cacheStats.hits+this.cacheStats.misses;return{...this.cacheStats,hitRate:e>0?this.cacheStats.hits/e:0}}resetCacheStats(){this.cacheStats={hits:0,misses:0,entries:0}}trackCacheDecision(e){if(!this.config.enabled)return;const n={id:`cache-${++this.cacheDecisionIdCounter}`,timestamp:Date.now(),expression:e.expression,decision:e.decision,reason:e.reason,context:{isInIteration:this.isInIteration,isInAction:this.isInActionExecution,renderCycleId:this.currentRenderCycleId||void 0,componentId:e.componentId,skipCacheOption:e.skipCacheOption},cachedValue:e.cachedValue!==void 0?this.safeClone(e.cachedValue):void 0,freshValue:e.freshValue!==void 0?this.safeClone(e.freshValue):void 0,valueMatch:e.cachedValue!==void 0&&e.freshValue!==void 0?JSON.stringify(e.cachedValue)===JSON.stringify(e.freshValue):void 0,duration:e.duration};this.cacheDecisions.push(n),this.cacheDecisions.length>this.maxCacheDecisions&&this.cacheDecisions.shift(),e.decision==="cache_hit"?this.cacheStats.hits++:(e.decision==="cache_miss"||e.decision==="skip_cache")&&this.cacheStats.misses++}startRenderCycle(e){return this.currentRenderCycleId=`render-${Date.now()}-${e||"root"}`,this.currentRenderCycleId}endRenderCycle(){this.currentRenderCycleId=null}startActionContext(){this.isInActionExecution=!0}endActionContext(){this.isInActionExecution=!1}startIterationContext(){this.isInIteration=!0}endIterationContext(){this.isInIteration=!1}getCacheDecisionTrackingInfo(){const e=this.getCacheDecisionStats();return{decisions:[...this.cacheDecisions],stats:e,timestamp:Date.now()}}getCacheDecisionStats(){const e=this.cacheDecisions;let n=0,r=0,i=0,l=0;const c={},d={};for(const h of e)h.decision==="cache_hit"?n++:h.decision==="cache_miss"?r++:h.decision==="skip_cache"?i++:h.decision==="invalidate"&&l++,c[h.reason]=(c[h.reason]||0)+1,h.context.componentId&&(d[h.context.componentId]=(d[h.context.componentId]||0)+1);const f=n+r+i;return{totalDecisions:e.length,cacheHits:n,cacheMisses:r,skipCacheCount:i,invalidateCount:l,byReason:c,byComponent:d,avgHitRate:f>0?n/f:0}}getRecentCacheDecisions(e=20,n){let r=[...this.cacheDecisions];return n&&(r=r.filter(i=>i.decision===n)),r.slice(-e)}clearCacheDecisionData(){this.cacheDecisions=[],this.cacheDecisionIdCounter=0}summarizePropsForLifecycle(e){if(!e||typeof e!="object")return e;const n={},r=["children","ref","key"];for(const[i,l]of Object.entries(e))if(!r.includes(i))if(l==null)n[i]=l;else if(Array.isArray(l))n[i]=`[Array(${l.length})]`;else if(typeof l=="object"){const c=Object.keys(l);c.length<=3?n[i]=`{${c.join(", ")}}`:n[i]=`{${c.slice(0,3).join(", ")}, ... +${c.length-3}}`}else typeof l=="string"&&l.length>50?n[i]=l.substring(0,50)+"...":typeof l=="function"?n[i]="[Function]":n[i]=l;return n}trackMount(e,n){if(!this.config.enabled)return;const r=this.summarizePropsForLifecycle(n.props),i={...n,props:r,id:e,mountTime:Date.now()};this.mountedComponents.set(e,i),this.mountWatchers.forEach(l=>{try{l({componentId:e,componentName:n.name,timestamp:i.mountTime})}catch(c){console.error("[G7DevTools] Mount watcher error:",c)}})}trackUnmount(e){if(!this.config.enabled)return;const n=this.mountedComponents.get(e),r=this.eventListeners.get(e)||[];r.length>0&&console.warn(`[G7DevTools] 컴포넌트 ${e} 언마운트 시 ${r.length}개 리스너 미정리`),n&&this.unmountWatchers.forEach(i=>{try{i({componentId:e,componentName:n.name,timestamp:Date.now(),orphanedListeners:r.length})}catch(l){console.error("[G7DevTools] Unmount watcher error:",l)}}),this.mountedComponents.delete(e)}trackListener(e,n,r){if(!this.config.enabled)return;const i=this.eventListeners.get(e)||[];i.push({type:n,target:r,addedAt:Date.now()}),this.eventListeners.set(e,i)}removeListener(e,n){if(!this.config.enabled)return;const r=this.eventListeners.get(e)||[],i=r.findIndex(l=>l.type===n);i>=0&&r.splice(i,1)}getMountedComponents(){return Array.from(this.mountedComponents.values())}getOrphanedListeners(){const e=[];for(const[n,r]of this.eventListeners)this.mountedComponents.has(n)||e.push(...r.map(i=>({...i,componentId:n})));return e}watchMount(e){return this.mountWatchers.add(e),()=>{this.mountWatchers.delete(e)}}watchUnmount(e){return this.unmountWatchers.add(e),()=>{this.unmountWatchers.delete(e)}}trackRender(e){if(!this.config.enabled)return;const n=this.renderCounts.get(e)||0;this.renderCounts.set(e,n+1),this.isProfiling&&this.profilingData.push({type:"render",component:e,timestamp:performance.now()})}trackBindingEval(e){this.config.enabled&&(this.bindingEvalCount++,this.isProfiling&&e&&this.profilingData.push({type:"binding",expression:e,timestamp:performance.now()}))}getRenderCount(){return new Map(this.renderCounts)}getBindingEvalCount(){return this.bindingEvalCount}getMemoryWarnings(){const e=[];try{const i=this.getState(),l=JSON.stringify(i).length;l>1e6&&e.push({type:"large-state",message:`상태 크기가 ${(l/1024/1024).toFixed(2)}MB입니다`,suggestion:"불필요한 데이터 정리 필요",severity:l>5e6?"error":"warning"})}catch{}this.stateHistory.length>this.config.maxHistorySize*.8&&e.push({type:"large-history",message:`상태 이력이 ${this.stateHistory.length}개입니다`,suggestion:"maxHistory 설정 조정 필요",severity:"warning"});const n=this.getOrphanedListeners().length;n>0&&e.push({type:"orphaned-listeners",message:`${n}개의 정리되지 않은 이벤트 리스너`,suggestion:"useEffect cleanup 또는 removeEventListener 확인",severity:n>10?"error":"warning"});const r=Array.from(this.renderCounts.entries()).filter(([,i])=>i>50);return r.length>0&&e.push({type:"excessive-renders",message:`${r.length}개 컴포넌트가 50회 이상 렌더링`,suggestion:"React.memo, useMemo, useCallback 사용 고려",severity:"warning"}),e}startProfiling(){this.config.enabled&&(this.isProfiling=!0,this.profilingData=[],this.profilingStartTime=performance.now(),console.log("[G7DevTools] 프로파일링 시작"))}stopProfiling(){this.isProfiling=!1;const e=performance.now()-this.profilingStartTime,n=this.analyzeProfile(e);return console.log("[G7DevTools] 프로파일링 완료",n),n}analyzeProfile(e){const n=this.profilingData.filter(h=>h.type==="render"),r=this.profilingData.filter(h=>h.type==="binding"),i=this.profilingData.filter(h=>h.type==="action"),l={};for(const h of n)h.component&&(l[h.component]||(l[h.component]={count:0,durations:[]}),l[h.component].count++,h.duration&&l[h.component].durations.push(h.duration));const c=Object.entries(l).map(([h,m])=>({name:h,renderCount:m.count,avgDuration:m.durations.length>0?m.durations.reduce((y,S)=>y+S,0)/m.durations.length:0})).sort((h,m)=>m.renderCount-h.renderCount).slice(0,10),d={};for(const h of r)h.expression&&(d[h.expression]=(d[h.expression]||0)+1);const f=Object.entries(d).sort(([,h],[,m])=>m-h).slice(0,10).map(([h])=>h);return{duration:e,entries:this.profilingData,summary:{totalRenders:n.length,totalBindings:r.length,totalActions:i.length,slowestComponents:c,hotPaths:f}}}resetPerformanceStats(){this.renderCounts.clear(),this.bindingEvalCount=0,this.profilingData=[]}trackRequest(e,n,r){if(!this.config.enabled)return"";const i=this.generateId(),l=MA(e),c=$A(e);return this.activeRequests.set(i,{id:i,url:l,fullUrl:e,queryParams:c,method:n,startTime:Date.now(),status:"pending",requestBody:r?.requestBody?this.sanitizeObject(r.requestBody):void 0,dataSourceId:r?.dataSourceId}),this.isProfiling&&this.profilingData.push({type:"network",timestamp:performance.now()}),i}completeRequest(e,n,r){if(!this.config.enabled)return;const i=this.activeRequests.get(e);if(!i)return;const l={...i,status:n>=200&&n<300?"success":"error",statusCode:n,duration:Date.now()-i.startTime,endTime:Date.now(),response:this.sanitizeObject(r)};this.requestHistory.push(l),this.activeRequests.delete(e),this.requestHistory.length>this.config.maxHistorySize&&this.requestHistory.shift(),this.notifyRequestWatchers(l)}failRequest(e,n){if(!this.config.enabled)return;const r=this.activeRequests.get(e);if(!r)return;const i={...r,status:"error",error:n,duration:Date.now()-r.startTime,endTime:Date.now()};this.requestHistory.push(i),this.activeRequests.delete(e),this.notifyRequestWatchers(i)}trackDataSource(e){this.config.enabled&&this.pendingDataSources.add(e)}completeDataSource(e){this.config.enabled&&this.pendingDataSources.delete(e)}getActiveRequests(){return Array.from(this.activeRequests.values())}getRequestHistory(){return[...this.requestHistory]}getPendingDataSources(){return Array.from(this.pendingDataSources)}watchRequest(e){return this.requestWatchers.add(e),()=>{this.requestWatchers.delete(e)}}notifyRequestWatchers(e){this.requestWatchers.forEach(n=>{try{n(e)}catch(r){console.error("[G7DevTools] Request watcher error:",r)}})}trackWebSocketConnection(e,n,r){this.config.enabled&&this.wsConnections.set(e,{id:e,url:n,state:r,connectedAt:r==="open"?Date.now():void 0})}trackWebSocketMessage(e,n,r,i){if(!this.config.enabled)return;const l={id:this.generateId(),connectionId:e,direction:n,type:r,payload:this.sanitizeObject(i),timestamp:Date.now(),sequence:this.wsMessageHistory.length};this.wsMessageHistory.push(l),this.wsMessageHistory.length>this.config.maxHistorySize&&this.wsMessageHistory.shift(),this.notifyWebSocketWatchers(l)}getWebSocketConnections(){return Array.from(this.wsConnections.values())}getWebSocketMessageHistory(){return[...this.wsMessageHistory]}getWebSocketConnectionState(){const e=Array.from(this.wsConnections.values());return e.some(n=>n.state==="open")?"connected":e.some(n=>n.state==="connecting")?"reconnecting":"disconnected"}watchWebSocketMessage(e){return this.wsMessageWatchers.add(e),()=>{this.wsMessageWatchers.delete(e)}}notifyWebSocketWatchers(e){this.wsMessageWatchers.forEach(n=>{try{n(e)}catch(r){console.error("[G7DevTools] WebSocket watcher error:",r)}})}trackIfCondition(e,n,r){if(!this.config.enabled)return;const i=this.ifConditions.get(e),l=i?.evaluatedValue;this.ifConditions.set(e,{id:e,expression:n,evaluatedValue:r,evaluationCount:(i?.evaluationCount||0)+1,lastEvaluated:Date.now()}),i&&l!==r&&this.notifyConditionWatchers({id:e,expression:n,oldValue:l,newValue:r,timestamp:Date.now()})}trackIteration(e,n){this.config.enabled&&this.iterations.set(e,{id:e,...n,lastRendered:Date.now()})}getIfConditions(){return Array.from(this.ifConditions.values())}getIterations(){return Array.from(this.iterations.values())}getScopeChain(e){const n=[],r=this.getState();return n.push({name:"_global",value:r._global,source:"global"}),n.push({name:"_local",value:r._local,source:"local"}),n.push({name:"_computed",value:r._computed,source:"computed"}),n}watchConditionChange(e){return this.conditionWatchers.add(e),()=>{this.conditionWatchers.delete(e)}}notifyConditionWatchers(e){this.conditionWatchers.forEach(n=>{try{n(e)}catch(r){console.error("[G7DevTools] Condition watcher error:",r)}})}trackForm(e,n,r){this.config.enabled&&this.forms.set(e,{id:e,dataKey:n,inputs:r,trackedAt:Date.now()})}trackFormChange(e,n,r){if(!this.config.enabled)return;const i={formId:e,inputName:n,value:r,timestamp:Date.now()};this.notifyFormWatchers(i)}untrackForm(e){this.forms.delete(e)}getForms(){return Array.from(this.forms.values())}getFormState(e){const n=this.getState();return this.getNestedValue(n,e)||{}}getBindingPath(e,n){return`${e}.${n}`}watchFormChange(e){return this.formWatchers.add(e),()=>{this.formWatchers.delete(e)}}notifyFormWatchers(e){this.formWatchers.forEach(n=>{try{n(e)}catch(r){console.error("[G7DevTools] Form watcher error:",r)}})}trackFormBindingIssue(e,n,r){if(!this.config.enabled)return;const i={id:`form-issue-${++this.formBindingIssueIdCounter}`,timestamp:Date.now(),type:e,severity:n,formId:r.formId,formDataKey:r.formDataKey,inputInfo:r.inputInfo,contextInfo:r.contextInfo,description:r.description,suggestion:r.suggestion,docLink:r.docLink};this.formBindingIssues.push(i),this.formBindingIssues.length>this.maxFormBindingIssues&&this.formBindingIssues.shift()}validateFormBinding(e,n,r,i){const l=r.map(f=>{const h=[];let m=!0;return f.name||(h.push("Input에 name 속성이 없습니다"),m=!1,this.trackFormBindingIssue("missing-input-name","error",{formId:e,formDataKey:n,inputInfo:{name:f.name,type:f.type},description:"Input에 name 속성이 없어 자동 바인딩이 동작하지 않습니다",suggestion:"Input에 name 속성을 추가하세요",docLink:"troubleshooting-components-form.md"})),n||(h.push("Form에 dataKey가 없습니다"),m=!1),{inputName:f.name||"(unnamed)",inputType:f.type,bindingPath:n&&f.name?`${n}.${f.name}`:"-",isValid:m,currentValue:f.value,issues:h}});if(n||this.trackFormBindingIssue("missing-datakey","error",{formId:e,description:"Form에 dataKey가 설정되지 않아 자동 바인딩이 동작하지 않습니다",suggestion:"Form 컴포넌트에 dataKey props를 설정하세요",docLink:"troubleshooting-components-form.md"}),i.isContextBroken){const f=i.breakReason?.includes("sortable")?"sortable-context-break":i.breakReason?.includes("modal")?"modal-context-isolation":"context-not-propagated";this.trackFormBindingIssue(f,"warning",{formId:e,formDataKey:n,contextInfo:{hasParentFormContext:i.hasParentContext,parentFormContextProp:i.parentContextProp,isInsideSortable:i.breakReason?.includes("sortable")||!1,isInsideModal:i.breakReason?.includes("modal")||!1,depth:0},description:i.breakReason||"Form 컨텍스트가 제대로 전파되지 않았습니다",suggestion:"parentFormContextProp={undefined}를 확인하거나 중첩 구조를 검토하세요",docLink:"troubleshooting-components-form.md"})}const c={formId:e,dataKey:n,timestamp:Date.now(),contextPropagation:i,inputBindings:l,isValid:l.every(f=>f.isValid)&&!!n&&!i.isContextBroken,issueCount:l.filter(f=>!f.isValid).length+(n?0:1)+(i.isContextBroken?1:0)},d=this.formBindingValidations.findIndex(f=>f.formId===e);return d>=0?this.formBindingValidations[d]=c:this.formBindingValidations.push(c),c}getFormBindingValidationTrackingInfo(){const e=this.getFormBindingValidationStats();return{issues:[...this.formBindingIssues],validations:[...this.formBindingValidations],stats:e,timestamp:Date.now()}}getFormBindingValidationStats(){const e={"missing-datakey":0,"missing-input-name":0,"context-not-propagated":0,"sortable-context-break":0,"modal-context-isolation":0,"duplicate-input-name":0,"value-type-mismatch":0,"binding-path-invalid":0},n={info:0,warning:0,error:0};for(const i of this.formBindingIssues)e[i.type]++,n[i.severity]++;const r=Object.entries(e).filter(([,i])=>i>0).sort((i,l)=>l[1]-i[1]).slice(0,5).map(([i,l])=>({type:i,count:l,description:this.getIssueTypeDescription(i)}));return{totalFormsValidated:this.formBindingValidations.length,validForms:this.formBindingValidations.filter(i=>i.isValid).length,formsWithIssues:this.formBindingValidations.filter(i=>!i.isValid).length,totalIssues:this.formBindingIssues.length,byIssueType:e,bySeverity:n,topIssues:r}}getIssueTypeDescription(e){return{"missing-datakey":"Form에 dataKey 누락","missing-input-name":"Input에 name 속성 누락","context-not-propagated":"Form 컨텍스트 전파 실패","sortable-context-break":"Sortable 컨테이너에서 컨텍스트 단절","modal-context-isolation":"모달에서 부모 Form 컨텍스트 격리","duplicate-input-name":"동일 Form 내 중복 Input name","value-type-mismatch":"값 타입과 Input 타입 불일치","binding-path-invalid":"바인딩 경로 유효하지 않음"}[e]||e}clearFormBindingIssues(){this.formBindingIssues=[],this.formBindingValidations=[],this.formBindingIssueIdCounter=0}trackComputedProperty(e,n,r,i,l,c,d){if(!this.config.enabled)return;const f=`computed-${e}-${c||"global"}`,h={id:f,name:e,expression:n,componentId:c,dependencies:r,currentValue:this.safeClone(i),lastComputedAt:Date.now(),computationTime:l,error:d};this.computedProperties.set(f,h)}trackComputedRecalc(e,n,r,i,l,c,d){if(!this.config.enabled)return;const f=`computed-${e}-${d||"global"}`,h=JSON.stringify(r)!==JSON.stringify(i),m={id:`recalc-${++this.computedRecalcIdCounter}`,computedId:f,computedName:e,timestamp:Date.now(),trigger:n,triggeredBy:c,previousValue:this.safeClone(r),newValue:this.safeClone(i),valueChanged:h,computationTime:l,cascadeCount:0};this.computedRecalcLogs.push(m),this.computedRecalcLogs.length>this.maxComputedRecalcLogs&&this.computedRecalcLogs.shift();const y=this.computedProperties.get(f);y&&(y.currentValue=this.safeClone(i),y.lastComputedAt=Date.now(),y.computationTime=l)}analyzeComputedDependencyChain(e,n){const r=new Set,i=[];let l=!1,c,d=0;const f=(m,y)=>{if(d=Math.max(d,y),r.has(m))return l=!0,c=[...i,m],{name:m,type:"computed",children:[],depth:y};r.add(m),i.push(m);const S=this.computedProperties.get(`computed-${m}-${n||"global"}`),v=[];if(S)for(const _ of S.dependencies)_.type==="computed"?v.push(f(_.path,y+1)):v.push({name:_.path,type:_.type,children:[],depth:y+1});return i.pop(),r.delete(m),{name:m,type:"computed",children:v,depth:y}},h=f(e,0);return{root:e,tree:h,hasCycle:l,cyclePath:c,maxDepth:d}}getComputedDependencyTrackingInfo(){const e=Array.from(this.computedProperties.values()),n=this.getComputedDependencyStats(),r=[];for(const i of e){const l=this.analyzeComputedDependencyChain(i.name,i.componentId);r.push(l)}return{properties:e,recalcLogs:[...this.computedRecalcLogs],dependencyChains:r,stats:n,timestamp:Date.now()}}getComputedDependencyStats(){const e={"state-change":0,"datasource-update":0,"dependency-change":0,manual:0,initial:0},n={},r={};let i=0,l=0;for(const h of this.computedRecalcLogs)e[h.trigger]++,h.valueChanged||l++,n[h.computedName]=(n[h.computedName]||0)+1,r[h.computedName]||(r[h.computedName]=[]),r[h.computedName].push(h.computationTime),i+=h.computationTime;const c=Object.entries(n).sort((h,m)=>m[1]-h[1]).slice(0,5).map(([h,m])=>({name:h,count:m})),d=Object.entries(r).map(([h,m])=>({name:h,avgTime:m.reduce((y,S)=>y+S,0)/m.length})).sort((h,m)=>m.avgTime-h.avgTime).slice(0,5);let f=0;for(const h of this.computedProperties.values())this.analyzeComputedDependencyChain(h.name,h.componentId).hasCycle&&f++;return{totalComputed:this.computedProperties.size,totalRecalculations:this.computedRecalcLogs.length,unnecessaryRecalculations:l,avgComputationTime:this.computedRecalcLogs.length>0?i/this.computedRecalcLogs.length:0,topRecalculated:c,slowestComputed:d,cycleDetectionCount:f,byTrigger:e}}clearComputedTracking(){this.computedProperties.clear(),this.computedRecalcLogs=[],this.computedRecalcIdCounter=0}trackModalOpen(e){if(!this.config.enabled)return;const n={modalId:e.modalId,modalName:e.modalName,openedAt:Date.now(),closedAt:null,scopeType:e.scopeType||"isolated",parentModalId:e.parentModalId,componentId:e.componentId,initialState:e.initialState?{...e.initialState}:{},currentState:e.initialState?{...e.initialState}:{},stateChangeCount:0,isolatedStateKeys:e.isolatedStateKeys||[],sharedStateKeys:e.sharedStateKeys||[]};this.modalStates.set(e.modalId,n),this.validateModalDefinitionExists(e.modalId,e.modalName),e.parentModalId&&(this.modalStateRelations.find(i=>i.parentModalId===e.parentModalId&&i.childModalId===e.modalId)||this.modalStateRelations.push({parentModalId:e.parentModalId,childModalId:e.modalId,sharedKeys:e.sharedStateKeys||[],isolatedKeys:e.isolatedStateKeys||[],relationType:"parent-child"}))}trackModalClose(e,n){if(!this.config.enabled)return;const r=this.modalStates.get(e);r&&(r.closedAt=Date.now(),n&&(r.currentState={...n}),this.detectStateLeakage(r))}validateModalDefinitionExists(e,n){const r=this.currentLayout;if(!r?.layoutJson)return;const i=r.layoutJson.modals;if(!i){this.recordModalStateIssue({type:"missing-definition",modalId:e,modalName:n,severity:"error",description:`모달 "${e}"이(가) modalStack에 추가되었으나, 현재 레이아웃에 modals 섹션이 없습니다. 레이아웃 경로: ${r.layoutPath}`,affectedStateKeys:[],expectedValue:`modals 섹션에 id="${e}" 정의 존재`,actualValue:"modals 섹션 없음"});return}const l=Array.isArray(i)?i:Object.values(i);l.some(d=>d?.id===e||d?.props?.id===e)||this.recordModalStateIssue({type:"missing-definition",modalId:e,modalName:n,severity:"error",description:`모달 "${e}"이(가) modalStack에 추가되었으나, 렌더링된 레이아웃의 modals 섹션에 해당 ID의 정의가 없습니다. partial 로딩 실패, 레이아웃 병합 문제, extends 상속 누락 등을 확인하세요. 레이아웃 경로: ${r.layoutPath}`,affectedStateKeys:[],expectedValue:`modals 배열에 id="${e}" 항목 존재`,actualValue:`modals 배열에 ${l.length}개 모달 정의 (${l.map(d=>d?.id||"unknown").join(", ")})`})}trackModalStateChange(e){if(!this.config.enabled)return;const n=this.modalStates.get(e.modalId);if(!n)return;n.stateChangeCount++,n.currentState[e.stateKey]=e.newValue;const r=this.checkIsolationViolation(n,e.stateKey),i={id:`modal-change-${++this.modalStateChangeLogIdCounter}`,modalId:e.modalId,modalName:n.modalName,timestamp:Date.now(),stateKey:e.stateKey,previousValue:e.previousValue,newValue:e.newValue,changeSource:e.changeSource||"user-action",violatesIsolation:r};this.modalStateChangeLogs.push(i),this.modalStateChangeLogs.length>this.maxModalStateChangeLogs&&this.modalStateChangeLogs.shift(),r&&this.recordModalStateIssue({type:"isolation-violation",modalId:e.modalId,modalName:n.modalName,severity:"warning",description:`모달 '${n.modalName}'에서 격리된 상태 키 '${e.stateKey}'가 변경됨`,affectedStateKeys:[e.stateKey]})}detectStateLeakage(e){if(e.scopeType==="isolated")for(const n of e.isolatedStateKeys){const r=e.initialState[n],i=e.currentState[n];if(r!==i&&e.parentModalId){const l=this.modalStates.get(e.parentModalId);l&&l.currentState.hasOwnProperty(n)&&this.recordModalStateIssue({type:"state-leakage",modalId:e.modalId,modalName:e.modalName,severity:"error",description:`모달 닫힘 후 상태 '${n}'가 부모 모달로 유출될 수 있음`,affectedStateKeys:[n],leakedValue:i,expectedValue:r})}}}checkIsolationViolation(e,n){return e.scopeType==="isolated",!1}recordModalStateIssue(e){const n={id:`modal-issue-${++this.modalStateIssueIdCounter}`,type:e.type,modalId:e.modalId,modalName:e.modalName,timestamp:Date.now(),severity:e.severity,description:e.description,affectedStateKeys:e.affectedStateKeys,leakedValue:e.leakedValue,expectedValue:e.expectedValue,actualValue:e.actualValue,stackInfo:e.stackInfo};this.modalStateIssues.push(n),this.modalStateIssues.length>this.maxModalStateIssues&&this.modalStateIssues.shift()}getModalStateScopeTrackingInfo(){const e=Array.from(this.modalStates.values()),n=this.getModalStateScopeStats();return{modals:e,issues:[...this.modalStateIssues],relations:[...this.modalStateRelations],changeLogs:[...this.modalStateChangeLogs],stats:n,timestamp:Date.now()}}getModalStateScopeStats(){const e=Array.from(this.modalStates.values()),n={warning:0,error:0},r={"state-leakage":0,"isolation-violation":0,"parent-mutation":0,"orphaned-state":0,"scope-mismatch":0,"cleanup-failure":0,"missing-definition":0};for(const l of this.modalStateIssues)n[l.severity]++,r[l.type]++;const i={isolated:0,shared:0,inherited:0};for(const l of e)i[l.scopeType]++;return{totalModals:e.length,openModals:e.filter(l=>l.closedAt===null).length,nestedModals:e.filter(l=>l.parentModalId!==void 0).length,totalIssues:this.modalStateIssues.length,issuesBySeverity:n,issuesByType:r,byScope:i,leakageDetectionCount:r["state-leakage"],cleanupFailureCount:r["cleanup-failure"]}}clearModalStateScopeTracking(){this.modalStates.clear(),this.modalStateIssues=[],this.modalStateRelations=[],this.modalStateChangeLogs=[],this.modalStateIssueIdCounter=0,this.modalStateChangeLogIdCounter=0}setNamedActionDefinitions(e){this.config.enabled&&(this.namedActionDefinitions=e||{})}trackNamedActionRef(e){if(!this.config.enabled)return;const n={...e,id:`named_action_ref_${++this.namedActionRefIdCounter}`};this.namedActionRefLogs.push(n),this.namedActionRefLogs.length>this.maxNamedActionRefLogs&&(this.namedActionRefLogs=this.namedActionRefLogs.slice(-this.maxNamedActionRefLogs))}getNamedActionTrackingInfo(){const e={};for(const r of this.namedActionRefLogs)e[r.actionRefName]=(e[r.actionRefName]||0)+1;const n=Object.keys(this.namedActionDefinitions).filter(r=>!e[r]);return{definitions:this.namedActionDefinitions,refLogs:[...this.namedActionRefLogs],stats:{totalDefinitions:Object.keys(this.namedActionDefinitions).length,totalRefs:this.namedActionRefLogs.length,refCountByName:e,unusedDefinitions:n},timestamp:Date.now()}}clearNamedActionTracking(){this.namedActionDefinitions={},this.namedActionRefLogs=[],this.namedActionRefIdCounter=0}trackExpressionEval(e){if(!this.config.enabled)return;const n={...e,id:`expr-${++this.expressionIdCounter}`,timestamp:Date.now(),warning:this.detectExpressionWarning(e)};this.expressionHistory.push(n),this.expressionHistory.length>500&&this.expressionHistory.shift(),this.isProfiling&&this.profilingData.push({type:"binding",expression:e.expression,timestamp:performance.now(),duration:e.duration}),this.notifyExpressionWatchers(n)}detectExpressionWarning(e){const{expression:n,result:r,resultType:i,method:l,duration:c}=e;if(i==="undefined"&&!n.includes("??")&&!n.includes("||")&&/^[a-zA-Z_$][a-zA-Z0-9_$.]*$/.test(n.replace(/{{|}}/g,"").trim()))return{type:"undefined-result",message:"표현식 결과가 undefined입니다",suggestion:`데이터가 로드되었는지 확인하거나 fallback 값을 추가하세요: ${n} ?? ''`};if(i==="null")return{type:"null-result",message:"표현식 결과가 null입니다",suggestion:`nullish coalescing 연산자를 사용하세요: ${n} ?? ''`};if(l==="resolveBindings"&&i==="string"){const d=String(r);if(d.includes("[object Object]")||/^\[.*\]$/.test(d))return{type:"array-to-string",message:"배열/객체가 문자열로 변환되었습니다",suggestion:"evaluateExpression()을 사용하여 원본 타입을 유지하세요"}}if(l==="resolveBindings"&&i==="string"&&String(r).includes("[object Object]"))return{type:"object-to-string",message:"객체가 [object Object]로 변환되었습니다",suggestion:"evaluateExpression()을 사용하거나 특정 속성에 접근하세요"};if(i==="undefined"&&n.includes(".")&&!n.includes("?.")){const d=n.replace(/{{|}}/g,"").trim().split(".");if(d.length>=2)return{type:"missing-optional-chain",message:"Optional chaining(?.) 누락 가능성",suggestion:`안전한 접근을 위해 ?. 사용을 고려하세요: ${d.join("?.")}`}}if((n.includes("{{item.")||n.includes("{{index}}"))&&Array.from(this.iterations.values()).some(h=>h.itemVar!=="item"))return{type:"wrong-iteration-var",message:"'item'/'index' 대신 iteration에서 정의한 변수명을 사용해야 합니다",suggestion:"iteration의 item_var/index_var에 정의된 변수명을 확인하세요"};if(c&&c>10)return{type:"slow-evaluation",message:`표현식 평가에 ${c.toFixed(2)}ms 소요됨`,suggestion:"복잡한 표현식을 단순화하거나 computed 값으로 분리하세요"}}getExpressions(){return[...this.expressionHistory]}getExpressionWarnings(){return this.expressionHistory.filter(e=>e.warning!=null)}searchExpressions(e){const n=e.toLowerCase();return this.expressionHistory.filter(r=>r.expression.toLowerCase().includes(n)||r.componentName?.toLowerCase().includes(n)||r.propName?.toLowerCase().includes(n))}getExpressionStats(){const e=this.expressionHistory,n=new Set(e.map(f=>f.expression)),r=e.filter(f=>f.warning!=null),i=e.filter(f=>f.fromCache),l=e.filter(f=>f.duration!=null).map(f=>f.duration),c={};for(const f of e)c[f.resultType]=(c[f.resultType]||0)+1;const d={};for(const f of r)f.warning&&(d[f.warning.type]=(d[f.warning.type]||0)+1);return{totalEvaluations:e.length,uniqueExpressions:n.size,warningCount:r.length,cacheHitRate:e.length>0?i.length/e.length:0,averageDuration:l.length>0?l.reduce((f,h)=>f+h,0)/l.length:0,byType:c,byWarning:d}}clearExpressions(){this.expressionHistory=[],this.expressionIdCounter=0}watchExpressions(e){return this.expressionWatchers.add(e),()=>{this.expressionWatchers.delete(e)}}notifyExpressionWatchers(e){this.expressionWatchers.forEach(n=>{try{n(e)}catch(r){console.error("[G7DevTools] Expression watcher error:",r)}})}setLogLevel(e){this.config.logLevel=e}setMaxHistory(e){this.config.maxHistorySize=Math.max(10,Math.min(1e3,e))}setServerEndpoint(e){this.config.serverEndpoint=e}getConfig(){return{...this.config}}generateId(){return`${Date.now()}-${Math.random().toString(36).substr(2,9)}`}sanitizeObject(e,n=new WeakSet){if(e===null||typeof e!="object")return e;if(n.has(e))return"[Circular]";if(n.add(e),Array.isArray(e))return e.map(i=>this.sanitizeObject(i,n));const r={};for(const i of Object.keys(e))try{r[i]=this.sanitizeObject(e[i],n)}catch{r[i]="[Unable to serialize]"}return r}getNestedValue(e,n){if(!n)return e;const r=n.split(".");let i=e;for(const l of r){if(i==null)return;i=i[l]}return i}getLifecycleInfo(){return{mountedComponents:Array.from(this.mountedComponents.values()),orphanedListeners:this.getOrphanedListeners()}}getPerformanceInfo(){return{renderCounts:this.renderCounts,bindingEvalCount:this.bindingEvalCount,memoryWarnings:this.getMemoryWarnings()}}getNetworkInfo(){return{activeRequests:Array.from(this.activeRequests.values()),requestHistory:[...this.requestHistory],pendingDataSources:Array.from(this.pendingDataSources)}}getConditionalInfo(){return{ifConditions:Array.from(this.ifConditions.values()),iterations:Array.from(this.iterations.values())}}getFormInfo(){return Array.from(this.forms.values())}getWebSocketInfo(){return{connections:Array.from(this.wsConnections.values()),messageHistory:[...this.wsMessageHistory],connectionState:this.getWebSocketConnectionState()}}getStateAtTime(e){const n=[...this.stateHistory].reverse().find(r=>r.timestamp<=e);if(n)return{_global:n.next,_local:{}}}reset(){this.stateHistory=[],this.actionHistory=[],this.cacheStats={hits:0,misses:0,entries:0},this.cacheDecisions=[],this.cacheDecisionIdCounter=0,this.currentRenderCycleId=null,this.isInActionExecution=!1,this.isInIteration=!1,this.mountedComponents.clear(),this.eventListeners.clear(),this.renderCounts.clear(),this.bindingEvalCount=0,this.profilingData=[],this.activeRequests.clear(),this.requestHistory=[],this.pendingDataSources.clear(),this.wsConnections.clear(),this.wsMessageHistory=[],this.ifConditions.clear(),this.iterations.clear(),this.forms.clear(),this.expressionHistory=[],this.expressionIdCounter=0,this.dataSources.clear(),this.dataPathTransforms=[],this.nestedContexts=[],this.nestedContextIdCounter=0,this.formBindingIssues=[],this.formBindingValidations=[],this.formBindingIssueIdCounter=0,this.computedProperties.clear(),this.computedRecalcLogs=[],this.computedRecalcIdCounter=0,this.modalStates.clear(),this.modalStateIssues=[],this.modalStateRelations=[],this.modalStateChangeLogs=[],this.modalStateIssueIdCounter=0,this.modalStateChangeLogIdCounter=0,this.logHistory=[],this.logIdCounter=0}getExpressionInfo(){return{expressions:this.getExpressions(),stats:this.getExpressionStats()}}trackLog(e,n,r){if(!this.config.enabled)return;const i=r.map(c=>{if(typeof c=="string")return c;try{return JSON.stringify(c)}catch{return String(c)}}).join(" "),l={id:`log-${++this.logIdCounter}`,level:e,prefix:n,message:i,args:this.sanitizeObject(r),timestamp:Date.now(),stack:e==="error"?new Error().stack:void 0};this.logHistory.push(l),this.logHistory.length>this.maxLogHistory&&this.logHistory.shift()}trackAction(e){if(!this.config.enabled)return;const n={id:`debounce-action-${++this.debounceActionIdCounter}`,...e,timestamp:Date.now()};this.debounceActionHistory.push(n),this.debounceActionHistory.length>100&&this.debounceActionHistory.shift()}trackDataSourceUpdate(e){if(!this.config.enabled)return;const n={id:`ds-update-${++this.dataSourceUpdateIdCounter}`,...e};this.dataSourceUpdateHistory.push(n),this.dataSourceUpdateHistory.length>100&&this.dataSourceUpdateHistory.shift()}getDebounceActionHistory(e){let n=[...this.debounceActionHistory];return e?.handler&&(n=n.filter(r=>r.handler.includes(e.handler))),e?.status&&(n=n.filter(r=>r.status===e.status)),e?.limit&&(n=n.slice(-e.limit)),n}getDataSourceUpdateHistory(e){let n=[...this.dataSourceUpdateHistory];return e?.dataSourceId&&(n=n.filter(r=>r.dataSourceId===e.dataSourceId)),e?.updateType&&(n=n.filter(r=>r.updateType===e.updateType)),e?.limit&&(n=n.slice(-e.limit)),n}getLogs(e){let n=[...this.logHistory];if(e?.level){const r=Array.isArray(e.level)?e.level:[e.level];n=n.filter(i=>r.includes(i.level))}if(e?.prefix){const r=e.prefix.toLowerCase();n=n.filter(i=>i.prefix.toLowerCase().includes(r))}if(e?.search){const r=e.search.toLowerCase();n=n.filter(i=>i.message.toLowerCase().includes(r))}return e?.since&&(n=n.filter(r=>r.timestamp>=e.since)),e?.limit&&(n=n.slice(-e.limit)),n}getLogStats(){const n=Date.now()-6e4,r={log:0,warn:0,error:0,debug:0,info:0},i={};let l=0,c=0;for(const d of this.logHistory)r[d.level]++,i[d.prefix]=(i[d.prefix]||0)+1,d.timestamp>=n&&(d.level==="error"&&l++,d.level==="warn"&&c++);return{totalLogs:this.logHistory.length,byLevel:r,byPrefix:i,recentErrors:l,recentWarnings:c}}clearLogs(){this.logHistory=[],this.logIdCounter=0}getLogInfo(){return{entries:this.getLogs(),stats:this.getLogStats()}}trackDataSourceDefinition(e){this.config.enabled&&this.dataSources.set(e.id,{...e,status:"idle"})}trackDataSourceLoading(e){if(!this.config.enabled)return;const n=this.dataSources.get(e);n&&this.dataSources.set(e,{...n,status:"loading"})}trackDataSourceLoaded(e,n,r){if(!this.config.enabled)return;const i=this.dataSources.get(e);if(!i)return;let l,c,d=r;n&&(Array.isArray(n)?(l=n.length,c=n.length>0&&typeof n[0]=="object"?Object.keys(n[0]):void 0):typeof n=="object"&&(Array.isArray(n.data)?(d=d||"data",l=n.data.length,c=n.data.length>0&&typeof n.data[0]=="object"?Object.keys(n.data[0]):void 0):Array.isArray(n.items)?(d=d||"items",l=n.items.length,c=n.items.length>0&&typeof n.items[0]=="object"?Object.keys(n.items[0]):void 0):c=Object.keys(n))),this.dataSources.set(e,{...i,status:"loaded",dataPath:d,itemCount:l,keys:c,lastLoadedAt:Date.now(),error:void 0})}trackDataSourceError(e,n){if(!this.config.enabled)return;const r=this.dataSources.get(e);r&&this.dataSources.set(e,{...r,status:"error",error:n,lastLoadedAt:Date.now()})}untrackDataSource(e){this.dataSources.delete(e)}getDataSources(){return Array.from(this.dataSources.values())}getDataSource(e){return this.dataSources.get(e)}clearDataSources(){this.dataSources.clear()}trackDataPathTransform(e){if(!this.config.enabled)return;let n=this.dataPathTransforms.find(r=>r.dataSourceId===e.dataSourceId);n||(n={dataSourceId:e.dataSourceId,timestamp:Date.now(),transformSteps:[],warnings:[]},this.dataPathTransforms.push(n),this.dataPathTransforms.length>this.maxDataPathTransforms&&this.dataPathTransforms.shift()),n.transformSteps.push({step:e.step,inputPath:e.inputPath,inputValue:this.safeClone(e.inputValue),outputPath:e.outputPath,outputValue:this.safeClone(e.outputValue),config:e.config}),e.warning&&n.warnings.push(e.warning)}setDataPathFinalBinding(e,n){if(!this.config.enabled)return;const r=this.dataPathTransforms.find(i=>i.dataSourceId===e);r&&(r.finalBinding={expression:n.expression,resolvedPath:n.resolvedPath,value:this.safeClone(n.value)})}getDataPathTransformTrackingInfo(){const e=this.getDataPathTransformStats();return{transforms:[...this.dataPathTransforms],stats:e,timestamp:Date.now()}}getDataPathTransformStats(){const e=this.dataPathTransforms,n={};let r=0;const i={};for(const c of e){n[c.dataSourceId]=(n[c.dataSourceId]||0)+1,r+=c.warnings.length;for(const d of c.warnings)i[d]=(i[d]||0)+1}const l=Object.entries(i).map(([c,d])=>({warning:c,count:d})).sort((c,d)=>d.count-c.count).slice(0,10);return{totalTransforms:e.length,byDataSource:n,warningsCount:r,commonWarnings:l}}getDataPathTransformForDataSource(e){return this.dataPathTransforms.find(n=>n.dataSourceId===e)}clearDataPathTransforms(){this.dataPathTransforms=[]}trackNestedContext(e){if(!this.config.enabled)return"";const n=`nested-${++this.nestedContextIdCounter}`,r=[...new Set([...e.parentContext.available,...e.ownContext.added])],i={...e.parentContext.values,...e.ownContext.values},l={id:n,timestamp:Date.now(),componentId:e.componentId,componentType:e.componentType,parentContext:{available:e.parentContext.available,values:this.safeClone(e.parentContext.values)},ownContext:{added:e.ownContext.added,values:this.safeClone(e.ownContext.values)},mergedContext:{all:r,values:this.safeClone(i)},accessAttempts:[],depth:e.depth,parentId:e.parentId};return this.nestedContexts.push(l),this.nestedContexts.length>this.maxNestedContexts&&this.nestedContexts.shift(),n}trackNestedContextAccess(e,n){if(!this.config.enabled)return;const r=this.nestedContexts.find(i=>i.id===e);r&&r.accessAttempts.push({path:n.path,found:n.found,value:n.found?this.safeClone(n.value):void 0,error:n.error})}getNestedContextTrackingInfo(){const e=this.getNestedContextStats();return{contexts:[...this.nestedContexts],stats:e,timestamp:Date.now()}}getNestedContextStats(){const e=this.nestedContexts,n={expandChildren:0,cellChildren:0,iteration:0,modal:0,slot:0};let r=0,i=0;const l={};for(const d of e){n[d.componentType]++,d.depth>r&&(r=d.depth);for(const f of d.accessAttempts)f.found||(i++,l[f.path]=(l[f.path]||0)+1)}const c=Object.entries(l).map(([d,f])=>({path:d,count:f})).sort((d,f)=>f.count-d.count).slice(0,10);return{totalContexts:e.length,byType:n,maxDepth:r,failedAccessCount:i,commonFailedPaths:c}}getNestedContextForComponent(e){return this.nestedContexts.find(n=>n.componentId===e)}clearNestedContexts(){this.nestedContexts=[],this.nestedContextIdCounter=0}trackHandlerRegistration(e,n="custom",r,i){this.isEnabled&&this.handlers.set(e,{name:e,category:n,description:r,registeredAt:Date.now(),source:i})}trackHandlerUnregistration(e){this.isEnabled&&this.handlers.delete(e)}getHandlers(){return Array.from(this.handlers.values())}getHandler(e){return this.handlers.get(e)}getHandlersByCategory(e){return Array.from(this.handlers.values()).filter(n=>n.category===e)}clearHandlers(){this.handlers.clear()}trackEventSubscribe(e){if(!this.isEnabled)return;const n=this.componentEventSubscriptions.get(e),r=Date.now();n?(n.subscriberCount++,n.lastSubscribedAt=r):this.componentEventSubscriptions.set(e,{eventName:e,subscriberCount:1,firstSubscribedAt:r,lastSubscribedAt:r})}trackEventUnsubscribe(e){if(!this.isEnabled)return;const n=this.componentEventSubscriptions.get(e);n&&(n.subscriberCount--,n.subscriberCount<=0&&this.componentEventSubscriptions.delete(e))}trackEventEmit(e,n,r,i,l){if(!this.isEnabled)return;const c={id:`evt_${++this.componentEventIdCounter}`,eventName:e,data:this.sanitizeForLogging(n),timestamp:Date.now(),listenerCount:r,results:i?this.sanitizeForLogging(i):void 0,hasError:!!l,errorMessage:l?.message};this.componentEventEmitHistory.push(c),this.componentEventEmitHistory.length>this.maxComponentEventHistory&&(this.componentEventEmitHistory=this.componentEventEmitHistory.slice(-this.maxComponentEventHistory))}trackEventOff(e){this.isEnabled&&this.componentEventSubscriptions.delete(e)}trackEventClear(){this.isEnabled&&this.componentEventSubscriptions.clear()}getComponentEventInfo(){const e=Array.from(this.componentEventSubscriptions.values());return{subscriptions:e,emitHistory:[...this.componentEventEmitHistory],totalSubscribers:e.reduce((n,r)=>n+r.subscriberCount,0),totalEmits:this.componentEventEmitHistory.length}}getEventEmitHistory(){return[...this.componentEventEmitHistory]}getEventSubscriptions(){return Array.from(this.componentEventSubscriptions.values())}clearComponentEvents(){this.componentEventSubscriptions.clear(),this.componentEventEmitHistory=[],this.componentEventIdCounter=0}sanitizeForLogging(e){if(e==null||typeof e!="object")return e;try{return JSON.parse(JSON.stringify(e))}catch{return"[Circular or Non-serializable]"}}startStateChange(e,n,r,i){if(!this.config.enabled)return"";const l=`setState_${++this.stateRenderingIdCounter}`;this.currentStateChangeContext={setStateId:l,startTime:performance.now(),changedPath:e,trigger:i||{},renderedComponents:[]};const c={id:`sr_${this.stateRenderingIdCounter}`,setStateId:l,statePath:e,oldValue:this.sanitizeForLogging(n),newValue:this.sanitizeForLogging(r),timestamp:Date.now(),triggeredBy:i||{},renderedComponents:[],totalRenderDuration:0,affectedBindingsCount:0};return this.stateRenderingLogs.push(c),this.stateRenderingLogs.length>this.maxStateRenderingLogs&&this.stateRenderingLogs.shift(),l}trackComponentRender(e,n,r,i=[],l=[],c){if(!this.config.enabled)return;const d=this.componentRenderCounts.get(n)||0;this.componentRenderCounts.set(n,d+1);for(const f of i)this.stateToComponentMap.has(f)||this.stateToComponentMap.set(f,new Set),this.stateToComponentMap.get(f).add(n);if(this.currentStateChangeContext){const f={componentId:e,componentName:n,renderDuration:r,accessedStatePaths:i,evaluatedBindings:l,renderOrder:this.currentStateChangeContext.renderedComponents.length,parentId:c};this.currentStateChangeContext.renderedComponents.push(f)}this.trackRender(n)}completeStateChange(e){if(!this.config.enabled||!this.currentStateChangeContext||this.currentStateChangeContext.setStateId!==e)return;const n=this.currentStateChangeContext,i=performance.now()-n.startTime,l=this.stateRenderingLogs.findIndex(c=>c.setStateId===e);if(l>=0){const c=this.stateRenderingLogs[l];c.renderedComponents=n.renderedComponents,c.totalRenderDuration=i,c.affectedBindingsCount=n.renderedComponents.reduce((d,f)=>d+f.evaluatedBindings.length,0)}this.currentStateChangeContext=null}getCurrentStateChangeContext(){return this.currentStateChangeContext}getStateRenderingLogs(){return[...this.stateRenderingLogs]}getStateRenderingInfo(){const e=this.stateRenderingLogs,n=Object.fromEntries(this.componentRenderCounts),r={};for(const[i,l]of this.stateToComponentMap)r[i]=Array.from(l);return{logs:e,componentRenderCounts:n,stateToComponentMap:r,stats:this.calculateStateRenderingStats()}}calculateStateRenderingStats(){const e=this.stateRenderingLogs;if(e.length===0)return{totalStateChanges:0,totalRenders:0,avgRenderDuration:0,avgComponentsPerChange:0,topRenderedComponents:[],topInfluentialPaths:[]};const n=e.reduce((d,f)=>d+f.renderedComponents.length,0),r=e.reduce((d,f)=>d+f.totalRenderDuration,0)/e.length,i=n/e.length,l=Array.from(this.componentRenderCounts.entries()).sort((d,f)=>f[1]-d[1]).slice(0,5).map(([d,f])=>({name:d,count:f})),c=Array.from(this.stateToComponentMap.entries()).sort((d,f)=>f[1].size-d[1].size).slice(0,5).map(([d,f])=>({path:d,affectedComponents:f.size}));return{totalStateChanges:e.length,totalRenders:n,avgRenderDuration:r,avgComponentsPerChange:i,topRenderedComponents:l,topInfluentialPaths:c}}getComponentsAffectedByState(e){const n=this.stateToComponentMap.get(e);return n?Array.from(n):[]}getComponentRenderHistory(e){return this.stateRenderingLogs.filter(n=>n.renderedComponents.some(r=>r.componentName===e))}clearStateRenderingLogs(){this.stateRenderingLogs=[],this.componentRenderCounts.clear(),this.stateToComponentMap.clear(),this.currentStateChangeContext=null,this.stateRenderingIdCounter=0}trackComponentStateSource(e,n,r,i){this.config.enabled&&this.componentStateSources.set(e,{componentId:e,componentName:n,stateSource:r,stateProvider:i})}trackDynamicState(e,n){this.config.enabled&&this.dynamicStates.set(e,n)}trackContextFlow(e,n,r,i,l,c){if(!this.config.enabled)return;const d={component:n,componentId:e,contextReceived:r,passedToChildren:i,usedInRender:l};if(this.contextFlowNodes.set(e,d),c){const f=this.contextFlowNodes.get(c);f&&(f.children||(f.children=[]),f.children.push(d))}}getStateHierarchyInfo(e=!0){const n=this.buildStateHierarchyLayers(),r=this.detectStateConflicts(n),i=Array.from(this.componentStateSources.values());return{layers:e?n.map(c=>({...c,values:this.summarizeValues(c.values,2)})):n,conflicts:r,componentStateSources:i,timestamp:Date.now()}}summarizeValues(e,n,r=0){if(e==null)return e;if(typeof e!="object")return typeof e=="string"&&e.length>100?e.substring(0,100)+`... (${e.length}자)`:e;if(r>=n){if(Array.isArray(e))return`[Array(${e.length})]`;const c=Object.keys(e);return`{${c.slice(0,5).join(", ")}${c.length>5?`, ... +${c.length-5}`:""}}`}if(Array.isArray(e))return e.length<=3?e.map(c=>this.summarizeValues(c,n,r+1)):{__type:"array",__length:e.length,__preview:e.slice(0,3).map(c=>this.summarizeValues(c,n,r+1))};const i={},l=Object.keys(e);for(const c of l)i[c]=this.summarizeValues(e[c],n,r+1);return i}buildStateHierarchyLayers(){const e=[];try{const r=window.G7Core?.state?.get?.();if(!r)return e;r._local&&e.push({name:"Global _local",type:"global",path:"_local",values:r._local,priority:1}),r._global&&e.push({name:"Global _global",type:"global",path:"_global",values:r._global,priority:1});for(const[l,c]of this.dynamicStates)c&&Object.keys(c).length>0&&e.push({name:`DynamicState (${l})`,type:"dynamicState",componentId:l,values:c,priority:2});const i=this.computeEffectiveState(r._local||{});e.push({name:"Effective _local (merged)",type:"effective",values:i,priority:3})}catch(n){console.warn("[G7DevTools] 상태 계층 빌드 실패:",n)}return e}computeEffectiveState(e){const n={...e};for(const[,r]of this.dynamicStates)r._local&&Object.assign(n,r._local);return n}detectStateConflicts(e){const n=[],r=e.find(l=>l.type==="global"&&l.path==="_local");if(!r)return n;const i=e.filter(l=>l.type==="dynamicState");for(const l of i){const c=l.values._local||l.values;for(const[d,f]of Object.entries(c)){const h=r.values[d];if(JSON.stringify(h)!==JSON.stringify(f)){const m=[],y=[];for(const S of this.componentStateSources.values())S.stateSource.local.some(_=>_===`_local.${d}`||_===d)&&(S.stateProvider.type==="dynamicState"?m.push(S.componentName):S.stateProvider.type==="globalState"&&y.push(S.componentName));n.push({path:`_local.${d}`,globalValue:h,dynamicStateValue:f,effectiveValue:f,usedBy:m,notUsedBy:y,severity:y.length>0?"warning":"info",description:y.length>0?`${y.join(", ")}은(는) globalState._local을 읽어 dynamicState 값을 사용하지 못함`:"dynamicState 값이 globalState와 다르지만 모든 컴포넌트가 dynamicState를 사용"})}}}return n}getContextFlowInfo(){const e=[],n=new Set(this.contextFlowNodes.keys());for(const r of this.contextFlowNodes.values())if(r.children)for(const i of r.children)n.delete(i.componentId);for(const r of n){const i=this.contextFlowNodes.get(r);i&&e.push(i)}return{rootComponent:e.length>0?e[0].component:"Unknown",contextFlow:e,timestamp:Date.now()}}clearStateHierarchyData(){this.componentStateSources.clear(),this.contextFlowNodes.clear(),this.dynamicStates.clear()}trackComponentStyle(e,n,r,i){if(!this.config.enabled)return;const l=this.analyzeTailwindClasses(r),c={componentId:e,componentName:n,classes:r,computedStyles:i,tailwindAnalysis:l};this.componentStyles.set(e,c),this.detectStyleIssues(c)}analyzeTailwindClasses(e){const n=[],r=[],i=[],l=[],c=["sm:","md:","lg:","xl:","2xl:"],d=[/bg-\w+-\d+/,/text-\w+-\d+/,/border-\w+-\d+/];for(const f of e){l.push(f),f.startsWith("dark:")&&n.push(f);for(const h of c)if(f.startsWith(h)){r.push(f);break}for(const h of d)if(h.test(f)){i.push(f);break}}return{usedClasses:l,darkClasses:n,responsiveClasses:r,dynamicClasses:i}}detectStyleIssues(e){const{componentId:n,componentName:r,computedStyles:i,tailwindAnalysis:l}=e;(i.opacity==="0"||i.visibility==="hidden"||i.display==="none"||i.width==="0px"&&i.height==="0px")&&this.addStyleIssue({id:this.generateId(),type:"invisible-element",componentId:n,componentName:r,property:i.opacity==="0"?"opacity":i.visibility==="hidden"?"visibility":i.display==="none"?"display":"width/height",currentValue:i.opacity==="0"?"0":i.visibility==="hidden"?"hidden":i.display==="none"?"none":"0px",severity:"warning",description:"요소가 화면에 보이지 않습니다.",suggestion:"opacity, visibility, display, width/height 값을 확인하세요."});const c=l.usedClasses.filter(f=>f.startsWith("bg-")&&!f.startsWith("dark:")),d=l.darkClasses.filter(f=>f.includes("bg-"));c.length>0&&d.length===0&&this.addStyleIssue({id:this.generateId(),type:"dark-mode-missing",componentId:n,componentName:r,property:"background-color",currentValue:c.join(", "),expectedValue:"dark:bg-* 클래스 필요",severity:"info",description:"다크 모드 배경색 클래스가 누락되었습니다.",suggestion:`${c[0]}에 대응하는 dark: 클래스를 추가하세요.`}),l.dynamicClasses.length>0&&this.addStyleIssue({id:this.generateId(),type:"tailwind-purging",componentId:n,componentName:r,property:"class",currentValue:l.dynamicClasses.join(", "),severity:"info",description:"동적으로 생성된 Tailwind 클래스가 있습니다.",suggestion:"tailwind.config.js의 safelist에 추가하거나 전체 클래스명을 상수로 정의하세요."})}addStyleIssue(e){this.styleIssues.some(r=>r.componentId===e.componentId&&r.type===e.type&&r.property===e.property)||this.styleIssues.push(e)}getStyleValidationInfo(){const e=Array.from(this.componentStyles.values());return{issues:[...this.styleIssues],componentStyles:e,stats:{totalComponents:e.length,invisibleCount:this.styleIssues.filter(n=>n.type==="invisible-element").length,tailwindIssueCount:this.styleIssues.filter(n=>n.type==="tailwind-purging").length,darkModeIssueCount:this.styleIssues.filter(n=>n.type==="dark-mode-missing").length},timestamp:Date.now()}}clearStyleValidationData(){this.styleIssues=[],this.componentStyles.clear()}trackAuthEvent(e,n,r,i){if(!this.config.enabled)return;const l={id:`auth_${++this.authEventIdCounter}`,type:e,timestamp:Date.now(),success:n,error:r,details:i};this.authEvents.push(l),this.authEvents.length>this.maxAuthEventHistory&&(this.authEvents=this.authEvents.slice(-this.maxAuthEventHistory))}trackAuthHeader(e,n,r,i,l){if(!this.config.enabled)return;const c={url:e,hasAuthHeader:n,headerType:r,tokenValid:i??!1,responseStatus:l,timestamp:Date.now()};this.authHeaderHistory.push(c),this.authHeaderHistory.length>this.maxAuthEventHistory&&(this.authHeaderHistory=this.authHeaderHistory.slice(-this.maxAuthEventHistory)),l===401&&this.trackAuthEvent("api-unauthorized",!1,`401 Unauthorized: ${e}`,{url:e})}getAuthState(){try{const e=window.G7Core,n=e?.api;let r=e?.auth;!r&&e?.AuthManager?.getInstance&&(r=e.AuthManager.getInstance());const i=n?.getToken?.()||r?.getAccessToken?.()||localStorage.getItem("auth_token")||localStorage.getItem("access_token"),l=r?.getRefreshToken?.()||localStorage.getItem("refresh_token");let c="unknown",d=r?.getUser?.();if(d&&(c="AuthManager"),!d){const v=e?.state?.get?.();d=v?._global?.user||v?._global?.currentUser||v?.user||v?.currentUser,d&&(c="G7Core.state")}const f=r?.isAuthenticated?.()??!1;let h="memory";localStorage.getItem("auth_token")||localStorage.getItem("access_token")?h="localStorage":(sessionStorage.getItem("auth_token")||sessionStorage.getItem("access_token"))&&(h="sessionStorage");const m=!!i&&(!!d||f);let y;i&&typeof i=="string"&&i.length>20?y=`${i.substring(0,10)}...${i.substring(i.length-6)}`:i&&(y="***");const S=d?{id:d.id,email:d.email,name:d.name,roles:d.roles?.map(v=>typeof v=="string"?{name:v}:{id:v.id,name:v.name,guard_name:v.guard_name}),permissions:d.permissions?.map(v=>typeof v=="string"?{name:v}:{id:v.id,name:v.name,guard_name:v.guard_name}),avatar:d.avatar||d.profile_photo_url||d.profile_image,created_at:d.created_at,updated_at:d.updated_at,last_login_at:d.last_login_at,email_verified_at:d.email_verified_at,...d.phone&&{phone:d.phone},...d.nickname&&{nickname:d.nickname},...d.status&&{status:d.status},...d.locale&&{locale:d.locale}}:void 0;return{isAuthenticated:m,user:S,tokens:{hasAccessToken:!!i,hasRefreshToken:!!l,storage:h,accessTokenPreview:y},lastActivity:Date.now(),source:c}}catch{return{isAuthenticated:!1,tokens:{hasAccessToken:!1,hasRefreshToken:!1,storage:"memory"},source:"unknown"}}}getAuthDebugInfo(){const e=[...this.authEvents];return{state:this.getAuthState(),events:e,headerAnalysis:[...this.authHeaderHistory],stats:{loginAttempts:e.filter(n=>n.type==="login").length,successfulLogins:e.filter(n=>n.type==="login"&&n.success).length,failedLogins:e.filter(n=>n.type==="login"&&!n.success).length,tokenRefreshes:e.filter(n=>n.type==="token-refresh").length,unauthorizedResponses:e.filter(n=>n.type==="api-unauthorized").length},timestamp:Date.now()}}clearAuthData(){this.authEvents=[],this.authHeaderHistory=[],this.authEventIdCounter=0}trackLayoutLoad(e,n,r,i="api"){if(!this.config.enabled)return;const l=Date.now();this.currentLayout={layoutPath:e,templateId:n,layoutJson:this.sanitizeObject(r),loadedAt:l,version:r.version,layoutName:r.layout_name,source:i};const c={id:`layout-${++this.layoutIdCounter}`,layoutPath:e,templateId:n,loadedAt:l,source:i,version:r.version};this.layoutHistory.push(c),this.layoutHistory.length>this.maxLayoutHistory&&this.layoutHistory.shift(),this.layoutStats.totalLoads++,i==="cache"?this.layoutStats.cacheHits++:this.layoutStats.apiLoads++}getCurrentLayout(){return this.currentLayout}getLayoutHistory(){return[...this.layoutHistory]}getLayoutDebugInfo(){return{current:this.currentLayout,history:[...this.layoutHistory],stats:{...this.layoutStats}}}clearLayoutData(){this.currentLayout=null,this.layoutHistory=[],this.layoutIdCounter=0,this.layoutStats={totalLoads:0,cacheHits:0,apiLoads:0}}startHandlerExecution(e){if(!this.config.enabled)return"";const n=`exec_${++this.executionIdCounter}_${Date.now()}`,r={handlerName:e,executionId:n,startTime:Date.now(),stateChanges:[],dataSourceChanges:[],alerts:[]};if(this.executionDetails.set(n,r),this.executionDetails.size>this.maxExecutionDetails){const i=Array.from(this.executionDetails.keys());i.slice(0,i.length-this.maxExecutionDetails).forEach(c=>this.executionDetails.delete(c))}return n}endHandlerExecution(e,n,r,i){if(!this.config.enabled||!e)return;const l=this.executionDetails.get(e);if(!l)return;l.endTime=Date.now(),l.duration=l.endTime-l.startTime,l.exitReason=n,l.exitLocation=r,l.exitDescription=i;const c=this.changeExpectations.get(e);c&&(l.expectedChanges=c,this.checkExpectations(e,l,c),this.changeExpectations.delete(e)),n==="normal"&&l.stateChanges.length===0&&l.dataSourceChanges.length===0&&this.addChangeAlert(e,{type:"no-state-change",severity:"warning",message:`핸들러 "${l.handlerName}"이(가) 상태 변경 없이 완료됨`,description:"핸들러가 성공적으로 완료되었지만 상태나 데이터소스 변경이 없습니다. 의도한 동작인지 확인하세요.",handlerName:l.handlerName,suggestion:'핸들러 내부 조건문을 확인하거나 DevTools의 "변경감지" 탭에서 exitLocation을 확인하세요.',docLink:"troubleshooting-state.md"}),(n==="early-return-condition"||n==="early-return-validation")&&this.addChangeAlert(e,{type:"early-return-detected",severity:"info",message:`핸들러 "${l.handlerName}"이(가) early return으로 종료됨`,description:i||`종료 위치: ${r||"알 수 없음"}`,handlerName:l.handlerName,suggestion:n==="early-return-validation"?"검증 실패로 인한 early return입니다. 입력 데이터를 확인하세요.":"조건부 early return입니다. 조건문의 평가 결과를 확인하세요."})}recordExitReason(e,n,r,i){if(!this.config.enabled||!e)return;const l=this.executionDetails.get(e);l&&(l.exitReason=n,l.exitLocation=r,l.exitDescription=i)}recordStateChange(e,n,r,i,l){if(!this.config.enabled)return;const c={id:`sc_${++this.stateChangeIdCounter}`,path:n,changeType:r,oldValue:this.safeClone(i),newValue:this.safeClone(l),timestamp:Date.now(),comparison:this.compareValues(i,l),executionId:e};if(this.stateChangeHistory.push(c),e){const d=this.executionDetails.get(e);d&&d.stateChanges.push(c)}this.stateChangeHistory.length>this.maxStateChangeHistory&&this.stateChangeHistory.splice(0,this.stateChangeHistory.length-this.maxStateChangeHistory),c.comparison.isDeepEqual&&typeof i=="object"&&i!==null&&this.addChangeAlert(e||"",{type:"object-reference-same",severity:"warning",message:`상태 "${n}"가 변경되었으나 값이 동일함`,description:"객체 참조가 동일하거나 깊은 비교 결과 변경이 없습니다. 변경 감지가 실패할 수 있습니다.",handlerName:e&&this.executionDetails.get(e)?.handlerName||"unknown",statePath:n,suggestion:"불변성을 유지하여 새 객체를 생성하세요. 예: { ...oldObject, newField: value }",docLink:"troubleshooting-state.md#object-mutation"})}recordDataSourceChange(e,n,r,i,l){if(!this.config.enabled)return;const c={dataSourceId:n,changeType:r,timestamp:Date.now(),previousStatus:i,newStatus:l,executionId:e};if(this.dataSourceChangeHistory.push(c),e){const d=this.executionDetails.get(e);d&&d.dataSourceChanges.push(c)}this.dataSourceChangeHistory.length>this.maxStateChangeHistory&&this.dataSourceChangeHistory.splice(0,this.dataSourceChangeHistory.length-this.maxStateChangeHistory)}expectChange(e,n,r){if(!this.config.enabled||!e)return;const i=this.executionDetails.get(e);if(!i)return;const l={expectedStatePaths:n,expectedDataSources:r,setAt:Date.now(),source:i.handlerName};this.changeExpectations.set(e,l)}checkExpectations(e,n,r){const i=new Set(n.stateChanges.map(c=>c.path)),l=new Set(n.dataSourceChanges.map(c=>c.dataSourceId));for(const c of r.expectedStatePaths)i.has(c)||this.addChangeAlert(e,{type:"expected-not-fulfilled",severity:"error",message:`기대한 상태 변경 "${c}"가 발생하지 않음`,description:`핸들러 "${n.handlerName}"이(가) "${c}" 변경을 예고했지만 실제로 변경되지 않았습니다.`,handlerName:n.handlerName,statePath:c,suggestion:"핸들러 내부 로직을 확인하세요. early return이나 조건부 분기로 인해 변경이 생략되었을 수 있습니다.",docLink:"troubleshooting-state.md"});for(const c of r.expectedDataSources)l.has(c)||this.addChangeAlert(e,{type:"expected-not-fulfilled",severity:"error",message:`기대한 데이터소스 갱신 "${c}"가 발생하지 않음`,description:`핸들러 "${n.handlerName}"이(가) "${c}" 갱신을 예고했지만 실제로 갱신되지 않았습니다.`,handlerName:n.handlerName,dataSourceId:c,suggestion:"refetchDataSource 호출이 실행되었는지 확인하세요.",docLink:"data-sources.md"})}addChangeAlert(e,n){const r={...n,id:`alert_${++this.alertIdCounter}`,timestamp:Date.now()};if(this.changeAlerts.push(r),e){const i=this.executionDetails.get(e);i&&i.alerts.push(r)}this.changeAlerts.length>this.maxChangeAlerts&&this.changeAlerts.splice(0,this.changeAlerts.length-this.maxChangeAlerts)}compareValues(e,n){const r=this.getValueType(e),i=this.getValueType(n),l=r!==i;let c=!1,d;return!l&&(r==="object"||r==="array")?(c=this.deepEqual(e,n),!c&&r==="object"&&(d=this.getChangedKeys(e,n))):c=e===n,{typeChanged:l,oldType:r,newType:i,isDeepEqual:c,changedKeys:d}}getValueType(e){return e===null?"null":e===void 0?"undefined":Array.isArray(e)?"array":typeof e}deepEqual(e,n){if(e===n)return!0;if(typeof e!=typeof n)return!1;if(e===null||n===null||typeof e!="object")return e===n;if(Array.isArray(e)!==Array.isArray(n))return!1;const r=Object.keys(e),i=Object.keys(n);if(r.length!==i.length)return!1;for(const l of r)if(!i.includes(l)||!this.deepEqual(e[l],n[l]))return!1;return!0}getChangedKeys(e,n){const r=[],i=new Set([...Object.keys(e),...Object.keys(n)]);for(const l of i)this.deepEqual(e[l],n[l])||r.push(l);return r}getChangeDetectionInfo(){const e=Array.from(this.executionDetails.values()),n={totalExecutions:e.length,executionsWithStateChange:e.filter(r=>r.stateChanges.length>0).length,executionsWithoutStateChange:e.filter(r=>r.stateChanges.length===0&&r.exitReason==="normal").length,earlyReturnCount:e.filter(r=>r.exitReason==="early-return-condition"||r.exitReason==="early-return-validation").length,alertCount:this.changeAlerts.length,alertsByType:this.getAlertsByType()};return{executionDetails:e,stateChangeHistory:[...this.stateChangeHistory],dataSourceChangeHistory:[...this.dataSourceChangeHistory],alerts:[...this.changeAlerts],stats:n,timestamp:Date.now()}}getAlertsByType(){const e={"no-state-change":0,"no-datasource-change":0,"expected-not-fulfilled":0,"object-reference-same":0,"early-return-detected":0,"async-timing-issue":0};for(const n of this.changeAlerts)e[n.type]++;return e}clearChangeDetectionData(){this.executionDetails.clear(),this.stateChangeHistory=[],this.dataSourceChangeHistory=[],this.changeAlerts=[],this.changeExpectations.clear(),this.executionIdCounter=0,this.stateChangeIdCounter=0,this.alertIdCounter=0}getRecentAlerts(e=10,n){let r=[...this.changeAlerts];return n&&(r=r.filter(i=>i.severity===n)),r.slice(-e)}getHandlerExecutions(e,n=10){return Array.from(this.executionDetails.values()).filter(i=>i.handlerName===e).slice(-n)}findExecutionInStack(e){return this.sequenceExecutionStack.find(n=>n.sequenceId===e)}startSequenceExecution(e){if(!this.config.enabled)return"";const n=`seq_${++this.sequenceIdCounter}_${Date.now()}`,r={sequenceId:n,startTime:Date.now(),totalDuration:0,trigger:e,actions:[],status:"running"};return this.sequenceExecutionStack.push(r),n}captureSequenceActionBefore(e,n,r,i,l){if(!this.config.enabled)return;const c=this.findExecutionInStack(e);if(!c)return;const d={index:n,handler:r,params:this.safeClone(i),stateBeforeAction:{_global:this.safeClone(l._global),_local:this.safeClone(l._local),_isolated:l._isolated?this.safeClone(l._isolated):void 0},stateAfterAction:{_global:{},_local:{}},duration:0,status:"success"};c.actions.push(d)}captureSequenceActionAfter(e,n,r,i,l,c){if(!this.config.enabled)return;const d=this.findExecutionInStack(e);if(!d)return;const f=d.actions.find(m=>m.index===n);if(!f)return;f.stateAfterAction={_global:this.safeClone(r._global),_local:this.safeClone(r._local),_isolated:r._isolated?this.safeClone(r._isolated):void 0},f.duration=i,f.result=this.safeClone(l),f.stateDiff={global:this.computeStateDiff(f.stateBeforeAction._global,f.stateAfterAction._global),local:this.computeStateDiff(f.stateBeforeAction._local,f.stateAfterAction._local)},f.stateBeforeAction._isolated&&f.stateAfterAction._isolated&&(f.stateDiff.isolated=this.computeStateDiff(f.stateBeforeAction._isolated,f.stateAfterAction._isolated));const h=window.__g7PendingLocalState;h&&(f.pendingState=this.safeClone(h)),c&&(f.status="error",f.error={name:c.name,message:c.message,stack:c.stack})}endSequenceExecution(e,n){if(!this.config.enabled)return;const r=this.sequenceExecutionStack.findIndex(l=>l.sequenceId===e);if(r===-1)return;const i=this.sequenceExecutionStack[r];if(i.endTime=Date.now(),i.totalDuration=i.endTime-i.startTime,n){i.status="error",i.error={name:n.name,message:n.message,stack:n.stack};const l=i.actions.find(c=>c.status==="error");l&&(i.failedAtIndex=l.index)}else i.status="success";this.sequenceExecutions.push(i),this.sequenceExecutions.length>this.maxSequenceExecutions&&this.sequenceExecutions.shift(),this.sequenceExecutionStack.splice(r,1)}computeStateDiff(e,n){const r=[],i=[],l=[],c=new Set(Object.keys(e)),d=new Set(Object.keys(n));for(const f of d)c.has(f)||r.push(f);for(const f of c)d.has(f)||i.push(f);for(const f of c)if(d.has(f)){const h=e[f],m=n[f];JSON.stringify(h)!==JSON.stringify(m)&&l.push({path:f,oldValue:h,newValue:m})}return{added:r,removed:i,changed:l}}getSequenceTrackingInfo(){const e=this.getSequenceStats(),n=this.sequenceExecutionStack.length>0?this.sequenceExecutionStack[this.sequenceExecutionStack.length-1]:void 0;return{executions:[...this.sequenceExecutions],currentExecution:n,stats:e}}getSequenceStats(){const e=this.sequenceExecutions,n=e.length,r=e.filter(h=>h.status==="success").length,i=e.filter(h=>h.status==="error").length,l=e.reduce((h,m)=>h+m.actions.length,0),c=n>0?e.reduce((h,m)=>h+m.totalDuration,0)/n:0,d={};for(const h of e)for(const m of h.actions)d[m.handler]=(d[m.handler]||0)+1;const f=Object.entries(d).sort(([,h],[,m])=>m-h).slice(0,5).map(([h,m])=>({handler:h,count:m}));return{totalExecutions:n,successCount:r,errorCount:i,totalActions:l,avgDuration:c,topHandlers:f}}clearSequenceData(){this.sequenceExecutions=[],this.sequenceExecutionStack=[],this.sequenceIdCounter=0}getSequenceExecution(e){const n=this.findExecutionInStack(e);return n||this.sequenceExecutions.find(r=>r.sequenceId===e)}getRecentSequences(e=10){return this.sequenceExecutions.slice(-e)}registerStateCaptureForHandler(e,n,r){if(!this.config.enabled)return;const i=new Map,l=Date.now();for(const c of n)i.set(c,{value:this.safeClone(r[c]),capturedAt:l});this.stateCaptureRegistry.set(e,i)}detectStaleClosure(e,n,r,i,l){if(!this.config.enabled)return[];const c=this.stateCaptureRegistry.get(e);if(!c)return[];const d=Date.now(),f=[];for(const[h,m]of c){const y=this.getValueByPath(r,h),S=d-m.capturedAt;if(!this.isDeepEqual(m.value,y)&&S>0){const v=this.createStaleClosureWarning(i,n,h,m.value,m.capturedAt,y,d,S,l);f.push(v),this.addStaleClosureWarning(v)}}return this.stateCaptureRegistry.delete(e),f}trackStaleClosureWarning(e){if(!this.config.enabled)return;const n=Date.now(),r=this.createStaleClosureWarning(e.type,e.location,e.capturedPath,e.capturedValue,e.capturedAt,e.currentValue,n,n-e.capturedAt,e.actionId,e.stackTrace);this.addStaleClosureWarning(r)}createStaleClosureWarning(e,n,r,i,l,c,d,f,h,m){const y=this.getStaleClosureSeverity(e,f),{description:S,suggestion:v,docLink:_}=this.getStaleClosureMessages(e,r,f);return{id:`stale_${++this.staleClosureIdCounter}_${Date.now()}`,timestamp:Date.now(),type:e,location:n,capturedState:{path:r,capturedValue:this.safeClone(i),capturedAt:l},currentState:{path:r,currentValue:this.safeClone(c),retrievedAt:d},timeDiff:f,severity:y,description:S,suggestion:v,docLink:_,actionId:h,stackTrace:m}}getStaleClosureSeverity(e,n){if(n>5e3)return"error";if(n>1e3)return"warning";switch(e){case"async-state-capture":case"sequence-state-mismatch":return"warning";case"callback-state-capture":case"timeout-state-capture":return"info";case"event-handler-stale":return"warning";default:return"info"}}getStaleClosureMessages(e,n,r){const i=r<1e3?`${r}ms`:`${(r/1e3).toFixed(1)}s`;switch(e){case"async-state-capture":return{description:`await 후 ${i} 경과 시점에 '${n}' 상태가 변경됨. 캡처된 상태 대신 최신 상태를 사용해야 함`,suggestion:"await 이후에는 G7Core.state.get()으로 최신 상태를 다시 조회하거나, useRef + getter 패턴을 사용하세요",docLink:"troubleshooting-state-closure.md"};case"callback-state-capture":return{description:`콜백에서 ${i} 전에 캡처된 '${n}' 상태를 사용 중. 최신 상태와 다름`,suggestion:"콜백에서 상태를 참조할 때는 stateRef.current 패턴 또는 G7Core.state.get()를 사용하세요",docLink:"troubleshooting-state-closure.md"};case"timeout-state-capture":return{description:`setTimeout/setInterval 콜백에서 '${n}' 상태가 ${i} 전 값 사용 중`,suggestion:"타이머 콜백 내에서는 G7Core.state.get()으로 최신 상태를 조회하세요",docLink:"troubleshooting-state-closure.md"};case"sequence-state-mismatch":return{description:`sequence 내 '${n}' 상태가 이전 액션 결과와 불일치. context.state 대신 캡처된 값 사용 의심`,suggestion:"sequence 내에서는 context.state 또는 $prev를 사용하여 최신 상태를 참조하세요",docLink:"troubleshooting-state-setstate.md"};case"event-handler-stale":return{description:`이벤트 핸들러에서 ${i} 전에 바인딩된 '${n}' 상태 사용 중`,suggestion:"이벤트 핸들러에서 상태를 참조할 때는 useRef 패턴 또는 G7Core.state.get()를 사용하세요",docLink:"troubleshooting-state-closure.md"};default:return{description:`'${n}' 상태에서 stale closure 감지됨 (${i} 경과)`,suggestion:"상태 참조 시 최신 값을 사용하는지 확인하세요"}}}addStaleClosureWarning(e){this.staleClosureWarnings.push(e),this.staleClosureWarnings.length>this.maxStaleClosureWarnings&&this.staleClosureWarnings.shift()}getValueByPath(e,n){const r=n.split(".");let i=e;for(const l of r){if(i==null)return;i=i[l]}return i}isDeepEqual(e,n){if(e===n)return!0;if(e===null||n===null)return e===n;if(typeof e!=typeof n)return!1;if(typeof e!="object")return e===n;try{return JSON.stringify(e)===JSON.stringify(n)}catch{return!1}}getStaleClosureTrackingInfo(){const e=this.getStaleClosureStats();return{warnings:[...this.staleClosureWarnings],stats:e,timestamp:Date.now()}}getStaleClosureStats(){const e=this.staleClosureWarnings,n={"async-state-capture":0,"callback-state-capture":0,"timeout-state-capture":0,"sequence-state-mismatch":0,"event-handler-stale":0};for(const f of e)n[f.type]++;const r={info:0,warning:0,error:0};for(const f of e)r[f.severity]++;const i={};for(const f of e)i[f.location]=(i[f.location]||0)+1;const l=Object.entries(i).sort(([,f],[,h])=>h-f).slice(0,5).map(([f,h])=>({location:f,count:h})),c={};for(const f of e)c[f.capturedState.path]=(c[f.capturedState.path]||0)+1;const d=Object.entries(c).sort(([,f],[,h])=>h-f).slice(0,5).map(([f,h])=>({path:f,count:h}));return{totalWarnings:e.length,warningsByType:n,warningsBySeverity:r,topLocations:l,topAffectedPaths:d}}clearStaleClosureData(){this.staleClosureWarnings=[],this.staleClosureIdCounter=0,this.stateCaptureRegistry.clear()}getRecentStaleClosureWarnings(e=10,n){let r=[...this.staleClosureWarnings];return n&&(r=r.filter(i=>i.severity===n)),r.slice(-e)}safeClone(e){if(e==null||typeof e!="object")return e;try{return JSON.parse(JSON.stringify(e))}catch{if(Array.isArray(e))return e.map(r=>{try{return JSON.parse(JSON.stringify(r))}catch{return"[Unserializable]"}});const n={};for(const r of Object.keys(e))try{n[r]=JSON.parse(JSON.stringify(e[r]))}catch{n[r]="[Unserializable]"}return n}}};M(Ti,"instance");let Ia=Ti;const Vn=dt("LayoutLoader");class xr extends Error{constructor(n,r,i){super(n);M(this,"code");M(this,"details");this.code=r,this.details=i,this.name="LayoutLoaderError"}}class Vf{constructor(e){M(this,"componentRegistry");M(this,"currentLayout",null);M(this,"layoutCache",new Map);M(this,"cacheVersion",0);this.componentRegistry=e}setCacheVersion(e){this.cacheVersion!==e&&(Vn.log("Cache version updated:",this.cacheVersion,"->",e),this.cacheVersion=e,this.layoutCache.clear())}getCacheVersion(){return this.cacheVersion}async loadLayout(e,n){const r=`${e}:${n}`;if(this.layoutCache.has(r)){Vn.log("Loading layout from cache:",n);const l=await this.layoutCache.get(r),c=JSON.parse(JSON.stringify(l));return this.currentLayout=c,Ia.getInstance().trackLayoutLoad(n,e,c,"cache"),c}const i=this.fetchLayout(e,n);return this.layoutCache.set(r,i),i.catch(()=>{this.layoutCache.get(r)===i&&this.layoutCache.delete(r)}),i}async fetchLayout(e,n,r=!1){try{const i=this.cacheVersion>0?this.cacheVersion:null;let l;if(n.startsWith("__preview__/")){const S=n.replace("__preview__/","");l=jr(`/api/layouts/preview/${S}`,"json",i)}else l=jr(`/api/layouts/${e}/${n}`,"json",i);Vn.log("Fetching layout from API:",l);const c=zr(),d=r?null:c.getToken(),f={Accept:"application/json"};d&&(f.Authorization=`Bearer ${d}`);const h=await Vl(l,{init:{headers:f},label:`layout: ${n}`});let m;try{m=await h.json()}catch{m=null}if(!h.ok){if(h.status===401&&!r&&d){Vn.log("Token invalid, removing and retrying without token"),c.removeToken();try{return await this.fetchLayout(e,n,!0)}catch(v){throw v instanceof xr&&v.details?.status===401?new xr(v.message,v.code,{...v.details,hadToken:!0}):v}}const S=m?.message||m?.error;throw new xr(`Failed to fetch layout: ${h.status} ${h.statusText}`,"FETCH_FAILED",{status:h.status,statusText:h.statusText,url:l,apiMessage:S})}const y=m.data||m;return this.validateLayoutData(y),this.currentLayout=y,Ia.getInstance().trackLayoutLoad(n,e,y,"api"),Vn.log("Layout fetched and cached successfully:",y.layout_name),y}catch(i){const l=`${e}:${n}`;throw this.layoutCache.delete(l),i instanceof xr?i:new xr("Failed to load layout","LOAD_FAILED",{originalError:i})}}prefetchLayout(e,n){return this.loadLayout(e,n)}validateLayoutData(e){if(!e.version)throw new xr("Layout data missing required field: version","VALIDATION_FAILED",{field:"version"});if(!e.layout_name)throw new xr("Layout data missing required field: layout_name","VALIDATION_FAILED",{field:"layout_name"});if(!Array.isArray(e.components))throw new xr('Layout data field "components" must be an array',"VALIDATION_FAILED",{field:"components",value:e.components});Vn.log("Layout data validation passed")}renderLayout(e,n){try{const r=n||this.currentLayout;if(!r)throw new xr("No layout data to render","NO_LAYOUT_DATA");Vn.log("Rendering layout:",r.layout_name),e.innerHTML="",this.renderComponents(e,r.components),Vn.log("Layout rendered successfully")}catch(r){Vn.error("Render error:",r),this.renderErrorState(e,r)}}renderComponents(e,n){for(const r of n){const i=this.renderComponent(r);i&&e.appendChild(i)}}renderComponent(e){try{if(!this.componentRegistry.getComponent(e.type))return Vn.warn(`Component not found: ${e.type}`),this.createPlaceholderElement(e.type);const r=document.createElement("div");return r.setAttribute("data-component",e.type),e.props&&Object.entries(e.props).forEach(([i,l])=>{r.setAttribute(`data-prop-${i}`,JSON.stringify(l))}),e.children&&e.children.length>0?this.renderComponents(r,e.children):e.text&&(r.textContent=e.text),r}catch(n){return Vn.error(`Error rendering component ${e.type}:`,n),this.createErrorElement(e.type,n)}}createPlaceholderElement(e){const n=document.createElement("div");return n.className="component-placeholder",n.setAttribute("data-component-type",e),n.innerHTML=`

Component not found: ${e}

@@ -105,8 +105,8 @@ Error generating stack: `+u.message+` " >페이지 새로고침 - `,Vn.error("Error state rendered:",i,r)}getCurrentLayout(){return this.currentLayout}clear(){this.currentLayout=null,this.layoutCache.clear(),Vn.log("Layout data and cache cleared")}}const NA=dt("TranslationContext"),Kf=N.createContext(null),Oc=({children:s,translationEngine:e,translationContext:n})=>{const r=N.useMemo(()=>(l,c)=>{if(c){const d="|"+Object.entries(c).map(([f,h])=>`${f}=${h}`).join("|");return e.translate(l,n,d)}return e.translate(l,n)},[e,n]),i=N.useMemo(()=>({translationEngine:e,translationContext:n,t:r}),[e,n,r]);return ft.jsx(Kf.Provider,{value:i,children:s})},Uy=()=>{const s=N.useContext(Kf);return s||(NA.warn("TranslationProvider 외부에서 호출되었습니다. 키를 그대로 반환합니다."),{t:e=>e,translationEngine:null,translationContext:null})},ja=dt("SlotContext"),IA={registerToSlot:()=>{ja.warn("SlotContext not available: registerToSlot called outside SlotProvider")},unregisterFromSlot:()=>{ja.warn("SlotContext not available: unregisterFromSlot called outside SlotProvider")},getSlotComponents:()=>[],subscribeToSlot:()=>()=>{},clearAllSlots:()=>{},isEnabled:!1},jA=N.createContext(IA),Wf=({children:s})=>{const e=N.useRef(new Map),n=N.useRef(new Map),r=N.useCallback(m=>{const y=n.current.get(m);y&&y.forEach(S=>{try{S()}catch(v){ja.error(`Slot subscriber error (slotId: ${m}):`,v)}})},[]),i=N.useCallback((m,y,S)=>{if(!m||!y){ja.warn("registerToSlot: slotId and componentId are required");return}e.current.has(m)||e.current.set(m,new Map);const v=e.current.get(m),_=v.get(y);_&&_.registrationKey===S.registrationKey||(v.set(y,S),ja.log(`Component registered to slot: ${y} -> ${m} (order: ${S.order})`),r(m))},[r]),l=N.useCallback((m,y)=>{const S=e.current.get(m);S&&S.has(y)&&(S.delete(y),ja.log(`Component unregistered from slot: ${y} <- ${m}`),S.size===0&&e.current.delete(m),r(m))},[r]),c=N.useCallback(m=>{const y=e.current.get(m);return y?Array.from(y.values()).sort((S,v)=>S.order-v.order):[]},[]),d=N.useCallback((m,y)=>{n.current.has(m)||n.current.set(m,new Set);const S=n.current.get(m);return S.add(y),()=>{S.delete(y),S.size===0&&n.current.delete(m)}},[]),f=N.useCallback(()=>{e.current.forEach((m,y)=>{r(y)}),e.current.clear(),n.current.clear(),ja.log("All slots cleared")},[r]),h=N.useMemo(()=>({registerToSlot:i,unregisterFromSlot:l,getSlotComponents:c,subscribeToSlot:d,clearAllSlots:f,isEnabled:!0}),[i,l,c,d,f]);return N.useLayoutEffect(()=>{typeof window<"u"&&(window.__slotContextValue=h,ja.log("SlotContext exposed to window.__slotContextValue"))},[h]),ft.jsx(jA.Provider,{value:h,children:s})};class Yf{constructor(){this.notificationCreatedEvent=".Illuminate\\Notifications\\Events\\BroadcastNotificationCreated"}listenForWhisper(e,n){return this.listen(".client-"+e,n)}notification(e){return this.listen(this.notificationCreatedEvent,e)}stopListeningForNotification(e){return this.stopListening(this.notificationCreatedEvent,e)}stopListeningForWhisper(e,n){return this.stopListening(".client-"+e,n)}}class Py{constructor(e){this.namespace=e}format(e){return[".","\\"].includes(e.charAt(0))?e.substring(1):(this.namespace&&(e=this.namespace+"."+e),e.replace(/\./g,"\\"))}setNamespace(e){this.namespace=e}}function HA(s){try{return Reflect.construct(String,[],s),!0}catch{return!1}}class Xf extends Yf{constructor(e,n,r){super(),this.name=n,this.pusher=e,this.options=r,this.eventFormatter=new Py(this.options.namespace),this.subscribe()}subscribe(){this.subscription=this.pusher.subscribe(this.name)}unsubscribe(){this.pusher.unsubscribe(this.name)}listen(e,n){return this.on(this.eventFormatter.format(e),n),this}listenToAll(e){return this.subscription.bind_global((n,r)=>{if(n.startsWith("pusher:"))return;let i=String(this.options.namespace??"").replace(/\./g,"\\"),l=n.startsWith(i)?n.substring(i.length+1):"."+n;e(l,r)}),this}stopListening(e,n){return n?this.subscription.unbind(this.eventFormatter.format(e),n):this.subscription.unbind(this.eventFormatter.format(e)),this}stopListeningToAll(e){return e?this.subscription.unbind_global(e):this.subscription.unbind_global(),this}subscribed(e){return this.on("pusher:subscription_succeeded",()=>{e()}),this}error(e){return this.on("pusher:subscription_error",n=>{e(n)}),this}on(e,n){return this.subscription.bind(e,n),this}}class By extends Xf{whisper(e,n){return this.pusher.channels.channels[this.name].trigger(`client-${e}`,n),this}}class zA extends Xf{whisper(e,n){return this.pusher.channels.channels[this.name].trigger(`client-${e}`,n),this}}class UA extends By{here(e){return this.on("pusher:subscription_succeeded",n=>{e(Object.keys(n.members).map(r=>n.members[r]))}),this}joining(e){return this.on("pusher:member_added",n=>{e(n.info)}),this}whisper(e,n){return this.pusher.channels.channels[this.name].trigger(`client-${e}`,n),this}leaving(e){return this.on("pusher:member_removed",n=>{e(n.info)}),this}}class qy extends Yf{constructor(e,n,r){super(),this.events={},this.listeners={},this.name=n,this.socket=e,this.options=r,this.eventFormatter=new Py(this.options.namespace),this.subscribe()}subscribe(){this.socket.emit("subscribe",{channel:this.name,auth:this.options.auth||{}})}unsubscribe(){this.unbind(),this.socket.emit("unsubscribe",{channel:this.name,auth:this.options.auth||{}})}listen(e,n){return this.on(this.eventFormatter.format(e),n),this}stopListening(e,n){return this.unbindEvent(this.eventFormatter.format(e),n),this}subscribed(e){return this.on("connect",n=>{e(n)}),this}error(e){return this}on(e,n){return this.listeners[e]=this.listeners[e]||[],this.events[e]||(this.events[e]=(r,i)=>{this.name===r&&this.listeners[e]&&this.listeners[e].forEach(l=>l(i))},this.socket.on(e,this.events[e])),this.listeners[e].push(n),this}unbind(){Object.keys(this.events).forEach(e=>{this.unbindEvent(e)})}unbindEvent(e,n){this.listeners[e]=this.listeners[e]||[],n&&(this.listeners[e]=this.listeners[e].filter(r=>r!==n)),(!n||this.listeners[e].length===0)&&(this.events[e]&&(this.socket.removeListener(e,this.events[e]),delete this.events[e]),delete this.listeners[e])}}class Gy extends qy{whisper(e,n){return this.socket.emit("client event",{channel:this.name,event:`client-${e}`,data:n}),this}}class PA extends Gy{here(e){return this.on("presence:subscribed",n=>{e(n.map(r=>r.user_info))}),this}joining(e){return this.on("presence:joining",n=>e(n.user_info)),this}whisper(e,n){return this.socket.emit("client event",{channel:this.name,event:`client-${e}`,data:n}),this}leaving(e){return this.on("presence:leaving",n=>e(n.user_info)),this}}class Lc extends Yf{subscribe(){}unsubscribe(){}listen(e,n){return this}listenToAll(e){return this}stopListening(e,n){return this}subscribed(e){return this}error(e){return this}on(e,n){return this}}class Fy extends Lc{whisper(e,n){return this}}class BA extends Lc{whisper(e,n){return this}}class qA extends Fy{here(e){return this}joining(e){return this}whisper(e,n){return this}leaving(e){return this}}const Vy=class Dw{constructor(e){this.setOptions(e),this.connect()}setOptions(e){this.options={...Dw._defaultOptions,...e,broadcaster:e.broadcaster};let n=this.csrfToken();n&&(this.options.auth.headers["X-CSRF-TOKEN"]=n,this.options.userAuthentication.headers["X-CSRF-TOKEN"]=n),n=this.options.bearerToken,n&&(this.options.auth.headers.Authorization="Bearer "+n,this.options.userAuthentication.headers.Authorization="Bearer "+n)}csrfToken(){var e,n;return typeof window<"u"&&(e=window.Laravel)!=null&&e.csrfToken?window.Laravel.csrfToken:this.options.csrfToken?this.options.csrfToken:typeof document<"u"&&typeof document.querySelector=="function"?((n=document.querySelector('meta[name="csrf-token"]'))==null?void 0:n.getAttribute("content"))??null:null}};Vy._defaultOptions={auth:{headers:{}},authEndpoint:"/broadcasting/auth",userAuthentication:{endpoint:"/broadcasting/user-auth",headers:{}},csrfToken:null,bearerToken:null,host:null,key:null,namespace:"App.Events"};let Jf=Vy;class $c extends Jf{constructor(){super(...arguments),this.channels={}}connect(){if(typeof this.options.client<"u")this.pusher=this.options.client;else if(this.options.Pusher)this.pusher=new this.options.Pusher(this.options.key,this.options);else if(typeof window<"u"&&typeof window.Pusher<"u")this.pusher=new window.Pusher(this.options.key,this.options);else throw new Error("Pusher client not found. Should be globally available or passed via options.client")}signin(){this.pusher.signin()}listen(e,n,r){return this.channel(e).listen(n,r)}channel(e){return this.channels[e]||(this.channels[e]=new Xf(this.pusher,e,this.options)),this.channels[e]}privateChannel(e){return this.channels["private-"+e]||(this.channels["private-"+e]=new By(this.pusher,"private-"+e,this.options)),this.channels["private-"+e]}encryptedPrivateChannel(e){return this.channels["private-encrypted-"+e]||(this.channels["private-encrypted-"+e]=new zA(this.pusher,"private-encrypted-"+e,this.options)),this.channels["private-encrypted-"+e]}presenceChannel(e){return this.channels["presence-"+e]||(this.channels["presence-"+e]=new UA(this.pusher,"presence-"+e,this.options)),this.channels["presence-"+e]}leave(e){[e,"private-"+e,"private-encrypted-"+e,"presence-"+e].forEach(n=>{this.leaveChannel(n)})}leaveChannel(e){this.channels[e]&&(this.channels[e].unsubscribe(),delete this.channels[e])}socketId(){return this.pusher.connection.socket_id}connectionStatus(){const e=this.pusher.connection.state;switch(e){case"connected":case"connecting":return e;case"failed":case"unavailable":return"failed";default:return"disconnected"}}onConnectionChange(e){const n=()=>{e(this.connectionStatus())},r=["state_change","connected","disconnected"];return r.forEach(i=>{this.pusher.connection.bind(i,n)}),()=>{r.forEach(i=>{this.pusher.connection.unbind(i,n)})}}disconnect(){this.pusher.disconnect()}}class GA extends Jf{constructor(){super(...arguments),this.channels={}}connect(){let e=this.getSocketIO();this.socket=e(this.options.host??void 0,this.options),this.socket.io.on("reconnect",()=>{Object.values(this.channels).forEach(n=>{n.subscribe()})})}getSocketIO(){if(typeof this.options.client<"u")return this.options.client;if(typeof window<"u"&&typeof window.io<"u")return window.io;throw new Error("Socket.io client not found. Should be globally available or passed via options.client")}listen(e,n,r){return this.channel(e).listen(n,r)}channel(e){return this.channels[e]||(this.channels[e]=new qy(this.socket,e,this.options)),this.channels[e]}privateChannel(e){return this.channels["private-"+e]||(this.channels["private-"+e]=new Gy(this.socket,"private-"+e,this.options)),this.channels["private-"+e]}presenceChannel(e){return this.channels["presence-"+e]||(this.channels["presence-"+e]=new PA(this.socket,"presence-"+e,this.options)),this.channels["presence-"+e]}leave(e){[e,"private-"+e,"presence-"+e].forEach(n=>{this.leaveChannel(n)})}leaveChannel(e){this.channels[e]&&(this.channels[e].unsubscribe(),delete this.channels[e])}socketId(){return this.socket.id}connectionStatus(){return this.socket.connected?"connected":this.socket.io._reconnecting?"reconnecting":this.socket.id!==void 0?"disconnected":"connecting"}onConnectionChange(e){const n=()=>{e(this.connectionStatus())},r=["connect","disconnect","connect_error","reconnect_attempt","reconnect","reconnect_error","reconnect_failed"];return r.forEach(i=>{this.socket.on(i,n)}),()=>{r.forEach(i=>{this.socket.off(i,n)})}}disconnect(){this.socket.disconnect()}}class Ky extends Jf{constructor(){super(...arguments),this.channels={}}connect(){}listen(e,n,r){return new Lc}channel(e){return new Lc}privateChannel(e){return new Fy}encryptedPrivateChannel(e){return new BA}presenceChannel(e){return new qA}leave(e){}leaveChannel(e){}socketId(){return"fake-socket-id"}connectionStatus(){return"connected"}onConnectionChange(e){return()=>{}}disconnect(){}}class FA{constructor(e){this.options=e,this.connect(),this.options.withoutInterceptors||this.registerInterceptors()}channel(e){return this.connector.channel(e)}connect(){if(this.options.broadcaster==="reverb")this.connector=new $c({...this.options,cluster:""});else if(this.options.broadcaster==="pusher")this.connector=new $c(this.options);else if(this.options.broadcaster==="ably")this.connector=new $c({...this.options,cluster:"",broadcaster:"pusher"});else if(this.options.broadcaster==="socket.io")this.connector=new GA(this.options);else if(this.options.broadcaster==="null")this.connector=new Ky(this.options);else if(typeof this.options.broadcaster=="function"&&HA(this.options.broadcaster))this.connector=new this.options.broadcaster(this.options);else throw new Error(`Broadcaster ${typeof this.options.broadcaster} ${String(this.options.broadcaster)} is not supported.`)}disconnect(){this.connector.disconnect()}join(e){return this.connector.presenceChannel(e)}leave(e){this.connector.leave(e)}leaveChannel(e){this.connector.leaveChannel(e)}leaveAllChannels(){for(const e in this.connector.channels)this.leaveChannel(e)}listen(e,n,r){return this.connector.listen(e,n,r)}private(e){return this.connector.privateChannel(e)}encryptedPrivate(e){if(this.connectorSupportsEncryptedPrivateChannels(this.connector))return this.connector.encryptedPrivateChannel(e);throw new Error(`Broadcaster ${typeof this.options.broadcaster} ${String(this.options.broadcaster)} does not support encrypted private channels.`)}connectorSupportsEncryptedPrivateChannels(e){return e instanceof $c||e instanceof Ky}socketId(){return this.connector.socketId()}connectionStatus(){return this.connector.connectionStatus()}registerInterceptors(){typeof Vue<"u"&&Vue!=null&&Vue.http&&this.registerVueRequestInterceptor(),typeof axios=="function"&&this.registerAxiosRequestInterceptor(),typeof jQuery=="function"&&this.registerjQueryAjaxSetup(),typeof Turbo=="object"&&this.registerTurboRequestInterceptor()}registerVueRequestInterceptor(){Vue.http.interceptors.push((e,n)=>{this.socketId()&&e.headers.set("X-Socket-ID",this.socketId()),n()})}registerAxiosRequestInterceptor(){axios.interceptors.request.use(e=>(this.socketId()&&(e.headers["X-Socket-Id"]=this.socketId()),e))}registerjQueryAjaxSetup(){typeof jQuery.ajax<"u"&&jQuery.ajaxPrefilter((e,n,r)=>{this.socketId()&&r.setRequestHeader("X-Socket-Id",this.socketId())})}registerTurboRequestInterceptor(){document.addEventListener("turbo:before-fetch-request",e=>{e.detail.fetchOptions.headers["X-Socket-Id"]=this.socketId()})}}var Qf={exports:{}};var Wy;function VA(){return Wy||(Wy=1,(function(s,e){(function(r,i){s.exports=i()})(self,()=>(()=>{var n={594(c,d){var f=this&&this.__extends||(function(){var $=function(k,O){return $=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(P,G){P.__proto__=G}||function(P,G){for(var B in G)G.hasOwnProperty(B)&&(P[B]=G[B])},$(k,O)};return function(k,O){$(k,O);function P(){this.constructor=k}k.prototype=O===null?Object.create(O):(P.prototype=O.prototype,new P)}})();Object.defineProperty(d,"__esModule",{value:!0});var h=256,m=(function(){function $(k){k===void 0&&(k="="),this._paddingCharacter=k}return $.prototype.encodedLength=function(k){return this._paddingCharacter?(k+2)/3*4|0:(k*8+5)/6|0},$.prototype.encode=function(k){for(var O="",P=0;P>>18&63),O+=this._encodeByte(G>>>12&63),O+=this._encodeByte(G>>>6&63),O+=this._encodeByte(G>>>0&63)}var B=k.length-P;if(B>0){var G=k[P]<<16|(B===2?k[P+1]<<8:0);O+=this._encodeByte(G>>>18&63),O+=this._encodeByte(G>>>12&63),B===2?O+=this._encodeByte(G>>>6&63):O+=this._paddingCharacter||"",O+=this._paddingCharacter||""}return O},$.prototype.maxDecodedLength=function(k){return this._paddingCharacter?k/4*3|0:(k*6+7)/8|0},$.prototype.decodedLength=function(k){return this.maxDecodedLength(k.length-this._getPaddingLength(k))},$.prototype.decode=function(k){if(k.length===0)return new Uint8Array(0);for(var O=this._getPaddingLength(k),P=k.length-O,G=new Uint8Array(this.maxDecodedLength(P)),B=0,W=0,pe=0,Se=0,we=0,Ue=0,Fe=0;W>>4,G[B++]=we<<4|Ue>>>2,G[B++]=Ue<<6|Fe,pe|=Se&h,pe|=we&h,pe|=Ue&h,pe|=Fe&h;if(W>>4,pe|=Se&h,pe|=we&h),W>>2,pe|=Ue&h),W>>8&6,O+=51-k>>>8&-75,O+=61-k>>>8&-15,O+=62-k>>>8&3,String.fromCharCode(O)},$.prototype._decodeChar=function(k){var O=h;return O+=(42-k&k-44)>>>8&-h+k-43+62,O+=(46-k&k-48)>>>8&-h+k-47+63,O+=(47-k&k-58)>>>8&-h+k-48+52,O+=(64-k&k-91)>>>8&-h+k-65+0,O+=(96-k&k-123)>>>8&-h+k-97+26,O},$.prototype._getPaddingLength=function(k){var O=0;if(this._paddingCharacter){for(var P=k.length-1;P>=0&&k[P]===this._paddingCharacter;P--)O++;if(k.length<4||O>2)throw new Error("Base64Coder: incorrect padding")}return O},$})();d.Coder=m;var y=new m;function S($){return y.encode($)}d.encode=S;function v($){return y.decode($)}d.decode=v;var _=(function($){f(k,$);function k(){return $!==null&&$.apply(this,arguments)||this}return k.prototype._encodeByte=function(O){var P=O;return P+=65,P+=25-O>>>8&6,P+=51-O>>>8&-75,P+=61-O>>>8&-13,P+=62-O>>>8&49,String.fromCharCode(P)},k.prototype._decodeChar=function(O){var P=h;return P+=(44-O&O-46)>>>8&-h+O-45+62,P+=(94-O&O-96)>>>8&-h+O-95+63,P+=(47-O&O-58)>>>8&-h+O-48+52,P+=(64-O&O-91)>>>8&-h+O-65+0,P+=(96-O&O-123)>>>8&-h+O-97+26,P},k})(m);d.URLSafeCoder=_;var x=new _;function A($){return x.encode($)}d.encodeURLSafe=A;function L($){return x.decode($)}d.decodeURLSafe=L,d.encodedLength=function($){return y.encodedLength($)},d.maxDecodedLength=function($){return y.maxDecodedLength($)},d.decodedLength=function($){return y.decodedLength($)}},978(c,d){var f="utf8: invalid source encoding";function h(m){for(var y=[],S=0;S=m.length)throw new Error(f);var x=m[++S];if((x&192)!==128)throw new Error(f);v=(v&31)<<6|x&63,_=128}else if(v<240){if(S>=m.length-1)throw new Error(f);var x=m[++S],A=m[++S];if((x&192)!==128||(A&192)!==128)throw new Error(f);v=(v&15)<<12|(x&63)<<6|A&63,_=2048}else if(v<248){if(S>=m.length-2)throw new Error(f);var x=m[++S],A=m[++S],L=m[++S];if((x&192)!==128||(A&192)!==128||(L&192)!==128)throw new Error(f);v=(v&15)<<18|(x&63)<<12|(A&63)<<6|L&63,_=65536}else throw new Error(f);if(v<_||v>=55296&&v<=57343)throw new Error(f);if(v>=65536){if(v>1114111)throw new Error(f);v-=65536,y.push(String.fromCharCode(55296|v>>10)),v=56320|v&1023}}y.push(String.fromCharCode(v))}return y.join("")}d.D4=h},721(c,d,f){c.exports=f(207).default},207(c,d,f){f.d(d,{default:()=>Ls});class h{constructor(b,C){this.lastId=0,this.prefix=b,this.name=C}create(b){this.lastId++;var C=this.lastId,D=this.prefix+C,I=this.name+"["+C+"]",ne=!1,me=function(){ne||(b.apply(null,arguments),ne=!0)};return this[C]=me,{number:C,id:D,name:I,callback:me}}remove(b){delete this[b.number]}}var m=new h("_pusher_script_","Pusher.ScriptReceivers"),y={VERSION:"8.5.0",PROTOCOL:7,wsPort:80,wssPort:443,wsPath:"",httpHost:"sockjs.pusher.com",httpPort:80,httpsPort:443,httpPath:"/pusher",stats_host:"stats.pusher.com",authEndpoint:"/pusher/auth",authTransport:"ajax",activityTimeout:12e4,pongTimeout:3e4,unavailableTimeout:1e4,userAuthentication:{endpoint:"/pusher/user-auth",transport:"ajax"},channelAuthorization:{endpoint:"/pusher/auth",transport:"ajax"},cdn_http:"http://js.pusher.com",cdn_https:"https://js.pusher.com",dependency_suffix:""};const S=y;class v{constructor(b){this.options=b,this.receivers=b.receivers||m,this.loading={}}load(b,C,D){var I=this;if(I.loading[b]&&I.loading[b].length>0)I.loading[b].push(D);else{I.loading[b]=[D];var ne=ze.createScriptRequest(I.getPath(b,C)),me=I.receivers.create(function($e){if(I.receivers.remove(me),I.loading[b]){var Ke=I.loading[b];delete I.loading[b];for(var ct=function(zt){zt||ne.cleanup()},gt=0;gt>>6)+J(128|b&63):J(224|b>>>12&15)+J(128|b>>>6&63)+J(128|b&63)},Z=function(E){return E.replace(/[^\x00-\x7F]/g,Le)},ge=function(E){var b=[0,2,1][E.length%3],C=E.charCodeAt(0)<<16|(E.length>1?E.charCodeAt(1):0)<<8|(E.length>2?E.charCodeAt(2):0),D=[fe.charAt(C>>>18),fe.charAt(C>>>12&63),b>=2?"=":fe.charAt(C>>>6&63),b>=1?"=":fe.charAt(C&63)];return D.join("")},H=window.btoa||function(E){return E.replace(/[\s\S]{1,3}/g,ge)};class T{constructor(b,C,D,I){this.clear=C,this.timer=b(()=>{this.timer&&(this.timer=I(this.timer))},D)}isRunning(){return this.timer!==null}ensureAborted(){this.timer&&(this.clear(this.timer),this.timer=null)}}const ce=T;function de(E){window.clearTimeout(E)}function be(E){window.clearInterval(E)}class ie extends ce{constructor(b,C){super(setTimeout,de,b,function(D){return C(),null})}}class xe extends ce{constructor(b,C){super(setInterval,be,b,function(D){return C(),D})}}var _e={now(){return Date.now?Date.now():new Date().valueOf()},defer(E){return new ie(0,E)},method(E,...b){var C=Array.prototype.slice.call(arguments,1);return function(D){return D[E].apply(D,C.concat(arguments))}}};const Te=_e;function Me(E,...b){for(var C=0;C{window.console&&window.console.log&&window.console.log(b)}}debug(...b){this.log(this.globalLog,b)}warn(...b){this.log(this.globalLogWarn,b)}error(...b){this.log(this.globalLogError,b)}globalLogWarn(b){window.console&&window.console.warn?window.console.warn(b):this.globalLog(b)}globalLogError(b){window.console&&window.console.error?window.console.error(b):this.globalLogWarn(b)}log(b,...C){var D=pt.apply(this,arguments);Ls.log?Ls.log(D):Ls.logToConsole&&b.bind(this)(D)}}const nt=new Dn;var In=function(E,b,C,D,I){(C.headers!==void 0||C.headersProvider!=null)&&nt.warn(`To send headers with the ${D.toString()} request, you must use AJAX, rather than JSONP.`);var ne=E.nextAuthCallbackID.toString();E.nextAuthCallbackID++;var me=E.getDocument(),$e=me.createElement("script");E.auth_callbacks[ne]=function(gt){I(null,gt)};var Ke="Pusher.auth_callbacks['"+ne+"']";$e.src=C.endpoint+"?callback="+encodeURIComponent(Ke)+"&"+b;var ct=me.getElementsByTagName("head")[0]||me.documentElement;ct.insertBefore($e,ct.firstChild)};const mn=In;class ca{constructor(b){this.src=b}send(b){var C=this,D="Error loading "+C.src;C.script=document.createElement("script"),C.script.id=b.id,C.script.src=C.src,C.script.type="text/javascript",C.script.charset="UTF-8",C.script.addEventListener?(C.script.onerror=function(){b.callback(D)},C.script.onload=function(){b.callback(null)}):C.script.onreadystatechange=function(){(C.script.readyState==="loaded"||C.script.readyState==="complete")&&b.callback(null)},C.script.async===void 0&&document.attachEvent&&/opera/i.test(navigator.userAgent)?(C.errorScript=document.createElement("script"),C.errorScript.id=b.id+"_error",C.errorScript.text=b.name+"('"+D+"');",C.script.async=C.errorScript.async=!1):C.script.async=!0;var I=document.getElementsByTagName("head")[0];I.insertBefore(C.script,I.firstChild),C.errorScript&&I.insertBefore(C.errorScript,C.script.nextSibling)}cleanup(){this.script&&(this.script.onload=this.script.onerror=null,this.script.onreadystatechange=null),this.script&&this.script.parentNode&&this.script.parentNode.removeChild(this.script),this.errorScript&&this.errorScript.parentNode&&this.errorScript.parentNode.removeChild(this.errorScript),this.script=null,this.errorScript=null}}class lr{constructor(b,C){this.url=b,this.data=C}send(b){if(!this.request){var C=ki(this.data),D=this.url+"/"+b.number+"?"+C;this.request=ze.createScriptRequest(D),this.request.send(b)}}cleanup(){this.request&&this.request.cleanup()}}var sn=function(E,b){return function(C,D){var I="http"+(b?"s":"")+"://",ne=I+(E.host||E.options.host)+E.options.path,me=ze.createJSONPRequest(ne,C),$e=ze.ScriptReceivers.create(function(Ke,ct){m.remove($e),me.cleanup(),ct&&ct.host&&(E.host=ct.host),D&&D(Ke,ct)});me.send($e)}},_n={name:"jsonp",getAgent:sn};const on=_n;function F(E,b,C){var D=E+(b.useTLS?"s":""),I=b.useTLS?b.hostTLS:b.hostNonTLS;return D+"://"+I+C}function se(E,b){var C="/app/"+E,D="?protocol="+S.PROTOCOL+"&client=js&version="+S.VERSION+(b?"&"+b:"");return C+D}var ue={getInitial:function(E,b){var C=(b.httpPath||"")+se(E,"flash=false");return F("ws",b,C)}},ee={getInitial:function(E,b){var C=(b.httpPath||"/pusher")+se(E);return F("http",b,C)}},ve={getInitial:function(E,b){return F("http",b,b.httpPath||"/pusher")},getPath:function(E,b){return se(E)}};class he{constructor(){this._callbacks={}}get(b){return this._callbacks[Ee(b)]}add(b,C,D){var I=Ee(b);this._callbacks[I]=this._callbacks[I]||[],this._callbacks[I].push({fn:C,context:D})}remove(b,C,D){if(!b&&!C&&!D){this._callbacks={};return}var I=b?[Ee(b)]:ht(this._callbacks);C||D?this.removeCallback(I,C,D):this.removeAllCallbacks(I)}removeCallback(b,C,D){Kt(b,function(I){this._callbacks[I]=hn(this._callbacks[I]||[],function(ne){return C&&C!==ne.fn||D&&D!==ne.context}),this._callbacks[I].length===0&&delete this._callbacks[I]},this)}removeAllCallbacks(b){Kt(b,function(C){delete this._callbacks[C]},this)}}function Ee(E){return"_"+E}class Ae{constructor(b){this.callbacks=new he,this.global_callbacks=[],this.failThrough=b}bind(b,C,D){return this.callbacks.add(b,C,D),this}bind_global(b){return this.global_callbacks.push(b),this}unbind(b,C,D){return this.callbacks.remove(b,C,D),this}unbind_global(b){return b?(this.global_callbacks=hn(this.global_callbacks||[],C=>C!==b),this):(this.global_callbacks=[],this)}unbind_all(){return this.unbind(),this.unbind_global(),this}emit(b,C,D){for(var I=0;I0)for(var I=0;I{this.onError(C),this.changeState("closed")}),!1}return this.bindListeners(),nt.debug("Connecting",{transport:this.name,url:b}),this.changeState("connecting"),!0}close(){return this.socket?(this.socket.close(),!0):!1}send(b){return this.state==="open"?(Te.defer(()=>{this.socket&&this.socket.send(b)}),!0):!1}ping(){this.state==="open"&&this.supportsPing()&&this.socket.ping()}onOpen(){this.hooks.beforeOpen&&this.hooks.beforeOpen(this.socket,this.hooks.urls.getPath(this.key,this.options)),this.changeState("open"),this.socket.onopen=void 0}onError(b){this.emit("error",{type:"WebSocketError",error:b}),this.timeline.error(this.buildTimelineMessage({error:b.toString()}))}onClose(b){b?this.changeState("closed",{code:b.code,reason:b.reason,wasClean:b.wasClean}):this.changeState("closed"),this.unbindListeners(),this.socket=void 0}onMessage(b){this.emit("message",b)}onActivity(){this.emit("activity")}bindListeners(){this.socket.onopen=()=>{this.onOpen()},this.socket.onerror=b=>{this.onError(b)},this.socket.onclose=b=>{this.onClose(b)},this.socket.onmessage=b=>{this.onMessage(b)},this.supportsPing()&&(this.socket.onactivity=()=>{this.onActivity()})}unbindListeners(){this.socket&&(this.socket.onopen=void 0,this.socket.onerror=void 0,this.socket.onclose=void 0,this.socket.onmessage=void 0,this.supportsPing()&&(this.socket.onactivity=void 0))}changeState(b,C){this.state=b,this.timeline.info(this.buildTimelineMessage({state:b,params:C})),this.emit(b,C)}buildTimelineMessage(b){return Me({cid:this.id},b)}}class ke{constructor(b){this.hooks=b}isSupported(b){return this.hooks.isSupported(b)}createConnection(b,C,D,I){return new Ve(this.hooks,b,C,D,I)}}var Ne=new ke({urls:ue,handlesActivityChecks:!1,supportsPing:!1,isInitialized:function(){return!!ze.getWebSocketAPI()},isSupported:function(){return!!ze.getWebSocketAPI()},getSocket:function(E){return ze.createWebSocket(E)}}),Re={urls:ee,handlesActivityChecks:!1,supportsPing:!0,isInitialized:function(){return!0}},et=Me({getSocket:function(E){return ze.HTTPFactory.createStreamingSocket(E)}},Re),He=Me({getSocket:function(E){return ze.HTTPFactory.createPollingSocket(E)}},Re),Ge={isSupported:function(){return ze.isXHRSupported()}},Ce=new ke(Me({},et,Ge)),je=new ke(Me({},He,Ge)),tt={ws:Ne,xhr_streaming:Ce,xhr_polling:je};const At=tt;var Mt=new ke({file:"sockjs",urls:ve,handlesActivityChecks:!0,supportsPing:!1,isSupported:function(){return!0},isInitialized:function(){return window.SockJS!==void 0},getSocket:function(E,b){return new window.SockJS(E,null,{js_path:x.getPath("sockjs",{useTLS:b.useTLS}),ignore_null_origin:b.ignoreNullOrigin})},beforeOpen:function(E,b){E.send(JSON.stringify({path:b}))}}),On={isSupported:function(E){var b=ze.isXDRSupported(E.useTLS);return b}},jt=new ke(Me({},et,On)),Ht=new ke(Me({},He,On));At.xdr_streaming=jt,At.xdr_polling=Ht,At.sockjs=Mt;const An=At;class za extends Ae{constructor(){super();var b=this;window.addEventListener!==void 0&&(window.addEventListener("online",function(){b.emit("online")},!1),window.addEventListener("offline",function(){b.emit("offline")},!1))}isOnline(){return window.navigator.onLine===void 0?!0:window.navigator.onLine}}var Ko=new za;class ih{constructor(b,C,D){this.manager=b,this.transport=C,this.minPingDelay=D.minPingDelay,this.maxPingDelay=D.maxPingDelay,this.pingDelay=void 0}createConnection(b,C,D,I){I=Me({},I,{activityTimeout:this.pingDelay});var ne=this.transport.createConnection(b,C,D,I),me=null,$e=function(){ne.unbind("open",$e),ne.bind("closed",Ke),me=Te.now()},Ke=ct=>{if(ne.unbind("closed",Ke),ct.code===1002||ct.code===1003)this.manager.reportDeath();else if(!ct.wasClean&&me){var gt=Te.now()-me;gt<2*this.maxPingDelay&&(this.manager.reportDeath(),this.pingDelay=Math.max(gt/2,this.minPingDelay))}};return ne.bind("open",$e),ne}isSupported(b){return this.manager.isAlive()&&this.transport.isSupported(b)}}const Bc={decodeMessage:function(E){try{var b=JSON.parse(E.data),C=b.data;if(typeof C=="string")try{C=JSON.parse(b.data)}catch{}var D={event:b.event,channel:b.channel,data:C};return b.user_id&&(D.user_id=b.user_id),D}catch(I){throw{type:"MessageParseError",error:I,data:E.data}}},encodeMessage:function(E){return JSON.stringify(E)},processHandshake:function(E){var b=Bc.decodeMessage(E);if(b.event==="pusher:connection_established"){if(!b.data.activity_timeout)throw"No activity timeout specified in handshake";return{action:"connected",id:b.data.socket_id,activityTimeout:b.data.activity_timeout*1e3}}else{if(b.event==="pusher:error")return{action:this.getCloseAction(b.data),error:this.getCloseError(b.data)};throw"Invalid handshake"}},getCloseAction:function(E){return E.code<4e3?E.code>=1002&&E.code<=1004?"backoff":null:E.code===4e3?"tls_only":E.code<4100?"refused":E.code<4200?"backoff":E.code<4300?"retry":"refused"},getCloseError:function(E){return E.code!==1e3&&E.code!==1001?{type:"PusherError",data:{code:E.code,message:E.reason||E.message}}:null}},Kr=Bc;class Ri extends Ae{constructor(b,C){super(),this.id=b,this.transport=C,this.activityTimeout=C.activityTimeout,this.bindListeners()}handlesActivityChecks(){return this.transport.handlesActivityChecks()}send(b){return this.transport.send(b)}send_event(b,C,D){var I={event:b,data:C};return D&&(I.channel=D),nt.debug("Event sent",I),this.send(Kr.encodeMessage(I))}ping(){this.transport.supportsPing()?this.transport.ping():this.send_event("pusher:ping",{})}close(){this.transport.close()}bindListeners(){var b={message:D=>{var I;try{I=Kr.decodeMessage(D)}catch(ne){this.emit("error",{type:"MessageParseError",error:ne,data:D.data})}if(I!==void 0){switch(nt.debug("Event recd",I),I.event){case"pusher:error":this.emit("error",{type:"PusherError",data:I.data});break;case"pusher:ping":this.emit("ping");break;case"pusher:pong":this.emit("pong");break}this.emit("message",I)}},activity:()=>{this.emit("activity")},error:D=>{this.emit("error",D)},closed:D=>{C(),D&&D.code&&this.handleCloseEvent(D),this.transport=null,this.emit("closed")}},C=()=>{Ot(b,(D,I)=>{this.transport.unbind(I,D)})};Ot(b,(D,I)=>{this.transport.bind(I,D)})}handleCloseEvent(b){var C=Kr.getCloseAction(b),D=Kr.getCloseError(b);D&&this.emit("error",D),C&&this.emit(C,{action:C,error:D})}}class Wo{constructor(b,C){this.transport=b,this.callback=C,this.bindListeners()}close(){this.unbindListeners(),this.transport.close()}bindListeners(){this.onMessage=b=>{this.unbindListeners();var C;try{C=Kr.processHandshake(b)}catch(D){this.finish("error",{error:D}),this.transport.close();return}C.action==="connected"?this.finish("connected",{connection:new Ri(C.id,this.transport),activityTimeout:C.activityTimeout}):(this.finish(C.action,{error:C.error}),this.transport.close())},this.onClosed=b=>{this.unbindListeners();var C=Kr.getCloseAction(b)||"backoff",D=Kr.getCloseError(b);this.finish(C,{error:D})},this.transport.bind("message",this.onMessage),this.transport.bind("closed",this.onClosed)}unbindListeners(){this.transport.unbind("message",this.onMessage),this.transport.unbind("closed",this.onClosed)}finish(b,C){this.callback(Me({transport:this.transport,action:b},C))}}class Ua{constructor(b,C){this.timeline=b,this.options=C||{}}send(b,C){this.timeline.isEmpty()||this.timeline.send(ze.TimelineTransport.getAgent(this,b),C)}}class Wr extends Ae{constructor(b,C){super(function(D,I){nt.debug("No callbacks on "+b+" for "+D)}),this.name=b,this.pusher=C,this.subscribed=!1,this.subscriptionPending=!1,this.subscriptionCancelled=!1}authorize(b,C){return C(null,{auth:""})}trigger(b,C){if(b.indexOf("client-")!==0)throw new O("Event '"+b+"' does not start with 'client-'");if(!this.subscribed){var D=$.buildLogSuffix("triggeringClientEvents");nt.warn(`Client event triggered before channel 'subscription_succeeded' event . ${D}`)}return this.pusher.send_event(b,C,this.name)}disconnect(){this.subscribed=!1,this.subscriptionPending=!1}handleEvent(b){var C=b.event,D=b.data;if(C==="pusher_internal:subscription_succeeded")this.handleSubscriptionSucceededEvent(b);else if(C==="pusher_internal:subscription_count")this.handleSubscriptionCountEvent(b);else if(C.indexOf("pusher_internal:")!==0){var I={};this.emit(C,D,I)}}handleSubscriptionSucceededEvent(b){this.subscriptionPending=!1,this.subscribed=!0,this.subscriptionCancelled?this.pusher.unsubscribe(this.name):this.emit("pusher:subscription_succeeded",b.data)}handleSubscriptionCountEvent(b){b.data.subscription_count&&(this.subscriptionCount=b.data.subscription_count),this.emit("pusher:subscription_count",b.data)}subscribe(){this.subscribed||(this.subscriptionPending=!0,this.subscriptionCancelled=!1,this.authorize(this.pusher.connection.socket_id,(b,C)=>{b?(this.subscriptionPending=!1,nt.error(b.toString()),this.emit("pusher:subscription_error",Object.assign({},{type:"AuthError",error:b.message},b instanceof Ue?{status:b.status}:{}))):this.pusher.send_event("pusher:subscribe",{auth:C.auth,channel_data:C.channel_data,channel:this.name})}))}unsubscribe(){this.subscribed=!1,this.pusher.send_event("pusher:unsubscribe",{channel:this.name})}cancelSubscription(){this.subscriptionCancelled=!0}reinstateSubscription(){this.subscriptionCancelled=!1}}class ua extends Wr{authorize(b,C){return this.pusher.config.channelAuthorizer({channelName:this.name,socketId:b},C)}}class Pa{constructor(){this.reset()}get(b){return Object.prototype.hasOwnProperty.call(this.members,b)?{id:b,info:this.members[b]}:null}each(b){Ot(this.members,(C,D)=>{b(this.get(D))})}setMyID(b){this.myID=b}onSubscription(b){this.members=b.presence.hash,this.count=b.presence.count,this.me=this.get(this.myID)}addMember(b){return this.get(b.user_id)===null&&this.count++,this.members[b.user_id]=b.user_info,this.get(b.user_id)}removeMember(b){var C=this.get(b.user_id);return C&&(delete this.members[b.user_id],this.count--),C}reset(){this.members={},this.count=0,this.myID=null,this.me=null}}var Jt=function(E,b,C,D){function I(ne){return ne instanceof C?ne:new C(function(me){me(ne)})}return new(C||(C=Promise))(function(ne,me){function $e(gt){try{ct(D.next(gt))}catch(zt){me(zt)}}function Ke(gt){try{ct(D.throw(gt))}catch(zt){me(zt)}}function ct(gt){gt.done?ne(gt.value):I(gt.value).then($e,Ke)}ct((D=D.apply(E,b||[])).next())})};class qc extends ua{constructor(b,C){super(b,C),this.members=new Pa}authorize(b,C){super.authorize(b,(D,I)=>Jt(this,void 0,void 0,function*(){if(!D)if(I=I,I.channel_data!=null){var ne=JSON.parse(I.channel_data);this.members.setMyID(ne.user_id)}else if(yield this.pusher.user.signinDonePromise,this.pusher.user.user_data!=null)this.members.setMyID(this.pusher.user.user_data.id);else{let me=$.buildLogSuffix("authorizationEndpoint");nt.error(`Invalid auth response for channel '${this.name}', expected 'channel_data' field. ${me}, or the user should be signed in.`),C("Invalid auth response");return}C(D,I)}))}handleEvent(b){var C=b.event;if(C.indexOf("pusher_internal:")===0)this.handleInternalEvent(b);else{var D=b.data,I={};b.user_id&&(I.user_id=b.user_id),this.emit(C,D,I)}}handleInternalEvent(b){var C=b.event,D=b.data;switch(C){case"pusher_internal:subscription_succeeded":this.handleSubscriptionSucceededEvent(b);break;case"pusher_internal:subscription_count":this.handleSubscriptionCountEvent(b);break;case"pusher_internal:member_added":var I=this.members.addMember(D);this.emit("pusher:member_added",I);break;case"pusher_internal:member_removed":var ne=this.members.removeMember(D);ne&&this.emit("pusher:member_removed",ne);break}}handleSubscriptionSucceededEvent(b){this.subscriptionPending=!1,this.subscribed=!0,this.subscriptionCancelled?this.pusher.unsubscribe(this.name):(this.members.onSubscription(b.data),this.emit("pusher:subscription_succeeded",this.members))}disconnect(){this.members.reset(),super.disconnect()}}var Gc=f(978),Rr=f(594);class Ba extends ua{constructor(b,C,D){super(b,C),this.key=null,this.nacl=D}authorize(b,C){super.authorize(b,(D,I)=>{if(D){C(D,I);return}let ne=I.shared_secret;if(!ne){C(new Error(`No shared_secret key in auth payload for encrypted channel: ${this.name}`),null);return}this.key=(0,Rr.decode)(ne),delete I.shared_secret,C(null,I)})}trigger(b,C){throw new pe("Client events are not currently supported for encrypted channels")}handleEvent(b){var C=b.event,D=b.data;if(C.indexOf("pusher_internal:")===0||C.indexOf("pusher:")===0){super.handleEvent(b);return}this.handleEncryptedEvent(C,D)}handleEncryptedEvent(b,C){if(!this.key){nt.debug("Received encrypted event before key has been retrieved from the authEndpoint");return}if(!C.ciphertext||!C.nonce){nt.error("Unexpected format for encrypted event, expected object with `ciphertext` and `nonce` fields, got: "+C);return}let D=(0,Rr.decode)(C.ciphertext);if(D.length{if(me){nt.error(`Failed to make a request to the authEndpoint: ${$e}. Unable to fetch new key, so dropping encrypted event`);return}if(ne=this.nacl.secretbox.open(D,I,this.key),ne===null){nt.error("Failed to decrypt event with new key. Dropping encrypted event");return}this.emit(b,this.getDataToEmit(ne))});return}this.emit(b,this.getDataToEmit(ne))}getDataToEmit(b){let C=(0,Gc.D4)(b);try{return JSON.parse(C)}catch{return C}}}class sh extends Ae{constructor(b,C){super(),this.state="initialized",this.connection=null,this.key=b,this.options=C,this.timeline=this.options.timeline,this.usingTLS=this.options.useTLS,this.errorCallbacks=this.buildErrorCallbacks(),this.connectionCallbacks=this.buildConnectionCallbacks(this.errorCallbacks),this.handshakeCallbacks=this.buildHandshakeCallbacks(this.errorCallbacks);var D=ze.getNetwork();D.bind("online",()=>{this.timeline.info({netinfo:"online"}),(this.state==="connecting"||this.state==="unavailable")&&this.retryIn(0)}),D.bind("offline",()=>{this.timeline.info({netinfo:"offline"}),this.connection&&this.sendActivityCheck()}),this.updateStrategy()}switchCluster(b){this.key=b,this.updateStrategy(),this.retryIn(0)}connect(){if(!(this.connection||this.runner)){if(!this.strategy.isSupported()){this.updateState("failed");return}this.updateState("connecting"),this.startConnecting(),this.setUnavailableTimer()}}send(b){return this.connection?this.connection.send(b):!1}send_event(b,C,D){return this.connection?this.connection.send_event(b,C,D):!1}disconnect(){this.disconnectInternally(),this.updateState("disconnected")}isUsingTLS(){return this.usingTLS}startConnecting(){var b=(C,D)=>{C?this.runner=this.strategy.connect(0,b):D.action==="error"?(this.emit("error",{type:"HandshakeError",error:D.error}),this.timeline.error({handshakeError:D.error})):(this.abortConnecting(),this.handshakeCallbacks[D.action](D))};this.runner=this.strategy.connect(0,b)}abortConnecting(){this.runner&&(this.runner.abort(),this.runner=null)}disconnectInternally(){if(this.abortConnecting(),this.clearRetryTimer(),this.clearUnavailableTimer(),this.connection){var b=this.abandonConnection();b.close()}}updateStrategy(){this.strategy=this.options.getStrategy({key:this.key,timeline:this.timeline,useTLS:this.usingTLS})}retryIn(b){this.timeline.info({action:"retry",delay:b}),b>0&&this.emit("connecting_in",Math.round(b/1e3)),this.retryTimer=new ie(b||0,()=>{this.disconnectInternally(),this.connect()})}clearRetryTimer(){this.retryTimer&&(this.retryTimer.ensureAborted(),this.retryTimer=null)}setUnavailableTimer(){this.unavailableTimer=new ie(this.options.unavailableTimeout,()=>{this.updateState("unavailable")})}clearUnavailableTimer(){this.unavailableTimer&&this.unavailableTimer.ensureAborted()}sendActivityCheck(){this.stopActivityCheck(),this.connection.ping(),this.activityTimer=new ie(this.options.pongTimeout,()=>{this.timeline.error({pong_timed_out:this.options.pongTimeout}),this.retryIn(0)})}resetActivityCheck(){this.stopActivityCheck(),this.connection&&!this.connection.handlesActivityChecks()&&(this.activityTimer=new ie(this.activityTimeout,()=>{this.sendActivityCheck()}))}stopActivityCheck(){this.activityTimer&&this.activityTimer.ensureAborted()}buildConnectionCallbacks(b){return Me({},b,{message:C=>{this.resetActivityCheck(),this.emit("message",C)},ping:()=>{this.send_event("pusher:pong",{})},activity:()=>{this.resetActivityCheck()},error:C=>{this.emit("error",C)},closed:()=>{this.abandonConnection(),this.shouldRetry()&&this.retryIn(1e3)}})}buildHandshakeCallbacks(b){return Me({},b,{connected:C=>{this.activityTimeout=Math.min(this.options.activityTimeout,C.activityTimeout,C.connection.activityTimeout||1/0),this.clearUnavailableTimer(),this.setConnection(C.connection),this.socket_id=this.connection.id,this.updateState("connected",{socket_id:this.socket_id})}})}buildErrorCallbacks(){let b=C=>D=>{D.error&&this.emit("error",{type:"WebSocketError",error:D.error}),C(D)};return{tls_only:b(()=>{this.usingTLS=!0,this.updateStrategy(),this.retryIn(0)}),refused:b(()=>{this.disconnect()}),backoff:b(()=>{this.retryIn(1e3)}),retry:b(()=>{this.retryIn(0)})}}setConnection(b){this.connection=b;for(var C in this.connectionCallbacks)this.connection.bind(C,this.connectionCallbacks[C]);this.resetActivityCheck()}abandonConnection(){if(this.connection){this.stopActivityCheck();for(var b in this.connectionCallbacks)this.connection.unbind(b,this.connectionCallbacks[b]);var C=this.connection;return this.connection=null,C}}updateState(b,C){var D=this.state;if(this.state=b,D!==b){var I=b;I==="connected"&&(I+=" with new socket ID "+C.socket_id),nt.debug("State changed",D+" -> "+I),this.timeline.info({state:b,params:C}),this.emit("state_change",{previous:D,current:b}),this.emit(b,C)}}shouldRetry(){return this.state==="connecting"||this.state==="connected"}}class Fc{constructor(){this.channels={}}add(b,C){return this.channels[b]||(this.channels[b]=Vc(b,C)),this.channels[b]}all(){return rn(this.channels)}find(b){return this.channels[b]}remove(b){var C=this.channels[b];return delete this.channels[b],C}disconnect(){Ot(this.channels,function(b){b.disconnect()})}}function Vc(E,b){if(E.indexOf("private-encrypted-")===0){if(b.config.nacl)return jn.createEncryptedChannel(E,b,b.config.nacl);let C="Tried to subscribe to a private-encrypted- channel but no nacl implementation available",D=$.buildLogSuffix("encryptedChannelSupport");throw new pe(`${C}. ${D}`)}else{if(E.indexOf("private-")===0)return jn.createPrivateChannel(E,b);if(E.indexOf("presence-")===0)return jn.createPresenceChannel(E,b);if(E.indexOf("#")===0)throw new P('Cannot create a channel with name "'+E+'".');return jn.createChannel(E,b)}}var oh={createChannels(){return new Fc},createConnectionManager(E,b){return new sh(E,b)},createChannel(E,b){return new Wr(E,b)},createPrivateChannel(E,b){return new ua(E,b)},createPresenceChannel(E,b){return new qc(E,b)},createEncryptedChannel(E,b,C){return new Ba(E,b,C)},createTimelineSender(E,b){return new Ua(E,b)},createHandshake(E,b){return new Wo(E,b)},createAssistantToTheTransportManager(E,b,C){return new ih(E,b,C)}};const jn=oh;class Di{constructor(b){this.options=b||{},this.livesLeft=this.options.lives||1/0}getAssistant(b){return jn.createAssistantToTheTransportManager(this,b,{minPingDelay:this.options.minPingDelay,maxPingDelay:this.options.maxPingDelay})}isAlive(){return this.livesLeft>0}reportDeath(){this.livesLeft-=1}}class yn{constructor(b,C){this.strategies=b,this.loop=!!C.loop,this.failFast=!!C.failFast,this.timeout=C.timeout,this.timeoutLimit=C.timeoutLimit}isSupported(){return Wn(this.strategies,Te.method("isSupported"))}connect(b,C){var D=this.strategies,I=0,ne=this.timeout,me=null,$e=(Ke,ct)=>{ct?C(null,ct):(I=I+1,this.loop&&(I=I%D.length),I0&&(ne=new ie(D.timeout,function(){me.abort(),I(!0)})),me=b.connect(C,function($e,Ke){$e&&ne&&ne.isRunning()&&!D.failFast||(ne&&ne.ensureAborted(),I($e,Ke))}),{abort:function(){ne&&ne.ensureAborted(),me.abort()},forceMinPriority:function($e){me.forceMinPriority($e)}}}}class xn{constructor(b){this.strategies=b}isSupported(){return Wn(this.strategies,Te.method("isSupported"))}connect(b,C){return Kc(this.strategies,b,function(D,I){return function(ne,me){if(I[D].error=ne,ne){lh(I)&&C(!0);return}Kt(I,function($e){$e.forceMinPriority(me.transport.priority)}),C(null,me)}})}}function Kc(E,b,C){var D=It(E,function(I,ne,me,$e){return I.connect(b,C(ne,$e))});return{abort:function(){Kt(D,Yo)},forceMinPriority:function(I){Kt(D,function(ne){ne.forceMinPriority(I)})}}}function lh(E){return Vr(E,function(b){return!!b.error})}function Yo(E){!E.error&&!E.aborted&&(E.abort(),E.aborted=!0)}class Wc{constructor(b,C,D){this.strategy=b,this.transports=C,this.ttl=D.ttl||18e5,this.usingTLS=D.useTLS,this.timeline=D.timeline}isSupported(){return this.strategy.isSupported()}connect(b,C){var D=this.usingTLS,I=ch(D),ne=I&&I.cacheSkipCount?I.cacheSkipCount:0,me=[this.strategy];if(I&&I.timestamp+this.ttl>=Te.now()){var $e=this.transports[I.transport];$e&&(["ws","wss"].includes(I.transport)||ne>3?(this.timeline.info({cached:!0,transport:I.transport,latency:I.latency}),me.push(new yn([$e],{timeout:I.latency*2+1e3,failFast:!0}))):ne++)}var Ke=Te.now(),ct=me.pop().connect(b,function gt(zt,$r){zt?(Ts(D),me.length>0?(Ke=Te.now(),ct=me.pop().connect(b,gt)):C(zt)):(Hn(D,$r.transport.name,Te.now()-Ke,ne),C(null,$r))});return{abort:function(){ct.abort()},forceMinPriority:function(gt){b=gt,ct&&ct.forceMinPriority(gt)}}}}function qa(E){return"pusherTransport"+(E?"TLS":"NonTLS")}function ch(E){var b=ze.getLocalStorage();if(b)try{var C=b[qa(E)];if(C)return JSON.parse(C)}catch{Ts(E)}return null}function Hn(E,b,C,D){var I=ze.getLocalStorage();if(I)try{I[qa(E)]=gn({timestamp:Te.now(),transport:b,latency:C,cacheSkipCount:D})}catch{}}function Ts(E){var b=ze.getLocalStorage();if(b)try{delete b[qa(E)]}catch{}}class Oi{constructor(b,{delay:C}){this.strategy=b,this.options={delay:C}}isSupported(){return this.strategy.isSupported()}connect(b,C){var D=this.strategy,I,ne=new ie(this.options.delay,function(){I=D.connect(b,C)});return{abort:function(){ne.ensureAborted(),I&&I.abort()},forceMinPriority:function(me){b=me,I&&I.forceMinPriority(me)}}}}class da{constructor(b,C,D){this.test=b,this.trueBranch=C,this.falseBranch=D}isSupported(){var b=this.test()?this.trueBranch:this.falseBranch;return b.isSupported()}connect(b,C){var D=this.test()?this.trueBranch:this.falseBranch;return D.connect(b,C)}}class Ga{constructor(b){this.strategy=b}isSupported(){return this.strategy.isSupported()}connect(b,C){var D=this.strategy.connect(b,function(I,ne){ne&&D.abort(),C(I,ne)});return D}}function Fa(E){return function(){return E.isSupported()}}var Yc=function(E,b,C){var D={};function I(cl,cu,uu,Dh,Oh){var du=C(E,cl,cu,uu,Dh,Oh);return D[cl]=du,du}var ne=Object.assign({},b,{hostNonTLS:E.wsHost+":"+E.wsPort,hostTLS:E.wsHost+":"+E.wssPort,httpPath:E.wsPath}),me=Object.assign({},ne,{useTLS:!0}),$e=Object.assign({},b,{hostNonTLS:E.httpHost+":"+E.httpPort,hostTLS:E.httpHost+":"+E.httpsPort,httpPath:E.httpPath}),Ke={loop:!0,timeout:15e3,timeoutLimit:6e4},ct=new Di({minPingDelay:1e4,maxPingDelay:E.activityTimeout}),gt=new Di({lives:2,minPingDelay:1e4,maxPingDelay:E.activityTimeout}),zt=I("ws","ws",3,ne,ct),$r=I("wss","ws",3,me,ct),Th=I("sockjs","sockjs",1,$e),ou=I("xhr_streaming","xhr_streaming",1,$e,gt),kh=I("xdr_streaming","xdr_streaming",1,$e,gt),sl=I("xhr_polling","xhr_polling",1,$e),lu=I("xdr_polling","xdr_polling",1,$e),Wa=new yn([zt],Ke),ji=new yn([$r],Ke),Rh=new yn([Th],Ke),Hi=new yn([new da(Fa(ou),ou,kh)],Ke),ol=new yn([new da(Fa(sl),sl,lu)],Ke),ll=new yn([new da(Fa(Hi),new xn([Hi,new Oi(ol,{delay:4e3})]),ol)],Ke),zi=new da(Fa(ll),ll,Rh),Ui;return b.useTLS?Ui=new xn([Wa,new Oi(zi,{delay:2e3})]):Ui=new xn([Wa,new Oi(ji,{delay:2e3}),new Oi(zi,{delay:5e3})]),new Wc(new Ga(new da(Fa(zt),Ui,zi)),D,{ttl:18e5,timeline:b.timeline,useTLS:b.useTLS})};const Va=Yc;function uh(){var E=this;E.timeline.info(E.buildTimelineMessage({transport:E.name+(E.options.useTLS?"s":"")})),E.hooks.isInitialized()?E.changeState("initialized"):E.hooks.file?(E.changeState("initializing"),x.load(E.hooks.file,{useTLS:E.options.useTLS},function(b,C){E.hooks.isInitialized()?(E.changeState("initialized"),C(!0)):(b&&E.onError(b),E.onClose(),C(!1))})):E.onClose()}var Xc={getRequest:function(E){var b=new window.XDomainRequest;return b.ontimeout=function(){E.emit("error",new G),E.close()},b.onerror=function(C){E.emit("error",C),E.close()},b.onprogress=function(){b.responseText&&b.responseText.length>0&&E.onChunk(200,b.responseText)},b.onload=function(){b.responseText&&b.responseText.length>0&&E.onChunk(200,b.responseText),E.emit("finished",200),E.close()},b},abortRequest:function(E){E.ontimeout=E.onerror=E.onprogress=E.onload=null,E.abort()}};const Jc=Xc,Xo=256*1024;class dh extends Ae{constructor(b,C,D){super(),this.hooks=b,this.method=C,this.url=D}start(b){this.position=0,this.xhr=this.hooks.getRequest(this),this.unloader=()=>{this.close()},ze.addUnloadListener(this.unloader),this.xhr.open(this.method,this.url,!0),this.xhr.setRequestHeader&&this.xhr.setRequestHeader("Content-Type","application/json"),this.xhr.send(b)}close(){this.unloader&&(ze.removeUnloadListener(this.unloader),this.unloader=null),this.xhr&&(this.hooks.abortRequest(this.xhr),this.xhr=null)}onChunk(b,C){for(;;){var D=this.advanceBuffer(C);if(D)this.emit("chunk",{status:b,data:D});else break}this.isBufferTooLong(C)&&this.emit("buffer_too_long")}advanceBuffer(b){var C=b.slice(this.position),D=C.indexOf(` -`);return D!==-1?(this.position+=D+1,C.slice(0,D)):null}isBufferTooLong(b){return this.position===b.length&&b.length>Xo}}var Jo;(function(E){E[E.CONNECTING=0]="CONNECTING",E[E.OPEN=1]="OPEN",E[E.CLOSED=3]="CLOSED"})(Jo||(Jo={}));const cr=Jo;var Dr=1;class Qo{constructor(b,C){this.hooks=b,this.session=ks(1e3)+"/"+Zc(8),this.location=Zo(C),this.readyState=cr.CONNECTING,this.openStream()}send(b){return this.sendRaw(JSON.stringify([b]))}ping(){this.hooks.sendHeartbeat(this)}close(b,C){this.onClose(b,C,!0)}sendRaw(b){if(this.readyState===cr.OPEN)try{return ze.createSocketRequest("POST",fa(Ka(this.location,this.session))).start(b),!0}catch{return!1}else return!1}reconnect(){this.closeStream(),this.openStream()}onClose(b,C,D){this.closeStream(),this.readyState=cr.CLOSED,this.onclose&&this.onclose({code:b,reason:C,wasClean:D})}onChunk(b){if(b.status===200){this.readyState===cr.OPEN&&this.onActivity();var C,D=b.data.slice(0,1);switch(D){case"o":C=JSON.parse(b.data.slice(1)||"{}"),this.onOpen(C);break;case"a":C=JSON.parse(b.data.slice(1)||"[]");for(var I=0;I{this.onChunk(b)}),this.stream.bind("finished",b=>{this.hooks.onFinished(this,b)}),this.stream.bind("buffer_too_long",()=>{this.reconnect()});try{this.stream.start()}catch(b){Te.defer(()=>{this.onError(b),this.onClose(1006,"Could not start streaming",!1)})}}closeStream(){this.stream&&(this.stream.unbind_all(),this.stream.close(),this.stream=null)}}function Zo(E){var b=/([^\?]*)\/*(\??.*)/.exec(E);return{base:b[1],queryString:b[2]}}function Ka(E,b){return E.base+"/"+b+"/xhr_send"}function fa(E){var b=E.indexOf("?")===-1?"?":"&";return E+b+"t="+ +new Date+"&n="+Dr++}function Qc(E,b){var C=/(https?:\/\/)([^\/:]+)((\/|:)?.*)/.exec(E);return C[1]+b+C[3]}function ks(E){return ze.randomInt(E)}function Zc(E){for(var b=[],C=0;C0&&E.onChunk(C.status,C.responseText);break;case 4:C.responseText&&C.responseText.length>0&&E.onChunk(C.status,C.responseText),E.emit("finished",C.status),E.close();break}},C},abortRequest:function(E){E.onreadystatechange=null,E.abort()}};const Rs=tl;var eu={createStreamingSocket(E){return this.createSocket(el,E)},createPollingSocket(E){return this.createSocket(Yr,E)},createSocket(E,b){return new Li(E,b)},createXHR(E,b){return this.createRequest(Rs,E,b)},createRequest(E,b,C){return new dh(E,b,C)}};const Mi=eu;Mi.createXDR=function(E,b){return this.createRequest(Jc,E,b)};var tu={nextAuthCallbackID:1,auth_callbacks:{},ScriptReceivers:m,DependenciesReceivers:_,getDefaultStrategy:Va,Transports:An,transportConnectionInitializer:uh,HTTPFactory:Mi,TimelineTransport:on,getXHRAPI(){return window.XMLHttpRequest},getWebSocketAPI(){return window.WebSocket||window.MozWebSocket},setup(E){window.Pusher=E;var b=()=>{this.onDocumentBody(E.ready)};window.JSON?b():x.load("json2",{},b)},getDocument(){return document},getProtocol(){return this.getDocument().location.protocol},getAuthorizers(){return{ajax:qe,jsonp:mn}},onDocumentBody(E){document.body?E():setTimeout(()=>{this.onDocumentBody(E)},0)},createJSONPRequest(E,b){return new lr(E,b)},createScriptRequest(E){return new ca(E)},getLocalStorage(){try{return window.localStorage}catch{return}},createXHR(){return this.getXHRAPI()?this.createXMLHttpRequest():this.createMicrosoftXHR()},createXMLHttpRequest(){var E=this.getXHRAPI();return new E},createMicrosoftXHR(){return new ActiveXObject("Microsoft.XMLHTTP")},getNetwork(){return Ko},createWebSocket(E){var b=this.getWebSocketAPI();return new b(E)},createSocketRequest(E,b){if(this.isXHRSupported())return this.HTTPFactory.createXHR(E,b);if(this.isXDRSupported(b.indexOf("https:")===0))return this.HTTPFactory.createXDR(E,b);throw"Cross-origin HTTP requests are not supported"},isXHRSupported(){var E=this.getXHRAPI();return!!E&&new E().withCredentials!==void 0},isXDRSupported(E){var b=E?"https:":"http:",C=this.getProtocol();return!!window.XDomainRequest&&C===b},addUnloadListener(E){window.addEventListener!==void 0?window.addEventListener("unload",E,!1):window.attachEvent!==void 0&&window.attachEvent("onunload",E)},removeUnloadListener(E){window.addEventListener!==void 0?window.removeEventListener("unload",E,!1):window.detachEvent!==void 0&&window.detachEvent("onunload",E)},randomInt(E){return Math.floor(function(){return(window.crypto||window.msCrypto).getRandomValues(new Uint32Array(1))[0]/Math.pow(2,32)}()*E)}};const ze=tu;var Lr;(function(E){E[E.ERROR=3]="ERROR",E[E.INFO=6]="INFO",E[E.DEBUG=7]="DEBUG"})(Lr||(Lr={}));const ha=Lr;class Ni{constructor(b,C,D){this.key=b,this.session=C,this.events=[],this.options=D||{},this.sent=0,this.uniqueID=0}log(b,C){b<=this.options.level&&(this.events.push(Me({},C,{timestamp:Te.now()})),this.options.limit&&this.events.length>this.options.limit&&this.events.shift())}error(b){this.log(ha.ERROR,b)}info(b){this.log(ha.INFO,b)}debug(b){this.log(ha.DEBUG,b)}isEmpty(){return this.events.length===0}send(b,C){var D=Me({session:this.session,bundle:this.sent+1,key:this.key,lib:"js",version:this.options.version,cluster:this.options.cluster,features:this.options.features,timeline:this.events},this.options.params);return this.events=[],b(D,(I,ne)=>{I||this.sent++,C&&C(I,ne)}),!0}generateUniqueID(){return this.uniqueID++,this.uniqueID}}class fh{constructor(b,C,D,I){this.name=b,this.priority=C,this.transport=D,this.options=I||{}}isSupported(){return this.transport.isSupported({useTLS:this.options.useTLS})}connect(b,C){if(this.isSupported()){if(this.priority{D||(gt(),ne?ne.close():I.close())},forceMinPriority:zt=>{D||this.priority{var C="socket_id="+encodeURIComponent(E.socketId);for(var D in b.params)C+="&"+encodeURIComponent(D)+"="+encodeURIComponent(b.params[D]);if(b.paramsProvider!=null){let I=b.paramsProvider();for(var D in I)C+="&"+encodeURIComponent(D)+"="+encodeURIComponent(I[D])}return C},ph=E=>{if(typeof ze.getAuthorizers()[E.transport]>"u")throw`'${E.transport}' is not a recognized auth transport`;return(b,C)=>{const D=hh(b,E);ze.getAuthorizers()[E.transport](ze,D,E,k.UserAuthentication,C)}},al=(E,b)=>{var C="socket_id="+encodeURIComponent(E.socketId);C+="&channel_name="+encodeURIComponent(E.channelName);for(var D in b.params)C+="&"+encodeURIComponent(D)+"="+encodeURIComponent(b.params[D]);if(b.paramsProvider!=null){let I=b.paramsProvider();for(var D in I)C+="&"+encodeURIComponent(D)+"="+encodeURIComponent(I[D])}return C},gh=E=>{if(typeof ze.getAuthorizers()[E.transport]>"u")throw`'${E.transport}' is not a recognized auth transport`;return(b,C)=>{const D=al(b,E);ze.getAuthorizers()[E.transport](ze,D,E,k.ChannelAuthorization,C)}},mh=(E,b,C)=>{const D={authTransport:b.transport,authEndpoint:b.endpoint,auth:{params:b.params,headers:b.headers}};return(I,ne)=>{const me=E.channel(I.channelName);C(me,D).authorize(I.socketId,ne)}};function ru(E,b){let C={activityTimeout:E.activityTimeout||S.activityTimeout,cluster:E.cluster,httpPath:E.httpPath||S.httpPath,httpPort:E.httpPort||S.httpPort,httpsPort:E.httpsPort||S.httpsPort,pongTimeout:E.pongTimeout||S.pongTimeout,statsHost:E.statsHost||S.stats_host,unavailableTimeout:E.unavailableTimeout||S.unavailableTimeout,wsPath:E.wsPath||S.wsPath,wsPort:E.wsPort||S.wsPort,wssPort:E.wssPort||S.wssPort,enableStats:Sh(E),httpHost:yh(E),useTLS:vh(E),wsHost:au(E),userAuthenticator:il(E),channelAuthorizer:Ch(E,b)};return"disabledTransports"in E&&(C.disabledTransports=E.disabledTransports),"enabledTransports"in E&&(C.enabledTransports=E.enabledTransports),"ignoreNullOrigin"in E&&(C.ignoreNullOrigin=E.ignoreNullOrigin),"timelineParams"in E&&(C.timelineParams=E.timelineParams),"nacl"in E&&(C.nacl=E.nacl),C}function yh(E){return E.httpHost?E.httpHost:E.cluster?`sockjs-${E.cluster}.pusher.com`:S.httpHost}function au(E){return E.wsHost?E.wsHost:bh(E.cluster)}function bh(E){return`ws-${E}.pusher.com`}function vh(E){return ze.getProtocol()==="https:"?!0:E.forceTLS!==!1}function Sh(E){return"enableStats"in E?E.enableStats:"disableStats"in E?!E.disableStats:!1}const iu=E=>"customHandler"in E&&E.customHandler!=null;function il(E){const b=Object.assign(Object.assign({},S.userAuthentication),E.userAuthentication);return iu(b)?b.customHandler:ph(b)}function wh(E,b){let C;if("channelAuthorization"in E)C=Object.assign(Object.assign({},S.channelAuthorization),E.channelAuthorization);else if(C={transport:E.authTransport||S.authTransport,endpoint:E.authEndpoint||S.authEndpoint},"auth"in E&&("params"in E.auth&&(C.params=E.auth.params),"headers"in E.auth&&(C.headers=E.auth.headers)),"authorizer"in E)return{customHandler:mh(b,C,E.authorizer)};return C}function Ch(E,b){const C=wh(E,b);return iu(C)?C.customHandler:gh(C)}class Eh extends Ae{constructor(b){super(function(C,D){nt.debug(`No callbacks on watchlist events for ${C}`)}),this.pusher=b,this.bindWatchlistInternalEvent()}handleEvent(b){b.data.events.forEach(C=>{this.emit(C.name,C)})}bindWatchlistInternalEvent(){this.pusher.connection.bind("message",b=>{var C=b.event;C==="pusher_internal:watchlist_events"&&this.handleEvent(b)})}}function su(){let E,b;return{promise:new Promise((D,I)=>{E=D,b=I}),resolve:E,reject:b}}const _h=su;class Ah extends Ae{constructor(b){super(function(C,D){nt.debug("No callbacks on user for "+C)}),this.signin_requested=!1,this.user_data=null,this.serverToUserChannel=null,this.signinDonePromise=null,this._signinDoneResolve=null,this._onAuthorize=(C,D)=>{if(C){nt.warn(`Error during signin: ${C}`),this._cleanup();return}this.pusher.send_event("pusher:signin",{auth:D.auth,user_data:D.user_data})},this.pusher=b,this.pusher.connection.bind("state_change",({previous:C,current:D})=>{C!=="connected"&&D==="connected"&&this._signin(),C==="connected"&&D!=="connected"&&(this._cleanup(),this._newSigninPromiseIfNeeded())}),this.watchlist=new Eh(b),this.pusher.connection.bind("message",C=>{var D=C.event;D==="pusher:signin_success"&&this._onSigninSuccess(C.data),this.serverToUserChannel&&this.serverToUserChannel.name===C.channel&&this.serverToUserChannel.handleEvent(C)})}signin(){this.signin_requested||(this.signin_requested=!0,this._signin())}_signin(){this.signin_requested&&(this._newSigninPromiseIfNeeded(),this.pusher.connection.state==="connected"&&this.pusher.config.userAuthenticator({socketId:this.pusher.connection.socket_id},this._onAuthorize))}_onSigninSuccess(b){try{this.user_data=JSON.parse(b.user_data)}catch{nt.error(`Failed parsing user data after signin: ${b.user_data}`),this._cleanup();return}if(typeof this.user_data.id!="string"||this.user_data.id===""){nt.error(`user_data doesn't contain an id. user_data: ${this.user_data}`),this._cleanup();return}this._signinDoneResolve(),this._subscribeChannels()}_subscribeChannels(){const b=C=>{C.subscriptionPending&&C.subscriptionCancelled?C.reinstateSubscription():!C.subscriptionPending&&this.pusher.connection.state==="connected"&&C.subscribe()};this.serverToUserChannel=new Wr(`#server-to-user-${this.user_data.id}`,this.pusher),this.serverToUserChannel.bind_global((C,D)=>{C.indexOf("pusher_internal:")===0||C.indexOf("pusher:")===0||this.emit(C,D)}),b(this.serverToUserChannel)}_cleanup(){this.user_data=null,this.serverToUserChannel&&(this.serverToUserChannel.unbind_all(),this.serverToUserChannel.disconnect(),this.serverToUserChannel=null),this.signin_requested&&this._signinDoneResolve()}_newSigninPromiseIfNeeded(){if(!this.signin_requested||this.signinDonePromise&&!this.signinDonePromise.done)return;const{promise:b,resolve:C}=_h();b.done=!1;const D=()=>{b.done=!0};b.then(D).catch(D),this.signinDonePromise=b,this._signinDoneResolve=C}}class ln{static ready(){ln.isReady=!0;for(var b=0,C=ln.instances.length;bze.getDefaultStrategy(this.config,I,Ii);this.connection=jn.createConnectionManager(this.key,{getStrategy:D,timeline:this.timeline,activityTimeout:this.config.activityTimeout,pongTimeout:this.config.pongTimeout,unavailableTimeout:this.config.unavailableTimeout,useTLS:!!this.config.useTLS}),this.connection.bind("connected",()=>{this.subscribeAll(),this.timelineSender&&this.timelineSender.send(this.connection.isUsingTLS())}),this.connection.bind("message",I=>{var ne=I.event,me=ne.indexOf("pusher_internal:")===0;if(I.channel){var $e=this.channel(I.channel);$e&&$e.handleEvent(I)}me||this.global_emitter.emit(I.event,I.data)}),this.connection.bind("connecting",()=>{this.channels.disconnect()}),this.connection.bind("disconnected",()=>{this.channels.disconnect()}),this.connection.bind("error",I=>{nt.warn(I)}),ln.instances.push(this),this.timeline.info({instances:ln.instances.length}),this.user=new Ah(this),ln.isReady&&this.connect()}switchCluster(b){const{appKey:C,cluster:D}=b;this.key=C,this.options=Object.assign(Object.assign({},this.options),{cluster:D}),this.config=ru(this.options,this),this.connection.switchCluster(this.key)}channel(b){return this.channels.find(b)}allChannels(){return this.channels.all()}connect(){if(this.connection.connect(),this.timelineSender&&!this.timelineSenderTimer){var b=this.connection.isUsingTLS(),C=this.timelineSender;this.timelineSenderTimer=new xe(6e4,function(){C.send(b)})}}disconnect(){this.connection.disconnect(),this.timelineSenderTimer&&(this.timelineSenderTimer.ensureAborted(),this.timelineSenderTimer=null)}bind(b,C,D){return this.global_emitter.bind(b,C,D),this}unbind(b,C,D){return this.global_emitter.unbind(b,C,D),this}bind_global(b){return this.global_emitter.bind_global(b),this}unbind_global(b){return this.global_emitter.unbind_global(b),this}unbind_all(b){return this.global_emitter.unbind_all(),this}subscribeAll(){var b;for(b in this.channels.channels)this.channels.channels.hasOwnProperty(b)&&this.subscribe(b)}subscribe(b){var C=this.channels.add(b,this);return C.subscriptionPending&&C.subscriptionCancelled?C.reinstateSubscription():!C.subscriptionPending&&this.connection.state==="connected"&&C.subscribe(),C}unsubscribe(b){var C=this.channels.find(b);C&&C.subscriptionPending?C.cancelSubscription():(C=this.channels.remove(b),C&&C.subscribed&&C.unsubscribe())}send_event(b,C,D){return this.connection.send_event(b,C,D)}shouldUseTLS(){return this.config.useTLS}signin(){this.user.signin()}}ln.instances=[],ln.isReady=!1,ln.logToConsole=!1,ln.Runtime=ze,ln.ScriptReceivers=ze.ScriptReceivers,ln.DependenciesReceivers=ze.DependenciesReceivers,ln.auth_callbacks=ze.auth_callbacks;const Ls=ln;function xh(E){if(E==null)throw"You must pass your app key when you instantiate Pusher."}ze.setup(ln)}},r={};function i(c){var d=r[c];if(d!==void 0)return d.exports;var f=r[c]={exports:{}};return n[c].call(f.exports,f,f.exports,i),f.exports}i.d=(c,d)=>{for(var f in d)i.o(d,f)&&!i.o(c,f)&&Object.defineProperty(c,f,{enumerable:!0,get:d[f]})},i.o=(c,d)=>Object.prototype.hasOwnProperty.call(c,d);var l=i(721);return l})())})(Qf)),Qf.exports}var KA=VA();const Yy=ta(KA),Pt=dt("WebSocketManager");class WA{constructor(){M(this,"echo",null);M(this,"subscriptions",new Map);M(this,"initialized",!1);M(this,"config",null)}configure(e){if(this.initialized){Pt.warn("[WebSocketManager] 이미 초기화되어 설정을 변경할 수 없습니다.");return}this.config=e,Pt.log("[WebSocketManager] 설정 완료:",{appKey:e.appKey?"***":"(없음)",host:e.host,port:e.port,scheme:e.scheme})}initialize(){if(this.initialized)return;if(!this.config||!this.config.appKey){Pt.warn("[WebSocketManager] WebSocket 설정이 없습니다. initTemplateApp에서 websocket 옵션을 전달해주세요.");return}const{appKey:e,host:n="localhost",port:r=80,scheme:i="https",authEndpoint:l="/api/broadcasting/auth"}=this.config,c=Number(r)||80,d=i==="https";Pt.log("[WebSocketManager] 연결 설정:",{host:n,port:c,scheme:i,useTLS:d,authEndpoint:l}),window.Pusher=Yy;const f=localStorage.getItem("auth_token"),h={wsHost:n,wsPort:c,wssPort:c,forceTLS:d,disableStats:!0,enabledTransports:["ws","wss"],cluster:"mt1",authEndpoint:l,auth:{headers:{Authorization:f?`Bearer ${f}`:"",Accept:"application/json"}}};Pt.log("[WebSocketManager] Pusher 옵션:",h);const m=new Yy(e,h);m.connection.bind("connecting",()=>{Pt.log("[WebSocketManager] 연결 시도 중...")}),m.connection.bind("connected",()=>{Pt.log("[WebSocketManager] 연결 성공! Socket ID:",m.connection.socket_id)}),m.connection.bind("failed",()=>{Pt.error("[WebSocketManager] 연결 실패 - WebSocket을 사용할 수 없습니다.")}),m.connection.bind("error",y=>{Pt.error("[WebSocketManager] 연결 오류:",y)}),m.connection.bind("state_change",y=>{Pt.log(`[WebSocketManager] 상태 변경: ${y.previous} → ${y.current}`)}),m.connection.bind("unavailable",()=>{Pt.error("[WebSocketManager] WebSocket 사용 불가 - 연결할 수 없습니다.")}),m.connection.bind("disconnected",()=>{Pt.warn("[WebSocketManager] 연결이 끊어졌습니다.")}),Pt.log("[WebSocketManager] 초기 연결 상태:",m.connection.state),this.echo=new FA({broadcaster:"reverb",client:m}),Pt.log("[WebSocketManager] 연결 시작 시도..."),m.connect(),window.Echo=this.echo,this.initialized=!0,Pt.log("[WebSocketManager] Echo 초기화 완료")}subscribe(e,n,r,i={}){if(this.initialize(),!this.echo)return Pt.warn("[WebSocketManager] Echo가 초기화되지 않았습니다."),"";const{channelType:l="private"}=i,c=`${e}:${n}`;if(this.subscriptions.has(c))return Pt.log(`[WebSocketManager] 이미 구독 중: ${c}`),c;let d;switch(l){case"public":d=this.echo.channel(e);break;case"presence":d=this.echo.join(e);break;default:d=this.echo.private(e)}return d.listen(`.${n}`,r),this.subscriptions.set(c,d),Pt.log(`[WebSocketManager] 구독 완료: ${c} (${l})`),c}unsubscribe(e){const n=this.subscriptions.get(e);if(!n)return;const r=e.lastIndexOf(":"),i=r>=0?e.substring(r+1):"";if(i)try{n.stopListening(`.${i}`)}catch(l){Pt.warn(`[WebSocketManager] stopListening 실패: ${e}`,l)}this.subscriptions.delete(e),Pt.log(`[WebSocketManager] 구독 해제: ${e}`)}leaveChannel(e){if(!this.echo)return;this.echo.leave(e);const n=[];this.subscriptions.forEach((r,i)=>{i.startsWith(`${e}:`)&&n.push(i)}),n.forEach(r=>this.subscriptions.delete(r)),Pt.log(`[WebSocketManager] 채널 구독 해제: ${e}`)}disconnect(){this.echo&&(this.echo.disconnect(),this.subscriptions.clear(),this.initialized=!1,Pt.log("[WebSocketManager] 연결 종료"))}getEcho(){return this.echo}isInitialized(){return this.initialized}isConfigured(){return this.config!==null&&!!this.config.appKey}getSubscriptionCount(){return this.subscriptions.size}}const Mc=new WA,bt=dt("DataSourceManager"),Xy=new kn;function Nc(s,e){const n=Da(s);if(n!==null)try{return Gn(n)?Xy.evaluatePipeExpression(n,e,{skipCache:!0}):Xy.evaluateExpression(n,e)}catch(r){return bt.error("Failed to evaluate param expression:",n,r),s}return ls(s,e,{skipCache:!0})}function Jy(s){const e={};for(const n of s.keys()){if(n in e)continue;const r=s.getAll(n);r.length>1?e[n]=r:r.length===1&&(n.endsWith("[]")?e[n]=r:e[n]=r[0])}return e}function YA(){try{return window.G7Core?.devTools}catch{return}}const Pc=class Pc{constructor(e={}){M(this,"options");M(this,"dataCache",new Map);M(this,"bindingEngine");M(this,"globalHeaders",[]);this.options=e,this.bindingEngine=new kn}setGlobalHeaders(e){this.globalHeaders=e||[]}matchesPattern(e,n){if(n==="*")return!0;const r=n.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${r}$`).test(e)}toFormData(e){const n=new FormData;for(const[r,i]of Object.entries(e))i instanceof File||i instanceof Blob?n.append(r,i):i!=null&&n.append(r,typeof i=="object"?JSON.stringify(i):String(i));return n}getMatchingGlobalHeaders(e,n){const r={};for(const i of this.globalHeaders)this.matchesPattern(e,i.pattern)&&Object.entries(i.headers).forEach(([l,c])=>{const d=Nc(c,n);d!=null&&d!==""&&(r[l]=String(d))});return r}filterByCondition(e,n={}){const r=new Set,i=[];for(const l of e){if(r.has(l.id))continue;if(!l.if&&!l.conditions){r.add(l.id),i.push(l);continue}os({if:l.if,conditions:l.conditions},n,this.bindingEngine,`data_source:${l.id}`)&&(r.add(l.id),i.push(l))}return i}checkErrorCondition(e,n){if(!e.errorCondition?.if||e.errorCondition?.errorCode===void 0)return null;try{const r={response:n};if(os({if:e.errorCondition.if},r,this.bindingEngine,`errorCondition:${e.id}`))return bt.log(`errorCondition matched for ${e.id}, triggering error ${e.errorCondition.errorCode}`),e.errorCondition.errorCode}catch(r){bt.error(`Failed to evaluate errorCondition for ${e.id}:`,r)}return null}async fetchDataSources(e,n={},r=new URLSearchParams,i,l){const c={},d=!!this.options.sampleProvider,f=e.filter(h=>(d||h.auto_fetch!==!1)&&h.type!=="websocket");return await Promise.all(f.map(async h=>{try{const m=await this.fetchDataSource(h,n,r,i,l);c[h.id]=m,this.dataCache.set(h.id,{data:m,timestamp:Date.now()});const y=this.checkErrorCondition(h,m);if(y!==null){const S={status:y,message:`Error condition matched for ${h.id}`,data:m},v=Er(),_=v.resolve(y,{errorHandling:h.errorHandling,onError:h.onError});if(_.handler)try{await v.execute(_.handler,S)}catch(x){bt.error(`Error executing errorCondition handler for ${h.id}:`,x)}h.fallback!==void 0&&(c[h.id]=h.fallback,this.dataCache.set(h.id,{data:h.fallback,timestamp:Date.now()}),bt.log(`Using fallback data for ${h.id} (errorCondition)`));return}if(h.onSuccess)try{const S={data:m,sourceId:h.id};await this.executeOnSuccessHandler(h.onSuccess,S)}catch(S){bt.error(`Error executing onSuccess handler for ${h.id}:`,S)}}catch(m){bt.error(`Failed to fetch data source: ${h.id}`,m);const y=m?.response?.status||m?.status||500,S=m?.response?.data,v=S?.message||m.message||"Unknown error",_={status:y,message:v,errors:S?.errors,data:S,statusText:m?.response?.statusText},x=Er(),A=x.resolve(y,{errorHandling:h.errorHandling,onError:h.onError});if(A.handler)try{await x.execute(A.handler,_)}catch(L){bt.error(`Error executing error handler for ${h.id}:`,L)}h.fallback!==void 0&&(c[h.id]=h.fallback,this.dataCache.set(h.id,{data:h.fallback,timestamp:Date.now()}),bt.log(`Using fallback data for ${h.id}`)),this.options.onError&&this.options.onError(m,h)}})),c}async fetchDataSourcesWithResults(e,n={},r=new URLSearchParams,i,l,c){if(e.some(m=>m.type==="websocket")){const m=e.filter(y=>y.type==="websocket").map(y=>y.id).join(", ");bt.warn(`fetchDataSourcesWithResults received WebSocket sources (caller should filter them out before calling): ${m}. WebSocket sources are event listeners, not data providers — they should not be passed to fetch.`)}const f=c?.ignoreAutoFetch?e.filter(m=>m.type!=="websocket"):e.filter(m=>m.auto_fetch!==!1&&m.type!=="websocket");return await Promise.all(f.map(async m=>{try{const y=await this.fetchDataSource(m,n,r,i,l);this.dataCache.set(m.id,{data:y,timestamp:Date.now()});const S=this.checkErrorCondition(m,y);if(S!==null){const v={status:S,message:`Error condition matched for ${m.id}`,data:y},_=Er(),x=_.resolve(S,{errorHandling:m.errorHandling,onError:m.onError});let A=!1;if(x.handler)if(m.loading_strategy==="blocking")_.execute(x.handler,v).catch(L=>{bt.error(`Error executing errorCondition handler for ${m.id}:`,L)}),A=!0;else try{await _.execute(x.handler,v),A=!0}catch(L){bt.error(`Error executing errorCondition handler for ${m.id}:`,L)}return m.fallback!==void 0?(this.dataCache.set(m.id,{data:m.fallback,timestamp:Date.now()}),bt.log(`Using fallback data for ${m.id} (errorCondition)`),{id:m.id,state:"success",data:m.fallback}):{id:m.id,state:"error",error:new Error(`Error condition matched: ${S}`),errorCode:S,errorHandled:A}}if(m.onSuccess)try{const v={data:y,sourceId:m.id};await this.executeOnSuccessHandler(m.onSuccess,v)}catch(v){bt.error(`Error executing onSuccess handler for ${m.id}:`,v)}return{id:m.id,state:"success",data:y}}catch(y){bt.error(`Failed to fetch data source: ${m.id}`,y);const S=y?.response?.status||y?.status||500,v=y?.response?.data,_=v?.message||y.message||"Unknown error",x={status:S,message:_,errors:v?.errors,data:v,statusText:y?.response?.statusText},A=Er(),L=A.resolve(S,{errorHandling:m.errorHandling,onError:m.onError});let $=!1;if(L.handler)if(m.loading_strategy==="blocking")A.execute(L.handler,x).catch(k=>{bt.error(`Error executing error handler for ${m.id}:`,k)}),$=!0;else try{await A.execute(L.handler,x),$=!0}catch(k){bt.error(`Error executing error handler for ${m.id}:`,k)}return m.fallback!==void 0?(this.dataCache.set(m.id,{data:m.fallback,timestamp:Date.now()}),bt.log(`Using fallback data for ${m.id}`),{id:m.id,state:"success",data:m.fallback}):(this.options.onError&&this.options.onError(y,m),{id:m.id,state:"error",error:y,errorCode:S,errorHandled:$})}}))}fetchDataSourcesInBackground(e,n={},r=new URLSearchParams,i){e.filter(c=>c.auto_fetch!==!1&&c.loading_strategy==="background"&&c.type!=="websocket").forEach(c=>{this.fetchDataSource(c,n,r).then(async d=>{this.dataCache.set(c.id,{data:d,timestamp:Date.now()});const f=this.checkErrorCondition(c,d);if(f!==null){const h={status:f,message:`Error condition matched for ${c.id}`,data:d},m=Er(),y=m.resolve(f,{errorHandling:c.errorHandling,onError:c.onError});if(y.handler)try{await m.execute(y.handler,h)}catch(S){bt.error(`Error executing errorCondition handler for ${c.id}:`,S)}c.fallback!==void 0&&(this.dataCache.set(c.id,{data:c.fallback,timestamp:Date.now()}),bt.log(`Using fallback data for ${c.id} (errorCondition)`),i&&i(c.id,c.fallback));return}if(c.onSuccess)try{const h={data:d,sourceId:c.id};await this.executeOnSuccessHandler(c.onSuccess,h)}catch(h){bt.error(`Error executing onSuccess handler for ${c.id}:`,h)}i&&i(c.id,d)}).catch(async d=>{bt.error(`Background fetch failed: ${c.id}`,d);const f=d?.response?.status||d?.status||500,h=d?.response?.data,m=h?.message||d.message||"Unknown error",y={status:f,message:m,errors:h?.errors,data:h,statusText:d?.response?.statusText},S=Er(),v=S.resolve(f,{errorHandling:c.errorHandling,onError:c.onError});if(v.handler)try{await S.execute(v.handler,y)}catch(_){bt.error(`Error executing error handler for ${c.id}:`,_)}if(c.fallback!==void 0){this.dataCache.set(c.id,{data:c.fallback,timestamp:Date.now()}),bt.log(`Using fallback data for ${c.id}`),i&&i(c.id,c.fallback);return}this.options.onError&&this.options.onError(d,c)})})}async fetchDataSource(e,n,r,i,l){switch(e.type){case"api":return this.fetchApiDataSource(e,n,r,i,l);case"static":return e.data;case"route_params":return n;case"query_params":return Jy(r);default:throw new Error(`Unknown data source type: ${e.type}`)}}async fetchApiDataSource(e,n,r,i,l){if(this.options.sampleProvider?.has(e.id))return await Promise.resolve(this.options.sampleProvider.resolve(e));if(!e.endpoint)throw new Error(`API data source ${e.id} has no endpoint`);const c={route:n,query:Jy(r)};i&&(c._global=i),l&&(c._local=l);let d=ls(e.endpoint,c,{skipCache:!0});const f=e.method||"GET",m=(e.contentType?typeof e.contentType=="string"&&e.contentType.includes("{{")?ls(e.contentType,c,{skipCache:!0}):e.contentType:"application/json")==="multipart/form-data";let y=m?{...e.params||{}}:JSON.parse(JSON.stringify(e.params||{}));Object.entries(y).forEach(([_,x])=>{typeof x=="string"&&(y[_]=Nc(x,c))}),Object.keys(y).forEach(_=>{y[_]===""&&delete y[_]});const S=YA();let v=null;if(S?.isEnabled()){S.trackDataSourceDefinition({id:e.id,type:e.type,endpoint:d,method:f,autoFetch:e.auto_fetch,initLocal:e.initLocal,initGlobal:e.initGlobal});let _=d;if(f==="GET"&&Object.keys(y).length>0){const x=new URLSearchParams;Object.entries(y).forEach(([L,$])=>{Array.isArray($)?$.forEach(k=>x.append(L,String(k))):$!=null&&x.append(L,String($))});const A=x.toString();_=A?`${d}?${A}`:d}v=S.trackRequest(_,f,{requestBody:f!=="GET"?y:void 0,dataSourceId:e.id}),S.trackDataSourceLoading(e.id)}try{let _;const x=e.auth_mode??(e.auth_required===!0?"required":"none"),A=wr.getInstance().isAuthenticated();if(x==="required"&&!A){bt.log(`[DataSourceManager] Skipping ${e.id}: auth_mode is 'required' but no token available`),S?.isEnabled()&&(S.trackDataSourceError(e.id,"Skipped: auth_mode required but not authenticated"),v&&S.failRequest(v,"Skipped: not authenticated"));const $=new Error("Auth required but not authenticated");throw $.response={status:401,statusText:"Unauthorized",data:null},$.status=401,$._authSkipped=!0,$}const L=x==="required"||x==="optional"&&A;if(L){const $=zr(),k=d.startsWith("/api/")?d.substring(4):d.startsWith("/api")?d.substring(4)||"/":d;this.options.onError&&bt.log(`[DataSourceManager] Normalized endpoint: ${d} -> ${k}`);const O=this.getMatchingGlobalHeaders(d,c),P={};e.headers&&Object.entries(e.headers).forEach(([pe,Se])=>{const we=Nc(Se,c);we!=null&&we!==""&&(P[pe]=String(we))});const G={...O,...P},B=Object.keys(G).length>0,W=m?this.toFormData(y):y;switch(f){case"GET":_=await $.get(k,{params:y,...B&&{headers:G}});break;case"POST":B?_=await $.post(k,W,{headers:G}):_=await $.post(k,W);break;case"PUT":B?_=await $.put(k,W,{headers:G}):_=await $.put(k,W);break;case"PATCH":B?_=await $.patch(k,W,{headers:G}):_=await $.patch(k,W);break;case"DELETE":_=await $.delete(k,{params:y,...B&&{headers:G}});break;default:throw new Error(`Unsupported HTTP method: ${f}`)}}else{let $=d;if(f==="GET"){const W=new URLSearchParams(y).toString();$=W?`${d}?${W}`:d}const k={...m?{}:{"Content-Type":"application/json"},Accept:"application/json"};if(typeof window<"u"){const W=localStorage.getItem("g7_locale");W&&(k["Accept-Language"]=W)}const O=this.getMatchingGlobalHeaders(d,c);Object.assign(k,O),e.headers&&Object.entries(e.headers).forEach(([W,pe])=>{const Se=Nc(pe,c);Se!=null&&Se!==""&&(k[W]=String(Se))});let P;f!=="GET"&&(m?(P=this.toFormData(y),delete k["Content-Type"]):P=JSON.stringify(y));const G=await fetch($,{method:f,headers:k,body:P});let B;try{B=await G.json()}catch{B=null}if(v&&S?.isEnabled()&&(S.completeRequest(v,G.status,B),v=null),!G.ok){S?.isEnabled()&&S.trackDataSourceError(e.id,`HTTP ${G.status}: ${G.statusText}`);const W=new Error(`HTTP error! status: ${G.status}`);throw W.response={status:G.status,statusText:G.statusText,data:B},W.status=G.status,W}_=B,S?.isEnabled()&&S.trackDataSourceLoaded(e.id,_)}return L&&v&&S?.isEnabled()&&(S.completeRequest(v,200,_),S.trackDataSourceLoaded(e.id,_)),_}catch(_){if(v&&S?.isEnabled()){const x=_;x?.response?S.completeRequest(v,x.response.status,x.response.data):S.failRequest(v,_ instanceof Error?_.message:String(_)),S.trackDataSourceError(e.id,_ instanceof Error?_.message:String(_))}throw _}}getCachedData(e){const n=this.dataCache.get(e);if(!n)return;if(Date.now()-n.timestamp>Pc.DATA_CACHE_TTL){this.dataCache.delete(e);return}return n.data}clearCache(){this.dataCache.clear()}subscribeWebSockets(e,n,r={}){const i=[],l=e.filter(c=>c.type==="websocket");return l.length===0||l.forEach(c=>{if(!c.channel||!c.event){bt.warn(`WebSocket source ${c.id} missing channel or event`);return}let d,f;try{d=ls(c.channel,r,{skipCache:!0}),f=ls(c.event,r,{skipCache:!0})}catch(y){bt.error(`Failed to resolve WebSocket channel/event for source ${c.id}:`,y);return}const h=y=>!!(!y||y.trim()===""||y.includes("{{")||y.endsWith(".")||y.endsWith(":")||y.startsWith(".")||y.startsWith(":")||y.includes("..")||y.includes("::"));if(h(d)||h(f)){bt.warn(`WebSocket source ${c.id} has invalid channel/event after expression resolution, skipping. Original channel="${c.channel}", resolved="${d}". Original event="${c.event}", resolved="${f}". Available context keys: [${Object.keys(r).join(", ")}]`);return}const m=Mc.subscribe(d,f,y=>{const S=c.target_source||c.id;this.dataCache.set(S,{data:y,timestamp:Date.now()}),n(S,y)},{channelType:c.channel_type||"private"});m&&i.push(m)}),i}unsubscribeWebSockets(e){e.length!==0&&e.forEach(n=>{Mc.unsubscribe(n)})}async executeOnSuccessHandler(e,n){const r=this.options.actionDispatcher??Wm();if(!r){bt.warn("ActionDispatcher not available, skipping onSuccess handler");return}const i=Array.isArray(e)?e:[e];for(const l of i)try{await r.dispatchAction({type:"click",...l},{data:{response:n}})}catch(c){throw bt.error("Failed to execute onSuccess handler:",c),c}}};M(Pc,"DATA_CACHE_TTL",3e5);let Tr=Pc;const XA=new Tr,_i=dt("ModalDataSourceWrapper");function JA(s,e){if(!s||!e)return s;const r=e.replace(/\?\./g,".").split(/\.(?![^\[]*\])/).flatMap(l=>{const c=l.match(/^([^\[]*)((?:\[\d+\])*)$/);if(c){const[,d,f]=c,h=[];d&&h.push(d);const m=f.match(/\[\d+\]/g);return m&&h.push(...m),h}return[l]}).filter(l=>l!=="");let i=s;for(const l of r){if(i==null)return;if(l.startsWith("[")&&l.endsWith("]")){const c=parseInt(l.slice(1,-1),10);i=i[c]}else i=i[l]}return i}const Qy=({isOpen:s,modalId:e,dataSources:n,dataContext:r,globalStateUpdater:i,bindingEngine:l,debug:c=!1,children:d})=>{const[f,h]=N.useState(!1),[m,y]=N.useState(!1),S=N.useRef(!1),v=N.useRef(null);v.current||(v.current=new Tr);const _=N.useCallback(async()=>{if(!(!n||n.length===0)&&v.current){h(!0);try{const x=r.route||{},A=new URLSearchParams(window.location.search),L=n.map(k=>{let O={...k};if(k.endpoint&&l){const P=l.resolveBindings(k.endpoint,r,{skipCache:!0});O.endpoint=P}if(k.params&&l){const P={};Object.entries(k.params).forEach(([G,B])=>{typeof B=="string"?P[G]=l.resolveBindings(B,r,{skipCache:!0}):P[G]=B}),O.params=P}return O});c&&_i.log(`[ModalDataSourceWrapper] Modal "${e}" fetching data sources:`,L.map(k=>({id:k.id,endpoint:k.endpoint})));const $=await v.current.fetchDataSourcesWithResults(L,x,A);i&&$.forEach(k=>{if(k.state==="success"&&k.data!==void 0){const O=L.find(P=>P.id===k.id);if(O?.initGlobal){const P=k.data?.data??k.data,G=Array.isArray(O.initGlobal)?O.initGlobal:[O.initGlobal];for(const B of G)if(typeof B=="string")i({[B]:P}),c&&_i.log(`[ModalDataSourceWrapper] Modal "${e}" initGlobal: ${k.id}.data -> _global.${B}`);else if(typeof B=="object"&&B.key){const{key:W,path:pe}=B,Se=pe?JA(P,pe):P;i({[W]:Se}),c&&_i.log(`Modal "${e}" initGlobal: ${k.id}.data${pe?"."+pe:""} -> _global.${W}`)}}}else k.state==="error"&&_i.error(`Modal "${e}" data source error:`,k.id,k.error)}),c&&_i.log(`Modal "${e}" data sources fetched successfully`)}catch(x){_i.error(`Modal "${e}" data source fetch error:`,x)}finally{h(!1),y(!0)}}},[n,r,i,l,e,c]);return N.useEffect(()=>{if(!n||n.length===0)return;const x=window.__templateApp;return x?.registerModalDataSources&&x.registerModalDataSources(e,n),()=>{x?.unregisterModalDataSources&&x.unregisterModalDataSources(e)}},[e,n]),N.useEffect(()=>{!s&&S.current&&(y(!1),c&&_i.log(`[ModalDataSourceWrapper] Modal "${e}" closed, reset fetch state`)),s&&!S.current&&n&&n.length>0&&!m&&_(),S.current=s},[s,n,m,_,e,c]),ft.jsx(ft.Fragment,{children:d})};class Ic extends Error{constructor(n,r,i={}){super(r);M(this,"code");M(this,"userMessageKey");M(this,"showStack");M(this,"icon");M(this,"recoverable");this.name="TemplateEngineError",this.code=n,this.userMessageKey=r,this.showStack=i.showStack??!0,this.icon=i.icon??"fa-circle-exclamation",this.recoverable=i.recoverable??!0,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}getUserMessage(n,r){if(!r||!n)return this.userMessageKey;try{return r.translate(this.userMessageKey,n)}catch{return this.userMessageKey}}}class QA extends Ic{constructor(){super("TEMPLATE_NOT_FOUND","$t:core.errors.template_not_found",{showStack:!1,icon:"fa-paint-brush",recoverable:!1}),this.name="TemplateNotFoundError"}}function Zy(s){if(s instanceof Ic)return s;if(s instanceof Error){const e=new Ic("TEMPLATE_INIT_ERROR",s.message||"$t:core.errors.template_init_error",{showStack:!0,icon:"fa-circle-exclamation",recoverable:!0});return e.stack=s.stack,e}return new Ic("TEMPLATE_INIT_ERROR","$t:core.errors.template_init_error",{showStack:!1,icon:"fa-circle-exclamation",recoverable:!0})}const ZA=dt("ErrorDisplay");class Zf{static render(e,n){const r=document.getElementById(e);if(!r){ZA.error(`Container #${e} not found`);return}const i=n.debug&&n.showStack&&n.stackTrace,l=window.matchMedia("(prefers-color-scheme: dark)").matches,c={container:` + `,Vn.error("Error state rendered:",i,r)}getCurrentLayout(){return this.currentLayout}clear(){this.currentLayout=null,this.layoutCache.clear(),Vn.log("Layout data and cache cleared")}}const NA=dt("TranslationContext"),Kf=N.createContext(null),Lc=({children:s,translationEngine:e,translationContext:n})=>{const r=N.useMemo(()=>(l,c)=>{if(c){const d="|"+Object.entries(c).map(([f,h])=>`${f}=${h}`).join("|");return e.translate(l,n,d)}return e.translate(l,n)},[e,n]),i=N.useMemo(()=>({translationEngine:e,translationContext:n,t:r}),[e,n,r]);return ft.jsx(Kf.Provider,{value:i,children:s})},Uy=()=>{const s=N.useContext(Kf);return s||(NA.warn("TranslationProvider 외부에서 호출되었습니다. 키를 그대로 반환합니다."),{t:e=>e,translationEngine:null,translationContext:null})},ja=dt("SlotContext"),IA={registerToSlot:()=>{ja.warn("SlotContext not available: registerToSlot called outside SlotProvider")},unregisterFromSlot:()=>{ja.warn("SlotContext not available: unregisterFromSlot called outside SlotProvider")},getSlotComponents:()=>[],subscribeToSlot:()=>()=>{},clearAllSlots:()=>{},isEnabled:!1},jA=N.createContext(IA),Wf=({children:s})=>{const e=N.useRef(new Map),n=N.useRef(new Map),r=N.useCallback(m=>{const y=n.current.get(m);y&&y.forEach(S=>{try{S()}catch(v){ja.error(`Slot subscriber error (slotId: ${m}):`,v)}})},[]),i=N.useCallback((m,y,S)=>{if(!m||!y){ja.warn("registerToSlot: slotId and componentId are required");return}e.current.has(m)||e.current.set(m,new Map);const v=e.current.get(m),_=v.get(y);_&&_.registrationKey===S.registrationKey||(v.set(y,S),ja.log(`Component registered to slot: ${y} -> ${m} (order: ${S.order})`),r(m))},[r]),l=N.useCallback((m,y)=>{const S=e.current.get(m);S&&S.has(y)&&(S.delete(y),ja.log(`Component unregistered from slot: ${y} <- ${m}`),S.size===0&&e.current.delete(m),r(m))},[r]),c=N.useCallback(m=>{const y=e.current.get(m);return y?Array.from(y.values()).sort((S,v)=>S.order-v.order):[]},[]),d=N.useCallback((m,y)=>{n.current.has(m)||n.current.set(m,new Set);const S=n.current.get(m);return S.add(y),()=>{S.delete(y),S.size===0&&n.current.delete(m)}},[]),f=N.useCallback(()=>{e.current.forEach((m,y)=>{r(y)}),e.current.clear(),n.current.clear(),ja.log("All slots cleared")},[r]),h=N.useMemo(()=>({registerToSlot:i,unregisterFromSlot:l,getSlotComponents:c,subscribeToSlot:d,clearAllSlots:f,isEnabled:!0}),[i,l,c,d,f]);return N.useLayoutEffect(()=>{typeof window<"u"&&(window.__slotContextValue=h,ja.log("SlotContext exposed to window.__slotContextValue"))},[h]),ft.jsx(jA.Provider,{value:h,children:s})};class Yf{constructor(){this.notificationCreatedEvent=".Illuminate\\Notifications\\Events\\BroadcastNotificationCreated"}listenForWhisper(e,n){return this.listen(".client-"+e,n)}notification(e){return this.listen(this.notificationCreatedEvent,e)}stopListeningForNotification(e){return this.stopListening(this.notificationCreatedEvent,e)}stopListeningForWhisper(e,n){return this.stopListening(".client-"+e,n)}}class Py{constructor(e){this.namespace=e}format(e){return[".","\\"].includes(e.charAt(0))?e.substring(1):(this.namespace&&(e=this.namespace+"."+e),e.replace(/\./g,"\\"))}setNamespace(e){this.namespace=e}}function HA(s){try{return Reflect.construct(String,[],s),!0}catch{return!1}}class Xf extends Yf{constructor(e,n,r){super(),this.name=n,this.pusher=e,this.options=r,this.eventFormatter=new Py(this.options.namespace),this.subscribe()}subscribe(){this.subscription=this.pusher.subscribe(this.name)}unsubscribe(){this.pusher.unsubscribe(this.name)}listen(e,n){return this.on(this.eventFormatter.format(e),n),this}listenToAll(e){return this.subscription.bind_global((n,r)=>{if(n.startsWith("pusher:"))return;let i=String(this.options.namespace??"").replace(/\./g,"\\"),l=n.startsWith(i)?n.substring(i.length+1):"."+n;e(l,r)}),this}stopListening(e,n){return n?this.subscription.unbind(this.eventFormatter.format(e),n):this.subscription.unbind(this.eventFormatter.format(e)),this}stopListeningToAll(e){return e?this.subscription.unbind_global(e):this.subscription.unbind_global(),this}subscribed(e){return this.on("pusher:subscription_succeeded",()=>{e()}),this}error(e){return this.on("pusher:subscription_error",n=>{e(n)}),this}on(e,n){return this.subscription.bind(e,n),this}}class By extends Xf{whisper(e,n){return this.pusher.channels.channels[this.name].trigger(`client-${e}`,n),this}}class zA extends Xf{whisper(e,n){return this.pusher.channels.channels[this.name].trigger(`client-${e}`,n),this}}class UA extends By{here(e){return this.on("pusher:subscription_succeeded",n=>{e(Object.keys(n.members).map(r=>n.members[r]))}),this}joining(e){return this.on("pusher:member_added",n=>{e(n.info)}),this}whisper(e,n){return this.pusher.channels.channels[this.name].trigger(`client-${e}`,n),this}leaving(e){return this.on("pusher:member_removed",n=>{e(n.info)}),this}}class qy extends Yf{constructor(e,n,r){super(),this.events={},this.listeners={},this.name=n,this.socket=e,this.options=r,this.eventFormatter=new Py(this.options.namespace),this.subscribe()}subscribe(){this.socket.emit("subscribe",{channel:this.name,auth:this.options.auth||{}})}unsubscribe(){this.unbind(),this.socket.emit("unsubscribe",{channel:this.name,auth:this.options.auth||{}})}listen(e,n){return this.on(this.eventFormatter.format(e),n),this}stopListening(e,n){return this.unbindEvent(this.eventFormatter.format(e),n),this}subscribed(e){return this.on("connect",n=>{e(n)}),this}error(e){return this}on(e,n){return this.listeners[e]=this.listeners[e]||[],this.events[e]||(this.events[e]=(r,i)=>{this.name===r&&this.listeners[e]&&this.listeners[e].forEach(l=>l(i))},this.socket.on(e,this.events[e])),this.listeners[e].push(n),this}unbind(){Object.keys(this.events).forEach(e=>{this.unbindEvent(e)})}unbindEvent(e,n){this.listeners[e]=this.listeners[e]||[],n&&(this.listeners[e]=this.listeners[e].filter(r=>r!==n)),(!n||this.listeners[e].length===0)&&(this.events[e]&&(this.socket.removeListener(e,this.events[e]),delete this.events[e]),delete this.listeners[e])}}class Gy extends qy{whisper(e,n){return this.socket.emit("client event",{channel:this.name,event:`client-${e}`,data:n}),this}}class PA extends Gy{here(e){return this.on("presence:subscribed",n=>{e(n.map(r=>r.user_info))}),this}joining(e){return this.on("presence:joining",n=>e(n.user_info)),this}whisper(e,n){return this.socket.emit("client event",{channel:this.name,event:`client-${e}`,data:n}),this}leaving(e){return this.on("presence:leaving",n=>e(n.user_info)),this}}class $c extends Yf{subscribe(){}unsubscribe(){}listen(e,n){return this}listenToAll(e){return this}stopListening(e,n){return this}subscribed(e){return this}error(e){return this}on(e,n){return this}}class Fy extends $c{whisper(e,n){return this}}class BA extends $c{whisper(e,n){return this}}class qA extends Fy{here(e){return this}joining(e){return this}whisper(e,n){return this}leaving(e){return this}}const Vy=class Dw{constructor(e){this.setOptions(e),this.connect()}setOptions(e){this.options={...Dw._defaultOptions,...e,broadcaster:e.broadcaster};let n=this.csrfToken();n&&(this.options.auth.headers["X-CSRF-TOKEN"]=n,this.options.userAuthentication.headers["X-CSRF-TOKEN"]=n),n=this.options.bearerToken,n&&(this.options.auth.headers.Authorization="Bearer "+n,this.options.userAuthentication.headers.Authorization="Bearer "+n)}csrfToken(){var e,n;return typeof window<"u"&&(e=window.Laravel)!=null&&e.csrfToken?window.Laravel.csrfToken:this.options.csrfToken?this.options.csrfToken:typeof document<"u"&&typeof document.querySelector=="function"?((n=document.querySelector('meta[name="csrf-token"]'))==null?void 0:n.getAttribute("content"))??null:null}};Vy._defaultOptions={auth:{headers:{}},authEndpoint:"/broadcasting/auth",userAuthentication:{endpoint:"/broadcasting/user-auth",headers:{}},csrfToken:null,bearerToken:null,host:null,key:null,namespace:"App.Events"};let Jf=Vy;class Mc extends Jf{constructor(){super(...arguments),this.channels={}}connect(){if(typeof this.options.client<"u")this.pusher=this.options.client;else if(this.options.Pusher)this.pusher=new this.options.Pusher(this.options.key,this.options);else if(typeof window<"u"&&typeof window.Pusher<"u")this.pusher=new window.Pusher(this.options.key,this.options);else throw new Error("Pusher client not found. Should be globally available or passed via options.client")}signin(){this.pusher.signin()}listen(e,n,r){return this.channel(e).listen(n,r)}channel(e){return this.channels[e]||(this.channels[e]=new Xf(this.pusher,e,this.options)),this.channels[e]}privateChannel(e){return this.channels["private-"+e]||(this.channels["private-"+e]=new By(this.pusher,"private-"+e,this.options)),this.channels["private-"+e]}encryptedPrivateChannel(e){return this.channels["private-encrypted-"+e]||(this.channels["private-encrypted-"+e]=new zA(this.pusher,"private-encrypted-"+e,this.options)),this.channels["private-encrypted-"+e]}presenceChannel(e){return this.channels["presence-"+e]||(this.channels["presence-"+e]=new UA(this.pusher,"presence-"+e,this.options)),this.channels["presence-"+e]}leave(e){[e,"private-"+e,"private-encrypted-"+e,"presence-"+e].forEach(n=>{this.leaveChannel(n)})}leaveChannel(e){this.channels[e]&&(this.channels[e].unsubscribe(),delete this.channels[e])}socketId(){return this.pusher.connection.socket_id}connectionStatus(){const e=this.pusher.connection.state;switch(e){case"connected":case"connecting":return e;case"failed":case"unavailable":return"failed";default:return"disconnected"}}onConnectionChange(e){const n=()=>{e(this.connectionStatus())},r=["state_change","connected","disconnected"];return r.forEach(i=>{this.pusher.connection.bind(i,n)}),()=>{r.forEach(i=>{this.pusher.connection.unbind(i,n)})}}disconnect(){this.pusher.disconnect()}}class GA extends Jf{constructor(){super(...arguments),this.channels={}}connect(){let e=this.getSocketIO();this.socket=e(this.options.host??void 0,this.options),this.socket.io.on("reconnect",()=>{Object.values(this.channels).forEach(n=>{n.subscribe()})})}getSocketIO(){if(typeof this.options.client<"u")return this.options.client;if(typeof window<"u"&&typeof window.io<"u")return window.io;throw new Error("Socket.io client not found. Should be globally available or passed via options.client")}listen(e,n,r){return this.channel(e).listen(n,r)}channel(e){return this.channels[e]||(this.channels[e]=new qy(this.socket,e,this.options)),this.channels[e]}privateChannel(e){return this.channels["private-"+e]||(this.channels["private-"+e]=new Gy(this.socket,"private-"+e,this.options)),this.channels["private-"+e]}presenceChannel(e){return this.channels["presence-"+e]||(this.channels["presence-"+e]=new PA(this.socket,"presence-"+e,this.options)),this.channels["presence-"+e]}leave(e){[e,"private-"+e,"presence-"+e].forEach(n=>{this.leaveChannel(n)})}leaveChannel(e){this.channels[e]&&(this.channels[e].unsubscribe(),delete this.channels[e])}socketId(){return this.socket.id}connectionStatus(){return this.socket.connected?"connected":this.socket.io._reconnecting?"reconnecting":this.socket.id!==void 0?"disconnected":"connecting"}onConnectionChange(e){const n=()=>{e(this.connectionStatus())},r=["connect","disconnect","connect_error","reconnect_attempt","reconnect","reconnect_error","reconnect_failed"];return r.forEach(i=>{this.socket.on(i,n)}),()=>{r.forEach(i=>{this.socket.off(i,n)})}}disconnect(){this.socket.disconnect()}}class Ky extends Jf{constructor(){super(...arguments),this.channels={}}connect(){}listen(e,n,r){return new $c}channel(e){return new $c}privateChannel(e){return new Fy}encryptedPrivateChannel(e){return new BA}presenceChannel(e){return new qA}leave(e){}leaveChannel(e){}socketId(){return"fake-socket-id"}connectionStatus(){return"connected"}onConnectionChange(e){return()=>{}}disconnect(){}}class FA{constructor(e){this.options=e,this.connect(),this.options.withoutInterceptors||this.registerInterceptors()}channel(e){return this.connector.channel(e)}connect(){if(this.options.broadcaster==="reverb")this.connector=new Mc({...this.options,cluster:""});else if(this.options.broadcaster==="pusher")this.connector=new Mc(this.options);else if(this.options.broadcaster==="ably")this.connector=new Mc({...this.options,cluster:"",broadcaster:"pusher"});else if(this.options.broadcaster==="socket.io")this.connector=new GA(this.options);else if(this.options.broadcaster==="null")this.connector=new Ky(this.options);else if(typeof this.options.broadcaster=="function"&&HA(this.options.broadcaster))this.connector=new this.options.broadcaster(this.options);else throw new Error(`Broadcaster ${typeof this.options.broadcaster} ${String(this.options.broadcaster)} is not supported.`)}disconnect(){this.connector.disconnect()}join(e){return this.connector.presenceChannel(e)}leave(e){this.connector.leave(e)}leaveChannel(e){this.connector.leaveChannel(e)}leaveAllChannels(){for(const e in this.connector.channels)this.leaveChannel(e)}listen(e,n,r){return this.connector.listen(e,n,r)}private(e){return this.connector.privateChannel(e)}encryptedPrivate(e){if(this.connectorSupportsEncryptedPrivateChannels(this.connector))return this.connector.encryptedPrivateChannel(e);throw new Error(`Broadcaster ${typeof this.options.broadcaster} ${String(this.options.broadcaster)} does not support encrypted private channels.`)}connectorSupportsEncryptedPrivateChannels(e){return e instanceof Mc||e instanceof Ky}socketId(){return this.connector.socketId()}connectionStatus(){return this.connector.connectionStatus()}registerInterceptors(){typeof Vue<"u"&&Vue!=null&&Vue.http&&this.registerVueRequestInterceptor(),typeof axios=="function"&&this.registerAxiosRequestInterceptor(),typeof jQuery=="function"&&this.registerjQueryAjaxSetup(),typeof Turbo=="object"&&this.registerTurboRequestInterceptor()}registerVueRequestInterceptor(){Vue.http.interceptors.push((e,n)=>{this.socketId()&&e.headers.set("X-Socket-ID",this.socketId()),n()})}registerAxiosRequestInterceptor(){axios.interceptors.request.use(e=>(this.socketId()&&(e.headers["X-Socket-Id"]=this.socketId()),e))}registerjQueryAjaxSetup(){typeof jQuery.ajax<"u"&&jQuery.ajaxPrefilter((e,n,r)=>{this.socketId()&&r.setRequestHeader("X-Socket-Id",this.socketId())})}registerTurboRequestInterceptor(){document.addEventListener("turbo:before-fetch-request",e=>{e.detail.fetchOptions.headers["X-Socket-Id"]=this.socketId()})}}var Qf={exports:{}};var Wy;function VA(){return Wy||(Wy=1,(function(s,e){(function(r,i){s.exports=i()})(self,()=>(()=>{var n={594(c,d){var f=this&&this.__extends||(function(){var $=function(k,O){return $=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(P,G){P.__proto__=G}||function(P,G){for(var B in G)G.hasOwnProperty(B)&&(P[B]=G[B])},$(k,O)};return function(k,O){$(k,O);function P(){this.constructor=k}k.prototype=O===null?Object.create(O):(P.prototype=O.prototype,new P)}})();Object.defineProperty(d,"__esModule",{value:!0});var h=256,m=(function(){function $(k){k===void 0&&(k="="),this._paddingCharacter=k}return $.prototype.encodedLength=function(k){return this._paddingCharacter?(k+2)/3*4|0:(k*8+5)/6|0},$.prototype.encode=function(k){for(var O="",P=0;P>>18&63),O+=this._encodeByte(G>>>12&63),O+=this._encodeByte(G>>>6&63),O+=this._encodeByte(G>>>0&63)}var B=k.length-P;if(B>0){var G=k[P]<<16|(B===2?k[P+1]<<8:0);O+=this._encodeByte(G>>>18&63),O+=this._encodeByte(G>>>12&63),B===2?O+=this._encodeByte(G>>>6&63):O+=this._paddingCharacter||"",O+=this._paddingCharacter||""}return O},$.prototype.maxDecodedLength=function(k){return this._paddingCharacter?k/4*3|0:(k*6+7)/8|0},$.prototype.decodedLength=function(k){return this.maxDecodedLength(k.length-this._getPaddingLength(k))},$.prototype.decode=function(k){if(k.length===0)return new Uint8Array(0);for(var O=this._getPaddingLength(k),P=k.length-O,G=new Uint8Array(this.maxDecodedLength(P)),B=0,W=0,pe=0,Se=0,we=0,Ue=0,Fe=0;W>>4,G[B++]=we<<4|Ue>>>2,G[B++]=Ue<<6|Fe,pe|=Se&h,pe|=we&h,pe|=Ue&h,pe|=Fe&h;if(W>>4,pe|=Se&h,pe|=we&h),W>>2,pe|=Ue&h),W>>8&6,O+=51-k>>>8&-75,O+=61-k>>>8&-15,O+=62-k>>>8&3,String.fromCharCode(O)},$.prototype._decodeChar=function(k){var O=h;return O+=(42-k&k-44)>>>8&-h+k-43+62,O+=(46-k&k-48)>>>8&-h+k-47+63,O+=(47-k&k-58)>>>8&-h+k-48+52,O+=(64-k&k-91)>>>8&-h+k-65+0,O+=(96-k&k-123)>>>8&-h+k-97+26,O},$.prototype._getPaddingLength=function(k){var O=0;if(this._paddingCharacter){for(var P=k.length-1;P>=0&&k[P]===this._paddingCharacter;P--)O++;if(k.length<4||O>2)throw new Error("Base64Coder: incorrect padding")}return O},$})();d.Coder=m;var y=new m;function S($){return y.encode($)}d.encode=S;function v($){return y.decode($)}d.decode=v;var _=(function($){f(k,$);function k(){return $!==null&&$.apply(this,arguments)||this}return k.prototype._encodeByte=function(O){var P=O;return P+=65,P+=25-O>>>8&6,P+=51-O>>>8&-75,P+=61-O>>>8&-13,P+=62-O>>>8&49,String.fromCharCode(P)},k.prototype._decodeChar=function(O){var P=h;return P+=(44-O&O-46)>>>8&-h+O-45+62,P+=(94-O&O-96)>>>8&-h+O-95+63,P+=(47-O&O-58)>>>8&-h+O-48+52,P+=(64-O&O-91)>>>8&-h+O-65+0,P+=(96-O&O-123)>>>8&-h+O-97+26,P},k})(m);d.URLSafeCoder=_;var x=new _;function A($){return x.encode($)}d.encodeURLSafe=A;function L($){return x.decode($)}d.decodeURLSafe=L,d.encodedLength=function($){return y.encodedLength($)},d.maxDecodedLength=function($){return y.maxDecodedLength($)},d.decodedLength=function($){return y.decodedLength($)}},978(c,d){var f="utf8: invalid source encoding";function h(m){for(var y=[],S=0;S=m.length)throw new Error(f);var x=m[++S];if((x&192)!==128)throw new Error(f);v=(v&31)<<6|x&63,_=128}else if(v<240){if(S>=m.length-1)throw new Error(f);var x=m[++S],A=m[++S];if((x&192)!==128||(A&192)!==128)throw new Error(f);v=(v&15)<<12|(x&63)<<6|A&63,_=2048}else if(v<248){if(S>=m.length-2)throw new Error(f);var x=m[++S],A=m[++S],L=m[++S];if((x&192)!==128||(A&192)!==128||(L&192)!==128)throw new Error(f);v=(v&15)<<18|(x&63)<<12|(A&63)<<6|L&63,_=65536}else throw new Error(f);if(v<_||v>=55296&&v<=57343)throw new Error(f);if(v>=65536){if(v>1114111)throw new Error(f);v-=65536,y.push(String.fromCharCode(55296|v>>10)),v=56320|v&1023}}y.push(String.fromCharCode(v))}return y.join("")}d.D4=h},721(c,d,f){c.exports=f(207).default},207(c,d,f){f.d(d,{default:()=>Ls});class h{constructor(b,C){this.lastId=0,this.prefix=b,this.name=C}create(b){this.lastId++;var C=this.lastId,D=this.prefix+C,I=this.name+"["+C+"]",ne=!1,me=function(){ne||(b.apply(null,arguments),ne=!0)};return this[C]=me,{number:C,id:D,name:I,callback:me}}remove(b){delete this[b.number]}}var m=new h("_pusher_script_","Pusher.ScriptReceivers"),y={VERSION:"8.5.0",PROTOCOL:7,wsPort:80,wssPort:443,wsPath:"",httpHost:"sockjs.pusher.com",httpPort:80,httpsPort:443,httpPath:"/pusher",stats_host:"stats.pusher.com",authEndpoint:"/pusher/auth",authTransport:"ajax",activityTimeout:12e4,pongTimeout:3e4,unavailableTimeout:1e4,userAuthentication:{endpoint:"/pusher/user-auth",transport:"ajax"},channelAuthorization:{endpoint:"/pusher/auth",transport:"ajax"},cdn_http:"http://js.pusher.com",cdn_https:"https://js.pusher.com",dependency_suffix:""};const S=y;class v{constructor(b){this.options=b,this.receivers=b.receivers||m,this.loading={}}load(b,C,D){var I=this;if(I.loading[b]&&I.loading[b].length>0)I.loading[b].push(D);else{I.loading[b]=[D];var ne=ze.createScriptRequest(I.getPath(b,C)),me=I.receivers.create(function($e){if(I.receivers.remove(me),I.loading[b]){var Ke=I.loading[b];delete I.loading[b];for(var ct=function(zt){zt||ne.cleanup()},gt=0;gt>>6)+J(128|b&63):J(224|b>>>12&15)+J(128|b>>>6&63)+J(128|b&63)},Z=function(E){return E.replace(/[^\x00-\x7F]/g,Le)},ge=function(E){var b=[0,2,1][E.length%3],C=E.charCodeAt(0)<<16|(E.length>1?E.charCodeAt(1):0)<<8|(E.length>2?E.charCodeAt(2):0),D=[fe.charAt(C>>>18),fe.charAt(C>>>12&63),b>=2?"=":fe.charAt(C>>>6&63),b>=1?"=":fe.charAt(C&63)];return D.join("")},H=window.btoa||function(E){return E.replace(/[\s\S]{1,3}/g,ge)};class T{constructor(b,C,D,I){this.clear=C,this.timer=b(()=>{this.timer&&(this.timer=I(this.timer))},D)}isRunning(){return this.timer!==null}ensureAborted(){this.timer&&(this.clear(this.timer),this.timer=null)}}const ce=T;function de(E){window.clearTimeout(E)}function be(E){window.clearInterval(E)}class ie extends ce{constructor(b,C){super(setTimeout,de,b,function(D){return C(),null})}}class xe extends ce{constructor(b,C){super(setInterval,be,b,function(D){return C(),D})}}var _e={now(){return Date.now?Date.now():new Date().valueOf()},defer(E){return new ie(0,E)},method(E,...b){var C=Array.prototype.slice.call(arguments,1);return function(D){return D[E].apply(D,C.concat(arguments))}}};const Te=_e;function Me(E,...b){for(var C=0;C{window.console&&window.console.log&&window.console.log(b)}}debug(...b){this.log(this.globalLog,b)}warn(...b){this.log(this.globalLogWarn,b)}error(...b){this.log(this.globalLogError,b)}globalLogWarn(b){window.console&&window.console.warn?window.console.warn(b):this.globalLog(b)}globalLogError(b){window.console&&window.console.error?window.console.error(b):this.globalLogWarn(b)}log(b,...C){var D=pt.apply(this,arguments);Ls.log?Ls.log(D):Ls.logToConsole&&b.bind(this)(D)}}const nt=new Dn;var In=function(E,b,C,D,I){(C.headers!==void 0||C.headersProvider!=null)&&nt.warn(`To send headers with the ${D.toString()} request, you must use AJAX, rather than JSONP.`);var ne=E.nextAuthCallbackID.toString();E.nextAuthCallbackID++;var me=E.getDocument(),$e=me.createElement("script");E.auth_callbacks[ne]=function(gt){I(null,gt)};var Ke="Pusher.auth_callbacks['"+ne+"']";$e.src=C.endpoint+"?callback="+encodeURIComponent(Ke)+"&"+b;var ct=me.getElementsByTagName("head")[0]||me.documentElement;ct.insertBefore($e,ct.firstChild)};const mn=In;class ca{constructor(b){this.src=b}send(b){var C=this,D="Error loading "+C.src;C.script=document.createElement("script"),C.script.id=b.id,C.script.src=C.src,C.script.type="text/javascript",C.script.charset="UTF-8",C.script.addEventListener?(C.script.onerror=function(){b.callback(D)},C.script.onload=function(){b.callback(null)}):C.script.onreadystatechange=function(){(C.script.readyState==="loaded"||C.script.readyState==="complete")&&b.callback(null)},C.script.async===void 0&&document.attachEvent&&/opera/i.test(navigator.userAgent)?(C.errorScript=document.createElement("script"),C.errorScript.id=b.id+"_error",C.errorScript.text=b.name+"('"+D+"');",C.script.async=C.errorScript.async=!1):C.script.async=!0;var I=document.getElementsByTagName("head")[0];I.insertBefore(C.script,I.firstChild),C.errorScript&&I.insertBefore(C.errorScript,C.script.nextSibling)}cleanup(){this.script&&(this.script.onload=this.script.onerror=null,this.script.onreadystatechange=null),this.script&&this.script.parentNode&&this.script.parentNode.removeChild(this.script),this.errorScript&&this.errorScript.parentNode&&this.errorScript.parentNode.removeChild(this.errorScript),this.script=null,this.errorScript=null}}class lr{constructor(b,C){this.url=b,this.data=C}send(b){if(!this.request){var C=ki(this.data),D=this.url+"/"+b.number+"?"+C;this.request=ze.createScriptRequest(D),this.request.send(b)}}cleanup(){this.request&&this.request.cleanup()}}var sn=function(E,b){return function(C,D){var I="http"+(b?"s":"")+"://",ne=I+(E.host||E.options.host)+E.options.path,me=ze.createJSONPRequest(ne,C),$e=ze.ScriptReceivers.create(function(Ke,ct){m.remove($e),me.cleanup(),ct&&ct.host&&(E.host=ct.host),D&&D(Ke,ct)});me.send($e)}},_n={name:"jsonp",getAgent:sn};const on=_n;function F(E,b,C){var D=E+(b.useTLS?"s":""),I=b.useTLS?b.hostTLS:b.hostNonTLS;return D+"://"+I+C}function se(E,b){var C="/app/"+E,D="?protocol="+S.PROTOCOL+"&client=js&version="+S.VERSION+(b?"&"+b:"");return C+D}var ue={getInitial:function(E,b){var C=(b.httpPath||"")+se(E,"flash=false");return F("ws",b,C)}},ee={getInitial:function(E,b){var C=(b.httpPath||"/pusher")+se(E);return F("http",b,C)}},ve={getInitial:function(E,b){return F("http",b,b.httpPath||"/pusher")},getPath:function(E,b){return se(E)}};class he{constructor(){this._callbacks={}}get(b){return this._callbacks[Ee(b)]}add(b,C,D){var I=Ee(b);this._callbacks[I]=this._callbacks[I]||[],this._callbacks[I].push({fn:C,context:D})}remove(b,C,D){if(!b&&!C&&!D){this._callbacks={};return}var I=b?[Ee(b)]:ht(this._callbacks);C||D?this.removeCallback(I,C,D):this.removeAllCallbacks(I)}removeCallback(b,C,D){Kt(b,function(I){this._callbacks[I]=hn(this._callbacks[I]||[],function(ne){return C&&C!==ne.fn||D&&D!==ne.context}),this._callbacks[I].length===0&&delete this._callbacks[I]},this)}removeAllCallbacks(b){Kt(b,function(C){delete this._callbacks[C]},this)}}function Ee(E){return"_"+E}class Ae{constructor(b){this.callbacks=new he,this.global_callbacks=[],this.failThrough=b}bind(b,C,D){return this.callbacks.add(b,C,D),this}bind_global(b){return this.global_callbacks.push(b),this}unbind(b,C,D){return this.callbacks.remove(b,C,D),this}unbind_global(b){return b?(this.global_callbacks=hn(this.global_callbacks||[],C=>C!==b),this):(this.global_callbacks=[],this)}unbind_all(){return this.unbind(),this.unbind_global(),this}emit(b,C,D){for(var I=0;I0)for(var I=0;I{this.onError(C),this.changeState("closed")}),!1}return this.bindListeners(),nt.debug("Connecting",{transport:this.name,url:b}),this.changeState("connecting"),!0}close(){return this.socket?(this.socket.close(),!0):!1}send(b){return this.state==="open"?(Te.defer(()=>{this.socket&&this.socket.send(b)}),!0):!1}ping(){this.state==="open"&&this.supportsPing()&&this.socket.ping()}onOpen(){this.hooks.beforeOpen&&this.hooks.beforeOpen(this.socket,this.hooks.urls.getPath(this.key,this.options)),this.changeState("open"),this.socket.onopen=void 0}onError(b){this.emit("error",{type:"WebSocketError",error:b}),this.timeline.error(this.buildTimelineMessage({error:b.toString()}))}onClose(b){b?this.changeState("closed",{code:b.code,reason:b.reason,wasClean:b.wasClean}):this.changeState("closed"),this.unbindListeners(),this.socket=void 0}onMessage(b){this.emit("message",b)}onActivity(){this.emit("activity")}bindListeners(){this.socket.onopen=()=>{this.onOpen()},this.socket.onerror=b=>{this.onError(b)},this.socket.onclose=b=>{this.onClose(b)},this.socket.onmessage=b=>{this.onMessage(b)},this.supportsPing()&&(this.socket.onactivity=()=>{this.onActivity()})}unbindListeners(){this.socket&&(this.socket.onopen=void 0,this.socket.onerror=void 0,this.socket.onclose=void 0,this.socket.onmessage=void 0,this.supportsPing()&&(this.socket.onactivity=void 0))}changeState(b,C){this.state=b,this.timeline.info(this.buildTimelineMessage({state:b,params:C})),this.emit(b,C)}buildTimelineMessage(b){return Me({cid:this.id},b)}}class ke{constructor(b){this.hooks=b}isSupported(b){return this.hooks.isSupported(b)}createConnection(b,C,D,I){return new Ve(this.hooks,b,C,D,I)}}var Ne=new ke({urls:ue,handlesActivityChecks:!1,supportsPing:!1,isInitialized:function(){return!!ze.getWebSocketAPI()},isSupported:function(){return!!ze.getWebSocketAPI()},getSocket:function(E){return ze.createWebSocket(E)}}),Re={urls:ee,handlesActivityChecks:!1,supportsPing:!0,isInitialized:function(){return!0}},et=Me({getSocket:function(E){return ze.HTTPFactory.createStreamingSocket(E)}},Re),He=Me({getSocket:function(E){return ze.HTTPFactory.createPollingSocket(E)}},Re),Ge={isSupported:function(){return ze.isXHRSupported()}},Ce=new ke(Me({},et,Ge)),je=new ke(Me({},He,Ge)),tt={ws:Ne,xhr_streaming:Ce,xhr_polling:je};const At=tt;var Mt=new ke({file:"sockjs",urls:ve,handlesActivityChecks:!0,supportsPing:!1,isSupported:function(){return!0},isInitialized:function(){return window.SockJS!==void 0},getSocket:function(E,b){return new window.SockJS(E,null,{js_path:x.getPath("sockjs",{useTLS:b.useTLS}),ignore_null_origin:b.ignoreNullOrigin})},beforeOpen:function(E,b){E.send(JSON.stringify({path:b}))}}),On={isSupported:function(E){var b=ze.isXDRSupported(E.useTLS);return b}},jt=new ke(Me({},et,On)),Ht=new ke(Me({},He,On));At.xdr_streaming=jt,At.xdr_polling=Ht,At.sockjs=Mt;const An=At;class za extends Ae{constructor(){super();var b=this;window.addEventListener!==void 0&&(window.addEventListener("online",function(){b.emit("online")},!1),window.addEventListener("offline",function(){b.emit("offline")},!1))}isOnline(){return window.navigator.onLine===void 0?!0:window.navigator.onLine}}var Ko=new za;class ih{constructor(b,C,D){this.manager=b,this.transport=C,this.minPingDelay=D.minPingDelay,this.maxPingDelay=D.maxPingDelay,this.pingDelay=void 0}createConnection(b,C,D,I){I=Me({},I,{activityTimeout:this.pingDelay});var ne=this.transport.createConnection(b,C,D,I),me=null,$e=function(){ne.unbind("open",$e),ne.bind("closed",Ke),me=Te.now()},Ke=ct=>{if(ne.unbind("closed",Ke),ct.code===1002||ct.code===1003)this.manager.reportDeath();else if(!ct.wasClean&&me){var gt=Te.now()-me;gt<2*this.maxPingDelay&&(this.manager.reportDeath(),this.pingDelay=Math.max(gt/2,this.minPingDelay))}};return ne.bind("open",$e),ne}isSupported(b){return this.manager.isAlive()&&this.transport.isSupported(b)}}const qc={decodeMessage:function(E){try{var b=JSON.parse(E.data),C=b.data;if(typeof C=="string")try{C=JSON.parse(b.data)}catch{}var D={event:b.event,channel:b.channel,data:C};return b.user_id&&(D.user_id=b.user_id),D}catch(I){throw{type:"MessageParseError",error:I,data:E.data}}},encodeMessage:function(E){return JSON.stringify(E)},processHandshake:function(E){var b=qc.decodeMessage(E);if(b.event==="pusher:connection_established"){if(!b.data.activity_timeout)throw"No activity timeout specified in handshake";return{action:"connected",id:b.data.socket_id,activityTimeout:b.data.activity_timeout*1e3}}else{if(b.event==="pusher:error")return{action:this.getCloseAction(b.data),error:this.getCloseError(b.data)};throw"Invalid handshake"}},getCloseAction:function(E){return E.code<4e3?E.code>=1002&&E.code<=1004?"backoff":null:E.code===4e3?"tls_only":E.code<4100?"refused":E.code<4200?"backoff":E.code<4300?"retry":"refused"},getCloseError:function(E){return E.code!==1e3&&E.code!==1001?{type:"PusherError",data:{code:E.code,message:E.reason||E.message}}:null}},Kr=qc;class Ri extends Ae{constructor(b,C){super(),this.id=b,this.transport=C,this.activityTimeout=C.activityTimeout,this.bindListeners()}handlesActivityChecks(){return this.transport.handlesActivityChecks()}send(b){return this.transport.send(b)}send_event(b,C,D){var I={event:b,data:C};return D&&(I.channel=D),nt.debug("Event sent",I),this.send(Kr.encodeMessage(I))}ping(){this.transport.supportsPing()?this.transport.ping():this.send_event("pusher:ping",{})}close(){this.transport.close()}bindListeners(){var b={message:D=>{var I;try{I=Kr.decodeMessage(D)}catch(ne){this.emit("error",{type:"MessageParseError",error:ne,data:D.data})}if(I!==void 0){switch(nt.debug("Event recd",I),I.event){case"pusher:error":this.emit("error",{type:"PusherError",data:I.data});break;case"pusher:ping":this.emit("ping");break;case"pusher:pong":this.emit("pong");break}this.emit("message",I)}},activity:()=>{this.emit("activity")},error:D=>{this.emit("error",D)},closed:D=>{C(),D&&D.code&&this.handleCloseEvent(D),this.transport=null,this.emit("closed")}},C=()=>{Ot(b,(D,I)=>{this.transport.unbind(I,D)})};Ot(b,(D,I)=>{this.transport.bind(I,D)})}handleCloseEvent(b){var C=Kr.getCloseAction(b),D=Kr.getCloseError(b);D&&this.emit("error",D),C&&this.emit(C,{action:C,error:D})}}class Wo{constructor(b,C){this.transport=b,this.callback=C,this.bindListeners()}close(){this.unbindListeners(),this.transport.close()}bindListeners(){this.onMessage=b=>{this.unbindListeners();var C;try{C=Kr.processHandshake(b)}catch(D){this.finish("error",{error:D}),this.transport.close();return}C.action==="connected"?this.finish("connected",{connection:new Ri(C.id,this.transport),activityTimeout:C.activityTimeout}):(this.finish(C.action,{error:C.error}),this.transport.close())},this.onClosed=b=>{this.unbindListeners();var C=Kr.getCloseAction(b)||"backoff",D=Kr.getCloseError(b);this.finish(C,{error:D})},this.transport.bind("message",this.onMessage),this.transport.bind("closed",this.onClosed)}unbindListeners(){this.transport.unbind("message",this.onMessage),this.transport.unbind("closed",this.onClosed)}finish(b,C){this.callback(Me({transport:this.transport,action:b},C))}}class Ua{constructor(b,C){this.timeline=b,this.options=C||{}}send(b,C){this.timeline.isEmpty()||this.timeline.send(ze.TimelineTransport.getAgent(this,b),C)}}class Wr extends Ae{constructor(b,C){super(function(D,I){nt.debug("No callbacks on "+b+" for "+D)}),this.name=b,this.pusher=C,this.subscribed=!1,this.subscriptionPending=!1,this.subscriptionCancelled=!1}authorize(b,C){return C(null,{auth:""})}trigger(b,C){if(b.indexOf("client-")!==0)throw new O("Event '"+b+"' does not start with 'client-'");if(!this.subscribed){var D=$.buildLogSuffix("triggeringClientEvents");nt.warn(`Client event triggered before channel 'subscription_succeeded' event . ${D}`)}return this.pusher.send_event(b,C,this.name)}disconnect(){this.subscribed=!1,this.subscriptionPending=!1}handleEvent(b){var C=b.event,D=b.data;if(C==="pusher_internal:subscription_succeeded")this.handleSubscriptionSucceededEvent(b);else if(C==="pusher_internal:subscription_count")this.handleSubscriptionCountEvent(b);else if(C.indexOf("pusher_internal:")!==0){var I={};this.emit(C,D,I)}}handleSubscriptionSucceededEvent(b){this.subscriptionPending=!1,this.subscribed=!0,this.subscriptionCancelled?this.pusher.unsubscribe(this.name):this.emit("pusher:subscription_succeeded",b.data)}handleSubscriptionCountEvent(b){b.data.subscription_count&&(this.subscriptionCount=b.data.subscription_count),this.emit("pusher:subscription_count",b.data)}subscribe(){this.subscribed||(this.subscriptionPending=!0,this.subscriptionCancelled=!1,this.authorize(this.pusher.connection.socket_id,(b,C)=>{b?(this.subscriptionPending=!1,nt.error(b.toString()),this.emit("pusher:subscription_error",Object.assign({},{type:"AuthError",error:b.message},b instanceof Ue?{status:b.status}:{}))):this.pusher.send_event("pusher:subscribe",{auth:C.auth,channel_data:C.channel_data,channel:this.name})}))}unsubscribe(){this.subscribed=!1,this.pusher.send_event("pusher:unsubscribe",{channel:this.name})}cancelSubscription(){this.subscriptionCancelled=!0}reinstateSubscription(){this.subscriptionCancelled=!1}}class ua extends Wr{authorize(b,C){return this.pusher.config.channelAuthorizer({channelName:this.name,socketId:b},C)}}class Pa{constructor(){this.reset()}get(b){return Object.prototype.hasOwnProperty.call(this.members,b)?{id:b,info:this.members[b]}:null}each(b){Ot(this.members,(C,D)=>{b(this.get(D))})}setMyID(b){this.myID=b}onSubscription(b){this.members=b.presence.hash,this.count=b.presence.count,this.me=this.get(this.myID)}addMember(b){return this.get(b.user_id)===null&&this.count++,this.members[b.user_id]=b.user_info,this.get(b.user_id)}removeMember(b){var C=this.get(b.user_id);return C&&(delete this.members[b.user_id],this.count--),C}reset(){this.members={},this.count=0,this.myID=null,this.me=null}}var Jt=function(E,b,C,D){function I(ne){return ne instanceof C?ne:new C(function(me){me(ne)})}return new(C||(C=Promise))(function(ne,me){function $e(gt){try{ct(D.next(gt))}catch(zt){me(zt)}}function Ke(gt){try{ct(D.throw(gt))}catch(zt){me(zt)}}function ct(gt){gt.done?ne(gt.value):I(gt.value).then($e,Ke)}ct((D=D.apply(E,b||[])).next())})};class Gc extends ua{constructor(b,C){super(b,C),this.members=new Pa}authorize(b,C){super.authorize(b,(D,I)=>Jt(this,void 0,void 0,function*(){if(!D)if(I=I,I.channel_data!=null){var ne=JSON.parse(I.channel_data);this.members.setMyID(ne.user_id)}else if(yield this.pusher.user.signinDonePromise,this.pusher.user.user_data!=null)this.members.setMyID(this.pusher.user.user_data.id);else{let me=$.buildLogSuffix("authorizationEndpoint");nt.error(`Invalid auth response for channel '${this.name}', expected 'channel_data' field. ${me}, or the user should be signed in.`),C("Invalid auth response");return}C(D,I)}))}handleEvent(b){var C=b.event;if(C.indexOf("pusher_internal:")===0)this.handleInternalEvent(b);else{var D=b.data,I={};b.user_id&&(I.user_id=b.user_id),this.emit(C,D,I)}}handleInternalEvent(b){var C=b.event,D=b.data;switch(C){case"pusher_internal:subscription_succeeded":this.handleSubscriptionSucceededEvent(b);break;case"pusher_internal:subscription_count":this.handleSubscriptionCountEvent(b);break;case"pusher_internal:member_added":var I=this.members.addMember(D);this.emit("pusher:member_added",I);break;case"pusher_internal:member_removed":var ne=this.members.removeMember(D);ne&&this.emit("pusher:member_removed",ne);break}}handleSubscriptionSucceededEvent(b){this.subscriptionPending=!1,this.subscribed=!0,this.subscriptionCancelled?this.pusher.unsubscribe(this.name):(this.members.onSubscription(b.data),this.emit("pusher:subscription_succeeded",this.members))}disconnect(){this.members.reset(),super.disconnect()}}var Fc=f(978),Rr=f(594);class Ba extends ua{constructor(b,C,D){super(b,C),this.key=null,this.nacl=D}authorize(b,C){super.authorize(b,(D,I)=>{if(D){C(D,I);return}let ne=I.shared_secret;if(!ne){C(new Error(`No shared_secret key in auth payload for encrypted channel: ${this.name}`),null);return}this.key=(0,Rr.decode)(ne),delete I.shared_secret,C(null,I)})}trigger(b,C){throw new pe("Client events are not currently supported for encrypted channels")}handleEvent(b){var C=b.event,D=b.data;if(C.indexOf("pusher_internal:")===0||C.indexOf("pusher:")===0){super.handleEvent(b);return}this.handleEncryptedEvent(C,D)}handleEncryptedEvent(b,C){if(!this.key){nt.debug("Received encrypted event before key has been retrieved from the authEndpoint");return}if(!C.ciphertext||!C.nonce){nt.error("Unexpected format for encrypted event, expected object with `ciphertext` and `nonce` fields, got: "+C);return}let D=(0,Rr.decode)(C.ciphertext);if(D.length{if(me){nt.error(`Failed to make a request to the authEndpoint: ${$e}. Unable to fetch new key, so dropping encrypted event`);return}if(ne=this.nacl.secretbox.open(D,I,this.key),ne===null){nt.error("Failed to decrypt event with new key. Dropping encrypted event");return}this.emit(b,this.getDataToEmit(ne))});return}this.emit(b,this.getDataToEmit(ne))}getDataToEmit(b){let C=(0,Fc.D4)(b);try{return JSON.parse(C)}catch{return C}}}class sh extends Ae{constructor(b,C){super(),this.state="initialized",this.connection=null,this.key=b,this.options=C,this.timeline=this.options.timeline,this.usingTLS=this.options.useTLS,this.errorCallbacks=this.buildErrorCallbacks(),this.connectionCallbacks=this.buildConnectionCallbacks(this.errorCallbacks),this.handshakeCallbacks=this.buildHandshakeCallbacks(this.errorCallbacks);var D=ze.getNetwork();D.bind("online",()=>{this.timeline.info({netinfo:"online"}),(this.state==="connecting"||this.state==="unavailable")&&this.retryIn(0)}),D.bind("offline",()=>{this.timeline.info({netinfo:"offline"}),this.connection&&this.sendActivityCheck()}),this.updateStrategy()}switchCluster(b){this.key=b,this.updateStrategy(),this.retryIn(0)}connect(){if(!(this.connection||this.runner)){if(!this.strategy.isSupported()){this.updateState("failed");return}this.updateState("connecting"),this.startConnecting(),this.setUnavailableTimer()}}send(b){return this.connection?this.connection.send(b):!1}send_event(b,C,D){return this.connection?this.connection.send_event(b,C,D):!1}disconnect(){this.disconnectInternally(),this.updateState("disconnected")}isUsingTLS(){return this.usingTLS}startConnecting(){var b=(C,D)=>{C?this.runner=this.strategy.connect(0,b):D.action==="error"?(this.emit("error",{type:"HandshakeError",error:D.error}),this.timeline.error({handshakeError:D.error})):(this.abortConnecting(),this.handshakeCallbacks[D.action](D))};this.runner=this.strategy.connect(0,b)}abortConnecting(){this.runner&&(this.runner.abort(),this.runner=null)}disconnectInternally(){if(this.abortConnecting(),this.clearRetryTimer(),this.clearUnavailableTimer(),this.connection){var b=this.abandonConnection();b.close()}}updateStrategy(){this.strategy=this.options.getStrategy({key:this.key,timeline:this.timeline,useTLS:this.usingTLS})}retryIn(b){this.timeline.info({action:"retry",delay:b}),b>0&&this.emit("connecting_in",Math.round(b/1e3)),this.retryTimer=new ie(b||0,()=>{this.disconnectInternally(),this.connect()})}clearRetryTimer(){this.retryTimer&&(this.retryTimer.ensureAborted(),this.retryTimer=null)}setUnavailableTimer(){this.unavailableTimer=new ie(this.options.unavailableTimeout,()=>{this.updateState("unavailable")})}clearUnavailableTimer(){this.unavailableTimer&&this.unavailableTimer.ensureAborted()}sendActivityCheck(){this.stopActivityCheck(),this.connection.ping(),this.activityTimer=new ie(this.options.pongTimeout,()=>{this.timeline.error({pong_timed_out:this.options.pongTimeout}),this.retryIn(0)})}resetActivityCheck(){this.stopActivityCheck(),this.connection&&!this.connection.handlesActivityChecks()&&(this.activityTimer=new ie(this.activityTimeout,()=>{this.sendActivityCheck()}))}stopActivityCheck(){this.activityTimer&&this.activityTimer.ensureAborted()}buildConnectionCallbacks(b){return Me({},b,{message:C=>{this.resetActivityCheck(),this.emit("message",C)},ping:()=>{this.send_event("pusher:pong",{})},activity:()=>{this.resetActivityCheck()},error:C=>{this.emit("error",C)},closed:()=>{this.abandonConnection(),this.shouldRetry()&&this.retryIn(1e3)}})}buildHandshakeCallbacks(b){return Me({},b,{connected:C=>{this.activityTimeout=Math.min(this.options.activityTimeout,C.activityTimeout,C.connection.activityTimeout||1/0),this.clearUnavailableTimer(),this.setConnection(C.connection),this.socket_id=this.connection.id,this.updateState("connected",{socket_id:this.socket_id})}})}buildErrorCallbacks(){let b=C=>D=>{D.error&&this.emit("error",{type:"WebSocketError",error:D.error}),C(D)};return{tls_only:b(()=>{this.usingTLS=!0,this.updateStrategy(),this.retryIn(0)}),refused:b(()=>{this.disconnect()}),backoff:b(()=>{this.retryIn(1e3)}),retry:b(()=>{this.retryIn(0)})}}setConnection(b){this.connection=b;for(var C in this.connectionCallbacks)this.connection.bind(C,this.connectionCallbacks[C]);this.resetActivityCheck()}abandonConnection(){if(this.connection){this.stopActivityCheck();for(var b in this.connectionCallbacks)this.connection.unbind(b,this.connectionCallbacks[b]);var C=this.connection;return this.connection=null,C}}updateState(b,C){var D=this.state;if(this.state=b,D!==b){var I=b;I==="connected"&&(I+=" with new socket ID "+C.socket_id),nt.debug("State changed",D+" -> "+I),this.timeline.info({state:b,params:C}),this.emit("state_change",{previous:D,current:b}),this.emit(b,C)}}shouldRetry(){return this.state==="connecting"||this.state==="connected"}}class Vc{constructor(){this.channels={}}add(b,C){return this.channels[b]||(this.channels[b]=Kc(b,C)),this.channels[b]}all(){return rn(this.channels)}find(b){return this.channels[b]}remove(b){var C=this.channels[b];return delete this.channels[b],C}disconnect(){Ot(this.channels,function(b){b.disconnect()})}}function Kc(E,b){if(E.indexOf("private-encrypted-")===0){if(b.config.nacl)return jn.createEncryptedChannel(E,b,b.config.nacl);let C="Tried to subscribe to a private-encrypted- channel but no nacl implementation available",D=$.buildLogSuffix("encryptedChannelSupport");throw new pe(`${C}. ${D}`)}else{if(E.indexOf("private-")===0)return jn.createPrivateChannel(E,b);if(E.indexOf("presence-")===0)return jn.createPresenceChannel(E,b);if(E.indexOf("#")===0)throw new P('Cannot create a channel with name "'+E+'".');return jn.createChannel(E,b)}}var oh={createChannels(){return new Vc},createConnectionManager(E,b){return new sh(E,b)},createChannel(E,b){return new Wr(E,b)},createPrivateChannel(E,b){return new ua(E,b)},createPresenceChannel(E,b){return new Gc(E,b)},createEncryptedChannel(E,b,C){return new Ba(E,b,C)},createTimelineSender(E,b){return new Ua(E,b)},createHandshake(E,b){return new Wo(E,b)},createAssistantToTheTransportManager(E,b,C){return new ih(E,b,C)}};const jn=oh;class Di{constructor(b){this.options=b||{},this.livesLeft=this.options.lives||1/0}getAssistant(b){return jn.createAssistantToTheTransportManager(this,b,{minPingDelay:this.options.minPingDelay,maxPingDelay:this.options.maxPingDelay})}isAlive(){return this.livesLeft>0}reportDeath(){this.livesLeft-=1}}class yn{constructor(b,C){this.strategies=b,this.loop=!!C.loop,this.failFast=!!C.failFast,this.timeout=C.timeout,this.timeoutLimit=C.timeoutLimit}isSupported(){return Wn(this.strategies,Te.method("isSupported"))}connect(b,C){var D=this.strategies,I=0,ne=this.timeout,me=null,$e=(Ke,ct)=>{ct?C(null,ct):(I=I+1,this.loop&&(I=I%D.length),I0&&(ne=new ie(D.timeout,function(){me.abort(),I(!0)})),me=b.connect(C,function($e,Ke){$e&&ne&&ne.isRunning()&&!D.failFast||(ne&&ne.ensureAborted(),I($e,Ke))}),{abort:function(){ne&&ne.ensureAborted(),me.abort()},forceMinPriority:function($e){me.forceMinPriority($e)}}}}class xn{constructor(b){this.strategies=b}isSupported(){return Wn(this.strategies,Te.method("isSupported"))}connect(b,C){return Wc(this.strategies,b,function(D,I){return function(ne,me){if(I[D].error=ne,ne){lh(I)&&C(!0);return}Kt(I,function($e){$e.forceMinPriority(me.transport.priority)}),C(null,me)}})}}function Wc(E,b,C){var D=It(E,function(I,ne,me,$e){return I.connect(b,C(ne,$e))});return{abort:function(){Kt(D,Yo)},forceMinPriority:function(I){Kt(D,function(ne){ne.forceMinPriority(I)})}}}function lh(E){return Vr(E,function(b){return!!b.error})}function Yo(E){!E.error&&!E.aborted&&(E.abort(),E.aborted=!0)}class Yc{constructor(b,C,D){this.strategy=b,this.transports=C,this.ttl=D.ttl||18e5,this.usingTLS=D.useTLS,this.timeline=D.timeline}isSupported(){return this.strategy.isSupported()}connect(b,C){var D=this.usingTLS,I=ch(D),ne=I&&I.cacheSkipCount?I.cacheSkipCount:0,me=[this.strategy];if(I&&I.timestamp+this.ttl>=Te.now()){var $e=this.transports[I.transport];$e&&(["ws","wss"].includes(I.transport)||ne>3?(this.timeline.info({cached:!0,transport:I.transport,latency:I.latency}),me.push(new yn([$e],{timeout:I.latency*2+1e3,failFast:!0}))):ne++)}var Ke=Te.now(),ct=me.pop().connect(b,function gt(zt,$r){zt?(Ts(D),me.length>0?(Ke=Te.now(),ct=me.pop().connect(b,gt)):C(zt)):(Hn(D,$r.transport.name,Te.now()-Ke,ne),C(null,$r))});return{abort:function(){ct.abort()},forceMinPriority:function(gt){b=gt,ct&&ct.forceMinPriority(gt)}}}}function qa(E){return"pusherTransport"+(E?"TLS":"NonTLS")}function ch(E){var b=ze.getLocalStorage();if(b)try{var C=b[qa(E)];if(C)return JSON.parse(C)}catch{Ts(E)}return null}function Hn(E,b,C,D){var I=ze.getLocalStorage();if(I)try{I[qa(E)]=gn({timestamp:Te.now(),transport:b,latency:C,cacheSkipCount:D})}catch{}}function Ts(E){var b=ze.getLocalStorage();if(b)try{delete b[qa(E)]}catch{}}class Oi{constructor(b,{delay:C}){this.strategy=b,this.options={delay:C}}isSupported(){return this.strategy.isSupported()}connect(b,C){var D=this.strategy,I,ne=new ie(this.options.delay,function(){I=D.connect(b,C)});return{abort:function(){ne.ensureAborted(),I&&I.abort()},forceMinPriority:function(me){b=me,I&&I.forceMinPriority(me)}}}}class da{constructor(b,C,D){this.test=b,this.trueBranch=C,this.falseBranch=D}isSupported(){var b=this.test()?this.trueBranch:this.falseBranch;return b.isSupported()}connect(b,C){var D=this.test()?this.trueBranch:this.falseBranch;return D.connect(b,C)}}class Ga{constructor(b){this.strategy=b}isSupported(){return this.strategy.isSupported()}connect(b,C){var D=this.strategy.connect(b,function(I,ne){ne&&D.abort(),C(I,ne)});return D}}function Fa(E){return function(){return E.isSupported()}}var Xc=function(E,b,C){var D={};function I(cl,uu,du,Dh,Oh){var fu=C(E,cl,uu,du,Dh,Oh);return D[cl]=fu,fu}var ne=Object.assign({},b,{hostNonTLS:E.wsHost+":"+E.wsPort,hostTLS:E.wsHost+":"+E.wssPort,httpPath:E.wsPath}),me=Object.assign({},ne,{useTLS:!0}),$e=Object.assign({},b,{hostNonTLS:E.httpHost+":"+E.httpPort,hostTLS:E.httpHost+":"+E.httpsPort,httpPath:E.httpPath}),Ke={loop:!0,timeout:15e3,timeoutLimit:6e4},ct=new Di({minPingDelay:1e4,maxPingDelay:E.activityTimeout}),gt=new Di({lives:2,minPingDelay:1e4,maxPingDelay:E.activityTimeout}),zt=I("ws","ws",3,ne,ct),$r=I("wss","ws",3,me,ct),Th=I("sockjs","sockjs",1,$e),lu=I("xhr_streaming","xhr_streaming",1,$e,gt),kh=I("xdr_streaming","xdr_streaming",1,$e,gt),sl=I("xhr_polling","xhr_polling",1,$e),cu=I("xdr_polling","xdr_polling",1,$e),Wa=new yn([zt],Ke),ji=new yn([$r],Ke),Rh=new yn([Th],Ke),Hi=new yn([new da(Fa(lu),lu,kh)],Ke),ol=new yn([new da(Fa(sl),sl,cu)],Ke),ll=new yn([new da(Fa(Hi),new xn([Hi,new Oi(ol,{delay:4e3})]),ol)],Ke),zi=new da(Fa(ll),ll,Rh),Ui;return b.useTLS?Ui=new xn([Wa,new Oi(zi,{delay:2e3})]):Ui=new xn([Wa,new Oi(ji,{delay:2e3}),new Oi(zi,{delay:5e3})]),new Yc(new Ga(new da(Fa(zt),Ui,zi)),D,{ttl:18e5,timeline:b.timeline,useTLS:b.useTLS})};const Va=Xc;function uh(){var E=this;E.timeline.info(E.buildTimelineMessage({transport:E.name+(E.options.useTLS?"s":"")})),E.hooks.isInitialized()?E.changeState("initialized"):E.hooks.file?(E.changeState("initializing"),x.load(E.hooks.file,{useTLS:E.options.useTLS},function(b,C){E.hooks.isInitialized()?(E.changeState("initialized"),C(!0)):(b&&E.onError(b),E.onClose(),C(!1))})):E.onClose()}var Jc={getRequest:function(E){var b=new window.XDomainRequest;return b.ontimeout=function(){E.emit("error",new G),E.close()},b.onerror=function(C){E.emit("error",C),E.close()},b.onprogress=function(){b.responseText&&b.responseText.length>0&&E.onChunk(200,b.responseText)},b.onload=function(){b.responseText&&b.responseText.length>0&&E.onChunk(200,b.responseText),E.emit("finished",200),E.close()},b},abortRequest:function(E){E.ontimeout=E.onerror=E.onprogress=E.onload=null,E.abort()}};const Qc=Jc,Xo=256*1024;class dh extends Ae{constructor(b,C,D){super(),this.hooks=b,this.method=C,this.url=D}start(b){this.position=0,this.xhr=this.hooks.getRequest(this),this.unloader=()=>{this.close()},ze.addUnloadListener(this.unloader),this.xhr.open(this.method,this.url,!0),this.xhr.setRequestHeader&&this.xhr.setRequestHeader("Content-Type","application/json"),this.xhr.send(b)}close(){this.unloader&&(ze.removeUnloadListener(this.unloader),this.unloader=null),this.xhr&&(this.hooks.abortRequest(this.xhr),this.xhr=null)}onChunk(b,C){for(;;){var D=this.advanceBuffer(C);if(D)this.emit("chunk",{status:b,data:D});else break}this.isBufferTooLong(C)&&this.emit("buffer_too_long")}advanceBuffer(b){var C=b.slice(this.position),D=C.indexOf(` +`);return D!==-1?(this.position+=D+1,C.slice(0,D)):null}isBufferTooLong(b){return this.position===b.length&&b.length>Xo}}var Jo;(function(E){E[E.CONNECTING=0]="CONNECTING",E[E.OPEN=1]="OPEN",E[E.CLOSED=3]="CLOSED"})(Jo||(Jo={}));const cr=Jo;var Dr=1;class Qo{constructor(b,C){this.hooks=b,this.session=ks(1e3)+"/"+eu(8),this.location=Zo(C),this.readyState=cr.CONNECTING,this.openStream()}send(b){return this.sendRaw(JSON.stringify([b]))}ping(){this.hooks.sendHeartbeat(this)}close(b,C){this.onClose(b,C,!0)}sendRaw(b){if(this.readyState===cr.OPEN)try{return ze.createSocketRequest("POST",fa(Ka(this.location,this.session))).start(b),!0}catch{return!1}else return!1}reconnect(){this.closeStream(),this.openStream()}onClose(b,C,D){this.closeStream(),this.readyState=cr.CLOSED,this.onclose&&this.onclose({code:b,reason:C,wasClean:D})}onChunk(b){if(b.status===200){this.readyState===cr.OPEN&&this.onActivity();var C,D=b.data.slice(0,1);switch(D){case"o":C=JSON.parse(b.data.slice(1)||"{}"),this.onOpen(C);break;case"a":C=JSON.parse(b.data.slice(1)||"[]");for(var I=0;I{this.onChunk(b)}),this.stream.bind("finished",b=>{this.hooks.onFinished(this,b)}),this.stream.bind("buffer_too_long",()=>{this.reconnect()});try{this.stream.start()}catch(b){Te.defer(()=>{this.onError(b),this.onClose(1006,"Could not start streaming",!1)})}}closeStream(){this.stream&&(this.stream.unbind_all(),this.stream.close(),this.stream=null)}}function Zo(E){var b=/([^\?]*)\/*(\??.*)/.exec(E);return{base:b[1],queryString:b[2]}}function Ka(E,b){return E.base+"/"+b+"/xhr_send"}function fa(E){var b=E.indexOf("?")===-1?"?":"&";return E+b+"t="+ +new Date+"&n="+Dr++}function Zc(E,b){var C=/(https?:\/\/)([^\/:]+)((\/|:)?.*)/.exec(E);return C[1]+b+C[3]}function ks(E){return ze.randomInt(E)}function eu(E){for(var b=[],C=0;C0&&E.onChunk(C.status,C.responseText);break;case 4:C.responseText&&C.responseText.length>0&&E.onChunk(C.status,C.responseText),E.emit("finished",C.status),E.close();break}},C},abortRequest:function(E){E.onreadystatechange=null,E.abort()}};const Rs=tl;var tu={createStreamingSocket(E){return this.createSocket(el,E)},createPollingSocket(E){return this.createSocket(Yr,E)},createSocket(E,b){return new Li(E,b)},createXHR(E,b){return this.createRequest(Rs,E,b)},createRequest(E,b,C){return new dh(E,b,C)}};const Mi=tu;Mi.createXDR=function(E,b){return this.createRequest(Qc,E,b)};var nu={nextAuthCallbackID:1,auth_callbacks:{},ScriptReceivers:m,DependenciesReceivers:_,getDefaultStrategy:Va,Transports:An,transportConnectionInitializer:uh,HTTPFactory:Mi,TimelineTransport:on,getXHRAPI(){return window.XMLHttpRequest},getWebSocketAPI(){return window.WebSocket||window.MozWebSocket},setup(E){window.Pusher=E;var b=()=>{this.onDocumentBody(E.ready)};window.JSON?b():x.load("json2",{},b)},getDocument(){return document},getProtocol(){return this.getDocument().location.protocol},getAuthorizers(){return{ajax:qe,jsonp:mn}},onDocumentBody(E){document.body?E():setTimeout(()=>{this.onDocumentBody(E)},0)},createJSONPRequest(E,b){return new lr(E,b)},createScriptRequest(E){return new ca(E)},getLocalStorage(){try{return window.localStorage}catch{return}},createXHR(){return this.getXHRAPI()?this.createXMLHttpRequest():this.createMicrosoftXHR()},createXMLHttpRequest(){var E=this.getXHRAPI();return new E},createMicrosoftXHR(){return new ActiveXObject("Microsoft.XMLHTTP")},getNetwork(){return Ko},createWebSocket(E){var b=this.getWebSocketAPI();return new b(E)},createSocketRequest(E,b){if(this.isXHRSupported())return this.HTTPFactory.createXHR(E,b);if(this.isXDRSupported(b.indexOf("https:")===0))return this.HTTPFactory.createXDR(E,b);throw"Cross-origin HTTP requests are not supported"},isXHRSupported(){var E=this.getXHRAPI();return!!E&&new E().withCredentials!==void 0},isXDRSupported(E){var b=E?"https:":"http:",C=this.getProtocol();return!!window.XDomainRequest&&C===b},addUnloadListener(E){window.addEventListener!==void 0?window.addEventListener("unload",E,!1):window.attachEvent!==void 0&&window.attachEvent("onunload",E)},removeUnloadListener(E){window.addEventListener!==void 0?window.removeEventListener("unload",E,!1):window.detachEvent!==void 0&&window.detachEvent("onunload",E)},randomInt(E){return Math.floor(function(){return(window.crypto||window.msCrypto).getRandomValues(new Uint32Array(1))[0]/Math.pow(2,32)}()*E)}};const ze=nu;var Lr;(function(E){E[E.ERROR=3]="ERROR",E[E.INFO=6]="INFO",E[E.DEBUG=7]="DEBUG"})(Lr||(Lr={}));const ha=Lr;class Ni{constructor(b,C,D){this.key=b,this.session=C,this.events=[],this.options=D||{},this.sent=0,this.uniqueID=0}log(b,C){b<=this.options.level&&(this.events.push(Me({},C,{timestamp:Te.now()})),this.options.limit&&this.events.length>this.options.limit&&this.events.shift())}error(b){this.log(ha.ERROR,b)}info(b){this.log(ha.INFO,b)}debug(b){this.log(ha.DEBUG,b)}isEmpty(){return this.events.length===0}send(b,C){var D=Me({session:this.session,bundle:this.sent+1,key:this.key,lib:"js",version:this.options.version,cluster:this.options.cluster,features:this.options.features,timeline:this.events},this.options.params);return this.events=[],b(D,(I,ne)=>{I||this.sent++,C&&C(I,ne)}),!0}generateUniqueID(){return this.uniqueID++,this.uniqueID}}class fh{constructor(b,C,D,I){this.name=b,this.priority=C,this.transport=D,this.options=I||{}}isSupported(){return this.transport.isSupported({useTLS:this.options.useTLS})}connect(b,C){if(this.isSupported()){if(this.priority{D||(gt(),ne?ne.close():I.close())},forceMinPriority:zt=>{D||this.priority{var C="socket_id="+encodeURIComponent(E.socketId);for(var D in b.params)C+="&"+encodeURIComponent(D)+"="+encodeURIComponent(b.params[D]);if(b.paramsProvider!=null){let I=b.paramsProvider();for(var D in I)C+="&"+encodeURIComponent(D)+"="+encodeURIComponent(I[D])}return C},ph=E=>{if(typeof ze.getAuthorizers()[E.transport]>"u")throw`'${E.transport}' is not a recognized auth transport`;return(b,C)=>{const D=hh(b,E);ze.getAuthorizers()[E.transport](ze,D,E,k.UserAuthentication,C)}},al=(E,b)=>{var C="socket_id="+encodeURIComponent(E.socketId);C+="&channel_name="+encodeURIComponent(E.channelName);for(var D in b.params)C+="&"+encodeURIComponent(D)+"="+encodeURIComponent(b.params[D]);if(b.paramsProvider!=null){let I=b.paramsProvider();for(var D in I)C+="&"+encodeURIComponent(D)+"="+encodeURIComponent(I[D])}return C},gh=E=>{if(typeof ze.getAuthorizers()[E.transport]>"u")throw`'${E.transport}' is not a recognized auth transport`;return(b,C)=>{const D=al(b,E);ze.getAuthorizers()[E.transport](ze,D,E,k.ChannelAuthorization,C)}},mh=(E,b,C)=>{const D={authTransport:b.transport,authEndpoint:b.endpoint,auth:{params:b.params,headers:b.headers}};return(I,ne)=>{const me=E.channel(I.channelName);C(me,D).authorize(I.socketId,ne)}};function au(E,b){let C={activityTimeout:E.activityTimeout||S.activityTimeout,cluster:E.cluster,httpPath:E.httpPath||S.httpPath,httpPort:E.httpPort||S.httpPort,httpsPort:E.httpsPort||S.httpsPort,pongTimeout:E.pongTimeout||S.pongTimeout,statsHost:E.statsHost||S.stats_host,unavailableTimeout:E.unavailableTimeout||S.unavailableTimeout,wsPath:E.wsPath||S.wsPath,wsPort:E.wsPort||S.wsPort,wssPort:E.wssPort||S.wssPort,enableStats:Sh(E),httpHost:yh(E),useTLS:vh(E),wsHost:iu(E),userAuthenticator:il(E),channelAuthorizer:Ch(E,b)};return"disabledTransports"in E&&(C.disabledTransports=E.disabledTransports),"enabledTransports"in E&&(C.enabledTransports=E.enabledTransports),"ignoreNullOrigin"in E&&(C.ignoreNullOrigin=E.ignoreNullOrigin),"timelineParams"in E&&(C.timelineParams=E.timelineParams),"nacl"in E&&(C.nacl=E.nacl),C}function yh(E){return E.httpHost?E.httpHost:E.cluster?`sockjs-${E.cluster}.pusher.com`:S.httpHost}function iu(E){return E.wsHost?E.wsHost:bh(E.cluster)}function bh(E){return`ws-${E}.pusher.com`}function vh(E){return ze.getProtocol()==="https:"?!0:E.forceTLS!==!1}function Sh(E){return"enableStats"in E?E.enableStats:"disableStats"in E?!E.disableStats:!1}const su=E=>"customHandler"in E&&E.customHandler!=null;function il(E){const b=Object.assign(Object.assign({},S.userAuthentication),E.userAuthentication);return su(b)?b.customHandler:ph(b)}function wh(E,b){let C;if("channelAuthorization"in E)C=Object.assign(Object.assign({},S.channelAuthorization),E.channelAuthorization);else if(C={transport:E.authTransport||S.authTransport,endpoint:E.authEndpoint||S.authEndpoint},"auth"in E&&("params"in E.auth&&(C.params=E.auth.params),"headers"in E.auth&&(C.headers=E.auth.headers)),"authorizer"in E)return{customHandler:mh(b,C,E.authorizer)};return C}function Ch(E,b){const C=wh(E,b);return su(C)?C.customHandler:gh(C)}class Eh extends Ae{constructor(b){super(function(C,D){nt.debug(`No callbacks on watchlist events for ${C}`)}),this.pusher=b,this.bindWatchlistInternalEvent()}handleEvent(b){b.data.events.forEach(C=>{this.emit(C.name,C)})}bindWatchlistInternalEvent(){this.pusher.connection.bind("message",b=>{var C=b.event;C==="pusher_internal:watchlist_events"&&this.handleEvent(b)})}}function ou(){let E,b;return{promise:new Promise((D,I)=>{E=D,b=I}),resolve:E,reject:b}}const _h=ou;class Ah extends Ae{constructor(b){super(function(C,D){nt.debug("No callbacks on user for "+C)}),this.signin_requested=!1,this.user_data=null,this.serverToUserChannel=null,this.signinDonePromise=null,this._signinDoneResolve=null,this._onAuthorize=(C,D)=>{if(C){nt.warn(`Error during signin: ${C}`),this._cleanup();return}this.pusher.send_event("pusher:signin",{auth:D.auth,user_data:D.user_data})},this.pusher=b,this.pusher.connection.bind("state_change",({previous:C,current:D})=>{C!=="connected"&&D==="connected"&&this._signin(),C==="connected"&&D!=="connected"&&(this._cleanup(),this._newSigninPromiseIfNeeded())}),this.watchlist=new Eh(b),this.pusher.connection.bind("message",C=>{var D=C.event;D==="pusher:signin_success"&&this._onSigninSuccess(C.data),this.serverToUserChannel&&this.serverToUserChannel.name===C.channel&&this.serverToUserChannel.handleEvent(C)})}signin(){this.signin_requested||(this.signin_requested=!0,this._signin())}_signin(){this.signin_requested&&(this._newSigninPromiseIfNeeded(),this.pusher.connection.state==="connected"&&this.pusher.config.userAuthenticator({socketId:this.pusher.connection.socket_id},this._onAuthorize))}_onSigninSuccess(b){try{this.user_data=JSON.parse(b.user_data)}catch{nt.error(`Failed parsing user data after signin: ${b.user_data}`),this._cleanup();return}if(typeof this.user_data.id!="string"||this.user_data.id===""){nt.error(`user_data doesn't contain an id. user_data: ${this.user_data}`),this._cleanup();return}this._signinDoneResolve(),this._subscribeChannels()}_subscribeChannels(){const b=C=>{C.subscriptionPending&&C.subscriptionCancelled?C.reinstateSubscription():!C.subscriptionPending&&this.pusher.connection.state==="connected"&&C.subscribe()};this.serverToUserChannel=new Wr(`#server-to-user-${this.user_data.id}`,this.pusher),this.serverToUserChannel.bind_global((C,D)=>{C.indexOf("pusher_internal:")===0||C.indexOf("pusher:")===0||this.emit(C,D)}),b(this.serverToUserChannel)}_cleanup(){this.user_data=null,this.serverToUserChannel&&(this.serverToUserChannel.unbind_all(),this.serverToUserChannel.disconnect(),this.serverToUserChannel=null),this.signin_requested&&this._signinDoneResolve()}_newSigninPromiseIfNeeded(){if(!this.signin_requested||this.signinDonePromise&&!this.signinDonePromise.done)return;const{promise:b,resolve:C}=_h();b.done=!1;const D=()=>{b.done=!0};b.then(D).catch(D),this.signinDonePromise=b,this._signinDoneResolve=C}}class ln{static ready(){ln.isReady=!0;for(var b=0,C=ln.instances.length;bze.getDefaultStrategy(this.config,I,Ii);this.connection=jn.createConnectionManager(this.key,{getStrategy:D,timeline:this.timeline,activityTimeout:this.config.activityTimeout,pongTimeout:this.config.pongTimeout,unavailableTimeout:this.config.unavailableTimeout,useTLS:!!this.config.useTLS}),this.connection.bind("connected",()=>{this.subscribeAll(),this.timelineSender&&this.timelineSender.send(this.connection.isUsingTLS())}),this.connection.bind("message",I=>{var ne=I.event,me=ne.indexOf("pusher_internal:")===0;if(I.channel){var $e=this.channel(I.channel);$e&&$e.handleEvent(I)}me||this.global_emitter.emit(I.event,I.data)}),this.connection.bind("connecting",()=>{this.channels.disconnect()}),this.connection.bind("disconnected",()=>{this.channels.disconnect()}),this.connection.bind("error",I=>{nt.warn(I)}),ln.instances.push(this),this.timeline.info({instances:ln.instances.length}),this.user=new Ah(this),ln.isReady&&this.connect()}switchCluster(b){const{appKey:C,cluster:D}=b;this.key=C,this.options=Object.assign(Object.assign({},this.options),{cluster:D}),this.config=au(this.options,this),this.connection.switchCluster(this.key)}channel(b){return this.channels.find(b)}allChannels(){return this.channels.all()}connect(){if(this.connection.connect(),this.timelineSender&&!this.timelineSenderTimer){var b=this.connection.isUsingTLS(),C=this.timelineSender;this.timelineSenderTimer=new xe(6e4,function(){C.send(b)})}}disconnect(){this.connection.disconnect(),this.timelineSenderTimer&&(this.timelineSenderTimer.ensureAborted(),this.timelineSenderTimer=null)}bind(b,C,D){return this.global_emitter.bind(b,C,D),this}unbind(b,C,D){return this.global_emitter.unbind(b,C,D),this}bind_global(b){return this.global_emitter.bind_global(b),this}unbind_global(b){return this.global_emitter.unbind_global(b),this}unbind_all(b){return this.global_emitter.unbind_all(),this}subscribeAll(){var b;for(b in this.channels.channels)this.channels.channels.hasOwnProperty(b)&&this.subscribe(b)}subscribe(b){var C=this.channels.add(b,this);return C.subscriptionPending&&C.subscriptionCancelled?C.reinstateSubscription():!C.subscriptionPending&&this.connection.state==="connected"&&C.subscribe(),C}unsubscribe(b){var C=this.channels.find(b);C&&C.subscriptionPending?C.cancelSubscription():(C=this.channels.remove(b),C&&C.subscribed&&C.unsubscribe())}send_event(b,C,D){return this.connection.send_event(b,C,D)}shouldUseTLS(){return this.config.useTLS}signin(){this.user.signin()}}ln.instances=[],ln.isReady=!1,ln.logToConsole=!1,ln.Runtime=ze,ln.ScriptReceivers=ze.ScriptReceivers,ln.DependenciesReceivers=ze.DependenciesReceivers,ln.auth_callbacks=ze.auth_callbacks;const Ls=ln;function xh(E){if(E==null)throw"You must pass your app key when you instantiate Pusher."}ze.setup(ln)}},r={};function i(c){var d=r[c];if(d!==void 0)return d.exports;var f=r[c]={exports:{}};return n[c].call(f.exports,f,f.exports,i),f.exports}i.d=(c,d)=>{for(var f in d)i.o(d,f)&&!i.o(c,f)&&Object.defineProperty(c,f,{enumerable:!0,get:d[f]})},i.o=(c,d)=>Object.prototype.hasOwnProperty.call(c,d);var l=i(721);return l})())})(Qf)),Qf.exports}var KA=VA();const Yy=ta(KA),Pt=dt("WebSocketManager");class WA{constructor(){M(this,"echo",null);M(this,"subscriptions",new Map);M(this,"initialized",!1);M(this,"config",null)}configure(e){if(this.initialized){Pt.warn("[WebSocketManager] 이미 초기화되어 설정을 변경할 수 없습니다.");return}this.config=e,Pt.log("[WebSocketManager] 설정 완료:",{appKey:e.appKey?"***":"(없음)",host:e.host,port:e.port,scheme:e.scheme})}initialize(){if(this.initialized)return;if(!this.config||!this.config.appKey){Pt.warn("[WebSocketManager] WebSocket 설정이 없습니다. initTemplateApp에서 websocket 옵션을 전달해주세요.");return}const{appKey:e,host:n="localhost",port:r=80,scheme:i="https",authEndpoint:l="/api/broadcasting/auth"}=this.config,c=Number(r)||80,d=i==="https";Pt.log("[WebSocketManager] 연결 설정:",{host:n,port:c,scheme:i,useTLS:d,authEndpoint:l}),window.Pusher=Yy;const f=localStorage.getItem("auth_token"),h={wsHost:n,wsPort:c,wssPort:c,forceTLS:d,disableStats:!0,enabledTransports:["ws","wss"],cluster:"mt1",authEndpoint:l,auth:{headers:{Authorization:f?`Bearer ${f}`:"",Accept:"application/json"}}};Pt.log("[WebSocketManager] Pusher 옵션:",h);const m=new Yy(e,h);m.connection.bind("connecting",()=>{Pt.log("[WebSocketManager] 연결 시도 중...")}),m.connection.bind("connected",()=>{Pt.log("[WebSocketManager] 연결 성공! Socket ID:",m.connection.socket_id)}),m.connection.bind("failed",()=>{Pt.error("[WebSocketManager] 연결 실패 - WebSocket을 사용할 수 없습니다.")}),m.connection.bind("error",y=>{Pt.error("[WebSocketManager] 연결 오류:",y)}),m.connection.bind("state_change",y=>{Pt.log(`[WebSocketManager] 상태 변경: ${y.previous} → ${y.current}`)}),m.connection.bind("unavailable",()=>{Pt.error("[WebSocketManager] WebSocket 사용 불가 - 연결할 수 없습니다.")}),m.connection.bind("disconnected",()=>{Pt.warn("[WebSocketManager] 연결이 끊어졌습니다.")}),Pt.log("[WebSocketManager] 초기 연결 상태:",m.connection.state),this.echo=new FA({broadcaster:"reverb",client:m}),Pt.log("[WebSocketManager] 연결 시작 시도..."),m.connect(),window.Echo=this.echo,this.initialized=!0,Pt.log("[WebSocketManager] Echo 초기화 완료")}subscribe(e,n,r,i={}){if(this.initialize(),!this.echo)return Pt.warn("[WebSocketManager] Echo가 초기화되지 않았습니다."),"";const{channelType:l="private"}=i,c=`${e}:${n}`;if(this.subscriptions.has(c))return Pt.log(`[WebSocketManager] 이미 구독 중: ${c}`),c;let d;switch(l){case"public":d=this.echo.channel(e);break;case"presence":d=this.echo.join(e);break;default:d=this.echo.private(e)}return d.listen(`.${n}`,r),this.subscriptions.set(c,d),Pt.log(`[WebSocketManager] 구독 완료: ${c} (${l})`),c}unsubscribe(e){const n=this.subscriptions.get(e);if(!n)return;const r=e.lastIndexOf(":"),i=r>=0?e.substring(r+1):"";if(i)try{n.stopListening(`.${i}`)}catch(l){Pt.warn(`[WebSocketManager] stopListening 실패: ${e}`,l)}this.subscriptions.delete(e),Pt.log(`[WebSocketManager] 구독 해제: ${e}`)}leaveChannel(e){if(!this.echo)return;this.echo.leave(e);const n=[];this.subscriptions.forEach((r,i)=>{i.startsWith(`${e}:`)&&n.push(i)}),n.forEach(r=>this.subscriptions.delete(r)),Pt.log(`[WebSocketManager] 채널 구독 해제: ${e}`)}disconnect(){this.echo&&(this.echo.disconnect(),this.subscriptions.clear(),this.initialized=!1,Pt.log("[WebSocketManager] 연결 종료"))}getEcho(){return this.echo}isInitialized(){return this.initialized}isConfigured(){return this.config!==null&&!!this.config.appKey}getSubscriptionCount(){return this.subscriptions.size}}const Nc=new WA,bt=dt("DataSourceManager"),Xy=new kn;function Ic(s,e){const n=Da(s);if(n!==null)try{return Gn(n)?Xy.evaluatePipeExpression(n,e,{skipCache:!0}):Xy.evaluateExpression(n,e)}catch(r){return bt.error("Failed to evaluate param expression:",n,r),s}return ls(s,e,{skipCache:!0})}function Jy(s){const e={};for(const n of s.keys()){if(n in e)continue;const r=s.getAll(n);r.length>1?e[n]=r:r.length===1&&(n.endsWith("[]")?e[n]=r:e[n]=r[0])}return e}function YA(){try{return window.G7Core?.devTools}catch{return}}const Bc=class Bc{constructor(e={}){M(this,"options");M(this,"dataCache",new Map);M(this,"bindingEngine");M(this,"globalHeaders",[]);this.options=e,this.bindingEngine=new kn}setGlobalHeaders(e){this.globalHeaders=e||[]}matchesPattern(e,n){if(n==="*")return!0;const r=n.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${r}$`).test(e)}toFormData(e){const n=new FormData;for(const[r,i]of Object.entries(e))i instanceof File||i instanceof Blob?n.append(r,i):i!=null&&n.append(r,typeof i=="object"?JSON.stringify(i):String(i));return n}getMatchingGlobalHeaders(e,n){const r={};for(const i of this.globalHeaders)this.matchesPattern(e,i.pattern)&&Object.entries(i.headers).forEach(([l,c])=>{const d=Ic(c,n);d!=null&&d!==""&&(r[l]=String(d))});return r}filterByCondition(e,n={}){const r=new Set,i=[];for(const l of e){if(r.has(l.id))continue;if(!l.if&&!l.conditions){r.add(l.id),i.push(l);continue}os({if:l.if,conditions:l.conditions},n,this.bindingEngine,`data_source:${l.id}`)&&(r.add(l.id),i.push(l))}return i}checkErrorCondition(e,n){if(!e.errorCondition?.if||e.errorCondition?.errorCode===void 0)return null;try{const r={response:n};if(os({if:e.errorCondition.if},r,this.bindingEngine,`errorCondition:${e.id}`))return bt.log(`errorCondition matched for ${e.id}, triggering error ${e.errorCondition.errorCode}`),e.errorCondition.errorCode}catch(r){bt.error(`Failed to evaluate errorCondition for ${e.id}:`,r)}return null}async fetchDataSources(e,n={},r=new URLSearchParams,i,l){const c={},d=!!this.options.sampleProvider,f=e.filter(h=>(d||h.auto_fetch!==!1)&&h.type!=="websocket");return await Promise.all(f.map(async h=>{try{const m=await this.fetchDataSource(h,n,r,i,l);c[h.id]=m,this.dataCache.set(h.id,{data:m,timestamp:Date.now()});const y=this.checkErrorCondition(h,m);if(y!==null){const S={status:y,message:`Error condition matched for ${h.id}`,data:m},v=Er(),_=v.resolve(y,{errorHandling:h.errorHandling,onError:h.onError});if(_.handler)try{await v.execute(_.handler,S)}catch(x){bt.error(`Error executing errorCondition handler for ${h.id}:`,x)}h.fallback!==void 0&&(c[h.id]=h.fallback,this.dataCache.set(h.id,{data:h.fallback,timestamp:Date.now()}),bt.log(`Using fallback data for ${h.id} (errorCondition)`));return}if(h.onSuccess)try{const S={data:m,sourceId:h.id};await this.executeOnSuccessHandler(h.onSuccess,S)}catch(S){bt.error(`Error executing onSuccess handler for ${h.id}:`,S)}}catch(m){bt.error(`Failed to fetch data source: ${h.id}`,m);const y=m?.response?.status||m?.status||500,S=m?.response?.data,v=S?.message||m.message||"Unknown error",_={status:y,message:v,errors:S?.errors,data:S,statusText:m?.response?.statusText},x=Er(),A=x.resolve(y,{errorHandling:h.errorHandling,onError:h.onError});if(A.handler)try{await x.execute(A.handler,_)}catch(L){bt.error(`Error executing error handler for ${h.id}:`,L)}h.fallback!==void 0&&(c[h.id]=h.fallback,this.dataCache.set(h.id,{data:h.fallback,timestamp:Date.now()}),bt.log(`Using fallback data for ${h.id}`)),this.options.onError&&this.options.onError(m,h)}})),c}async fetchDataSourcesWithResults(e,n={},r=new URLSearchParams,i,l,c){if(e.some(m=>m.type==="websocket")){const m=e.filter(y=>y.type==="websocket").map(y=>y.id).join(", ");bt.warn(`fetchDataSourcesWithResults received WebSocket sources (caller should filter them out before calling): ${m}. WebSocket sources are event listeners, not data providers — they should not be passed to fetch.`)}const f=c?.ignoreAutoFetch?e.filter(m=>m.type!=="websocket"):e.filter(m=>m.auto_fetch!==!1&&m.type!=="websocket");return await Promise.all(f.map(async m=>{try{const y=await this.fetchDataSource(m,n,r,i,l);this.dataCache.set(m.id,{data:y,timestamp:Date.now()});const S=this.checkErrorCondition(m,y);if(S!==null){const v={status:S,message:`Error condition matched for ${m.id}`,data:y},_=Er(),x=_.resolve(S,{errorHandling:m.errorHandling,onError:m.onError});let A=!1;if(x.handler)if(m.loading_strategy==="blocking")_.execute(x.handler,v).catch(L=>{bt.error(`Error executing errorCondition handler for ${m.id}:`,L)}),A=!0;else try{await _.execute(x.handler,v),A=!0}catch(L){bt.error(`Error executing errorCondition handler for ${m.id}:`,L)}return m.fallback!==void 0?(this.dataCache.set(m.id,{data:m.fallback,timestamp:Date.now()}),bt.log(`Using fallback data for ${m.id} (errorCondition)`),{id:m.id,state:"success",data:m.fallback}):{id:m.id,state:"error",error:new Error(`Error condition matched: ${S}`),errorCode:S,errorHandled:A}}if(m.onSuccess)try{const v={data:y,sourceId:m.id};await this.executeOnSuccessHandler(m.onSuccess,v)}catch(v){bt.error(`Error executing onSuccess handler for ${m.id}:`,v)}return{id:m.id,state:"success",data:y}}catch(y){bt.error(`Failed to fetch data source: ${m.id}`,y);const S=y?.response?.status||y?.status||500,v=y?.response?.data,_=v?.message||y.message||"Unknown error",x={status:S,message:_,errors:v?.errors,data:v,statusText:y?.response?.statusText},A=Er(),L=A.resolve(S,{errorHandling:m.errorHandling,onError:m.onError});let $=!1;if(L.handler)if(m.loading_strategy==="blocking")A.execute(L.handler,x).catch(k=>{bt.error(`Error executing error handler for ${m.id}:`,k)}),$=!0;else try{await A.execute(L.handler,x),$=!0}catch(k){bt.error(`Error executing error handler for ${m.id}:`,k)}return m.fallback!==void 0?(this.dataCache.set(m.id,{data:m.fallback,timestamp:Date.now()}),bt.log(`Using fallback data for ${m.id}`),{id:m.id,state:"success",data:m.fallback}):(this.options.onError&&this.options.onError(y,m),{id:m.id,state:"error",error:y,errorCode:S,errorHandled:$})}}))}fetchDataSourcesInBackground(e,n={},r=new URLSearchParams,i){e.filter(c=>c.auto_fetch!==!1&&c.loading_strategy==="background"&&c.type!=="websocket").forEach(c=>{this.fetchDataSource(c,n,r).then(async d=>{this.dataCache.set(c.id,{data:d,timestamp:Date.now()});const f=this.checkErrorCondition(c,d);if(f!==null){const h={status:f,message:`Error condition matched for ${c.id}`,data:d},m=Er(),y=m.resolve(f,{errorHandling:c.errorHandling,onError:c.onError});if(y.handler)try{await m.execute(y.handler,h)}catch(S){bt.error(`Error executing errorCondition handler for ${c.id}:`,S)}c.fallback!==void 0&&(this.dataCache.set(c.id,{data:c.fallback,timestamp:Date.now()}),bt.log(`Using fallback data for ${c.id} (errorCondition)`),i&&i(c.id,c.fallback));return}if(c.onSuccess)try{const h={data:d,sourceId:c.id};await this.executeOnSuccessHandler(c.onSuccess,h)}catch(h){bt.error(`Error executing onSuccess handler for ${c.id}:`,h)}i&&i(c.id,d)}).catch(async d=>{bt.error(`Background fetch failed: ${c.id}`,d);const f=d?.response?.status||d?.status||500,h=d?.response?.data,m=h?.message||d.message||"Unknown error",y={status:f,message:m,errors:h?.errors,data:h,statusText:d?.response?.statusText},S=Er(),v=S.resolve(f,{errorHandling:c.errorHandling,onError:c.onError});if(v.handler)try{await S.execute(v.handler,y)}catch(_){bt.error(`Error executing error handler for ${c.id}:`,_)}if(c.fallback!==void 0){this.dataCache.set(c.id,{data:c.fallback,timestamp:Date.now()}),bt.log(`Using fallback data for ${c.id}`),i&&i(c.id,c.fallback);return}this.options.onError&&this.options.onError(d,c)})})}async fetchDataSource(e,n,r,i,l){switch(e.type){case"api":return this.fetchApiDataSource(e,n,r,i,l);case"static":return e.data;case"route_params":return n;case"query_params":return Jy(r);default:throw new Error(`Unknown data source type: ${e.type}`)}}async fetchApiDataSource(e,n,r,i,l){if(this.options.sampleProvider?.has(e.id))return await Promise.resolve(this.options.sampleProvider.resolve(e));if(!e.endpoint)throw new Error(`API data source ${e.id} has no endpoint`);const c={route:n,query:Jy(r)};i&&(c._global=i),l&&(c._local=l);let d=ls(e.endpoint,c,{skipCache:!0});const f=e.method||"GET",m=(e.contentType?typeof e.contentType=="string"&&e.contentType.includes("{{")?ls(e.contentType,c,{skipCache:!0}):e.contentType:"application/json")==="multipart/form-data";let y=m?{...e.params||{}}:JSON.parse(JSON.stringify(e.params||{}));Object.entries(y).forEach(([_,x])=>{typeof x=="string"&&(y[_]=Ic(x,c))}),Object.keys(y).forEach(_=>{y[_]===""&&delete y[_]});const S=YA();let v=null;if(S?.isEnabled()){S.trackDataSourceDefinition({id:e.id,type:e.type,endpoint:d,method:f,autoFetch:e.auto_fetch,initLocal:e.initLocal,initGlobal:e.initGlobal});let _=d;if(f==="GET"&&Object.keys(y).length>0){const x=new URLSearchParams;Object.entries(y).forEach(([L,$])=>{Array.isArray($)?$.forEach(k=>x.append(L,String(k))):$!=null&&x.append(L,String($))});const A=x.toString();_=A?`${d}?${A}`:d}v=S.trackRequest(_,f,{requestBody:f!=="GET"?y:void 0,dataSourceId:e.id}),S.trackDataSourceLoading(e.id)}try{let _;const x=e.auth_mode??(e.auth_required===!0?"required":"none"),A=wr.getInstance().isAuthenticated();if(x==="required"&&!A){bt.log(`[DataSourceManager] Skipping ${e.id}: auth_mode is 'required' but no token available`),S?.isEnabled()&&(S.trackDataSourceError(e.id,"Skipped: auth_mode required but not authenticated"),v&&S.failRequest(v,"Skipped: not authenticated"));const $=new Error("Auth required but not authenticated");throw $.response={status:401,statusText:"Unauthorized",data:null},$.status=401,$._authSkipped=!0,$}const L=x==="required"||x==="optional"&&A;if(L){const $=zr(),k=d.startsWith("/api/")?d.substring(4):d.startsWith("/api")?d.substring(4)||"/":d;this.options.onError&&bt.log(`[DataSourceManager] Normalized endpoint: ${d} -> ${k}`);const O=this.getMatchingGlobalHeaders(d,c),P={};e.headers&&Object.entries(e.headers).forEach(([pe,Se])=>{const we=Ic(Se,c);we!=null&&we!==""&&(P[pe]=String(we))});const G={...O,...P},B=Object.keys(G).length>0,W=m?this.toFormData(y):y;switch(f){case"GET":_=await $.get(k,{params:y,...B&&{headers:G}});break;case"POST":B?_=await $.post(k,W,{headers:G}):_=await $.post(k,W);break;case"PUT":B?_=await $.put(k,W,{headers:G}):_=await $.put(k,W);break;case"PATCH":B?_=await $.patch(k,W,{headers:G}):_=await $.patch(k,W);break;case"DELETE":_=await $.delete(k,{params:y,...B&&{headers:G}});break;default:throw new Error(`Unsupported HTTP method: ${f}`)}}else{let $=d;if(f==="GET"){const W=new URLSearchParams(y).toString();$=W?`${d}?${W}`:d}const k={...m?{}:{"Content-Type":"application/json"},Accept:"application/json"};if(typeof window<"u"){const W=localStorage.getItem("g7_locale");W&&(k["Accept-Language"]=W)}const O=this.getMatchingGlobalHeaders(d,c);Object.assign(k,O),e.headers&&Object.entries(e.headers).forEach(([W,pe])=>{const Se=Ic(pe,c);Se!=null&&Se!==""&&(k[W]=String(Se))});let P;f!=="GET"&&(m?(P=this.toFormData(y),delete k["Content-Type"]):P=JSON.stringify(y));const G=await fetch($,{method:f,headers:k,body:P});let B;try{B=await G.json()}catch{B=null}if(v&&S?.isEnabled()&&(S.completeRequest(v,G.status,B),v=null),!G.ok){S?.isEnabled()&&S.trackDataSourceError(e.id,`HTTP ${G.status}: ${G.statusText}`);const W=new Error(`HTTP error! status: ${G.status}`);throw W.response={status:G.status,statusText:G.statusText,data:B},W.status=G.status,W}_=B,S?.isEnabled()&&S.trackDataSourceLoaded(e.id,_)}return L&&v&&S?.isEnabled()&&(S.completeRequest(v,200,_),S.trackDataSourceLoaded(e.id,_)),_}catch(_){if(v&&S?.isEnabled()){const x=_;x?.response?S.completeRequest(v,x.response.status,x.response.data):S.failRequest(v,_ instanceof Error?_.message:String(_)),S.trackDataSourceError(e.id,_ instanceof Error?_.message:String(_))}throw _}}getCachedData(e){const n=this.dataCache.get(e);if(!n)return;if(Date.now()-n.timestamp>Bc.DATA_CACHE_TTL){this.dataCache.delete(e);return}return n.data}clearCache(){this.dataCache.clear()}subscribeWebSockets(e,n,r={}){const i=[],l=e.filter(c=>c.type==="websocket");return l.length===0||l.forEach(c=>{if(!c.channel||!c.event){bt.warn(`WebSocket source ${c.id} missing channel or event`);return}let d,f;try{d=ls(c.channel,r,{skipCache:!0}),f=ls(c.event,r,{skipCache:!0})}catch(y){bt.error(`Failed to resolve WebSocket channel/event for source ${c.id}:`,y);return}const h=y=>!!(!y||y.trim()===""||y.includes("{{")||y.endsWith(".")||y.endsWith(":")||y.startsWith(".")||y.startsWith(":")||y.includes("..")||y.includes("::"));if(h(d)||h(f)){bt.warn(`WebSocket source ${c.id} has invalid channel/event after expression resolution, skipping. Original channel="${c.channel}", resolved="${d}". Original event="${c.event}", resolved="${f}". Available context keys: [${Object.keys(r).join(", ")}]`);return}const m=Nc.subscribe(d,f,y=>{const S=c.target_source||c.id;this.dataCache.set(S,{data:y,timestamp:Date.now()}),n(S,y)},{channelType:c.channel_type||"private"});m&&i.push(m)}),i}unsubscribeWebSockets(e){e.length!==0&&e.forEach(n=>{Nc.unsubscribe(n)})}async executeOnSuccessHandler(e,n){const r=this.options.actionDispatcher??Wm();if(!r){bt.warn("ActionDispatcher not available, skipping onSuccess handler");return}const i=Array.isArray(e)?e:[e];for(const l of i)try{await r.dispatchAction({type:"click",...l},{data:{response:n}})}catch(c){throw bt.error("Failed to execute onSuccess handler:",c),c}}};M(Bc,"DATA_CACHE_TTL",3e5);let Tr=Bc;const XA=new Tr,_i=dt("ModalDataSourceWrapper");function JA(s,e){if(!s||!e)return s;const r=e.replace(/\?\./g,".").split(/\.(?![^\[]*\])/).flatMap(l=>{const c=l.match(/^([^\[]*)((?:\[\d+\])*)$/);if(c){const[,d,f]=c,h=[];d&&h.push(d);const m=f.match(/\[\d+\]/g);return m&&h.push(...m),h}return[l]}).filter(l=>l!=="");let i=s;for(const l of r){if(i==null)return;if(l.startsWith("[")&&l.endsWith("]")){const c=parseInt(l.slice(1,-1),10);i=i[c]}else i=i[l]}return i}const Qy=({isOpen:s,modalId:e,dataSources:n,dataContext:r,globalStateUpdater:i,bindingEngine:l,debug:c=!1,children:d})=>{const[f,h]=N.useState(!1),[m,y]=N.useState(!1),S=N.useRef(!1),v=N.useRef(null);v.current||(v.current=new Tr);const _=N.useCallback(async()=>{if(!(!n||n.length===0)&&v.current){h(!0);try{const x=r.route||{},A=new URLSearchParams(window.location.search),L=n.map(k=>{let O={...k};if(k.endpoint&&l){const P=l.resolveBindings(k.endpoint,r,{skipCache:!0});O.endpoint=P}if(k.params&&l){const P={};Object.entries(k.params).forEach(([G,B])=>{typeof B=="string"?P[G]=l.resolveBindings(B,r,{skipCache:!0}):P[G]=B}),O.params=P}return O});c&&_i.log(`[ModalDataSourceWrapper] Modal "${e}" fetching data sources:`,L.map(k=>({id:k.id,endpoint:k.endpoint})));const $=await v.current.fetchDataSourcesWithResults(L,x,A);i&&$.forEach(k=>{if(k.state==="success"&&k.data!==void 0){const O=L.find(P=>P.id===k.id);if(O?.initGlobal){const P=k.data?.data??k.data,G=Array.isArray(O.initGlobal)?O.initGlobal:[O.initGlobal];for(const B of G)if(typeof B=="string")i({[B]:P}),c&&_i.log(`[ModalDataSourceWrapper] Modal "${e}" initGlobal: ${k.id}.data -> _global.${B}`);else if(typeof B=="object"&&B.key){const{key:W,path:pe}=B,Se=pe?JA(P,pe):P;i({[W]:Se}),c&&_i.log(`Modal "${e}" initGlobal: ${k.id}.data${pe?"."+pe:""} -> _global.${W}`)}}}else k.state==="error"&&_i.error(`Modal "${e}" data source error:`,k.id,k.error)}),c&&_i.log(`Modal "${e}" data sources fetched successfully`)}catch(x){_i.error(`Modal "${e}" data source fetch error:`,x)}finally{h(!1),y(!0)}}},[n,r,i,l,e,c]);return N.useEffect(()=>{if(!n||n.length===0)return;const x=window.__templateApp;return x?.registerModalDataSources&&x.registerModalDataSources(e,n),()=>{x?.unregisterModalDataSources&&x.unregisterModalDataSources(e)}},[e,n]),N.useEffect(()=>{!s&&S.current&&(y(!1),c&&_i.log(`[ModalDataSourceWrapper] Modal "${e}" closed, reset fetch state`)),s&&!S.current&&n&&n.length>0&&!m&&_(),S.current=s},[s,n,m,_,e,c]),ft.jsx(ft.Fragment,{children:d})};class jc extends Error{constructor(n,r,i={}){super(r);M(this,"code");M(this,"userMessageKey");M(this,"showStack");M(this,"icon");M(this,"recoverable");this.name="TemplateEngineError",this.code=n,this.userMessageKey=r,this.showStack=i.showStack??!0,this.icon=i.icon??"fa-circle-exclamation",this.recoverable=i.recoverable??!0,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}getUserMessage(n,r){if(!r||!n)return this.userMessageKey;try{return r.translate(this.userMessageKey,n)}catch{return this.userMessageKey}}}class QA extends jc{constructor(){super("TEMPLATE_NOT_FOUND","$t:core.errors.template_not_found",{showStack:!1,icon:"fa-paint-brush",recoverable:!1}),this.name="TemplateNotFoundError"}}function Zy(s){if(s instanceof jc)return s;if(s instanceof Error){const e=new jc("TEMPLATE_INIT_ERROR",s.message||"$t:core.errors.template_init_error",{showStack:!0,icon:"fa-circle-exclamation",recoverable:!0});return e.stack=s.stack,e}return new jc("TEMPLATE_INIT_ERROR","$t:core.errors.template_init_error",{showStack:!1,icon:"fa-circle-exclamation",recoverable:!0})}const ZA=dt("ErrorDisplay");class Zf{static render(e,n){const r=document.getElementById(e);if(!r){ZA.error(`Container #${e} not found`);return}const i=n.debug&&n.showStack&&n.stackTrace,l=window.matchMedia("(prefers-color-scheme: dark)").matches,c={container:` display: flex; align-items: center; justify-content: center; @@ -227,4 +227,4 @@ Error generating stack: `+u.message+` `:""} - `}static renderFromError(e,n,r,i=!1,l,c,d){let f,h;if(n.userMessageKey.startsWith("$t:"))if(c&&l)try{f=c.translate(n.userMessageKey,l)}catch{f=n.userMessageKey.replace("$t:","")}else f=n.userMessageKey.replace("$t:","");else f=n.userMessageKey;if(d){const m=d;m.details?.apiMessage?h=m.details.apiMessage:m.response?.data?.message&&(h=m.response.data.message)}this.render(e,{title:r,message:f,detailMessage:h,icon:n.icon,showStack:n.showStack,stackTrace:n.stack,showReloadButton:n.recoverable,debug:i})}static escapeHtml(e){if(!e)return"";const n=document.createElement("div");return n.textContent=e,n.innerHTML}}const bs=dt("Router");class ex{constructor(e){M(this,"routes",[]);M(this,"templateIdentifier");M(this,"eventHandlers",new Map);M(this,"pendingNavigation",null);M(this,"isNavigating",!1);M(this,"handlePopState",()=>{this.navigateToCurrentPath()});this.templateIdentifier=e,this.initPopstateListener()}initPopstateListener(){window.addEventListener("popstate",this.handlePopState)}on(e,n){this.eventHandlers.has(e)||this.eventHandlers.set(e,[]),this.eventHandlers.get(e).push(n)}async emit(e,...n){const r=this.eventHandlers.get(e);r&&await Promise.all(r.map(i=>i(...n)))}async loadRoutes(e){try{const n=e!==void 0&&e>0?e:null,r=await fetch(jr(`/api/templates/${this.templateIdentifier}/routes`,"json",n));if(!r.ok)throw new Error(`Failed to load routes: ${r.statusText}`);const i=await r.json();if(!i.success)throw new Error("Failed to load routes from API");if(i.data&&Array.isArray(i.data.routes))this.routes=i.data.routes,bs.log(`Loaded ${this.routes.length} routes${e?` (v=${e})`:""}`);else throw new Error("Invalid routes data format")}catch(n){throw bs.error("Error loading routes:",n),n}}setRoutes(e){this.routes=e,bs.log(`Set ${this.routes.length} routes`)}match(e){const n=this.normalizePathname(e);for(const r of this.routes){const i=this.matchPattern(r.path,n);if(i!==null)return{route:r,params:i}}return null}normalizePathname(e){return e.length>1&&e.endsWith("/")?e.replace(/\/+$/,"")||"/":e}matchPattern(e,n){const r=[];let i=e.replace(/:([^/]+)/g,(f,h)=>(r.push(h),"([^/]+)"));i.startsWith("*/")&&(i="(?:/[^/]+)?"+i.slice(1)),i=i.replace(/\//g,"\\/");const l=new RegExp(`^${i}$`),c=n.match(l);if(!c)return null;const d={};return r.forEach((f,h)=>{d[f]=c[h+1]}),d}getRoutes(){return[...this.routes]}getAuthType(e,n){return e.auth_type?e.auth_type:n.startsWith("/admin")?"admin":"user"}async navigateToCurrentPath(){const e=window.location.pathname,n=window.location.search,r=this.match(e);if(!r){bs.warn(`No route matched for path: ${e}`),this.emit("routeNotFound",e);return}if(r.route.redirect){bs.log(`Redirecting from ${e} to ${r.route.redirect}`),this.navigate(r.route.redirect);return}if(r.route.auth_required){const c=this.getAuthType(r.route,e),d=wr.getInstance();let f=d.isAuthenticated()&&d.getAuthType()===c;if(f||(f=await d.checkAuth(c)),!f){const h=d.getLoginRedirectUrl(c,e+n);bs.log(`Not authenticated, redirecting to: ${h}`),window.location.href=h;return}}const i=new URLSearchParams(n),l={};for(const c of i.keys()){if(c in l)continue;const d=i.getAll(c);d.length>1?l[c]=d:d.length===1&&(c.endsWith("[]")?l[c]=d:l[c]=d[0])}await this.emit("routeChange",{path:e,layout:r.route.layout,endpoint:r.route.endpoint,params:{...r.route.params||{},...r.params},query:l,auth_required:r.route.auth_required,auth_type:r.route.auth_type,meta:r.route.meta})}navigate(e){if(this.isNavigating){this.pendingNavigation=e;return}this.executeNavigation(e)}async executeNavigation(e){this.isNavigating=!0,this.pendingNavigation=null;try{window.history.pushState({},"",e),await this.navigateToCurrentPath()}finally{if(this.isNavigating=!1,this.pendingNavigation){const n=this.pendingNavigation;this.executeNavigation(n)}}}}const tx=/^\/admin\/layout-editor\/([^/?#]+)\/?$/;function eb(s){const e=tx.exec(s);return e?{templateIdentifier:e[1]}:null}const Bt=dt("ErrorPageHandler");class nx{constructor(e){M(this,"templateId");M(this,"layoutLoader");M(this,"locale");M(this,"debug");M(this,"renderFunction");M(this,"dataSourceManager");M(this,"globalState");M(this,"errorConfig",null);M(this,"configLoaded",!1);this.templateId=e.templateId,this.layoutLoader=e.layoutLoader,this.locale=e.locale,this.debug=e.debug,this.renderFunction=e.renderFunction,this.dataSourceManager=e.dataSourceManager,this.globalState=e.globalState||{}}async loadConfig(){if(this.configLoaded)return this.errorConfig;try{const e=await fetch(jr(`/api/templates/${this.templateId}/config`,"json"));if(!e.ok)return this.debug&&Bt.warn("Failed to load template config:",e.statusText),this.configLoaded=!0,null;const n=await e.json();if(!n.success||!n.data)return this.debug&&Bt.warn("Invalid template config response"),this.configLoaded=!0,null;const r=n.data;return!r.error_config||!r.error_config.layouts?(this.debug&&Bt.warn("No error_config found in template.json"),this.configLoaded=!0,null):(this.errorConfig=r.error_config,this.configLoaded=!0,this.debug&&Bt.log("Error config loaded:",this.errorConfig),this.errorConfig)}catch(e){return Bt.error("Failed to load error config:",e),this.configLoaded=!0,null}}async renderError(e,n="app"){try{const r=await this.loadConfig();if(!r)return this.debug&&Bt.warn("No error config available, cannot render error page"),!1;const i=r.layouts[e]||r.layouts[String(e)];if(!i)return this.debug&&Bt.warn(`No layout defined for error code: ${e}`),!1;this.debug&&Bt.log(`Loading error layout: ${i} for code: ${e}`);const l=await this.layoutLoader.loadLayout(this.templateId,i);if(!l)return this.debug&&Bt.error(`Failed to load error layout: ${i}`),!1;this.debug&&Bt.log("Error layout loaded:",l);let c={};const d=l.data_sources||[];if(d.length>0){this.debug&&Bt.log("Fetching data sources:",d.map(v=>v.id));const m=d.filter(v=>v.loading_strategy==="blocking"),y=d.filter(v=>!v.loading_strategy||v.loading_strategy==="progressive"),S=[...m,...y];if(S.length>0)try{c=await this.dataSourceManager.fetchDataSources(S,{},new URLSearchParams),this.debug&&Bt.log("Data sources fetched:",Object.keys(c))}catch(v){Bt.error("Failed to fetch data sources:",v)}}const f={};d.length>0&&(this.processInitOptions(d,c,f),this.debug&&Bt.log("initOptions processed:",{globalKeys:Object.keys(this.globalState),localKeys:Object.keys(f)}));const h={...c,errorCode:e,_global:{...this.globalState},_local:{...f}};return await this.renderFunction({containerId:n,layoutJson:l,dataContext:h,translationContext:{templateId:this.templateId,locale:this.locale}}),this.debug&&Bt.log(`Error page ${e} rendered successfully`),!0}catch(r){return Bt.error(`Failed to render error page ${e}:`,r),!1}}processInitOptions(e,n,r){for(const i of e){const l=n[i.id];if(!l)continue;const c=l?.data??l;if(i.initLocal){if(typeof i.initLocal=="string")r[i.initLocal]=c,Bt.log(`initLocal: ${i.id}.data -> _local.${i.initLocal}`);else if(typeof i.initLocal=="object"&&"key"in i.initLocal){const{key:d,path:f}=i.initLocal;r[d]=f?this.getValueByPath(c,f):c,Bt.log(`initLocal: ${i.id}.data${f?"."+f:""} -> _local.${d}`)}}if(i.initGlobal){const d=Array.isArray(i.initGlobal)?i.initGlobal:[i.initGlobal];for(const f of d)if(typeof f=="string")this.globalState[f]=c,Bt.log(`initGlobal: ${i.id}.data -> _global.${f}`);else if(typeof f=="object"&&f!==null&&"key"in f){const{key:h,path:m}=f;this.globalState[h]=m?this.getValueByPath(c,m):c,Bt.log(`initGlobal: ${i.id}.data${m?"."+m:""} -> _global.${h}`)}}}}getValueByPath(e,n){return n.split(".").reduce((r,i)=>r?.[i],e)}updateGlobalState(e){this.globalState={...this.globalState,...e}}updateLocale(e){this.locale=e,this.debug&&Bt.log("Locale updated:",e)}isConfigLoaded(){return this.configLoaded}async hasErrorLayout(e){const n=await this.loadConfig();return n?!!(n.layouts[e]||n.layouts[String(e)]):!1}clearConfigCache(){this.errorConfig=null,this.configLoaded=!1,this.debug&&Bt.log("Config cache cleared")}}const jc=dt("AssetFailureNotice"),tb="g7-asset-failure-notice",rx="g7-system-banners",qr=new Map;let vs=!1,Hc=!1,zo=null;function Ss(s,e,n){try{const r=window?.G7Core?.t;if(typeof r=="function"){const i=r(s,n);if(typeof i=="string"&&i!==s&&!i.startsWith("core.assets."))return i}}catch{}return ax(e,n)}function ax(s,e){return e?Object.entries(e).reduce((n,[r,i])=>n.split("{"+r+"}").join(String(i)),s):s}function ws(s){!s||!s.id||(qr.set(s.id,s),Hc=!1,jc.warn(`Asset failure notified: ${s.id} (${s.label})`),Cs())}function nb(s){qr.delete(s)&&(jc.log(`Asset failure cleared: ${s}`),Cs())}function rb(){qr.size!==0&&(qr.clear(),Cs())}function ix(){return Array.from(qr.values())}async function ab(){if(vs)return;vs=!0,Hc=!1,Cs();const s=Array.from(qr.values()).filter(n=>typeof n.retry=="function");let e=!1;for(const n of s)try{await n.retry(),qr.delete(n.id)}catch(r){e=!0,jc.warn(`Asset retry failed: ${n.id}`,r)}vs=!1,Hc=e,Cs()}function sx(){try{return document.documentElement.classList.contains("dark")}catch{return!1}}function Cs(){if(typeof document>"u"||!document.body)return;const s=document.getElementById(tb);if(qr.size===0){s?.remove(),hx();return}const e=s??ox();lx(e),e.replaceChildren(cx()),fx()}function ox(){const s=document.createElement("div");return s.id=tb,s.setAttribute("role","alert"),s.setAttribute("aria-live","polite"),document.body.appendChild(s),s}function lx(s){const n=document.getElementById(rx)?.offsetHeight??0;s.style.cssText=["position:fixed",`top:${n}px`,"left:0","right:0","z-index:9998","display:flex","justify-content:center","pointer-events:none"].join(";")}function cx(){const s=sx(),e=Array.from(qr.values()),n=typeof window<"u"&&window.innerWidth<768,r=document.createElement("div");return r.style.cssText=["pointer-events:auto","box-sizing:border-box","width:100%","max-width:960px","margin:8px","padding:12px 16px","border-radius:8px",`border:1px solid ${s?"#78350f":"#fcd34d"}`,`background:${s?"#451a03":"#fffbeb"}`,`color:${s?"#fef3c7":"#78350f"}`,"box-shadow:0 4px 12px rgba(0,0,0,0.12)","font-size:14px","line-height:1.5","display:flex",n?"flex-direction:column":"flex-direction:row",n?"align-items:stretch":"align-items:center","gap:12px"].join(";"),r.style.background=s?"#451a03":"#fffbeb",r.style.color=s?"#fef3c7":"#78350f",r.style.borderColor=s?"#78350f":"#fcd34d",r.appendChild(ux(e,n)),r.appendChild(dx(e,n,s)),r}function ux(s,e){const n=document.createElement("div");n.style.cssText=["flex:1 1 auto","min-width:0","display:flex","gap:8px"].join(";");const r=document.createElement("span");r.setAttribute("aria-hidden","true"),r.textContent="⚠",r.style.cssText="flex:0 0 auto;font-size:16px;line-height:1.4",n.appendChild(r);const i=document.createElement("div");if(i.style.cssText="flex:1 1 auto;min-width:0",s.length===1){const l=s[0],c=document.createElement("div");c.setAttribute("data-asset-failure-id",l.id),c.textContent=l.message??Ss("core.assets.load_failed","{label}을(를) 불러오지 못했습니다.",{label:l.label}),i.appendChild(c)}else{const l=document.createElement("div");l.style.cssText="font-weight:600",l.textContent=Ss("core.assets.load_failed_multiple","{count}개 항목을 불러오지 못했습니다.",{count:s.length}),i.appendChild(l);const c=document.createElement("div");c.style.cssText="margin-top:2px;opacity:0.9;word-break:break-word",c.textContent=s.map(d=>d.label).join(", "),i.appendChild(c)}if(Hc){const l=document.createElement("div");l.style.cssText="margin-top:4px;font-weight:600",l.textContent=Ss("core.assets.retry_failed","다시 시도했지만 실패했습니다. 잠시 후 다시 시도해 주세요."),i.appendChild(l)}return n.appendChild(i),e&&(n.style.alignItems="flex-start"),n}function dx(s,e,n){const r=document.createElement("div");if(r.style.cssText=["flex:0 0 auto","display:flex","gap:8px",e?"width:100%":"","align-items:center"].filter(Boolean).join(";"),s.some(c=>typeof c.retry=="function")){const c=document.createElement("button");c.type="button",c.dataset.action="retry",c.disabled=vs,c.textContent=vs?Ss("core.assets.retrying","다시 시도 중..."):Ss("core.assets.retry","다시 시도"),c.style.cssText=[e?"flex:1 1 auto":"","padding:6px 14px","border-radius:6px","font-size:14px","font-weight:600","cursor:pointer",`border:1px solid ${n?"#b45309":"#d97706"}`,`background:${n?"#b45309":"#f59e0b"}`,`color:${n?"#fffbeb":"#451a03"}`,vs?"opacity:0.6":""].filter(Boolean).join(";"),c.addEventListener("click",()=>{ab()}),r.appendChild(c)}const l=document.createElement("button");return l.type="button",l.dataset.action="close",l.setAttribute("aria-label",Ss("core.assets.close","닫기")),l.textContent="✕",l.style.cssText=["padding:6px 10px","border-radius:6px","font-size:14px","cursor:pointer","border:1px solid transparent","background:transparent",`color:${n?"#fef3c7":"#78350f"}`].join(";"),l.addEventListener("click",()=>{rb()}),r.appendChild(l),r}function fx(){zo||typeof MutationObserver>"u"||(zo=new MutationObserver(()=>{qr.size>0&&Cs()}),zo.observe(document.documentElement,{attributes:!0,attributeFilter:["class"]}))}function hx(){zo?.disconnect(),zo=null}function px(){const s=window,e=r=>({id:String(r?.id??""),label:String(r?.label??r?.url??"asset"),retry:typeof r?.retry=="function"?r.retry:void 0}),n=Array.isArray(s.__g7ExternalAssetFailures)?s.__g7ExternalAssetFailures:[];n.forEach(r=>{r?.id&&ws(e(r))}),s.__g7ExternalAssetSink=r=>{r?.id&&ws(e(r))},jc.log(`템플릿 externals 실패 대기열 ${n.length}건 반영`)}const Rt=dt("ModuleAssetLoader");class gx{constructor(){M(this,"loadedAssets",new Map);M(this,"loadingPromises",new Map);M(this,"failedJsAssets",new Set);M(this,"failedCssAssets",new Set)}getFailedCssAssets(){return[...this.failedCssAssets]}hasFailedJsAssets(){return this.failedJsAssets.size>0}getFailedJsAssets(){return[...this.failedJsAssets]}async loadActiveExtensionAssets(e){if(!e||e.length===0){Rt.log("No module assets to load");return}const n=[...e].sort((d,f)=>d.priority-f.priority);Rt.log("Loading module assets:",n.map(d=>d.identifier));const r=n.filter(d=>d.css).map(d=>this.loadCSS(d.identifier,d.css)),i=n.filter(d=>d.js).map(d=>this.loadJS(d.identifier,d.js)),l=await Promise.allSettled([...r,...i]),c=l.filter(d=>d.status==="rejected");if(c.length>0){Rt.warn(`Some module assets failed to load (${c.length}/${l.length}); continuing with the rest`,this.getFailedJsAssets());return}Rt.log("All module assets loaded successfully")}async loadBundle(e,n,r){const i=[];if(r&&i.push(this.loadBundleCss(e,r)),n&&i.push(this.loadBundleJs(e,n)),i.length===0){Rt.log(`No bundle assets to load for: ${e}`);return}await Promise.all(i)}async loadCustomAssets(){const e=mx();if(e.length!==0)for(const n of e){const r=`g7-custom-${n.type}-${yx(n.id)}`;if(document.getElementById(r))continue;const i=`${n.type==="style"?"custom CSS":"custom JS"}: ${n.id}`,l=(d,f)=>n.type==="style"?yi(Tn(d),{id:r},{label:i,retries:f}):ra(Tn(d),{id:r},{label:i,retries:f}),c=xd(n.url);try{if(c!==null)try{await l(n.url,0)}catch{Rt.warn(`Custom asset static miss, falling back to API: ${n.id} (${n.url} -> ${c})`),await l(c)}else await l(n.url);Rt.log(`Custom asset loaded: ${n.id}`)}catch(d){Rt.warn(`Failed to load custom asset: ${n.id} (${n.url})`,d),ws({id:`custom-asset:${n.id}`,label:n.id.split(":").pop()??n.id,retry:async()=>{document.getElementById(r)?.remove(),await l(c??n.url)}})}}}async loadBundleCss(e,n){const r=`ext-bundle-css-${e}`;if(document.getElementById(r)){Rt.log(`Bundle CSS already loaded: ${e}`);return}const i=xd(n);try{if(i!==null)try{await yi(n,{id:r},{label:`bundle CSS: ${e}`,retries:0})}catch{Rt.warn(`Bundle CSS static miss, falling back to API: ${e} (${n} -> ${i})`),await yi(Tn(i),{id:r},{label:`bundle CSS: ${e}`})}else await yi(n,{id:r},{label:`bundle CSS: ${e}`});Rt.log(`Bundle CSS loaded: ${e}`);const l=document.getElementById(r);l&&this.registerLoadedAsset(`bundle-${e}`,{type:"css",element:l})}catch(l){this.surfaceCssFailure(`bundle-${e}`,e,i!==null?Tn(i):n,l)}}async loadBundleJs(e,n){const r=`ext-bundle-js-${e}`;if(document.getElementById(r)){Rt.log(`Bundle JS already loaded: ${e}`);return}const i=this.loadingPromises.get(r);if(i)return Rt.log(`Bundle JS already loading: ${e}`),i;const l=xd(n),d=(l!==null?ra(n,{id:r},{label:`bundle JS: ${e}`,retries:0}).catch(()=>(Rt.warn(`Bundle JS static miss, falling back to API: ${e} (${n} -> ${l})`),ra(Tn(l),{id:r},{label:`bundle JS: ${e}`}))):ra(n,{id:r},{label:`bundle JS: ${e}`})).then(()=>{Rt.log(`Bundle JS loaded: ${e}`);const f=document.getElementById(r);f&&this.registerLoadedAsset(`bundle-${e}`,{type:"js",element:f}),this.loadingPromises.delete(r)}).catch(f=>{throw Rt.warn(`Failed to load bundle JS: ${e} (${n})`,f),this.failedJsAssets.add(e),this.loadingPromises.delete(r),f});return this.loadingPromises.set(r,d),d}async loadCSS(e,n){const r=`module-css-${e}`;if(document.getElementById(r)){Rt.log(`CSS already loaded: ${e}`);return}try{await yi(n,{id:r},{label:`CSS: ${e}`}),Rt.log(`CSS loaded: ${e}`);const i=document.getElementById(r);i&&this.registerLoadedAsset(e,{type:"css",element:i})}catch(i){this.surfaceCssFailure(e,e,n,i)}}surfaceCssFailure(e,n,r,i){Rt.warn(`Failed to load CSS after retries: ${e} (${r})`,i),this.failedCssAssets.add(e),ws({id:`ext-css:${e}`,label:n,retry:async()=>{document.getElementById(`module-css-${e}`)?.remove(),document.getElementById(`ext-bundle-css-${e.replace(/^bundle-/,"")}`)?.remove(),await yi(r,{},{label:`CSS retry: ${e}`}),this.failedCssAssets.delete(e)}})}async loadJS(e,n){const r=`module-js-${e}`;if(document.getElementById(r)){Rt.log(`JS already loaded: ${e}`);return}const i=this.loadingPromises.get(e);if(i)return Rt.log(`JS already loading: ${e}`),i;const l=ra(n,{id:r},{label:`JS: ${e}`}).then(()=>{Rt.log(`JS loaded: ${e}`);const c=document.getElementById(r);c&&this.registerLoadedAsset(e,{type:"js",element:c}),this.loadingPromises.delete(e)}).catch(c=>{throw Rt.warn(`Failed to load JS: ${e} (${n})`,c),this.failedJsAssets.add(e),this.loadingPromises.delete(e),c});return this.loadingPromises.set(e,l),l}registerLoadedAsset(e,n){const r=this.loadedAssets.get(e)||[];r.push(n),this.loadedAssets.set(e,r)}unloadExtensionAsset(e){const n=this.loadedAssets.get(e);if(!n||n.length===0){Rt.log(`No assets to unload for: ${e}`);return}n.forEach(r=>{r.element.parentNode&&(r.element.parentNode.removeChild(r.element),Rt.log(`${r.type.toUpperCase()} unloaded: ${e}`))}),this.loadedAssets.delete(e),Rt.log(`All assets unloaded for: ${e}`)}unloadAllAssets(){Array.from(this.loadedAssets.keys()).forEach(n=>{this.unloadExtensionAsset(n)}),Rt.log("All module assets unloaded")}isLoaded(e){return this.loadedAssets.has(e)}getLoadedModules(){return Array.from(this.loadedAssets.keys())}}let eh=null;function mx(){const s=window?.G7Config?.customAssets;return Array.isArray(s)?s.filter(e=>e&&typeof e.id=="string"&&typeof e.url=="string"&&(e.type==="style"||e.type==="script")):[]}function yx(s){return s.replace(/[^A-Za-z0-9_-]/g,"-")}function th(){return eh||(eh=new gx),eh}function bx(){if(typeof window>"u")return[];const s=window.G7Config;if(!s?.moduleAssets)return[];const e=[];for(const[n,r]of Object.entries(s.moduleAssets)){const i=r;e.push({identifier:n,js:i.js?Tn(i.js):i.js,css:i.css?Tn(i.css):i.css,priority:i.priority,external:i.external})}return e}function vx(){if(typeof window>"u")return null;const s=window.G7Config;if(!s?.bundleUrls)return null;const e=s.bundleUrls;return{moduleJs:e.moduleJs?Tn(e.moduleJs):e.moduleJs,moduleCss:e.moduleCss?Tn(e.moduleCss):e.moduleCss,pluginJs:e.pluginJs?Tn(e.pluginJs):e.pluginJs,pluginCss:e.pluginCss?Tn(e.pluginCss):e.pluginCss}}function Sx(){if(typeof window>"u")return[];const s=window.G7Config;if(!s?.pluginAssets)return[];const e=[];for(const[n,r]of Object.entries(s.pluginAssets)){const i=r;e.push({identifier:n,js:i.js?Tn(i.js):i.js,css:i.css?Tn(i.css):i.css,priority:i.priority,external:i.external})}return e}const nh=dt("SystemBannerManager");class zc{static show(e){this.banners.set(e.id,e),this.render(),nh.log(`Banner shown: ${e.id}`)}static hide(e){this.banners.delete(e)&&(this.render(),nh.log(`Banner hidden: ${e}`))}static hideAll(){this.banners.clear(),this.render(),nh.log("All banners hidden")}static detectLocale(){try{const n=window.G7Core;if(n?.locale?.current)return n.locale.current()}catch{}return(navigator.language||"ko").split("-")[0]}static resolveMessage(e,n){return typeof e=="string"?e:e[n]||e.en||e.ko||Object.values(e)[0]||""}static render(){if(typeof document>"u")return;let e=document.getElementById(this.containerId);if(this.banners.size===0){e&&(e.remove(),this.adjustAppPadding(0));return}e||(e=document.createElement("div"),e.id=this.containerId,e.style.cssText="position:fixed;top:0;left:0;right:0;z-index:99999;",document.body.prepend(e));const n=Array.from(this.banners.values()).sort((i,l)=>(i.order??0)-(l.order??0)),r=this.detectLocale();e.innerHTML=n.map(i=>{const l=this.resolveMessage(i.message,r),c=i.background||"#f59e0b",d=i.color||"white";return`
${l}
`}).join(""),requestAnimationFrame(()=>{e&&this.adjustAppPadding(e.offsetHeight)})}static adjustAppPadding(e){const n=document.getElementById("app");n&&(n.style.paddingTop=e>0?`${e}px`:"")}}M(zc,"banners",new Map),M(zc,"containerId","g7-system-banners");const U=dt("TemplateApp");function ib(s){const e={};for(const n of s.keys()){if(n in e)continue;const r=s.getAll(n);r.length>1?e[n]=r:r.length===1&&(n.endsWith("[]")?e[n]=r:e[n]=r[0])}return e}const or=class or{constructor(e){M(this,"router",null);M(this,"layoutLoader",null);M(this,"errorPageHandler",null);M(this,"config");M(this,"globalState");M(this,"globalStateListeners",new Set);M(this,"currentRouteChangeId",0);M(this,"failedLayoutScripts",new Set);M(this,"currentDataSources",[]);M(this,"currentRawDataSources",[]);M(this,"currentRouteParams",{});M(this,"currentQueryParams",new URLSearchParams);M(this,"currentFetchedData",{});M(this,"currentLayoutName","");M(this,"templateErrorHandling",null);M(this,"currentWebSocketSubscriptions",[]);M(this,"extensionCacheVersion",0);M(this,"currentGlobalHeaders",[]);M(this,"transitionOverlayEl",null);M(this,"skeletonOverlayRoot",null);M(this,"skeletonOverlayContainer",null);M(this,"_spinnerState",null);M(this,"modalDataSources",new Map);this.globalState={sidebarOpen:!1},this.loadG7Config(),this.migrateLocaleStorage();const n=this.loadLocaleFromStorage(),r=n||e.locale||"ko";this.config={...e,locale:r},!n&&e.locale&&this.saveLocaleToStorage(e.locale)}loadG7Config(){if(typeof window<"u"&&window.G7Config){const e=window.G7Config;e.settings&&(this.globalState.settings=e.settings,U.log("Loaded settings from G7Config:",Object.keys(e.settings)),e.settings.upload&&(this.globalState.uploadSettings=e.settings.upload)),e.plugins&&(this.globalState.plugins=e.plugins,U.log("Loaded plugin settings from G7Config:",Object.keys(e.plugins))),e.modules&&(this.globalState.modules=e.modules,U.log("Loaded module settings from G7Config:",Object.keys(e.modules))),e.appConfig&&(this.globalState.appConfig=e.appConfig,U.log("Loaded appConfig from G7Config:",Object.keys(e.appConfig)))}}resolveRouteExpressions(e){const n=new kn,r={_global:this.globalState};return e.map(i=>{const l={...i};if(l.path&&l.path.includes("{{")){const c=l.path;l.path=n.resolveBindings(l.path,r),l.path=l.path.replace(/\/\/+/g,"/")||"/",l.path.includes("{{")&&(U.warn("Route expression resolution failed, using fallback:",c),l.path=c.replace(/\{\{[^}]+\}\}/g,"").replace(/\/\/+/g,"/")||"/")}if(l.redirect&&l.redirect.includes("{{")){const c=l.redirect;l.redirect=n.resolveBindings(l.redirect,r),l.redirect=l.redirect.replace(/\/\/+/g,"/")||"/",l.redirect.includes("{{")&&(U.warn("Route redirect expression resolution failed:",c),l.redirect=c.replace(/\{\{[^}]+\}\}/g,"").replace(/\/\/+/g,"/")||"/")}return l})}migrateLocaleStorage(){const e=["locale","g7_template_locale"];for(const n of e)try{const r=localStorage.getItem(n);r&&r!==localStorage.getItem(or.LOCALE_STORAGE_KEY)&&(localStorage.setItem(or.LOCALE_STORAGE_KEY,r),U.log(`Migrated locale from '${n}' to '${or.LOCALE_STORAGE_KEY}'`)),localStorage.removeItem(n)}catch(r){U.warn(`Failed to migrate locale key '${n}':`,r)}}async init(){try{co.getInstance().setDebug(this.config.debug),U.log("Initializing with config:",this.config),Kw();const e=br.getInstance(),n=wr.getInstance(),r=typeof window<"u"&&Number(window.G7Config?.cache_version)||0,i=r>0?r:this.loadCacheVersionFromStorage()||0,[l,c,d,f,h]=await Promise.all([Fo({templateId:this.config.templateId,templateType:this.config.templateType,locale:this.config.locale,debug:this.config.debug,cacheVersion:i}),e.loadComponents(this.config.templateId,this.config.templateType,i),Vl(i>0?uo(`templates/${this.config.templateId}/routes.json`,i):null,jr(`/api/templates/${this.config.templateId}/routes`,"json",i>0?i:null),{label:"routes.json"}).then(A=>{if(!A.ok)throw new Error(`Failed to load routes: ${A.statusText}`);return A.json()}).then(A=>{if(!A.success)throw new Error("Failed to load routes from API");return A.data}).catch(A=>{throw U.error("Error loading routes:",A),A}),n.preloadAuth(this.config.templateType==="admin"?"admin":"user"),fetch(jr(`/api/templates/${this.config.templateId}/config`,"json")).then(A=>A.ok?A.json():null).then(A=>!A?.success||!A?.data?null:A.data).catch(A=>(U.warn("Error loading template config:",A),null))]);if(U.log("Template Engine initialized"),U.log("ComponentRegistry loaded"),U.log("Routes data loaded"),U.log("User info preloaded"),U.log("Template config loaded:",h),h?.cache_version!==void 0){const A=i>0?i:null;if(this.extensionCacheVersion=h.cache_version,this.saveCacheVersionToStorage(this.extensionCacheVersion),U.log("Extension cache version:",this.extensionCacheVersion),A!==null&&A!==this.extensionCacheVersion){U.log("Cache version changed, reloading routes...");const L=await Vl(uo(`templates/${this.config.templateId}/routes.json`,this.extensionCacheVersion),jr(`/api/templates/${this.config.templateId}/routes`,"json",this.extensionCacheVersion),{label:"routes.json (reload)"}).then($=>{if(!$.ok)throw new Error(`Failed to reload routes: ${$.statusText}`);return $.json()}).then($=>{if(!$.success)throw new Error("Failed to reload routes from API");return $.data});Array.isArray(L.routes)&&(L.routes=this.resolveRouteExpressions(L.routes),Object.assign(d,L),U.log("Routes reloaded with new cache version"));try{const{TranslationEngine:$}=await Promise.resolve().then(()=>Ug),k=$.getInstance();k.setCacheVersion(this.extensionCacheVersion);const O=this.config.locale||"ko",P="en";await k.loadTranslations(this.config.templateId,O,"/api",!0),O!==P&&await k.loadTranslations(this.config.templateId,P,"/api",!0),U.log("Translations reloaded with new cache version")}catch($){U.error("Failed to reload translations:",$)}}}h?.errorHandling&&(this.templateErrorHandling=h.errorHandling,Er().setTemplateConfig(this.templateErrorHandling),U.log("Template errorHandling registered:",this.templateErrorHandling)),n.on("logout",()=>{U.log("User logged out")}),n.on("authStateChange",A=>{U.log("Auth state changed:",A)}),U.log("AuthManager event handlers registered");const m=zr(),y=this.config.templateType==="admin"?"admin":"user",S=n.getConfig(y);m.setOnUnauthorized(()=>{U.log("Unauthorized - redirecting to login page"),m.removeToken();const A=window.location.pathname+window.location.search,L=n.getLoginRedirectUrl(y,A,"session_expired");window.location.href=L}),U.log("ApiClient onUnauthorized callback registered"),this.layoutLoader=new Vf(e),this.extensionCacheVersion>0&&this.layoutLoader.setCacheVersion(this.extensionCacheVersion),U.log("LayoutLoader initialized:",this.layoutLoader);const v=new Tr({onUnauthorized:()=>{U.warn("Unauthorized request in error page")}});if(this.errorPageHandler=new nx({templateId:this.config.templateId,layoutLoader:this.layoutLoader,locale:this.config.locale,debug:this.config.debug,renderFunction:_s,dataSourceManager:v,globalState:this.globalState}),U.log("ErrorPageHandler initialized with DataSourceManager"),await this.handleServerError()){U.log("Server error handled, skipping normal initialization");return}if(this.router=new ex(this.config.templateId),Array.isArray(d.routes)){const A=this.resolveRouteExpressions(d.routes);this.router.setRoutes(A)}else throw new Error("Invalid routes data format");U.log("Router initialized:",this.router),U.log("Routes set:",this.router.getRoutes());const{getActionDispatcher:_}=await Promise.resolve().then(()=>Gr),x=_();if(x&&(x.setDefaultContext({navigate:A=>this.router?.navigate(A)}),x.setGlobalStateUpdater((A,L)=>this.setGlobalState(A,L)),U.log("Navigate function and setGlobalState injected to ActionDispatcher")),await this.loadExtensionAssets(),this.reinitializeTemplateHandlers(),this.router.on("routeChange",A=>this.handleRouteChange(A)),this.router.on("routeNotFound",A=>this.handleRouteNotFound(A)),typeof window<"u"&&eb(window.location.pathname)){U.log("Layout editor mode detected — skipping router match"),await _s({containerId:"app",layoutJson:{components:[]},dataContext:{},translationContext:{templateId:this.config.templateId,locale:this.config.locale}}),U.log("Template App initialized in layout editor mode");return}this.router.navigateToCurrentPath(),U.log("Template App initialized successfully")}catch(e){U.error("Initialization failed:",e),this.showInitError(e)}}async loadExtensionAssets(){try{const e=th(),n=vx();if(!n){await this.loadExtensionAssetsIndividually(),await e.loadCustomAssets();return}await e.loadBundle("module",n.moduleJs,n.moduleCss),await e.loadBundle("plugin",n.pluginJs,n.pluginCss),await e.loadCustomAssets(),U.log("Extension bundle assets loaded successfully")}catch(e){U.warn("Failed to load extension assets:",e)}}async loadExtensionAssetsIndividually(){const e=th(),n=bx();n.length>0&&(U.log("Loading module assets (individual fallback):",n.map(i=>i.identifier)),await e.loadActiveExtensionAssets(n));const r=Sx();r.length>0&&(U.log("Loading plugin assets (individual fallback):",r.map(i=>i.identifier)),await e.loadActiveExtensionAssets(r))}async handleRouteChange(e){const n=++this.currentRouteChangeId;window.__g7ForcedLocalFields=void 0,window.__g7ActionContext=void 0,window.__g7PendingLocalState=void 0,window.__g7LastSetLocalSnapshot=void 0,window.__g7SetLocalOverrideKeys=void 0,window.__g7SequenceLocalSync=void 0,window.__g7AutoBindingPaths=new Map;try{if(U.log("Route changed:",e,"requestId:",n),!this.layoutLoader)throw new Error("LayoutLoader is not initialized");if(!e.layout)throw new Error("Route layout is not defined");let r=e.layout;const i=r==="__preview__";i&&e.params?.token&&(r=`__preview__/${e.params.token}`);const l=await this.layoutLoader.loadLayout(this.config.templateId,r);if(n!==this.currentRouteChangeId){U.log("Route change cancelled (newer request exists):",n);return}U.log("Layout loaded:",l);const c=Er();l.errorHandling?(c.setLayoutConfig(l.errorHandling),U.log("Layout errorHandling registered:",l.errorHandling)):c.clearLayoutConfig();const d=l.data_sources||[],f=e.query||{},h=new URLSearchParams;for(const[Z,ge]of Object.entries(f))if(Array.isArray(ge))for(const H of ge)h.append(Z,H);else h.set(Z,ge);const m={route:e.params||{},query:f,_global:this.globalState};l.scripts&&Array.isArray(l.scripts)&&await this.loadLayoutScripts(l.scripts,m);const{DataSourceManager:y,getActionDispatcher:S}=await Promise.resolve().then(()=>Gr),v=new y;if(i){const Z=S();Z&&Z.setPreviewMode(!0),this.setGlobalState({__isPreview:!0}),zc.show({id:"preview-mode",message:{ko:"⚠ 미리보기 모드 — 페이지 이동이 비활성화됩니다",en:"⚠ Preview Mode — Navigation is disabled"},background:"linear-gradient(90deg, #f59e0b, #d97706)",color:"white"}),U.log("Preview mode activated")}else{const Z=S();Z?.isPreviewMode()&&(Z.setPreviewMode(!1),zc.hide("preview-mode"))}if(this.currentGlobalHeaders=l.globalHeaders||[],this.currentGlobalHeaders.length>0){v.setGlobalHeaders(this.currentGlobalHeaders);const Z=S();Z&&Z.setGlobalHeaders(this.currentGlobalHeaders),U.log("globalHeaders set:",this.currentGlobalHeaders.map(ge=>ge.pattern))}if(l.named_actions&&Object.keys(l.named_actions).length>0){const Z=S();Z&&Z.setNamedActions(l.named_actions)}const _=v.filterByCondition(d,m);d.length!==_.length&&U.log("Data sources filtered by condition:",{before:d.map(Z=>Z.id),after:_.map(Z=>Z.id)});const x=_.filter(Z=>Z.loading_strategy==="blocking"),A=_.filter(Z=>(Z.loading_strategy||"progressive")!=="blocking"&&Z.type!=="websocket"),L=Array.isArray(l.transition_overlay?.wait_for)?l.transition_overlay.wait_for:[],$=L.length>0&&_.some(Z=>L.includes(Z.id)&&Z.type!=="websocket"&&(Z.loading_strategy||"progressive")!=="background");if((x.length>0||$)&&l.transition_overlay){const Z=typeof l.transition_overlay=="boolean"?{enabled:l.transition_overlay,style:"opaque"}:l.transition_overlay;Z.enabled&&Z.style==="skeleton"&&Z.skeleton?.component&&Z.target?this.renderSkeletonOverlay(Z.target,Z.skeleton,l,Z.fallback_target):Z.enabled&&Z.style==="spinner"&&Z.target&&this.renderSpinnerOverlay(Z.target,Z.spinner,Z.fallback_target)}let k={},O={},P={},G={};this.currentWebSocketSubscriptions.length>0&&(U.log("Unsubscribing previous WebSocket subscriptions:",this.currentWebSocketSubscriptions),v.unsubscribeWebSockets(this.currentWebSocketSubscriptions),this.currentWebSocketSubscriptions=[]),this.currentDataSources=_,this.currentRawDataSources=d,this.currentRouteParams=e.params||{},this.currentQueryParams=h,U.log(`handleRouteChange #${n} - queryObject:`,f),U.log(`handleRouteChange #${n} - queryParams:`,h.toString()),x.length>0&&(U.log("Fetching blocking data sources:",x.map(ge=>ge.id)),(await v.fetchDataSourcesWithResults(x,e.params||{},h)).forEach(ge=>{if(ge.state==="success"&&ge.data!==void 0)k[ge.id]=ge.data;else if(ge.state==="error"&&ge.error){const H=ge.error,T=H.response?.data?.message;O[ge.id]={message:T||ge.error.message,status:H.response?.status||H.status}}}),this.processInitOptions(x,k,P,G),this.currentFetchedData={...k},U.log("Blocking data loaded:",Object.keys(k)),Object.keys(O).length>0&&U.log("Data source errors:",O),Object.keys(P).length>0&&U.log("Local state init (blocking):",Object.keys(P)),Object.keys(G).length>0&&U.log("Isolated state init (blocking):",Object.keys(G)));const B=A.length>0;if(B&&(Ur.setPending(!0),U.log("Transition started before rendering")),n!==this.currentRouteChangeId){U.log("Route change cancelled after blocking data (newer request exists):",n);return}const{getState:W}=await Promise.resolve().then(()=>Gr),pe=W().currentDataContext||{},Se=A.map(Z=>Z.id),we={};if(B){Se.forEach(ge=>{pe[ge]!==void 0?we[ge]=pe[ge]:we[ge]=void 0});const Z=Object.keys(we).filter(ge=>we[ge]!==void 0);Z.length>0&&U.log("Preserving previous progressive data:",Z),U.log("Progressive data sources initialized:",Se)}const Ue=l.defines||{},Fe={...we,...e.params,...k,route:{...e.params||{},path:e.path},query:f,_global:{...this.globalState},_globalSetState:Z=>this.setGlobalState(Z),_dataSourceErrors:Object.keys(O).length>0?O:void 0,_localInit:Object.keys(P).length>0?P:void 0,_isolatedInit:Object.keys(G).length>0?G:void 0,_defines:Object.keys(Ue).length>0?Ue:void 0};if(l.computed&&Object.keys(l.computed).length>0){const Z=this.calculateComputed(l.computed,Fe);Object.keys(Z).length>0&&(Fe._computed=Z,this.globalState._computed=Z,U.log("Computed values calculated:",Object.keys(Z))),Fe._computedDefinitions=l.computed}const qe=l.layout_name||e.layout;this.currentLayoutName!==""&&this.currentLayoutName!==qe&&(U.log("_local reset due to layout change:",{from:this.currentLayoutName,to:qe}),this.globalState._local={},mE()),this.currentLayoutName=qe;const J=l.initLocal||l.state;if(J&&Object.keys(J).length>0){this.globalState._local||(this.globalState._local={});for(const[Z,ge]of Object.entries(J))this.globalState._local[Z]===void 0&&(this.globalState._local[Z]=JSON.parse(JSON.stringify(ge)));Fe._local={...this.globalState._local},U.log("initLocal applied to _local:",Object.keys(J))}if(l.initGlobal&&Object.keys(l.initGlobal).length>0){for(const[Z,ge]of Object.entries(l.initGlobal))this.globalState[Z]===void 0&&(this.globalState[Z]=JSON.parse(JSON.stringify(ge)));U.log("initGlobal applied to _global:",Object.keys(l.initGlobal))}if(l.initIsolated&&Object.keys(l.initIsolated).length>0){for(const[Z,ge]of Object.entries(l.initIsolated))G[Z]===void 0&&(G[Z]=JSON.parse(JSON.stringify(ge)));U.log("initIsolated applied:",Object.keys(l.initIsolated))}Fe._global={...this.globalState,layoutWarnings:l.warnings||[]};const fe=l.initActions||l.init_actions;if(fe&&fe.length>0){await this.executeInitActions(fe,Fe),U.log("initActions executed before render");const Z=this.globalState;if(Z._local){if(Object.keys(P).length>0){for(const[ge,H]of Object.entries(P))Z._local[ge]!==void 0?Z._local[ge]=this.deepMerge(Z._local[ge],H):Z._local[ge]=H;U.log("localInit merged into _local after initActions:",Object.keys(P))}Fe._local=Z._local,U.log("_local merged into dataContext:",Z._local)}if(Fe._global={...this.globalState,layoutWarnings:l.warnings||[]},U.log("_global merged into dataContext after initActions"),l.computed&&Object.keys(l.computed).length>0){const ge=this.calculateComputed(l.computed,Fe);Object.keys(ge).length>0&&(Fe._computed=ge,this.globalState._computed=ge,U.log("Computed values recalculated after init_actions:",Object.keys(ge)))}if(Object.keys(this.currentFetchedData).length>0){for(const[ge,H]of Object.entries(this.currentFetchedData))Fe[ge]=H;U.log("Fetched data sources merged into dataContext after initActions:",Object.keys(this.currentFetchedData))}}if(l.transition_overlay&&!this.skeletonOverlayContainer&&this.showTransitionOverlay(l.transition_overlay,l),await _s({containerId:"app",layoutJson:l,dataContext:Fe,translationContext:{templateId:this.config.templateId,locale:this.config.locale}}),U.log("Initial render complete with blocking data"),this.reattachSpinnerOverlay(),A.length>0){if(n!==this.currentRouteChangeId){U.log("Route change cancelled before progressive fetch (newer request exists):",n),Ur.setPending(!1),this.hideTransitionOverlay();return}U.log("Fetching progressive/background data sources:",A.map(H=>H.id));const{updateTemplateData:Z,getState:ge}=await Promise.resolve().then(()=>Gr);try{const H=A.map(async T=>{try{const de=(await v.fetchDataSourcesWithResults([T],e.params||{},h,this.globalState))[0];if(!de){U.log(`Data source ${T.id} skipped (no fetch result)`);return}if(n!==this.currentRouteChangeId){U.log(`Data source ${T.id} fetch cancelled (newer request exists)`);return}if(de.state==="success"&&de.data!==void 0){U.log(`Progressive data source loaded: ${T.id}`),this.currentFetchedData[T.id]=de.data;const be={};this.processInitOptions([T],{[T.id]:de.data},be);const ie=ge();if(ie.bindingEngine){const _e=[T.id];T.initGlobal&&_e.push("_global"),T.initLocal&&_e.push("_local"),ie.bindingEngine.invalidateCacheByKeys(_e)}const xe={[T.id]:de.data};Object.keys(be).length>0&&(xe._localInit=be,Object.assign(P,be)),T.initGlobal&&(xe._global={...this.globalState}),Z(xe)}else if(de.state==="error"&&de.error){const be=de.error,ie=be.response?.data?.message;O[T.id]={message:ie||de.error.message,status:be.response?.status||be.status},U.log(`Progressive data source error: ${T.id}`,O[T.id]),Z({[T.id]:null,_dataSourceErrors:{...O}})}}catch(ce){U.error(`Failed to fetch data source: ${T.id}`,ce)}});if(await Promise.all(H),n!==this.currentRouteChangeId){U.log("Route change cancelled after progressive fetch (newer request exists):",n);return}U.log("All progressive data sources loaded")}finally{Ur.setPending(!1),this.hideTransitionOverlay()}}else this.hideTransitionOverlay();const Le=_.filter(Z=>Z.type==="websocket");if(Le.length>0){U.log("Subscribing WebSocket data sources:",Le.map(T=>T.id));const{updateTemplateData:Z,getState:ge}=await Promise.resolve().then(()=>Gr),H={...this.currentFetchedData,...e.params,route:{...e.params||{},path:e.path},query:f,_global:{...this.globalState}};U.log("WebSocket binding context keys:",Object.keys(H)),this.currentWebSocketSubscriptions=v.subscribeWebSockets(_,(T,ce)=>{U.log(`WebSocket data received for: ${T}`,ce),this.currentFetchedData[T]=ce;const de=_.find(_e=>_e.id===T),be=ge();if(be.bindingEngine){const _e=[T];de?.initGlobal&&_e.push("_global"),de?.initLocal&&_e.push("_local"),be.bindingEngine.invalidateCacheByKeys(_e)}Z({[T]:ce});const xe=_.find(_e=>_e.type==="websocket"&&(_e.target_source||_e.id)===T)?.onReceive;Array.isArray(xe)&&xe.length>0&&window.G7Core?.dispatch&&(async()=>{for(const Te of xe)try{const Me=this.getActionDispatcher?.();Me&&await Me.dispatchAction(Te,{navigate:this.getRouter?.()?(pt,Ct)=>this.getRouter().navigate(pt,Ct):void 0,setState:pt=>this.setGlobalState(pt),state:this.globalState,data:{...this.globalState,$args:[ce],$event:ce},_isDispatchFallbackContext:!0})}catch(Me){U.error(`WebSocket onReceive action failed for ${T}:`,Me)}})()},H),U.log("WebSocket subscriptions established:",this.currentWebSocketSubscriptions)}U.log("Layout rendered successfully")}catch(r){U.error("Route change handling failed:",r),this.hideTransitionOverlay(),this.showRouteError(r)}}processInitOptions(e,n,r,i){e.some(c=>c.refetchOnMount===!0&&c.initLocal)&&(r._forceLocalInit=Date.now(),U.log("refetchOnMount detected, forcing local state init")),e.forEach(c=>{const d=n[c.id];if(!d)return;const f=d.data??d;if(c.initLocal){if(typeof c.initLocal=="string"){let h=f;if(c.initLocalDefaults&&typeof c.initLocalDefaults=="object"){const y=this.evaluateDefaults(c.initLocalDefaults,n);h={...y,...f},U.log(`initLocalDefaults applied for ${c.initLocal}:`,Object.keys(y))}const m=this.globalState._local?.[c.initLocal];m!==void 0&&typeof m=="object"&&typeof h=="object"?(r[c.initLocal]=this.deepMerge(m,h),U.log(`initLocal (merged): ${c.id}.data -> _local.${c.initLocal}`)):(r[c.initLocal]=h,U.log(`initLocal: ${c.id}.data -> _local.${c.initLocal}`))}else if(typeof c.initLocal=="object"&&c.initLocal.key){const{key:h,path:m}=c.initLocal;let y=m?this.extractValueByPathOrExpression(f,m,c.id):f;if(c.initLocalDefaults&&typeof c.initLocalDefaults=="object"){const v=this.evaluateDefaults(c.initLocalDefaults,n);y={...v,...y},U.log(`initLocalDefaults applied for ${h}:`,Object.keys(v))}const S=this.globalState._local?.[h];S!==void 0&&typeof S=="object"&&typeof y=="object"?(r[h]=this.deepMerge(S,y),U.log(`initLocal (merged): ${c.id}.data${m?"."+m:""} -> _local.${h}`)):(r[h]=y,U.log(`initLocal: ${c.id}.data${m?"."+m:""} -> _local.${h}`))}else if(typeof c.initLocal=="object"){const h=c.initLocal._merge||"deep",m=this.flattenNestedObjectToMappings(c.initLocal);for(const{targetPath:y,sourcePath:S}of m){const v=this.extractValueByPathOrExpression(f,S,c.id);if(y.includes(".")){const _=y.split(".")[0];r[_]===void 0&&this.globalState._local?.[_]!==void 0&&(r[_]=JSON.parse(JSON.stringify(this.globalState._local[_]))),this.setValueAtPath(r,y,v,h),U.log(`initLocal map (${h}): ${c.id} ${S} -> _local.${y}`)}else{const _=this.globalState._local?.[y];h==="replace"?(r[y]=v,U.log(`initLocal map (replace): ${c.id} ${S} -> _local.${y}`)):h==="shallow"?_!==void 0&&typeof _=="object"&&typeof v=="object"?(r[y]={..._,...v},U.log(`initLocal map (shallow): ${c.id} ${S} -> _local.${y}`)):(r[y]=v,U.log(`initLocal map: ${c.id} ${S} -> _local.${y}`)):_!==void 0&&typeof _=="object"&&typeof v=="object"?(r[y]=this.deepMerge(_,v),U.log(`initLocal map (deep): ${c.id} ${S} -> _local.${y}`)):(r[y]=v,U.log(`initLocal map: ${c.id} ${S} -> _local.${y}`))}}}}if(c.initGlobal)if(typeof c.initGlobal=="object"&&!Array.isArray(c.initGlobal)&&!("key"in c.initGlobal))for(const[m,y]of Object.entries(c.initGlobal)){if(typeof y!="string"){U.warn(`initGlobal map value must be string, got ${typeof y} for key ${m}`);continue}const S=this.extractValueByPathOrExpression(f,y,c.id),v=this.globalState[m];v!==void 0&&typeof v=="object"&&typeof S=="object"?(this.globalState[m]=this.deepMerge(v,S),U.log(`initGlobal map (merged): ${c.id} ${y} -> _global.${m}`)):(this.globalState[m]=S,U.log(`initGlobal map: ${c.id} ${y} -> _global.${m}`))}else{const m=Array.isArray(c.initGlobal)?c.initGlobal:[c.initGlobal];for(const y of m)if(typeof y=="string"){const S=this.globalState[y];S!==void 0&&typeof S=="object"&&typeof f=="object"?(this.globalState[y]=this.deepMerge(S,f),U.log(`initGlobal (merged): ${c.id}.data -> _global.${y}`)):(this.globalState[y]=f,U.log(`initGlobal: ${c.id}.data -> _global.${y}`))}else if(typeof y=="object"&&y.key){const{key:S,path:v}=y,_=v?this.extractValueByPathOrExpression(f,v,c.id):f,x=this.globalState[S];x!==void 0&&typeof x=="object"&&typeof _=="object"?(this.globalState[S]=this.deepMerge(x,_),U.log(`initGlobal (merged): ${c.id}.data${v?"."+v:""} -> _global.${S}`)):(this.globalState[S]=_,U.log(`initGlobal: ${c.id}.data${v?"."+v:""} -> _global.${S}`))}}if(i&&c.initIsolated){if(typeof c.initIsolated=="string"){const h=i[c.initIsolated];h!==void 0&&typeof h=="object"&&typeof f=="object"?(i[c.initIsolated]=this.deepMerge(h,f),U.log(`initIsolated (merged): ${c.id}.data -> _isolated.${c.initIsolated}`)):(i[c.initIsolated]=f,U.log(`initIsolated: ${c.id}.data -> _isolated.${c.initIsolated}`))}else if(typeof c.initIsolated=="object"&&c.initIsolated.key){const{key:h,path:m}=c.initIsolated,y=m?this.extractValueByPathOrExpression(f,m,c.id):f,S=i[h];S!==void 0&&typeof S=="object"&&typeof y=="object"?(i[h]=this.deepMerge(S,y),U.log(`initIsolated (merged): ${c.id}.data${m?"."+m:""} -> _isolated.${h}`)):(i[h]=y,U.log(`initIsolated: ${c.id}.data${m?"."+m:""} -> _isolated.${h}`))}else if(typeof c.initIsolated=="object")for(const[h,m]of Object.entries(c.initIsolated)){if(typeof m!="string"){U.warn(`initIsolated map value must be string, got ${typeof m} for key ${h}`);continue}const y=this.extractValueByPathOrExpression(f,m,c.id),S=i[h];S!==void 0&&typeof S=="object"&&typeof y=="object"?(i[h]=this.deepMerge(S,y),U.log(`initIsolated map (merged): ${c.id} ${m} -> _isolated.${h}`)):(i[h]=y,U.log(`initIsolated map: ${c.id} ${m} -> _isolated.${h}`))}}})}evaluateDefaults(e,n){const r={};for(const[i,l]of Object.entries(e))if(typeof l=="string"&&l.startsWith("{{")&&l.endsWith("}}")){const c=l.slice(2,-2).trim();r[i]=this.evaluateExpression(c,n)}else r[i]=l;return r}evaluateExpression(e,n){try{const r=e.split("??").map(i=>i.trim());for(const i of r){if(/^['"].*['"]$/.test(i))return i.slice(1,-1);if(i==="true")return!0;if(i==="false")return!1;if(/^-?\d+(\.\d+)?$/.test(i))return Number(i);const l=this.getNestedValue(n,i);if(l!=null)return l}return}catch(r){U.warn(`Expression evaluation failed: ${e}`,r);return}}getNestedValue(e,n){const r=n.replace(/\?\./g,".");let i=e;const l=r.split(/\.(?![^\[]*\])/).flatMap(c=>{const d=c.match(/^([^\[]*)((?:\[\d+\])*)$/);if(d){const[,f,h]=d,m=[];f&&m.push(f);const y=h.match(/\[\d+\]/g);return y&&m.push(...y),m}return[c]}).filter(c=>c!=="");for(const c of l){if(i==null)return;if(c.startsWith("[")&&c.endsWith("]")){const d=parseInt(c.slice(1,-1),10);i=i[d]}else i=i[c]}return i}extractValueByPathOrExpression(e,n,r){const i=Da(n);if(i!==null){const l=new kn,c={data:e,_global:this.globalState,_local:this.globalState._local||{}};try{const d=Gn(i)?l.evaluatePipeExpression(i,c,{skipCache:!0}):l.evaluateExpression(i,c);return U.log(`initLocal/initGlobal expression evaluated: ${n} -> `,d),d}catch(d){U.warn(`initLocal/initGlobal expression evaluation failed for ${r}:`,n,d);return}}return this.getNestedValue(e,n)}async loadLayoutScripts(e,n){const r=[];for(const i of e){if((i.if!==void 0||i.conditions!==void 0)&&!os({if:i.if,conditions:i.conditions},n,this.bindingEngine,`script:${i.id}`)){U.log(`Script skipped (condition not met): ${i.id}`);continue}if(document.getElementById(i.id)){U.log(`Script already loaded: ${i.id}`);continue}if(!this.isAllowedScriptSrc(i.src)){U.warn(`Blocked untrusted external script src (same-origin path or declared trusted host required): ${i.id} (${i.src})`);continue}r.push(this.loadLayoutScript(i))}r.length>0&&(await Promise.all(r),U.log(`All scripts loaded: ${e.filter(i=>!document.getElementById(i.id)||r.length>0).map(i=>i.id).join(", ")}`))}async loadLayoutScript(e){const n=e.src.startsWith("/")?Tn(e.src):e.src;try{await ra(n,{id:e.id},{label:`layout-script:${e.id}`}),this.failedLayoutScripts.delete(e.id),nb(`layout-script:${e.id}`),U.log(`Script loaded successfully: ${e.id}`)}catch(r){this.failedLayoutScripts.add(e.id),U.warn(`Failed to load script after retries: ${e.id} (${n})`,r),ws({id:`layout-script:${e.id}`,label:e.id,retry:async()=>{document.getElementById(e.id)?.remove(),await ra(n,{id:e.id},{label:`layout-script:${e.id}`}),this.failedLayoutScripts.delete(e.id)}})}}getFailedLayoutScripts(){return Array.from(this.failedLayoutScripts)}isAllowedScriptSrc(e){if(typeof e!="string")return!1;const n=e.trim();if(n==="")return!1;const r=or.normalizeScriptSrcForOriginCheck(n),i=r.startsWith("//"),l=/^[a-z][a-z0-9+.-]*:/i.test(r);if(!i&&!l&&r.startsWith("/"))return!0;const c=this.extractScriptHost(r);return c!==null&&this.getTrustedScriptHosts().includes(c)}static normalizeScriptSrcForOriginCheck(e){return e.replace(/[\t\n\r]/g,"").replace(/\\/g,"/").replace(/^([a-z][a-z0-9+.\-]*:)?\/{2,}/i,"$1//")}extractScriptHost(e){try{const n=e.startsWith("//")?`${window.location.protocol}${e}`:e,r=new URL(n,window.location.origin);return r.protocol!=="http:"&&r.protocol!=="https:"?null:r.hostname.toLowerCase()}catch{return null}}getTrustedScriptHosts(){const e=window.G7Config?.trustedScriptHosts;return Array.isArray(e)?e.map(n=>String(n).toLowerCase()):[]}evaluateScriptCondition(e,n){try{if(e.startsWith("{{")&&e.endsWith("}}")){const r=e.slice(2,-2).trim();return!!Wd(r,n)}return!!e}catch(r){return U.warn(`Failed to evaluate script condition: ${e}`,r),!1}}showInitError(e){if(Fl()){U.warn("Init failed while document is unloading — skipping error screen",e);return}const n=Zy(e);Zf.renderFromError("app",n,"초기화 실패",this.config.debug,{templateId:this.config.templateId,locale:this.config.locale},void 0,e)}showTransitionOverlay(e,n){const r=typeof e=="boolean"?{enabled:e,style:"opaque",target:void 0,skeleton:void 0,spinner:void 0}:{enabled:e.enabled,style:e.style||"opaque",target:e.target,skeleton:e.skeleton,spinner:e.spinner,fallback_target:e.fallback_target};if(!r.enabled)return;if(this.hideTransitionOverlay(),r.style==="skeleton"&&r.skeleton?.component&&r.target&&n){this.renderSkeletonOverlay(r.target,r.skeleton,n,r.fallback_target);return}if(r.style==="spinner"&&r.target){this.renderSpinnerOverlay(r.target,r.spinner,r.fallback_target);return}const i=document.documentElement.classList.contains("dark");let l,c="";switch(r.style){case"blur":l=i?"rgba(17,24,39,0.3)":"rgba(255,255,255,0.3)",c="backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);";break;case"fade":l=i?"rgba(17,24,39,0.8)":"rgba(255,255,255,0.8)";break;case"skeleton":l=i?"rgb(17,24,39)":"rgb(249,250,251)";break;default:l=i?"rgb(17,24,39)":"rgb(249,250,251)";break}if(r.target){const d=`#${CSS.escape(r.target)}`,f=document.createElement("style");f.id="g7-transition-overlay",f.textContent=`${d}{position:relative;z-index:0;}${d}::after{content:'';position:absolute;inset:0;background:${l};${c}z-index:2147483647;pointer-events:none;}`,document.head.appendChild(f),this.transitionOverlayEl=f}else{const d=document.createElement("div");d.id="g7-transition-overlay",d.setAttribute("aria-hidden","true"),d.style.position="fixed",d.style.inset="0",d.style.zIndex="9999",d.style.pointerEvents="none",d.style.background=l;for(const f of c.split(";")){const h=f.indexOf(":");h!==-1&&d.style.setProperty(f.slice(0,h).trim(),f.slice(h+1).trim())}document.body.appendChild(d),this.transitionOverlayEl=d}}hideTransitionOverlay(){this.transitionOverlayEl&&(this.transitionOverlayEl.remove(),this.transitionOverlayEl=null),this.hideSkeletonOverlay()}renderSkeletonOverlay(e,n,r,i){const c=br.getInstance().getComponent(n.component);if(!c){U.log(`Skeleton component "${n.component}" not found in registry, falling back to opaque overlay`),this.showTransitionOverlay({enabled:!0,style:"opaque",target:e});return}let d=document.getElementById(e),f="target";if(!d&&i&&(d=document.getElementById(i),f="fallback"),d||(d=document.getElementById("app"),f="fullpage"),!d){U.log(`Skeleton overlay: no target found (target="#${e}", fallback="${i||"none"}"), falling back to opaque overlay`),this.showTransitionOverlay({enabled:!0,style:"opaque",target:e});return}this.hideSkeletonOverlay();const m=document.documentElement.classList.contains("dark")?"rgb(17,24,39)":"rgb(249,250,251)",y=f==="fullpage"?"app":f==="fallback"?i:e,S=`#${CSS.escape(y)}`,v=document.createElement("style");v.id="g7-skeleton-overlay-style",v.textContent=`${S}{position:relative;z-index:0;}${S}::after{content:'';position:absolute;inset:0;background:${m};z-index:2147483646;pointer-events:none;}`,document.head.appendChild(v),this.transitionOverlayEl=v;const _=document.createElement("div");if(_.id="g7-skeleton-overlay",_.setAttribute("role","status"),_.setAttribute("aria-busy","true"),_.setAttribute("aria-label","Loading..."),f==="fullpage")_.style.cssText=["position:fixed","inset:0","z-index:20","overflow:hidden","pointer-events:none",`background:${m}`].join(";")+";";else{const k=d.getBoundingClientRect(),O=window.scrollX||document.documentElement.scrollLeft,P=window.scrollY||document.documentElement.scrollTop;_.style.cssText=["position:absolute",`top:${k.top+P}px`,`left:${k.left+O}px`,`width:${k.width}px`,`height:${k.height}px`,"z-index:20","overflow:hidden","pointer-events:none",`background:${m}`].join(";")+";"}document.body.appendChild(_),this.skeletonOverlayContainer=_;const x=r.components||[];let A;if(f==="fullpage")A=x;else{const k=f==="fallback"?i:e;A=this.findComponentChildrenById(x,k)}const L=Sd.createRoot(_);this.skeletonOverlayRoot=L,Ma.flushSync(()=>{L.render(Ye.createElement(c,{components:A,options:{animation:n.animation||"pulse",iteration_count:n.iteration_count||5}}))});const $=f==="fullpage"?"fullpage (#app)":f==="fallback"?`fallback (#${i})`:`target (#${e})`;U.log(`Skeleton overlay rendered [${$}] with "${n.component}" (${A.length} components)`)}findComponentChildrenById(e,n){const r=i=>{for(const l of i){if(l.id===n)return l.children||[];if(l.children&&Array.isArray(l.children)){const c=r(l.children);if(c!==null)return c}}return null};return r(e)||e}renderSpinnerOverlay(e,n,r){let i=document.getElementById(e),l="target";if(!i&&r&&(i=document.getElementById(r),l="fallback"),i||(i=document.getElementById("app"),l="fullpage"),!i){U.log(`Spinner overlay: no target found (target="#${e}", fallback="${r||"none"}"), falling back to opaque overlay`),this.showTransitionOverlay({enabled:!0,style:"opaque",target:e});return}this.hideSkeletonOverlay();const c=l==="fullpage"?"app":l==="fallback"?r:e,d=`#${CSS.escape(c)}`,f=document.createElement("style");f.id="g7-skeleton-overlay-style",f.textContent=[`${d}{position:relative;}`,"@keyframes g7-spin{to{transform:rotate(360deg)}}"].join(""),document.head.appendChild(f),this.transitionOverlayEl=f;const h=n?.text||window.G7Core?.t?.("nav.loading")||"";this._spinnerState={target:e,fallbackTarget:r,spinnerConfig:n,resolvedText:h},this._mountSpinnerInTarget(i);const m=l==="fullpage"?"fullpage (#app)":l==="fallback"?`fallback (#${r})`:`target (#${e})`,y=n?.component||"default spinner";U.log(`Spinner overlay rendered [${m}] with "${y}"`)}_mountSpinnerInTarget(e){if(!this._spinnerState)return;const{spinnerConfig:n,resolvedText:r}=this._spinnerState;if(this.skeletonOverlayRoot){try{this.skeletonOverlayRoot.unmount()}catch{}this.skeletonOverlayRoot=null}if(this.skeletonOverlayContainer){try{this.skeletonOverlayContainer.remove()}catch{}this.skeletonOverlayContainer=null}const i=document.createElement("div");if(i.id="g7-skeleton-overlay",i.setAttribute("role","status"),i.setAttribute("aria-busy","true"),e.appendChild(i),this.skeletonOverlayContainer=i,n?.component){const c=br.getInstance().getComponent(n.component);if(c){const d=Sd.createRoot(i);this.skeletonOverlayRoot=d,Ma.flushSync(()=>{d.render(Ye.createElement(c,{options:{text:r}}))});return}U.log(`Spinner component "${n.component}" not found in registry, using default spinner`)}i.innerHTML='
'}reattachSpinnerOverlay(){if(!this._spinnerState)return;const{target:e,fallbackTarget:n}=this._spinnerState;let r=document.getElementById(e);!r&&n&&(r=document.getElementById(n)),r||(r=document.getElementById("app")),r&&(this._mountSpinnerInTarget(r),U.log("Spinner overlay reattached to new DOM target"))}hideSkeletonOverlay(){if(this.skeletonOverlayRoot){try{this.skeletonOverlayRoot.unmount()}catch{}this.skeletonOverlayRoot=null}if(this.skeletonOverlayContainer){try{this.skeletonOverlayContainer.parentNode&&this.skeletonOverlayContainer.remove()}catch{}this.skeletonOverlayContainer=null}const e=document.getElementById("g7-skeleton-overlay-style");e&&e.remove(),this._spinnerState=null}showRouteError(e){if(e instanceof xr&&e.details?.status===401){const r=this.config.templateId||"",i=window.location.pathname,l=r.includes("admin")||i.startsWith("/admin")?"admin":"user",c=i+window.location.search,d=!!zr().getToken()||e.details?.hadToken===!0,f=wr.getInstance().getLoginRedirectUrl(l,c,d?"session_expired":void 0);window.location.href=f;return}const n=Zy(e);Zf.renderFromError("app",n,"페이지 로딩 실패",this.config.debug,{templateId:this.config.templateId,locale:this.config.locale},void 0,e)}async handleServerError(){const e=window.G7Error;if(!e)return!1;U.warn("Server error detected:",e);try{return this.errorPageHandler&&(e.data&&(this.globalState.errorData=e.data),this.errorPageHandler.updateGlobalState(this.globalState),this.errorPageHandler.updateLocale(this.config.locale),await this.errorPageHandler.renderError(e.code,"app"))?(U.log(`${e.code} error page rendered successfully`),!0):(U.log(`Falling back to ErrorDisplay for ${e.code}`),this.showInitError(new Error(`Service unavailable (${e.code})`)),!0)}catch(n){return U.error(`Failed to render ${e.code} page:`,n),this.showInitError(new Error(`Service unavailable (${e.code})`)),!0}}async handleRouteNotFound(e){U.warn("Route not found:",e);try{if(this.errorPageHandler&&(this.errorPageHandler.updateGlobalState(this.globalState),this.errorPageHandler.updateLocale(this.config.locale),await this.errorPageHandler.renderError(404,"app"))){U.log("404 error page rendered successfully");return}U.log("Falling back to ErrorDisplay for 404"),this.showRouteError(new Error(`Page not found: ${e}`))}catch(n){U.error("Failed to render 404 page:",n),this.showRouteError(new Error(`Page not found: ${e}`))}}getRouter(){return this.router}getConfig(){return this.config}getLayoutLoader(){return this.layoutLoader}async reloadExtensionState(){U.log("reloadExtensionState: start");let e;try{const n=await fetch(jr(`/api/templates/${this.config.templateId}/config`,"json",null,`_=${Date.now()}`));if(n.ok){const r=await n.json();r?.success&&r?.data?.cache_version!==void 0&&(e=r.data.cache_version)}}catch(n){U.warn("reloadExtensionState: failed to fetch config.json",n)}e!==void 0&&e!==this.extensionCacheVersion&&(U.log(`reloadExtensionState: cache version ${this.extensionCacheVersion} -> ${e}`),this.extensionCacheVersion=e,this.saveCacheVersionToStorage(e));try{this.router&&(await this.router.loadRoutes(this.extensionCacheVersion),U.log("reloadExtensionState: routes reloaded"))}catch(n){U.error("reloadExtensionState: routes reload failed",n)}try{this.layoutLoader&&(this.extensionCacheVersion>0&&this.layoutLoader.setCacheVersion(this.extensionCacheVersion),this.layoutLoader.clear(),U.log("reloadExtensionState: layout cache cleared"))}catch(n){U.error("reloadExtensionState: layout cache clear failed",n)}try{const{TranslationEngine:n}=await Promise.resolve().then(()=>Ug),r=n.getInstance();this.extensionCacheVersion>0&&r.setCacheVersion(this.extensionCacheVersion);const i=this.config.locale||"ko",l="en";await r.loadTranslations(this.config.templateId,i,"/api",!0),i!==l&&await r.loadTranslations(this.config.templateId,l,"/api",!0),U.log("reloadExtensionState: translations reloaded")}catch(n){U.error("reloadExtensionState: translations reload failed",n)}try{const n=await fetch(`/api/locales/active?_=${Date.now()}`);if(n.ok){const i=(await n.json())?.data?.locales;if(Array.isArray(i)&&i.length>0){const l=this.globalState.appConfig??{};this.setGlobalState({appConfig:{...l,supportedLocales:i}}),U.log("reloadExtensionState: supportedLocales refreshed",i)}}}catch(n){U.warn("reloadExtensionState: supportedLocales refresh failed",n)}U.log("reloadExtensionState: done")}getActionDispatcher(){return sa().actionDispatcher}async changeLocale(e){try{if(U.log("Changing locale to:",e),this.config.locale===e){U.log("Locale is already",e);return}this.config.locale=e,this.saveLocaleToStorage(e),await this.saveLocaleToDatabase(e),this.layoutLoader&&(this.layoutLoader.clear(),U.log("Layout cache cleared")),this.errorPageHandler&&(this.errorPageHandler.updateLocale(e),U.log("ErrorPageHandler locale updated")),Uc(),await Fo({templateId:this.config.templateId,templateType:this.config.templateType,locale:e,debug:this.config.debug,cacheVersion:this.extensionCacheVersion}),U.log("Template Engine re-initialized with new locale");const{getActionDispatcher:n}=await Promise.resolve().then(()=>Gr),r=n();r&&(r.setDefaultContext({navigate:i=>this.router?.navigate(i)}),r.setGlobalStateUpdater((i,l)=>this.setGlobalState(i,l)),U.log("Navigate function and setGlobalState re-injected to ActionDispatcher")),this.reinitializeModuleHandlers(),U.log("Module handlers re-initialized"),this.reinitializeTemplateHandlers(),U.log("Template handlers re-initialized"),this.reinitializePluginHandlers(),U.log("Plugin handlers re-initialized"),this.router&&this.router.navigateToCurrentPath(),U.log("Locale changed successfully to",e)}catch(n){throw U.error("Failed to change locale:",n),n}}loadLocaleFromStorage(){try{return localStorage.getItem(or.LOCALE_STORAGE_KEY)}catch(e){return U.warn("Failed to load locale from storage:",e),null}}saveLocaleToStorage(e){try{localStorage.setItem(or.LOCALE_STORAGE_KEY,e)}catch(n){U.warn("Failed to save locale to storage:",n)}}async saveLocaleToDatabase(e){const n=localStorage.getItem("auth_token");if(!n){U.log("No auth token, skipping DB locale save");return}let r,i;if(this.config.localeApi)r=this.config.localeApi.endpoint,i=this.config.localeApi.method;else{const l=this.config.templateType==="admin";r=l?"/api/admin/users/me/language":"/api/user/profile/update-language",i=l?"PATCH":"POST"}try{const l=this.getXsrfToken(),c=await fetch(r,{method:i,headers:{"Content-Type":"application/json",Accept:"application/json",...l&&{"X-XSRF-TOKEN":l},Authorization:`Bearer ${n}`},credentials:"include",body:JSON.stringify({language:e})});c.ok?U.log("Locale saved to DB:",e):U.warn("Failed to save locale to DB (UI will still change):",c.statusText)}catch(l){U.warn("Failed to call locale API (UI will still change):",l)}}getXsrfToken(){if(typeof document>"u")return null;const n=`; ${document.cookie}`.split("; XSRF-TOKEN=");return n.length===2?decodeURIComponent(n.pop()?.split(";").shift()||""):null}loadCacheVersionFromStorage(){try{const e=localStorage.getItem(or.CACHE_VERSION_STORAGE_KEY);return e?parseInt(e,10):null}catch(e){return U.warn("Failed to load cache version from storage:",e),null}}saveCacheVersionToStorage(e){try{localStorage.setItem(or.CACHE_VERSION_STORAGE_KEY,String(e))}catch(n){U.warn("Failed to save cache version to storage:",n)}}reinitializeModuleHandlers(){if(typeof window>"u")return;const e="__",n=window;Object.keys(n).forEach(r=>{if(r.startsWith(e)&&typeof n[r]?.initModule=="function")try{n[r].initModule(),U.log(`Module handler re-initialized: ${r}`)}catch(i){U.warn(`Failed to re-initialize module handlers for ${r}:`,i)}})}reinitializeTemplateHandlers(){if(typeof window>"u")return;const e=window.G7TemplateHandlers;if(!e){U.warn("Template handlers not found on window.G7TemplateHandlers");return}const n=this.getActionDispatcher();if(!n){U.warn("ActionDispatcher not available for template handler registration");return}Object.entries(e).forEach(([r,i])=>{n.registerHandler(r,i)}),U.log(`${Object.keys(e).length} template handler(s) re-registered:`,Object.keys(e))}reinitializePluginHandlers(){if(typeof window>"u")return;const e="__",n=window;Object.keys(n).forEach(r=>{if(r.startsWith(e)&&typeof n[r]?.initPlugin=="function")try{n[r].initPlugin(),U.log(`Plugin handler re-initialized: ${r}`)}catch(i){U.warn(`Failed to re-initialize plugin handlers for ${r}:`,i)}})}getLocale(){return this.config.locale}getErrorPageHandler(){return this.errorPageHandler}getGlobalState(){return{...this.globalState}}setGlobalState(e,n){const r={...this.globalState};typeof e=="function"?this.globalState=e(this.globalState):this.globalState={...this.globalState,...e},U.log("Global state updated:",this.globalState),window.G7Core?.devTools?.captureStateSnapshot?.({source:"setGlobalState",prev:r,next:this.globalState}),this.globalStateListeners.forEach(l=>{l(this.globalState)}),n?.render!==!1&&Promise.resolve().then(()=>Gr).then(({updateTemplateData:l,getState:c})=>{const d=c();d.reactRoot&&d.currentLayoutJson&&l({_global:{...this.globalState},_local:this.globalState._local||{}})})}onGlobalStateChange(e){this.globalStateListeners.add(e)}offGlobalStateChange(e){this.globalStateListeners.delete(e)}async refetchDataSource(e,n){let r=this.currentDataSources.find(i=>i.id===e);if(!r)for(const[,i]of this.modalDataSources){const l=i.find(c=>c.id===e);if(l){r=l;break}}if(!r){U.warn(`Data source not found: ${e}`);return}U.log(`Refetching data source: ${e}`,n?.sync?"(sync mode)":"",n?.globalStateOverride?"(with global override)":"",n?.localStateOverride?"(with local override)":""),Ur.setPending(!0);try{const i=new Tr;this.currentGlobalHeaders.length>0&&i.setGlobalHeaders(this.currentGlobalHeaders);const l=sa(),c=l.currentDataContext?._global||{},d=n?.globalStateOverride?{...c,...n.globalStateOverride}:c,f=l.currentDataContext?._local||{},h=n?.localStateOverride?{...f,...n.localStateOverride}:f,y=(await i.fetchDataSourcesWithResults([r],this.currentRouteParams,this.currentQueryParams,d,h,{ignoreAutoFetch:!0}))[0];if(y.state==="success"&&y.data!==void 0){this.currentFetchedData[e]=y.data;const S={};this.processInitOptions([r],{[e]:y.data},S);const v=sa();if(v.bindingEngine){const x=[e];r.initGlobal&&x.push("_global"),r.initLocal&&x.push("_local"),v.bindingEngine.invalidateCacheByKeys(x)}const _={[e]:y.data};return Object.keys(S).length>0&&(_._localInit=S),r.initGlobal&&(_._global={...this.globalState}),As(_,n?.sync?{sync:!0}:void 0),U.log(`Data source refetched successfully: ${e}`),y.data}else if(y.state==="error"){U.error(`Failed to refetch data source: ${e}`,y.error);return}}catch(i){U.error(`Error refetching data source: ${e}`,i);return}finally{Ur.setPending(!1)}}registerModalDataSources(e,n){this.modalDataSources.set(e,n),U.log(`Modal data sources registered: ${e} (${n.length} sources)`)}unregisterModalDataSources(e){this.modalDataSources.delete(e),U.log(`Modal data sources unregistered: ${e}`)}getDataSource(e){return this.currentFetchedData[e]}setDataSource(e,n,r){if(!e){U.warn("setDataSource: dataSourceId is required");return}const{merge:i=!1,sync:l=!1}=r||{};i&&this.currentFetchedData[e]?this.currentFetchedData[e]={...this.currentFetchedData[e],...n}:this.currentFetchedData[e]=n,Promise.resolve().then(()=>Gr).then(({updateTemplateData:c})=>{c({[e]:this.currentFetchedData[e]},l?{sync:!0}:void 0)}),U.log(`setDataSource: Updated ${e}`,i?"(merged)":"(replaced)")}updateDataSourceItem(e,n,r,i,l){const{idField:c="id",merge:d=!0,skipRender:f=!1}=l||{},h=this.currentFetchedData[e];if(!h)return U.warn(`updateDataSourceItem: DataSource '${e}' not found`),!1;const m=this.parseItemPath(n);let y=h;for(const _ of m)if(y=y?.[_],y===void 0)return U.warn(`updateDataSourceItem: Path '${n}' not found in dataSource`),!1;if(!Array.isArray(y))return U.warn(`updateDataSourceItem: Target at '${n}' is not an array`),!1;const S=y.findIndex(_=>String(_[c])===String(r));if(S===-1)return U.warn(`updateDataSourceItem: Item with ${c}='${r}' not found`),!1;d?y[S]=this.deepMerge(y[S],i):y[S]={...y[S],...i};const v=window.G7Core?.devTools;return v?.isEnabled?.()&&v.trackDataSourceUpdate?.({dataSourceId:e,updateType:"partial",itemPath:n,itemId:r,updates:i,timestamp:Date.now()}),f||Promise.resolve().then(()=>Gr).then(({updateTemplateData:_})=>{_({[e]:this.currentFetchedData[e]},{sync:!1})}),U.log(`updateDataSourceItem: Updated ${e}.${n}[${c}=${r}]`),!0}parseItemPath(e){const n=[],r=/([^\.\[\]]+)|\[(\d+)\]/g;let i;for(;(i=r.exec(e))!==null;)i[1]!==void 0?n.push(i[1]):i[2]!==void 0&&n.push(parseInt(i[2],10));return n}deepMerge(e,n){if(n==null)return e;if(typeof n!="object"||Array.isArray(n))return n;const r={...e};for(const i of Object.keys(n))typeof n[i]=="object"&&n[i]!==null&&!Array.isArray(n[i])?r[i]=this.deepMerge(r[i]||{},n[i]):r[i]=n[i];return r}setValueAtPath(e,n,r,i="deep"){const l=n.split(".");let c=e;for(let h=0;h0?l.filterByCondition(this.currentRawDataSources,d):this.currentDataSources;this.currentDataSources=f;const h=f.filter(x=>x.auto_fetch!==!1&&x.type!=="websocket");if(h.length===0){U.log("No auto_fetch data sources to refetch");return}U.log(`Refetching ${h.length} auto_fetch data sources`),Ur.setPending(!0);const m=sa().currentLayoutJson,y=m?.transition_overlay,S=Array.isArray(y?.wait_for)?y.wait_for:[],v=h.some(x=>(x.loading_strategy||"progressive")==="blocking"),_=S.length>0&&h.some(x=>S.includes(x.id)&&x.type!=="websocket"&&(x.loading_strategy||"progressive")!=="background");if((v||_)&&y&&typeof y=="object"){const x=n?.transitionOverlayTarget||y.target;y.enabled&&y.style==="skeleton"&&y.skeleton?.component&&x?this.renderSkeletonOverlay(x,y.skeleton,m,y.fallback_target):y.enabled&&y.style==="spinner"&&x&&this.renderSpinnerOverlay(x,y.spinner,y.fallback_target)}try{const x=new Tr;this.currentGlobalHeaders.length>0&&x.setGlobalHeaders(this.currentGlobalHeaders);const A=sa(),L=A.currentDataContext?._global||{},$=await x.fetchDataSourcesWithResults(h,this.currentRouteParams,this.currentQueryParams,L,void 0,{ignoreAutoFetch:!1}),k={},O={},P=new Map(h.map(G=>[G.id,G]));for(const G of $){const B=P.get(G.id);if(!B){U.warn(`Refetch result id not found in autoFetchDataSources: ${G.id}`);continue}const W=G.id;G.state==="success"&&G.data!==void 0?(this.currentFetchedData[W]=G.data,k[W]=G.data,this.processInitOptions([B],{[W]:G.data},O),U.log(`Data source refetched: ${W}`)):G.state==="error"&&U.error(`Failed to refetch data source: ${W}`,G.error)}if(A.bindingEngine){const G=Object.keys(k);G.push("query"),A.bindingEngine.invalidateCacheByKeys(G)}if(Object.keys(O).length>0&&(k._localInit=O),Object.keys(k).length>0){if(k.query=ib(this.currentQueryParams),A.currentLayoutJson?.computed&&Object.keys(A.currentLayoutJson.computed).length>0){const G={...A.currentDataContext,...k,query:k.query},B=this.calculateComputed(A.currentLayoutJson.computed,G);Object.keys(B).length>0&&(k._computed=B,this.globalState._computed=B,U.log("Computed values recalculated in updateQueryParams:",Object.keys(B)))}As(k,{sync:!0}),U.log("Template data updated with new query params")}}catch(x){U.error("Error in updateQueryParams:",x)}finally{Ur.setPending(!1),this.hideTransitionOverlay()}}calculateComputed(e,n){const r={},i=new kn;for(const[l,c]of Object.entries(e))try{let d;if(this.isComputedSwitchDefinition(c))d=i.resolveSwitch(c,n,{skipCache:!0});else if(typeof c=="string")if(c.startsWith("{{")&&c.endsWith("}}")){const f=c.slice(2,-2).trim();d=this.evaluateComputedExpression(f,n)}else d=c;r[l]=d,U.log(`Computed ${l}:`,d)}catch(d){U.warn(`Failed to calculate computed value: ${l}`,d),r[l]=void 0}return r}isComputedSwitchDefinition(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&"$switch"in e&&"$cases"in e}evaluateComputedExpression(e,n){try{return Wd(e,n)}catch(r){U.warn(`Expression evaluation failed: ${e}`,r);return}}async executeInitActions(e,n={}){const{getActionDispatcher:r}=await Promise.resolve().then(()=>Gr),i=r();if(!i){U.warn("ActionDispatcher not available for init_actions");return}U.log("Executing init_actions:",e.map(d=>d.handler)),U.log("Init actions dataContext:",n),U.log("Init actions dataContext._global:",n._global);const l=e.map(d=>d.handler).filter(d=>d.includes("."));l.length>0&&await this.waitForHandlers(i,l);let c={...n};for(const d of e)try{const f={type:"click",handler:d.handler,target:d.target,params:d.params,resultTo:d.resultTo,onSuccess:d.onSuccess,onError:d.onError,if:d.if,conditions:d.conditions,auth_mode:d.auth_mode,auth_required:d.auth_required},h=i.createHandler(f,c),m=new Event("init");await h(m),U.log(`Init action executed: ${d.handler}`);const y=this.globalState;c={...c,_global:{...y},_local:y._local||c._local||{}},U.log(`Data context refreshed after ${d.handler}:`,{cartKey:c._global?.cartKey})}catch(f){U.error(`Failed to execute init action: ${d.handler}`,f)}}async waitForHandlers(e,n,r=5e3){const i=Date.now(),l=50,c=()=>n.every(f=>e.customHandlers?.has(f));if(c()){U.log("All module handlers already registered");return}const d=th().getFailedJsAssets();if(d.length>0){const f=d.some(y=>y==="module"||y==="plugin"),h=n.filter(y=>!e.customHandlers?.has(y)),m=h.length>0&&h.every(y=>d.some(S=>y.startsWith(`${S}.`)));if(f||m){U.warn("Extension asset load failed — not waiting for handlers that will never register:",{pending:h,failedAssets:d});return}}return U.log("Waiting for module handlers:",n),new Promise(f=>{const h=()=>{if(c()){U.log("All module handlers now registered"),f();return}if(Date.now()-i>=r){const m=n.filter(y=>!e.customHandlers?.has(y));U.warn("Timeout waiting for handlers:",m),f();return}setTimeout(h,l)};h()})}};M(or,"LOCALE_STORAGE_KEY","g7_locale"),M(or,"CACHE_VERSION_STORAGE_KEY","g7_cache_version");let Uo=or;function rh(s){const e=new Uo(s);return s.websocket&&(Mc.configure(s.websocket),U.log("WebSocket 설정 완료")),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{e.init(),window.__templateApp=e}):(e.init(),window.__templateApp=e),e}typeof window<"u"&&(window.G7Core=window.G7Core||{},window.G7Core.initTemplateApp=rh,window.G7Core.dataSource={refetch:async(s,e)=>{const n=window.__templateApp;if(!n){U.warn("TemplateApp not initialized (G7Core.dataSource.refetch)");return}return n.refetchDataSource(s,e)},get:s=>{const e=window.__templateApp;if(!e){U.warn("TemplateApp not initialized (G7Core.dataSource.get)");return}return e.getDataSource(s)}});function wx(s={}){const{checked:e,value:n,name:r,type:i="checkbox"}=s,c=n!==void 0?n:i==="checkbox"||i==="radio"?e??!1:String(e??""),d={checked:e??!1,value:c,name:r??"",type:i};return{target:d,currentTarget:d,preventDefault:()=>{},stopPropagation:()=>{},nativeEvent:new Event("change"),bubbles:!0,cancelable:!0,defaultPrevented:!1,eventPhase:Event.AT_TARGET,isTrusted:!1,timeStamp:Date.now(),type:"change",isDefaultPrevented:()=>!1,isPropagationStopped:()=>!1,persist:()=>{}}}function Cx(s={}){const{button:e=0,clientX:n=0,clientY:r=0}=s;return{button:e,clientX:n,clientY:r,preventDefault:()=>{},stopPropagation:()=>{},nativeEvent:new MouseEvent("click"),bubbles:!0,cancelable:!0,defaultPrevented:!1,eventPhase:Event.AT_TARGET,isTrusted:!1,timeStamp:Date.now(),type:"click",isDefaultPrevented:()=>!1,isPropagationStopped:()=>!1,persist:()=>{},target:document.createElement("div"),currentTarget:document.createElement("div")}}function Ex(){return{preventDefault:()=>{},stopPropagation:()=>{},nativeEvent:new Event("submit"),bubbles:!0,cancelable:!0,defaultPrevented:!1,eventPhase:Event.AT_TARGET,isTrusted:!1,timeStamp:Date.now(),type:"submit",isDefaultPrevented:()=>!1,isPropagationStopped:()=>!1,persist:()=>{},target:document.createElement("form"),currentTarget:document.createElement("form")}}function _x(s,e="keydown"){return{key:s,code:s.length===1?`Key${s.toUpperCase()}`:s,preventDefault:()=>{},stopPropagation:()=>{},nativeEvent:new KeyboardEvent(e,{key:s}),bubbles:!0,cancelable:!0,defaultPrevented:!1,eventPhase:Event.AT_TARGET,isTrusted:!1,timeStamp:Date.now(),type:e,isDefaultPrevented:()=>!1,isPropagationStopped:()=>!1,persist:()=>{},target:document.createElement("div"),currentTarget:document.createElement("div"),altKey:!1,ctrlKey:!1,metaKey:!1,shiftKey:!1,repeat:!1}}const Ax={justify:/^justify-(start|end|center|between|around|evenly)$/,items:/^items-(start|end|center|baseline|stretch)$/,content:/^content-(start|end|center|between|around|evenly|stretch)$/,self:/^self-(auto|start|end|center|stretch|baseline)$/,flex:/^flex-(row|row-reverse|col|col-reverse|wrap|wrap-reverse|nowrap|1|auto|initial|none)$/,grow:/^(grow|grow-0)$/,shrink:/^(shrink|shrink-0)$/,basis:/^basis-/,order:/^(order-|-)order-/,gap:/^gap(-x|-y)?-/,gridCols:/^grid-cols-/,gridRows:/^grid-rows-/,colSpan:/^col-(span-|start-|end-)/,rowSpan:/^row-(span-|start-|end-)/,display:/^(block|inline-block|inline|flex|inline-flex|table|inline-table|table-caption|table-cell|table-column|table-column-group|table-footer-group|table-header-group|table-row-group|table-row|flow-root|grid|inline-grid|contents|list-item|hidden)$/,position:/^(static|fixed|absolute|relative|sticky)$/,inset:/^(inset|top|right|bottom|left)-/,zIndex:/^z-/,width:/^w-/,minWidth:/^min-w-/,maxWidth:/^max-w-/,height:/^h-/,minHeight:/^min-h-/,maxHeight:/^max-h-/,padding:/^p[xytblr]?-/,margin:/^-?m[xytblr]?-/,space:/^space-(x|y)-/,fontSize:/^text-(xs|sm|base|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl|8xl|9xl)$/,fontWeight:/^font-(thin|extralight|light|normal|medium|semibold|bold|extrabold|black)$/,fontStyle:/^(italic|not-italic)$/,fontFamily:/^font-(sans|serif|mono)/,textAlign:/^text-(left|center|right|justify|start|end)$/,textColor:/^text-(inherit|current|transparent|black|white|slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-/,textDecoration:/^(underline|overline|line-through|no-underline)$/,textTransform:/^(uppercase|lowercase|capitalize|normal-case)$/,lineHeight:/^leading-/,letterSpacing:/^tracking-/,textOverflow:/^(truncate|text-ellipsis|text-clip)$/,whitespace:/^whitespace-/,wordBreak:/^break-/,bgColor:/^bg-(inherit|current|transparent|black|white|slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-/,bgGradient:/^bg-gradient-/,bgSize:/^bg-(auto|cover|contain)$/,bgPosition:/^bg-(bottom|center|left|left-bottom|left-top|right|right-bottom|right-top|top)$/,bgRepeat:/^bg-(repeat|no-repeat|repeat-x|repeat-y|repeat-round|repeat-space)$/,bgAttachment:/^bg-(fixed|local|scroll)$/,bgClip:/^bg-clip-/,bgOrigin:/^bg-origin-/,borderWidth:/^border(-[xytblr])?(-0|-2|-4|-8)?$/,borderColor:/^border-(inherit|current|transparent|black|white|slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-/,borderStyle:/^border-(solid|dashed|dotted|double|hidden|none)$/,borderRadius:/^rounded(-[tblrse]{1,2})?(-none|-sm|-md|-lg|-xl|-2xl|-3xl|-full)?$/,ringWidth:/^ring(-0|-1|-2|-4|-8|-inset)?$/,ringColor:/^ring-(inherit|current|transparent|black|white|slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-/,ringOffset:/^ring-offset-/,shadow:/^shadow(-sm|-md|-lg|-xl|-2xl|-inner|-none)?$/,opacity:/^opacity-/,mixBlend:/^mix-blend-/,bgBlend:/^bg-blend-/,blur:/^blur(-none|-sm|-md|-lg|-xl|-2xl|-3xl)?$/,brightness:/^brightness-/,contrast:/^contrast-/,grayscale:/^grayscale(-0)?$/,hueRotate:/^-?hue-rotate-/,invert:/^invert(-0)?$/,saturate:/^saturate-/,sepia:/^sepia(-0)?$/,backdropBlur:/^backdrop-blur-/,backdropBrightness:/^backdrop-brightness-/,backdropContrast:/^backdrop-contrast-/,backdropGrayscale:/^backdrop-grayscale-/,backdropHueRotate:/^backdrop-hue-rotate-/,backdropInvert:/^backdrop-invert-/,backdropOpacity:/^backdrop-opacity-/,backdropSaturate:/^backdrop-saturate-/,backdropSepia:/^backdrop-sepia-/,scale:/^scale(-x|-y)?-/,rotate:/^-?rotate-/,translate:/^-?translate-[xy]-/,skew:/^-?skew-[xy]-/,transformOrigin:/^origin-/,transition:/^transition(-none|-all|-colors|-opacity|-shadow|-transform)?$/,duration:/^duration-/,ease:/^ease-(linear|in|out|in-out)$/,delay:/^delay-/,animate:/^animate-/,cursor:/^cursor-/,userSelect:/^select-/,pointerEvents:/^pointer-events-/,resize:/^resize(-none|-x|-y)?$/,scrollBehavior:/^scroll-(auto|smooth)$/,touchAction:/^touch-/,overflow:/^overflow(-x|-y)?-(auto|hidden|clip|visible|scroll)$/,overscroll:/^overscroll(-x|-y)?-(auto|contain|none)$/,visibility:/^(visible|invisible|collapse)$/,aspectRatio:/^aspect-/,columns:/^columns-/,breakAfter:/^break-after-/,breakBefore:/^break-before-/,breakInside:/^break-inside-/,boxDecorationBreak:/^box-decoration-/,boxSizing:/^box-(border|content)$/,float:/^float-(right|left|none)$/,clear:/^clear-(left|right|both|none)$/,isolation:/^(isolate|isolation-auto)$/,objectFit:/^object-(contain|cover|fill|none|scale-down)$/,objectPosition:/^object-/};function sb(s){const e=s.replace(/^(dark:|hover:|focus:|active:|disabled:|group-hover:|sm:|md:|lg:|xl:|2xl:)+/,"");for(const[n,r]of Object.entries(Ax))if(r.test(e))return n;return null}function ob(s){const e=s.match(/^((dark:|hover:|focus:|active:|disabled:|group-hover:|sm:|md:|lg:|xl:|2xl:)+)/);return e?e[1]:""}function xx(s,e){if(!e||e.trim()==="")return s;if(!s||s.trim()==="")return e;const n=s.split(/\s+/).filter(Boolean),r=e.split(/\s+/).filter(Boolean),i=new Map;for(const c of r){const d=sb(c);if(d){const f=ob(c),h=`${d}:${f}`;i.set(h,c)}}return[...n.filter(c=>{const d=sb(c);if(!d)return!0;const f=ob(c),h=`${d}:${f}`;return!i.has(h)}),...r].join(" ")}function Tx(s){return Object.entries(s).filter(([,e])=>e).map(([e])=>e).join(" ")}function kx(...s){return s.filter(e=>typeof e=="string"&&e.length>0).join(" ")}const ye=dt("G7CoreGlobals");function Rx(){window.React=Ye,window.ReactDOM={...wd,createPortal:Ma.createPortal,unstable_batchedUpdates:s=>s()},window.ReactJSXRuntime=uE,ye.log("전역 객체 window.React, window.ReactDOM, window.ReactJSXRuntime에 노출됨")}function Dx(s){const e=new Map,n=Ia.getInstance();s.componentEvent={on:(r,i)=>(e.has(r)||e.set(r,new Set),e.get(r).add(i),n.trackEventSubscribe(r),()=>{e.get(r)?.delete(i),n.trackEventUnsubscribe(r)}),emit:async(r,i)=>{const l=e.get(r),c=l?.size??0;if(!l||l.size===0)return n.trackEventEmit(r,i,0),[];let d,f=[];try{f=await Promise.all(Array.from(l).map(async h=>{try{return await h(i)}catch(m){throw ye.error(`componentEvent: Error in listener for "${r}":`,m),m}}))}catch(h){d=h instanceof Error?h:new Error(String(h))}if(n.trackEventEmit(r,i,c,f,d),d)throw d;return f},off:r=>{e.delete(r),n.trackEventOff(r)},clear:()=>{e.clear(),n.trackEventClear()}},ye.log("전역 객체 window.G7Core.componentEvent에 노출됨")}function Ox(s){s.__runtime||(s.__runtime={DynamicRenderer:Br,ComponentRegistry:br,TranslationEngine:Ra,DataSourceManager:Tr,dataSourceManager:XA,DataBindingEngine:kn,dataBindingEngine:Xd,ActionDispatcher:ko,TranslationReactContext:Kf,TranslationProvider:Oc,useTranslation:Uy,ResponsiveContext:_f,ResponsiveProvider:yc,useResponsive:Af,responsiveManager:Si,BREAKPOINT_PRESETS:Jl,AuthManager:wr,createLogger:dt,G7DevToolsCore:Ia},ye.log("전역 객체 window.G7Core.__runtime(코어 런타임 표면)에 노출됨"))}function Lx(s){if(s.layoutEditor&&s.layoutEditor.__isStub!==!0||s.layoutEditor&&s.layoutEditor.__isStub===!0)return;const e=[],n=[];s.layoutEditor={__isStub:!0,__queue:e,__readyCallbacks:n,registerWidget:(r,i)=>e.push(["widget",r,i]),registerNodeEditor:(r,i)=>e.push(["nodeEditor",r,i]),registerCanvasOverlay:(r,i)=>e.push(["canvasOverlay",r,i]),onReady:r=>{typeof r=="function"&&n.push(r)}},ye.log("전역 객체 window.G7Core.layoutEditor 예약 접수함(stub) 노출됨")}function $x(s){s.asset={template:(e,n,r)=>zw(e,n,r),templateDir:(e,n)=>Uw(e,n),module:(e,n,r)=>Pw(e,n,r),plugin:(e,n,r)=>Bw(e,n,r),convertToCurrentMode:e=>Tn(e),loadScript:(e,n,r)=>ra(e,n,r),loadStylesheet:(e,n,r)=>yi(e,n,r)},s.assets={notifyFailure:ws,clearFailure:nb,clearAll:rb,getFailures:ix,retryAll:ab},px(),ye.log("전역 객체 window.G7Core.asset / window.G7Core.assets 노출됨")}function Mx(s,e){s.useTranslation=Uy,s.t=(n,r)=>{const i=e.getState();if(!i.translationEngine||!i.translationContext)return n;if(r){const l="|"+Object.entries(r).map(([c,d])=>`${c}=${d}`).join("|");return i.translationEngine.translate(n,i.translationContext,l)}return i.translationEngine.translate(n,i.translationContext)},ye.log("전역 객체 window.G7Core.useTranslation에 노출됨")}function Nx(s,e){s.createChangeEvent=wx,s.createClickEvent=Cx,s.createSubmitEvent=Ex,s.createKeyboardEvent=_x,s.uuid=()=>typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const r=Math.random()*16|0;return(n==="x"?r:r&3|8).toString(16)}),s.createLogger=dt,ye.log("전역 객체 window.G7Core.createLogger에 노출됨"),s.renderItemChildren=(n,r,i,l,c)=>{const d=e.getState(),m={_global:window.__templateApp?.getGlobalState?.()||{},_local:r._local||{},_computed:r._computed||{},...r},y=new Set,S=(_,x)=>{const A=m._global?._remountKeys;return _&&A?.[_]&&!y.has(_)?(y.add(_),`${_}-remount-${A[_]}`):_||x},v={translationContext:d.translationContext,translationEngine:d.translationEngine,bindingEngine:d.bindingEngine,actionDispatcher:d.actionDispatcher,getRemountKey:S,...c};return vo(n,m,i,l,v)},s.evaluateCondition=(n,r)=>{if(!n)return!0;const i=e.getState(),c=window.__templateApp?.getGlobalState?.()||{},d={_global:c,_local:c._local||{},_computed:c._computed||{},...r||{}},f=i.bindingEngine??Xd;return em(n,d,f)},s.getComponentMap=()=>br.getInstance().getComponentMap(),s.renderComponentLayout=(n,r,i)=>{if(!n||!Array.isArray(n)||n.length===0)return null;const l=br.getInstance().getComponentMap(),c=e.getState(),f=window.__templateApp?.getGlobalState?.()||{},h={_global:f._global||{},_local:f._local||{},_computed:f._computed||{},...r},m=new Set,y=(S,v)=>{const _=h._global?._remountKeys;return S&&_?.[S]&&!m.has(S)?(m.add(S),`${S}-remount-${_[S]}`):S||v};return vo(n,h,l,i,{translationContext:c.translationContext,translationEngine:c.translationEngine,bindingEngine:c.bindingEngine,actionDispatcher:c.actionDispatcher,getRemountKey:y})},s.renderExpandContent=n=>{const{children:r,row:i,expandContext:l,componentContext:c,keyPrefix:d}=n;if(!r||!Array.isArray(r)||r.length===0)return null;const f=n.componentMap||br.getInstance().getComponentMap(),h=e.getState(),m=s.state?.get?.()||{},y=c?.stateRef?.current??c?.state??{},S={...m._local||{},...y},v=c?.computedRef?.current??m._computed??{},_=h.bindingEngine??s.getDataBindingEngine?.(),x={...m,_local:S,_computed:v,row:i,item:i,$item:i};let A={};if(l&&typeof l=="object"&&_)try{for(const[O,P]of Object.entries(l))if(typeof P=="string"){const G=Da(P);if(G!==null)try{A[O]=Gn(G)?_.evaluatePipeExpression(G,x,{skipCache:!0}):_.evaluateExpression(G,x,{skipCache:!0})}catch{A[O]=void 0}else A[O]=_.resolveBindings(P,x,{skipCache:!0})}else A[O]=P}catch(O){ye.warn("renderExpandContent: expandContext 평가 오류:",O)}const L={row:i,item:i,$item:i,_local:S,_global:m._global||{},_computed:m._computed||{},...A},$=new Set,k=(O,P)=>{const G=L._global?._remountKeys;return O&&G?.[O]&&!$.has(O)?($.add(O),`${O}-remount-${G[O]}`):O||P};return vo(r,L,f,d,{translationContext:h.translationContext,translationEngine:h.translationEngine??void 0,bindingEngine:h.bindingEngine??void 0,actionDispatcher:h.actionDispatcher,componentContext:c,getRemountKey:k})},s.$get=function(r,i,l=void 0){if(r==null)return l;const c=Array.isArray(i)?i:[i];if(c.length===0)return r;let d=r;for(const f of c){if(d==null||f==null)return l;d=d[f]}return d??l},ye.log("전역 객체 window.G7Core.renderItemChildren에 노출됨"),ye.log("전역 객체 window.G7Core.renderComponentLayout에 노출됨"),ye.log("전역 객체 window.G7Core.renderExpandContent에 노출됨"),ye.log("전역 객체 window.G7Core.$get에 노출됨")}function Ix(s){s.dispatch=async(e,n)=>{const r=window.__templateApp;if(!r)return ye.warn("G7Core.dispatch: TemplateApp이 초기화되지 않았습니다."),{success:!1,error:new Error("TemplateApp이 초기화되지 않았습니다.")};const i=r.getActionDispatcher?.();if(!i)return ye.warn("G7Core.dispatch: ActionDispatcher를 찾을 수 없습니다."),{success:!1,error:new Error("ActionDispatcher를 찾을 수 없습니다.")};const l=r.getRouter?.(),c=r.getGlobalState?.(),d=r.setGlobalState?.bind(r),h=n?.componentContext||window.__g7ActionContext,m=window.__g7PendingLocalState;let y=h?.state??c;m&&h&&(y=m,ye.log("[dispatch] Using __g7PendingLocalState for context.state:",m));let S=h?.data??c;m&&h?.data?._local&&(S={...h.data,_local:m},ye.log("[dispatch] Updated context.data._local with pendingLocalState"));const v={navigate:l?(_,x)=>l.navigate(_,x):void 0,setState:h?.setState??d,state:y,data:S,_isDispatchFallbackContext:!h?.setState};if(e.debounce){const _=e.debounceKey||`dispatch-${e.handler}`,x=typeof e.debounce=="number"?e.debounce:e.debounce.delay;return i.debouncedCall(_,x,()=>{const{debounce:A,debounceKey:L,...$}=e;i.dispatchAction($,v)}),{success:!0,debounced:!0}}try{return await i.dispatchAction(e,v)}catch(_){return ye.error("G7Core.dispatch: 액션 실행 오류:",_),{success:!1,error:_ instanceof Error?_:new Error(String(_))}}},ye.log("전역 객체 window.G7Core.dispatch에 노출됨")}function Po(s){const e={};for(const[n,r]of Object.entries(s))if(n.includes(".")){const i=n.split(".");let l=e;for(let c=0;c0&&e.every(n=>/^\d+$/.test(n))}function cb(s,e){const n={...s};for(const r of Object.keys(e))r in n?n[r]!==null&&typeof n[r]=="object"&&!Array.isArray(n[r])&&e[r]!==null&&typeof e[r]=="object"&&!Array.isArray(e[r])&&(n[r]=cb(n[r],e[r])):n[r]=e[r];return n}function sr(s,e){if(Array.isArray(s)&&!Array.isArray(e)&&jx(e)){const r=Object.keys(e).map(l=>parseInt(l,10));if(!((r.length>0?Math.max(...r):0)>=s.length+r.length+10)){const l=[...s];for(const[c,d]of Object.entries(e)){const f=parseInt(c,10);f>=0&&f=l.length&&(l[f]=d)}return l}}const n={...s};for(const[r,i]of Object.entries(e))i!==null&&typeof i=="object"&&!Array.isArray(i)?n[r]!==null&&typeof n[r]=="object"?n[r]=sr(n[r],i):n[r]={...i}:n[r]=i;return n}function Hx(s){s.state={get:()=>window.__templateApp?.getGlobalState?.()||{},set:(e,n)=>{const r=window.__templateApp;if(r?.setGlobalState&&r?.getGlobalState){const i=n?.merge||"deep",l=Po(e);let c;if(i==="replace")c=l;else if(i==="shallow")c={...r.getGlobalState(),...l};else{const d=r.getGlobalState();c=sr(d,l)}r.setGlobalState(c,{render:n?.render})}else ye.warn("G7Core.state.set: TemplateApp이 초기화되지 않았습니다.")},setLocal:(e,n)=>{const r=window.__templateApp;if(n?.render===!1&&!n?.selfManaged){const A=window.__g7AutoBindingPaths;A&&A.size>0&&lb(Po(e)).some($=>A.has($))&&(ye.log("[setLocal] render:false + 자동바인딩 경로 겹침 감지 → render:true 자동 승격 (engine-v1.43.0)"),n={...n,render:!0})}if(n?.debounce){const A=r?.getActionDispatcher?.();if(A){const L=n.debounceKey||`setLocal-${Object.keys(e).join(",")}`,{debounce:$,debounceKey:k,...O}=n;A.debouncedCall(L,n.debounce,()=>{s.state.setLocal(e,O)});return}}const i=n?.scope??"current",l=n?.merge||"deep",c=window.__g7ActionContext,d=Po(e);if(i==="parent"||i==="root"){const A=window.__g7LayoutContextStack||[];if(A.length>0){const L=i==="parent"?A[A.length-1]:A[0];if(L?.setState){L.setState($=>l==="replace"?d:l==="shallow"?{...$||{},...d}:sr($||{},d)),ye.log(`[setLocal] scope=${i}: 타겟 컨텍스트에 상태 업데이트 (mergeMode=${l})`,d);return}}ye.warn(`[setLocal] scope=${i}: 레이아웃 컨텍스트 스택이 비어있습니다. current로 폴백합니다.`)}const f=window.__g7PendingLocalState,h=r?.getGlobalState?.()?._local||{},S=!((window.__g7LayoutContextStack||[]).length>0)&&c?.state?c.state:void 0,v=S?cb(h,S):h,_=f||v;let x;if(l==="replace"?x=d:l==="shallow"?x={..._,...d}:x=sr(_,d),r?.setGlobalState&&(r.setGlobalState({_local:x},{render:n?.render}),ye.log(`[setLocal] globalLocal updated via setGlobalState (mergeMode=${l}, render=${n?.render??!0}):`,d)),window.__g7PendingLocalState=x,ye.log("[setLocal] __g7PendingLocalState updated:",x),window.__g7SequenceLocalSync=x,window.__g7LastSetLocalSnapshot=x,l==="replace")window.__g7ForcedLocalFields=d;else{const A=window.__g7ForcedLocalFields||{};window.__g7ForcedLocalFields=sr(A,d)}if(ye.log("[setLocal] __g7ForcedLocalFields updated:",d),l==="replace")window.__g7SetLocalOverrideKeys=d;else{const A=window.__g7SetLocalOverrideKeys||{};window.__g7SetLocalOverrideKeys=sr(A,d)}ye.log("[setLocal] __g7SetLocalOverrideKeys updated:",d),c?.setState&&c.setState(A=>l==="replace"?d:l==="shallow"?{...A||{},...d}:sr(A||{},d)),r?.setGlobalState||ye.warn("G7Core.state.setLocal: TemplateApp이 없습니다.")},getLocal:()=>{const r=(window.__templateApp?.getGlobalState?.()||{})._local||{},i=window.__g7PendingLocalState;if(i)return sr(r,i);const l=window.__g7LastSetLocalSnapshot;return l&&l!==r?sr(r,l):r},update:e=>{const n=window.__templateApp;if(n?.getGlobalState&&n?.setGlobalState){const r=n.getGlobalState(),i=e(r);n.setGlobalState(i)}else ye.warn("G7Core.state.update: TemplateApp이 초기화되지 않았습니다.")},subscribe:e=>{const n=window.__templateApp;return n?.onGlobalStateChange?n.onGlobalStateChange(e):(ye.warn("G7Core.state.subscribe: TemplateApp이 초기화되지 않았습니다."),()=>{})},getDataSource:e=>window.__templateApp?.getDataSource?.(e),getIsolated:e=>e?window.__g7IsolatedStates?.[e]?.state??null:window.__g7ActionContext?.isolatedContext?.state??null,setIsolated:(e,n,r)=>{let i,l,c;typeof e=="string"?(i=e,l=n||{},c=r):(l=e,c=n&&typeof n=="object"&&"merge"in n?n:r);const d=c?.merge||"deep",f=Po(l);if(i){const y=window.__g7IsolatedStates?.[i];y?.mergeState?y.mergeState(f,d):ye.warn(`G7Core.state.setIsolated: scopeId '${i}'를 찾을 수 없습니다.`);return}const h=window.__g7ActionContext;h?.isolatedContext?.mergeState?h.isolatedContext.mergeState(f,d):ye.warn("G7Core.state.setIsolated: 액션 컨텍스트에 isolatedContext가 없습니다.")},getParent:()=>{const e=window.__g7LayoutContextStack||[];if(e.length===0)return ye.log("[getParent] 레이아웃 컨텍스트 스택이 비어있습니다."),null;const n=e[e.length-1];if(!n)return null;const r=n.dataContext||{};return{_local:n.state||r._local||{},_global:r._global||s.state.get()||{},setState:n.setState}},setParentLocal:(e,n,r)=>{const i=window.__g7LayoutContextStack||[];if(i.length===0){ye.warn("[setParentLocal] 레이아웃 컨텍스트 스택이 비어있습니다.");return}const l=i[i.length-1];if(!l?.setState){ye.warn("[setParentLocal] 부모 컨텍스트에 setState가 없습니다.");return}let c,d;typeof e=="string"?(c={[e]:n},d=r):(c=e,d=n&&typeof n=="object"&&"merge"in n?n:r);const f=d?.merge||"deep",h=Po(c),m=l.state?._local!==void 0,y=m?l.state._local:l.state||{};let S;f==="replace"?S=h:f==="shallow"?S={...y,...h}:S=sr(y,h),window.__g7PendingLocalState=S;const v=window.__templateApp;if(v?.setGlobalState&&v.setGlobalState({_local:S}),l.setState(S),m?l.state._local=S:l.state=S,l.dataContext&&(l.dataContext._local=S),f==="replace")window.__g7ForcedLocalFields=h;else{const _=window.__g7ForcedLocalFields||{};window.__g7ForcedLocalFields=sr(_,h)}wf()},setParentGlobal:(e,n)=>{let r;typeof e=="string"?r={[e]:n}:r=e,s.state.set(r),ye.log("[setParentGlobal] 전역 상태 업데이트:",r)}},window.__g7IsolatedStates||(window.__g7IsolatedStates={}),s.state.getGlobal=s.state.get,s.state.setGlobal=s.state.set,ye.log("전역 객체 window.G7Core.state에 노출됨")}function zx(s){s.dataSource={get:e=>window.__templateApp?.getDataSource?.(e),set:(e,n,r)=>{const i=window.__templateApp;i?.setDataSource?i.setDataSource(e,n,r):ye.warn("G7Core.dataSource.set: TemplateApp이 초기화되지 않았습니다.")},refetch:async(e,n)=>{const r=window.__templateApp;if(r?.refetchDataSource)return r.refetchDataSource(e,n);ye.warn("G7Core.dataSource.refetch: TemplateApp이 초기화되지 않았습니다.")},updateItem:(e,n,r,i,l)=>{const c=window.__templateApp;return c?.updateDataSourceItem?c.updateDataSourceItem(e,n,r,i,l):(ye.warn("G7Core.dataSource.updateItem: TemplateApp이 초기화되지 않았습니다."),!1)},updateData:(e,n,r,i="append")=>{const l=window.__templateApp;if(!l?.getDataSource||!l?.setDataSource)return ye.warn("G7Core.dataSource.updateData: TemplateApp이 초기화되지 않았습니다."),!1;const c=l.getDataSource(e);if(!c)return ye.warn(`G7Core.dataSource.updateData: 데이터 소스 '${e}'를 찾을 수 없습니다.`),!1;let d,f=c,h=null;if(n){const y=n.split(".");h=y.pop();for(const S of y)if(f&&typeof f=="object"&&S in f)f=f[S];else return ye.warn(`G7Core.dataSource.updateData: 경로 '${n}'를 찾을 수 없습니다.`),!1;d=f[h]}else d=c;if(!Array.isArray(d))return ye.warn("G7Core.dataSource.updateData: 대상 경로의 데이터가 배열이 아닙니다."),!1;if(!Array.isArray(r))return ye.warn("G7Core.dataSource.updateData: newData가 배열이 아닙니다."),!1;const m=i==="prepend"?[...r,...d]:[...d,...r];return n&&h?(f[h]=m,l.setDataSource(e,c,{merge:!1})):l.setDataSource(e,m,{merge:!1}),ye.log(`G7Core.dataSource.updateData: '${e}'에 ${r.length}개 항목 ${i==="prepend"?"앞에":"뒤에"} 추가됨`),!0}},ye.log("전역 객체 window.G7Core.dataSource에 노출됨")}function Ux(s,e){s.locale={current:()=>window.__templateApp?.getLocale?.()||"ko",supported:()=>{const r=window.__templateApp?.globalState?.appConfig?.supportedLocales;return Array.isArray(r)&&r.length>0?r:e.getState().templateMetadata?.locales||["ko","en"]},change:async n=>{const r=window.__templateApp;r?.changeLocale?await r.changeLocale(n):ye.warn("G7Core.locale.change: TemplateApp이 초기화되지 않았습니다.")}},ye.log("전역 객체 window.G7Core.locale에 노출됨")}function Px(s){s.toast={show:(e,n)=>{s.dispatch({handler:"toast",params:{message:e,type:n?.type||"info",...n?.duration&&{duration:n.duration}}})},success:(e,n)=>{s.toast.show(e,{type:"success",duration:n})},error:(e,n)=>{s.toast.show(e,{type:"error",duration:n})},warning:(e,n)=>{s.toast.show(e,{type:"warning",duration:n})},info:(e,n)=>{s.toast.show(e,{type:"info",duration:n})}},ye.log("전역 객체 window.G7Core.toast에 노출됨")}function Bx(s){s.modal={open:e=>{s.dispatch({handler:"openModal",target:e})},close:e=>{s.dispatch({handler:"closeModal",...e&&{target:e}})},closeAll:()=>{s.dispatch({handler:"closeAllModals"})},isOpen:e=>{const n=s.state.get();return n._global?.activeModal===e||n._global?.modalStack?.includes(e)||!1},getStack:()=>s.state.get()._global?.modalStack||[]},ye.log("전역 객체 window.G7Core.modal에 노출됨")}function qx(s){s.style={mergeClasses:xx,conditionalClass:Tx,joinClasses:kx},ye.log("전역 객체 window.G7Core.style에 노출됨")}function Gx(s,e){const{webSocketManager:n}=e;s.websocket={manager:n,subscribe:(r,i,l,c)=>n.subscribe(r,i,l,c),unsubscribe:r=>n.unsubscribe(r),leaveChannel:r=>n.leaveChannel(r),disconnect:()=>n.disconnect(),isInitialized:()=>n.isInitialized(),getSubscriptionCount:()=>n.getSubscriptionCount()},ye.log("전역 객체 window.G7Core.websocket에 노출됨")}function Fx(s,e){const{transitionManager:n}=e;s.navigation={isPending:()=>n?.getIsPending?.()||!1,onComplete:r=>{if(!n)return r(),()=>{};let i=n.getIsPending();const l=n.subscribe(c=>{c?i=!0:i&&(r(),l())});return l}},ye.log("전역 객체 window.G7Core.navigation에 노출됨")}function Vx(s){s.plugin={getSettings:e=>window.G7Config?.plugins?.[e],get:(e,n,r)=>window.G7Config?.plugins?.[e]?.[n]??r,getAll:()=>window.G7Config?.plugins??{}},ye.log("전역 객체 window.G7Core.plugin에 노출됨")}function Kx(s){s.module={getSettings:e=>window.G7Config?.modules?.[e],get:(e,n,r)=>window.G7Config?.modules?.[e]?.[n]??r,getAll:()=>window.G7Config?.modules??{}},ye.log("전역 객체 window.G7Core.module에 노출됨")}function Wx(s,e){const{transitionManager:n,responsiveManager:r}=e;s.AuthManager=wr,s.api=zr(),s.TransitionManager=n,s.useTransitionState=Jm,s.ResponsiveManager=r,s.useResponsive=Af,s.useControllableState=EE,s.shallowArrayEqual=_E,s.shallowObjectEqual=Zm,s.updateQueryParams=async(i,l)=>{const c=window.__templateApp;if(c?.updateQueryParams)return c.updateQueryParams(i,l);ye.warn("G7Core.updateQueryParams: TemplateApp이 초기화되지 않았습니다.")},ye.log("전역 객체 window.G7Core.AuthManager에 노출됨"),ye.log("전역 객체 window.G7Core.api에 노출됨"),ye.log("전역 객체 window.G7Core.ResponsiveManager에 노출됨"),ye.log("전역 객체 window.G7Core.useResponsive에 노출됨"),ye.log("전역 객체 window.G7Core.useControllableState에 노출됨"),ye.log("전역 객체 window.G7Core.updateQueryParams에 노출됨")}function Yx(s,e){s.getSlotContext=()=>window.__slotContextValue??null,s.getDynamicRenderer=()=>window.__DynamicRenderer??null,s.getComponentRegistry=()=>e.getComponentRegistry?.()??br.getInstance(),s.getDataBindingEngine=()=>e.getDataBindingEngine?.()??e.getState().bindingEngine,s.getTranslationEngine=()=>e.getTranslationEngine?.()??e.getState().translationEngine,s.getActionDispatcher=()=>e.getActionDispatcher?.()??e.getState().actionDispatcher,ye.log("전역 객체 window.G7Core 슬롯 API에 노출됨 (getSlotContext, getDynamicRenderer 등)")}function Xx(s){s.identity={setLauncher:St.setLauncher.bind(St),handle:St.handle.bind(St),isIdentityRequired:St.isIdentityRequired.bind(St),hasLauncher:St.hasLauncher.bind(St),markDomainNoticeShown:St.markDomainNoticeShown.bind(St),redirectExternally:St.redirectExternally.bind(St),createDeferred:St.createDeferred.bind(St),resolveDeferred:St.resolveDeferred.bind(St),reset:St.reset.bind(St),redirectStashKey:gf},ye.log("전역 객체 window.G7Core 본인인증(IDV) API에 노출됨 (identity)")}function Jx(s){if(typeof window>"u")return;Rx(),window.G7Core||(window.G7Core={});const e=window.G7Core;Ox(e),Dx(e),Lx(e),Wx(e,s),$x(e),Mx(e,s),Nx(e,s),Ix(e),Hx(e),zx(e),Ux(e,s),Px(e),Bx(e),qx(e),Gx(e,s),Fx(e,s),Vx(e),Kx(e),Yx(e,s),Xx(e),ye.log("G7Core 전역 객체 초기화 완료")}function Qx(){const s=window.G7Core;if(!s){ye.warn("G7Core가 초기화되지 않았습니다.");return}const e=()=>Ia.getInstance(),n={isEnabled:()=>{try{return e().isEnabled()}catch{return!1}},trackRender:r=>{try{e().isEnabled()&&e().trackRender(r)}catch{}},trackIteration:(r,i,l,c,d)=>{try{e().isEnabled()&&e().trackIteration(r,{source:i,itemVar:l,indexVar:c,sourceLength:d})}catch{}},trackIfCondition:(r,i,l,c)=>{try{e().isEnabled()&&e().trackIfCondition(r,i,l)}catch{}},trackMount:(r,i)=>{try{e().isEnabled()&&e().trackMount(r,{...i,id:r})}catch{}},trackUnmount:r=>{try{e().isEnabled()&&e().trackUnmount(r)}catch{}},trackExpressionEval:r=>{try{e().isEnabled()&&e().trackExpressionEval(r)}catch{}},trackBindingEval:r=>{try{e().isEnabled()&&e().trackBindingEval(r)}catch{}},recordCacheHit:()=>{try{e().isEnabled()&&e().recordCacheHit()}catch{}},recordCacheMiss:()=>{try{e().isEnabled()&&e().recordCacheMiss()}catch{}},trackHandlerRegistration:(r,i,l,c)=>{try{e().isEnabled()&&e().trackHandlerRegistration(r,i,l,c)}catch{}},trackHandlerUnregistration:r=>{try{e().isEnabled()&&e().trackHandlerUnregistration(r)}catch{}},logAction:r=>{try{e().isEnabled()&&e().logAction(r)}catch{}},trackRequest:(r,i)=>{try{return e().isEnabled()?e().trackRequest(r,i):""}catch{return""}},completeRequest:(r,i,l)=>{try{e().isEnabled()&&e().completeRequest(r,i,l)}catch{}},failRequest:(r,i)=>{try{e().isEnabled()&&e().failRequest(r,i)}catch{}},trackDataSourceDefinition:r=>{try{e().isEnabled()&&e().trackDataSourceDefinition(r)}catch{}},trackDataSourceLoading:r=>{try{e().isEnabled()&&e().trackDataSourceLoading(r)}catch{}},trackDataSourceLoaded:(r,i,l)=>{try{e().isEnabled()&&e().trackDataSourceLoaded(r,i,l)}catch{}},trackDataSourceError:(r,i)=>{try{e().isEnabled()&&e().trackDataSourceError(r,i)}catch{}},trackForm:(r,i,l)=>{try{e().isEnabled()&&e().trackForm(r,i,l)}catch{}},untrackForm:r=>{try{e().isEnabled()&&e().untrackForm(r)}catch{}},startStateChange:(r,i,l,c)=>{try{return e().isEnabled()?e().startStateChange(r,i,l,c):""}catch{return""}},completeStateChange:r=>{try{e().isEnabled()&&e().completeStateChange(r)}catch{}},trackComponentRender:(r,i,l,c,d,f)=>{try{e().isEnabled()&&e().trackComponentRender(r,i,l,c,d,f)}catch{}},updateLocalState:r=>{try{e().isEnabled()&&e().updateLocalState(r)}catch{}},updateComputedState:r=>{try{e().isEnabled()&&e().updateComputedState(r)}catch{}},updateParentContext:r=>{try{e().isEnabled()&&e().updateParentContext(r)}catch{}},trackComponentStateSource:(r,i,l,c)=>{try{e().isEnabled()&&e().trackComponentStateSource(r,i,l,c)}catch{}},trackDynamicState:(r,i)=>{try{e().isEnabled()&&e().trackDynamicState(r,i)}catch{}},trackContextFlow:(r,i,l,c,d,f)=>{try{e().isEnabled()&&e().trackContextFlow(r,i,l,c,d,f)}catch{}},trackComponentStyle:(r,i,l,c)=>{try{e().isEnabled()&&e().trackComponentStyle(r,i,l,c)}catch{}},trackAuthEvent:(r,i,l,c)=>{try{e().isEnabled()&&e().trackAuthEvent(r,i,l,c)}catch{}},trackAuthHeader:(r,i,l,c,d)=>{try{e().isEnabled()&&e().trackAuthHeader(r,i,l,c,d)}catch{}},trackLog:(r,i,l)=>{try{e().isEnabled()&&e().trackLog(r,i,l)}catch{}},trackAction:r=>{try{e().isEnabled()&&e().trackAction?.(r)}catch{}},trackDataSourceUpdate:r=>{try{e().isEnabled()&&e().trackDataSourceUpdate?.(r)}catch{}},startSequenceExecution:r=>{try{return e().isEnabled()?e().startSequenceExecution(r):""}catch{return""}},captureSequenceActionBefore:(r,i,l,c,d)=>{try{e().isEnabled()&&e().captureSequenceActionBefore(r,i,l,c,d)}catch{}},captureSequenceActionAfter:(r,i,l,c,d,f)=>{try{e().isEnabled()&&e().captureSequenceActionAfter(r,i,l,c,d,f)}catch{}},endSequenceExecution:(r,i)=>{try{e().isEnabled()&&e().endSequenceExecution(r,i)}catch{}},registerStateCaptureForHandler:(r,i,l)=>{try{e().isEnabled()&&e().registerStateCaptureForHandler(r,i,l)}catch{}},detectStaleClosure:(r,i,l,c,d)=>{try{return e().isEnabled()?e().detectStaleClosure(r,i,l,c,d):[]}catch{return[]}},trackStaleClosureWarning:r=>{try{e().isEnabled()&&e().trackStaleClosureWarning(r)}catch{}},trackModalOpen:r=>{try{e().isEnabled()&&e().trackModalOpen(r)}catch{}},trackModalClose:(r,i)=>{try{e().isEnabled()&&e().trackModalClose(r,i)}catch{}},trackModalStateChange:r=>{try{e().isEnabled()&&e().trackModalStateChange(r)}catch{}},trackNestedContext:r=>{try{return e().isEnabled()?e().trackNestedContext(r):""}catch{return""}},trackNestedContextAccess:(r,i)=>{try{e().isEnabled()&&e().trackNestedContextAccess(r,i)}catch{}},trackComputedProperty:(r,i,l,c,d,f,h)=>{try{e().isEnabled()&&e().trackComputedProperty(r,i,l,c,d,f,h)}catch{}},trackComputedRecalc:(r,i,l,c,d,f,h)=>{try{e().isEnabled()&&e().trackComputedRecalc(r,i,l,c,d,f,h)}catch{}},setNamedActionDefinitions:r=>{try{e().isEnabled()&&e().setNamedActionDefinitions(r)}catch{}},trackNamedActionRef:r=>{try{e().isEnabled()&&e().trackNamedActionRef(r)}catch{}}};s.devTools=n,ye.log("G7Core.devTools 인터페이스 초기화 완료")}let Bo=null;function Zx(){const s=window.G7Core;return s?.__devtools?Promise.resolve(s.__devtools):Bo||(Bo=new Promise((e,n)=>{const r=window.G7Config?.coreDevToolsAsset||"/build/core/devtools.min.js",i="g7-devtools-bundle",l=()=>{const f=window.G7Core?.__devtools;f?e(f):n(new Error("DevTools 번들 로드됨 — 그러나 __devtools 미노출"))};window.G7Core=window.G7Core||{},window.G7Core.__onDevToolsReady=l;const c=document.getElementById(i);if(c){c.addEventListener("load",l,{once:!0}),c.addEventListener("error",()=>n(new Error(`DevTools 번들 로드 실패: ${r}`)),{once:!0});return}const d=document.createElement("script");d.id=i,d.src=r,d.async=!1,d.addEventListener("load",l,{once:!0}),d.addEventListener("error",()=>{Bo=null,n(new Error(`DevTools 번들 로드 실패: ${r}`))},{once:!0}),document.head.appendChild(d)}),Bo)}function eT(){const s=window.G7Core;if(!s){ye.warn("G7Core가 초기화되지 않았습니다.");return}const e=Ia.getInstance();if(e.initialize(),!e.isEnabled()){window.G7DevTools={isEnabled:()=>!1,enable:()=>{ye.log("환경설정 > 고급 설정 > 디버그 모드를 켜세요")}},Ed(),ye.log("G7DevTools 비활성화됨 (디버그 모드 꺼짐)");return}tT(s,e)}async function tT(s,e){let n;try{n=await Zx()}catch(h){ye.warn("DevTools 번들 로드 실패 — 최소 API 로 폴백:",h),window.G7DevTools={isEnabled:()=>!1,enable:()=>{}},Ed();return}const{DiagnosticEngine:r,getServerConnector:i,getStyleTracker:l}=n;Qx(),Ed();try{l().enable(),ye.log("StyleTracker 활성화됨")}catch(h){ye.warn("StyleTracker 활성화 실패:",h)}const c=new r,d=i(),f={isEnabled:()=>e.isEnabled(),state:{get:()=>e.getState(),getHistory:()=>e.getStateHistory(),watch:(h,m)=>e.watchState(h,m)},actions:{getHistory:()=>e.getActionHistory(),watch:h=>e.watchActions(h),getMetrics:()=>e.getActionMetrics()},binding:{evaluate:h=>{const m=s.getDataBindingEngine?.();if(!m){ye.warn("DataBindingEngine이 없습니다.");return}return m.evaluateExpression(h,e.getState())},getCacheStats:()=>e.getCacheStats(),clearStats:()=>{e.resetCacheStats(),ye.log("캐시 통계 초기화됨")}},diagnose:{analyze:h=>c.analyze(h),suggestFix:h=>c.suggestFix(h),getCommonIssues:()=>c.getCommonIssues(),getRulesByCategory:h=>c.getRulesByCategory(h)},server:{dumpState:h=>d.dumpState(h),sendLog:h=>d.sendLog(h),sendError:(h,m)=>d.sendError(h,m),isConnected:()=>d.isConnected(),testConnection:()=>d.testConnection()},config:{isDebugMode:()=>e.isEnabled(),setLogLevel:h=>e.setLogLevel(h),setMaxHistory:h=>e.setMaxHistory(h)},lifecycle:{getMountedComponents:()=>e.getLifecycleInfo().mountedComponents,getOrphanedListeners:()=>e.getLifecycleInfo().orphanedListeners},performance:{getRenderCount:()=>e.getPerformanceInfo().renderCounts,getBindingEvalCount:()=>e.getPerformanceInfo().bindingEvalCount,getMemoryWarnings:()=>e.getPerformanceInfo().memoryWarnings,startProfiling:()=>e.startProfiling(),stopProfiling:()=>e.stopProfiling()},network:{getActiveRequests:()=>e.getNetworkInfo().activeRequests,getRequestHistory:()=>e.getNetworkInfo().requestHistory,getPendingDataSources:()=>e.getNetworkInfo().pendingDataSources},conditional:{getIfConditions:()=>e.getConditionalInfo().ifConditions,getIterations:()=>e.getConditionalInfo().iterations},form:{getForms:()=>e.getFormInfo()},websocket:{getInfo:()=>e.getWebSocketInfo()}};window.G7DevTools=f,s.devtools=f,ye.log("G7DevTools 전역 객체 초기화 완료 (window.G7DevTools)"),nT(n.DevToolsPanel)}function nT(s){if(document.getElementById("g7-devtools-root")){ye.log("DevToolsPanel 이미 렌더링됨");return}const e=document.createElement("div");e.id="g7-devtools-root",document.body.appendChild(e);try{wd.createRoot(e).render(Ye.createElement(s)),ye.log("DevToolsPanel UI 렌더링 완료")}catch(n){ye.error("DevToolsPanel UI 렌더링 실패:",n)}}const Je=dt("TemplateEngine"),ae={templateId:null,locale:"ko",isInitialized:!1,reactRoot:null,containerId:null,currentLayoutJson:null,currentDataContext:{},translationContext:{templateId:"",locale:"ko"},registry:null,bindingEngine:null,translationEngine:null,actionDispatcher:null,templateMetadata:null};let qo=!1;const Go=[];async function rT(s){try{Je.log("템플릿 메타데이터 로드 중...",s);const e=s.split("-").map(r=>r.split("_").map(i=>i.charAt(0).toUpperCase()+i.slice(1)).join("")).join(""),n=window[e];return n?.templateMetadata?(Je.log("템플릿 메타데이터 로드 완료 (전역 변수)",n.templateMetadata),n.templateMetadata):(Je.warn(`템플릿 번들에 메타데이터가 없습니다. 전역 변수: ${e}`),{identifier:s,locales:["ko","en"],name:{ko:s,en:s},description:{ko:"",en:""},version:"1.0.0",type:"admin"})}catch(e){return Je.error("템플릿 메타데이터 로드 실패",e),{identifier:s,locales:["ko","en"],name:{ko:s,en:s},description:{ko:"",en:""},version:"1.0.0",type:"admin"}}}function ub(){const e=(typeof window<"u"?window.__templateApp:void 0)?.globalState?.appConfig?.supportedLocales,n=ae.templateMetadata?.locales;return{$locale:ae.locale,$locales:Array.isArray(e)&&e.length>0?e:n||["ko","en"],$templateLocales:n||["ko","en"],$templateId:ae.templateId}}async function Fo(s){try{if(Je.log("템플릿 엔진 초기화 시작",s),ae.isInitialized)throw new Error("템플릿 엔진이 이미 초기화되었습니다. destroyTemplate()을 먼저 호출하세요.");if(!s.templateId)throw new QA;qo=s.debug??!1,typeof window<"u"&&(window.G7Config||(window.G7Config={}),window.G7Config.debug=qo),eT(),ae.templateId=s.templateId,ae.locale=s.locale||"ko",Je.log("엔진 인스턴스 생성 중..."),ae.registry=br.getInstance(),ae.bindingEngine=new kn,ae.translationEngine=Ra.getInstance(),s.cacheVersion!==void 0&&s.cacheVersion>0&&ae.translationEngine.setCacheVersion(s.cacheVersion),ae.translationContext={templateId:s.templateId,locale:ae.locale},ae.actionDispatcher=new ko({},ae.translationEngine,ae.translationContext),pE(ae.actionDispatcher),Je.log("다국어 파일 로드 중...",s.templateId,ae.locale);const e="en",n=[ae.translationEngine.loadTranslations(s.templateId,ae.locale).then(()=>{Je.log(`다국어 파일 로드 완료: ${ae.locale}`)}).catch(r=>{Je.warn(`다국어 파일 로드 실패 (${ae.locale}):`,r instanceof Error?r.message:r)})];ae.locale!==e&&n.push(ae.translationEngine.loadTranslations(s.templateId,e).then(()=>{Je.log(`폴백 다국어 파일 로드 완료: ${e}`)}).catch(r=>{Je.warn(`폴백 다국어 파일 로드 실패 (${e}):`,r instanceof Error?r.message:r)})),await Promise.allSettled(n),Je.log("템플릿 메타데이터 로드 중...",s.templateId),ae.templateMetadata=await rT(s.templateId),ae.isInitialized=!0,Je.log("템플릿 엔진 초기화 완료 (ComponentRegistry는 별도 로드)")}catch(e){throw Je.error("템플릿 엔진 초기화 실패",e),ae.isInitialized=!1,ae.registry=null,ae.bindingEngine=null,ae.translationEngine=null,ae.actionDispatcher=null,e}}let Es=null;const db="g7-layout-editor-bundle";function ah(){const s=window.G7Core;return s?.__LayoutEditorChrome?Promise.resolve(s.__LayoutEditorChrome):Es||(Es=(async()=>{const e=window.G7Config?.coreEditorAsset||"/build/core/layout-editor.min.js";document.getElementById(db)?.remove(),window.G7Core=window.G7Core||{},window.G7Core.__onChromeReady=()=>{};try{await ra(e,{id:db},{label:"layout-editor bundle"})}catch(r){throw Es=null,Je.error(`편집기 번들 로드 실패 (${e})`,r),new Error("편집기를 불러오지 못했습니다. 네트워크 상태를 확인한 뒤 다시 시도해 주세요.")}const n=window.G7Core?.__LayoutEditorChrome;if(!n)throw Es=null,Je.error(`편집기 번들 로드됨 — 그러나 __LayoutEditorChrome 미노출 (${e})`),new Error("편집기를 불러왔으나 초기화하지 못했습니다. 페이지를 새로고침해 주세요.");return n})(),Es)}async function _s(s){try{if(Je.log("템플릿 렌더링 시작",s),!ae.isInitialized)throw new Error("템플릿 엔진이 초기화되지 않았습니다. initTemplateEngine()을 먼저 호출하세요.");if(!s.containerId)throw new Error("containerId는 필수입니다.");if(!s.layoutJson)throw new Error("layoutJson은 필수입니다.");const e=document.getElementById(s.containerId);if(!e)throw new Error(`컨테이너를 찾을 수 없습니다: #${s.containerId}`);const n=ub();if(ae.containerId=s.containerId,ae.currentLayoutJson=s.layoutJson,ae.currentDataContext={...n,...s.dataContext||{}},ae.translationContext=s.translationContext||{templateId:ae.templateId||"",locale:ae.locale},ae.reactRoot||(Je.log("React Root 생성"),ae.reactRoot=wd.createRoot(e)),typeof window<"u"){const l=eb(window.location.pathname);if(l){Je.log("레이아웃 편집기 모드 진입",l);let c;try{c=await ah()}catch(f){Je.error("레이아웃 편집기 번들 로드 실패",f),Zf.render(s.containerId,{title:"레이아웃 편집기 로드 실패",message:f instanceof Error?f.message:"편집기 번들을 불러오지 못했습니다.",icon:"fas fa-triangle-exclamation",showStack:!1,showReloadButton:!0,debug:qo});return}const d=Ye.createElement(c,{templateIdentifier:l.templateIdentifier,initialLocale:ae.locale});ae.reactRoot.render(Ye.createElement(Oc,{translationEngine:ae.translationEngine,translationContext:ae.translationContext,children:Ye.createElement(Cf,{children:Ye.createElement(yc,{children:Ye.createElement(Wf,{children:d})})})}));return}}const r=s.layoutJson.components||[];if(r.length===0){Je.warn("렌더링할 컴포넌트가 없습니다.");return}const i=s.layoutJson.modals||[];if(Je.log("modals 배열:",i),Je.log("modals 개수:",i.length),Je.log("DynamicRenderer로 렌더링 시작"),ae.reactRoot.render(Ye.createElement(Oc,{translationEngine:ae.translationEngine,translationContext:ae.translationContext},Ye.createElement(Cf,null,Ye.createElement(yc,null,Ye.createElement(Wf,null,[...r.map((l,c)=>{const d=ae.currentLayoutJson?.layout_name||"";return Ye.createElement(Br,{key:d&&!l._fromBase?`${l.id}_${d}`:l.id,componentDef:l,dataContext:ae.currentDataContext,translationContext:ae.translationContext,registry:ae.registry,bindingEngine:ae.bindingEngine,translationEngine:ae.translationEngine,actionDispatcher:ae.actionDispatcher,isRootRenderer:c===0,layoutKey:d})}),Ye.createElement(Fm,{key:"__modal_parent_context_provider"},i.map(l=>{const c=ae.currentDataContext._global?.modalStack||[],f=c.includes(l.id)||ae.currentDataContext._global?.activeModal===l.id,h=c.indexOf(l.id),m=h>=0?50+h:50,y=window.__g7LayoutContextStack||[],v=y[y.length-1]?.dataContext,_=Ye.createElement(Br,{key:`modal_${l.id}_renderer`,componentDef:{...l,props:{...l.props,isOpen:f,style:{...l.props?.style,zIndex:m},onClose:ae.actionDispatcher?.createHandler({type:"click",handler:"closeModal"},ae.currentDataContext)}},dataContext:ae.currentDataContext,translationContext:ae.translationContext,registry:ae.registry,bindingEngine:ae.bindingEngine,translationEngine:ae.translationEngine,actionDispatcher:ae.actionDispatcher,parentDataContext:v});return l.data_sources&&l.data_sources.length>0?Ye.createElement(Qy,{key:`modal_${l.id}`,isOpen:f,modalId:l.id,dataSources:l.data_sources,dataContext:ae.currentDataContext,globalStateUpdater:ae.actionDispatcher?.getGlobalStateUpdater(),bindingEngine:ae.bindingEngine,debug:qo,children:_}):_}))]))))),Je.log("템플릿 렌더링 완료"),Go.length>0){Je.log(`대기 중인 데이터 업데이트 ${Go.length}건 적용`);const l=[...Go];Go.length=0;for(const{data:c,options:d}of l)As(c,d)}}catch(e){throw Je.error("템플릿 렌더링 실패",e),e}}function As(s,e){try{if(Je.log("템플릿 데이터 업데이트 시작",Object.keys(s)),!ae.isInitialized)throw new Error("템플릿 엔진이 초기화되지 않았습니다.");if(!ae.reactRoot||!ae.currentLayoutJson){Je.log("React 미준비 - 데이터 업데이트 큐잉:",Object.keys(s)),Go.push({data:s,options:e});return}const n=ub(),r={...ae.currentDataContext._global||{},...s._global||{}},i=wE(ae.currentDataContext._localInit,s._localInit);ae.currentDataContext={...n,...ae.currentDataContext,...s,_global:r,_localInit:i},r._local!==void 0&&(ae.currentDataContext._local=r._local),r._computed!==void 0&&(ae.currentDataContext._computed=r._computed);const l=ae.currentLayoutJson.components||[],c=ae.currentLayoutJson.modals||[];Je.log("updateTemplateData - modals 배열:",c),Je.log("updateTemplateData - modals 개수:",c.length),Je.log("updateTemplateData - activeModal:",ae.currentDataContext._global?.activeModal);const d=()=>{ae.reactRoot.render(Ye.createElement(Oc,{translationEngine:ae.translationEngine,translationContext:ae.translationContext},Ye.createElement(Cf,null,Ye.createElement(yc,null,Ye.createElement(Wf,null,[...l.map((f,h)=>{const m=ae.currentLayoutJson?.layout_name||"";return Ye.createElement(Br,{key:m&&!f._fromBase?`${f.id}_${m}`:f.id,componentDef:f,dataContext:ae.currentDataContext,translationContext:ae.translationContext,registry:ae.registry,bindingEngine:ae.bindingEngine,translationEngine:ae.translationEngine,actionDispatcher:ae.actionDispatcher,isRootRenderer:h===0,layoutKey:m})}),Ye.createElement(Fm,{key:"__modal_parent_context_provider_update"},c.map(f=>{const h=ae.currentDataContext._global?.modalStack||[],y=h.includes(f.id)||ae.currentDataContext._global?.activeModal===f.id,S=h.indexOf(f.id),v=S>=0?50+S:50,_=window.__g7LayoutContextStack||[],A=_[_.length-1]?.dataContext,L=Ye.createElement(Br,{key:`modal_${f.id}_renderer`,componentDef:{...f,props:{...f.props,isOpen:y,style:{...f.props?.style,zIndex:v},onClose:ae.actionDispatcher?.createHandler({type:"click",handler:"closeModal"},ae.currentDataContext)}},dataContext:ae.currentDataContext,translationContext:ae.translationContext,registry:ae.registry,bindingEngine:ae.bindingEngine,translationEngine:ae.translationEngine,actionDispatcher:ae.actionDispatcher,parentDataContext:A});return f.data_sources&&f.data_sources.length>0?Ye.createElement(Qy,{key:`modal_${f.id}`,isOpen:y,modalId:f.id,dataSources:f.data_sources,dataContext:ae.currentDataContext,globalStateUpdater:ae.actionDispatcher?.getGlobalStateUpdater(),bindingEngine:ae.bindingEngine,debug:qo,children:L}):L}))])))))};e?.sync?(Je.log("재렌더링 시작 (sync mode - 즉시 렌더링)"),d()):(Je.log("재렌더링 시작 (with startTransition)"),N.startTransition(()=>{d()})),Je.log("템플릿 데이터 업데이트 완료")}catch(n){throw Je.error("템플릿 데이터 업데이트 실패",n),n}}function Uc(){try{Je.log("템플릿 정리 시작"),ae.reactRoot&&(Je.log("React Root 언마운트"),ae.reactRoot.unmount(),ae.reactRoot=null),ae.templateId=null,ae.locale="ko",ae.isInitialized=!1,ae.containerId=null,ae.currentLayoutJson=null,ae.currentDataContext={},ae.translationContext={templateId:"",locale:"ko"},ae.registry=null,ae.bindingEngine=null,ae.translationEngine=null,ae.actionDispatcher=null,ae.templateMetadata=null,Je.log("템플릿 정리 완료")}catch(s){throw Je.error("템플릿 정리 실패",s),s}}function sa(){return Object.freeze({...ae})}function fb(){return ae.actionDispatcher}const Vo={initTemplateEngine:Fo,renderTemplate:_s,updateTemplateData:As,destroyTemplate:Uc,getState:sa};typeof window<"u"&&(window.G7Core||(window.G7Core={}),window.G7Core.TemplateEngine=Vo,Jx({getState:()=>({translationEngine:ae.translationEngine,translationContext:ae.translationContext,bindingEngine:ae.bindingEngine,actionDispatcher:ae.actionDispatcher,templateMetadata:ae.templateMetadata}),transitionManager:Ur,responsiveManager:Si,webSocketManager:Mc}),Je.log("전역 객체 window.G7Core.TemplateEngine에 노출됨"));const Gr=Object.freeze(Object.defineProperty({__proto__:null,DataSourceManager:Tr,LayoutLoader:Vf,TemplateApp:Uo,TemplateEngine:Vo,default:Vo,destroyTemplate:Uc,getActionDispatcher:fb,getState:sa,initTemplateApp:rh,initTemplateEngine:Fo,loadLayoutEditorBundle:ah,renderTemplate:_s,updateTemplateData:As},Symbol.toStringTag,{value:"Module"}));Xt.DataSourceManager=Tr,Xt.LayoutLoader=Vf,Xt.TemplateApp=Uo,Xt.TemplateEngine=Vo,Xt.default=Vo,Xt.destroyTemplate=Uc,Xt.getActionDispatcher=fb,Xt.getState=sa,Xt.initTemplateApp=rh,Xt.initTemplateEngine=Fo,Xt.loadLayoutEditorBundle=ah,Xt.renderTemplate=_s,Xt.updateTemplateData=As,Object.defineProperties(Xt,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})})(this.G7Core=this.G7Core||{}); + `}static renderFromError(e,n,r,i=!1,l,c,d){let f,h;if(n.userMessageKey.startsWith("$t:"))if(c&&l)try{f=c.translate(n.userMessageKey,l)}catch{f=n.userMessageKey.replace("$t:","")}else f=n.userMessageKey.replace("$t:","");else f=n.userMessageKey;if(d){const m=d;m.details?.apiMessage?h=m.details.apiMessage:m.response?.data?.message&&(h=m.response.data.message)}this.render(e,{title:r,message:f,detailMessage:h,icon:n.icon,showStack:n.showStack,stackTrace:n.stack,showReloadButton:n.recoverable,debug:i})}static escapeHtml(e){if(!e)return"";const n=document.createElement("div");return n.textContent=e,n.innerHTML}}const bs=dt("Router");class ex{constructor(e){M(this,"routes",[]);M(this,"templateIdentifier");M(this,"eventHandlers",new Map);M(this,"pendingNavigation",null);M(this,"isNavigating",!1);M(this,"handlePopState",()=>{this.navigateToCurrentPath()});this.templateIdentifier=e,this.initPopstateListener()}initPopstateListener(){window.addEventListener("popstate",this.handlePopState)}on(e,n){this.eventHandlers.has(e)||this.eventHandlers.set(e,[]),this.eventHandlers.get(e).push(n)}async emit(e,...n){const r=this.eventHandlers.get(e);r&&await Promise.all(r.map(i=>i(...n)))}async loadRoutes(e){try{const n=e!==void 0&&e>0?e:null,r=await fetch(jr(`/api/templates/${this.templateIdentifier}/routes`,"json",n));if(!r.ok)throw new Error(`Failed to load routes: ${r.statusText}`);const i=await r.json();if(!i.success)throw new Error("Failed to load routes from API");if(i.data&&Array.isArray(i.data.routes))this.routes=i.data.routes,bs.log(`Loaded ${this.routes.length} routes${e?` (v=${e})`:""}`);else throw new Error("Invalid routes data format")}catch(n){throw bs.error("Error loading routes:",n),n}}setRoutes(e){this.routes=e,bs.log(`Set ${this.routes.length} routes`)}match(e){const n=this.normalizePathname(e);for(const r of this.routes){const i=this.matchPattern(r.path,n);if(i!==null)return{route:r,params:i}}return null}normalizePathname(e){return e.length>1&&e.endsWith("/")?e.replace(/\/+$/,"")||"/":e}matchPattern(e,n){const r=[];let i=e.replace(/:([^/]+)/g,(f,h)=>(r.push(h),"([^/]+)"));i.startsWith("*/")&&(i="(?:/[^/]+)?"+i.slice(1)),i=i.replace(/\//g,"\\/");const l=new RegExp(`^${i}$`),c=n.match(l);if(!c)return null;const d={};return r.forEach((f,h)=>{d[f]=c[h+1]}),d}getRoutes(){return[...this.routes]}getAuthType(e,n){return e.auth_type?e.auth_type:n.startsWith("/admin")?"admin":"user"}async navigateToCurrentPath(){const e=window.location.pathname,n=window.location.search,r=this.match(e);if(!r){bs.warn(`No route matched for path: ${e}`),this.emit("routeNotFound",e);return}if(r.route.redirect){bs.log(`Redirecting from ${e} to ${r.route.redirect}`),this.navigate(r.route.redirect);return}if(r.route.auth_required){const c=this.getAuthType(r.route,e),d=wr.getInstance();let f=d.isAuthenticated()&&d.getAuthType()===c;if(f||(f=await d.checkAuth(c)),!f){const h=d.getLoginRedirectUrl(c,e+n);bs.log(`Not authenticated, redirecting to: ${h}`),window.location.href=h;return}}const i=new URLSearchParams(n),l={};for(const c of i.keys()){if(c in l)continue;const d=i.getAll(c);d.length>1?l[c]=d:d.length===1&&(c.endsWith("[]")?l[c]=d:l[c]=d[0])}await this.emit("routeChange",{path:e,layout:r.route.layout,endpoint:r.route.endpoint,params:{...r.route.params||{},...r.params},query:l,auth_required:r.route.auth_required,auth_type:r.route.auth_type,meta:r.route.meta})}navigate(e){if(this.isNavigating){this.pendingNavigation=e;return}this.executeNavigation(e)}async executeNavigation(e){this.isNavigating=!0,this.pendingNavigation=null;try{window.history.pushState({},"",e),await this.navigateToCurrentPath()}finally{if(this.isNavigating=!1,this.pendingNavigation){const n=this.pendingNavigation;this.executeNavigation(n)}}}}const tx=/^\/admin\/layout-editor\/([^/?#]+)\/?$/;function eb(s){const e=tx.exec(s);return e?{templateIdentifier:e[1]}:null}const Bt=dt("ErrorPageHandler");class nx{constructor(e){M(this,"templateId");M(this,"layoutLoader");M(this,"locale");M(this,"debug");M(this,"renderFunction");M(this,"dataSourceManager");M(this,"globalState");M(this,"errorConfig",null);M(this,"configLoaded",!1);this.templateId=e.templateId,this.layoutLoader=e.layoutLoader,this.locale=e.locale,this.debug=e.debug,this.renderFunction=e.renderFunction,this.dataSourceManager=e.dataSourceManager,this.globalState=e.globalState||{}}async loadConfig(){if(this.configLoaded)return this.errorConfig;try{const e=await fetch(jr(`/api/templates/${this.templateId}/config`,"json"));if(!e.ok)return this.debug&&Bt.warn("Failed to load template config:",e.statusText),this.configLoaded=!0,null;const n=await e.json();if(!n.success||!n.data)return this.debug&&Bt.warn("Invalid template config response"),this.configLoaded=!0,null;const r=n.data;return!r.error_config||!r.error_config.layouts?(this.debug&&Bt.warn("No error_config found in template.json"),this.configLoaded=!0,null):(this.errorConfig=r.error_config,this.configLoaded=!0,this.debug&&Bt.log("Error config loaded:",this.errorConfig),this.errorConfig)}catch(e){return Bt.error("Failed to load error config:",e),this.configLoaded=!0,null}}async renderError(e,n="app"){try{const r=await this.loadConfig();if(!r)return this.debug&&Bt.warn("No error config available, cannot render error page"),!1;const i=r.layouts[e]||r.layouts[String(e)];if(!i)return this.debug&&Bt.warn(`No layout defined for error code: ${e}`),!1;this.debug&&Bt.log(`Loading error layout: ${i} for code: ${e}`);const l=await this.layoutLoader.loadLayout(this.templateId,i);if(!l)return this.debug&&Bt.error(`Failed to load error layout: ${i}`),!1;this.debug&&Bt.log("Error layout loaded:",l);let c={};const d=l.data_sources||[];if(d.length>0){this.debug&&Bt.log("Fetching data sources:",d.map(v=>v.id));const m=d.filter(v=>v.loading_strategy==="blocking"),y=d.filter(v=>!v.loading_strategy||v.loading_strategy==="progressive"),S=[...m,...y];if(S.length>0)try{c=await this.dataSourceManager.fetchDataSources(S,{},new URLSearchParams),this.debug&&Bt.log("Data sources fetched:",Object.keys(c))}catch(v){Bt.error("Failed to fetch data sources:",v)}}const f={};d.length>0&&(this.processInitOptions(d,c,f),this.debug&&Bt.log("initOptions processed:",{globalKeys:Object.keys(this.globalState),localKeys:Object.keys(f)}));const h={...c,errorCode:e,_global:{...this.globalState},_local:{...f}};return await this.renderFunction({containerId:n,layoutJson:l,dataContext:h,translationContext:{templateId:this.templateId,locale:this.locale}}),this.debug&&Bt.log(`Error page ${e} rendered successfully`),!0}catch(r){return Bt.error(`Failed to render error page ${e}:`,r),!1}}processInitOptions(e,n,r){for(const i of e){const l=n[i.id];if(!l)continue;const c=l?.data??l;if(i.initLocal){if(typeof i.initLocal=="string")r[i.initLocal]=c,Bt.log(`initLocal: ${i.id}.data -> _local.${i.initLocal}`);else if(typeof i.initLocal=="object"&&"key"in i.initLocal){const{key:d,path:f}=i.initLocal;r[d]=f?this.getValueByPath(c,f):c,Bt.log(`initLocal: ${i.id}.data${f?"."+f:""} -> _local.${d}`)}}if(i.initGlobal){const d=Array.isArray(i.initGlobal)?i.initGlobal:[i.initGlobal];for(const f of d)if(typeof f=="string")this.globalState[f]=c,Bt.log(`initGlobal: ${i.id}.data -> _global.${f}`);else if(typeof f=="object"&&f!==null&&"key"in f){const{key:h,path:m}=f;this.globalState[h]=m?this.getValueByPath(c,m):c,Bt.log(`initGlobal: ${i.id}.data${m?"."+m:""} -> _global.${h}`)}}}}getValueByPath(e,n){return n.split(".").reduce((r,i)=>r?.[i],e)}updateGlobalState(e){this.globalState={...this.globalState,...e}}updateLocale(e){this.locale=e,this.debug&&Bt.log("Locale updated:",e)}isConfigLoaded(){return this.configLoaded}async hasErrorLayout(e){const n=await this.loadConfig();return n?!!(n.layouts[e]||n.layouts[String(e)]):!1}clearConfigCache(){this.errorConfig=null,this.configLoaded=!1,this.debug&&Bt.log("Config cache cleared")}}const Hc=dt("AssetFailureNotice"),tb="g7-asset-failure-notice",rx="g7-system-banners",qr=new Map;let vs=!1,zc=!1,zo=null;function Ss(s,e,n){try{const r=window?.G7Core?.t;if(typeof r=="function"){const i=r(s,n);if(typeof i=="string"&&i!==s&&!i.startsWith("core.assets."))return i}}catch{}return ax(e,n)}function ax(s,e){return e?Object.entries(e).reduce((n,[r,i])=>n.split("{"+r+"}").join(String(i)),s):s}function ws(s){!s||!s.id||(qr.set(s.id,s),zc=!1,Hc.warn(`Asset failure notified: ${s.id} (${s.label})`),Cs())}function nb(s){qr.delete(s)&&(Hc.log(`Asset failure cleared: ${s}`),Cs())}function rb(){qr.size!==0&&(qr.clear(),Cs())}function ix(){return Array.from(qr.values())}async function ab(){if(vs)return;vs=!0,zc=!1,Cs();const s=Array.from(qr.values()).filter(n=>typeof n.retry=="function");let e=!1;for(const n of s)try{await n.retry(),qr.delete(n.id)}catch(r){e=!0,Hc.warn(`Asset retry failed: ${n.id}`,r)}vs=!1,zc=e,Cs()}function sx(){try{return document.documentElement.classList.contains("dark")}catch{return!1}}function Cs(){if(typeof document>"u"||!document.body)return;const s=document.getElementById(tb);if(qr.size===0){s?.remove(),hx();return}const e=s??ox();lx(e),e.replaceChildren(cx()),fx()}function ox(){const s=document.createElement("div");return s.id=tb,s.setAttribute("role","alert"),s.setAttribute("aria-live","polite"),document.body.appendChild(s),s}function lx(s){const n=document.getElementById(rx)?.offsetHeight??0;s.style.cssText=["position:fixed",`top:${n}px`,"left:0","right:0","z-index:9998","display:flex","justify-content:center","pointer-events:none"].join(";")}function cx(){const s=sx(),e=Array.from(qr.values()),n=typeof window<"u"&&window.innerWidth<768,r=document.createElement("div");return r.style.cssText=["pointer-events:auto","box-sizing:border-box","width:100%","max-width:960px","margin:8px","padding:12px 16px","border-radius:8px",`border:1px solid ${s?"#78350f":"#fcd34d"}`,`background:${s?"#451a03":"#fffbeb"}`,`color:${s?"#fef3c7":"#78350f"}`,"box-shadow:0 4px 12px rgba(0,0,0,0.12)","font-size:14px","line-height:1.5","display:flex",n?"flex-direction:column":"flex-direction:row",n?"align-items:stretch":"align-items:center","gap:12px"].join(";"),r.style.background=s?"#451a03":"#fffbeb",r.style.color=s?"#fef3c7":"#78350f",r.style.borderColor=s?"#78350f":"#fcd34d",r.appendChild(ux(e,n)),r.appendChild(dx(e,n,s)),r}function ux(s,e){const n=document.createElement("div");n.style.cssText=["flex:1 1 auto","min-width:0","display:flex","gap:8px"].join(";");const r=document.createElement("span");r.setAttribute("aria-hidden","true"),r.textContent="⚠",r.style.cssText="flex:0 0 auto;font-size:16px;line-height:1.4",n.appendChild(r);const i=document.createElement("div");if(i.style.cssText="flex:1 1 auto;min-width:0",s.length===1){const l=s[0],c=document.createElement("div");c.setAttribute("data-asset-failure-id",l.id),c.textContent=l.message??Ss("core.assets.load_failed","{label}을(를) 불러오지 못했습니다.",{label:l.label}),i.appendChild(c)}else{const l=document.createElement("div");l.style.cssText="font-weight:600",l.textContent=Ss("core.assets.load_failed_multiple","{count}개 항목을 불러오지 못했습니다.",{count:s.length}),i.appendChild(l);const c=document.createElement("div");c.style.cssText="margin-top:2px;opacity:0.9;word-break:break-word",c.textContent=s.map(d=>d.label).join(", "),i.appendChild(c)}if(zc){const l=document.createElement("div");l.style.cssText="margin-top:4px;font-weight:600",l.textContent=Ss("core.assets.retry_failed","다시 시도했지만 실패했습니다. 잠시 후 다시 시도해 주세요."),i.appendChild(l)}return n.appendChild(i),e&&(n.style.alignItems="flex-start"),n}function dx(s,e,n){const r=document.createElement("div");if(r.style.cssText=["flex:0 0 auto","display:flex","gap:8px",e?"width:100%":"","align-items:center"].filter(Boolean).join(";"),s.some(c=>typeof c.retry=="function")){const c=document.createElement("button");c.type="button",c.dataset.action="retry",c.disabled=vs,c.textContent=vs?Ss("core.assets.retrying","다시 시도 중..."):Ss("core.assets.retry","다시 시도"),c.style.cssText=[e?"flex:1 1 auto":"","padding:6px 14px","border-radius:6px","font-size:14px","font-weight:600","cursor:pointer",`border:1px solid ${n?"#b45309":"#d97706"}`,`background:${n?"#b45309":"#f59e0b"}`,`color:${n?"#fffbeb":"#451a03"}`,vs?"opacity:0.6":""].filter(Boolean).join(";"),c.addEventListener("click",()=>{ab()}),r.appendChild(c)}const l=document.createElement("button");return l.type="button",l.dataset.action="close",l.setAttribute("aria-label",Ss("core.assets.close","닫기")),l.textContent="✕",l.style.cssText=["padding:6px 10px","border-radius:6px","font-size:14px","cursor:pointer","border:1px solid transparent","background:transparent",`color:${n?"#fef3c7":"#78350f"}`].join(";"),l.addEventListener("click",()=>{rb()}),r.appendChild(l),r}function fx(){zo||typeof MutationObserver>"u"||(zo=new MutationObserver(()=>{qr.size>0&&Cs()}),zo.observe(document.documentElement,{attributes:!0,attributeFilter:["class"]}))}function hx(){zo?.disconnect(),zo=null}function px(){const s=window,e=r=>({id:String(r?.id??""),label:String(r?.label??r?.url??"asset"),retry:typeof r?.retry=="function"?r.retry:void 0}),n=Array.isArray(s.__g7ExternalAssetFailures)?s.__g7ExternalAssetFailures:[];n.forEach(r=>{r?.id&&ws(e(r))}),s.__g7ExternalAssetSink=r=>{r?.id&&ws(e(r))},Hc.log(`템플릿 externals 실패 대기열 ${n.length}건 반영`)}const Rt=dt("ModuleAssetLoader");class gx{constructor(){M(this,"loadedAssets",new Map);M(this,"loadingPromises",new Map);M(this,"failedJsAssets",new Set);M(this,"failedCssAssets",new Set)}getFailedCssAssets(){return[...this.failedCssAssets]}hasFailedJsAssets(){return this.failedJsAssets.size>0}getFailedJsAssets(){return[...this.failedJsAssets]}async loadActiveExtensionAssets(e){if(!e||e.length===0){Rt.log("No module assets to load");return}const n=[...e].sort((d,f)=>d.priority-f.priority);Rt.log("Loading module assets:",n.map(d=>d.identifier));const r=n.filter(d=>d.css).map(d=>this.loadCSS(d.identifier,d.css)),i=n.filter(d=>d.js).map(d=>this.loadJS(d.identifier,d.js)),l=await Promise.allSettled([...r,...i]),c=l.filter(d=>d.status==="rejected");if(c.length>0){Rt.warn(`Some module assets failed to load (${c.length}/${l.length}); continuing with the rest`,this.getFailedJsAssets());return}Rt.log("All module assets loaded successfully")}async loadBundle(e,n,r){const i=[];if(r&&i.push(this.loadBundleCss(e,r)),n&&i.push(this.loadBundleJs(e,n)),i.length===0){Rt.log(`No bundle assets to load for: ${e}`);return}await Promise.all(i)}async loadCustomAssets(){const e=mx();if(e.length!==0)for(const n of e){const r=`g7-custom-${n.type}-${yx(n.id)}`;if(document.getElementById(r))continue;const i=`${n.type==="style"?"custom CSS":"custom JS"}: ${n.id}`,l=(d,f)=>n.type==="style"?yi(Tn(d),{id:r},{label:i,retries:f}):ra(Tn(d),{id:r},{label:i,retries:f}),c=Td(n.url);try{if(c!==null)try{await l(n.url,0)}catch{Rt.warn(`Custom asset static miss, falling back to API: ${n.id} (${n.url} -> ${c})`),await l(c)}else await l(n.url);Rt.log(`Custom asset loaded: ${n.id}`)}catch(d){Rt.warn(`Failed to load custom asset: ${n.id} (${n.url})`,d),ws({id:`custom-asset:${n.id}`,label:n.id.split(":").pop()??n.id,retry:async()=>{document.getElementById(r)?.remove(),await l(c??n.url)}})}}}async loadBundleCss(e,n){const r=`ext-bundle-css-${e}`;if(document.getElementById(r)){Rt.log(`Bundle CSS already loaded: ${e}`);return}const i=Td(n);try{if(i!==null)try{await yi(n,{id:r},{label:`bundle CSS: ${e}`,retries:0})}catch{Rt.warn(`Bundle CSS static miss, falling back to API: ${e} (${n} -> ${i})`),await yi(Tn(i),{id:r},{label:`bundle CSS: ${e}`})}else await yi(n,{id:r},{label:`bundle CSS: ${e}`});Rt.log(`Bundle CSS loaded: ${e}`);const l=document.getElementById(r);l&&this.registerLoadedAsset(`bundle-${e}`,{type:"css",element:l})}catch(l){this.surfaceCssFailure(`bundle-${e}`,e,i!==null?Tn(i):n,l)}}async loadBundleJs(e,n){const r=`ext-bundle-js-${e}`;if(document.getElementById(r)){Rt.log(`Bundle JS already loaded: ${e}`);return}const i=this.loadingPromises.get(r);if(i)return Rt.log(`Bundle JS already loading: ${e}`),i;const l=Td(n),d=(l!==null?ra(n,{id:r},{label:`bundle JS: ${e}`,retries:0}).catch(()=>(Rt.warn(`Bundle JS static miss, falling back to API: ${e} (${n} -> ${l})`),ra(Tn(l),{id:r},{label:`bundle JS: ${e}`}))):ra(n,{id:r},{label:`bundle JS: ${e}`})).then(()=>{Rt.log(`Bundle JS loaded: ${e}`);const f=document.getElementById(r);f&&this.registerLoadedAsset(`bundle-${e}`,{type:"js",element:f}),this.loadingPromises.delete(r)}).catch(f=>{throw Rt.warn(`Failed to load bundle JS: ${e} (${n})`,f),this.failedJsAssets.add(e),this.loadingPromises.delete(r),f});return this.loadingPromises.set(r,d),d}async loadCSS(e,n){const r=`module-css-${e}`;if(document.getElementById(r)){Rt.log(`CSS already loaded: ${e}`);return}try{await yi(n,{id:r},{label:`CSS: ${e}`}),Rt.log(`CSS loaded: ${e}`);const i=document.getElementById(r);i&&this.registerLoadedAsset(e,{type:"css",element:i})}catch(i){this.surfaceCssFailure(e,e,n,i)}}surfaceCssFailure(e,n,r,i){Rt.warn(`Failed to load CSS after retries: ${e} (${r})`,i),this.failedCssAssets.add(e),ws({id:`ext-css:${e}`,label:n,retry:async()=>{document.getElementById(`module-css-${e}`)?.remove(),document.getElementById(`ext-bundle-css-${e.replace(/^bundle-/,"")}`)?.remove(),await yi(r,{},{label:`CSS retry: ${e}`}),this.failedCssAssets.delete(e)}})}async loadJS(e,n){const r=`module-js-${e}`;if(document.getElementById(r)){Rt.log(`JS already loaded: ${e}`);return}const i=this.loadingPromises.get(e);if(i)return Rt.log(`JS already loading: ${e}`),i;const l=ra(n,{id:r},{label:`JS: ${e}`}).then(()=>{Rt.log(`JS loaded: ${e}`);const c=document.getElementById(r);c&&this.registerLoadedAsset(e,{type:"js",element:c}),this.loadingPromises.delete(e)}).catch(c=>{throw Rt.warn(`Failed to load JS: ${e} (${n})`,c),this.failedJsAssets.add(e),this.loadingPromises.delete(e),c});return this.loadingPromises.set(e,l),l}registerLoadedAsset(e,n){const r=this.loadedAssets.get(e)||[];r.push(n),this.loadedAssets.set(e,r)}unloadExtensionAsset(e){const n=this.loadedAssets.get(e);if(!n||n.length===0){Rt.log(`No assets to unload for: ${e}`);return}n.forEach(r=>{r.element.parentNode&&(r.element.parentNode.removeChild(r.element),Rt.log(`${r.type.toUpperCase()} unloaded: ${e}`))}),this.loadedAssets.delete(e),Rt.log(`All assets unloaded for: ${e}`)}unloadAllAssets(){Array.from(this.loadedAssets.keys()).forEach(n=>{this.unloadExtensionAsset(n)}),Rt.log("All module assets unloaded")}isLoaded(e){return this.loadedAssets.has(e)}getLoadedModules(){return Array.from(this.loadedAssets.keys())}}let eh=null;function mx(){const s=window?.G7Config?.customAssets;return Array.isArray(s)?s.filter(e=>e&&typeof e.id=="string"&&typeof e.url=="string"&&(e.type==="style"||e.type==="script")):[]}function yx(s){return s.replace(/[^A-Za-z0-9_-]/g,"-")}function th(){return eh||(eh=new gx),eh}function bx(){if(typeof window>"u")return[];const s=window.G7Config;if(!s?.moduleAssets)return[];const e=[];for(const[n,r]of Object.entries(s.moduleAssets)){const i=r;e.push({identifier:n,js:i.js?Tn(i.js):i.js,css:i.css?Tn(i.css):i.css,priority:i.priority,external:i.external})}return e}function vx(){if(typeof window>"u")return null;const s=window.G7Config;if(!s?.bundleUrls)return null;const e=s.bundleUrls;return{moduleJs:e.moduleJs?Tn(e.moduleJs):e.moduleJs,moduleCss:e.moduleCss?Tn(e.moduleCss):e.moduleCss,pluginJs:e.pluginJs?Tn(e.pluginJs):e.pluginJs,pluginCss:e.pluginCss?Tn(e.pluginCss):e.pluginCss}}function Sx(){if(typeof window>"u")return[];const s=window.G7Config;if(!s?.pluginAssets)return[];const e=[];for(const[n,r]of Object.entries(s.pluginAssets)){const i=r;e.push({identifier:n,js:i.js?Tn(i.js):i.js,css:i.css?Tn(i.css):i.css,priority:i.priority,external:i.external})}return e}const nh=dt("SystemBannerManager");class Uc{static show(e){this.banners.set(e.id,e),this.render(),nh.log(`Banner shown: ${e.id}`)}static hide(e){this.banners.delete(e)&&(this.render(),nh.log(`Banner hidden: ${e}`))}static hideAll(){this.banners.clear(),this.render(),nh.log("All banners hidden")}static detectLocale(){try{const n=window.G7Core;if(n?.locale?.current)return n.locale.current()}catch{}return(navigator.language||"ko").split("-")[0]}static resolveMessage(e,n){return typeof e=="string"?e:e[n]||e.en||e.ko||Object.values(e)[0]||""}static render(){if(typeof document>"u")return;let e=document.getElementById(this.containerId);if(this.banners.size===0){e&&(e.remove(),this.adjustAppPadding(0));return}e||(e=document.createElement("div"),e.id=this.containerId,e.style.cssText="position:fixed;top:0;left:0;right:0;z-index:99999;",document.body.prepend(e));const n=Array.from(this.banners.values()).sort((i,l)=>(i.order??0)-(l.order??0)),r=this.detectLocale();e.innerHTML=n.map(i=>{const l=this.resolveMessage(i.message,r),c=i.background||"#f59e0b",d=i.color||"white";return`
${l}
`}).join(""),requestAnimationFrame(()=>{e&&this.adjustAppPadding(e.offsetHeight)})}static adjustAppPadding(e){const n=document.getElementById("app");n&&(n.style.paddingTop=e>0?`${e}px`:"")}}M(Uc,"banners",new Map),M(Uc,"containerId","g7-system-banners");const U=dt("TemplateApp");function ib(s){const e={};for(const n of s.keys()){if(n in e)continue;const r=s.getAll(n);r.length>1?e[n]=r:r.length===1&&(n.endsWith("[]")?e[n]=r:e[n]=r[0])}return e}const or=class or{constructor(e){M(this,"router",null);M(this,"layoutLoader",null);M(this,"errorPageHandler",null);M(this,"config");M(this,"globalState");M(this,"globalStateListeners",new Set);M(this,"currentRouteChangeId",0);M(this,"failedLayoutScripts",new Set);M(this,"currentDataSources",[]);M(this,"currentRawDataSources",[]);M(this,"currentRouteParams",{});M(this,"currentQueryParams",new URLSearchParams);M(this,"currentFetchedData",{});M(this,"currentLayoutName","");M(this,"templateErrorHandling",null);M(this,"currentWebSocketSubscriptions",[]);M(this,"extensionCacheVersion",0);M(this,"currentGlobalHeaders",[]);M(this,"transitionOverlayEl",null);M(this,"skeletonOverlayRoot",null);M(this,"skeletonOverlayContainer",null);M(this,"_spinnerState",null);M(this,"modalDataSources",new Map);this.globalState={sidebarOpen:!1},this.loadG7Config(),this.migrateLocaleStorage();const n=this.loadLocaleFromStorage(),r=n||e.locale||"ko";this.config={...e,locale:r},!n&&e.locale&&this.saveLocaleToStorage(e.locale)}loadG7Config(){if(typeof window<"u"&&window.G7Config){const e=window.G7Config;e.settings&&(this.globalState.settings=e.settings,U.log("Loaded settings from G7Config:",Object.keys(e.settings)),e.settings.upload&&(this.globalState.uploadSettings=e.settings.upload)),e.plugins&&(this.globalState.plugins=e.plugins,U.log("Loaded plugin settings from G7Config:",Object.keys(e.plugins))),e.modules&&(this.globalState.modules=e.modules,U.log("Loaded module settings from G7Config:",Object.keys(e.modules))),e.appConfig&&(this.globalState.appConfig=e.appConfig,U.log("Loaded appConfig from G7Config:",Object.keys(e.appConfig)))}}resolveRouteExpressions(e){const n=new kn,r={_global:this.globalState};return e.map(i=>{const l={...i};if(l.path&&l.path.includes("{{")){const c=l.path;l.path=n.resolveBindings(l.path,r),l.path=l.path.replace(/\/\/+/g,"/")||"/",l.path.includes("{{")&&(U.warn("Route expression resolution failed, using fallback:",c),l.path=c.replace(/\{\{[^}]+\}\}/g,"").replace(/\/\/+/g,"/")||"/")}if(l.redirect&&l.redirect.includes("{{")){const c=l.redirect;l.redirect=n.resolveBindings(l.redirect,r),l.redirect=l.redirect.replace(/\/\/+/g,"/")||"/",l.redirect.includes("{{")&&(U.warn("Route redirect expression resolution failed:",c),l.redirect=c.replace(/\{\{[^}]+\}\}/g,"").replace(/\/\/+/g,"/")||"/")}return l})}migrateLocaleStorage(){const e=["locale","g7_template_locale"];for(const n of e)try{const r=localStorage.getItem(n);r&&r!==localStorage.getItem(or.LOCALE_STORAGE_KEY)&&(localStorage.setItem(or.LOCALE_STORAGE_KEY,r),U.log(`Migrated locale from '${n}' to '${or.LOCALE_STORAGE_KEY}'`)),localStorage.removeItem(n)}catch(r){U.warn(`Failed to migrate locale key '${n}':`,r)}}async init(){try{co.getInstance().setDebug(this.config.debug),U.log("Initializing with config:",this.config),Kw();const e=br.getInstance(),n=wr.getInstance(),r=typeof window<"u"&&Number(window.G7Config?.cache_version)||0,i=r>0?r:this.loadCacheVersionFromStorage()||0,[l,c,d,f,h]=await Promise.all([Fo({templateId:this.config.templateId,templateType:this.config.templateType,locale:this.config.locale,debug:this.config.debug,cacheVersion:i}),e.loadComponents(this.config.templateId,this.config.templateType,i),Kl(i>0?uo(`templates/${this.config.templateId}/routes.json`,i):null,jr(`/api/templates/${this.config.templateId}/routes`,"json",i>0?i:null),{label:"routes.json"}).then(A=>{if(!A.ok)throw new Error(`Failed to load routes: ${A.statusText}`);return A.json()}).then(A=>{if(!A.success)throw new Error("Failed to load routes from API");return A.data}).catch(A=>{throw U.error("Error loading routes:",A),A}),n.preloadAuth(this.config.templateType==="admin"?"admin":"user"),fetch(jr(`/api/templates/${this.config.templateId}/config`,"json")).then(A=>A.ok?A.json():null).then(A=>!A?.success||!A?.data?null:A.data).catch(A=>(U.warn("Error loading template config:",A),null))]);if(U.log("Template Engine initialized"),U.log("ComponentRegistry loaded"),U.log("Routes data loaded"),U.log("User info preloaded"),U.log("Template config loaded:",h),h?.cache_version!==void 0){const A=i>0?i:null;if(this.extensionCacheVersion=h.cache_version,this.saveCacheVersionToStorage(this.extensionCacheVersion),U.log("Extension cache version:",this.extensionCacheVersion),A!==null&&A!==this.extensionCacheVersion){U.log("Cache version changed, reloading routes...");const L=await Kl(uo(`templates/${this.config.templateId}/routes.json`,this.extensionCacheVersion),jr(`/api/templates/${this.config.templateId}/routes`,"json",this.extensionCacheVersion),{label:"routes.json (reload)"}).then($=>{if(!$.ok)throw new Error(`Failed to reload routes: ${$.statusText}`);return $.json()}).then($=>{if(!$.success)throw new Error("Failed to reload routes from API");return $.data});Array.isArray(L.routes)&&(L.routes=this.resolveRouteExpressions(L.routes),Object.assign(d,L),U.log("Routes reloaded with new cache version"));try{const{TranslationEngine:$}=await Promise.resolve().then(()=>Ug),k=$.getInstance();k.setCacheVersion(this.extensionCacheVersion);const O=this.config.locale||"ko",P="en";await k.loadTranslations(this.config.templateId,O,"/api",!0),O!==P&&await k.loadTranslations(this.config.templateId,P,"/api",!0),U.log("Translations reloaded with new cache version")}catch($){U.error("Failed to reload translations:",$)}}}h?.errorHandling&&(this.templateErrorHandling=h.errorHandling,Er().setTemplateConfig(this.templateErrorHandling),U.log("Template errorHandling registered:",this.templateErrorHandling)),n.on("logout",()=>{U.log("User logged out")}),n.on("authStateChange",A=>{U.log("Auth state changed:",A)}),U.log("AuthManager event handlers registered");const m=zr(),y=this.config.templateType==="admin"?"admin":"user",S=n.getConfig(y);m.setOnUnauthorized(()=>{U.log("Unauthorized - redirecting to login page"),m.removeToken();const A=window.location.pathname+window.location.search,L=n.getLoginRedirectUrl(y,A,"session_expired");window.location.href=L}),U.log("ApiClient onUnauthorized callback registered"),this.layoutLoader=new Vf(e),this.extensionCacheVersion>0&&this.layoutLoader.setCacheVersion(this.extensionCacheVersion),U.log("LayoutLoader initialized:",this.layoutLoader);const v=new Tr({onUnauthorized:()=>{U.warn("Unauthorized request in error page")}});if(this.errorPageHandler=new nx({templateId:this.config.templateId,layoutLoader:this.layoutLoader,locale:this.config.locale,debug:this.config.debug,renderFunction:_s,dataSourceManager:v,globalState:this.globalState}),U.log("ErrorPageHandler initialized with DataSourceManager"),await this.handleServerError()){U.log("Server error handled, skipping normal initialization");return}if(this.router=new ex(this.config.templateId),Array.isArray(d.routes)){const A=this.resolveRouteExpressions(d.routes);this.router.setRoutes(A)}else throw new Error("Invalid routes data format");U.log("Router initialized:",this.router),U.log("Routes set:",this.router.getRoutes());const{getActionDispatcher:_}=await Promise.resolve().then(()=>Gr),x=_();if(x&&(x.setDefaultContext({navigate:A=>this.router?.navigate(A)}),x.setGlobalStateUpdater((A,L)=>this.setGlobalState(A,L)),U.log("Navigate function and setGlobalState injected to ActionDispatcher")),await this.loadExtensionAssets(),this.reinitializeTemplateHandlers(),this.router.on("routeChange",A=>this.handleRouteChange(A)),this.router.on("routeNotFound",A=>this.handleRouteNotFound(A)),typeof window<"u"&&eb(window.location.pathname)){U.log("Layout editor mode detected — skipping router match"),await _s({containerId:"app",layoutJson:{components:[]},dataContext:{},translationContext:{templateId:this.config.templateId,locale:this.config.locale}}),U.log("Template App initialized in layout editor mode");return}this.router.navigateToCurrentPath(),U.log("Template App initialized successfully")}catch(e){U.error("Initialization failed:",e),this.showInitError(e)}}async loadExtensionAssets(){try{const e=th(),n=vx();if(!n){await this.loadExtensionAssetsIndividually(),await e.loadCustomAssets();return}await e.loadBundle("module",n.moduleJs,n.moduleCss),await e.loadBundle("plugin",n.pluginJs,n.pluginCss),await e.loadCustomAssets(),U.log("Extension bundle assets loaded successfully")}catch(e){U.warn("Failed to load extension assets:",e)}}async loadExtensionAssetsIndividually(){const e=th(),n=bx();n.length>0&&(U.log("Loading module assets (individual fallback):",n.map(i=>i.identifier)),await e.loadActiveExtensionAssets(n));const r=Sx();r.length>0&&(U.log("Loading plugin assets (individual fallback):",r.map(i=>i.identifier)),await e.loadActiveExtensionAssets(r))}async handleRouteChange(e){const n=++this.currentRouteChangeId;window.__g7ForcedLocalFields=void 0,window.__g7ActionContext=void 0,window.__g7PendingLocalState=void 0,window.__g7LastSetLocalSnapshot=void 0,window.__g7SetLocalOverrideKeys=void 0,window.__g7SequenceLocalSync=void 0,window.__g7AutoBindingPaths=new Map;try{if(U.log("Route changed:",e,"requestId:",n),!this.layoutLoader)throw new Error("LayoutLoader is not initialized");if(!e.layout)throw new Error("Route layout is not defined");let r=e.layout;const i=r==="__preview__";i&&e.params?.token&&(r=`__preview__/${e.params.token}`);const l=await this.layoutLoader.loadLayout(this.config.templateId,r);if(n!==this.currentRouteChangeId){U.log("Route change cancelled (newer request exists):",n);return}U.log("Layout loaded:",l);const c=Er();l.errorHandling?(c.setLayoutConfig(l.errorHandling),U.log("Layout errorHandling registered:",l.errorHandling)):c.clearLayoutConfig();const d=l.data_sources||[],f=e.query||{},h=new URLSearchParams;for(const[Z,ge]of Object.entries(f))if(Array.isArray(ge))for(const H of ge)h.append(Z,H);else h.set(Z,ge);const m={route:e.params||{},query:f,_global:this.globalState};l.scripts&&Array.isArray(l.scripts)&&await this.loadLayoutScripts(l.scripts,m);const{DataSourceManager:y,getActionDispatcher:S}=await Promise.resolve().then(()=>Gr),v=new y;if(i){const Z=S();Z&&Z.setPreviewMode(!0),this.setGlobalState({__isPreview:!0}),Uc.show({id:"preview-mode",message:{ko:"⚠ 미리보기 모드 — 페이지 이동이 비활성화됩니다",en:"⚠ Preview Mode — Navigation is disabled"},background:"linear-gradient(90deg, #f59e0b, #d97706)",color:"white"}),U.log("Preview mode activated")}else{const Z=S();Z?.isPreviewMode()&&(Z.setPreviewMode(!1),Uc.hide("preview-mode"))}if(this.currentGlobalHeaders=l.globalHeaders||[],this.currentGlobalHeaders.length>0){v.setGlobalHeaders(this.currentGlobalHeaders);const Z=S();Z&&Z.setGlobalHeaders(this.currentGlobalHeaders),U.log("globalHeaders set:",this.currentGlobalHeaders.map(ge=>ge.pattern))}if(l.named_actions&&Object.keys(l.named_actions).length>0){const Z=S();Z&&Z.setNamedActions(l.named_actions)}const _=v.filterByCondition(d,m);d.length!==_.length&&U.log("Data sources filtered by condition:",{before:d.map(Z=>Z.id),after:_.map(Z=>Z.id)});const x=_.filter(Z=>Z.loading_strategy==="blocking"),A=_.filter(Z=>(Z.loading_strategy||"progressive")!=="blocking"&&Z.type!=="websocket"),L=Array.isArray(l.transition_overlay?.wait_for)?l.transition_overlay.wait_for:[],$=L.length>0&&_.some(Z=>L.includes(Z.id)&&Z.type!=="websocket"&&(Z.loading_strategy||"progressive")!=="background");if((x.length>0||$)&&l.transition_overlay){const Z=typeof l.transition_overlay=="boolean"?{enabled:l.transition_overlay,style:"opaque"}:l.transition_overlay;Z.enabled&&Z.style==="skeleton"&&Z.skeleton?.component&&Z.target?this.renderSkeletonOverlay(Z.target,Z.skeleton,l,Z.fallback_target):Z.enabled&&Z.style==="spinner"&&Z.target&&this.renderSpinnerOverlay(Z.target,Z.spinner,Z.fallback_target)}let k={},O={},P={},G={};this.currentWebSocketSubscriptions.length>0&&(U.log("Unsubscribing previous WebSocket subscriptions:",this.currentWebSocketSubscriptions),v.unsubscribeWebSockets(this.currentWebSocketSubscriptions),this.currentWebSocketSubscriptions=[]),this.currentDataSources=_,this.currentRawDataSources=d,this.currentRouteParams=e.params||{},this.currentQueryParams=h,U.log(`handleRouteChange #${n} - queryObject:`,f),U.log(`handleRouteChange #${n} - queryParams:`,h.toString()),x.length>0&&(U.log("Fetching blocking data sources:",x.map(ge=>ge.id)),(await v.fetchDataSourcesWithResults(x,e.params||{},h)).forEach(ge=>{if(ge.state==="success"&&ge.data!==void 0)k[ge.id]=ge.data;else if(ge.state==="error"&&ge.error){const H=ge.error,T=H.response?.data?.message;O[ge.id]={message:T||ge.error.message,status:H.response?.status||H.status}}}),this.processInitOptions(x,k,P,G),this.currentFetchedData={...k},U.log("Blocking data loaded:",Object.keys(k)),Object.keys(O).length>0&&U.log("Data source errors:",O),Object.keys(P).length>0&&U.log("Local state init (blocking):",Object.keys(P)),Object.keys(G).length>0&&U.log("Isolated state init (blocking):",Object.keys(G)));const B=A.length>0;if(B&&(Ur.setPending(!0),U.log("Transition started before rendering")),n!==this.currentRouteChangeId){U.log("Route change cancelled after blocking data (newer request exists):",n);return}const{getState:W}=await Promise.resolve().then(()=>Gr),pe=W().currentDataContext||{},Se=A.map(Z=>Z.id),we={};if(B){Se.forEach(ge=>{pe[ge]!==void 0?we[ge]=pe[ge]:we[ge]=void 0});const Z=Object.keys(we).filter(ge=>we[ge]!==void 0);Z.length>0&&U.log("Preserving previous progressive data:",Z),U.log("Progressive data sources initialized:",Se)}const Ue=l.defines||{},Fe={...we,...e.params,...k,route:{...e.params||{},path:e.path},query:f,_global:{...this.globalState},_globalSetState:Z=>this.setGlobalState(Z),_dataSourceErrors:Object.keys(O).length>0?O:void 0,_localInit:Object.keys(P).length>0?P:void 0,_isolatedInit:Object.keys(G).length>0?G:void 0,_defines:Object.keys(Ue).length>0?Ue:void 0};if(l.computed&&Object.keys(l.computed).length>0){const Z=this.calculateComputed(l.computed,Fe);Object.keys(Z).length>0&&(Fe._computed=Z,this.globalState._computed=Z,U.log("Computed values calculated:",Object.keys(Z))),Fe._computedDefinitions=l.computed}const qe=l.layout_name||e.layout;this.currentLayoutName!==""&&this.currentLayoutName!==qe&&(U.log("_local reset due to layout change:",{from:this.currentLayoutName,to:qe}),this.globalState._local={},mE()),this.currentLayoutName=qe;const J=l.initLocal||l.state;if(J&&Object.keys(J).length>0){this.globalState._local||(this.globalState._local={});for(const[Z,ge]of Object.entries(J))this.globalState._local[Z]===void 0&&(this.globalState._local[Z]=JSON.parse(JSON.stringify(ge)));Fe._local={...this.globalState._local},U.log("initLocal applied to _local:",Object.keys(J))}if(l.initGlobal&&Object.keys(l.initGlobal).length>0){for(const[Z,ge]of Object.entries(l.initGlobal))this.globalState[Z]===void 0&&(this.globalState[Z]=JSON.parse(JSON.stringify(ge)));U.log("initGlobal applied to _global:",Object.keys(l.initGlobal))}if(l.initIsolated&&Object.keys(l.initIsolated).length>0){for(const[Z,ge]of Object.entries(l.initIsolated))G[Z]===void 0&&(G[Z]=JSON.parse(JSON.stringify(ge)));U.log("initIsolated applied:",Object.keys(l.initIsolated))}Fe._global={...this.globalState,layoutWarnings:l.warnings||[]};const fe=l.initActions||l.init_actions;if(fe&&fe.length>0){await this.executeInitActions(fe,Fe),U.log("initActions executed before render");const Z=this.globalState;if(Z._local){if(Object.keys(P).length>0){for(const[ge,H]of Object.entries(P))Z._local[ge]!==void 0?Z._local[ge]=this.deepMerge(Z._local[ge],H):Z._local[ge]=H;U.log("localInit merged into _local after initActions:",Object.keys(P))}Fe._local=Z._local,U.log("_local merged into dataContext:",Z._local)}if(Fe._global={...this.globalState,layoutWarnings:l.warnings||[]},U.log("_global merged into dataContext after initActions"),l.computed&&Object.keys(l.computed).length>0){const ge=this.calculateComputed(l.computed,Fe);Object.keys(ge).length>0&&(Fe._computed=ge,this.globalState._computed=ge,U.log("Computed values recalculated after init_actions:",Object.keys(ge)))}if(Object.keys(this.currentFetchedData).length>0){for(const[ge,H]of Object.entries(this.currentFetchedData))Fe[ge]=H;U.log("Fetched data sources merged into dataContext after initActions:",Object.keys(this.currentFetchedData))}}if(l.transition_overlay&&!this.skeletonOverlayContainer&&this.showTransitionOverlay(l.transition_overlay,l),await _s({containerId:"app",layoutJson:l,dataContext:Fe,translationContext:{templateId:this.config.templateId,locale:this.config.locale}}),U.log("Initial render complete with blocking data"),this.reattachSpinnerOverlay(),A.length>0){if(n!==this.currentRouteChangeId){U.log("Route change cancelled before progressive fetch (newer request exists):",n),Ur.setPending(!1),this.hideTransitionOverlay();return}U.log("Fetching progressive/background data sources:",A.map(H=>H.id));const{updateTemplateData:Z,getState:ge}=await Promise.resolve().then(()=>Gr);try{const H=A.map(async T=>{try{const de=(await v.fetchDataSourcesWithResults([T],e.params||{},h,this.globalState))[0];if(!de){U.log(`Data source ${T.id} skipped (no fetch result)`);return}if(n!==this.currentRouteChangeId){U.log(`Data source ${T.id} fetch cancelled (newer request exists)`);return}if(de.state==="success"&&de.data!==void 0){U.log(`Progressive data source loaded: ${T.id}`),this.currentFetchedData[T.id]=de.data;const be={};this.processInitOptions([T],{[T.id]:de.data},be);const ie=ge();if(ie.bindingEngine){const _e=[T.id];T.initGlobal&&_e.push("_global"),T.initLocal&&_e.push("_local"),ie.bindingEngine.invalidateCacheByKeys(_e)}const xe={[T.id]:de.data};Object.keys(be).length>0&&(xe._localInit=be,Object.assign(P,be)),T.initGlobal&&(xe._global={...this.globalState}),Z(xe)}else if(de.state==="error"&&de.error){const be=de.error,ie=be.response?.data?.message;O[T.id]={message:ie||de.error.message,status:be.response?.status||be.status},U.log(`Progressive data source error: ${T.id}`,O[T.id]),Z({[T.id]:null,_dataSourceErrors:{...O}})}}catch(ce){U.error(`Failed to fetch data source: ${T.id}`,ce)}});if(await Promise.all(H),n!==this.currentRouteChangeId){U.log("Route change cancelled after progressive fetch (newer request exists):",n);return}U.log("All progressive data sources loaded")}finally{Ur.setPending(!1),this.hideTransitionOverlay()}}else this.hideTransitionOverlay();const Le=_.filter(Z=>Z.type==="websocket");if(Le.length>0){U.log("Subscribing WebSocket data sources:",Le.map(T=>T.id));const{updateTemplateData:Z,getState:ge}=await Promise.resolve().then(()=>Gr),H={...this.currentFetchedData,...e.params,route:{...e.params||{},path:e.path},query:f,_global:{...this.globalState}};U.log("WebSocket binding context keys:",Object.keys(H)),this.currentWebSocketSubscriptions=v.subscribeWebSockets(_,(T,ce)=>{U.log(`WebSocket data received for: ${T}`,ce),this.currentFetchedData[T]=ce;const de=_.find(_e=>_e.id===T),be=ge();if(be.bindingEngine){const _e=[T];de?.initGlobal&&_e.push("_global"),de?.initLocal&&_e.push("_local"),be.bindingEngine.invalidateCacheByKeys(_e)}Z({[T]:ce});const xe=_.find(_e=>_e.type==="websocket"&&(_e.target_source||_e.id)===T)?.onReceive;Array.isArray(xe)&&xe.length>0&&window.G7Core?.dispatch&&(async()=>{for(const Te of xe)try{const Me=this.getActionDispatcher?.();Me&&await Me.dispatchAction(Te,{navigate:this.getRouter?.()?(pt,Ct)=>this.getRouter().navigate(pt,Ct):void 0,setState:pt=>this.setGlobalState(pt),state:this.globalState,data:{...this.globalState,$args:[ce],$event:ce},_isDispatchFallbackContext:!0})}catch(Me){U.error(`WebSocket onReceive action failed for ${T}:`,Me)}})()},H),U.log("WebSocket subscriptions established:",this.currentWebSocketSubscriptions)}U.log("Layout rendered successfully")}catch(r){U.error("Route change handling failed:",r),this.hideTransitionOverlay(),this.showRouteError(r)}}processInitOptions(e,n,r,i){e.some(c=>c.refetchOnMount===!0&&c.initLocal)&&(r._forceLocalInit=Date.now(),U.log("refetchOnMount detected, forcing local state init")),e.forEach(c=>{const d=n[c.id];if(!d)return;const f=d.data??d;if(c.initLocal){if(typeof c.initLocal=="string"){let h=f;if(c.initLocalDefaults&&typeof c.initLocalDefaults=="object"){const y=this.evaluateDefaults(c.initLocalDefaults,n);h={...y,...f},U.log(`initLocalDefaults applied for ${c.initLocal}:`,Object.keys(y))}const m=this.globalState._local?.[c.initLocal];m!==void 0&&typeof m=="object"&&typeof h=="object"?(r[c.initLocal]=this.deepMerge(m,h),U.log(`initLocal (merged): ${c.id}.data -> _local.${c.initLocal}`)):(r[c.initLocal]=h,U.log(`initLocal: ${c.id}.data -> _local.${c.initLocal}`))}else if(typeof c.initLocal=="object"&&c.initLocal.key){const{key:h,path:m}=c.initLocal;let y=m?this.extractValueByPathOrExpression(f,m,c.id):f;if(c.initLocalDefaults&&typeof c.initLocalDefaults=="object"){const v=this.evaluateDefaults(c.initLocalDefaults,n);y={...v,...y},U.log(`initLocalDefaults applied for ${h}:`,Object.keys(v))}const S=this.globalState._local?.[h];S!==void 0&&typeof S=="object"&&typeof y=="object"?(r[h]=this.deepMerge(S,y),U.log(`initLocal (merged): ${c.id}.data${m?"."+m:""} -> _local.${h}`)):(r[h]=y,U.log(`initLocal: ${c.id}.data${m?"."+m:""} -> _local.${h}`))}else if(typeof c.initLocal=="object"){const h=c.initLocal._merge||"deep",m=this.flattenNestedObjectToMappings(c.initLocal);for(const{targetPath:y,sourcePath:S}of m){const v=this.extractValueByPathOrExpression(f,S,c.id);if(y.includes(".")){const _=y.split(".")[0];r[_]===void 0&&this.globalState._local?.[_]!==void 0&&(r[_]=JSON.parse(JSON.stringify(this.globalState._local[_]))),this.setValueAtPath(r,y,v,h),U.log(`initLocal map (${h}): ${c.id} ${S} -> _local.${y}`)}else{const _=this.globalState._local?.[y];h==="replace"?(r[y]=v,U.log(`initLocal map (replace): ${c.id} ${S} -> _local.${y}`)):h==="shallow"?_!==void 0&&typeof _=="object"&&typeof v=="object"?(r[y]={..._,...v},U.log(`initLocal map (shallow): ${c.id} ${S} -> _local.${y}`)):(r[y]=v,U.log(`initLocal map: ${c.id} ${S} -> _local.${y}`)):_!==void 0&&typeof _=="object"&&typeof v=="object"?(r[y]=this.deepMerge(_,v),U.log(`initLocal map (deep): ${c.id} ${S} -> _local.${y}`)):(r[y]=v,U.log(`initLocal map: ${c.id} ${S} -> _local.${y}`))}}}}if(c.initGlobal)if(typeof c.initGlobal=="object"&&!Array.isArray(c.initGlobal)&&!("key"in c.initGlobal))for(const[m,y]of Object.entries(c.initGlobal)){if(typeof y!="string"){U.warn(`initGlobal map value must be string, got ${typeof y} for key ${m}`);continue}const S=this.extractValueByPathOrExpression(f,y,c.id),v=this.globalState[m];v!==void 0&&typeof v=="object"&&typeof S=="object"?(this.globalState[m]=this.deepMerge(v,S),U.log(`initGlobal map (merged): ${c.id} ${y} -> _global.${m}`)):(this.globalState[m]=S,U.log(`initGlobal map: ${c.id} ${y} -> _global.${m}`))}else{const m=Array.isArray(c.initGlobal)?c.initGlobal:[c.initGlobal];for(const y of m)if(typeof y=="string"){const S=this.globalState[y];S!==void 0&&typeof S=="object"&&typeof f=="object"?(this.globalState[y]=this.deepMerge(S,f),U.log(`initGlobal (merged): ${c.id}.data -> _global.${y}`)):(this.globalState[y]=f,U.log(`initGlobal: ${c.id}.data -> _global.${y}`))}else if(typeof y=="object"&&y.key){const{key:S,path:v}=y,_=v?this.extractValueByPathOrExpression(f,v,c.id):f,x=this.globalState[S];x!==void 0&&typeof x=="object"&&typeof _=="object"?(this.globalState[S]=this.deepMerge(x,_),U.log(`initGlobal (merged): ${c.id}.data${v?"."+v:""} -> _global.${S}`)):(this.globalState[S]=_,U.log(`initGlobal: ${c.id}.data${v?"."+v:""} -> _global.${S}`))}}if(i&&c.initIsolated){if(typeof c.initIsolated=="string"){const h=i[c.initIsolated];h!==void 0&&typeof h=="object"&&typeof f=="object"?(i[c.initIsolated]=this.deepMerge(h,f),U.log(`initIsolated (merged): ${c.id}.data -> _isolated.${c.initIsolated}`)):(i[c.initIsolated]=f,U.log(`initIsolated: ${c.id}.data -> _isolated.${c.initIsolated}`))}else if(typeof c.initIsolated=="object"&&c.initIsolated.key){const{key:h,path:m}=c.initIsolated,y=m?this.extractValueByPathOrExpression(f,m,c.id):f,S=i[h];S!==void 0&&typeof S=="object"&&typeof y=="object"?(i[h]=this.deepMerge(S,y),U.log(`initIsolated (merged): ${c.id}.data${m?"."+m:""} -> _isolated.${h}`)):(i[h]=y,U.log(`initIsolated: ${c.id}.data${m?"."+m:""} -> _isolated.${h}`))}else if(typeof c.initIsolated=="object")for(const[h,m]of Object.entries(c.initIsolated)){if(typeof m!="string"){U.warn(`initIsolated map value must be string, got ${typeof m} for key ${h}`);continue}const y=this.extractValueByPathOrExpression(f,m,c.id),S=i[h];S!==void 0&&typeof S=="object"&&typeof y=="object"?(i[h]=this.deepMerge(S,y),U.log(`initIsolated map (merged): ${c.id} ${m} -> _isolated.${h}`)):(i[h]=y,U.log(`initIsolated map: ${c.id} ${m} -> _isolated.${h}`))}}})}evaluateDefaults(e,n){const r={};for(const[i,l]of Object.entries(e))if(typeof l=="string"&&l.startsWith("{{")&&l.endsWith("}}")){const c=l.slice(2,-2).trim();r[i]=this.evaluateExpression(c,n)}else r[i]=l;return r}evaluateExpression(e,n){try{const r=e.split("??").map(i=>i.trim());for(const i of r){if(/^['"].*['"]$/.test(i))return i.slice(1,-1);if(i==="true")return!0;if(i==="false")return!1;if(/^-?\d+(\.\d+)?$/.test(i))return Number(i);const l=this.getNestedValue(n,i);if(l!=null)return l}return}catch(r){U.warn(`Expression evaluation failed: ${e}`,r);return}}getNestedValue(e,n){const r=n.replace(/\?\./g,".");let i=e;const l=r.split(/\.(?![^\[]*\])/).flatMap(c=>{const d=c.match(/^([^\[]*)((?:\[\d+\])*)$/);if(d){const[,f,h]=d,m=[];f&&m.push(f);const y=h.match(/\[\d+\]/g);return y&&m.push(...y),m}return[c]}).filter(c=>c!=="");for(const c of l){if(i==null)return;if(c.startsWith("[")&&c.endsWith("]")){const d=parseInt(c.slice(1,-1),10);i=i[d]}else i=i[c]}return i}extractValueByPathOrExpression(e,n,r){const i=Da(n);if(i!==null){const l=new kn,c={data:e,_global:this.globalState,_local:this.globalState._local||{}};try{const d=Gn(i)?l.evaluatePipeExpression(i,c,{skipCache:!0}):l.evaluateExpression(i,c);return U.log(`initLocal/initGlobal expression evaluated: ${n} -> `,d),d}catch(d){U.warn(`initLocal/initGlobal expression evaluation failed for ${r}:`,n,d);return}}return this.getNestedValue(e,n)}async loadLayoutScripts(e,n){const r=[];for(const i of e){if((i.if!==void 0||i.conditions!==void 0)&&!os({if:i.if,conditions:i.conditions},n,this.bindingEngine,`script:${i.id}`)){U.log(`Script skipped (condition not met): ${i.id}`);continue}if(document.getElementById(i.id)){U.log(`Script already loaded: ${i.id}`);continue}if(!this.isAllowedScriptSrc(i.src)){U.warn(`Blocked untrusted external script src (same-origin path or declared trusted host required): ${i.id} (${i.src})`);continue}r.push(this.loadLayoutScript(i))}r.length>0&&(await Promise.all(r),U.log(`All scripts loaded: ${e.filter(i=>!document.getElementById(i.id)||r.length>0).map(i=>i.id).join(", ")}`))}async loadLayoutScript(e){const n=e.src.startsWith("/")?Tn(e.src):e.src;try{await ra(n,{id:e.id},{label:`layout-script:${e.id}`}),this.failedLayoutScripts.delete(e.id),nb(`layout-script:${e.id}`),U.log(`Script loaded successfully: ${e.id}`)}catch(r){this.failedLayoutScripts.add(e.id),U.warn(`Failed to load script after retries: ${e.id} (${n})`,r),ws({id:`layout-script:${e.id}`,label:e.id,retry:async()=>{document.getElementById(e.id)?.remove(),await ra(n,{id:e.id},{label:`layout-script:${e.id}`}),this.failedLayoutScripts.delete(e.id)}})}}getFailedLayoutScripts(){return Array.from(this.failedLayoutScripts)}isAllowedScriptSrc(e){if(typeof e!="string")return!1;const n=e.trim();if(n==="")return!1;const r=or.normalizeScriptSrcForOriginCheck(n),i=r.startsWith("//"),l=/^[a-z][a-z0-9+.-]*:/i.test(r);if(!i&&!l&&r.startsWith("/"))return!0;const c=this.extractScriptHost(r);return c!==null&&this.getTrustedScriptHosts().includes(c)}static normalizeScriptSrcForOriginCheck(e){return e.replace(/[\t\n\r]/g,"").replace(/\\/g,"/").replace(/^([a-z][a-z0-9+.\-]*:)?\/{2,}/i,"$1//")}extractScriptHost(e){try{const n=e.startsWith("//")?`${window.location.protocol}${e}`:e,r=new URL(n,window.location.origin);return r.protocol!=="http:"&&r.protocol!=="https:"?null:r.hostname.toLowerCase()}catch{return null}}getTrustedScriptHosts(){const e=window.G7Config?.trustedScriptHosts;return Array.isArray(e)?e.map(n=>String(n).toLowerCase()):[]}evaluateScriptCondition(e,n){try{if(e.startsWith("{{")&&e.endsWith("}}")){const r=e.slice(2,-2).trim();return!!Wd(r,n)}return!!e}catch(r){return U.warn(`Failed to evaluate script condition: ${e}`,r),!1}}showInitError(e){if(Fl()){U.warn("Init failed while document is unloading — skipping error screen",e);return}const n=Zy(e);Zf.renderFromError("app",n,"초기화 실패",this.config.debug,{templateId:this.config.templateId,locale:this.config.locale},void 0,e)}showTransitionOverlay(e,n){const r=typeof e=="boolean"?{enabled:e,style:"opaque",target:void 0,skeleton:void 0,spinner:void 0}:{enabled:e.enabled,style:e.style||"opaque",target:e.target,skeleton:e.skeleton,spinner:e.spinner,fallback_target:e.fallback_target};if(!r.enabled)return;if(this.hideTransitionOverlay(),r.style==="skeleton"&&r.skeleton?.component&&r.target&&n){this.renderSkeletonOverlay(r.target,r.skeleton,n,r.fallback_target);return}if(r.style==="spinner"&&r.target){this.renderSpinnerOverlay(r.target,r.spinner,r.fallback_target);return}const i=document.documentElement.classList.contains("dark");let l,c="";switch(r.style){case"blur":l=i?"rgba(17,24,39,0.3)":"rgba(255,255,255,0.3)",c="backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);";break;case"fade":l=i?"rgba(17,24,39,0.8)":"rgba(255,255,255,0.8)";break;case"skeleton":l=i?"rgb(17,24,39)":"rgb(249,250,251)";break;default:l=i?"rgb(17,24,39)":"rgb(249,250,251)";break}if(r.target){const d=`#${CSS.escape(r.target)}`,f=document.createElement("style");f.id="g7-transition-overlay",f.textContent=`${d}{position:relative;z-index:0;}${d}::after{content:'';position:absolute;inset:0;background:${l};${c}z-index:2147483647;pointer-events:none;}`,document.head.appendChild(f),this.transitionOverlayEl=f}else{const d=document.createElement("div");d.id="g7-transition-overlay",d.setAttribute("aria-hidden","true"),d.style.position="fixed",d.style.inset="0",d.style.zIndex="9999",d.style.pointerEvents="none",d.style.background=l;for(const f of c.split(";")){const h=f.indexOf(":");h!==-1&&d.style.setProperty(f.slice(0,h).trim(),f.slice(h+1).trim())}document.body.appendChild(d),this.transitionOverlayEl=d}}hideTransitionOverlay(){this.transitionOverlayEl&&(this.transitionOverlayEl.remove(),this.transitionOverlayEl=null),this.hideSkeletonOverlay()}renderSkeletonOverlay(e,n,r,i){const c=br.getInstance().getComponent(n.component);if(!c){U.log(`Skeleton component "${n.component}" not found in registry, falling back to opaque overlay`),this.showTransitionOverlay({enabled:!0,style:"opaque",target:e});return}let d=document.getElementById(e),f="target";if(!d&&i&&(d=document.getElementById(i),f="fallback"),d||(d=document.getElementById("app"),f="fullpage"),!d){U.log(`Skeleton overlay: no target found (target="#${e}", fallback="${i||"none"}"), falling back to opaque overlay`),this.showTransitionOverlay({enabled:!0,style:"opaque",target:e});return}this.hideSkeletonOverlay();const m=document.documentElement.classList.contains("dark")?"rgb(17,24,39)":"rgb(249,250,251)",y=f==="fullpage"?"app":f==="fallback"?i:e,S=`#${CSS.escape(y)}`,v=document.createElement("style");v.id="g7-skeleton-overlay-style",v.textContent=`${S}{position:relative;z-index:0;}${S}::after{content:'';position:absolute;inset:0;background:${m};z-index:2147483646;pointer-events:none;}`,document.head.appendChild(v),this.transitionOverlayEl=v;const _=document.createElement("div");if(_.id="g7-skeleton-overlay",_.setAttribute("role","status"),_.setAttribute("aria-busy","true"),_.setAttribute("aria-label","Loading..."),f==="fullpage")_.style.cssText=["position:fixed","inset:0","z-index:20","overflow:hidden","pointer-events:none",`background:${m}`].join(";")+";";else{const k=d.getBoundingClientRect(),O=window.scrollX||document.documentElement.scrollLeft,P=window.scrollY||document.documentElement.scrollTop;_.style.cssText=["position:absolute",`top:${k.top+P}px`,`left:${k.left+O}px`,`width:${k.width}px`,`height:${k.height}px`,"z-index:20","overflow:hidden","pointer-events:none",`background:${m}`].join(";")+";"}document.body.appendChild(_),this.skeletonOverlayContainer=_;const x=r.components||[];let A;if(f==="fullpage")A=x;else{const k=f==="fallback"?i:e;A=this.findComponentChildrenById(x,k)}const L=wd.createRoot(_);this.skeletonOverlayRoot=L,Ma.flushSync(()=>{L.render(Ye.createElement(c,{components:A,options:{animation:n.animation||"pulse",iteration_count:n.iteration_count||5}}))});const $=f==="fullpage"?"fullpage (#app)":f==="fallback"?`fallback (#${i})`:`target (#${e})`;U.log(`Skeleton overlay rendered [${$}] with "${n.component}" (${A.length} components)`)}findComponentChildrenById(e,n){const r=i=>{for(const l of i){if(l.id===n)return l.children||[];if(l.children&&Array.isArray(l.children)){const c=r(l.children);if(c!==null)return c}}return null};return r(e)||e}renderSpinnerOverlay(e,n,r){let i=document.getElementById(e),l="target";if(!i&&r&&(i=document.getElementById(r),l="fallback"),i||(i=document.getElementById("app"),l="fullpage"),!i){U.log(`Spinner overlay: no target found (target="#${e}", fallback="${r||"none"}"), falling back to opaque overlay`),this.showTransitionOverlay({enabled:!0,style:"opaque",target:e});return}this.hideSkeletonOverlay();const c=l==="fullpage"?"app":l==="fallback"?r:e,d=`#${CSS.escape(c)}`,f=document.createElement("style");f.id="g7-skeleton-overlay-style",f.textContent=[`${d}{position:relative;}`,"@keyframes g7-spin{to{transform:rotate(360deg)}}"].join(""),document.head.appendChild(f),this.transitionOverlayEl=f;const h=n?.text||window.G7Core?.t?.("nav.loading")||"";this._spinnerState={target:e,fallbackTarget:r,spinnerConfig:n,resolvedText:h},this._mountSpinnerInTarget(i);const m=l==="fullpage"?"fullpage (#app)":l==="fallback"?`fallback (#${r})`:`target (#${e})`,y=n?.component||"default spinner";U.log(`Spinner overlay rendered [${m}] with "${y}"`)}_mountSpinnerInTarget(e){if(!this._spinnerState)return;const{spinnerConfig:n,resolvedText:r}=this._spinnerState;if(this.skeletonOverlayRoot){try{this.skeletonOverlayRoot.unmount()}catch{}this.skeletonOverlayRoot=null}if(this.skeletonOverlayContainer){try{this.skeletonOverlayContainer.remove()}catch{}this.skeletonOverlayContainer=null}const i=document.createElement("div");if(i.id="g7-skeleton-overlay",i.setAttribute("role","status"),i.setAttribute("aria-busy","true"),e.appendChild(i),this.skeletonOverlayContainer=i,n?.component){const c=br.getInstance().getComponent(n.component);if(c){const d=wd.createRoot(i);this.skeletonOverlayRoot=d,Ma.flushSync(()=>{d.render(Ye.createElement(c,{options:{text:r}}))});return}U.log(`Spinner component "${n.component}" not found in registry, using default spinner`)}i.innerHTML='
'}reattachSpinnerOverlay(){if(!this._spinnerState)return;const{target:e,fallbackTarget:n}=this._spinnerState;let r=document.getElementById(e);!r&&n&&(r=document.getElementById(n)),r||(r=document.getElementById("app")),r&&(this._mountSpinnerInTarget(r),U.log("Spinner overlay reattached to new DOM target"))}hideSkeletonOverlay(){if(this.skeletonOverlayRoot){try{this.skeletonOverlayRoot.unmount()}catch{}this.skeletonOverlayRoot=null}if(this.skeletonOverlayContainer){try{this.skeletonOverlayContainer.parentNode&&this.skeletonOverlayContainer.remove()}catch{}this.skeletonOverlayContainer=null}const e=document.getElementById("g7-skeleton-overlay-style");e&&e.remove(),this._spinnerState=null}showRouteError(e){if(e instanceof xr&&e.details?.status===401){const r=this.config.templateId||"",i=window.location.pathname,l=r.includes("admin")||i.startsWith("/admin")?"admin":"user",c=i+window.location.search,d=!!zr().getToken()||e.details?.hadToken===!0,f=wr.getInstance().getLoginRedirectUrl(l,c,d?"session_expired":void 0);window.location.href=f;return}const n=Zy(e);Zf.renderFromError("app",n,"페이지 로딩 실패",this.config.debug,{templateId:this.config.templateId,locale:this.config.locale},void 0,e)}async handleServerError(){const e=window.G7Error;if(!e)return!1;U.warn("Server error detected:",e);try{return this.errorPageHandler&&(e.data&&(this.globalState.errorData=e.data),this.errorPageHandler.updateGlobalState(this.globalState),this.errorPageHandler.updateLocale(this.config.locale),await this.errorPageHandler.renderError(e.code,"app"))?(U.log(`${e.code} error page rendered successfully`),!0):(U.log(`Falling back to ErrorDisplay for ${e.code}`),this.showInitError(new Error(`Service unavailable (${e.code})`)),!0)}catch(n){return U.error(`Failed to render ${e.code} page:`,n),this.showInitError(new Error(`Service unavailable (${e.code})`)),!0}}async handleRouteNotFound(e){U.warn("Route not found:",e);try{if(this.errorPageHandler&&(this.errorPageHandler.updateGlobalState(this.globalState),this.errorPageHandler.updateLocale(this.config.locale),await this.errorPageHandler.renderError(404,"app"))){U.log("404 error page rendered successfully");return}U.log("Falling back to ErrorDisplay for 404"),this.showRouteError(new Error(`Page not found: ${e}`))}catch(n){U.error("Failed to render 404 page:",n),this.showRouteError(new Error(`Page not found: ${e}`))}}getRouter(){return this.router}getConfig(){return this.config}getLayoutLoader(){return this.layoutLoader}async reloadExtensionState(){U.log("reloadExtensionState: start");let e;try{const n=await fetch(jr(`/api/templates/${this.config.templateId}/config`,"json",null,`_=${Date.now()}`));if(n.ok){const r=await n.json();r?.success&&r?.data?.cache_version!==void 0&&(e=r.data.cache_version)}}catch(n){U.warn("reloadExtensionState: failed to fetch config.json",n)}e!==void 0&&e!==this.extensionCacheVersion&&(U.log(`reloadExtensionState: cache version ${this.extensionCacheVersion} -> ${e}`),this.extensionCacheVersion=e,this.saveCacheVersionToStorage(e));try{this.router&&(await this.router.loadRoutes(this.extensionCacheVersion),U.log("reloadExtensionState: routes reloaded"))}catch(n){U.error("reloadExtensionState: routes reload failed",n)}try{this.layoutLoader&&(this.extensionCacheVersion>0&&this.layoutLoader.setCacheVersion(this.extensionCacheVersion),this.layoutLoader.clear(),U.log("reloadExtensionState: layout cache cleared"))}catch(n){U.error("reloadExtensionState: layout cache clear failed",n)}try{const{TranslationEngine:n}=await Promise.resolve().then(()=>Ug),r=n.getInstance();this.extensionCacheVersion>0&&r.setCacheVersion(this.extensionCacheVersion);const i=this.config.locale||"ko",l="en";await r.loadTranslations(this.config.templateId,i,"/api",!0),i!==l&&await r.loadTranslations(this.config.templateId,l,"/api",!0),U.log("reloadExtensionState: translations reloaded")}catch(n){U.error("reloadExtensionState: translations reload failed",n)}try{const n=await fetch(`/api/locales/active?_=${Date.now()}`);if(n.ok){const i=(await n.json())?.data?.locales;if(Array.isArray(i)&&i.length>0){const l=this.globalState.appConfig??{};this.setGlobalState({appConfig:{...l,supportedLocales:i}}),U.log("reloadExtensionState: supportedLocales refreshed",i)}}}catch(n){U.warn("reloadExtensionState: supportedLocales refresh failed",n)}U.log("reloadExtensionState: done")}getActionDispatcher(){return sa().actionDispatcher}async changeLocale(e){try{if(U.log("Changing locale to:",e),this.config.locale===e){U.log("Locale is already",e);return}this.config.locale=e,this.saveLocaleToStorage(e),await this.saveLocaleToDatabase(e),this.layoutLoader&&(this.layoutLoader.clear(),U.log("Layout cache cleared")),this.errorPageHandler&&(this.errorPageHandler.updateLocale(e),U.log("ErrorPageHandler locale updated")),Pc(),await Fo({templateId:this.config.templateId,templateType:this.config.templateType,locale:e,debug:this.config.debug,cacheVersion:this.extensionCacheVersion}),U.log("Template Engine re-initialized with new locale");const{getActionDispatcher:n}=await Promise.resolve().then(()=>Gr),r=n();r&&(r.setDefaultContext({navigate:i=>this.router?.navigate(i)}),r.setGlobalStateUpdater((i,l)=>this.setGlobalState(i,l)),U.log("Navigate function and setGlobalState re-injected to ActionDispatcher")),this.reinitializeModuleHandlers(),U.log("Module handlers re-initialized"),this.reinitializeTemplateHandlers(),U.log("Template handlers re-initialized"),this.reinitializePluginHandlers(),U.log("Plugin handlers re-initialized"),this.router&&this.router.navigateToCurrentPath(),U.log("Locale changed successfully to",e)}catch(n){throw U.error("Failed to change locale:",n),n}}loadLocaleFromStorage(){try{return localStorage.getItem(or.LOCALE_STORAGE_KEY)}catch(e){return U.warn("Failed to load locale from storage:",e),null}}saveLocaleToStorage(e){try{localStorage.setItem(or.LOCALE_STORAGE_KEY,e)}catch(n){U.warn("Failed to save locale to storage:",n)}}async saveLocaleToDatabase(e){const n=localStorage.getItem("auth_token");if(!n){U.log("No auth token, skipping DB locale save");return}let r,i;if(this.config.localeApi)r=this.config.localeApi.endpoint,i=this.config.localeApi.method;else{const l=this.config.templateType==="admin";r=l?"/api/admin/users/me/language":"/api/user/profile/update-language",i=l?"PATCH":"POST"}try{const l=this.getXsrfToken(),c=await fetch(r,{method:i,headers:{"Content-Type":"application/json",Accept:"application/json",...l&&{"X-XSRF-TOKEN":l},Authorization:`Bearer ${n}`},credentials:"include",body:JSON.stringify({language:e})});c.ok?U.log("Locale saved to DB:",e):U.warn("Failed to save locale to DB (UI will still change):",c.statusText)}catch(l){U.warn("Failed to call locale API (UI will still change):",l)}}getXsrfToken(){if(typeof document>"u")return null;const n=`; ${document.cookie}`.split("; XSRF-TOKEN=");return n.length===2?decodeURIComponent(n.pop()?.split(";").shift()||""):null}loadCacheVersionFromStorage(){try{const e=localStorage.getItem(or.CACHE_VERSION_STORAGE_KEY);return e?parseInt(e,10):null}catch(e){return U.warn("Failed to load cache version from storage:",e),null}}saveCacheVersionToStorage(e){try{localStorage.setItem(or.CACHE_VERSION_STORAGE_KEY,String(e))}catch(n){U.warn("Failed to save cache version to storage:",n)}}reinitializeModuleHandlers(){if(typeof window>"u")return;const e="__",n=window;Object.keys(n).forEach(r=>{if(r.startsWith(e)&&typeof n[r]?.initModule=="function")try{n[r].initModule(),U.log(`Module handler re-initialized: ${r}`)}catch(i){U.warn(`Failed to re-initialize module handlers for ${r}:`,i)}})}reinitializeTemplateHandlers(){if(typeof window>"u")return;const e=window.G7TemplateHandlers;if(!e){U.warn("Template handlers not found on window.G7TemplateHandlers");return}const n=this.getActionDispatcher();if(!n){U.warn("ActionDispatcher not available for template handler registration");return}Object.entries(e).forEach(([r,i])=>{n.registerHandler(r,i)}),U.log(`${Object.keys(e).length} template handler(s) re-registered:`,Object.keys(e))}reinitializePluginHandlers(){if(typeof window>"u")return;const e="__",n=window;Object.keys(n).forEach(r=>{if(r.startsWith(e)&&typeof n[r]?.initPlugin=="function")try{n[r].initPlugin(),U.log(`Plugin handler re-initialized: ${r}`)}catch(i){U.warn(`Failed to re-initialize plugin handlers for ${r}:`,i)}})}getLocale(){return this.config.locale}getErrorPageHandler(){return this.errorPageHandler}getGlobalState(){return{...this.globalState}}setGlobalState(e,n){const r={...this.globalState};typeof e=="function"?this.globalState=e(this.globalState):this.globalState={...this.globalState,...e},U.log("Global state updated:",this.globalState),window.G7Core?.devTools?.captureStateSnapshot?.({source:"setGlobalState",prev:r,next:this.globalState}),this.globalStateListeners.forEach(l=>{l(this.globalState)}),n?.render!==!1&&Promise.resolve().then(()=>Gr).then(({updateTemplateData:l,getState:c})=>{const d=c();d.reactRoot&&d.currentLayoutJson&&l({_global:{...this.globalState},_local:this.globalState._local||{}})})}onGlobalStateChange(e){this.globalStateListeners.add(e)}offGlobalStateChange(e){this.globalStateListeners.delete(e)}async refetchDataSource(e,n){let r=this.currentDataSources.find(i=>i.id===e);if(!r)for(const[,i]of this.modalDataSources){const l=i.find(c=>c.id===e);if(l){r=l;break}}if(!r){U.warn(`Data source not found: ${e}`);return}U.log(`Refetching data source: ${e}`,n?.sync?"(sync mode)":"",n?.globalStateOverride?"(with global override)":"",n?.localStateOverride?"(with local override)":""),Ur.setPending(!0);try{const i=new Tr;this.currentGlobalHeaders.length>0&&i.setGlobalHeaders(this.currentGlobalHeaders);const l=sa(),c=l.currentDataContext?._global||{},d=n?.globalStateOverride?{...c,...n.globalStateOverride}:c,f=l.currentDataContext?._local||{},h=n?.localStateOverride?{...f,...n.localStateOverride}:f,y=(await i.fetchDataSourcesWithResults([r],this.currentRouteParams,this.currentQueryParams,d,h,{ignoreAutoFetch:!0}))[0];if(y.state==="success"&&y.data!==void 0){this.currentFetchedData[e]=y.data;const S={};this.processInitOptions([r],{[e]:y.data},S);const v=sa();if(v.bindingEngine){const x=[e];r.initGlobal&&x.push("_global"),r.initLocal&&x.push("_local"),v.bindingEngine.invalidateCacheByKeys(x)}const _={[e]:y.data};return Object.keys(S).length>0&&(_._localInit=S),r.initGlobal&&(_._global={...this.globalState}),As(_,n?.sync?{sync:!0}:void 0),U.log(`Data source refetched successfully: ${e}`),y.data}else if(y.state==="error"){U.error(`Failed to refetch data source: ${e}`,y.error);return}}catch(i){U.error(`Error refetching data source: ${e}`,i);return}finally{Ur.setPending(!1)}}registerModalDataSources(e,n){this.modalDataSources.set(e,n),U.log(`Modal data sources registered: ${e} (${n.length} sources)`)}unregisterModalDataSources(e){this.modalDataSources.delete(e),U.log(`Modal data sources unregistered: ${e}`)}getDataSource(e){return this.currentFetchedData[e]}setDataSource(e,n,r){if(!e){U.warn("setDataSource: dataSourceId is required");return}const{merge:i=!1,sync:l=!1}=r||{};i&&this.currentFetchedData[e]?this.currentFetchedData[e]={...this.currentFetchedData[e],...n}:this.currentFetchedData[e]=n,Promise.resolve().then(()=>Gr).then(({updateTemplateData:c})=>{c({[e]:this.currentFetchedData[e]},l?{sync:!0}:void 0)}),U.log(`setDataSource: Updated ${e}`,i?"(merged)":"(replaced)")}updateDataSourceItem(e,n,r,i,l){const{idField:c="id",merge:d=!0,skipRender:f=!1}=l||{},h=this.currentFetchedData[e];if(!h)return U.warn(`updateDataSourceItem: DataSource '${e}' not found`),!1;const m=this.parseItemPath(n);let y=h;for(const _ of m)if(y=y?.[_],y===void 0)return U.warn(`updateDataSourceItem: Path '${n}' not found in dataSource`),!1;if(!Array.isArray(y))return U.warn(`updateDataSourceItem: Target at '${n}' is not an array`),!1;const S=y.findIndex(_=>String(_[c])===String(r));if(S===-1)return U.warn(`updateDataSourceItem: Item with ${c}='${r}' not found`),!1;d?y[S]=this.deepMerge(y[S],i):y[S]={...y[S],...i};const v=window.G7Core?.devTools;return v?.isEnabled?.()&&v.trackDataSourceUpdate?.({dataSourceId:e,updateType:"partial",itemPath:n,itemId:r,updates:i,timestamp:Date.now()}),f||Promise.resolve().then(()=>Gr).then(({updateTemplateData:_})=>{_({[e]:this.currentFetchedData[e]},{sync:!1})}),U.log(`updateDataSourceItem: Updated ${e}.${n}[${c}=${r}]`),!0}parseItemPath(e){const n=[],r=/([^\.\[\]]+)|\[(\d+)\]/g;let i;for(;(i=r.exec(e))!==null;)i[1]!==void 0?n.push(i[1]):i[2]!==void 0&&n.push(parseInt(i[2],10));return n}deepMerge(e,n){if(n==null)return e;if(typeof n!="object"||Array.isArray(n))return n;const r={...e};for(const i of Object.keys(n))typeof n[i]=="object"&&n[i]!==null&&!Array.isArray(n[i])?r[i]=this.deepMerge(r[i]||{},n[i]):r[i]=n[i];return r}setValueAtPath(e,n,r,i="deep"){const l=n.split(".");let c=e;for(let h=0;h0?l.filterByCondition(this.currentRawDataSources,d):this.currentDataSources;this.currentDataSources=f;const h=f.filter(x=>x.auto_fetch!==!1&&x.type!=="websocket");if(h.length===0){U.log("No auto_fetch data sources to refetch");return}U.log(`Refetching ${h.length} auto_fetch data sources`),Ur.setPending(!0);const m=sa().currentLayoutJson,y=m?.transition_overlay,S=Array.isArray(y?.wait_for)?y.wait_for:[],v=h.some(x=>(x.loading_strategy||"progressive")==="blocking"),_=S.length>0&&h.some(x=>S.includes(x.id)&&x.type!=="websocket"&&(x.loading_strategy||"progressive")!=="background");if((v||_)&&y&&typeof y=="object"){const x=n?.transitionOverlayTarget||y.target;y.enabled&&y.style==="skeleton"&&y.skeleton?.component&&x?this.renderSkeletonOverlay(x,y.skeleton,m,y.fallback_target):y.enabled&&y.style==="spinner"&&x&&this.renderSpinnerOverlay(x,y.spinner,y.fallback_target)}try{const x=new Tr;this.currentGlobalHeaders.length>0&&x.setGlobalHeaders(this.currentGlobalHeaders);const A=sa(),L=A.currentDataContext?._global||{},$=await x.fetchDataSourcesWithResults(h,this.currentRouteParams,this.currentQueryParams,L,void 0,{ignoreAutoFetch:!1}),k={},O={},P=new Map(h.map(G=>[G.id,G]));for(const G of $){const B=P.get(G.id);if(!B){U.warn(`Refetch result id not found in autoFetchDataSources: ${G.id}`);continue}const W=G.id;G.state==="success"&&G.data!==void 0?(this.currentFetchedData[W]=G.data,k[W]=G.data,this.processInitOptions([B],{[W]:G.data},O),U.log(`Data source refetched: ${W}`)):G.state==="error"&&U.error(`Failed to refetch data source: ${W}`,G.error)}if(A.bindingEngine){const G=Object.keys(k);G.push("query"),A.bindingEngine.invalidateCacheByKeys(G)}if(Object.keys(O).length>0&&(k._localInit=O),Object.keys(k).length>0){if(k.query=ib(this.currentQueryParams),A.currentLayoutJson?.computed&&Object.keys(A.currentLayoutJson.computed).length>0){const G={...A.currentDataContext,...k,query:k.query},B=this.calculateComputed(A.currentLayoutJson.computed,G);Object.keys(B).length>0&&(k._computed=B,this.globalState._computed=B,U.log("Computed values recalculated in updateQueryParams:",Object.keys(B)))}As(k,{sync:!0}),U.log("Template data updated with new query params")}}catch(x){U.error("Error in updateQueryParams:",x)}finally{Ur.setPending(!1),this.hideTransitionOverlay()}}calculateComputed(e,n){const r={},i=new kn;for(const[l,c]of Object.entries(e))try{let d;if(this.isComputedSwitchDefinition(c))d=i.resolveSwitch(c,n,{skipCache:!0});else if(typeof c=="string")if(c.startsWith("{{")&&c.endsWith("}}")){const f=c.slice(2,-2).trim();d=this.evaluateComputedExpression(f,n)}else d=c;r[l]=d,U.log(`Computed ${l}:`,d)}catch(d){U.warn(`Failed to calculate computed value: ${l}`,d),r[l]=void 0}return r}isComputedSwitchDefinition(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&"$switch"in e&&"$cases"in e}evaluateComputedExpression(e,n){try{return Wd(e,n)}catch(r){U.warn(`Expression evaluation failed: ${e}`,r);return}}async executeInitActions(e,n={}){const{getActionDispatcher:r}=await Promise.resolve().then(()=>Gr),i=r();if(!i){U.warn("ActionDispatcher not available for init_actions");return}U.log("Executing init_actions:",e.map(d=>d.handler)),U.log("Init actions dataContext:",n),U.log("Init actions dataContext._global:",n._global);const l=e.map(d=>d.handler).filter(d=>d.includes("."));l.length>0&&await this.waitForHandlers(i,l);let c={...n};for(const d of e)try{const f={type:"click",handler:d.handler,target:d.target,params:d.params,resultTo:d.resultTo,onSuccess:d.onSuccess,onError:d.onError,if:d.if,conditions:d.conditions,auth_mode:d.auth_mode,auth_required:d.auth_required},h=i.createHandler(f,c),m=new Event("init");await h(m),U.log(`Init action executed: ${d.handler}`);const y=this.globalState;c={...c,_global:{...y},_local:y._local||c._local||{}},U.log(`Data context refreshed after ${d.handler}:`,{cartKey:c._global?.cartKey})}catch(f){U.error(`Failed to execute init action: ${d.handler}`,f)}}async waitForHandlers(e,n,r=5e3){const i=Date.now(),l=50,c=()=>n.every(f=>e.customHandlers?.has(f));if(c()){U.log("All module handlers already registered");return}const d=th().getFailedJsAssets();if(d.length>0){const f=d.some(y=>y==="module"||y==="plugin"),h=n.filter(y=>!e.customHandlers?.has(y)),m=h.length>0&&h.every(y=>d.some(S=>y.startsWith(`${S}.`)));if(f||m){U.warn("Extension asset load failed — not waiting for handlers that will never register:",{pending:h,failedAssets:d});return}}return U.log("Waiting for module handlers:",n),new Promise(f=>{const h=()=>{if(c()){U.log("All module handlers now registered"),f();return}if(Date.now()-i>=r){const m=n.filter(y=>!e.customHandlers?.has(y));U.warn("Timeout waiting for handlers:",m),f();return}setTimeout(h,l)};h()})}};M(or,"LOCALE_STORAGE_KEY","g7_locale"),M(or,"CACHE_VERSION_STORAGE_KEY","g7_cache_version");let Uo=or;function rh(s){const e=new Uo(s);return s.websocket&&(Nc.configure(s.websocket),U.log("WebSocket 설정 완료")),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{e.init(),window.__templateApp=e}):(e.init(),window.__templateApp=e),e}typeof window<"u"&&(window.G7Core=window.G7Core||{},window.G7Core.initTemplateApp=rh,window.G7Core.dataSource={refetch:async(s,e)=>{const n=window.__templateApp;if(!n){U.warn("TemplateApp not initialized (G7Core.dataSource.refetch)");return}return n.refetchDataSource(s,e)},get:s=>{const e=window.__templateApp;if(!e){U.warn("TemplateApp not initialized (G7Core.dataSource.get)");return}return e.getDataSource(s)}});function wx(s={}){const{checked:e,value:n,name:r,type:i="checkbox"}=s,c=n!==void 0?n:i==="checkbox"||i==="radio"?e??!1:String(e??""),d={checked:e??!1,value:c,name:r??"",type:i};return{target:d,currentTarget:d,preventDefault:()=>{},stopPropagation:()=>{},nativeEvent:new Event("change"),bubbles:!0,cancelable:!0,defaultPrevented:!1,eventPhase:Event.AT_TARGET,isTrusted:!1,timeStamp:Date.now(),type:"change",isDefaultPrevented:()=>!1,isPropagationStopped:()=>!1,persist:()=>{}}}function Cx(s={}){const{button:e=0,clientX:n=0,clientY:r=0}=s;return{button:e,clientX:n,clientY:r,preventDefault:()=>{},stopPropagation:()=>{},nativeEvent:new MouseEvent("click"),bubbles:!0,cancelable:!0,defaultPrevented:!1,eventPhase:Event.AT_TARGET,isTrusted:!1,timeStamp:Date.now(),type:"click",isDefaultPrevented:()=>!1,isPropagationStopped:()=>!1,persist:()=>{},target:document.createElement("div"),currentTarget:document.createElement("div")}}function Ex(){return{preventDefault:()=>{},stopPropagation:()=>{},nativeEvent:new Event("submit"),bubbles:!0,cancelable:!0,defaultPrevented:!1,eventPhase:Event.AT_TARGET,isTrusted:!1,timeStamp:Date.now(),type:"submit",isDefaultPrevented:()=>!1,isPropagationStopped:()=>!1,persist:()=>{},target:document.createElement("form"),currentTarget:document.createElement("form")}}function _x(s,e="keydown"){return{key:s,code:s.length===1?`Key${s.toUpperCase()}`:s,preventDefault:()=>{},stopPropagation:()=>{},nativeEvent:new KeyboardEvent(e,{key:s}),bubbles:!0,cancelable:!0,defaultPrevented:!1,eventPhase:Event.AT_TARGET,isTrusted:!1,timeStamp:Date.now(),type:e,isDefaultPrevented:()=>!1,isPropagationStopped:()=>!1,persist:()=>{},target:document.createElement("div"),currentTarget:document.createElement("div"),altKey:!1,ctrlKey:!1,metaKey:!1,shiftKey:!1,repeat:!1}}const Ax={justify:/^justify-(start|end|center|between|around|evenly)$/,items:/^items-(start|end|center|baseline|stretch)$/,content:/^content-(start|end|center|between|around|evenly|stretch)$/,self:/^self-(auto|start|end|center|stretch|baseline)$/,flex:/^flex-(row|row-reverse|col|col-reverse|wrap|wrap-reverse|nowrap|1|auto|initial|none)$/,grow:/^(grow|grow-0)$/,shrink:/^(shrink|shrink-0)$/,basis:/^basis-/,order:/^(order-|-)order-/,gap:/^gap(-x|-y)?-/,gridCols:/^grid-cols-/,gridRows:/^grid-rows-/,colSpan:/^col-(span-|start-|end-)/,rowSpan:/^row-(span-|start-|end-)/,display:/^(block|inline-block|inline|flex|inline-flex|table|inline-table|table-caption|table-cell|table-column|table-column-group|table-footer-group|table-header-group|table-row-group|table-row|flow-root|grid|inline-grid|contents|list-item|hidden)$/,position:/^(static|fixed|absolute|relative|sticky)$/,inset:/^(inset|top|right|bottom|left)-/,zIndex:/^z-/,width:/^w-/,minWidth:/^min-w-/,maxWidth:/^max-w-/,height:/^h-/,minHeight:/^min-h-/,maxHeight:/^max-h-/,padding:/^p[xytblr]?-/,margin:/^-?m[xytblr]?-/,space:/^space-(x|y)-/,fontSize:/^text-(xs|sm|base|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl|8xl|9xl)$/,fontWeight:/^font-(thin|extralight|light|normal|medium|semibold|bold|extrabold|black)$/,fontStyle:/^(italic|not-italic)$/,fontFamily:/^font-(sans|serif|mono)/,textAlign:/^text-(left|center|right|justify|start|end)$/,textColor:/^text-(inherit|current|transparent|black|white|slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-/,textDecoration:/^(underline|overline|line-through|no-underline)$/,textTransform:/^(uppercase|lowercase|capitalize|normal-case)$/,lineHeight:/^leading-/,letterSpacing:/^tracking-/,textOverflow:/^(truncate|text-ellipsis|text-clip)$/,whitespace:/^whitespace-/,wordBreak:/^break-/,bgColor:/^bg-(inherit|current|transparent|black|white|slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-/,bgGradient:/^bg-gradient-/,bgSize:/^bg-(auto|cover|contain)$/,bgPosition:/^bg-(bottom|center|left|left-bottom|left-top|right|right-bottom|right-top|top)$/,bgRepeat:/^bg-(repeat|no-repeat|repeat-x|repeat-y|repeat-round|repeat-space)$/,bgAttachment:/^bg-(fixed|local|scroll)$/,bgClip:/^bg-clip-/,bgOrigin:/^bg-origin-/,borderWidth:/^border(-[xytblr])?(-0|-2|-4|-8)?$/,borderColor:/^border-(inherit|current|transparent|black|white|slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-/,borderStyle:/^border-(solid|dashed|dotted|double|hidden|none)$/,borderRadius:/^rounded(-[tblrse]{1,2})?(-none|-sm|-md|-lg|-xl|-2xl|-3xl|-full)?$/,ringWidth:/^ring(-0|-1|-2|-4|-8|-inset)?$/,ringColor:/^ring-(inherit|current|transparent|black|white|slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-/,ringOffset:/^ring-offset-/,shadow:/^shadow(-sm|-md|-lg|-xl|-2xl|-inner|-none)?$/,opacity:/^opacity-/,mixBlend:/^mix-blend-/,bgBlend:/^bg-blend-/,blur:/^blur(-none|-sm|-md|-lg|-xl|-2xl|-3xl)?$/,brightness:/^brightness-/,contrast:/^contrast-/,grayscale:/^grayscale(-0)?$/,hueRotate:/^-?hue-rotate-/,invert:/^invert(-0)?$/,saturate:/^saturate-/,sepia:/^sepia(-0)?$/,backdropBlur:/^backdrop-blur-/,backdropBrightness:/^backdrop-brightness-/,backdropContrast:/^backdrop-contrast-/,backdropGrayscale:/^backdrop-grayscale-/,backdropHueRotate:/^backdrop-hue-rotate-/,backdropInvert:/^backdrop-invert-/,backdropOpacity:/^backdrop-opacity-/,backdropSaturate:/^backdrop-saturate-/,backdropSepia:/^backdrop-sepia-/,scale:/^scale(-x|-y)?-/,rotate:/^-?rotate-/,translate:/^-?translate-[xy]-/,skew:/^-?skew-[xy]-/,transformOrigin:/^origin-/,transition:/^transition(-none|-all|-colors|-opacity|-shadow|-transform)?$/,duration:/^duration-/,ease:/^ease-(linear|in|out|in-out)$/,delay:/^delay-/,animate:/^animate-/,cursor:/^cursor-/,userSelect:/^select-/,pointerEvents:/^pointer-events-/,resize:/^resize(-none|-x|-y)?$/,scrollBehavior:/^scroll-(auto|smooth)$/,touchAction:/^touch-/,overflow:/^overflow(-x|-y)?-(auto|hidden|clip|visible|scroll)$/,overscroll:/^overscroll(-x|-y)?-(auto|contain|none)$/,visibility:/^(visible|invisible|collapse)$/,aspectRatio:/^aspect-/,columns:/^columns-/,breakAfter:/^break-after-/,breakBefore:/^break-before-/,breakInside:/^break-inside-/,boxDecorationBreak:/^box-decoration-/,boxSizing:/^box-(border|content)$/,float:/^float-(right|left|none)$/,clear:/^clear-(left|right|both|none)$/,isolation:/^(isolate|isolation-auto)$/,objectFit:/^object-(contain|cover|fill|none|scale-down)$/,objectPosition:/^object-/};function sb(s){const e=s.replace(/^(dark:|hover:|focus:|active:|disabled:|group-hover:|sm:|md:|lg:|xl:|2xl:)+/,"");for(const[n,r]of Object.entries(Ax))if(r.test(e))return n;return null}function ob(s){const e=s.match(/^((dark:|hover:|focus:|active:|disabled:|group-hover:|sm:|md:|lg:|xl:|2xl:)+)/);return e?e[1]:""}function xx(s,e){if(!e||e.trim()==="")return s;if(!s||s.trim()==="")return e;const n=s.split(/\s+/).filter(Boolean),r=e.split(/\s+/).filter(Boolean),i=new Map;for(const c of r){const d=sb(c);if(d){const f=ob(c),h=`${d}:${f}`;i.set(h,c)}}return[...n.filter(c=>{const d=sb(c);if(!d)return!0;const f=ob(c),h=`${d}:${f}`;return!i.has(h)}),...r].join(" ")}function Tx(s){return Object.entries(s).filter(([,e])=>e).map(([e])=>e).join(" ")}function kx(...s){return s.filter(e=>typeof e=="string"&&e.length>0).join(" ")}const ye=dt("G7CoreGlobals");function Rx(){window.React=Ye,window.ReactDOM={...Cd,createPortal:Ma.createPortal,unstable_batchedUpdates:s=>s()},window.ReactJSXRuntime=uE,ye.log("전역 객체 window.React, window.ReactDOM, window.ReactJSXRuntime에 노출됨")}function Dx(s){const e=new Map,n=Ia.getInstance();s.componentEvent={on:(r,i)=>(e.has(r)||e.set(r,new Set),e.get(r).add(i),n.trackEventSubscribe(r),()=>{e.get(r)?.delete(i),n.trackEventUnsubscribe(r)}),emit:async(r,i)=>{const l=e.get(r),c=l?.size??0;if(!l||l.size===0)return n.trackEventEmit(r,i,0),[];let d,f=[];try{f=await Promise.all(Array.from(l).map(async h=>{try{return await h(i)}catch(m){throw ye.error(`componentEvent: Error in listener for "${r}":`,m),m}}))}catch(h){d=h instanceof Error?h:new Error(String(h))}if(n.trackEventEmit(r,i,c,f,d),d)throw d;return f},off:r=>{e.delete(r),n.trackEventOff(r)},clear:()=>{e.clear(),n.trackEventClear()}},ye.log("전역 객체 window.G7Core.componentEvent에 노출됨")}function Ox(s){s.__runtime||(s.__runtime={DynamicRenderer:Br,ComponentRegistry:br,TranslationEngine:Ra,DataSourceManager:Tr,dataSourceManager:XA,DataBindingEngine:kn,dataBindingEngine:Xd,ActionDispatcher:ko,TranslationReactContext:Kf,TranslationProvider:Lc,useTranslation:Uy,ResponsiveContext:_f,ResponsiveProvider:bc,useResponsive:Af,responsiveManager:Si,BREAKPOINT_PRESETS:Ql,AuthManager:wr,createLogger:dt,G7DevToolsCore:Ia},ye.log("전역 객체 window.G7Core.__runtime(코어 런타임 표면)에 노출됨"))}function Lx(s){if(s.layoutEditor&&s.layoutEditor.__isStub!==!0||s.layoutEditor&&s.layoutEditor.__isStub===!0)return;const e=[],n=[];s.layoutEditor={__isStub:!0,__queue:e,__readyCallbacks:n,registerWidget:(r,i)=>e.push(["widget",r,i]),registerNodeEditor:(r,i)=>e.push(["nodeEditor",r,i]),registerCanvasOverlay:(r,i)=>e.push(["canvasOverlay",r,i]),onReady:r=>{typeof r=="function"&&n.push(r)}},ye.log("전역 객체 window.G7Core.layoutEditor 예약 접수함(stub) 노출됨")}function $x(s){s.asset={template:(e,n,r)=>zw(e,n,r),templateDir:(e,n)=>Uw(e,n),module:(e,n,r)=>Pw(e,n,r),plugin:(e,n,r)=>Bw(e,n,r),convertToCurrentMode:e=>Tn(e),loadScript:(e,n,r)=>ra(e,n,r),loadStylesheet:(e,n,r)=>yi(e,n,r)},s.assets={notifyFailure:ws,clearFailure:nb,clearAll:rb,getFailures:ix,retryAll:ab},px(),ye.log("전역 객체 window.G7Core.asset / window.G7Core.assets 노출됨")}function Mx(s,e){s.useTranslation=Uy,s.t=(n,r)=>{const i=e.getState();if(!i.translationEngine||!i.translationContext)return n;if(r){const l="|"+Object.entries(r).map(([c,d])=>`${c}=${d}`).join("|");return i.translationEngine.translate(n,i.translationContext,l)}return i.translationEngine.translate(n,i.translationContext)},ye.log("전역 객체 window.G7Core.useTranslation에 노출됨")}function Nx(s,e){s.createChangeEvent=wx,s.createClickEvent=Cx,s.createSubmitEvent=Ex,s.createKeyboardEvent=_x,s.uuid=()=>typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const r=Math.random()*16|0;return(n==="x"?r:r&3|8).toString(16)}),s.createLogger=dt,ye.log("전역 객체 window.G7Core.createLogger에 노출됨"),s.renderItemChildren=(n,r,i,l,c)=>{const d=e.getState(),m={_global:window.__templateApp?.getGlobalState?.()||{},_local:r._local||{},_computed:r._computed||{},...r},y=new Set,S=(_,x)=>{const A=m._global?._remountKeys;return _&&A?.[_]&&!y.has(_)?(y.add(_),`${_}-remount-${A[_]}`):_||x},v={translationContext:d.translationContext,translationEngine:d.translationEngine,bindingEngine:d.bindingEngine,actionDispatcher:d.actionDispatcher,getRemountKey:S,...c};return vo(n,m,i,l,v)},s.evaluateCondition=(n,r)=>{if(!n)return!0;const i=e.getState(),c=window.__templateApp?.getGlobalState?.()||{},d={_global:c,_local:c._local||{},_computed:c._computed||{},...r||{}},f=i.bindingEngine??Xd;return em(n,d,f)},s.getComponentMap=()=>br.getInstance().getComponentMap(),s.renderComponentLayout=(n,r,i)=>{if(!n||!Array.isArray(n)||n.length===0)return null;const l=br.getInstance().getComponentMap(),c=e.getState(),f=window.__templateApp?.getGlobalState?.()||{},h={_global:f._global||{},_local:f._local||{},_computed:f._computed||{},...r},m=new Set,y=(S,v)=>{const _=h._global?._remountKeys;return S&&_?.[S]&&!m.has(S)?(m.add(S),`${S}-remount-${_[S]}`):S||v};return vo(n,h,l,i,{translationContext:c.translationContext,translationEngine:c.translationEngine,bindingEngine:c.bindingEngine,actionDispatcher:c.actionDispatcher,getRemountKey:y})},s.renderExpandContent=n=>{const{children:r,row:i,expandContext:l,componentContext:c,keyPrefix:d}=n;if(!r||!Array.isArray(r)||r.length===0)return null;const f=n.componentMap||br.getInstance().getComponentMap(),h=e.getState(),m=s.state?.get?.()||{},y=c?.stateRef?.current??c?.state??{},S={...m._local||{},...y},v=c?.computedRef?.current??m._computed??{},_=h.bindingEngine??s.getDataBindingEngine?.(),x={...m,_local:S,_computed:v,row:i,item:i,$item:i};let A={};if(l&&typeof l=="object"&&_)try{for(const[O,P]of Object.entries(l))if(typeof P=="string"){const G=Da(P);if(G!==null)try{A[O]=Gn(G)?_.evaluatePipeExpression(G,x,{skipCache:!0}):_.evaluateExpression(G,x,{skipCache:!0})}catch{A[O]=void 0}else A[O]=_.resolveBindings(P,x,{skipCache:!0})}else A[O]=P}catch(O){ye.warn("renderExpandContent: expandContext 평가 오류:",O)}const L={row:i,item:i,$item:i,_local:S,_global:m._global||{},_computed:m._computed||{},...A},$=new Set,k=(O,P)=>{const G=L._global?._remountKeys;return O&&G?.[O]&&!$.has(O)?($.add(O),`${O}-remount-${G[O]}`):O||P};return vo(r,L,f,d,{translationContext:h.translationContext,translationEngine:h.translationEngine??void 0,bindingEngine:h.bindingEngine??void 0,actionDispatcher:h.actionDispatcher,componentContext:c,getRemountKey:k})},s.$get=function(r,i,l=void 0){if(r==null)return l;const c=Array.isArray(i)?i:[i];if(c.length===0)return r;let d=r;for(const f of c){if(d==null||f==null)return l;d=d[f]}return d??l},ye.log("전역 객체 window.G7Core.renderItemChildren에 노출됨"),ye.log("전역 객체 window.G7Core.renderComponentLayout에 노출됨"),ye.log("전역 객체 window.G7Core.renderExpandContent에 노출됨"),ye.log("전역 객체 window.G7Core.$get에 노출됨")}function Ix(s){s.dispatch=async(e,n)=>{const r=window.__templateApp;if(!r)return ye.warn("G7Core.dispatch: TemplateApp이 초기화되지 않았습니다."),{success:!1,error:new Error("TemplateApp이 초기화되지 않았습니다.")};const i=r.getActionDispatcher?.();if(!i)return ye.warn("G7Core.dispatch: ActionDispatcher를 찾을 수 없습니다."),{success:!1,error:new Error("ActionDispatcher를 찾을 수 없습니다.")};const l=r.getRouter?.(),c=r.getGlobalState?.(),d=r.setGlobalState?.bind(r),h=n?.componentContext||window.__g7ActionContext,m=window.__g7PendingLocalState;let y=h?.state??c;m&&h&&(y=m,ye.log("[dispatch] Using __g7PendingLocalState for context.state:",m));let S=h?.data??c;m&&h?.data?._local&&(S={...h.data,_local:m},ye.log("[dispatch] Updated context.data._local with pendingLocalState"));const v={navigate:l?(_,x)=>l.navigate(_,x):void 0,setState:h?.setState??d,state:y,data:S,_isDispatchFallbackContext:!h?.setState};if(e.debounce){const _=e.debounceKey||`dispatch-${e.handler}`,x=typeof e.debounce=="number"?e.debounce:e.debounce.delay;return i.debouncedCall(_,x,()=>{const{debounce:A,debounceKey:L,...$}=e;i.dispatchAction($,v)}),{success:!0,debounced:!0}}try{return await i.dispatchAction(e,v)}catch(_){return ye.error("G7Core.dispatch: 액션 실행 오류:",_),{success:!1,error:_ instanceof Error?_:new Error(String(_))}}},ye.log("전역 객체 window.G7Core.dispatch에 노출됨")}function Po(s){const e={};for(const[n,r]of Object.entries(s))if(n.includes(".")){const i=n.split(".");let l=e;for(let c=0;c0&&e.every(n=>/^\d+$/.test(n))}function cb(s,e){const n={...s};for(const r of Object.keys(e))r in n?n[r]!==null&&typeof n[r]=="object"&&!Array.isArray(n[r])&&e[r]!==null&&typeof e[r]=="object"&&!Array.isArray(e[r])&&(n[r]=cb(n[r],e[r])):n[r]=e[r];return n}function sr(s,e){if(Array.isArray(s)&&!Array.isArray(e)&&jx(e)){const r=Object.keys(e).map(l=>parseInt(l,10));if(!((r.length>0?Math.max(...r):0)>=s.length+r.length+10)){const l=[...s];for(const[c,d]of Object.entries(e)){const f=parseInt(c,10);f>=0&&f=l.length&&(l[f]=d)}return l}}const n={...s};for(const[r,i]of Object.entries(e))i!==null&&typeof i=="object"&&!Array.isArray(i)?n[r]!==null&&typeof n[r]=="object"?n[r]=sr(n[r],i):n[r]={...i}:n[r]=i;return n}function Hx(s){s.state={get:()=>window.__templateApp?.getGlobalState?.()||{},set:(e,n)=>{const r=window.__templateApp;if(r?.setGlobalState&&r?.getGlobalState){const i=n?.merge||"deep",l=Po(e);let c;if(i==="replace")c=l;else if(i==="shallow")c={...r.getGlobalState(),...l};else{const d=r.getGlobalState();c=sr(d,l)}r.setGlobalState(c,{render:n?.render})}else ye.warn("G7Core.state.set: TemplateApp이 초기화되지 않았습니다.")},setLocal:(e,n)=>{const r=window.__templateApp;if(n?.render===!1&&!n?.selfManaged){const A=window.__g7AutoBindingPaths;A&&A.size>0&&lb(Po(e)).some($=>A.has($))&&(ye.log("[setLocal] render:false + 자동바인딩 경로 겹침 감지 → render:true 자동 승격 (engine-v1.43.0)"),n={...n,render:!0})}if(n?.debounce){const A=r?.getActionDispatcher?.();if(A){const L=n.debounceKey||`setLocal-${Object.keys(e).join(",")}`,{debounce:$,debounceKey:k,...O}=n;A.debouncedCall(L,n.debounce,()=>{s.state.setLocal(e,O)});return}}const i=n?.scope??"current",l=n?.merge||"deep",c=window.__g7ActionContext,d=Po(e);if(i==="parent"||i==="root"){const A=window.__g7LayoutContextStack||[];if(A.length>0){const L=i==="parent"?A[A.length-1]:A[0];if(L?.setState){L.setState($=>l==="replace"?d:l==="shallow"?{...$||{},...d}:sr($||{},d)),ye.log(`[setLocal] scope=${i}: 타겟 컨텍스트에 상태 업데이트 (mergeMode=${l})`,d);return}}ye.warn(`[setLocal] scope=${i}: 레이아웃 컨텍스트 스택이 비어있습니다. current로 폴백합니다.`)}const f=window.__g7PendingLocalState,h=r?.getGlobalState?.()?._local||{},S=!((window.__g7LayoutContextStack||[]).length>0)&&c?.state?c.state:void 0,v=S?cb(h,S):h,_=f||v;let x;if(l==="replace"?x=d:l==="shallow"?x={..._,...d}:x=sr(_,d),r?.setGlobalState&&(r.setGlobalState({_local:x},{render:n?.render}),ye.log(`[setLocal] globalLocal updated via setGlobalState (mergeMode=${l}, render=${n?.render??!0}):`,d)),window.__g7PendingLocalState=x,ye.log("[setLocal] __g7PendingLocalState updated:",x),window.__g7SequenceLocalSync=x,window.__g7LastSetLocalSnapshot=x,l==="replace")window.__g7ForcedLocalFields=d;else{const A=window.__g7ForcedLocalFields||{};window.__g7ForcedLocalFields=sr(A,d)}if(ye.log("[setLocal] __g7ForcedLocalFields updated:",d),l==="replace")window.__g7SetLocalOverrideKeys=d;else{const A=window.__g7SetLocalOverrideKeys||{};window.__g7SetLocalOverrideKeys=sr(A,d)}ye.log("[setLocal] __g7SetLocalOverrideKeys updated:",d),c?.setState&&c.setState(A=>l==="replace"?d:l==="shallow"?{...A||{},...d}:sr(A||{},d)),r?.setGlobalState||ye.warn("G7Core.state.setLocal: TemplateApp이 없습니다.")},getLocal:()=>{const r=(window.__templateApp?.getGlobalState?.()||{})._local||{},i=window.__g7PendingLocalState;if(i)return sr(r,i);const l=window.__g7LastSetLocalSnapshot;return l&&l!==r?sr(r,l):r},update:e=>{const n=window.__templateApp;if(n?.getGlobalState&&n?.setGlobalState){const r=n.getGlobalState(),i=e(r);n.setGlobalState(i)}else ye.warn("G7Core.state.update: TemplateApp이 초기화되지 않았습니다.")},subscribe:e=>{const n=window.__templateApp;return n?.onGlobalStateChange?n.onGlobalStateChange(e):(ye.warn("G7Core.state.subscribe: TemplateApp이 초기화되지 않았습니다."),()=>{})},getDataSource:e=>window.__templateApp?.getDataSource?.(e),getIsolated:e=>e?window.__g7IsolatedStates?.[e]?.state??null:window.__g7ActionContext?.isolatedContext?.state??null,setIsolated:(e,n,r)=>{let i,l,c;typeof e=="string"?(i=e,l=n||{},c=r):(l=e,c=n&&typeof n=="object"&&"merge"in n?n:r);const d=c?.merge||"deep",f=Po(l);if(i){const y=window.__g7IsolatedStates?.[i];y?.mergeState?y.mergeState(f,d):ye.warn(`G7Core.state.setIsolated: scopeId '${i}'를 찾을 수 없습니다.`);return}const h=window.__g7ActionContext;h?.isolatedContext?.mergeState?h.isolatedContext.mergeState(f,d):ye.warn("G7Core.state.setIsolated: 액션 컨텍스트에 isolatedContext가 없습니다.")},getParent:()=>{const e=window.__g7LayoutContextStack||[];if(e.length===0)return ye.log("[getParent] 레이아웃 컨텍스트 스택이 비어있습니다."),null;const n=e[e.length-1];if(!n)return null;const r=n.dataContext||{};return{_local:n.state||r._local||{},_global:r._global||s.state.get()||{},setState:n.setState}},setParentLocal:(e,n,r)=>{const i=window.__g7LayoutContextStack||[];if(i.length===0){ye.warn("[setParentLocal] 레이아웃 컨텍스트 스택이 비어있습니다.");return}const l=i[i.length-1];if(!l?.setState){ye.warn("[setParentLocal] 부모 컨텍스트에 setState가 없습니다.");return}let c,d;typeof e=="string"?(c={[e]:n},d=r):(c=e,d=n&&typeof n=="object"&&"merge"in n?n:r);const f=d?.merge||"deep",h=Po(c),m=l.state?._local!==void 0,y=m?l.state._local:l.state||{};let S;f==="replace"?S=h:f==="shallow"?S={...y,...h}:S=sr(y,h),window.__g7PendingLocalState=S;const v=window.__templateApp;if(v?.setGlobalState&&v.setGlobalState({_local:S}),l.setState(S),m?l.state._local=S:l.state=S,l.dataContext&&(l.dataContext._local=S),f==="replace")window.__g7ForcedLocalFields=h;else{const _=window.__g7ForcedLocalFields||{};window.__g7ForcedLocalFields=sr(_,h)}wf()},setParentGlobal:(e,n)=>{let r;typeof e=="string"?r={[e]:n}:r=e,s.state.set(r),ye.log("[setParentGlobal] 전역 상태 업데이트:",r)}},window.__g7IsolatedStates||(window.__g7IsolatedStates={}),s.state.getGlobal=s.state.get,s.state.setGlobal=s.state.set,ye.log("전역 객체 window.G7Core.state에 노출됨")}function zx(s){s.dataSource={get:e=>window.__templateApp?.getDataSource?.(e),set:(e,n,r)=>{const i=window.__templateApp;i?.setDataSource?i.setDataSource(e,n,r):ye.warn("G7Core.dataSource.set: TemplateApp이 초기화되지 않았습니다.")},refetch:async(e,n)=>{const r=window.__templateApp;if(r?.refetchDataSource)return r.refetchDataSource(e,n);ye.warn("G7Core.dataSource.refetch: TemplateApp이 초기화되지 않았습니다.")},updateItem:(e,n,r,i,l)=>{const c=window.__templateApp;return c?.updateDataSourceItem?c.updateDataSourceItem(e,n,r,i,l):(ye.warn("G7Core.dataSource.updateItem: TemplateApp이 초기화되지 않았습니다."),!1)},updateData:(e,n,r,i="append")=>{const l=window.__templateApp;if(!l?.getDataSource||!l?.setDataSource)return ye.warn("G7Core.dataSource.updateData: TemplateApp이 초기화되지 않았습니다."),!1;const c=l.getDataSource(e);if(!c)return ye.warn(`G7Core.dataSource.updateData: 데이터 소스 '${e}'를 찾을 수 없습니다.`),!1;let d,f=c,h=null;if(n){const y=n.split(".");h=y.pop();for(const S of y)if(f&&typeof f=="object"&&S in f)f=f[S];else return ye.warn(`G7Core.dataSource.updateData: 경로 '${n}'를 찾을 수 없습니다.`),!1;d=f[h]}else d=c;if(!Array.isArray(d))return ye.warn("G7Core.dataSource.updateData: 대상 경로의 데이터가 배열이 아닙니다."),!1;if(!Array.isArray(r))return ye.warn("G7Core.dataSource.updateData: newData가 배열이 아닙니다."),!1;const m=i==="prepend"?[...r,...d]:[...d,...r];return n&&h?(f[h]=m,l.setDataSource(e,c,{merge:!1})):l.setDataSource(e,m,{merge:!1}),ye.log(`G7Core.dataSource.updateData: '${e}'에 ${r.length}개 항목 ${i==="prepend"?"앞에":"뒤에"} 추가됨`),!0}},ye.log("전역 객체 window.G7Core.dataSource에 노출됨")}function Ux(s,e){s.locale={current:()=>window.__templateApp?.getLocale?.()||"ko",supported:()=>{const r=window.__templateApp?.globalState?.appConfig?.supportedLocales;return Array.isArray(r)&&r.length>0?r:e.getState().templateMetadata?.locales||["ko","en"]},change:async n=>{const r=window.__templateApp;r?.changeLocale?await r.changeLocale(n):ye.warn("G7Core.locale.change: TemplateApp이 초기화되지 않았습니다.")}},ye.log("전역 객체 window.G7Core.locale에 노출됨")}function Px(s){s.toast={show:(e,n)=>{s.dispatch({handler:"toast",params:{message:e,type:n?.type||"info",...n?.duration&&{duration:n.duration}}})},success:(e,n)=>{s.toast.show(e,{type:"success",duration:n})},error:(e,n)=>{s.toast.show(e,{type:"error",duration:n})},warning:(e,n)=>{s.toast.show(e,{type:"warning",duration:n})},info:(e,n)=>{s.toast.show(e,{type:"info",duration:n})}},ye.log("전역 객체 window.G7Core.toast에 노출됨")}function Bx(s){s.modal={open:e=>{s.dispatch({handler:"openModal",target:e})},close:e=>{s.dispatch({handler:"closeModal",...e&&{target:e}})},closeAll:()=>{s.dispatch({handler:"closeAllModals"})},isOpen:e=>{const n=s.state.get();return n._global?.activeModal===e||n._global?.modalStack?.includes(e)||!1},getStack:()=>s.state.get()._global?.modalStack||[]},ye.log("전역 객체 window.G7Core.modal에 노출됨")}function qx(s){s.style={mergeClasses:xx,conditionalClass:Tx,joinClasses:kx},ye.log("전역 객체 window.G7Core.style에 노출됨")}function Gx(s,e){const{webSocketManager:n}=e;s.websocket={manager:n,subscribe:(r,i,l,c)=>n.subscribe(r,i,l,c),unsubscribe:r=>n.unsubscribe(r),leaveChannel:r=>n.leaveChannel(r),disconnect:()=>n.disconnect(),isInitialized:()=>n.isInitialized(),getSubscriptionCount:()=>n.getSubscriptionCount()},ye.log("전역 객체 window.G7Core.websocket에 노출됨")}function Fx(s,e){const{transitionManager:n}=e;s.navigation={isPending:()=>n?.getIsPending?.()||!1,onComplete:r=>{if(!n)return r(),()=>{};let i=n.getIsPending();const l=n.subscribe(c=>{c?i=!0:i&&(r(),l())});return l}},ye.log("전역 객체 window.G7Core.navigation에 노출됨")}function Vx(s){s.plugin={getSettings:e=>window.G7Config?.plugins?.[e],get:(e,n,r)=>window.G7Config?.plugins?.[e]?.[n]??r,getAll:()=>window.G7Config?.plugins??{}},ye.log("전역 객체 window.G7Core.plugin에 노출됨")}function Kx(s){s.module={getSettings:e=>window.G7Config?.modules?.[e],get:(e,n,r)=>window.G7Config?.modules?.[e]?.[n]??r,getAll:()=>window.G7Config?.modules??{}},ye.log("전역 객체 window.G7Core.module에 노출됨")}function Wx(s,e){const{transitionManager:n,responsiveManager:r}=e;s.AuthManager=wr,s.api=zr(),s.TransitionManager=n,s.useTransitionState=Jm,s.ResponsiveManager=r,s.useResponsive=Af,s.useControllableState=EE,s.shallowArrayEqual=_E,s.shallowObjectEqual=Zm,s.updateQueryParams=async(i,l)=>{const c=window.__templateApp;if(c?.updateQueryParams)return c.updateQueryParams(i,l);ye.warn("G7Core.updateQueryParams: TemplateApp이 초기화되지 않았습니다.")},ye.log("전역 객체 window.G7Core.AuthManager에 노출됨"),ye.log("전역 객체 window.G7Core.api에 노출됨"),ye.log("전역 객체 window.G7Core.ResponsiveManager에 노출됨"),ye.log("전역 객체 window.G7Core.useResponsive에 노출됨"),ye.log("전역 객체 window.G7Core.useControllableState에 노출됨"),ye.log("전역 객체 window.G7Core.updateQueryParams에 노출됨")}function Yx(s,e){s.getSlotContext=()=>window.__slotContextValue??null,s.getDynamicRenderer=()=>window.__DynamicRenderer??null,s.getComponentRegistry=()=>e.getComponentRegistry?.()??br.getInstance(),s.getDataBindingEngine=()=>e.getDataBindingEngine?.()??e.getState().bindingEngine,s.getTranslationEngine=()=>e.getTranslationEngine?.()??e.getState().translationEngine,s.getActionDispatcher=()=>e.getActionDispatcher?.()??e.getState().actionDispatcher,ye.log("전역 객체 window.G7Core 슬롯 API에 노출됨 (getSlotContext, getDynamicRenderer 등)")}function Xx(s){s.identity={setLauncher:St.setLauncher.bind(St),handle:St.handle.bind(St),isIdentityRequired:St.isIdentityRequired.bind(St),hasLauncher:St.hasLauncher.bind(St),markDomainNoticeShown:St.markDomainNoticeShown.bind(St),redirectExternally:St.redirectExternally.bind(St),createDeferred:St.createDeferred.bind(St),resolveDeferred:St.resolveDeferred.bind(St),reset:St.reset.bind(St),redirectStashKey:gf},ye.log("전역 객체 window.G7Core 본인인증(IDV) API에 노출됨 (identity)")}function Jx(s){if(typeof window>"u")return;Rx(),window.G7Core||(window.G7Core={});const e=window.G7Core;Ox(e),Dx(e),Lx(e),Wx(e,s),$x(e),Mx(e,s),Nx(e,s),Ix(e),Hx(e),zx(e),Ux(e,s),Px(e),Bx(e),qx(e),Gx(e,s),Fx(e,s),Vx(e),Kx(e),Yx(e,s),Xx(e),ye.log("G7Core 전역 객체 초기화 완료")}function Qx(){const s=window.G7Core;if(!s){ye.warn("G7Core가 초기화되지 않았습니다.");return}const e=()=>Ia.getInstance(),n={isEnabled:()=>{try{return e().isEnabled()}catch{return!1}},trackRender:r=>{try{e().isEnabled()&&e().trackRender(r)}catch{}},trackIteration:(r,i,l,c,d)=>{try{e().isEnabled()&&e().trackIteration(r,{source:i,itemVar:l,indexVar:c,sourceLength:d})}catch{}},trackIfCondition:(r,i,l,c)=>{try{e().isEnabled()&&e().trackIfCondition(r,i,l)}catch{}},trackMount:(r,i)=>{try{e().isEnabled()&&e().trackMount(r,{...i,id:r})}catch{}},trackUnmount:r=>{try{e().isEnabled()&&e().trackUnmount(r)}catch{}},trackExpressionEval:r=>{try{e().isEnabled()&&e().trackExpressionEval(r)}catch{}},trackBindingEval:r=>{try{e().isEnabled()&&e().trackBindingEval(r)}catch{}},recordCacheHit:()=>{try{e().isEnabled()&&e().recordCacheHit()}catch{}},recordCacheMiss:()=>{try{e().isEnabled()&&e().recordCacheMiss()}catch{}},trackHandlerRegistration:(r,i,l,c)=>{try{e().isEnabled()&&e().trackHandlerRegistration(r,i,l,c)}catch{}},trackHandlerUnregistration:r=>{try{e().isEnabled()&&e().trackHandlerUnregistration(r)}catch{}},logAction:r=>{try{e().isEnabled()&&e().logAction(r)}catch{}},trackRequest:(r,i)=>{try{return e().isEnabled()?e().trackRequest(r,i):""}catch{return""}},completeRequest:(r,i,l)=>{try{e().isEnabled()&&e().completeRequest(r,i,l)}catch{}},failRequest:(r,i)=>{try{e().isEnabled()&&e().failRequest(r,i)}catch{}},trackDataSourceDefinition:r=>{try{e().isEnabled()&&e().trackDataSourceDefinition(r)}catch{}},trackDataSourceLoading:r=>{try{e().isEnabled()&&e().trackDataSourceLoading(r)}catch{}},trackDataSourceLoaded:(r,i,l)=>{try{e().isEnabled()&&e().trackDataSourceLoaded(r,i,l)}catch{}},trackDataSourceError:(r,i)=>{try{e().isEnabled()&&e().trackDataSourceError(r,i)}catch{}},trackForm:(r,i,l)=>{try{e().isEnabled()&&e().trackForm(r,i,l)}catch{}},untrackForm:r=>{try{e().isEnabled()&&e().untrackForm(r)}catch{}},startStateChange:(r,i,l,c)=>{try{return e().isEnabled()?e().startStateChange(r,i,l,c):""}catch{return""}},completeStateChange:r=>{try{e().isEnabled()&&e().completeStateChange(r)}catch{}},trackComponentRender:(r,i,l,c,d,f)=>{try{e().isEnabled()&&e().trackComponentRender(r,i,l,c,d,f)}catch{}},updateLocalState:r=>{try{e().isEnabled()&&e().updateLocalState(r)}catch{}},updateComputedState:r=>{try{e().isEnabled()&&e().updateComputedState(r)}catch{}},updateParentContext:r=>{try{e().isEnabled()&&e().updateParentContext(r)}catch{}},trackComponentStateSource:(r,i,l,c)=>{try{e().isEnabled()&&e().trackComponentStateSource(r,i,l,c)}catch{}},trackDynamicState:(r,i)=>{try{e().isEnabled()&&e().trackDynamicState(r,i)}catch{}},trackContextFlow:(r,i,l,c,d,f)=>{try{e().isEnabled()&&e().trackContextFlow(r,i,l,c,d,f)}catch{}},trackComponentStyle:(r,i,l,c)=>{try{e().isEnabled()&&e().trackComponentStyle(r,i,l,c)}catch{}},trackAuthEvent:(r,i,l,c)=>{try{e().isEnabled()&&e().trackAuthEvent(r,i,l,c)}catch{}},trackAuthHeader:(r,i,l,c,d)=>{try{e().isEnabled()&&e().trackAuthHeader(r,i,l,c,d)}catch{}},trackLog:(r,i,l)=>{try{e().isEnabled()&&e().trackLog(r,i,l)}catch{}},trackAction:r=>{try{e().isEnabled()&&e().trackAction?.(r)}catch{}},trackDataSourceUpdate:r=>{try{e().isEnabled()&&e().trackDataSourceUpdate?.(r)}catch{}},startSequenceExecution:r=>{try{return e().isEnabled()?e().startSequenceExecution(r):""}catch{return""}},captureSequenceActionBefore:(r,i,l,c,d)=>{try{e().isEnabled()&&e().captureSequenceActionBefore(r,i,l,c,d)}catch{}},captureSequenceActionAfter:(r,i,l,c,d,f)=>{try{e().isEnabled()&&e().captureSequenceActionAfter(r,i,l,c,d,f)}catch{}},endSequenceExecution:(r,i)=>{try{e().isEnabled()&&e().endSequenceExecution(r,i)}catch{}},registerStateCaptureForHandler:(r,i,l)=>{try{e().isEnabled()&&e().registerStateCaptureForHandler(r,i,l)}catch{}},detectStaleClosure:(r,i,l,c,d)=>{try{return e().isEnabled()?e().detectStaleClosure(r,i,l,c,d):[]}catch{return[]}},trackStaleClosureWarning:r=>{try{e().isEnabled()&&e().trackStaleClosureWarning(r)}catch{}},trackModalOpen:r=>{try{e().isEnabled()&&e().trackModalOpen(r)}catch{}},trackModalClose:(r,i)=>{try{e().isEnabled()&&e().trackModalClose(r,i)}catch{}},trackModalStateChange:r=>{try{e().isEnabled()&&e().trackModalStateChange(r)}catch{}},trackNestedContext:r=>{try{return e().isEnabled()?e().trackNestedContext(r):""}catch{return""}},trackNestedContextAccess:(r,i)=>{try{e().isEnabled()&&e().trackNestedContextAccess(r,i)}catch{}},trackComputedProperty:(r,i,l,c,d,f,h)=>{try{e().isEnabled()&&e().trackComputedProperty(r,i,l,c,d,f,h)}catch{}},trackComputedRecalc:(r,i,l,c,d,f,h)=>{try{e().isEnabled()&&e().trackComputedRecalc(r,i,l,c,d,f,h)}catch{}},setNamedActionDefinitions:r=>{try{e().isEnabled()&&e().setNamedActionDefinitions(r)}catch{}},trackNamedActionRef:r=>{try{e().isEnabled()&&e().trackNamedActionRef(r)}catch{}}};s.devTools=n,ye.log("G7Core.devTools 인터페이스 초기화 완료")}let Bo=null;function Zx(){const s=window.G7Core;return s?.__devtools?Promise.resolve(s.__devtools):Bo||(Bo=new Promise((e,n)=>{const r=window.G7Config?.coreDevToolsAsset||"/build/core/devtools.min.js",i="g7-devtools-bundle",l=()=>{const f=window.G7Core?.__devtools;f?e(f):n(new Error("DevTools 번들 로드됨 — 그러나 __devtools 미노출"))};window.G7Core=window.G7Core||{},window.G7Core.__onDevToolsReady=l;const c=document.getElementById(i);if(c){c.addEventListener("load",l,{once:!0}),c.addEventListener("error",()=>n(new Error(`DevTools 번들 로드 실패: ${r}`)),{once:!0});return}const d=document.createElement("script");d.id=i,d.src=r,d.async=!1,d.addEventListener("load",l,{once:!0}),d.addEventListener("error",()=>{Bo=null,n(new Error(`DevTools 번들 로드 실패: ${r}`))},{once:!0}),document.head.appendChild(d)}),Bo)}function eT(){const s=window.G7Core;if(!s){ye.warn("G7Core가 초기화되지 않았습니다.");return}const e=Ia.getInstance();if(e.initialize(),!e.isEnabled()){window.G7DevTools={isEnabled:()=>!1,enable:()=>{ye.log("환경설정 > 고급 설정 > 디버그 모드를 켜세요")}},_d(),ye.log("G7DevTools 비활성화됨 (디버그 모드 꺼짐)");return}tT(s,e)}async function tT(s,e){let n;try{n=await Zx()}catch(h){ye.warn("DevTools 번들 로드 실패 — 최소 API 로 폴백:",h),window.G7DevTools={isEnabled:()=>!1,enable:()=>{}},_d();return}const{DiagnosticEngine:r,getServerConnector:i,getStyleTracker:l}=n;Qx(),_d();try{l().enable(),ye.log("StyleTracker 활성화됨")}catch(h){ye.warn("StyleTracker 활성화 실패:",h)}const c=new r,d=i(),f={isEnabled:()=>e.isEnabled(),state:{get:()=>e.getState(),getHistory:()=>e.getStateHistory(),watch:(h,m)=>e.watchState(h,m)},actions:{getHistory:()=>e.getActionHistory(),watch:h=>e.watchActions(h),getMetrics:()=>e.getActionMetrics()},binding:{evaluate:h=>{const m=s.getDataBindingEngine?.();if(!m){ye.warn("DataBindingEngine이 없습니다.");return}return m.evaluateExpression(h,e.getState())},getCacheStats:()=>e.getCacheStats(),clearStats:()=>{e.resetCacheStats(),ye.log("캐시 통계 초기화됨")}},diagnose:{analyze:h=>c.analyze(h),suggestFix:h=>c.suggestFix(h),getCommonIssues:()=>c.getCommonIssues(),getRulesByCategory:h=>c.getRulesByCategory(h)},server:{dumpState:h=>d.dumpState(h),sendLog:h=>d.sendLog(h),sendError:(h,m)=>d.sendError(h,m),isConnected:()=>d.isConnected(),testConnection:()=>d.testConnection()},config:{isDebugMode:()=>e.isEnabled(),setLogLevel:h=>e.setLogLevel(h),setMaxHistory:h=>e.setMaxHistory(h)},lifecycle:{getMountedComponents:()=>e.getLifecycleInfo().mountedComponents,getOrphanedListeners:()=>e.getLifecycleInfo().orphanedListeners},performance:{getRenderCount:()=>e.getPerformanceInfo().renderCounts,getBindingEvalCount:()=>e.getPerformanceInfo().bindingEvalCount,getMemoryWarnings:()=>e.getPerformanceInfo().memoryWarnings,startProfiling:()=>e.startProfiling(),stopProfiling:()=>e.stopProfiling()},network:{getActiveRequests:()=>e.getNetworkInfo().activeRequests,getRequestHistory:()=>e.getNetworkInfo().requestHistory,getPendingDataSources:()=>e.getNetworkInfo().pendingDataSources},conditional:{getIfConditions:()=>e.getConditionalInfo().ifConditions,getIterations:()=>e.getConditionalInfo().iterations},form:{getForms:()=>e.getFormInfo()},websocket:{getInfo:()=>e.getWebSocketInfo()}};window.G7DevTools=f,s.devtools=f,ye.log("G7DevTools 전역 객체 초기화 완료 (window.G7DevTools)"),nT(n.DevToolsPanel)}function nT(s){if(document.getElementById("g7-devtools-root")){ye.log("DevToolsPanel 이미 렌더링됨");return}const e=document.createElement("div");e.id="g7-devtools-root",document.body.appendChild(e);try{Cd.createRoot(e).render(Ye.createElement(s)),ye.log("DevToolsPanel UI 렌더링 완료")}catch(n){ye.error("DevToolsPanel UI 렌더링 실패:",n)}}const Je=dt("TemplateEngine"),ae={templateId:null,locale:"ko",isInitialized:!1,reactRoot:null,containerId:null,currentLayoutJson:null,currentDataContext:{},translationContext:{templateId:"",locale:"ko"},registry:null,bindingEngine:null,translationEngine:null,actionDispatcher:null,templateMetadata:null};let qo=!1;const Go=[];async function rT(s){try{Je.log("템플릿 메타데이터 로드 중...",s);const e=s.split("-").map(r=>r.split("_").map(i=>i.charAt(0).toUpperCase()+i.slice(1)).join("")).join(""),n=window[e];return n?.templateMetadata?(Je.log("템플릿 메타데이터 로드 완료 (전역 변수)",n.templateMetadata),n.templateMetadata):(Je.warn(`템플릿 번들에 메타데이터가 없습니다. 전역 변수: ${e}`),{identifier:s,locales:["ko","en"],name:{ko:s,en:s},description:{ko:"",en:""},version:"1.0.0",type:"admin"})}catch(e){return Je.error("템플릿 메타데이터 로드 실패",e),{identifier:s,locales:["ko","en"],name:{ko:s,en:s},description:{ko:"",en:""},version:"1.0.0",type:"admin"}}}function ub(){const e=(typeof window<"u"?window.__templateApp:void 0)?.globalState?.appConfig?.supportedLocales,n=ae.templateMetadata?.locales;return{$locale:ae.locale,$locales:Array.isArray(e)&&e.length>0?e:n||["ko","en"],$templateLocales:n||["ko","en"],$templateId:ae.templateId}}async function Fo(s){try{if(Je.log("템플릿 엔진 초기화 시작",s),ae.isInitialized)throw new Error("템플릿 엔진이 이미 초기화되었습니다. destroyTemplate()을 먼저 호출하세요.");if(!s.templateId)throw new QA;qo=s.debug??!1,typeof window<"u"&&(window.G7Config||(window.G7Config={}),window.G7Config.debug=qo),eT(),ae.templateId=s.templateId,ae.locale=s.locale||"ko",Je.log("엔진 인스턴스 생성 중..."),ae.registry=br.getInstance(),ae.bindingEngine=new kn,ae.translationEngine=Ra.getInstance(),s.cacheVersion!==void 0&&s.cacheVersion>0&&ae.translationEngine.setCacheVersion(s.cacheVersion),ae.translationContext={templateId:s.templateId,locale:ae.locale},ae.actionDispatcher=new ko({},ae.translationEngine,ae.translationContext),pE(ae.actionDispatcher),Je.log("다국어 파일 로드 중...",s.templateId,ae.locale);const e="en",n=[ae.translationEngine.loadTranslations(s.templateId,ae.locale).then(()=>{Je.log(`다국어 파일 로드 완료: ${ae.locale}`)}).catch(r=>{Je.warn(`다국어 파일 로드 실패 (${ae.locale}):`,r instanceof Error?r.message:r)})];ae.locale!==e&&n.push(ae.translationEngine.loadTranslations(s.templateId,e).then(()=>{Je.log(`폴백 다국어 파일 로드 완료: ${e}`)}).catch(r=>{Je.warn(`폴백 다국어 파일 로드 실패 (${e}):`,r instanceof Error?r.message:r)})),await Promise.allSettled(n),Je.log("템플릿 메타데이터 로드 중...",s.templateId),ae.templateMetadata=await rT(s.templateId),ae.isInitialized=!0,Je.log("템플릿 엔진 초기화 완료 (ComponentRegistry는 별도 로드)")}catch(e){throw Je.error("템플릿 엔진 초기화 실패",e),ae.isInitialized=!1,ae.registry=null,ae.bindingEngine=null,ae.translationEngine=null,ae.actionDispatcher=null,e}}let Es=null;const db="g7-layout-editor-bundle";function ah(){const s=window.G7Core;return s?.__LayoutEditorChrome?Promise.resolve(s.__LayoutEditorChrome):Es||(Es=(async()=>{const e=window.G7Config?.coreEditorAsset||"/build/core/layout-editor.min.js";document.getElementById(db)?.remove(),window.G7Core=window.G7Core||{},window.G7Core.__onChromeReady=()=>{};try{await ra(e,{id:db},{label:"layout-editor bundle"})}catch(r){throw Es=null,Je.error(`편집기 번들 로드 실패 (${e})`,r),new Error("편집기를 불러오지 못했습니다. 네트워크 상태를 확인한 뒤 다시 시도해 주세요.")}const n=window.G7Core?.__LayoutEditorChrome;if(!n)throw Es=null,Je.error(`편집기 번들 로드됨 — 그러나 __LayoutEditorChrome 미노출 (${e})`),new Error("편집기를 불러왔으나 초기화하지 못했습니다. 페이지를 새로고침해 주세요.");return n})(),Es)}async function _s(s){try{if(Je.log("템플릿 렌더링 시작",s),!ae.isInitialized)throw new Error("템플릿 엔진이 초기화되지 않았습니다. initTemplateEngine()을 먼저 호출하세요.");if(!s.containerId)throw new Error("containerId는 필수입니다.");if(!s.layoutJson)throw new Error("layoutJson은 필수입니다.");const e=document.getElementById(s.containerId);if(!e)throw new Error(`컨테이너를 찾을 수 없습니다: #${s.containerId}`);const n=ub();if(ae.containerId=s.containerId,ae.currentLayoutJson=s.layoutJson,ae.currentDataContext={...n,...s.dataContext||{}},ae.translationContext=s.translationContext||{templateId:ae.templateId||"",locale:ae.locale},ae.reactRoot||(Je.log("React Root 생성"),ae.reactRoot=Cd.createRoot(e)),typeof window<"u"){const l=eb(window.location.pathname);if(l){Je.log("레이아웃 편집기 모드 진입",l);let c;try{c=await ah()}catch(f){Je.error("레이아웃 편집기 번들 로드 실패",f),Zf.render(s.containerId,{title:"레이아웃 편집기 로드 실패",message:f instanceof Error?f.message:"편집기 번들을 불러오지 못했습니다.",icon:"fas fa-triangle-exclamation",showStack:!1,showReloadButton:!0,debug:qo});return}const d=Ye.createElement(c,{templateIdentifier:l.templateIdentifier,initialLocale:ae.locale});ae.reactRoot.render(Ye.createElement(Lc,{translationEngine:ae.translationEngine,translationContext:ae.translationContext,children:Ye.createElement(Cf,{children:Ye.createElement(bc,{children:Ye.createElement(Wf,{children:d})})})}));return}}const r=s.layoutJson.components||[];if(r.length===0){Je.warn("렌더링할 컴포넌트가 없습니다.");return}const i=s.layoutJson.modals||[];if(Je.log("modals 배열:",i),Je.log("modals 개수:",i.length),Je.log("DynamicRenderer로 렌더링 시작"),ae.reactRoot.render(Ye.createElement(Lc,{translationEngine:ae.translationEngine,translationContext:ae.translationContext},Ye.createElement(Cf,null,Ye.createElement(bc,null,Ye.createElement(Wf,null,[...r.map((l,c)=>{const d=ae.currentLayoutJson?.layout_name||"";return Ye.createElement(Br,{key:d&&!l._fromBase?`${l.id}_${d}`:l.id,componentDef:l,dataContext:ae.currentDataContext,translationContext:ae.translationContext,registry:ae.registry,bindingEngine:ae.bindingEngine,translationEngine:ae.translationEngine,actionDispatcher:ae.actionDispatcher,isRootRenderer:c===0,layoutKey:d})}),Ye.createElement(Fm,{key:"__modal_parent_context_provider"},i.map(l=>{const c=ae.currentDataContext._global?.modalStack||[],f=c.includes(l.id)||ae.currentDataContext._global?.activeModal===l.id,h=c.indexOf(l.id),m=h>=0?50+h:50,y=window.__g7LayoutContextStack||[],v=y[y.length-1]?.dataContext,_=Ye.createElement(Br,{key:`modal_${l.id}_renderer`,componentDef:{...l,props:{...l.props,isOpen:f,style:{...l.props?.style,zIndex:m},onClose:ae.actionDispatcher?.createHandler({type:"click",handler:"closeModal"},ae.currentDataContext)}},dataContext:ae.currentDataContext,translationContext:ae.translationContext,registry:ae.registry,bindingEngine:ae.bindingEngine,translationEngine:ae.translationEngine,actionDispatcher:ae.actionDispatcher,parentDataContext:v});return l.data_sources&&l.data_sources.length>0?Ye.createElement(Qy,{key:`modal_${l.id}`,isOpen:f,modalId:l.id,dataSources:l.data_sources,dataContext:ae.currentDataContext,globalStateUpdater:ae.actionDispatcher?.getGlobalStateUpdater(),bindingEngine:ae.bindingEngine,debug:qo,children:_}):_}))]))))),Je.log("템플릿 렌더링 완료"),Go.length>0){Je.log(`대기 중인 데이터 업데이트 ${Go.length}건 적용`);const l=[...Go];Go.length=0;for(const{data:c,options:d}of l)As(c,d)}}catch(e){throw Je.error("템플릿 렌더링 실패",e),e}}function As(s,e){try{if(Je.log("템플릿 데이터 업데이트 시작",Object.keys(s)),!ae.isInitialized)throw new Error("템플릿 엔진이 초기화되지 않았습니다.");if(!ae.reactRoot||!ae.currentLayoutJson){Je.log("React 미준비 - 데이터 업데이트 큐잉:",Object.keys(s)),Go.push({data:s,options:e});return}const n=ub(),r={...ae.currentDataContext._global||{},...s._global||{}},i=wE(ae.currentDataContext._localInit,s._localInit);ae.currentDataContext={...n,...ae.currentDataContext,...s,_global:r,_localInit:i},r._local!==void 0&&(ae.currentDataContext._local=r._local),r._computed!==void 0&&(ae.currentDataContext._computed=r._computed);const l=ae.currentLayoutJson.components||[],c=ae.currentLayoutJson.modals||[];Je.log("updateTemplateData - modals 배열:",c),Je.log("updateTemplateData - modals 개수:",c.length),Je.log("updateTemplateData - activeModal:",ae.currentDataContext._global?.activeModal);const d=()=>{ae.reactRoot.render(Ye.createElement(Lc,{translationEngine:ae.translationEngine,translationContext:ae.translationContext},Ye.createElement(Cf,null,Ye.createElement(bc,null,Ye.createElement(Wf,null,[...l.map((f,h)=>{const m=ae.currentLayoutJson?.layout_name||"";return Ye.createElement(Br,{key:m&&!f._fromBase?`${f.id}_${m}`:f.id,componentDef:f,dataContext:ae.currentDataContext,translationContext:ae.translationContext,registry:ae.registry,bindingEngine:ae.bindingEngine,translationEngine:ae.translationEngine,actionDispatcher:ae.actionDispatcher,isRootRenderer:h===0,layoutKey:m})}),Ye.createElement(Fm,{key:"__modal_parent_context_provider_update"},c.map(f=>{const h=ae.currentDataContext._global?.modalStack||[],y=h.includes(f.id)||ae.currentDataContext._global?.activeModal===f.id,S=h.indexOf(f.id),v=S>=0?50+S:50,_=window.__g7LayoutContextStack||[],A=_[_.length-1]?.dataContext,L=Ye.createElement(Br,{key:`modal_${f.id}_renderer`,componentDef:{...f,props:{...f.props,isOpen:y,style:{...f.props?.style,zIndex:v},onClose:ae.actionDispatcher?.createHandler({type:"click",handler:"closeModal"},ae.currentDataContext)}},dataContext:ae.currentDataContext,translationContext:ae.translationContext,registry:ae.registry,bindingEngine:ae.bindingEngine,translationEngine:ae.translationEngine,actionDispatcher:ae.actionDispatcher,parentDataContext:A});return f.data_sources&&f.data_sources.length>0?Ye.createElement(Qy,{key:`modal_${f.id}`,isOpen:y,modalId:f.id,dataSources:f.data_sources,dataContext:ae.currentDataContext,globalStateUpdater:ae.actionDispatcher?.getGlobalStateUpdater(),bindingEngine:ae.bindingEngine,debug:qo,children:L}):L}))])))))};e?.sync?(Je.log("재렌더링 시작 (sync mode - 즉시 렌더링)"),d()):(Je.log("재렌더링 시작 (with startTransition)"),N.startTransition(()=>{d()})),Je.log("템플릿 데이터 업데이트 완료")}catch(n){throw Je.error("템플릿 데이터 업데이트 실패",n),n}}function Pc(){try{Je.log("템플릿 정리 시작"),ae.reactRoot&&(Je.log("React Root 언마운트"),ae.reactRoot.unmount(),ae.reactRoot=null),ae.templateId=null,ae.locale="ko",ae.isInitialized=!1,ae.containerId=null,ae.currentLayoutJson=null,ae.currentDataContext={},ae.translationContext={templateId:"",locale:"ko"},ae.registry=null,ae.bindingEngine=null,ae.translationEngine=null,ae.actionDispatcher=null,ae.templateMetadata=null,Je.log("템플릿 정리 완료")}catch(s){throw Je.error("템플릿 정리 실패",s),s}}function sa(){return Object.freeze({...ae})}function fb(){return ae.actionDispatcher}const Vo={initTemplateEngine:Fo,renderTemplate:_s,updateTemplateData:As,destroyTemplate:Pc,getState:sa};typeof window<"u"&&(window.G7Core||(window.G7Core={}),window.G7Core.TemplateEngine=Vo,Jx({getState:()=>({translationEngine:ae.translationEngine,translationContext:ae.translationContext,bindingEngine:ae.bindingEngine,actionDispatcher:ae.actionDispatcher,templateMetadata:ae.templateMetadata}),transitionManager:Ur,responsiveManager:Si,webSocketManager:Nc}),Je.log("전역 객체 window.G7Core.TemplateEngine에 노출됨"));const Gr=Object.freeze(Object.defineProperty({__proto__:null,DataSourceManager:Tr,LayoutLoader:Vf,TemplateApp:Uo,TemplateEngine:Vo,default:Vo,destroyTemplate:Pc,getActionDispatcher:fb,getState:sa,initTemplateApp:rh,initTemplateEngine:Fo,loadLayoutEditorBundle:ah,renderTemplate:_s,updateTemplateData:As},Symbol.toStringTag,{value:"Module"}));Xt.DataSourceManager=Tr,Xt.LayoutLoader=Vf,Xt.TemplateApp=Uo,Xt.TemplateEngine=Vo,Xt.default=Vo,Xt.destroyTemplate=Pc,Xt.getActionDispatcher=fb,Xt.getState=sa,Xt.initTemplateApp=rh,Xt.initTemplateEngine=Fo,Xt.loadLayoutEditorBundle=ah,Xt.renderTemplate=_s,Xt.updateTemplateData=As,Object.defineProperties(Xt,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})})(this.G7Core=this.G7Core||{}); diff --git a/resources/js/core/modules/__tests__/ModuleAssetLoader.test.ts b/resources/js/core/modules/__tests__/ModuleAssetLoader.test.ts index 7f9dd7b2..ca17d2f8 100644 --- a/resources/js/core/modules/__tests__/ModuleAssetLoader.test.ts +++ b/resources/js/core/modules/__tests__/ModuleAssetLoader.test.ts @@ -105,6 +105,66 @@ describe('ModuleAssetLoader', () => { }); }); + /** + * 사용자 추가 에셋(`custom/`)의 정적 게시 폴백 (#122 R2/W9). + * + * 스타일(`type: 'style'`) 축은 형제 파일 `ModuleAssetLoader.customAssets.test.ts` + * 가 세 확장 타입 전부에 대해 이미 고정하고 있다. 여기 남기는 것은 그 파일이 덮지 + * 않는 **스크립트 축**뿐이다 — 스타일은 `loadStylesheetWithRetry`, 스크립트는 + * `loadScriptWithRetry` 로 서로 다른 로더를 타므로 한쪽의 통과가 다른 쪽의 근거가 + * 되지 않는다. + */ + describe('loadCustomAssets 정적 게시 폴백 — script 축 (#122 R2/W9)', () => { + afterEach(() => { + delete (window as any).G7Config; + document.querySelectorAll('[id^="g7-custom-"]').forEach(el => el.remove()); + }); + + /** + * @effects custom_asset_static_miss_falls_back_to_api + */ + it('정적 게시 JS 미스 시 레거시 API URL 로 전환한다', async () => { + (window as any).G7Config = { + customAssets: [ + { + id: 'custom:modules:sirsoft-board:custom.js', + type: 'script', + url: '/build/ext/42/modules/sirsoft-board/assets/custom/custom.js', + }, + ], + }; + + const urls: string[] = []; + const appendSpy = vi.spyOn(document.head, 'appendChild').mockImplementation(((node: any) => { + if (node.tagName === 'SCRIPT') { + urls.push(node.getAttribute('src')); + document.body.appendChild(node); + + const failed = urls.length === 1; + queueMicrotask(() => { + if (failed) { + node.onerror?.(new Event('error')); + } else { + node.onload?.(new Event('load')); + } + }); + } + return node; + }) as any); + + try { + await loader.loadCustomAssets(); + + expect(urls).toEqual([ + '/build/ext/42/modules/sirsoft-board/assets/custom/custom.js', + '/api/modules/assets/sirsoft-board/custom/custom.js?v=42', + ]); + } finally { + appendSpy.mockRestore(); + } + }); + }); + describe('loadActiveExtensionAssets', () => { it('JS 에셋을 priority 오름차순으로 DOM에 append한다 (실행 순서 보장)', async () => { const appendOrder: string[] = []; diff --git a/resources/js/core/support/__tests__/fetchStaticFirst.test.ts b/resources/js/core/support/__tests__/fetchStaticFirst.test.ts index 0ddb8dcb..30f56f8e 100644 --- a/resources/js/core/support/__tests__/fetchStaticFirst.test.ts +++ b/resources/js/core/support/__tests__/fetchStaticFirst.test.ts @@ -13,13 +13,32 @@ import { fetchStaticFirst } from '../fetchStaticFirst'; import { extStaticUrl, extStaticVersion, staticToLegacy } from '../assetUrl'; function ok(body: unknown = {}): Response { + const text = JSON.stringify(body); + return { ok: true, status: 200, + statusText: 'OK', + headers: new Headers({ 'Content-Type': 'application/json' }), + text: async () => text, json: async () => body, } as unknown as Response; } +/** + * 200 인데 본문이 잘린 응답 — 디스크 풀/quota 로 절단된 게시본이 서빙되는 상황. + */ +function truncated(raw: string): Response { + return { + ok: true, + status: 200, + statusText: 'OK', + headers: new Headers({ 'Content-Type': 'application/json' }), + text: async () => raw, + json: async () => JSON.parse(raw), + } as unknown as Response; +} + function notFound(): Response { return { ok: false, status: 404 } as unknown as Response; } @@ -50,6 +69,36 @@ describe('fetchStaticFirst (#122)', () => { expect(String(fetchMock.mock.calls[0][0])).toContain('/build/ext/7/'); }); + it('정적 200 이어도 본문이 손상 JSON 이면 legacy 로 폴백한다 (#122 A1)', async () => { + // 디스크 풀/quota 로 절단된 게시본은 웹서버가 **정상 200** 으로 서빙한다. + // `response.ok` 만 보고 돌려주면 호출부의 `.json()` 이 던지는데 그 지점에는 + // 폴백이 없어 부팅 전체가 실패한다 — 3층 폴백이 개입 못 하던 유일한 경로. + fetchMock.mockImplementation((url: string) => + Promise.resolve( + String(url).includes('/build/ext/') + ? truncated('{"messages":{"a":"b"') + : ok({ from: 'legacy' }) + ) + ); + + const response = await fetchStaticFirst('/build/ext/7/templates/t/lang/ko.json', '/api/templates/t/lang/ko.json'); + + await expect(response.json()).resolves.toEqual({ from: 'legacy' }); + expect(fetchMock).toHaveBeenCalledTimes(2); + expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('malformed JSON')); + }); + + it('정적 200 + 온전한 JSON 은 본문이 그대로 소비된다 (검증이 본문을 삼키지 않는다)', async () => { + // 검증을 위해 body 를 읽으므로, 읽고 나서 호출부가 다시 소비할 수 있어야 한다. + // (Response body 는 1회용 스트림이라 그대로 돌려주면 호출부에서 빈다.) + fetchMock.mockResolvedValue(ok({ from: 'static', nested: { a: 1 } })); + + const response = await fetchStaticFirst('/build/ext/7/templates/t/routes.json', '/api/templates/t/routes.json'); + + await expect(response.json()).resolves.toEqual({ from: 'static', nested: { a: 1 } }); + expect(fetchMock).toHaveBeenCalledTimes(1); + }); + it('정적 404 이면 legacy 로 1회 폴백하고 warn 을 남긴다', async () => { fetchMock.mockImplementation((url: string) => Promise.resolve(String(url).includes('/build/ext/') ? notFound() : ok({ from: 'legacy' })) diff --git a/resources/js/core/support/fetchStaticFirst.ts b/resources/js/core/support/fetchStaticFirst.ts index 95e7ed14..9e8e10ee 100644 --- a/resources/js/core/support/fetchStaticFirst.ts +++ b/resources/js/core/support/fetchStaticFirst.ts @@ -8,6 +8,10 @@ * * legacy 측은 `fetchWithRetry` 를 재사용해 종전의 네트워크 복원력(#463)을 유지한다. * + * 정적 응답은 `ok` 뿐 아니라 **본문이 JSON 으로 파싱되는지**까지 확인한다 — 디스크 + * 풀/quota 로 절단된 게시본을 웹서버가 정상 200 으로 서빙하기 때문이다 + * (engine-v1.63.2, #122 A1). + * * @since engine-v1.61.0 */ @@ -34,7 +38,31 @@ export async function fetchStaticFirst( const response = await fetch(staticUrl, options.init); if (response.ok) { - return response; + // 200 이라고 본문이 온전하다는 뜻은 아니다. 디스크 풀/quota 에서 게시가 잘린 + // 파일을 남기면 웹서버는 그것을 **정상 200 으로** 서빙한다. `response.ok` 만 + // 보고 돌려주면 호출부의 `response.json()` 이 던지고, 그 지점에는 폴백이 없어 + // 부팅 전체가 실패한다 — 3층 폴백이 유일하게 개입하지 못하는 경로였다. + // + // 이 헬퍼의 소비자는 전부 JSON 부트스트랩 리소스(routes/lang/components)이므로 + // 파싱 가능 여부를 여기서 판정할 수 있다. 파싱은 두 번 일어나지만(여기서 검증, + // 호출부에서 소비) 그 비용은 부팅 실패와 비교할 값이 아니다. + const text = await response.text(); + + try { + JSON.parse(text); + + return new Response(text, { + status: response.status, + statusText: response.statusText, + headers: response.headers, + }); + } catch { + console.warn( + `[fetchStaticFirst] Static fast path returned malformed JSON — falling back to API: ${staticUrl}` + ); + + return fetchWithRetry(legacyUrl, options); + } } // 디버그 게이트 없는 console.warn — 폴백은 자가 치유 실패를 발견할 유일한 diff --git a/resources/js/core/template-engine/CHANGELOG.md b/resources/js/core/template-engine/CHANGELOG.md index 48953776..315a1252 100644 --- a/resources/js/core/template-engine/CHANGELOG.md +++ b/resources/js/core/template-engine/CHANGELOG.md @@ -5,6 +5,15 @@ > > 형식: [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/) +## [engine-v1.63.2] - 2026-08-27 + +### Fixed + +#### 정적 게시본이 200 인데 본문이 손상된 경우 폴백하지 못하던 문제 (#122) + +- `fetchStaticFirst()` 가 정적 응답의 본문이 **JSON 으로 파싱되는지까지** 확인한 뒤 돌려준다. 종전에는 `response.ok` 만 보았는데, 디스크가 가득 찼거나 quota 를 넘긴 상태에서 만들어진 게시본은 내용이 중간에 잘린 채로도 웹서버가 정상 200 으로 서빙한다. 그러면 폴백이 걸리지 않은 채 호출부의 `response.json()` 이 예외를 던지고, 그 지점에는 폴백 계층이 없어 화면 전체가 뜨지 않았다 — 정적·API·태그 3층 폴백이 유일하게 개입하지 못하던 경로다. 이제 손상이 확인되면 종전 API 로 폴백하고, 폴백 사실을 콘솔 경고 한 줄로 남긴다(조용한 폴백 금지). +- 검증을 위해 본문을 읽더라도 호출부가 그대로 다시 소비할 수 있다 — 응답 본문은 1회용 스트림이라, 읽고 그대로 돌려주면 호출부에서 빈 본문이 된다. + ## [engine-v1.63.1] - 2026-08-27 ### Fixed diff --git a/resources/views/dev-dashboard.blade.php b/resources/views/dev-dashboard.blade.php index 2809ce64..ac07827e 100644 --- a/resources/views/dev-dashboard.blade.php +++ b/resources/views/dev-dashboard.blade.php @@ -1079,6 +1079,10 @@ if (isset($_GET['ajax_action'])) { 정적 게시 정리 (ext-static:cleanup) +