diff --git a/AGENTS.md b/AGENTS.md index 2b2bfebe..94eadf63 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -41,7 +41,7 @@ | [service-provider.md](docs/backend/service-provider.md) | 서비스 프로바이더 안전성 | DB 접근 전 .env 파일 존재 확인 필수 | | [service-repository.md](docs/backend/service-repository.md) | Service-Repository 패턴 | RepositoryInterface 주입 필수 (구체 클래스 직접 주입 금지) | | [settings-multilingual-enrichment.md](docs/backend/settings-multilingual-enrichment.md) | Settings 카탈로그 다국어 자동 보강 | settings JSON 의 다국어 카탈로그 라벨(_cached_name 등)은 카탈로그 빌드 시점에 보강 | -| [static-asset-publishing.md](docs/backend/static-asset-publishing.md) | 부트스트랩 리소스 정적 게시 (Static Asset Publishing) | 게시물: public/build/ext/{cache_version}/ — 수명주기 이벤트마다 termi... | +| [static-asset-publishing.md](docs/backend/static-asset-publishing.md) | 부트스트랩 리소스 정적 게시 (Static Asset Publishing) | 게시물: public/build/ext/{cache_version}/ — 수명주기 이벤트와 운영자 cu... | | [translatable-seeders.md](docs/backend/translatable-seeders.md) | 다국어 시더 인터페이스 (Translatable Seeders) | 다국어 JSON 컬럼(name 등)을 시드하는 확장 entity 시더는 TranslatableSeede... | | [user-overrides.md](docs/backend/user-overrides.md) | 사용자 수정 보존 (HasUserOverrides Trait) | 모델에 `use HasUserOverrides;` + `protected array $trackable... | | [validation.md](docs/backend/validation.md) | 검증 (Validation) | 필수: FormRequest에서 검증 (Service에 검증 로직 배치 금지) | @@ -153,7 +153,7 @@ | 대상 | 진입점 | 문서/엔드포인트 | |------|--------|----------------| -| 코어 | [docs/backend/api/README.md](docs/backend/api/README.md) | 36 / 319 | +| 코어 | [docs/backend/api/README.md](docs/backend/api/README.md) | 36 / 324 | ### 확장 API 레퍼런스 (14개 확장, 자동 스캔) @@ -416,6 +416,31 @@ Icon 은 `` 글리프라 박스 크기가 곧 `font-size` 다. `w-N h-N` 은 > 상세: [validation.md](docs/backend/validation.md), [service-repository.md](docs/backend/service-repository.md), [frontend/security.md](docs/frontend/security.md) +### 확장·템플릿 구동 에셋은 자체 제공한다 + +브라우저가 화면을 그리기 위해 제3자 CDN 에 도달해야 하면, 그 도달 실패는 **예외도 로그도 남기지 않고 화면 기능만 조용히 사라진다.** 폐쇄망·방화벽·광고차단기에서 재현되며 자체 서버 로그에 흔적이 없어 운영자가 원인을 특정할 수 없다. + +| ❌ 금지 | ✅ 올바른 사용 | +|--------|---------------| +| 구동 자산(js/css/웹폰트)을 외부 CDN 에서 실시간 로드 | 확장이 `dist/vendor/{lib}/{version}/` 에 동봉하고 same-origin 서빙 | +| `trusted_script_hosts` 만 선언하고 사유는 생략 | `trusted_script_hosts_reason` 에 호스트별 사유 동반 — 자체 제공이 원칙이고 예외는 근거가 코드에 남는다 | +| 자산 URL 을 문자열로 조립 (`'/api/plugins/assets/'+id+'/…'`) | `G7Core.asset.{template,module,plugin}` — 확장자를 정적 location 이 가로채는 서버에서 조립 URL 만 404 가 된다 | +| AMD 로더·워커에 `G7Core.asset.template()` 결과를 base 로 전달 | `G7Core.asset.templateDir()` — 쿼리 형태(`?file=`)는 뒤에 파일명을 이어 붙일 수 없다. 확장자 없는 모드에서 404 일 수 있으므로 **소비자가 폴백을 갖춘다** | +| CSS 로드에 `onerror` 미설치 또는 `resolve()` 로 삼킴 | `loadStylesheetWithRetry` — 아이콘만으로 조작하는 버튼이 있는 화면에서 스타일 소실은 곧 조작 불능이다 | +| 자산 실패를 `console.error` 한 줄로 끝냄 | `G7Core.assets.notifyFailure({id,label,retry})` — 사용자가 사실을 알고 조치할 수 있어야 한다 | +| 편집기·코드편집기 확보 실패 시 빈 컨테이너를 남김 | 평문 입력(textarea) 폴백 + 저장 계약 유지(`{name}_mode='text'`) + 재시도 시 입력 내용 승계 | +| 확장 `dist/`·`src/` 에 운영자 CSS 를 둠 | 확장 디렉토리 안의 **`custom/`** — 빌드 불필요, 확장 교체가 보존 | +| 번들 확장이 `custom/` 을 담아 배포 | `dist/vendor/` 에 담는다. `custom/` 은 운영자 소유라 보존 계층이 덮어쓰지 않아 **저작자 파일이 영영 반영되지 않는다** | +| 사용자 추가 에셋 URL 을 `ext.cache_version` 으로 무효화 | 파일 서명(수정 시각) — 확장 캐시 버전은 운영자가 파일을 고쳤다고 오르지 않는다 | +| `custom/` 보존을 rename 경로에만 적용 | 교체 **두 경로 모두**(rename · 제자리 동기화 폴백) — 한쪽만 고치면 Windows 잠금 상황에서만 조용히 사라진다 | + +동봉 자산은 배포 산출물이므로 `sourceMappingURL` 참조를 남기지 않는다(`.map` 은 gitignore 대상이라 404 가 된다). 인라인 여부는 "없으면 조작 불능인가" 로 가른다 — 아이콘 폰트는 인라인, 글꼴·장식 아이콘은 파일 분리(자산 URL 이 쿼리 형태가 되는 서버에서 CSS 내부 상대 `url()` 이 해석되지 않는 조합이 남는다). + +사용자 추가 에셋(`custom/`)은 **출처에 의존하지 않는 서술자**로 해석하고 `core.assets.custom_assets` 필터 훅을 해석기 끝에 둔다. 소비자(뷰 컴포저·프론트 로더·서빙)가 출처를 보면, 나중에 다른 출처(템플릿 환경설정의 화면 입력 등)가 붙을 때 평행 경로가 생기고 "운영자 CSS 가 어디서 오는가" 의 SSoT 가 둘로 갈린다. + +> 상세: [module-assets.md](docs/extension/module-assets.md) "사용자 추가 에셋", [static-asset-publishing.md](docs/backend/static-asset-publishing.md) +> 정적 검사가 외부 자산 URL 과 번들 확장의 `custom/` 배포를 차단한다. 서술자 형태와 교체 2경로 보존은 테스트가 잠근다. + ### 목록 응답의 하위 컬렉션 목록은 화면이 그 행에서 **실제로 그리는 것**만 싣는다. 행마다 하위 컬렉션을 통째로 직렬화하면 한 페이지를 여는 것만으로 수백~수천 행이 응답에 실린다 (공개 #76 — 상품 100건 × 옵션 20건). diff --git a/CHANGELOG.md b/CHANGELOG.md index f41a8665..b43a6845 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,14 +8,24 @@ ### Added +- 화면 구동에 필요한 아이콘·글꼴·편집기 등을 외부 CDN 이 아니라 사이트 자신의 서버에서 불러옵니다. 폐쇄망이나 외부 접속이 제한된 환경에서도 관리자·사용자 화면이 정상 동작합니다. 외부 연결이 필요한 기능은 주소 검색 하나만 남았습니다. (#123 @bigmsg 님께서 건의해주셨습니다.) +- 운영자가 자기 CSS·JS 를 덧붙일 자리를 각 확장이 제공합니다. 확장 디렉토리의 `custom/` 에 파일을 놓으면 빌드 없이 바로 적용되고, 확장을 업데이트해도 그 파일은 지워지지 않습니다. 적용 순서는 항상 확장 스타일보다 뒤라서 재정의가 그대로 반영됩니다. (sir.kr 커뮤니티에서 문의해주신 내용입니다.) +- 화면에 필요한 파일을 끝내 불러오지 못하면 안내와 [다시 시도] 를 표시합니다. 아이콘 글꼴이나 본문 글꼴처럼 페이지가 직접 불러오는 파일도 대상이라, 아이콘이 통째로 사라져 버튼을 못 누르게 되는 상황에서도 원인이 화면에 남습니다. 종전에는 아무 표시 없이 기능만 사라져 원인을 알 수 없었습니다. (#123 @bigmsg 님께서 건의해주셨습니다.) +- 설치 마법사와 개발 대시보드도 외부 CDN 없이 동작합니다. +- 확장을 삭제할 때 `custom/` 에 넣어 둔 운영자 파일을 먼저 사본으로 보관하고, 그 보관 경로를 삭제 결과에 함께 알립니다. 관리자 화면과 콘솔 양쪽에서 확인할 수 있습니다. +- 운영자가 덧붙인 CSS·JS·글꼴·이미지를 레이아웃 편집기 화면에서 직접 넣고 고칠 수 있습니다. 서버 접속 없이 파일을 만들고 편집하고 지울 수 있으며, 저장하면 다음 화면부터 바로 반영됩니다. 편집 중인 템플릿뿐 아니라 설치된 모듈·플러그인도 대상으로 고를 수 있습니다. 이 기능은 레이아웃 편집과 별도의 「커스텀 자산 관리」 권한으로 열립니다 — 여기서 올린 스크립트는 사이트 전 화면에서 실행되기 때문입니다. (#123 @bigmsg 님께서 건의해주셨습니다.) +- 주소 끝에 `?custom=off` 를 붙여 열면 운영자가 추가한 CSS·JS 없이 화면이 표시됩니다. 추가한 스타일이 화면을 망가뜨려 고치러 들어갈 수조차 없게 된 상황에서 쓰는 탈출구이며, 레이아웃 편집기 툴바에도 같은 동작의 버튼이 있습니다. 이 설정은 저장되지 않고 그 화면에만 적용됩니다. +- 템플릿·모듈·플러그인의 `custom/` 파일이 다른 확장 자산과 같은 방식으로 정적 파일로 게시됩니다. CSS 안에서 글꼴·이미지를 상대 경로(`url('./font.woff2')`)로 참조할 수 있게 되었고, 파일을 고치면 자동으로 다시 게시됩니다. - 초기 화면에 필요한 다국어·컴포넌트 정의·라우트 정보·확장 번들·템플릿 에셋을 정적 파일로 미리 만들어 웹서버가 직접 전달합니다. 확장 설치/활성화나 레이아웃 편집 시 자동으로 다시 생성되며, 파일이 없으면 기존 방식으로 동작합니다. 초기 화면 표시가 빨라집니다. (#122 @glitter-gim 님께서 건의해주셨습니다.) ### Changed - 템플릿 컴포넌트 정의·다국어·라우트 응답에 조건부 캐시(ETag)가 적용되어, 변경이 없으면 본문 전송 없이 캐시를 재사용합니다. (#122 @glitter-gim 님께서 건의해주셨습니다.) +- 레이아웃 편집기를 여는 중 네트워크가 잠시 끊겨도 자동으로 다시 시도합니다. 끝내 실패하면 내부 파일 경로 대신 다음에 무엇을 하면 되는지를 안내합니다. ### Fixed +- 확장 설치가 의존성·버전 검사에서 실패해도 복사된 파일이 남아, 목록에도 보이지 않는 디렉토리가 쌓이던 문제를 수정했습니다. 실패한 설치는 이번에 만든 파일을 되돌립니다(이미 설치돼 있던 확장을 다시 설치하다 실패한 경우에는 기존 파일을 건드리지 않습니다). - 사이트 첫 접속 시 확장 캐시 버전이 어긋나 있으면 라우트·다국어 데이터를 두 번 내려받던 문제를 수정했습니다. (#122 @glitter-gim 님께서 건의해주셨습니다.) - 레이아웃 props 의 `$switch` 조건 분기 값이 검색엔진(봇) 화면에서는 해석되지 않아 해당 속성이 표시되지 않던 문제를 수정했습니다. 이제 일반 화면과 봇 화면이 동일하게 분기 값을 렌더링합니다. - sudo(root) 로 코어를 업데이트하면 업데이트 과정이 만든 캐시 파일이 root 소유로 남아, 이후 웹 화면 전체가 서버 오류(500)가 되거나 캐시가 동작하지 않을 수 있던 문제를 수정했습니다. 업데이트 종료 시 캐시·번들 디렉토리 소유권을 자동 정상화하고, 캐시 쓰기 실패는 화면을 중단시키지 않고 경고 로그와 함께 무캐시로 계속 동작합니다. diff --git a/app/Console/Commands/Concerns/PrunesBuildOutput.php b/app/Console/Commands/Concerns/PrunesBuildOutput.php new file mode 100644 index 00000000..ecc54442 --- /dev/null +++ b/app/Console/Commands/Concerns/PrunesBuildOutput.php @@ -0,0 +1,69 @@ + $preserve 삭제하지 않을 최상위 항목명 + * @return array 삭제한 최상위 항목명 목록 + */ + private function pruneBuildOutput(string $buildPath, array $preserve = ['vendor']): array + { + $distPath = rtrim($buildPath, '/\\').DIRECTORY_SEPARATOR.'dist'; + + if (! File::isDirectory($distPath)) { + return []; + } + + $removed = []; + + foreach (new \FilesystemIterator($distPath, \FilesystemIterator::SKIP_DOTS) as $item) { + $name = $item->getBasename(); + + if (in_array($name, $preserve, true)) { + continue; + } + + $deleted = $item->isDir() + ? File::deleteDirectory($item->getPathname()) + : File::delete($item->getPathname()); + + if ($deleted) { + $removed[] = $name; + + continue; + } + + // 삭제 실패는 빌드를 막을 이유가 못 된다 — vite 가 같은 경로를 덮어쓴다. + // 다만 조용히 넘기면 stale 산출물이 남은 것을 알 수 없으므로 기록한다. + Log::warning('빌드 산출물 정리 실패 (다음 빌드에서 재시도)', [ + 'path' => $item->getPathname(), + ]); + } + + return $removed; + } +} diff --git a/app/Console/Commands/Core/BuildCoreCommand.php b/app/Console/Commands/Core/BuildCoreCommand.php index ae68a910..593abad9 100644 --- a/app/Console/Commands/Core/BuildCoreCommand.php +++ b/app/Console/Commands/Core/BuildCoreCommand.php @@ -88,7 +88,7 @@ class BuildCoreCommand extends Command // 감시 모드: 엔진 번들 + 편집기 번들(layout-editor.min.js)을 각각 vite --watch 로 // 병렬 감시한다. (기존 dev 서버는 코어 lib 를 빌드하지 않으므로 사용 불가) if ($watchMode) { - $this->info('👀 파일 감시 모드로 코어 빌드 시작 (템플릿 엔진 + 레이아웃 편집기)'); + $this->info('👀 파일 감시 모드로 코어 빌드 시작 (템플릿 엔진 + 레이아웃 편집기 + DevTools + 개발 대시보드 CSS)'); $this->line(' Ctrl+C로 종료할 수 있습니다.'); return $this->runWatchBundles($projectPath); @@ -125,7 +125,17 @@ class BuildCoreCommand extends Command return $devtoolsResult; } - $this->info('✅ 코어 빌드 완료 (템플릿 엔진 + 레이아웃 편집기 + DevTools)'); + // ── 4) 개발 대시보드 CSS (자체 제공 — 종전 Tailwind Play CDN 대체) ── + $this->info('🔨 코어 빌드 시작 (개발 대시보드 CSS)'.($productionMode ? ' (프로덕션)' : '')); + $dashboardResult = $this->runNpmCommand(['npm', 'run', 'build:core-devdashboard'], $projectPath, true, $buildEnv); + + if ($dashboardResult !== Command::SUCCESS) { + $this->error('❌ 개발 대시보드 CSS 빌드 실패'); + + return $dashboardResult; + } + + $this->info('✅ 코어 빌드 완료 (템플릿 엔진 + 레이아웃 편집기 + DevTools + 개발 대시보드 CSS)'); $this->showEngineBuildResults($projectPath); $this->incrementExtensionCacheVersion(); @@ -140,11 +150,14 @@ class BuildCoreCommand extends Command */ private function runWatchBundles(string $projectPath): int { - // 엔진 + 편집기 + DevTools 번들을 각각 vite --watch 로 병렬 감시 + // 엔진 + 편집기 + DevTools + 개발 대시보드 CSS 를 각각 vite --watch 로 병렬 감시. + // 1회 빌드가 굽는 산출물과 같은 집합이어야 한다 — 한쪽만 빠지면 감시 모드에서 + // 그 산출물만 조용히 stale 해진다. $bundles = [ 'engine' => ['npm', 'run', 'build:core-watch'], 'editor' => ['npm', 'run', 'build:core-editor-watch'], 'devtools' => ['npm', 'run', 'build:core-devtools-watch'], + 'dashboard' => ['npm', 'run', 'build:core-devdashboard-watch'], ]; /** @var array $processes */ diff --git a/app/Console/Commands/Module/BuildModuleCommand.php b/app/Console/Commands/Module/BuildModuleCommand.php index 43ed1e00..dd8b3966 100644 --- a/app/Console/Commands/Module/BuildModuleCommand.php +++ b/app/Console/Commands/Module/BuildModuleCommand.php @@ -2,6 +2,7 @@ namespace App\Console\Commands\Module; +use App\Console\Commands\Concerns\PrunesBuildOutput; use App\Extension\ModuleManager; use App\Extension\Traits\ClearsTemplateCaches; use App\Extension\Traits\GeneratesComponentManifest; @@ -13,6 +14,7 @@ class BuildModuleCommand extends Command { use ClearsTemplateCaches; use GeneratesComponentManifest; + use PrunesBuildOutput; /** * The name and signature of the console command. @@ -189,6 +191,14 @@ class BuildModuleCommand extends Command $this->info("🔨 빌드 시작: {$identifier}".($productionMode ? ' (프로덕션)' : '')); } + // 이전 산출물 정리 (동봉 vendor 는 보존 — vite emptyOutDir 대체) + if (! $watchMode) { + $removed = $this->pruneBuildOutput($buildPath); + + if ($removed !== []) { + $this->line(' 🧹 이전 산출물 정리: '.implode(', ', $removed)); + } + } // 빌드 실행 (감시 모드에는 소스맵 억제를 주입하지 않는다 — 개발 중 디버깅 필요) $result = $this->runNpmCommand( $buildCommand, diff --git a/app/Console/Commands/Module/UninstallModuleCommand.php b/app/Console/Commands/Module/UninstallModuleCommand.php index 10edf49f..3a55aa41 100644 --- a/app/Console/Commands/Module/UninstallModuleCommand.php +++ b/app/Console/Commands/Module/UninstallModuleCommand.php @@ -95,7 +95,13 @@ class UninstallModuleCommand extends Command $deleteData = $this->option('delete-data'); $onProgress = $this->createProgressCallback(ModuleManager::UNINSTALL_STEPS); try { - $result = $this->moduleManager->uninstallModule($identifier, $deleteData, $onProgress); + $result = $this->moduleManager->uninstallModule( + $identifier, + $deleteData, + $onProgress, + $uninstallFailureReason, + $preservedBackups + ); $this->finishProgress(); } catch (\Exception $e) { $this->finishProgress(); @@ -108,6 +114,16 @@ class UninstallModuleCommand extends Command $this->info(' - '.__('modules.commands.uninstall.permissions_deleted', ['count' => $permissionsCount])); $this->info(' - '.__('modules.commands.uninstall.menus_deleted', ['count' => $menusCount])); $this->info(' - '.__('modules.commands.uninstall.layouts_deleted', ['count' => $layoutsCount])); + + // 운영자가 넣은 `custom/` 은 삭제 전에 사본을 남긴다 — 그 경로를 알리지 않으면 + // 로그를 뒤지지 않는 한 사본의 존재를 알 수 없다. + foreach ($preservedBackups ?? [] as $backup) { + $this->info(' - '.__('modules.commands.uninstall.custom_preserved', [ + 'directory' => $backup['directory'], + 'archive' => $backup['archive'], + ])); + } + Log::info(__('modules.commands.uninstall.success', ['module' => $identifier])); return Command::SUCCESS; diff --git a/app/Console/Commands/Plugin/BuildPluginCommand.php b/app/Console/Commands/Plugin/BuildPluginCommand.php index b0704d45..c510bee4 100644 --- a/app/Console/Commands/Plugin/BuildPluginCommand.php +++ b/app/Console/Commands/Plugin/BuildPluginCommand.php @@ -2,6 +2,7 @@ namespace App\Console\Commands\Plugin; +use App\Console\Commands\Concerns\PrunesBuildOutput; use App\Extension\PluginManager; use App\Extension\Traits\ClearsTemplateCaches; use App\Extension\Traits\GeneratesComponentManifest; @@ -13,6 +14,7 @@ class BuildPluginCommand extends Command { use ClearsTemplateCaches; use GeneratesComponentManifest; + use PrunesBuildOutput; /** * The name and signature of the console command. @@ -189,6 +191,14 @@ class BuildPluginCommand extends Command $this->info("🔨 빌드 시작: {$identifier}".($productionMode ? ' (프로덕션)' : '')); } + // 이전 산출물 정리 (동봉 vendor 는 보존 — vite emptyOutDir 대체) + if (! $watchMode) { + $removed = $this->pruneBuildOutput($buildPath); + + if ($removed !== []) { + $this->line(' 🧹 이전 산출물 정리: '.implode(', ', $removed)); + } + } // 빌드 실행 (감시 모드에는 소스맵 억제를 주입하지 않는다 — 개발 중 디버깅 필요) $result = $this->runNpmCommand( $buildCommand, diff --git a/app/Console/Commands/Plugin/UninstallPluginCommand.php b/app/Console/Commands/Plugin/UninstallPluginCommand.php index 20cf7e24..2852998b 100644 --- a/app/Console/Commands/Plugin/UninstallPluginCommand.php +++ b/app/Console/Commands/Plugin/UninstallPluginCommand.php @@ -92,7 +92,13 @@ class UninstallPluginCommand extends Command $deleteData = $this->option('delete-data'); $onProgress = $this->createProgressCallback(PluginManager::UNINSTALL_STEPS); try { - $result = $this->pluginManager->uninstallPlugin($identifier, $deleteData, $onProgress); + $result = $this->pluginManager->uninstallPlugin( + $identifier, + $deleteData, + $onProgress, + $uninstallFailureReason, + $preservedBackups + ); $this->finishProgress(); } catch (\Exception $e) { $this->finishProgress(); @@ -104,6 +110,16 @@ class UninstallPluginCommand extends Command $this->info(' - '.__('plugins.commands.uninstall.roles_deleted', ['count' => $rolesCount])); $this->info(' - '.__('plugins.commands.uninstall.permissions_deleted', ['count' => $permissionsCount])); $this->info(' - '.__('plugins.commands.uninstall.layouts_deleted', ['count' => $layoutsCount])); + + // 운영자가 넣은 `custom/` 은 삭제 전에 사본을 남긴다 — 그 경로를 알리지 않으면 + // 로그를 뒤지지 않는 한 사본의 존재를 알 수 없다. + foreach ($preservedBackups ?? [] as $backup) { + $this->info(' - '.__('plugins.commands.uninstall.custom_preserved', [ + 'directory' => $backup['directory'], + 'archive' => $backup['archive'], + ])); + } + Log::info(__('plugins.commands.uninstall.success', ['plugin' => $identifier])); return Command::SUCCESS; diff --git a/app/Console/Commands/Template/BuildTemplateCommand.php b/app/Console/Commands/Template/BuildTemplateCommand.php index dd0f89da..c81908ae 100644 --- a/app/Console/Commands/Template/BuildTemplateCommand.php +++ b/app/Console/Commands/Template/BuildTemplateCommand.php @@ -2,6 +2,7 @@ namespace App\Console\Commands\Template; +use App\Console\Commands\Concerns\PrunesBuildOutput; use App\Extension\TemplateManager; use App\Extension\Traits\ClearsTemplateCaches; use Illuminate\Console\Command; @@ -11,6 +12,7 @@ use Symfony\Component\Process\Process; class BuildTemplateCommand extends Command { use ClearsTemplateCaches; + use PrunesBuildOutput; /** * The name and signature of the console command. @@ -181,6 +183,14 @@ class BuildTemplateCommand extends Command $this->info("🔨 빌드 시작: {$identifier}".($productionMode ? ' (프로덕션)' : '')); } + // 이전 산출물 정리 (동봉 vendor 는 보존 — vite emptyOutDir 대체) + if (! $watchMode) { + $removed = $this->pruneBuildOutput($buildPath); + + if ($removed !== []) { + $this->line(' 🧹 이전 산출물 정리: '.implode(', ', $removed)); + } + } // 빌드 실행 (감시 모드에는 소스맵 억제를 주입하지 않는다 — 개발 중 디버깅 필요) $result = $this->runNpmCommand( $buildCommand, diff --git a/app/Console/Commands/Template/UninstallTemplateCommand.php b/app/Console/Commands/Template/UninstallTemplateCommand.php index 5813468f..ac747302 100644 --- a/app/Console/Commands/Template/UninstallTemplateCommand.php +++ b/app/Console/Commands/Template/UninstallTemplateCommand.php @@ -71,7 +71,7 @@ class UninstallTemplateCommand extends Command // 템플릿 삭제 $onProgress = $this->createProgressCallback(TemplateManager::UNINSTALL_STEPS); try { - $result = $this->templateManager->uninstallTemplate($identifier, $onProgress); + $result = $this->templateManager->uninstallTemplate($identifier, $onProgress, $preservedBackups); $this->finishProgress(); } catch (\Exception $e) { $this->finishProgress(); @@ -83,6 +83,15 @@ class UninstallTemplateCommand extends Command $this->info('✅ '.__('templates.commands.uninstall.success', ['template' => $identifier])); $this->info(' - '.__('templates.commands.uninstall.layouts_deleted', ['count' => $layoutsCount])); + // 운영자가 넣은 `custom/` 은 삭제 전에 사본을 남긴다 — 그 경로를 알리지 않으면 + // 로그를 뒤지지 않는 한 사본의 존재를 알 수 없다. + foreach ($preservedBackups ?? [] as $backup) { + $this->info(' - '.__('templates.commands.uninstall.custom_preserved', [ + 'directory' => $backup['directory'], + 'archive' => $backup['archive'], + ])); + } + Log::info(__('templates.commands.uninstall.success', ['template' => $identifier])); return Command::SUCCESS; diff --git a/app/Exceptions/CustomAssetOperationException.php b/app/Exceptions/CustomAssetOperationException.php new file mode 100644 index 00000000..579627c2 --- /dev/null +++ b/app/Exceptions/CustomAssetOperationException.php @@ -0,0 +1,32 @@ + $params 메시지 파라미터 + * @param Throwable|null $previous 원인 예외 + */ + public function __construct( + public readonly string $errorKey, + public readonly array $params = [], + ?Throwable $previous = null, + ) { + parent::__construct(__($errorKey, $params), 0, $previous); + } +} diff --git a/app/Extension/Helpers/ExtensionInstallRollbackHelper.php b/app/Extension/Helpers/ExtensionInstallRollbackHelper.php new file mode 100644 index 00000000..e6ca6271 --- /dev/null +++ b/app/Extension/Helpers/ExtensionInstallRollbackHelper.php @@ -0,0 +1,54 @@ + $type, + 'identifier' => $identifier, + 'path' => $activePath, + 'removed' => $removed, + ]); + + return $removed; + } +} diff --git a/app/Extension/Helpers/ExtensionPendingHelper.php b/app/Extension/Helpers/ExtensionPendingHelper.php index a3e45d8b..2755b9d6 100644 --- a/app/Extension/Helpers/ExtensionPendingHelper.php +++ b/app/Extension/Helpers/ExtensionPendingHelper.php @@ -21,6 +21,21 @@ class ExtensionPendingHelper 'node_modules', ]; + /** + * 확장 교체 시 보존할 최상위 디렉토리명 목록 + * + * `custom/` 은 운영자가 자기 CSS·JS·정적 파일을 두는 자리다. 확장이 소유한 것이 + * 아니므로 새 배포본으로 덮어써서는 안 된다 — 덮어쓰면 업데이트할 때마다 운영자가 + * 넣은 파일이 사라지고, 그 사실이 어디에도 남지 않는다(파일이 조용히 없어질 뿐이다). + * + * 보존은 **교체 경로 둘 다**에서 성립해야 한다: 디렉토리 rename 경로와, 하위 트리에 + * 열린 핸들이 있을 때의 제자리 동기화 폴백. 한쪽만 고치면 Windows 잠금 상황에서만 + * 조용히 사라진다. + */ + public const PRESERVED_DIRECTORIES = [ + 'custom', + ]; + /** * _pending 또는 _bundled 디렉토리에서 확장 메타데이터를 로드합니다. * @@ -162,6 +177,9 @@ class ExtensionPendingHelper try { self::copyDirectoryWithProgress($sourcePath, $tempPath, $sourcePath, $onProgress); + + // 운영자 소유 디렉토리를 새 트리로 옮겨 심는다 (교체 전에 해 둬야 원본이 살아 있다) + self::carryOverPreservedDirectories($targetPath, $tempPath, $onProgress); } catch (\Exception $e) { // 복사 실패 시 임시 디렉토리 정리 후 예외 전파 if (File::isDirectory($tempPath)) { @@ -379,7 +397,7 @@ class ExtensionPendingHelper } $staleFailures = []; - self::removeStaleEntries($source, $dest, $staleFailures); + self::removeStaleEntries($source, $dest, $staleFailures, true); if (! empty($staleFailures)) { Log::warning('확장 제자리 교체: 일부 잔존 파일을 삭제하지 못했습니다 (다음 교체 시 재시도)', [ @@ -389,6 +407,40 @@ class ExtensionPendingHelper } } + /** + * 운영자 소유 디렉토리를 기존 활성 디렉토리에서 새 트리로 옮겨 심습니다. + * + * 새 배포본에 같은 이름의 디렉토리가 있으면 **그것을 치우고** 기존 것을 심는다 — + * `custom/` 은 확장이 소유하지 않는 자리이므로, 확장이 그 자리에 무언가를 담아 + * 배포했더라도 운영자 파일이 우선한다(그런 배포 자체를 정적 검사가 막는다). + * + * @param string $existingPath 기존 활성 디렉토리 + * @param string $stagingPath 새 배포본이 복사된 임시 디렉토리 + * @param \Closure|null $onProgress 진행 콜백 + */ + private static function carryOverPreservedDirectories( + string $existingPath, + string $stagingPath, + ?\Closure $onProgress = null + ): void { + foreach (self::PRESERVED_DIRECTORIES as $name) { + $from = $existingPath.DIRECTORY_SEPARATOR.$name; + + if (! File::isDirectory($from)) { + continue; + } + + $to = $stagingPath.DIRECTORY_SEPARATOR.$name; + + if (File::isDirectory($to)) { + File::deleteDirectory($to); + } + + $onProgress?->__invoke(null, "운영자 파일 보존: {$name}/"); + self::copyDirectoryWithProgress($from, $to, $from, $onProgress); + } + } + /** * 소스 디렉토리의 파일을 대상 디렉토리에 재귀적으로 덮어씁니다. * @@ -550,7 +602,7 @@ class ExtensionPendingHelper * @param string $dest 활성 디렉토리 * @param array $failures 삭제 실패 경로 수집 (참조) */ - private static function removeStaleEntries(string $source, string $dest, array &$failures): void + private static function removeStaleEntries(string $source, string $dest, array &$failures, bool $isRoot = false): void { if (! is_dir($dest)) { return; @@ -559,6 +611,11 @@ class ExtensionPendingHelper $items = new \FilesystemIterator($dest, \FilesystemIterator::SKIP_DOTS); foreach ($items as $item) { + // 운영자 소유 디렉토리는 소스에 없어도 정리 대상이 아니다 (확장 루트에서만 판정) + if ($isRoot && $item->isDir() && in_array($item->getBasename(), self::PRESERVED_DIRECTORIES, true)) { + continue; + } + $counterpart = $source.DIRECTORY_SEPARATOR.$item->getBasename(); if ($item->isDir()) { @@ -627,14 +684,85 @@ class ExtensionPendingHelper * * @param string $basePath 확장 타입의 기본 경로 * @param string $identifier 확장 식별자 + * @return array 보관된 운영자 디렉토리 목록 */ - public static function deleteExtensionDirectory(string $basePath, string $identifier): void + public static function deleteExtensionDirectory(string $basePath, string $identifier): array { $targetPath = $basePath.DIRECTORY_SEPARATOR.$identifier; - if (File::isDirectory($targetPath)) { - File::deleteDirectory($targetPath); + if (! File::isDirectory($targetPath)) { + return []; } + + $archived = self::archivePreservedDirectories($targetPath, $identifier); + + File::deleteDirectory($targetPath); + + return $archived; + } + + /** + * 삭제 전에 운영자 소유 디렉토리를 보관합니다. + * + * 확장을 삭제하면 그 안의 `custom/` 도 함께 사라진다 — 운영자가 넣은 파일이므로 + * 되돌릴 방법 없이 없어지면 안 된다. 교체(업데이트)는 보존이 답이지만 삭제는 + * "확장을 없앤다" 는 명시적 의사이므로 막지 않고, 대신 사본을 남기고 그 사실을 + * 기록한다. + * + * 보관 실패가 삭제를 막지는 않는다 — 삭제는 운영자가 요청한 동작이다. + * + * @param string $targetPath 삭제 대상 확장 디렉토리 + * @param string $identifier 확장 식별자 + * @return array 보관에 성공한 디렉토리 목록 + */ + private static function archivePreservedDirectories(string $targetPath, string $identifier): array + { + $archived = []; + + foreach (self::PRESERVED_DIRECTORIES as $name) { + $source = $targetPath.DIRECTORY_SEPARATOR.$name; + + if (! File::isDirectory($source) || self::isEmptyDirectory($source)) { + continue; + } + + $archivePath = storage_path( + 'app'.DIRECTORY_SEPARATOR.'extension-custom-backups' + .DIRECTORY_SEPARATOR.$identifier.'-'.date('Ymd_His') + .DIRECTORY_SEPARATOR.$name + ); + + try { + self::copyDirectoryWithProgress($source, $archivePath, $source, null); + + Log::info('확장 삭제: 운영자 파일을 보관했습니다', [ + 'identifier' => $identifier, + 'directory' => $name, + 'archive' => $archivePath, + ]); + + $archived[] = ['directory' => $name, 'archive' => $archivePath]; + } catch (\Throwable $e) { + Log::warning('확장 삭제: 운영자 파일 보관에 실패했습니다 (삭제는 계속합니다)', [ + 'identifier' => $identifier, + 'directory' => $name, + 'error' => $e->getMessage(), + ]); + } + } + + return $archived; + } + + /** + * 디렉토리가 비어 있는지 판정합니다. + * + * @param string $path 대상 디렉토리 + * @return bool 비어 있으면 true + */ + private static function isEmptyDirectory(string $path): bool + { + return ! (new \FilesystemIterator($path, \FilesystemIterator::SKIP_DOTS))->valid(); } /** diff --git a/app/Extension/ModuleManager.php b/app/Extension/ModuleManager.php index df68fb30..85cd9617 100644 --- a/app/Extension/ModuleManager.php +++ b/app/Extension/ModuleManager.php @@ -21,6 +21,7 @@ use App\Enums\PermissionType; use App\Extension\Concerns\ResolvesExtensionSharedRecords; use App\Extension\Helpers\DependencyEnricher; use App\Extension\Helpers\ExtensionBackupHelper; +use App\Extension\Helpers\ExtensionInstallRollbackHelper; use App\Extension\Helpers\ExtensionMenuSyncHelper; use App\Extension\Helpers\ExtensionPendingHelper; use App\Extension\Helpers\ExtensionRoleSyncHelper; @@ -372,168 +373,186 @@ class ModuleManager implements ModuleManagerInterface // _pending 또는 _bundled에서 활성 디렉토리로 복사 (미설치 모듈 설치 시) // force=true 시 활성 디렉토리가 있어도 원본으로 덮어씀 (불완전 설치 복구) + $rollbackActivePath = $this->modulesPath.DIRECTORY_SEPARATOR.$moduleName; + // 검증은 로드된 확장 인스턴스를 요구해 복사보다 뒤에 온다. 그래서 검증이 실패하면 + // 방금 만든 활성 디렉토리가 고아로 남는다 — DB 행이 없어 목록에도 뜨지 않고 오류도 + // 남지 않은 채 디스크만 점유한다. 이번 호출이 만든 것이면 되돌린다. + $rollbackDirExisted = File::isDirectory($rollbackActivePath); + $onProgress?->__invoke('copy', '파일 복사 중...'); $this->copyFromPendingOrBundled($moduleName, $onProgress, $force); - // 모듈이 활성 디렉토리에 있지 않으면 로드 시도 - $module = $this->getModule($moduleName); - if (! $module) { - // 복사 후 재로드 시도 - $this->reloadModule($moduleName); - $module = $this->getModule($moduleName); - } - - if (! $module) { - throw new \Exception(__('modules.not_found', ['module' => $moduleName])); - } - - // 그누보드7 코어 버전 호환성 검증 - CoreVersionChecker::validateExtension( - $module->getRequiredCoreVersion(), - $module->getIdentifier(), - 'module' - ); - - // 의존성 확인 (트랜잭션 외부에서 먼저 검증) - $onProgress?->__invoke('validate', '검증 중...'); - $this->checkDependencies($module); - - // 권한 구조 검증 (계층형 구조 필수) - $this->validatePermissionStructure($module, 'module'); - - // 언어 파일 경로 검증 (src/lang 경로 필수) - $this->validateTranslationPath($module, 'module'); - - // SEO 변수명 중복 검증 - $this->validateSeoVariables($module, 'module'); - - // 모듈 설치 실행 - $module->clearLifecycleFailureReason(); - $result = $module->install(); - - if (! $result) { - $failureReason = $module->getLifecycleFailureReason() ?? __('modules.errors.unknown_error'); - - return false; - } - - // Phase 1: 마이그레이션 실행 (DDL - 트랜잭션 외부) - // MySQL에서 CREATE TABLE 등 DDL 문은 암시적 커밋을 유발하므로 트랜잭션 외부에서 실행 - $onProgress?->__invoke('migration', '마이그레이션 실행 중...'); - $this->runMigrations($module); - - // Phase 2: 데이터 작업 (DML - 트랜잭션 내부) - $onProgress?->__invoke('db', 'DB 등록 중...'); try { - DB::beginTransaction(); + // 모듈이 활성 디렉토리에 있지 않으면 로드 시도 + $module = $this->getModule($moduleName); + if (! $module) { + // 복사 후 재로드 시도 + $this->reloadModule($moduleName); + $module = $this->getModule($moduleName); + } - // GitHub에서 최신 버전 정보 가져오기 - $latestVersion = $this->fetchLatestVersion($module); - $updateAvailable = $latestVersion ? version_compare($latestVersion, $module->getVersion(), '>') : false; + if (! $module) { + throw new \Exception(__('modules.not_found', ['module' => $moduleName])); + } - // 다국어 name, description 처리 (역호환성 지원) - $name = $this->convertToMultilingual($module->getName()); - $description = $this->convertToMultilingual($module->getDescription()); - - // 활성 언어팩의 manifest seed(ja 등)를 name/description 다국어 필드에 주입 - $manifest = HookManager::applyFilters( - "module.{$module->getIdentifier()}.manifest.translations", - ['name' => $name, 'description' => $description] - ); - $name = $manifest['name'] ?? $name; - $description = $manifest['description'] ?? $description; - - // 데이터베이스에 모듈 정보 저장 - $this->moduleRepository->updateOrCreate( - ['identifier' => $module->getIdentifier()], - [ - 'vendor' => $module->getVendor(), - 'name' => $name, - 'version' => $module->getVersion(), - 'latest_version' => $latestVersion, - 'description' => $description, - 'github_url' => $module->getGithubUrl(), - 'github_changelog_url' => $this->buildChangelogUrl($module->getGithubUrl()), - 'update_available' => $updateAvailable, - 'metadata' => $module->getMetadata(), - 'status' => ExtensionStatus::Inactive->value, - 'vendor_mode' => $resolvedVendorMode->value, - 'config' => $module->getConfig(), - 'created_by' => Auth::id(), - 'updated_by' => Auth::id(), - 'created_at' => now(), - 'updated_at' => now(), - ] + // 그누보드7 코어 버전 호환성 검증 + CoreVersionChecker::validateExtension( + $module->getRequiredCoreVersion(), + $module->getIdentifier(), + 'module' ); - // Role 자동 생성 - $this->createModuleRoles($module); + // 의존성 확인 (트랜잭션 외부에서 먼저 검증) + $onProgress?->__invoke('validate', '검증 중...'); + $this->checkDependencies($module); - // 권한 자동 생성 - $this->createModulePermissions($module); + // 권한 구조 검증 (계층형 구조 필수) + $this->validatePermissionStructure($module, 'module'); - // 권한-Role 연결 - $this->assignPermissionsToRoles($module); + // 언어 파일 경로 검증 (src/lang 경로 필수) + $this->validateTranslationPath($module, 'module'); - // 관리자 메뉴 자동 생성 - $this->createModuleMenus($module); + // SEO 변수명 중복 검증 + $this->validateSeoVariables($module, 'module'); - // IDV 정책 자동 동기화 (identity_policies 테이블) - $this->syncModuleIdentityPolicies($module); + // 모듈 설치 실행 + $module->clearLifecycleFailureReason(); + $result = $module->install(); - // IDV 메시지 정의/템플릿 자동 동기화 (identity_message_definitions / identity_message_templates) - $this->syncModuleIdentityMessages($module); + if (! $result) { + $failureReason = $module->getLifecycleFailureReason() ?? __('modules.errors.unknown_error'); - // 알림 정의/템플릿 자동 동기화 (notification_definitions / notification_templates) - $this->syncModuleNotificationDefinitions($module); + return false; + } - DB::commit(); + // Phase 1: 마이그레이션 실행 (DDL - 트랜잭션 외부) + // MySQL에서 CREATE TABLE 등 DDL 문은 암시적 커밋을 유발하므로 트랜잭션 외부에서 실행 + $onProgress?->__invoke('migration', '마이그레이션 실행 중...'); + $this->runMigrations($module); + + // Phase 2: 데이터 작업 (DML - 트랜잭션 내부) + $onProgress?->__invoke('db', 'DB 등록 중...'); + try { + DB::beginTransaction(); + + // GitHub에서 최신 버전 정보 가져오기 + $latestVersion = $this->fetchLatestVersion($module); + $updateAvailable = $latestVersion ? version_compare($latestVersion, $module->getVersion(), '>') : false; + + // 다국어 name, description 처리 (역호환성 지원) + $name = $this->convertToMultilingual($module->getName()); + $description = $this->convertToMultilingual($module->getDescription()); + + // 활성 언어팩의 manifest seed(ja 등)를 name/description 다국어 필드에 주입 + $manifest = HookManager::applyFilters( + "module.{$module->getIdentifier()}.manifest.translations", + ['name' => $name, 'description' => $description] + ); + $name = $manifest['name'] ?? $name; + $description = $manifest['description'] ?? $description; + + // 데이터베이스에 모듈 정보 저장 + $this->moduleRepository->updateOrCreate( + ['identifier' => $module->getIdentifier()], + [ + 'vendor' => $module->getVendor(), + 'name' => $name, + 'version' => $module->getVersion(), + 'latest_version' => $latestVersion, + 'description' => $description, + 'github_url' => $module->getGithubUrl(), + 'github_changelog_url' => $this->buildChangelogUrl($module->getGithubUrl()), + 'update_available' => $updateAvailable, + 'metadata' => $module->getMetadata(), + 'status' => ExtensionStatus::Inactive->value, + 'vendor_mode' => $resolvedVendorMode->value, + 'config' => $module->getConfig(), + 'created_by' => Auth::id(), + 'updated_by' => Auth::id(), + 'created_at' => now(), + 'updated_at' => now(), + ] + ); + + // Role 자동 생성 + $this->createModuleRoles($module); + + // 권한 자동 생성 + $this->createModulePermissions($module); + + // 권한-Role 연결 + $this->assignPermissionsToRoles($module); + + // 관리자 메뉴 자동 생성 + $this->createModuleMenus($module); + + // IDV 정책 자동 동기화 (identity_policies 테이블) + $this->syncModuleIdentityPolicies($module); + + // IDV 메시지 정의/템플릿 자동 동기화 (identity_message_definitions / identity_message_templates) + $this->syncModuleIdentityMessages($module); + + // 알림 정의/템플릿 자동 동기화 (notification_definitions / notification_templates) + $this->syncModuleNotificationDefinitions($module); + + DB::commit(); + + } catch (\Exception $e) { + DB::rollBack(); + throw $e; + } + + // Phase 3: 시더 실행 (트랜잭션 외부) + // 시더 내부에서 별도 트랜잭션을 사용할 수 있으므로 외부에서 실행 + $onProgress?->__invoke('seed', '시더 실행 중...'); + $this->runModuleSeeders($module); + + // Phase 4: 기본 설정 파일 생성 + $onProgress?->__invoke('settings', '환경설정 초기화 중...'); + $this->initializeModuleSettings($module); + + // Phase 4.5: Composer 의존성 설치 (외부 패키지가 있는 경우에만) + // _pending에서 이미 설치한 경우 스킵 (vendor/가 활성 디렉토리에 복사됨) + if (! $composerDoneInPending) { + $onProgress?->__invoke('composer', 'Composer 의존성 설치 중...'); + if (! app()->environment('testing') + && $this->extensionManager->hasComposerDependencies('modules', $moduleName)) { + $composerResult = $this->extensionManager->runComposerInstall('modules', $moduleName); + if (! $composerResult) { + Log::warning('모듈 Composer 의존성 설치 실패', ['module' => $moduleName]); + } + } + } + + // Phase 5: 오토로드 병합 실행 (트랜잭션 외부) + $onProgress?->__invoke('autoload', '오토로드 갱신 중...'); + $this->extensionManager->updateComposerAutoload(); + + // 모듈 상태 캐시 무효화 + self::invalidateModuleStatusCache(); + + // 확장 캐시 버전 증가 (프론트엔드가 새로운 캐시로 요청하도록) + $this->incrementExtensionCacheVersion(); + RouteCacheHelper::rebuild(); + + // 확장 미들웨어 인덱스 무효화 — 새 모듈의 미들웨어 선언이 즉시 게이트에 반영. + ExtensionMiddlewareRegistry::flush(); + + // 훅 발행: 모듈 설치 완료 + HookManager::doAction('core.modules.installed', $moduleName); + + return true; + } catch (\Throwable $e) { + ExtensionInstallRollbackHelper::removeIfCreatedByThisInstall( + $rollbackActivePath, + $rollbackDirExisted, + $moduleName, + 'module', + ); - } catch (\Exception $e) { - DB::rollBack(); throw $e; } - // Phase 3: 시더 실행 (트랜잭션 외부) - // 시더 내부에서 별도 트랜잭션을 사용할 수 있으므로 외부에서 실행 - $onProgress?->__invoke('seed', '시더 실행 중...'); - $this->runModuleSeeders($module); - - // Phase 4: 기본 설정 파일 생성 - $onProgress?->__invoke('settings', '환경설정 초기화 중...'); - $this->initializeModuleSettings($module); - - // Phase 4.5: Composer 의존성 설치 (외부 패키지가 있는 경우에만) - // _pending에서 이미 설치한 경우 스킵 (vendor/가 활성 디렉토리에 복사됨) - if (! $composerDoneInPending) { - $onProgress?->__invoke('composer', 'Composer 의존성 설치 중...'); - if (! app()->environment('testing') - && $this->extensionManager->hasComposerDependencies('modules', $moduleName)) { - $composerResult = $this->extensionManager->runComposerInstall('modules', $moduleName); - if (! $composerResult) { - Log::warning('모듈 Composer 의존성 설치 실패', ['module' => $moduleName]); - } - } - } - - // Phase 5: 오토로드 병합 실행 (트랜잭션 외부) - $onProgress?->__invoke('autoload', '오토로드 갱신 중...'); - $this->extensionManager->updateComposerAutoload(); - - // 모듈 상태 캐시 무효화 - self::invalidateModuleStatusCache(); - - // 확장 캐시 버전 증가 (프론트엔드가 새로운 캐시로 요청하도록) - $this->incrementExtensionCacheVersion(); - RouteCacheHelper::rebuild(); - - // 확장 미들웨어 인덱스 무효화 — 새 모듈의 미들웨어 선언이 즉시 게이트에 반영. - ExtensionMiddlewareRegistry::flush(); - - // 훅 발행: 모듈 설치 완료 - HookManager::doAction('core.modules.installed', $moduleName); - - return true; } /** @@ -905,6 +924,9 @@ class ModuleManager implements ModuleManagerInterface * @param bool $deleteData 모듈 데이터(테이블) 삭제 여부 * @param \Closure|null $onProgress 진행 콜백 (?string $step, string $message) * @param string|null $failureReason 실패 시 사유가 담기는 out 파라미터 (성공 시 null) + * @param array|null $preservedBackups + * 삭제 전에 보관한 운영자 소유 디렉토리(`custom/`)의 사본 경로가 담기는 out 파라미터. + * 운영자에게 "지웠지만 사본은 여기 있다" 를 알리기 위한 것이므로 호출부가 노출해야 한다. * @return bool 제거 성공 여부 * * @throws \Exception 모듈을 찾을 수 없을 때 @@ -914,8 +936,10 @@ class ModuleManager implements ModuleManagerInterface bool $deleteData = false, ?\Closure $onProgress = null, ?string &$failureReason = null, + ?array &$preservedBackups = null, ): bool { $failureReason = null; + $preservedBackups = []; // 상태 가드: 진행 중 상태 체크 $existingRecord = $this->moduleRepository->findByIdentifier($moduleName); @@ -1045,7 +1069,10 @@ class ModuleManager implements ModuleManagerInterface // 활성 모듈 디렉토리 전체 삭제 (_pending/_bundled에 원본 보존되므로 재설치 가능) $onProgress?->__invoke('files', '파일 삭제 중...'); - ExtensionPendingHelper::deleteExtensionDirectory($this->modulesPath, $module->getIdentifier()); + $preservedBackups = ExtensionPendingHelper::deleteExtensionDirectory( + $this->modulesPath, + $module->getIdentifier() + ); // 메모리에서 모듈 제거 unset($this->modules[$module->getIdentifier()]); diff --git a/app/Extension/PluginManager.php b/app/Extension/PluginManager.php index dc016663..c354712e 100644 --- a/app/Extension/PluginManager.php +++ b/app/Extension/PluginManager.php @@ -21,6 +21,7 @@ use App\Exceptions\LayoutIncludeException; use App\Extension\Concerns\ResolvesExtensionSharedRecords; use App\Extension\Helpers\DependencyEnricher; use App\Extension\Helpers\ExtensionBackupHelper; +use App\Extension\Helpers\ExtensionInstallRollbackHelper; use App\Extension\Helpers\ExtensionMenuSyncHelper; use App\Extension\Helpers\ExtensionPendingHelper; use App\Extension\Helpers\ExtensionRoleSyncHelper; @@ -357,167 +358,184 @@ class PluginManager implements PluginManagerInterface // _pending 또는 _bundled에서 활성 디렉토리로 복사 (미설치 플러그인 설치 시) // force=true 시 활성 디렉토리가 있어도 원본으로 덮어씀 (불완전 설치 복구) + // 검증은 로드된 확장 인스턴스를 요구해 복사보다 뒤에 온다. 그래서 검증이 실패하면 + // 방금 만든 활성 디렉토리가 고아로 남는다 — DB 행이 없어 목록에도 뜨지 않고 오류도 + // 남지 않은 채 디스크만 점유한다. 이번 호출이 만든 것이면 되돌린다. + $rollbackDirExisted = File::isDirectory($activePath); + $onProgress?->__invoke('copy', '파일 복사 중...'); $this->copyFromPendingOrBundled($pluginName, $onProgress, $force); - // 플러그인이 활성 디렉토리에 있지 않으면 로드 시도 - $plugin = $this->getPlugin($pluginName); - if (! $plugin) { - // 복사 후 재로드 시도 - $this->reloadPlugin($pluginName); - $plugin = $this->getPlugin($pluginName); - } - - if (! $plugin) { - throw new \Exception(__('plugins.not_found', ['plugin' => $pluginName])); - } - - // 그누보드7 코어 버전 호환성 검증 - CoreVersionChecker::validateExtension( - $plugin->getRequiredCoreVersion(), - $plugin->getIdentifier(), - 'plugin' - ); - - // 의존성 확인 (트랜잭션 외부에서 먼저 검증) - $this->checkDependencies($plugin); - - // 언어 파일 경로 검증 (lang 경로 필수) - $this->validateTranslationPath($plugin, 'plugin'); - - // SEO 변수명 중복 검증 - $this->validateSeoVariables($plugin, 'plugin'); - - // 플러그인 설치 실행 - $onProgress?->__invoke('validate', '검증 중...'); - $plugin->clearLifecycleFailureReason(); - $result = $plugin->install(); - - if (! $result) { - $failureReason = $plugin->getLifecycleFailureReason() ?? __('plugins.errors.unknown_error'); - } - - if (! $result) { - return false; - } - - // Phase 1: 마이그레이션 실행 (DDL - 트랜잭션 외부) - // MySQL에서 CREATE TABLE 등 DDL 문은 암시적 커밋을 유발하므로 트랜잭션 외부에서 실행 - $onProgress?->__invoke('migration', '마이그레이션 실행 중...'); - $this->runMigrations($plugin); - - // Phase 2: 데이터 작업 (DML - 트랜잭션 내부) - $onProgress?->__invoke('db', 'DB 등록 중...'); try { - DB::beginTransaction(); + // 플러그인이 활성 디렉토리에 있지 않으면 로드 시도 + $plugin = $this->getPlugin($pluginName); + if (! $plugin) { + // 복사 후 재로드 시도 + $this->reloadPlugin($pluginName); + $plugin = $this->getPlugin($pluginName); + } - // GitHub에서 최신 버전 정보 가져오기 - $latestVersion = $this->fetchLatestVersion($plugin); - $updateAvailable = $latestVersion ? version_compare($latestVersion, $plugin->getVersion(), '>') : false; + if (! $plugin) { + throw new \Exception(__('plugins.not_found', ['plugin' => $pluginName])); + } - // 다국어 name, description 처리 (역호환성 지원) - $name = $this->convertToMultilingual($plugin->getName()); - $description = $this->convertToMultilingual($plugin->getDescription()); - - // 활성 언어팩의 manifest seed(ja 등)를 name/description 다국어 필드에 주입 - $manifest = HookManager::applyFilters( - "plugin.{$plugin->getIdentifier()}.manifest.translations", - ['name' => $name, 'description' => $description] - ); - $name = $manifest['name'] ?? $name; - $description = $manifest['description'] ?? $description; - - // 데이터베이스에 플러그인 정보 저장 - $this->pluginRepository->updateOrCreate( - ['identifier' => $plugin->getIdentifier()], - [ - 'vendor' => $plugin->getVendor(), - 'name' => $name, - 'version' => $plugin->getVersion(), - 'latest_version' => $latestVersion, - 'description' => $description, - 'github_url' => $plugin->getGithubUrl(), - 'github_changelog_url' => $this->buildChangelogUrl($plugin->getGithubUrl()), - 'update_available' => $updateAvailable, - 'metadata' => $plugin->getMetadata(), - 'status' => ExtensionStatus::Inactive->value, - 'vendor_mode' => $resolvedVendorMode->value, - 'hooks' => $this->normalizeHooksToArray($plugin->getHooks()), - 'created_by' => Auth::id(), - 'updated_by' => Auth::id(), - 'created_at' => now(), - 'updated_at' => now(), - ] + // 그누보드7 코어 버전 호환성 검증 + CoreVersionChecker::validateExtension( + $plugin->getRequiredCoreVersion(), + $plugin->getIdentifier(), + 'plugin' ); - // Role 자동 생성 - $this->createPluginRoles($plugin); + // 의존성 확인 (트랜잭션 외부에서 먼저 검증) + $this->checkDependencies($plugin); - // 권한 자동 생성 - $this->createPluginPermissions($plugin); + // 언어 파일 경로 검증 (lang 경로 필수) + $this->validateTranslationPath($plugin, 'plugin'); - // 권한-Role 연결 - $this->assignPermissionsToRoles($plugin); + // SEO 변수명 중복 검증 + $this->validateSeoVariables($plugin, 'plugin'); - // 관리자 메뉴 자동 생성 (모듈 installModule 과 동일 순서) - $this->createPluginMenus($plugin); + // 플러그인 설치 실행 + $onProgress?->__invoke('validate', '검증 중...'); + $plugin->clearLifecycleFailureReason(); + $result = $plugin->install(); - // IDV 정책 자동 동기화 (identity_policies 테이블) - $this->syncPluginIdentityPolicies($plugin); + if (! $result) { + $failureReason = $plugin->getLifecycleFailureReason() ?? __('plugins.errors.unknown_error'); + } - // IDV 메시지 정의/템플릿 자동 동기화 - $this->syncPluginIdentityMessages($plugin); + if (! $result) { + return false; + } - // 알림 정의/템플릿 자동 동기화 (notification_definitions / notification_templates) - $this->syncPluginNotificationDefinitions($plugin); + // Phase 1: 마이그레이션 실행 (DDL - 트랜잭션 외부) + // MySQL에서 CREATE TABLE 등 DDL 문은 암시적 커밋을 유발하므로 트랜잭션 외부에서 실행 + $onProgress?->__invoke('migration', '마이그레이션 실행 중...'); + $this->runMigrations($plugin); - DB::commit(); + // Phase 2: 데이터 작업 (DML - 트랜잭션 내부) + $onProgress?->__invoke('db', 'DB 등록 중...'); + try { + DB::beginTransaction(); + + // GitHub에서 최신 버전 정보 가져오기 + $latestVersion = $this->fetchLatestVersion($plugin); + $updateAvailable = $latestVersion ? version_compare($latestVersion, $plugin->getVersion(), '>') : false; + + // 다국어 name, description 처리 (역호환성 지원) + $name = $this->convertToMultilingual($plugin->getName()); + $description = $this->convertToMultilingual($plugin->getDescription()); + + // 활성 언어팩의 manifest seed(ja 등)를 name/description 다국어 필드에 주입 + $manifest = HookManager::applyFilters( + "plugin.{$plugin->getIdentifier()}.manifest.translations", + ['name' => $name, 'description' => $description] + ); + $name = $manifest['name'] ?? $name; + $description = $manifest['description'] ?? $description; + + // 데이터베이스에 플러그인 정보 저장 + $this->pluginRepository->updateOrCreate( + ['identifier' => $plugin->getIdentifier()], + [ + 'vendor' => $plugin->getVendor(), + 'name' => $name, + 'version' => $plugin->getVersion(), + 'latest_version' => $latestVersion, + 'description' => $description, + 'github_url' => $plugin->getGithubUrl(), + 'github_changelog_url' => $this->buildChangelogUrl($plugin->getGithubUrl()), + 'update_available' => $updateAvailable, + 'metadata' => $plugin->getMetadata(), + 'status' => ExtensionStatus::Inactive->value, + 'vendor_mode' => $resolvedVendorMode->value, + 'hooks' => $this->normalizeHooksToArray($plugin->getHooks()), + 'created_by' => Auth::id(), + 'updated_by' => Auth::id(), + 'created_at' => now(), + 'updated_at' => now(), + ] + ); + + // Role 자동 생성 + $this->createPluginRoles($plugin); + + // 권한 자동 생성 + $this->createPluginPermissions($plugin); + + // 권한-Role 연결 + $this->assignPermissionsToRoles($plugin); + + // 관리자 메뉴 자동 생성 (모듈 installModule 과 동일 순서) + $this->createPluginMenus($plugin); + + // IDV 정책 자동 동기화 (identity_policies 테이블) + $this->syncPluginIdentityPolicies($plugin); + + // IDV 메시지 정의/템플릿 자동 동기화 + $this->syncPluginIdentityMessages($plugin); + + // 알림 정의/템플릿 자동 동기화 (notification_definitions / notification_templates) + $this->syncPluginNotificationDefinitions($plugin); + + DB::commit(); + + } catch (\Exception $e) { + DB::rollBack(); + throw $e; + } + + // Phase 3: 시더 실행 (트랜잭션 외부) + // 시더 내부에서 별도 트랜잭션을 사용할 수 있으므로 외부에서 실행 + $onProgress?->__invoke('seed', '시더 실행 중...'); + $this->runPluginSeeders($plugin); + + // Phase 4: 기본 설정 파일 생성 + $onProgress?->__invoke('settings', '설정 초기화 중...'); + $this->initializePluginSettings($plugin); + + // Phase 4.5: Composer 의존성 설치 (외부 패키지가 있는 경우에만) + // _pending에서 이미 설치한 경우 스킵 (vendor/가 활성 디렉토리에 복사됨) + if (! $composerDoneInPending) { + $onProgress?->__invoke('composer', 'Composer 의존성 설치 중...'); + if (! app()->environment('testing') + && $this->extensionManager->hasComposerDependencies('plugins', $pluginName)) { + $composerResult = $this->extensionManager->runComposerInstall('plugins', $pluginName); + if (! $composerResult) { + Log::warning('플러그인 Composer 의존성 설치 실패', ['plugin' => $pluginName]); + } + } + } + + // Phase 5: 오토로드 병합 실행 (트랜잭션 외부) + $onProgress?->__invoke('autoload', '오토로드 갱신 중...'); + $this->extensionManager->updateComposerAutoload(); + + // Phase 6: 플러그인 상태 캐시 무효화 + self::invalidatePluginStatusCache(); + + // 확장 캐시 버전 증가 (프론트엔드가 새로운 캐시로 요청하도록) + $this->incrementExtensionCacheVersion(); + RouteCacheHelper::rebuild(); + + // 확장 미들웨어 인덱스 무효화 — 새 플러그인의 미들웨어 선언이 즉시 게이트에 반영. + ExtensionMiddlewareRegistry::flush(); + + // 훅 발행: 플러그인 설치 완료 + HookManager::doAction('core.plugins.installed', $pluginName); + + return true; + } catch (\Throwable $e) { + ExtensionInstallRollbackHelper::removeIfCreatedByThisInstall( + $activePath, + $rollbackDirExisted, + $pluginName, + 'plugin', + ); - } catch (\Exception $e) { - DB::rollBack(); throw $e; } - // Phase 3: 시더 실행 (트랜잭션 외부) - // 시더 내부에서 별도 트랜잭션을 사용할 수 있으므로 외부에서 실행 - $onProgress?->__invoke('seed', '시더 실행 중...'); - $this->runPluginSeeders($plugin); - - // Phase 4: 기본 설정 파일 생성 - $onProgress?->__invoke('settings', '설정 초기화 중...'); - $this->initializePluginSettings($plugin); - - // Phase 4.5: Composer 의존성 설치 (외부 패키지가 있는 경우에만) - // _pending에서 이미 설치한 경우 스킵 (vendor/가 활성 디렉토리에 복사됨) - if (! $composerDoneInPending) { - $onProgress?->__invoke('composer', 'Composer 의존성 설치 중...'); - if (! app()->environment('testing') - && $this->extensionManager->hasComposerDependencies('plugins', $pluginName)) { - $composerResult = $this->extensionManager->runComposerInstall('plugins', $pluginName); - if (! $composerResult) { - Log::warning('플러그인 Composer 의존성 설치 실패', ['plugin' => $pluginName]); - } - } - } - - // Phase 5: 오토로드 병합 실행 (트랜잭션 외부) - $onProgress?->__invoke('autoload', '오토로드 갱신 중...'); - $this->extensionManager->updateComposerAutoload(); - - // Phase 6: 플러그인 상태 캐시 무효화 - self::invalidatePluginStatusCache(); - - // 확장 캐시 버전 증가 (프론트엔드가 새로운 캐시로 요청하도록) - $this->incrementExtensionCacheVersion(); - RouteCacheHelper::rebuild(); - - // 확장 미들웨어 인덱스 무효화 — 새 플러그인의 미들웨어 선언이 즉시 게이트에 반영. - ExtensionMiddlewareRegistry::flush(); - - // 훅 발행: 플러그인 설치 완료 - HookManager::doAction('core.plugins.installed', $pluginName); - - return true; } /** @@ -932,6 +950,9 @@ class PluginManager implements PluginManagerInterface * @param bool $deleteData 플러그인 데이터(테이블) 삭제 여부 * @param \Closure|null $onProgress 진행 콜백 (?string $step, string $message) * @param string|null $failureReason 실패 시 사유가 담기는 out 파라미터 (성공 시 null) + * @param array|null $preservedBackups + * 삭제 전에 보관한 운영자 소유 디렉토리(`custom/`)의 사본 경로가 담기는 out 파라미터. + * 운영자에게 "지웠지만 사본은 여기 있다" 를 알리기 위한 것이므로 호출부가 노출해야 한다. * @return bool 제거 성공 여부 * * @throws \Exception 플러그인을 찾을 수 없을 때 @@ -941,8 +962,10 @@ class PluginManager implements PluginManagerInterface bool $deleteData = false, ?\Closure $onProgress = null, ?string &$failureReason = null, + ?array &$preservedBackups = null, ): bool { $failureReason = null; + $preservedBackups = []; // 상태 가드: 진행 중 상태 체크 $existingRecord = $this->pluginRepository->findByIdentifier($pluginName); @@ -1075,7 +1098,10 @@ class PluginManager implements PluginManagerInterface // 활성 플러그인 디렉토리 전체 삭제 (_pending/_bundled에 원본 보존되므로 재설치 가능) $onProgress?->__invoke('files', '파일 삭제 중...'); - ExtensionPendingHelper::deleteExtensionDirectory($this->pluginsPath, $plugin->getIdentifier()); + $preservedBackups = ExtensionPendingHelper::deleteExtensionDirectory( + $this->pluginsPath, + $plugin->getIdentifier() + ); // 메모리에서 플러그인 제거 unset($this->plugins[$plugin->getIdentifier()]); diff --git a/app/Extension/TemplateManager.php b/app/Extension/TemplateManager.php index 9fd3fbc2..b3970284 100644 --- a/app/Extension/TemplateManager.php +++ b/app/Extension/TemplateManager.php @@ -13,6 +13,7 @@ use App\Enums\ExtensionStatus; use App\Enums\LayoutSourceType; use App\Extension\Cache\CoreCacheDriver; use App\Extension\Helpers\ExtensionBackupHelper; +use App\Extension\Helpers\ExtensionInstallRollbackHelper; use App\Extension\Helpers\ExtensionPendingHelper; use App\Extension\Helpers\ExtensionStatusGuard; use App\Extension\Helpers\GithubHelper; @@ -425,6 +426,12 @@ class TemplateManager implements TemplateManagerInterface ); } + // 검증(2단계)은 복사된 활성 디렉토리를 읽어야 해서 복사보다 뒤에 온다. 그래서 검증이 + // 실패하면 방금 만든 활성 디렉토리가 고아로 남는다 — DB 행이 없어 목록에도 뜨지 않고 + // 오류도 남지 않은 채 디스크만 점유한다. 이번 호출이 만든 것이면 되돌린다. + $rollbackActivePath = $this->templatesPath.DIRECTORY_SEPARATOR.$templateName; + $rollbackDirExisted = File::isDirectory($rollbackActivePath); + // 1. _pending/_bundled에서 활성 디렉토리로 복사 (활성 디렉토리에 없는 경우) // force=true 시 활성 디렉토리가 있어도 원본으로 덮어씀 (불완전 설치 복구) $onProgress?->__invoke('copy', '파일 복사 중...'); @@ -435,79 +442,90 @@ class TemplateManager implements TemplateManagerInterface // 2. 검증 $onProgress?->__invoke('validate', '검증 중...'); - return DB::transaction(function () use ($templateName, $onProgress) { - $template = $this->getTemplate($templateName); - if (! $template) { - throw new \Exception(__('templates.errors.not_found', ['template' => $templateName])); - } + try { + return DB::transaction(function () use ($templateName, $onProgress) { + $template = $this->getTemplate($templateName); + if (! $template) { + throw new \Exception(__('templates.errors.not_found', ['template' => $templateName])); + } - // 의존성 확인 - $this->checkDependencies($template); + // 의존성 확인 + $this->checkDependencies($template); - // SEO 설정 검증 (설치 전 seo-config.json 유효성 검사) - $this->validateSeoConfig($templateName); + // SEO 설정 검증 (설치 전 seo-config.json 유효성 검사) + $this->validateSeoConfig($templateName); - // 레이아웃 검증 (설치 전 모든 레이아웃 파일 유효성 검사) - $this->validateLayouts($templateName); + // 레이아웃 검증 (설치 전 모든 레이아웃 파일 유효성 검사) + $this->validateLayouts($templateName); - // name과 description 다국어 변환 (역호환성) - $name = $this->convertToMultilingual($template['name']); - $description = $this->convertToMultilingual($template['description'] ?? ''); + // name과 description 다국어 변환 (역호환성) + $name = $this->convertToMultilingual($template['name']); + $description = $this->convertToMultilingual($template['description'] ?? ''); - // 활성 언어팩의 manifest seed(ja 등)를 name/description 다국어 필드에 주입 - $manifest = HookManager::applyFilters( - "template.{$templateName}.manifest.translations", - ['name' => $name, 'description' => $description] - ); - $name = $manifest['name'] ?? $name; - $description = $manifest['description'] ?? $description; + // 활성 언어팩의 manifest seed(ja 등)를 name/description 다국어 필드에 주입 + $manifest = HookManager::applyFilters( + "template.{$templateName}.manifest.translations", + ['name' => $name, 'description' => $description] + ); + $name = $manifest['name'] ?? $name; + $description = $manifest['description'] ?? $description; - // 3. DB 등록 - $onProgress?->__invoke('db', 'DB 등록 중...'); + // 3. DB 등록 + $onProgress?->__invoke('db', 'DB 등록 중...'); - // 템플릿 레코드 생성 또는 업데이트 - $templateRecord = $this->templateRepository->updateOrCreate( - ['identifier' => $templateName], - [ - 'vendor' => $template['vendor'], - 'name' => $name, - 'version' => $template['version'], - 'type' => $template['type'], - 'description' => $description, - 'github_url' => $template['github_url'] ?? null, - 'metadata' => $template['metadata'] ?? null, - 'status' => ExtensionStatus::Inactive->value, - 'created_by' => Auth::id(), - 'updated_by' => Auth::id(), - ] + // 템플릿 레코드 생성 또는 업데이트 + $templateRecord = $this->templateRepository->updateOrCreate( + ['identifier' => $templateName], + [ + 'vendor' => $template['vendor'], + 'name' => $name, + 'version' => $template['version'], + 'type' => $template['type'], + 'description' => $description, + 'github_url' => $template['github_url'] ?? null, + 'metadata' => $template['metadata'] ?? null, + 'status' => ExtensionStatus::Inactive->value, + 'created_by' => Auth::id(), + 'updated_by' => Auth::id(), + ] + ); + + // 4. 레이아웃 등록 + $onProgress?->__invoke('layout', '레이아웃 등록 중...'); + + // 레이아웃 JSON 파일 일괄 등록 + $this->registerLayouts($templateName, $templateRecord->id); + + // 모듈 레이아웃 오버라이드 등록 + $this->registerLayoutOverrides($templateName, $templateRecord->id); + + // Extension 오버라이드 등록 (모듈/플러그인 Extension 커스터마이징) + $this->registerExtensionOverrides($templateName, $templateRecord->id); + + // 에러 레이아웃 검증 (레이아웃 등록 후 수행) + $this->validateErrorLayouts($templateName, $template); + + // 템플릿 상태 캐시 무효화 + self::invalidateTemplateStatusCache(); + + // 확장 캐시 버전 증가 (프론트엔드가 새로운 캐시로 요청하도록) + $this->incrementExtensionCacheVersion(); + + // 훅 발행: 템플릿 설치 완료 + HookManager::doAction('core.templates.installed', $templateName); + + return true; + }); + } catch (\Throwable $e) { + ExtensionInstallRollbackHelper::removeIfCreatedByThisInstall( + $rollbackActivePath, + $rollbackDirExisted, + $templateName, + 'template', ); - // 4. 레이아웃 등록 - $onProgress?->__invoke('layout', '레이아웃 등록 중...'); - - // 레이아웃 JSON 파일 일괄 등록 - $this->registerLayouts($templateName, $templateRecord->id); - - // 모듈 레이아웃 오버라이드 등록 - $this->registerLayoutOverrides($templateName, $templateRecord->id); - - // Extension 오버라이드 등록 (모듈/플러그인 Extension 커스터마이징) - $this->registerExtensionOverrides($templateName, $templateRecord->id); - - // 에러 레이아웃 검증 (레이아웃 등록 후 수행) - $this->validateErrorLayouts($templateName, $template); - - // 템플릿 상태 캐시 무효화 - self::invalidateTemplateStatusCache(); - - // 확장 캐시 버전 증가 (프론트엔드가 새로운 캐시로 요청하도록) - $this->incrementExtensionCacheVersion(); - - // 훅 발행: 템플릿 설치 완료 - HookManager::doAction('core.templates.installed', $templateName); - - return true; - }); + throw $e; + } } /** @@ -731,12 +749,20 @@ class TemplateManager implements TemplateManagerInterface * * @param string $templateName 제거할 템플릿명 (identifier) * @param \Closure|null $onProgress 진행 콜백 (?string $step, string $message) + * @param array|null $preservedBackups + * 삭제 전에 보관한 운영자 소유 디렉토리(`custom/`)의 사본 경로가 담기는 out 파라미터. + * 운영자에게 "지웠지만 사본은 여기 있다" 를 알리기 위한 것이므로 호출부가 노출해야 한다. * @return bool 제거 성공 여부 * * @throws \Exception 템플릿을 찾을 수 없을 때 */ - public function uninstallTemplate(string $templateName, ?\Closure $onProgress = null): bool - { + public function uninstallTemplate( + string $templateName, + ?\Closure $onProgress = null, + ?array &$preservedBackups = null, + ): bool { + $preservedBackups = []; + // 1. 캐시 삭제 $onProgress?->__invoke('cache', '캐시 삭제 중...'); @@ -782,7 +808,10 @@ class TemplateManager implements TemplateManagerInterface $onProgress?->__invoke('files', '파일 삭제 중...'); // 활성 템플릿 디렉토리 전체 삭제 (_pending/_bundled에 원본 보존되므로 재설치 가능) - ExtensionPendingHelper::deleteExtensionDirectory($this->templatesPath, $templateName); + $preservedBackups = ExtensionPendingHelper::deleteExtensionDirectory( + $this->templatesPath, + $templateName + ); // 메모리에서 템플릿 제거 unset($this->templates[$templateName]); diff --git a/app/Http/Controllers/Api/Admin/AdminExtensionCustomAssetController.php b/app/Http/Controllers/Api/Admin/AdminExtensionCustomAssetController.php new file mode 100644 index 00000000..6a95832a --- /dev/null +++ b/app/Http/Controllers/Api/Admin/AdminExtensionCustomAssetController.php @@ -0,0 +1,222 @@ + 'modules', + 'plugin' => 'plugins', + 'template' => 'templates', + ]; + + public function __construct( + private CustomAssetService $service, + ) { + parent::__construct(); + } + + /** + * 사용자 추가 에셋 목록 조회. + * + * @param string $type 확장 타입 (`module` | `plugin` | `template`) + * @param string $identifier 확장 식별자 + * @return JsonResponse 파일 목록 + 편집기 메타(허용 확장자·크기 상한) + */ + public function index(string $type, string $identifier): JsonResponse + { + try { + $files = $this->service->list($this->resolveType($type), $identifier); + } catch (CustomAssetOperationException $e) { + return $this->error($e->errorKey, 422, null, $e->params); + } catch (\Throwable $e) { + Log::error('사용자 추가 에셋 목록 조회 실패', [ + 'type' => $type, + 'identifier' => $identifier, + 'error' => $e->getMessage(), + ]); + + return $this->error('custom_assets.errors.read_failed', 500, $e, ['path' => 'custom/']); + } + + return $this->success('custom_assets.messages.listed', [ + 'files' => $files, + 'editable_extensions' => CustomAssetService::EDITABLE_EXTENSIONS, + 'uploadable_extensions' => AllowedTemplateFileType::getAllowedExtensions(), + 'max_text_bytes' => CustomAssetService::MAX_TEXT_BYTES, + 'max_upload_bytes' => CustomAssetService::MAX_UPLOAD_BYTES, + ]); + } + + /** + * 텍스트 파일 본문 조회. + * + * @param ReadExtensionCustomAssetRequest $request 검증된 요청 (`path`) + * @param string $type 확장 타입 + * @param string $identifier 확장 식별자 + * @return JsonResponse 본문 응답 + */ + public function show(ReadExtensionCustomAssetRequest $request, string $type, string $identifier): JsonResponse + { + $path = (string) $request->validated('path'); + + try { + $file = $this->service->read($this->resolveType($type), $identifier, $path); + } catch (CustomAssetOperationException $e) { + return $this->error($e->errorKey, 422, null, $e->params); + } catch (\Throwable $e) { + Log::error('사용자 추가 에셋 본문 조회 실패', [ + 'type' => $type, + 'identifier' => $identifier, + 'error' => $e->getMessage(), + ]); + + return $this->error('custom_assets.errors.read_failed', 500, $e, ['path' => $path]); + } + + return $this->success('custom_assets.messages.listed', $file); + } + + /** + * 텍스트 파일 본문 저장 (없으면 생성). + * + * @param SaveExtensionCustomAssetRequest $request 검증된 요청 (`path`, `content`) + * @param string $type 확장 타입 + * @param string $identifier 확장 식별자 + * @return JsonResponse 저장 결과 + */ + public function store(SaveExtensionCustomAssetRequest $request, string $type, string $identifier): JsonResponse + { + $path = (string) $request->validated('path'); + + try { + $saved = $this->service->save( + $this->resolveType($type), + $identifier, + $path, + (string) $request->validated('content'), + ); + } catch (CustomAssetOperationException $e) { + return $this->error($e->errorKey, 422, null, $e->params); + } catch (\Throwable $e) { + Log::error('사용자 추가 에셋 저장 실패', [ + 'type' => $type, + 'identifier' => $identifier, + 'error' => $e->getMessage(), + ]); + + return $this->error('custom_assets.errors.write_failed', 500, $e, ['path' => $path]); + } + + return $this->success('custom_assets.messages.saved', $saved); + } + + /** + * 파일 업로드 (폰트·이미지 등 바이너리 포함). + * + * @param UploadExtensionCustomAssetRequest $request 검증된 요청 (`file`, `directory`) + * @param string $type 확장 타입 + * @param string $identifier 확장 식별자 + * @return JsonResponse 업로드 결과 + */ + public function upload(UploadExtensionCustomAssetRequest $request, string $type, string $identifier): JsonResponse + { + $directory = $request->validated('directory'); + + try { + $uploaded = $this->service->upload( + $this->resolveType($type), + $identifier, + $request->file('file'), + is_string($directory) ? $directory : null, + ); + } catch (CustomAssetOperationException $e) { + return $this->error($e->errorKey, 422, null, $e->params); + } catch (\Throwable $e) { + Log::error('사용자 추가 에셋 업로드 실패', [ + 'type' => $type, + 'identifier' => $identifier, + 'error' => $e->getMessage(), + ]); + + return $this->error('custom_assets.errors.write_failed', 500, $e, ['path' => (string) $directory]); + } + + return $this->success('custom_assets.messages.uploaded', $uploaded); + } + + /** + * 파일 삭제. + * + * @param ReadExtensionCustomAssetRequest $request 검증된 요청 (`path`) + * @param string $type 확장 타입 + * @param string $identifier 확장 식별자 + * @return JsonResponse 삭제 결과 + */ + public function destroy(ReadExtensionCustomAssetRequest $request, string $type, string $identifier): JsonResponse + { + $path = (string) $request->validated('path'); + + try { + $this->service->delete($this->resolveType($type), $identifier, $path); + } catch (CustomAssetOperationException $e) { + return $this->error($e->errorKey, 422, null, $e->params); + } catch (\Throwable $e) { + Log::error('사용자 추가 에셋 삭제 실패', [ + 'type' => $type, + 'identifier' => $identifier, + 'error' => $e->getMessage(), + ]); + + return $this->error('custom_assets.errors.delete_failed', 500, $e, ['path' => $path]); + } + + return $this->success('custom_assets.messages.deleted', ['path' => $path]); + } + + /** + * 라우트 타입 파라미터를 해석기 어휘로 바꿉니다. + * + * 라우트 정규식이 이미 세 값으로 제한하지만, 매핑에 없으면 그대로 넘긴다 — + * 해석기가 알 수 없는 타입을 무효로 판정해 422 를 만든다(빈 목록으로 조용히 + * 통과시키지 않는다). + * + * @param string $type 라우트 파라미터 + * @return string 해석기 어휘 + */ + private function resolveType(string $type): string + { + return self::TYPE_MAP[$type] ?? $type; + } +} diff --git a/app/Http/Controllers/Api/Admin/ModuleController.php b/app/Http/Controllers/Api/Admin/ModuleController.php index ce2c228f..00aea1ac 100644 --- a/app/Http/Controllers/Api/Admin/ModuleController.php +++ b/app/Http/Controllers/Api/Admin/ModuleController.php @@ -390,10 +390,19 @@ class ModuleController extends AdminBaseController $moduleName = $validated['module_name']; $deleteData = $validated['delete_data'] ?? false; - $result = $this->moduleService->uninstallModule($moduleName, $deleteData, $uninstallFailureReason); + $result = $this->moduleService->uninstallModule( + $moduleName, + $deleteData, + $uninstallFailureReason, + $preservedBackups + ); if ($result) { - return $this->success('module.uninstall_success'); + // 운영자가 넣은 `custom/` 은 삭제 전에 사본을 남긴다 — 그 경로를 응답에 실어 + // 알리지 않으면 로그를 뒤지지 않는 한 사본의 존재를 알 수 없다. + return $this->success('module.uninstall_success', [ + 'preserved_backups' => $preservedBackups ?? [], + ]); } else { return $this->error('module.uninstall_failed', 400, null, [ 'error' => $uninstallFailureReason ?? __('modules.errors.unknown_error'), diff --git a/app/Http/Controllers/Api/Admin/PluginController.php b/app/Http/Controllers/Api/Admin/PluginController.php index 7f85fb81..f49da0a9 100644 --- a/app/Http/Controllers/Api/Admin/PluginController.php +++ b/app/Http/Controllers/Api/Admin/PluginController.php @@ -397,10 +397,19 @@ class PluginController extends AdminBaseController $pluginName = $validated['plugin_name']; $deleteData = $validated['delete_data'] ?? false; - $result = $this->pluginService->uninstallPlugin($pluginName, $deleteData, $uninstallFailureReason); + $result = $this->pluginService->uninstallPlugin( + $pluginName, + $deleteData, + $uninstallFailureReason, + $preservedBackups + ); if ($result) { - return $this->success('plugins.uninstall_success'); + // 운영자가 넣은 `custom/` 은 삭제 전에 사본을 남긴다 — 그 경로를 응답에 실어 + // 알리지 않으면 로그를 뒤지지 않는 한 사본의 존재를 알 수 없다. + return $this->success('plugins.uninstall_success', [ + 'preserved_backups' => $preservedBackups ?? [], + ]); } else { return $this->error('plugins.uninstall_failed', 400, null, [ 'error' => $uninstallFailureReason ?? __('plugins.errors.unknown_error'), diff --git a/app/Http/Controllers/Api/Admin/TemplateController.php b/app/Http/Controllers/Api/Admin/TemplateController.php index 5bbef459..0ab4c10d 100644 --- a/app/Http/Controllers/Api/Admin/TemplateController.php +++ b/app/Http/Controllers/Api/Admin/TemplateController.php @@ -286,10 +286,14 @@ class TemplateController extends AdminBaseController $templateName = $validated['template_name']; $deleteData = $validated['delete_data'] ?? false; - $result = $this->templateService->uninstallTemplate($templateName, $deleteData); + $result = $this->templateService->uninstallTemplate($templateName, $deleteData, $preservedBackups); if ($result) { - return $this->success('templates.uninstall_success'); + // 운영자가 넣은 `custom/` 은 삭제 전에 사본을 남긴다 — 그 경로를 응답에 실어 + // 알리지 않으면 로그를 뒤지지 않는 한 사본의 존재를 알 수 없다. + return $this->success('templates.uninstall_success', [ + 'preserved_backups' => $preservedBackups ?? [], + ]); } else { return $this->error('templates.uninstall_failed', 400, null, [ 'error' => __('templates.errors.unknown_error'), diff --git a/app/Http/Requests/Admin/Extension/ReadExtensionCustomAssetRequest.php b/app/Http/Requests/Admin/Extension/ReadExtensionCustomAssetRequest.php new file mode 100644 index 00000000..c2ccd181 --- /dev/null +++ b/app/Http/Requests/Admin/Extension/ReadExtensionCustomAssetRequest.php @@ -0,0 +1,56 @@ + + */ + public function rules(): array + { + $rules = [ + // 삭제는 폰트·이미지도 대상이므로 확장자 제한을 두지 않는다. 편집 가능 여부는 + // 서비스가 판정한다 — 여기서 편집 확장자로 좁히면 올린 폰트를 지울 수 없다. + 'path' => ['required', 'string', 'max:255', new SafeCustomAssetPath], + ]; + + return HookManager::applyFilters('core.extension_custom_asset.read_validation_rules', $rules, $this); + } + + /** + * 검증 메시지 + * + * @return array + */ + public function messages(): array + { + return [ + 'path.required' => __('custom_assets.validation.path_required'), + ]; + } +} diff --git a/app/Http/Requests/Admin/Extension/SaveExtensionCustomAssetRequest.php b/app/Http/Requests/Admin/Extension/SaveExtensionCustomAssetRequest.php new file mode 100644 index 00000000..6606a800 --- /dev/null +++ b/app/Http/Requests/Admin/Extension/SaveExtensionCustomAssetRequest.php @@ -0,0 +1,60 @@ + + */ + public function rules(): array + { + $rules = [ + 'path' => ['required', 'string', 'max:255', new SafeCustomAssetPath(CustomAssetService::EDITABLE_EXTENSIONS)], + // 빈 문자열 저장을 허용한다 — 운영자가 CSS 를 통째로 비우는 것은 정당한 조작이고, + // 그것을 막으면 파일을 지우는 것 말고는 되돌릴 방법이 없어진다. + 'content' => ['present', 'string', 'max:'.CustomAssetService::MAX_TEXT_BYTES], + ]; + + return HookManager::applyFilters('core.extension_custom_asset.save_validation_rules', $rules, $this); + } + + /** + * 검증 메시지 + * + * @return array + */ + public function messages(): array + { + return [ + 'path.required' => __('custom_assets.validation.path_required'), + 'content.present' => __('custom_assets.validation.content_present'), + 'content.max' => __('custom_assets.errors.too_large_to_edit', [ + 'limit' => (string) CustomAssetService::MAX_TEXT_BYTES, + ]), + ]; + } +} diff --git a/app/Http/Requests/Admin/Extension/UploadExtensionCustomAssetRequest.php b/app/Http/Requests/Admin/Extension/UploadExtensionCustomAssetRequest.php new file mode 100644 index 00000000..56f884a8 --- /dev/null +++ b/app/Http/Requests/Admin/Extension/UploadExtensionCustomAssetRequest.php @@ -0,0 +1,72 @@ + + */ + public function rules(): array + { + $maxKilobytes = (int) (CustomAssetService::MAX_UPLOAD_BYTES / 1024); + + $rules = [ + 'file' => [ + 'required', + 'file', + 'max:'.$maxKilobytes, + 'mimes:'.implode(',', AllowedTemplateFileType::getAllowedExtensions()), + ], + // 하위 디렉토리는 선택 — 없으면 `custom/` 바로 아래에 놓인다. + 'directory' => ['nullable', 'string', 'max:200', new SafeCustomAssetPath], + ]; + + return HookManager::applyFilters('core.extension_custom_asset.upload_validation_rules', $rules, $this); + } + + /** + * 검증 메시지 + * + * @return array + */ + public function messages(): array + { + return [ + 'file.required' => __('custom_assets.validation.file_required'), + 'file.file' => __('custom_assets.validation.file_invalid'), + 'file.mimes' => __('custom_assets.validation.file_mimes', [ + 'allowed' => implode(', ', AllowedTemplateFileType::getAllowedExtensions()), + ]), + 'file.max' => __('custom_assets.errors.upload_too_large', [ + 'limit' => (string) CustomAssetService::MAX_UPLOAD_BYTES, + ]), + ]; + } +} diff --git a/app/Http/Requests/Public/Template/ServeTemplateAssetRequest.php b/app/Http/Requests/Public/Template/ServeTemplateAssetRequest.php index 8902303e..570c9491 100644 --- a/app/Http/Requests/Public/Template/ServeTemplateAssetRequest.php +++ b/app/Http/Requests/Public/Template/ServeTemplateAssetRequest.php @@ -4,6 +4,7 @@ namespace App\Http\Requests\Public\Template; use App\Rules\AllowedTemplateFileType; use App\Rules\SafeTemplatePath; +use App\Support\CustomAssets; use App\Support\Routing\DualExtensionRoute; use Illuminate\Foundation\Http\FormRequest; @@ -32,9 +33,19 @@ class ServeTemplateAssetRequest extends FormRequest // 확장 가능한 "동적 필드" 가 없는 요청이라 룰의 취지(필드 확장)도 해당하지 않는다. public function rules(): array { - // 템플릿 식별자로부터 기준 경로 구성 + // 템플릿 식별자로부터 기준 경로 구성. + // + // 컨테인먼트 기준은 **실제로 읽는 디렉토리**여야 한다. 템플릿 자산은 `dist/` 이하가 + // 기본이지만 운영자 소유 디렉토리(`custom/`)만은 그 밖에 있고, 서빙측 + // `TemplateService::getAssetFilePath()` 가 그 분기를 갖는다. 기준을 `dist` 로 + // 고정하면 `custom/**` 은 realpath 가 실패해 문자열 접두 비교로만 통과하므로, + // 검증한 경로와 읽는 경로가 서로 다른 상태가 된다. 두 곳의 분기를 같은 조건으로 + // 맞춰 둔다 — 한쪽만 바뀌면 custom 서빙이 조용히 깨지거나 검증이 헐거워진다. $identifier = $this->route('identifier'); - $basePath = base_path("templates/{$identifier}/dist"); + $requestedPath = (string) $this->input('path'); + $basePath = str_starts_with($requestedPath, CustomAssets::DIRECTORY.'/') + ? base_path("templates/{$identifier}") + : base_path("templates/{$identifier}/dist"); return [ 'identifier' => ['required', 'string'], diff --git a/app/Http/Resources/TemplateResource.php b/app/Http/Resources/TemplateResource.php index 1e026c66..161d027a 100644 --- a/app/Http/Resources/TemplateResource.php +++ b/app/Http/Resources/TemplateResource.php @@ -4,6 +4,7 @@ namespace App\Http\Resources; use App\Contracts\Repositories\ModuleRepositoryInterface; use App\Contracts\Repositories\PluginRepositoryInterface; +use App\Services\ExtensionStaticCacheService; use App\Support\TemplateExternals; use Composer\Semver\Semver; use Illuminate\Http\Request; @@ -118,8 +119,18 @@ class TemplateResource extends BaseApiResource 'components' => $this->getValue('components', ['basic' => [], 'composite' => []]), 'license' => $this->getValue('license'), 'metadata' => $this->getValue('metadata', []), - // 외부 리소스 (template.json externals) — 정규화 책임은 TemplateExternals 에 위임 - 'externals' => TemplateExternals::normalize($this->getValue('externals', [])), + // 외부 리소스 (template.json externals) — 정규화 책임은 TemplateExternals 에 위임. + // `asset` 항목의 URL 해석에는 식별자와 캐시 버전이 필요하므로 뷰 컴포저 + // (CollectsTemplateExternals) 와 같은 인자를 넘긴다 — 빠뜨리면 `asset` 항목이 + // "식별자 미상" 으로 조용히 버려져 응답에서 사라진다. + 'externals' => TemplateExternals::normalize( + $this->getValue('externals', []), + $this->getValue('identifier'), + // 트레이트를 사용하는 클래스 경유로 호출한다 — 트레이트 정적 메서드 + // 직접 호출(`ClearsTemplateCaches::`)은 PHP 8.1+ E_DEPRECATED 라 + // 템플릿 상세 응답마다 로그를 남긴다 (AssetUrl::staticExtBase 와 동형). + ExtensionStaticCacheService::getExtensionCacheVersion(), + ), // 의존성 상세 정보 'dependencies' => $this->getDetailedDependencies(), // 타임스탬프 diff --git a/app/Http/View/Composers/TemplateComposer.php b/app/Http/View/Composers/TemplateComposer.php index 01cef569..6bd14759 100644 --- a/app/Http/View/Composers/TemplateComposer.php +++ b/app/Http/View/Composers/TemplateComposer.php @@ -8,6 +8,7 @@ use App\Extension\PluginManager; use App\Extension\TemplateManager; use App\Extension\Traits\ClearsTemplateCaches; use App\Http\View\Composers\Traits\CollectsActiveExtensionMeta; +use App\Http\View\Composers\Traits\CollectsCustomAssets; use App\Http\View\Composers\Traits\CollectsExtensionAssets; use App\Http\View\Composers\Traits\CollectsTemplateExternals; use App\Services\ModuleSettingsService; @@ -20,6 +21,7 @@ use Illuminate\View\View; class TemplateComposer { use CollectsActiveExtensionMeta; + use CollectsCustomAssets; use CollectsExtensionAssets; use CollectsTemplateExternals; @@ -95,12 +97,13 @@ class TemplateComposer $appConfig = []; } - // 템플릿의 외부 리소스 정보 수집 - $templateExternals = $this->collectTemplateExternals($activeTemplate); - // 확장 기능 캐시 버전 (브라우저 캐시 무효화용) $extensionCacheVersion = ClearsTemplateCaches::getExtensionCacheVersion(); + // 템플릿의 외부 리소스 정보 수집 + // (자체 제공 `asset` 항목의 URL 을 만들 때 캐시 버전이 필요해 뒤로 옮겼다) + $templateExternals = $this->collectTemplateExternals($activeTemplate, $extensionCacheVersion); + // 확장 프론트엔드 병합 번들 URL (상시 ON — 활성 에셋이 없으면 null) $bundleUrls = $this->buildExtensionBundleUrls($moduleAssets, $pluginAssets, $extensionCacheVersion); @@ -120,6 +123,8 @@ class TemplateComposer $view->with('activePluginsMeta', $activePluginsMeta); $view->with('appConfig', $appConfig); $view->with('templateExternals', $templateExternals); + $view->with('customAssets', $this->collectCustomAssets($activeTemplate)); + $view->with('customAssetsDisabled', $this->customAssetsDisabledByRequest()); $view->with('trustedScriptHosts', $trustedScriptHosts); } } diff --git a/app/Http/View/Composers/Traits/CollectsCustomAssets.php b/app/Http/View/Composers/Traits/CollectsCustomAssets.php new file mode 100644 index 00000000..e63a7d30 --- /dev/null +++ b/app/Http/View/Composers/Traits/CollectsCustomAssets.php @@ -0,0 +1,216 @@ +> 서술자 목록 (로드 순서대로) + */ + private function collectCustomAssets(?string $templateIdentifier): array + { + if ($this->customAssetsDisabledByRequest()) { + return []; + } + + $assets = $this->resolveCustomAssets($templateIdentifier); + + // 변경을 감지해 버전이 올랐다면 방금 만든 URL 은 **옛 버전**을 가리킨다. + // 그대로 내보내면 운영자가 파일을 고친 그 화면에서만 옛 CSS 가 보이고, 새로고침 + // 한 번을 더 해야 반영된다 — 원인을 알 수 없는 한 박자 지연으로만 나타난다. + // 새 버전으로 다시 해석한다. 게시본은 아직 없으므로 URL 은 API 형태로 떨어지고, + // 그 응답은 디스크의 최신 내용을 그대로 준다. 다음 요청부터 정적 경로가 된다. + if ($this->syncCustomAssetCacheVersion($assets, $templateIdentifier)) { + CustomAssets::flushCache(); + $assets = $this->resolveCustomAssets($templateIdentifier); + } + + return $assets; + } + + /** + * 활성 확장의 사용자 추가 에셋 서술자를 해석합니다. + * + * @param string|null $templateIdentifier 활성 템플릿 식별자 + * @return array> 서술자 목록 (로드 순서대로) + */ + private function resolveCustomAssets(?string $templateIdentifier): array + { + $assets = []; + + foreach ($this->activeExtensionIdentifiers('modules') as $identifier) { + $assets = array_merge($assets, CustomAssets::forExtension('modules', $identifier)); + } + + foreach ($this->activeExtensionIdentifiers('plugins') as $identifier) { + $assets = array_merge($assets, CustomAssets::forExtension('plugins', $identifier)); + } + + if (! empty($templateIdentifier)) { + $assets = array_merge($assets, CustomAssets::forExtension('templates', $templateIdentifier)); + } + + return $assets; + } + + /** + * 운영자가 파일을 고쳤으면 확장 캐시 버전을 올립니다. + * + * custom 자산은 확장 자산과 **같은 메커니즘**으로 정적 게시되므로 갱신 축도 같아야 + * 한다. 그런데 확장 캐시 버전은 수명주기 이벤트에서만 오르고, 운영자가 FTP 로 파일 + * 하나를 바꾸는 것은 그 이벤트가 아니다. 그래서 파일 서명이 달라진 것을 여기서 + * 감지해 같은 단일 지점(`incrementExtensionCacheVersion`)을 호출한다 — 그 지점이 + * 재게시 예약까지 담당하므로 새로 만들 기계가 없다. + * + * 서명이 **저장된 적 없으면 올리지 않는다.** 캐시 스토어가 요청마다 비는 환경 + * (array 스토어 등)에서 "매번 달라짐" 으로 읽혀 버전이 무한히 오르고 재게시가 + * 끝없이 돌게 되기 때문이다. 첫 관측은 기록만 하고 다음 변화부터 반응한다. + * + * 버전을 올렸으면 `true` 를 돌려준다 — 호출자가 서술자를 다시 해석해야 한다. + * 이미 만든 URL 은 옛 버전을 가리키기 때문이다. + * + * 서명은 **렌더 스코프별로** 따로 기억한다. 수집 대상이 모듈·플러그인(양쪽 동일)에 + * 더해 `resolveCustomAssets` 가 싣는 **그 렌더의 템플릿 하나**라, 관리자 렌더와 + * 사용자 렌더의 서명은 파일이 그대로여도 정상적으로 다르다. 기억할 자리가 하나면 + * 두 렌더가 번갈아 덮어쓰며 매번 "파일이 바뀌었다" 로 읽혀, 운영자가 아무것도 + * 건드리지 않았는데 페이지를 오갈 때마다 확장 캐시 버전이 오르고 전체 재게시가 + * 예약된다(모든 자산 URL 이 상시 변동 → 브라우저 캐시 무효). 예외도 화면 이상도 + * 없어 로그 외에는 드러나지 않는다. + * + * 스코프를 나누되 **키는 하나로 두고 값을 맵으로** 쓴다. `CustomAssetService` 가 + * 쓰기 뒤 이 키 하나를 `forget` 하는 것에 의존하므로(같은 키를 보는 두 소비자), + * 키를 쪼개면 그 소비자가 일부만 지우게 되어 같은 결함군이 재생산된다. + * + * @param array> $assets 수집된 서술자 목록 + * @param string|null $scope 렌더 스코프 (활성 템플릿 식별자) + * @return bool 확장 캐시 버전을 올렸으면 true + */ + private function syncCustomAssetCacheVersion(array $assets, ?string $scope = null): bool + { + try { + $parts = []; + + foreach ($assets as $asset) { + // 파일 출처만 본다 — 외부 URL·훅이 더한 항목은 파일 서명이 없다 + if (($asset['source'] ?? null) !== 'file') { + continue; + } + + $parts[] = ($asset['id'] ?? '').'@'.($asset['version'] ?? ''); + } + + sort($parts, SORT_STRING); + $signature = $parts === [] ? 'empty' : md5(implode('|', $parts)); + + $scopeKey = $scope ?? ''; + + $cache = app(CacheInterface::class); + + // 구 배포본이 남긴 스칼라 값은 맵이 아니다 — 어느 스코프의 것인지 알 수 없으므로 + // 서명으로 쓰지 않고 미관측으로 취급한다(첫 관측은 기록만 하니 헛된 bump 가 없다). + $storedMap = $cache->get(CustomAssets::SIGNATURE_CACHE_KEY); + $storedMap = is_array($storedMap) ? $storedMap : []; + + $stored = $storedMap[$scopeKey] ?? null; + + if ($stored === $signature) { + return false; + } + + $storedMap[$scopeKey] = $signature; + $cache->put(CustomAssets::SIGNATURE_CACHE_KEY, $storedMap); + + if ($stored === null) { + return false; + } + + Log::info('사용자 추가 에셋 변경 감지 — 확장 캐시 버전을 올립니다.', [ + 'scope' => $scopeKey, + 'previous' => $stored, + 'current' => $signature, + ]); + + $this->incrementExtensionCacheVersion(); + + return true; + } catch (\Exception $e) { + // 감지 실패가 화면을 막지 않는다 — 최악이라도 URL 이 한동안 옛 버전일 뿐이다 + Log::warning('사용자 추가 에셋 변경 감지 실패', ['error' => $e->getMessage()]); + + return false; + } + } + + /** + * 이번 요청이 사용자 추가 에셋을 끄도록 요구했는지 판정합니다. + * + * 판정을 수집 **맨 앞**에 두는 것이 중요하다. 뒤에 두면 빈 목록이 변경 감지 + * (`syncCustomAssetCacheVersion`)에 도달해 "전부 사라짐" 으로 읽히고, 그 다음 정상 + * 요청이 다시 "전부 생김" 으로 읽혀 요청마다 확장 캐시 버전이 오르내린다. + * + * @return bool `?custom=off` 이면 true + */ + private function customAssetsDisabledByRequest(): bool + { + try { + return request()->query('custom') === 'off'; + } catch (\Exception $e) { + // 요청 컨텍스트가 없는 렌더(콘솔·SEO 사전 렌더 등)는 끄지 않는다 + return false; + } + } + + /** + * 활성 확장 식별자 목록을 돌려줍니다. + * + * @param string $extensionType `modules` | `plugins` + * @return array 식별자 목록 + */ + private function activeExtensionIdentifiers(string $extensionType): array + { + try { + $active = $extensionType === 'modules' + ? $this->moduleManager->getActiveModules() + : $this->pluginManager->getActivePlugins(); + + return array_keys($active); + } catch (\Exception $e) { + Log::warning("Failed to collect active {$extensionType} for custom assets: ".$e->getMessage()); + + return []; + } + } +} diff --git a/app/Http/View/Composers/Traits/CollectsTemplateExternals.php b/app/Http/View/Composers/Traits/CollectsTemplateExternals.php index f3c5efd6..73fb2c57 100644 --- a/app/Http/View/Composers/Traits/CollectsTemplateExternals.php +++ b/app/Http/View/Composers/Traits/CollectsTemplateExternals.php @@ -21,10 +21,14 @@ trait CollectsTemplateExternals * * template.json의 externals 배열만 사용하며 legacy key fallback은 제공하지 않습니다. * + * 항목이 `asset`(템플릿이 자체 제공하는 `dist/` 이하 경로)을 선언하면 식별자와 + * 캐시 버전으로 자산 URL 을 만든다 — 그래서 둘을 함께 받는다. + * * @param string|null $templateIdentifier 템플릿 식별자 + * @param int|string|null $version 캐시 무효화 버전 (`asset` 항목의 `?v`) * @return array> */ - private function collectTemplateExternals(?string $templateIdentifier): array + private function collectTemplateExternals(?string $templateIdentifier, int|string|null $version = null): array { if (empty($templateIdentifier)) { return []; @@ -37,7 +41,7 @@ trait CollectsTemplateExternals return []; } - return TemplateExternals::normalize($template['externals']); + return TemplateExternals::normalize($template['externals'], $templateIdentifier, $version); } catch (\Exception $e) { Log::warning('Failed to collect template externals: '.$e->getMessage()); diff --git a/app/Http/View/Composers/UserTemplateComposer.php b/app/Http/View/Composers/UserTemplateComposer.php index 4205a4c3..26869ec0 100644 --- a/app/Http/View/Composers/UserTemplateComposer.php +++ b/app/Http/View/Composers/UserTemplateComposer.php @@ -8,6 +8,7 @@ use App\Extension\PluginManager; use App\Extension\TemplateManager; use App\Extension\Traits\ClearsTemplateCaches; use App\Http\View\Composers\Traits\CollectsActiveExtensionMeta; +use App\Http\View\Composers\Traits\CollectsCustomAssets; use App\Http\View\Composers\Traits\CollectsExtensionAssets; use App\Http\View\Composers\Traits\CollectsTemplateExternals; use App\Services\ModuleSettingsService; @@ -25,6 +26,7 @@ use Illuminate\View\View; class UserTemplateComposer { use CollectsActiveExtensionMeta; + use CollectsCustomAssets; use CollectsExtensionAssets; use CollectsTemplateExternals; @@ -101,12 +103,13 @@ class UserTemplateComposer $appConfig = []; } - // 템플릿의 외부 리소스 정보 수집 - $templateExternals = $this->collectTemplateExternals($activeTemplate); - // 확장 기능 캐시 버전 (브라우저 캐시 무효화용) $extensionCacheVersion = ClearsTemplateCaches::getExtensionCacheVersion(); + // 템플릿의 외부 리소스 정보 수집 + // (자체 제공 `asset` 항목의 URL 을 만들 때 캐시 버전이 필요해 뒤로 옮겼다) + $templateExternals = $this->collectTemplateExternals($activeTemplate, $extensionCacheVersion); + // 확장 프론트엔드 병합 번들 URL (상시 ON — 활성 에셋이 없으면 null) $bundleUrls = $this->buildExtensionBundleUrls($moduleAssets, $pluginAssets, $extensionCacheVersion); @@ -126,6 +129,8 @@ class UserTemplateComposer $view->with('activePluginsMeta', $activePluginsMeta); $view->with('appConfig', $appConfig); $view->with('templateExternals', $templateExternals); + $view->with('customAssets', $this->collectCustomAssets($activeTemplate)); + $view->with('customAssetsDisabled', $this->customAssetsDisabledByRequest()); $view->with('trustedScriptHosts', $trustedScriptHosts); } } diff --git a/app/Listeners/CoreActivityLogListener.php b/app/Listeners/CoreActivityLogListener.php index ef1fbdcf..41710c51 100644 --- a/app/Listeners/CoreActivityLogListener.php +++ b/app/Listeners/CoreActivityLogListener.php @@ -130,6 +130,7 @@ class CoreActivityLogListener implements HookListenerInterface 'core.templates.after_uninstall' => ['method' => 'handleTemplateAfterUninstall', 'priority' => 20], 'core.templates.after_version_update' => ['method' => 'handleTemplateAfterVersionUpdate', 'priority' => 20], 'core.templates.after_refresh_layouts' => ['method' => 'handleTemplateAfterRefreshLayouts', 'priority' => 20], + 'core.custom_assets.after_change' => ['method' => 'handleCustomAssetAfterChange', 'priority' => 20], // ─── Layout ─── 'core.layout.after_update' => ['method' => 'handleLayoutAfterUpdate', 'priority' => 20], @@ -1103,6 +1104,31 @@ class CoreActivityLogListener implements HookListenerInterface ]); } + /** + * 사용자 추가 에셋(`custom/`) 변경 후 로그 기록 + * + * @param string $extensionType 확장 타입 (`templates` 등) + * @param string $identifier 확장 식별자 + * @param string $operation 수행한 작업 (`save` | `upload` | `delete`) + * @param string $path `custom/` 기준 상대 경로 + */ + public function handleCustomAssetAfterChange( + string $extensionType, + string $identifier, + string $operation, + string $path + ): void { + $this->logActivity('custom_asset.'.$operation, [ + 'description_key' => 'activity_log.description.custom_asset_'.$operation, + 'description_params' => ['identifier' => $identifier, 'path' => $path], + 'properties' => [ + 'extension_type' => $extensionType, + 'identifier' => $identifier, + 'path' => $path, + ], + ]); + } + // ═══════════════════════════════════════════ // Layout 핸들러 // ═══════════════════════════════════════════ diff --git a/app/Rules/SafeCustomAssetPath.php b/app/Rules/SafeCustomAssetPath.php new file mode 100644 index 00000000..d8958bfe --- /dev/null +++ b/app/Rules/SafeCustomAssetPath.php @@ -0,0 +1,67 @@ +|null $allowedExtensions 허용 확장자 (null 이면 확장자 검사 생략) + */ + public function __construct(private readonly ?array $allowedExtensions = null) {} + + /** + * 경로가 안전한지 검증합니다. + * + * @param string $attribute 속성명 + * @param mixed $value 값 + * @param Closure $fail 실패 콜백 + * @return void + */ + public function validate(string $attribute, mixed $value, Closure $fail): void + { + if (! is_string($value)) { + $fail(__('custom_assets.errors.invalid_path', ['path' => ''])); + + return; + } + + $normalized = str_replace('\\', '/', trim($value)); + + if ($normalized === '' || str_starts_with($normalized, '/')) { + $fail(__('custom_assets.errors.invalid_path', ['path' => $value])); + + return; + } + + foreach (explode('/', $normalized) as $segment) { + if ($segment === '' || $segment === '.' || $segment === '..') { + $fail(__('custom_assets.errors.invalid_path', ['path' => $value])); + + return; + } + } + + if ($this->allowedExtensions === null) { + return; + } + + $extension = strtolower(pathinfo($normalized, PATHINFO_EXTENSION)); + + if (! in_array($extension, $this->allowedExtensions, true)) { + $fail(__('custom_assets.errors.extension_not_allowed', ['extension' => $extension])); + } + } +} diff --git a/app/Seo/SeoRenderer.php b/app/Seo/SeoRenderer.php index 1cf9fc91..53929e9f 100644 --- a/app/Seo/SeoRenderer.php +++ b/app/Seo/SeoRenderer.php @@ -485,7 +485,10 @@ class SeoRenderer implements SeoRendererInterface // stylesheets: 템플릿 자체 CSS + seo-config.json 선언 stylesheets 병합 $templateCssUrls = $this->getTemplateCssUrls($templateIdentifier); - $configStylesheets = $seoTemplateConfig['stylesheets'] ?? []; + $configStylesheets = $this->resolveConfigStylesheets( + $seoTemplateConfig['stylesheets'] ?? [], + $templateIdentifier + ); $allStylesheets = array_merge($templateCssUrls, $configStylesheets); $viewData = [ @@ -700,6 +703,42 @@ class SeoRenderer implements SeoRendererInterface } } + /** + * `seo-config.json` 의 stylesheets 선언을 실제 URL 로 해석합니다. + * + * 절대 URL(`http://`·`https://`·`//`)이나 `/` 로 시작하는 경로는 그대로 쓴다. + * 그 외 값은 **템플릿이 자체 제공하는 자산의 `dist/` 이하 경로**로 보고 자산 URL 을 + * 만든다 — 봇이 보는 화면도 사용자 화면과 같은 자산을 같은 origin 에서 받아야 한다. + * + * 정적 게시 경로는 쓰지 않는다(`allowStatic: false`). SEO 페이지는 캐시에 오래 + * 남는데, 정적 게시본은 GC(현재+직전 1개 보존) 대상이라 캐시된 HTML 이 사라진 + * 버전 디렉토리를 가리키게 된다. + * + * @param array $stylesheets 선언 목록 + * @param string $templateIdentifier 템플릿 식별자 + * @return array 해석된 URL 목록 + */ + private function resolveConfigStylesheets(array $stylesheets, string $templateIdentifier): array + { + $resolved = []; + + foreach ($stylesheets as $stylesheet) { + if (! is_string($stylesheet) || $stylesheet === '') { + continue; + } + + if (preg_match('#^(https?:)?//#i', $stylesheet) === 1 || str_starts_with($stylesheet, '/')) { + $resolved[] = $stylesheet; + + continue; + } + + $resolved[] = AssetUrl::templateAsset($templateIdentifier, $stylesheet, null, false); + } + + return $resolved; + } + /** * 템플릿의 CSS 에셋 URL 목록을 반환합니다. * diff --git a/app/Services/CustomAssetService.php b/app/Services/CustomAssetService.php new file mode 100644 index 00000000..cf048ee3 --- /dev/null +++ b/app/Services/CustomAssetService.php @@ -0,0 +1,392 @@ +> 파일 목록 (상대 경로 오름차순) + */ + public function list(string $extensionType, string $identifier): array + { + $directory = CustomAssets::directory($extensionType, $identifier); + + if ($directory === null || ! is_dir($directory)) { + return []; + } + + // 로드 대상 서술자를 미리 만들어, 목록의 각 파일이 실제로 페이지에 실리는지 + // (`loaded`) 알려준다. 규약 스캔·선언 파일 어느 쪽이든 결과는 같은 형태다. + // + // 서술자는 상대 경로 필드를 갖지 않는다 — 소비자가 출처에 의존하지 않도록 URL 과 + // id 만 노출하는 계약이다. 그래서 id 접두(`custom:{type}:{identifier}:`)를 떼어 + // 상대 경로를 얻는다. 훅이 더한 항목은 이 접두가 없어 자연히 제외되는데, 그것이 + // 옳다 — 디스크에 없는 항목을 파일 목록에 표시할 이유가 없다. + $idPrefix = 'custom:'.$extensionType.':'.$identifier.':'; + $loadedPaths = []; + + foreach (CustomAssets::forExtension($extensionType, $identifier) as $asset) { + $id = (string) ($asset['id'] ?? ''); + + if (($asset['source'] ?? null) !== 'file' || ! str_starts_with($id, $idPrefix)) { + continue; + } + + $loadedPaths[substr($id, strlen($idPrefix))] = true; + } + + $files = []; + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS), + \RecursiveIteratorIterator::SELF_FIRST + ); + + foreach ($iterator as $file) { + if (! $file->isFile()) { + continue; + } + + $relative = str_replace('\\', '/', substr($file->getPathname(), strlen($directory) + 1)); + $extension = strtolower($file->getExtension()); + + $files[] = [ + 'path' => $relative, + 'name' => $file->getFilename(), + 'extension' => $extension, + 'size' => $file->getSize(), + 'modified_at' => date('c', $file->getMTime()), + 'editable' => in_array($extension, self::EDITABLE_EXTENSIONS, true), + 'loaded' => isset($loadedPaths[$relative]), + ]; + } + + usort($files, fn (array $a, array $b) => strcmp($a['path'], $b['path'])); + + return $files; + } + + /** + * 텍스트 파일 본문을 읽습니다. + * + * @param string $extensionType 확장 타입 + * @param string $identifier 확장 식별자 + * @param string $relative `custom/` 기준 상대 경로 + * @return array{path: string, content: string, size: int} 본문 + * + * @throws CustomAssetOperationException 파일 부재·비편집 대상·크기 초과 시 + */ + public function read(string $extensionType, string $identifier, string $relative): array + { + $absolute = $this->resolveExisting($extensionType, $identifier, $relative); + + $extension = strtolower(pathinfo($relative, PATHINFO_EXTENSION)); + + if (! in_array($extension, self::EDITABLE_EXTENSIONS, true)) { + throw new CustomAssetOperationException('custom_assets.errors.not_editable', ['extension' => $extension]); + } + + $size = (int) filesize($absolute); + + if ($size > self::MAX_TEXT_BYTES) { + throw new CustomAssetOperationException('custom_assets.errors.too_large_to_edit', [ + 'limit' => (string) self::MAX_TEXT_BYTES, + ]); + } + + $content = file_get_contents($absolute); + + if ($content === false) { + throw new CustomAssetOperationException('custom_assets.errors.read_failed', ['path' => $relative]); + } + + return ['path' => $relative, 'content' => $content, 'size' => $size]; + } + + /** + * 텍스트 파일 본문을 저장합니다 (없으면 생성). + * + * @param string $extensionType 확장 타입 + * @param string $identifier 확장 식별자 + * @param string $relative `custom/` 기준 상대 경로 + * @param string $content 본문 + * @return array 저장된 파일 정보 + * + * @throws CustomAssetOperationException 경로 무효·쓰기 실패 시 + */ + public function save(string $extensionType, string $identifier, string $relative, string $content): array + { + $absolute = $this->resolveWritable($extensionType, $identifier, $relative); + + $extension = strtolower(pathinfo($relative, PATHINFO_EXTENSION)); + + if (! in_array($extension, self::EDITABLE_EXTENSIONS, true)) { + throw new CustomAssetOperationException('custom_assets.errors.not_editable', ['extension' => $extension]); + } + + if (strlen($content) > self::MAX_TEXT_BYTES) { + throw new CustomAssetOperationException('custom_assets.errors.too_large_to_edit', [ + 'limit' => (string) self::MAX_TEXT_BYTES, + ]); + } + + $this->ensureDirectory(dirname($absolute)); + + if (file_put_contents($absolute, $content) === false) { + throw new CustomAssetOperationException('custom_assets.errors.write_failed', ['path' => $relative]); + } + + $this->invalidate($extensionType, $identifier, 'save', $relative); + + return [ + 'path' => $relative, + 'size' => strlen($content), + 'modified_at' => date('c'), + ]; + } + + /** + * 업로드 파일을 `custom/` 에 저장합니다. + * + * @param string $extensionType 확장 타입 + * @param string $identifier 확장 식별자 + * @param UploadedFile $file 업로드 파일 + * @param string|null $directory `custom/` 기준 하위 디렉토리 (선택) + * @return array 저장된 파일 정보 + * + * @throws CustomAssetOperationException 경로 무효·확장자 불허·쓰기 실패 시 + */ + public function upload( + string $extensionType, + string $identifier, + UploadedFile $file, + ?string $directory = null + ): array { + $name = $this->sanitizeFileName($file->getClientOriginalName()); + $relative = $directory !== null && $directory !== '' ? trim($directory, '/').'/'.$name : $name; + + $absolute = $this->resolveWritable($extensionType, $identifier, $relative); + + $extension = strtolower(pathinfo($name, PATHINFO_EXTENSION)); + + if (! in_array($extension, AllowedTemplateFileType::getAllowedExtensions(), true)) { + throw new CustomAssetOperationException('custom_assets.errors.extension_not_allowed', [ + 'extension' => $extension, + ]); + } + + if ($file->getSize() > self::MAX_UPLOAD_BYTES) { + throw new CustomAssetOperationException('custom_assets.errors.upload_too_large', [ + 'limit' => (string) self::MAX_UPLOAD_BYTES, + ]); + } + + $this->ensureDirectory(dirname($absolute)); + $file->move(dirname($absolute), basename($absolute)); + + $this->invalidate($extensionType, $identifier, 'upload', $relative); + + return [ + 'path' => $relative, + 'size' => (int) @filesize($absolute), + 'modified_at' => date('c'), + ]; + } + + /** + * 파일을 삭제합니다. + * + * @param string $extensionType 확장 타입 + * @param string $identifier 확장 식별자 + * @param string $relative `custom/` 기준 상대 경로 + * @return void + * + * @throws CustomAssetOperationException 파일 부재·삭제 실패 시 + */ + public function delete(string $extensionType, string $identifier, string $relative): void + { + $absolute = $this->resolveExisting($extensionType, $identifier, $relative); + + if (! @unlink($absolute)) { + throw new CustomAssetOperationException('custom_assets.errors.delete_failed', ['path' => $relative]); + } + + $this->invalidate($extensionType, $identifier, 'delete', $relative); + } + + /** + * 쓰기 뒤 캐시·게시본을 무효화합니다. + * + * 확장 캐시 버전을 올리면 그 단일 지점이 정적 재게시까지 예약한다 — 편집한 파일이 + * 게시본에 반영되는 경로가 여기 한 곳으로 모인다. + * + * 변경 감지 서명은 **지운다**. 뷰 컴포저가 다음 렌더에서 같은 변경을 다시 발견해 + * 버전을 한 번 더 올리는 것을 막기 위해서다 (서명이 없으면 그 관측은 기록만 한다). + * + * @param string $extensionType 확장 타입 + * @param string $identifier 확장 식별자 + * @param string $operation 수행한 작업 (로그용) + * @param string $relative 대상 상대 경로 (로그용) + * @return void + */ + private function invalidate(string $extensionType, string $identifier, string $operation, string $relative): void + { + CustomAssets::flushCache(); + + try { + app(CacheInterface::class)->forget(CustomAssets::SIGNATURE_CACHE_KEY); + } catch (\Exception $e) { + Log::warning('사용자 추가 에셋 서명 캐시 삭제 실패', ['error' => $e->getMessage()]); + } + + $this->incrementExtensionCacheVersion(); + + Log::info('사용자 추가 에셋 변경', [ + 'extension_type' => $extensionType, + 'identifier' => $identifier, + 'operation' => $operation, + 'path' => $relative, + ]); + + // 운영자가 올린 스크립트는 사이트 전 화면에서 실행된다 — 누가 언제 무엇을 바꿨는지 + // 남지 않으면 사후에 되짚을 수단이 없다. 활동 로그가 그 유일한 기록이다. + HookManager::doAction('core.custom_assets.after_change', $extensionType, $identifier, $operation, $relative); + } + + /** + * 존재하는 파일의 절대 경로를 해석합니다. + * + * @param string $extensionType 확장 타입 + * @param string $identifier 확장 식별자 + * @param string $relative 상대 경로 + * @return string 절대 경로 + * + * @throws CustomAssetOperationException 경로 무효·파일 부재 시 + */ + private function resolveExisting(string $extensionType, string $identifier, string $relative): string + { + $absolute = $this->resolveWritable($extensionType, $identifier, $relative); + + if (! is_file($absolute)) { + throw new CustomAssetOperationException('custom_assets.errors.not_found', ['path' => $relative]); + } + + return $absolute; + } + + /** + * 쓰기 대상 절대 경로를 해석합니다 (아직 없어도 됩니다). + * + * 컨테인먼트는 문자열 접두 비교가 아니라 세그먼트 검사로 판정한다. 아직 없는 + * 파일은 `realpath` 가 실패하므로 실경로 정규화에 기댈 수 없고, 접두 비교만으로는 + * `custom-evil/` 같은 형제 디렉토리가 통과한다. + * + * @param string $extensionType 확장 타입 + * @param string $identifier 확장 식별자 + * @param string $relative 상대 경로 + * @return string 절대 경로 + * + * @throws CustomAssetOperationException 경로가 무효한 경우 + */ + private function resolveWritable(string $extensionType, string $identifier, string $relative): string + { + $directory = CustomAssets::directory($extensionType, $identifier); + + if ($directory === null) { + throw new CustomAssetOperationException('custom_assets.errors.invalid_extension_target', [ + 'identifier' => $identifier, + ]); + } + + $normalized = str_replace('\\', '/', trim($relative)); + + if ($normalized === '' || str_starts_with($normalized, '/')) { + throw new CustomAssetOperationException('custom_assets.errors.invalid_path', ['path' => $relative]); + } + + foreach (explode('/', $normalized) as $segment) { + if ($segment === '' || $segment === '.' || $segment === '..') { + throw new CustomAssetOperationException('custom_assets.errors.invalid_path', ['path' => $relative]); + } + } + + return $directory.DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $normalized); + } + + /** + * 업로드 파일명을 안전한 형태로 정규화합니다. + * + * @param string $name 원본 파일명 + * @return string 정규화된 파일명 + */ + private function sanitizeFileName(string $name): string + { + $base = basename(str_replace('\\', '/', $name)); + + return preg_replace('/[^A-Za-z0-9._-]/', '_', $base) ?? ''; + } + + /** + * 디렉토리를 보장합니다. + * + * @param string $directory 절대 경로 + * @return void + * + * @throws CustomAssetOperationException 생성 실패 시 + */ + private function ensureDirectory(string $directory): void + { + if (is_dir($directory)) { + return; + } + + if (! @mkdir($directory, 0755, true) && ! is_dir($directory)) { + throw new CustomAssetOperationException('custom_assets.errors.directory_failed', ['path' => $directory]); + } + } +} diff --git a/app/Services/ExtensionStaticCacheService.php b/app/Services/ExtensionStaticCacheService.php index 5b76aa98..eca69fea 100644 --- a/app/Services/ExtensionStaticCacheService.php +++ b/app/Services/ExtensionStaticCacheService.php @@ -2,6 +2,8 @@ namespace App\Services; +use App\Contracts\Repositories\ModuleRepositoryInterface; +use App\Contracts\Repositories\PluginRepositoryInterface; use App\Contracts\Repositories\TemplateRepositoryInterface; use App\Exceptions\StaticCachePublishException; use App\Extension\Helpers\FilePermissionHelper; @@ -9,6 +11,7 @@ use App\Extension\Traits\ClearsTemplateCaches; use App\Helpers\ResponseHelper; use App\Models\Template; use App\Rules\AllowedTemplateFileType; +use App\Support\CustomAssets; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Log; @@ -55,6 +58,8 @@ class ExtensionStaticCacheService public function __construct( private TemplateService $templateService, private TemplateRepositoryInterface $templateRepository, + private ModuleRepositoryInterface $moduleRepository, + private PluginRepositoryInterface $pluginRepository, private ExtensionBundleService $bundleService, private LanguagePackService $languagePackService, ) {} @@ -312,6 +317,8 @@ class ExtensionStaticCacheService $this->publishBundles($tmp, $version, $files); + $this->publishExtensionCustomAssets($tmp, $files); + // 원자적 스왑 — force 재게시 시 기존 디렉토리를 비켜낸 뒤 rename if (File::isDirectory($final)) { File::deleteDirectory($final); @@ -341,9 +348,14 @@ class ExtensionStaticCacheService return true; } catch (\Throwable $e) { + // 예외 종류와 발생 위치까지 남긴다. 메시지만으로는 파일시스템 오류인지 병합 + // 오류인지 구분되지 않아, 운영자도 개발자도 재현부터 다시 해야 한다 — + // 게시 실패는 사이트를 멈추지 않고 폴백으로 넘어가므로 이 로그가 유일한 흔적이다. Log::warning('부트스트랩 리소스 정적 게시 실패 — API 폴백으로 동작합니다', [ 'version' => $version, + 'exception' => $e::class, 'error' => $e->getMessage(), + 'at' => $e->getFile().':'.$e->getLine(), ]); File::deleteDirectory($tmp); @@ -443,18 +455,43 @@ class ExtensionStaticCacheService $files, $tmp ); + + // 5. 운영자 소유 디렉토리(`custom/`) 사본 + // + // 게시하지 않으면 이 자산만 API 경로에 남는데, 그 경로에서는 CSS 내부 상대 + // `url()` 이 해석되지 않는다 — `?file=` 형태는 기준 URL 이 `/api/templates/assets/` + // 라 `url('./font.woff2')` 가 그 디렉토리를 가리키고, 확장자 형태는 정적 최적화 + // 서버가 먼저 가로챈다(그래서 `extensionless` 모드가 존재한다). 즉 정적 확장자 + // URL 은 **public 아래 실제 파일일 때만** 200 이 되므로, 문서가 안내하는 + // "폰트·이미지를 custom/ 에 두고 상대 경로로 참조" 를 성립시키는 방법은 게시뿐이다. + // + // 갱신 축은 확장 자산과 동일하다 — 운영자가 파일을 고치면 `CustomAssets` 가 + // 그것을 감지해 `ext.cache_version` 을 올리고, 그 단일 지점이 재게시까지 예약한다. + $this->publishDistAssets( + base_path("templates/{$identifier}/".CustomAssets::DIRECTORY), + $templateDir.DIRECTORY_SEPARATOR.'assets'.DIRECTORY_SEPARATOR.CustomAssets::DIRECTORY, + $files, + $tmp, + excludeCustom: false + ); } /** * 템플릿 dist 디렉토리를 재귀 복사합니다 (허용 확장자만, 소스맵 제외). * - * @param string $sourceDir 원본 dist 절대 경로 + * @param string $sourceDir 원본 절대 경로 (dist 또는 custom) * @param string $targetDir 게시 대상 절대 경로 * @param array $files 기록된 상대 경로 누적 (참조) * @param string $tmp tmp 루트 (상대 경로 계산용) + * @param bool $excludeCustom 원본 안의 `custom/` 하위를 건너뛸지 (dist 원본에서만 참) */ - private function publishDistAssets(string $sourceDir, string $targetDir, array &$files, string $tmp): void - { + private function publishDistAssets( + string $sourceDir, + string $targetDir, + array &$files, + string $tmp, + bool $excludeCustom = true + ): void { $realSource = realpath($sourceDir); if ($realSource === false || ! is_dir($realSource)) { @@ -486,10 +523,33 @@ class ExtensionStaticCacheService } $relative = substr($realFile, strlen($realSource) + 1); + + // dist 원본에서는 `custom/` 하위를 건너뛴다 — 운영자 파일은 자기 원본 + // 루트로 따로 게시되므로, dist 를 통해 한 번 더 실리면 같은 파일이 두 경로에 + // 놓여 어느 쪽이 유효한지가 갈린다. custom 원본으로 호출될 때는 끄고 들어온다 + // (그러지 않으면 `custom/custom/…` 이 조용히 누락된다). + if ($excludeCustom && $this->isCustomAssetPath($relative)) { + continue; + } + $this->copyFile($realFile, $targetDir.DIRECTORY_SEPARATOR.$relative, $files, $tmp); } } + /** + * 상대 경로가 운영자 소유 디렉토리(`custom/`) 소속인지 판정합니다. + * + * @param string $relative 게시 원본 기준 상대 경로 + * @return bool custom 소속이면 true + */ + private function isCustomAssetPath(string $relative): bool + { + $normalized = str_replace(DIRECTORY_SEPARATOR, '/', $relative); + + return $normalized === CustomAssets::DIRECTORY + || str_starts_with($normalized, CustomAssets::DIRECTORY.'/'); + } + /** * 확장 병합 번들 4종(modules/plugins × js/css)을 게시합니다. * @@ -519,6 +579,59 @@ class ExtensionStaticCacheService } } + /** + * 활성 모듈·플러그인의 운영자 소유 디렉토리(`custom/`)를 게시합니다. + * + * 모듈·플러그인의 빌드 산출물은 **병합 번들**로만 게시되는데, `custom/` 은 그 번들에 + * 들어가지 않는다(운영자 파일은 번들보다 뒤에 따로 로드되어야 재정의가 성립한다). + * 그래서 게시하지 않으면 확장 자산 중 이것만 요청마다 PHP 를 거치고, 무엇보다 + * CSS 내부 상대 `url()` 이 해석되지 않는다 — `?file=` 형태는 기준 URL 이 + * `/api/modules/assets/` 라 `url('./font.woff2')` 가 그 디렉토리를 가리키고, + * 확장자 형태는 정적 최적화 서버가 먼저 가로챈다. 정적 확장자 URL 은 **public 아래 + * 실제 파일일 때만** 200 이 되므로 게시가 유일한 방법이다 (템플릿과 같은 사유). + * + * **활성 확장만** 게시한다. 자산 서빙이 활성 확장에만 응답하므로, 비활성 확장의 파일을 + * 게시해 봐야 아무도 참조하지 않는 사본이 버전 디렉토리마다 쌓일 뿐이다. + * + * @param string $tmp tmp 디렉토리 절대 경로 + * @param array $files 기록된 상대 경로 누적 (참조) + */ + private function publishExtensionCustomAssets(string $tmp, array &$files): void + { + // 활성 목록은 **레포지토리**에서 읽는다. 매니저(`getActiveModules()`)는 확장을 + // 실제로 적재하는 부작용이 있어, 게시 중에 그 부작용을 끌어들이면 게시가 확장 + // 부팅 상태에 좌우된다. 같은 메서드가 템플릿을 `templateRepository->getActive()` + // 로 세는 것과 대칭이다. + $sources = [ + 'modules' => $this->moduleRepository->getActiveModuleIdentifiers(), + 'plugins' => $this->pluginRepository->getActivePluginIdentifiers(), + ]; + + foreach ($sources as $root => $identifiers) { + foreach ($identifiers as $identifier) { + $identifier = (string) $identifier; + + if (! preg_match(self::IDENTIFIER_PATTERN, $identifier)) { + Log::warning('정적 게시 제외 — 식별자 패턴 불일치', [ + 'type' => $root, + 'identifier' => $identifier, + ]); + + continue; + } + + $this->publishDistAssets( + base_path("{$root}/{$identifier}/".CustomAssets::DIRECTORY), + $tmp.DIRECTORY_SEPARATOR.$root.DIRECTORY_SEPARATOR.$identifier + .DIRECTORY_SEPARATOR.'assets'.DIRECTORY_SEPARATOR.CustomAssets::DIRECTORY, + $files, + $tmp, + excludeCustom: false + ); + } + } + } + /** * 게시 대상 로케일을 열거합니다 — `/api/locales/active` 와 동일 소스 * (언어팩이 추가한 로케일 포함). diff --git a/app/Services/ModuleService.php b/app/Services/ModuleService.php index 7d765025..115d5c35 100644 --- a/app/Services/ModuleService.php +++ b/app/Services/ModuleService.php @@ -366,13 +366,20 @@ class ModuleService * @param string $moduleName 제거할 모듈명 * @param bool $deleteData 모듈 데이터(테이블) 삭제 여부 * @param string|null $failureReason 실패 시 사유가 담기는 out 파라미터 (성공 시 null) + * @param array|null $preservedBackups + * 삭제 전에 보관한 운영자 소유 디렉토리(`custom/`)의 사본 경로가 담기는 out 파라미터 * @return bool 제거 성공 여부 * * @throws ValidationException 모듈 제거 실패 시 */ - public function uninstallModule(string $moduleName, bool $deleteData = false, ?string &$failureReason = null): bool - { + public function uninstallModule( + string $moduleName, + bool $deleteData = false, + ?string &$failureReason = null, + ?array &$preservedBackups = null, + ): bool { $failureReason = null; + $preservedBackups = []; HookManager::doAction('core.modules.before_uninstall', $moduleName, $deleteData); @@ -381,7 +388,13 @@ class ModuleService $this->moduleManager->loadModules(); $moduleInfo = $this->moduleManager->getModuleInfo($moduleName); - $result = $this->moduleManager->uninstallModule($moduleName, $deleteData, null, $failureReason); + $result = $this->moduleManager->uninstallModule( + $moduleName, + $deleteData, + null, + $failureReason, + $preservedBackups + ); if ($result) { $module = $this->moduleRepository->findByName($moduleName); diff --git a/app/Services/PluginService.php b/app/Services/PluginService.php index 3767f183..3f64e81b 100644 --- a/app/Services/PluginService.php +++ b/app/Services/PluginService.php @@ -243,20 +243,33 @@ class PluginService * @param string $pluginName 플러그인 식별자 * @param bool $deleteData 플러그인이 생성한 DB 데이터/스토리지 디렉토리까지 삭제 여부 * @param string|null $failureReason 실패 시 사유가 담기는 out 파라미터 (성공 시 null) + * @param array|null $preservedBackups + * 삭제 전에 보관한 운영자 소유 디렉토리(`custom/`)의 사본 경로가 담기는 out 파라미터 * @return bool 제거 성공 여부 * * @throws ValidationException 제거 실패 시 */ - public function uninstallPlugin(string $pluginName, bool $deleteData = false, ?string &$failureReason = null): bool - { + public function uninstallPlugin( + string $pluginName, + bool $deleteData = false, + ?string &$failureReason = null, + ?array &$preservedBackups = null, + ): bool { $failureReason = null; + $preservedBackups = []; HookManager::doAction('core.plugins.before_uninstall', $pluginName, $deleteData); try { $this->pluginManager->loadPlugins(); - $result = $this->pluginManager->uninstallPlugin($pluginName, $deleteData, null, $failureReason); + $result = $this->pluginManager->uninstallPlugin( + $pluginName, + $deleteData, + null, + $failureReason, + $preservedBackups + ); HookManager::doAction('core.plugins.after_uninstall', $pluginName, $deleteData, $result); diff --git a/app/Services/TemplateService.php b/app/Services/TemplateService.php index 153c0667..6d2cddb9 100644 --- a/app/Services/TemplateService.php +++ b/app/Services/TemplateService.php @@ -16,6 +16,7 @@ use App\Extension\Helpers\GithubHelper; use App\Extension\Helpers\ZipInstallHelper; use App\Extension\HookManager; use App\Extension\Traits\ResolvesLanguageFragments; +use App\Support\CustomAssets; use Illuminate\Http\UploadedFile; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Log; @@ -432,19 +433,26 @@ class TemplateService * * @param string $identifier 제거할 템플릿 식별자 * @param bool $deleteData 템플릿 관련 데이터 삭제 여부 + * @param array|null $preservedBackups + * 삭제 전에 보관한 운영자 소유 디렉토리(`custom/`)의 사본 경로가 담기는 out 파라미터 * @return array|null 제거된 템플릿 정보 또는 null * * @throws ValidationException 제거 실패 시 */ - public function uninstallTemplate(string $identifier, bool $deleteData = false): ?array - { + public function uninstallTemplate( + string $identifier, + bool $deleteData = false, + ?array &$preservedBackups = null, + ): ?array { + $preservedBackups = []; + HookManager::doAction('core.templates.before_uninstall', $identifier, $deleteData); try { // 제거 전 템플릿 정보 보존 $templateInfo = $this->templateManager->getTemplateInfo($identifier); - $result = $this->templateManager->uninstallTemplate($identifier); + $result = $this->templateManager->uninstallTemplate($identifier, null, $preservedBackups); if ($result) { HookManager::doAction('core.templates.after_uninstall', $identifier, $templateInfo, $deleteData); @@ -660,7 +668,13 @@ class TemplateService $safePath = $this->sanitizePath($path); // 3. 파일 경로 구성 - $filePath = base_path("templates/{$identifier}/dist/{$safePath}"); + // + // 템플릿 자산은 `dist/` 이하가 기본이지만, 운영자 소유 디렉토리(`custom/`)만은 + // 그 밖에 있다 — 빌드 산출물이 아니라 사람이 넣은 파일이고, 확장 교체가 + // 보존하는 대상이라 빌드 디렉토리에 둘 수 없다. + $filePath = str_starts_with($safePath, CustomAssets::DIRECTORY.'/') + ? base_path("templates/{$identifier}/{$safePath}") + : base_path("templates/{$identifier}/dist/{$safePath}"); // 4. 파일 존재 확인 if (! file_exists($filePath) || ! is_file($filePath)) { diff --git a/app/Support/AssetUrl.php b/app/Support/AssetUrl.php index 71f15af8..1204c574 100644 --- a/app/Support/AssetUrl.php +++ b/app/Support/AssetUrl.php @@ -264,9 +264,13 @@ class AssetUrl * @param int|string|null $version 캐시 무효화 버전 (null 이면 미부착) * @return string 생성된 URL */ - public static function moduleAsset(string $identifier, string $path, int|string|null $version = null): string - { - return self::asset('modules', $identifier, $path, $version); + public static function moduleAsset( + string $identifier, + string $path, + int|string|null $version = null, + bool $allowStatic = false + ): string { + return self::extensionStaticOrApi('modules', $identifier, $path, $version, $allowStatic); } /** @@ -277,9 +281,52 @@ class AssetUrl * @param int|string|null $version 캐시 무효화 버전 (null 이면 미부착) * @return string 생성된 URL */ - public static function pluginAsset(string $identifier, string $path, int|string|null $version = null): string - { - return self::asset('plugins', $identifier, $path, $version); + public static function pluginAsset( + string $identifier, + string $path, + int|string|null $version = null, + bool $allowStatic = false + ): string { + return self::extensionStaticOrApi('plugins', $identifier, $path, $version, $allowStatic); + } + + /** + * 모듈·플러그인 자산의 정적 게시본 우선 URL 을 만듭니다. + * + * 정적 분기가 **기본 꺼짐**인 것이 템플릿과 다른 점이고, 그것이 의도다. 모듈·플러그인의 + * 빌드 산출물은 개별 파일로 게시되지 않고 **병합 번들**로만 게시되므로, 그 경로에 + * 존재 검사를 걸어 봐야 언제나 실패하는 파일시스템 조회만 늘어난다. 개별 게시 대상은 + * 운영자 소유 디렉토리(`custom/`) 하나뿐이라 그 호출부만 켜서 쓴다. + * + * @param string $root `modules` | `plugins` + * @param string $identifier 확장 식별자 + * @param string $path 확장 루트 기준 파일 경로 + * @param int|string|null $version 캐시 무효화 버전 + * @param bool $allowStatic 정적 게시본 우선 여부 + * @return string 생성된 URL + */ + private static function extensionStaticOrApi( + string $root, + string $identifier, + string $path, + int|string|null $version, + bool $allowStatic + ): string { + // 게이트는 템플릿과 동일하다 — 프로덕션·kill-switch·게시 완료·개별 파일 존재를 + // `staticTagUrl` 이 확인하고, 버전이 현재 게시본과 다르면 정적 분기를 건너뛴다. + if ($allowStatic) { + $base = self::staticExtBase(); + + if ($base !== null && ($version === null || $base === '/build/ext/'.$version)) { + $static = self::staticTagUrl($root.'/'.$identifier.'/assets/'.ltrim($path, '/')); + + if ($static !== null) { + return $static; + } + } + } + + return self::asset($root, $identifier, $path, $version); } /** diff --git a/app/Support/CustomAssets.php b/app/Support/CustomAssets.php new file mode 100644 index 00000000..14a8f801 --- /dev/null +++ b/app/Support/CustomAssets.php @@ -0,0 +1,433 @@ + 'style', + 'js' => 'script', + ]; + + /** 확장 타입 → 확장 루트 디렉토리 */ + private const ROOTS = [ + 'templates' => 'templates', + 'modules' => 'modules', + 'plugins' => 'plugins', + ]; + + /** 요청 스코프 메모이즈 (같은 요청에서 같은 확장을 여러 번 묻는 경로 대비) */ + private static array $cache = []; + + /** + * 확장 하나의 사용자 추가 에셋 목록을 돌려줍니다. + * + * @param string $extensionType `templates` | `modules` | `plugins` + * @param string $identifier 확장 식별자 + * @return array> 서술자 목록 + */ + public static function forExtension(string $extensionType, string $identifier): array + { + $cacheKey = $extensionType.'|'.$identifier; + + if (array_key_exists($cacheKey, self::$cache)) { + return self::$cache[$cacheKey]; + } + + $assets = self::resolve($extensionType, $identifier); + + // 7.1.0 템플릿 환경설정 등 다른 출처가 항목을 더할 수 있는 지점. + // 소비자는 출처를 보지 않으므로 여기서 더한 항목도 같은 규칙으로 로드된다. + $assets = HookManager::applyFilters('core.assets.custom_assets', $assets, $extensionType, $identifier); + + self::$cache[$cacheKey] = is_array($assets) ? array_values($assets) : []; + + return self::$cache[$cacheKey]; + } + + /** + * 요청 스코프 캐시를 비웁니다 (테스트·파일 변경 직후용). + * + * @return void + */ + public static function flushCache(): void + { + self::$cache = []; + } + + /** + * 확장의 `custom/` 디렉토리 절대 경로를 돌려줍니다. + * + * @param string $extensionType 확장 타입 + * @param string $identifier 확장 식별자 + * @return string|null 경로, 타입이 유효하지 않으면 null + */ + public static function directory(string $extensionType, string $identifier): ?string + { + $root = self::ROOTS[$extensionType] ?? null; + + if ($root === null || $identifier === '' || ! self::isSafeIdentifier($identifier)) { + return null; + } + + return base_path($root.'/'.$identifier.'/'.self::DIRECTORY); + } + + /** + * 선언 파일 또는 규약 스캔으로 자산 목록을 만듭니다. + * + * @param string $extensionType 확장 타입 + * @param string $identifier 확장 식별자 + * @return array> 서술자 목록 + */ + private static function resolve(string $extensionType, string $identifier): array + { + $directory = self::directory($extensionType, $identifier); + + if ($directory === null || ! is_dir($directory)) { + return []; + } + + $declaration = $directory.DIRECTORY_SEPARATOR.self::DECLARATION_FILE; + + if (is_file($declaration)) { + return self::fromDeclaration($declaration, $extensionType, $identifier, $directory); + } + + return self::fromConvention($extensionType, $identifier, $directory); + } + + /** + * `custom/assets.json` 선언을 해석합니다. + * + * 선언이 있으면 규약 스캔은 하지 않는다 — 둘을 합치면 "선언에서 뺐는데 왜 아직 + * 로드되나" 가 된다. 선언이 깨졌을 때도 스캔으로 되돌아가지 않는다. 되돌아가면 + * 운영자가 의도적으로 뺀 파일이 되살아난다. + * + * @param string $declaration 선언 파일 경로 + * @param string $extensionType 확장 타입 + * @param string $identifier 확장 식별자 + * @param string $directory `custom/` 절대 경로 + * @return array> 서술자 목록 + */ + private static function fromDeclaration( + string $declaration, + string $extensionType, + string $identifier, + string $directory + ): array { + $decoded = json_decode((string) file_get_contents($declaration), true); + + if (! is_array($decoded) || ! isset($decoded['assets']) || ! is_array($decoded['assets'])) { + Log::warning('사용자 추가 에셋 선언을 읽을 수 없습니다 (해당 확장의 custom 자산을 로드하지 않습니다).', [ + 'declaration' => $declaration, + 'json_error' => json_last_error_msg(), + ]); + + return []; + } + + $assets = []; + + foreach ($decoded['assets'] as $index => $entry) { + if (! is_array($entry)) { + continue; + } + + $type = $entry['type'] ?? null; + + if (! in_array($type, ['style', 'script'], true)) { + Log::warning('사용자 추가 에셋 항목의 type 이 올바르지 않습니다.', [ + 'declaration' => $declaration, + 'index' => $index, + 'type' => is_scalar($type) ? $type : gettype($type), + ]); + + continue; + } + + // 외부 URL — 운영자가 자기 사이트에 직접 등록한 것만 허용한다 (D14). + // 확장 저작자의 기본값이 아니라 운영자 본인의 선택이라서 성립하는 예외이며, + // 왜 외부로 나가는지가 파일에 남도록 사유를 요구한다. + if (isset($entry['url'])) { + $url = $entry['url']; + $reason = $entry['reason'] ?? null; + + if (! is_string($url) || ! preg_match('#^https://#i', $url)) { + Log::warning('사용자 추가 에셋의 외부 URL 은 https 여야 합니다.', [ + 'declaration' => $declaration, + 'index' => $index, + ]); + + continue; + } + + if (! is_string($reason) || trim($reason) === '') { + Log::warning('사용자 추가 에셋의 외부 URL 에는 reason(사유)이 필요합니다.', [ + 'declaration' => $declaration, + 'index' => $index, + 'url' => $url, + ]); + + continue; + } + + $assets[] = [ + 'id' => self::assetId($extensionType, $identifier, $url), + 'type' => $type, + 'url' => $url, + 'version' => null, + 'source' => 'url', + ]; + + continue; + } + + $file = $entry['file'] ?? null; + + if (! is_string($file) || $file === '') { + Log::warning('사용자 추가 에셋 항목에 file 또는 url 이 없습니다.', [ + 'declaration' => $declaration, + 'index' => $index, + ]); + + continue; + } + + $descriptor = self::fileDescriptor($extensionType, $identifier, $directory, $file, $type); + + if ($descriptor !== null) { + $assets[] = $descriptor; + } + } + + return $assets; + } + + /** + * 규약 스캔으로 자산 목록을 만듭니다. + * + * `custom/*.css` · `custom/*.js` 를 파일명 오름차순으로 싣는다. 하위 디렉토리는 + * 훑지 않는다 — 폰트·이미지는 CSS 가 상대 경로로 참조하는 대상이지 그 자체로 + * 로드할 것이 아니다. + * + * @param string $extensionType 확장 타입 + * @param string $identifier 확장 식별자 + * @param string $directory `custom/` 절대 경로 + * @return array> 서술자 목록 + */ + private static function fromConvention(string $extensionType, string $identifier, string $directory): array + { + $entries = scandir($directory); + + if ($entries === false) { + return []; + } + + sort($entries, SORT_STRING); + + $styles = []; + $scripts = []; + + foreach ($entries as $entry) { + if ($entry === '.' || $entry === '..' || ! is_file($directory.DIRECTORY_SEPARATOR.$entry)) { + continue; + } + + $extension = strtolower(pathinfo($entry, PATHINFO_EXTENSION)); + $type = self::CONVENTION_TYPES[$extension] ?? null; + + if ($type === null) { + continue; + } + + $descriptor = self::fileDescriptor($extensionType, $identifier, $directory, $entry, $type); + + if ($descriptor === null) { + continue; + } + + // CSS 를 JS 보다 먼저 — 스타일이 먼저 붙어야 스크립트가 만드는 DOM 도 즉시 적용된다 + if ($type === 'style') { + $styles[] = $descriptor; + } else { + $scripts[] = $descriptor; + } + } + + return array_merge($styles, $scripts); + } + + /** + * 파일 기반 서술자를 만듭니다. + * + * `version` 은 파일 수정 시각이다. 확장 캐시 버전(`ext.cache_version`)은 운영자가 + * 파일을 고쳤다고 오르지 않으므로, 그 값으로 URL 을 만들면 수정이 브라우저에 + * 반영되지 않는다. + * + * @param string $extensionType 확장 타입 + * @param string $identifier 확장 식별자 + * @param string $directory `custom/` 절대 경로 + * @param string $file `custom/` 기준 상대 경로 + * @param string $type `style` | `script` + * @return array|null 서술자, 유효하지 않으면 null + */ + private static function fileDescriptor( + string $extensionType, + string $identifier, + string $directory, + string $file, + string $type + ): ?array { + $relative = ltrim(str_replace('\\', '/', $file), '/'); + + if ($relative === '' || str_contains($relative, '..') || str_contains($relative, "\0")) { + Log::warning('사용자 추가 에셋 경로가 안전하지 않습니다.', [ + 'identifier' => $identifier, + 'file' => $file, + ]); + + return null; + } + + if (! self::isAllowedExtension($relative)) { + Log::warning('사용자 추가 에셋의 확장자가 허용 목록에 없습니다.', [ + 'identifier' => $identifier, + 'file' => $relative, + ]); + + return null; + } + + $absolute = $directory.DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $relative); + + if (! is_file($absolute)) { + Log::warning('선언된 사용자 추가 에셋 파일이 없습니다.', [ + 'identifier' => $identifier, + 'file' => $relative, + ]); + + return null; + } + + $servePath = self::DIRECTORY.'/'.$relative; + $version = @filemtime($absolute) ?: null; + + return [ + 'id' => self::assetId($extensionType, $identifier, $relative), + 'type' => $type, + 'url' => self::assetUrl($extensionType, $identifier, $servePath, $version), + 'version' => $version, + 'source' => 'file', + ]; + } + + /** + * 확장 타입에 맞는 자산 URL 을 만듭니다. + * + * 템플릿은 서버가 `dist/` 를 자동 부가하지만 `custom/` 은 그 밖에 있다 — + * `TemplateService::getAssetFilePath` 가 `custom/` 접두를 따로 해석한다. + * + * @param string $extensionType 확장 타입 + * @param string $identifier 확장 식별자 + * @param string $servePath 서빙 경로 (`custom/...`) + * @param int|null $version 캐시 무효화 버전 + * @return string 자산 URL + */ + private static function assetUrl(string $extensionType, string $identifier, string $servePath, ?int $version): string + { + // 세 타입 모두 확장 자산과 **같은 메커니즘**으로 정적 게시되므로 URL 축도 같다. + // 파일 서명(mtime)을 넘기지 않는 이유: 정적 경로는 언제나 **현재 게시 버전**이라, + // 다른 값을 넘기면 `AssetUrl` 의 버전 일치 게이트에 걸려 정적 분기가 영영 선택되지 + // 않는다. 운영자가 파일을 고치면 `CollectsCustomAssets` 가 그것을 감지해 확장 캐시 + // 버전을 올리고, 그 단일 지점이 재게시까지 예약한다. + // + // 게시본이 아직 없으면(게시 직전 창·비프로덕션·kill-switch) `AssetUrl` 이 API 경로로 + // 떨어지고, 그 응답은 디스크의 최신 내용을 그대로 준다. 그 경로의 `?v` 도 캐시 + // 버전이라 파일 수정 → 감지 → bump 로 함께 갱신된다. + // + // `$version`(파일 mtime)은 URL 에 쓰지 않는다. 서술자의 `version` 필드로만 남아 + // 변경 감지 서명의 재료가 된다 — URL 축과 감지 축은 목적이 다르다. + $current = ExtensionStaticCacheService::getExtensionCacheVersion(); + + return match ($extensionType) { + 'templates' => AssetUrl::templateAsset($identifier, $servePath, $current), + 'modules' => AssetUrl::moduleAsset($identifier, $servePath, $current, allowStatic: true), + default => AssetUrl::pluginAsset($identifier, $servePath, $current, allowStatic: true), + }; + } + + /** + * 서술자 식별자를 만듭니다 (중복 로드 방지 · 실패 표면화 키). + * + * @param string $extensionType 확장 타입 + * @param string $identifier 확장 식별자 + * @param string $suffix 파일 경로 또는 URL + * @return string 식별자 + */ + private static function assetId(string $extensionType, string $identifier, string $suffix): string + { + return 'custom:'.$extensionType.':'.$identifier.':'.$suffix; + } + + /** + * 확장자가 허용 목록에 있는지 판정합니다. + * + * 자산 서빙이 다시 검증하지만, 목록에 없는 파일을 URL 로 만들어 페이지에 실어 + * 보낼 이유가 없다. + * + * @param string $relative 상대 경로 + * @return bool 허용되면 true + */ + private static function isAllowedExtension(string $relative): bool + { + $extension = strtolower(pathinfo($relative, PATHINFO_EXTENSION)); + + return in_array($extension, ['css', 'js', 'mjs'], true); + } + + /** + * 확장 식별자가 경로로 안전한지 판정합니다. + * + * @param string $identifier 확장 식별자 + * @return bool 안전하면 true + */ + private static function isSafeIdentifier(string $identifier): bool + { + return preg_match('/^[A-Za-z0-9._-]+$/', $identifier) === 1 && ! str_contains($identifier, '..'); + } +} diff --git a/app/Support/TemplateExternals.php b/app/Support/TemplateExternals.php index cd063d06..e64aa402 100644 --- a/app/Support/TemplateExternals.php +++ b/app/Support/TemplateExternals.php @@ -2,10 +2,28 @@ namespace App\Support; +use App\Rules\SafeLayoutExpressions; use Illuminate\Support\Facades\Log; class TemplateExternals { + /** + * same-origin 자산 항목에서 무시하는 키. + * + * `preconnect`·`dns-prefetch` 는 다른 origin 과의 커넥션을 미리 여는 힌트이고, + * `crossorigin` 은 교차 출처 요청의 자격 증명 모드를 정하는 속성이다. 자기 서버의 + * 자산에는 둘 다 의미가 없다 — 남겨두면 브라우저가 자기 origin 에 preconnect 를 + * 걸고, 폰트 CSS 에 불필요한 CORS 모드가 붙는다. + */ + private const EXTERNAL_ONLY_KEYS = ['preconnect', 'crossorigin']; + + /** + * 자체 제공(same-origin)이 불가능한 타입. + * + * 리소스 힌트는 정의상 다른 origin 을 향한다. + */ + private const EXTERNAL_ONLY_TYPES = ['preconnect', 'dns-prefetch']; + private const TYPES = [ 'style', 'webfont', @@ -35,10 +53,19 @@ class TemplateExternals ]; /** - * @param array $externals + * externals 선언을 정규화합니다. + * + * 항목은 두 형태 중 하나로 자산을 가리킨다: + * - `asset`: 템플릿이 **자체 제공**하는 파일의 `dist/` 이하 경로. `AssetUrl::templateAsset()` + * 이 자산 URL 이중 모드·정적 게시를 반영한 URL 을 만든다. 자체 제공이 원칙이므로 이쪽이 기본. + * - `url`: 절대 URL. `https://` 외부 URL 또는 `/` 로 시작하는 same-origin 경로. + * + * @param array $externals template.json 의 externals 배열 + * @param string|null $templateIdentifier `asset` 해석에 필요한 템플릿 식별자 + * @param int|string|null $version 캐시 무효화 버전 * @return array> */ - public static function normalize(array $externals): array + public static function normalize(array $externals, ?string $templateIdentifier = null, int|string|null $version = null): array { $normalized = []; $seen = []; @@ -48,7 +75,7 @@ class TemplateExternals continue; } - $item = self::normalizeItem($external); + $item = self::normalizeItem($external, $templateIdentifier, $version); if ($item === null) { continue; @@ -133,6 +160,7 @@ class TemplateExternals if (in_array($external['type'], ['style', 'webfont'], true)) { self::appendIfString($attributes, 'media', $external['media'] ?? null); + $attributes['onerror'] = self::failureHandlerScript($external); } if ($external['type'] === 'preload') { @@ -167,9 +195,59 @@ class TemplateExternals $attributes['defer'] = true; } + $attributes['onerror'] = self::failureHandlerScript($external); + return $attributes; } + /** + * 자산 로드 실패를 알리는 인라인 핸들러를 만듭니다. + * + * 이 태그들은 서버가 HTML 에 직접 심으므로, 브라우저가 자산에 도달하지 못해도 + * 자바스크립트 쪽에는 아무 신호가 오지 않는다. 실패는 "아이콘이 안 보인다" · + * "글꼴이 다르다" 로만 나타나고 자체 서버 로그에도 흔적이 남지 않아 운영자가 + * 원인을 특정할 수 없다. `onerror` 가 그 유일한 신호다. + * + * 부팅 초기에는 엔진이 아직 없을 수 있으므로 핸들러는 `template-externals-head` + * 가 먼저 심어 두는 부트스트랩(대기열)을 부른다. + * + * @param array $external 정규화된 externals 항목 + * @return string onerror 속성값 + */ + private static function failureHandlerScript(array $external): string + { + $label = self::failureLabel($external); + + return "window.__g7ExternalAssetFailed&&window.__g7ExternalAssetFailed(this,'".$label."')"; + } + + /** + * 안내 배너에 표시할 짧은 항목명을 만듭니다. + * + * 선언된 `id` 가 있으면 그것을, 없으면 URL 의 파일명을 쓴다 — 운영자가 어느 자산이 + * 실패했는지 알아볼 수 있어야 한다. + * + * @param array $external 정규화된 externals 항목 + * @return string 항목명 (작은따옴표 안전) + */ + private static function failureLabel(array $external): string + { + $id = $external['id'] ?? null; + + if (is_string($id) && $id !== '') { + return $id; + } + + $path = parse_url((string) ($external['url'] ?? ''), PHP_URL_PATH) ?: ''; + $basename = basename($path); + + if ($basename === '') { + return 'asset'; + } + + return preg_replace('/[^A-Za-z0-9._-]/', '', $basename) ?: 'asset'; + } + /** * @param array $attributes */ @@ -192,15 +270,41 @@ class TemplateExternals return $html; } - private static function normalizeItem(array $external): ?array + /** + * externals 항목 1건을 정규화합니다. + * + * @param array $external 원본 항목 + * @param string|null $templateIdentifier `asset` 해석용 템플릿 식별자 + * @param int|string|null $version 캐시 무효화 버전 + * @return array|null 정규화 결과, 유효하지 않으면 null + */ + private static function normalizeItem(array $external, ?string $templateIdentifier = null, int|string|null $version = null): ?array { $type = $external['type'] ?? null; - $url = $external['url'] ?? null; - if (! is_string($type) || ! in_array($type, self::TYPES, true) || ! self::isHttpsUrl($url)) { + if (! is_string($type) || ! in_array($type, self::TYPES, true)) { + Log::warning('Template external skipped because type is invalid.', [ + 'type' => is_scalar($type) ? $type : gettype($type), + ]); + return null; } + $resolved = self::resolveUrl($external, $type, $templateIdentifier, $version); + + if ($resolved === null) { + return null; + } + + [$url, $isSameOrigin] = $resolved; + + // same-origin 항목에서는 외부 전용 키를 떨어뜨린다 (선언에 남아 있어도 무시) + if ($isSameOrigin) { + foreach (self::EXTERNAL_ONLY_KEYS as $key) { + unset($external[$key]); + } + } + if ($type === 'preload' && empty($external['as'])) { Log::warning('Template external preload skipped because as is missing.', ['url' => $url]); @@ -264,6 +368,128 @@ class TemplateExternals return $item; } + /** + * 항목이 가리키는 자산 URL 을 해석합니다. + * + * 종전에는 `https://` 로 시작하지 않는 항목을 **로그 없이 버렸다**. 그래서 자체 제공 + * 경로를 적으면 자산이 조용히 사라지고, 선언은 파일에 남아 있어 원인을 찾을 수 없었다. + * + * @param array $external 원본 항목 + * @param string $type 항목 타입 + * @param string|null $templateIdentifier `asset` 해석용 템플릿 식별자 + * @param int|string|null $version 캐시 무효화 버전 + * @return array{0: string, 1: bool}|null [URL, same-origin 여부], 유효하지 않으면 null + */ + private static function resolveUrl(array $external, string $type, ?string $templateIdentifier, int|string|null $version): ?array + { + $asset = $external['asset'] ?? null; + + if (is_string($asset) && $asset !== '') { + if (in_array($type, self::EXTERNAL_ONLY_TYPES, true)) { + Log::warning('Template external skipped because asset is not applicable to this type.', [ + 'type' => $type, + 'asset' => $asset, + ]); + + return null; + } + + if ($templateIdentifier === null || $templateIdentifier === '') { + Log::warning('Template external skipped because template identifier is unknown.', [ + 'asset' => $asset, + ]); + + return null; + } + + if (! self::isSafeAssetPath($asset)) { + Log::warning('Template external skipped because asset path is unsafe.', [ + 'asset' => $asset, + ]); + + return null; + } + + if (isset($external['url'])) { + Log::warning('Template external url is ignored because asset takes precedence.', [ + 'asset' => $asset, + 'url' => is_scalar($external['url']) ? $external['url'] : gettype($external['url']), + ]); + } + + return [AssetUrl::templateAsset($templateIdentifier, $asset, $version), true]; + } + + $url = $external['url'] ?? null; + + if (self::isHttpsUrl($url)) { + return [$url, false]; + } + + if (is_string($url) && self::isSameOriginPath($url)) { + if (in_array($type, self::EXTERNAL_ONLY_TYPES, true)) { + Log::warning('Template external skipped because same-origin url is not applicable to this type.', [ + 'type' => $type, + 'url' => $url, + ]); + + return null; + } + + return [$url, true]; + } + + Log::warning('Template external skipped because url is neither https nor a same-origin path.', [ + 'type' => $type, + 'url' => is_scalar($url) ? $url : gettype($url), + ]); + + return null; + } + + /** + * `asset` 경로가 안전한지 판정합니다. + * + * 서버측 자산 서빙이 다시 검증하지만, URL 을 만들기 전에 걸러야 잘못된 선언이 + * 페이지에 실려 나가지 않는다. + * + * @param string $path `dist/` 이하 상대 경로 + * @return bool 안전하면 true + */ + private static function isSafeAssetPath(string $path): bool + { + if (str_starts_with($path, '/') || str_contains($path, '..') || str_contains($path, "\0")) { + return false; + } + + return preg_match('#^[A-Za-z0-9._\-/]+$#', $path) === 1; + } + + /** + * same-origin path-only URL 인지 판정합니다. + * + * 접두 문자열만 보면 `/\evil.com/x.css` 같은 값이 통과한다 — 브라우저는 그것을 + * 외부 origin 으로 해석한다. 저장측·런타임·정적검사가 공유하는 정규화(SSoT: + * `TrustedScriptHosts::normalizeForOriginCheck`)를 거친 뒤 판정한다. + * + * @param string $url 검사 대상 URL + * @return bool same-origin 경로면 true + */ + private static function isSameOriginPath(string $url): bool + { + $normalized = SafeLayoutExpressions::normalizeForOriginCheck($url); + + if (str_starts_with($normalized, '//')) { + return false; + } + + if (preg_match('/^[a-z][a-z0-9+.\-]*:/i', $normalized) === 1) { + return false; + } + + return str_starts_with($normalized, '/'); + } + /** * @param array> $hints * @param array $seen diff --git a/config/core.php b/config/core.php index cd37d68e..53288a11 100644 --- a/config/core.php +++ b/config/core.php @@ -268,6 +268,22 @@ return [ ['identifier' => 'core.templates.layouts.edit', 'type' => 'admin', 'name' => ['ko' => '레이아웃 편집', 'en' => 'Edit Layouts'], 'description' => ['ko' => '템플릿 레이아웃을 편집할 수 있습니다.', 'en' => 'Can edit template layouts.'], 'order' => 5], ], ], + [ + 'identifier' => 'core.extensions', + 'name' => ['ko' => '확장 공통', 'en' => 'Extension Common'], + 'description' => ['ko' => '모듈·플러그인·템플릿에 공통으로 적용되는 권한', 'en' => 'Permissions that apply across modules, plugins and templates'], + 'category' => 'extensions', + 'order' => 5.5, + 'type' => 'admin', + 'permissions' => [ + // 확장 타입을 가리지 않는 단일 권한이다. 타입별로 쪼개면 운영자가 셋을 모두 + // 부여해야 하고, "모듈 CSS 는 되는데 템플릿 CSS 는 안 되는" 상태가 실질적 + // 의미 없이 생긴다. 레이아웃 편집 권한과는 분리한다 — 여기서 올린 스크립트는 + // 그 레이아웃 한 장이 아니라 사이트 전 화면에서 실행되므로, 레이아웃을 고칠 + // 수 있다는 것이 곧 그 권한이 될 수 없다. + ['identifier' => 'core.extensions.custom_assets.manage', 'type' => 'admin', 'name' => ['ko' => '커스텀 자산 관리', 'en' => 'Manage Custom Assets'], 'description' => ['ko' => '모듈·플러그인·템플릿에 운영자 CSS·JS·폰트·이미지를 추가하거나 수정할 수 있습니다. 추가한 스크립트는 사이트 전체에서 실행되므로 레이아웃 편집과 별도로 부여합니다.', 'en' => 'Can add or edit operator CSS/JS/fonts/images on modules, plugins and templates. Added scripts run across the whole site, so this is granted separately from layout editing.'], 'order' => 1], + ], + ], [ 'identifier' => 'core.permissions', 'name' => ['ko' => '권한 관리', 'en' => 'Permission Management'], diff --git a/docs/ai-tools/skills/create-template.md b/docs/ai-tools/skills/create-template.md index 8d198cfd..fa65cc77 100644 --- a/docs/ai-tools/skills/create-template.md +++ b/docs/ai-tools/skills/create-template.md @@ -54,6 +54,8 @@ | `vitest.config.ts` | Vitest 테스트 설정 | | `tsconfig.json` | TypeScript 설정 | +구동 에셋은 템플릿이 자체 제공한다. `template.json` 의 `externals` 는 제3자 CDN 주소(`url`)가 아니라 동봉 파일의 상대 경로(`asset`)로 선언하고, 라이브러리는 `dist/vendor/{lib}/{version}/` 에 원본 라이선스 파일과 함께 담는다. CDN 에 도달하지 못하는 환경에서는 아이콘·글꼴이 오류 표시 없이 사라져 화면이 조작 불능이 되기 때문이다. 자체 호스팅이 성립하지 않는 서비스 SDK 만 예외이며, 그때는 manifest 에 신뢰 호스트와 그 사유를 함께 선언한다. 상세: [template-basics.md](../../extension/template-basics.md) "외부 리소스 (externals)". + ## 생성되는 디렉토리 - `src/components/basic/` — 기본 컴포넌트 (Div, Button, Input 등) diff --git a/docs/backend/activity-log-hooks.md b/docs/backend/activity-log-hooks.md index fff7968e..18a6be98 100644 --- a/docs/backend/activity-log-hooks.md +++ b/docs/backend/activity-log-hooks.md @@ -43,13 +43,12 @@ Service → doAction('hook.name') → ActivityLogListener → Log::channel('acti ## 2. 코어 훅 (CoreActivityLogListener) **파일**: `app/Listeners/CoreActivityLogListener.php` -**총 66훅** (스냅샷 캡처용 before 훅 포함) +**총 66훅** -### User (9훅) +### User (8훅) | 훅 이름 | Listener 메서드 | Action (DB) | LogType | Loggable | |---------|----------------|-------------|---------|----------| -| `core.user.before_update` | `captureUserSnapshot` | _(스냅샷 캡처)_ | - | - | | `core.user.after_create` | `handleUserAfterCreate` | `user.create` | Admin | User | | `core.user.after_update` | `handleUserAfterUpdate` | `user.update` | Admin | User | | `core.user.after_delete` | `handleUserAfterDelete` | `user.delete` | Admin | User | @@ -59,7 +58,7 @@ Service → doAction('hook.name') → ActivityLogListener → Log::channel('acti | `core.user.after_search` | `handleUserAfterSearch` | `user.search` | Admin | - | | `sirsoft-core.user.after_bulk_update` | `handleUserAfterBulkUpdate` | `user.bulk_update` | Admin | - | -### Auth (6훅) +### Auth (9훅) | 훅 이름 | Listener 메서드 | Action (DB) | LogType | Loggable | |---------|----------------|-------------|---------|----------| @@ -69,23 +68,34 @@ Service → doAction('hook.name') → ActivityLogListener → Log::channel('acti | `core.auth.forgot_password` | `handleAuthForgotPassword` | `auth.forgot_password` | User | - | | `core.auth.reset_password` | `handleAuthResetPassword` | `auth.reset_password` | User | - | | `core.auth.record_consents` | `handleAuthRecordConsents` | `auth.record_consents` | User | User | +| `core.auth.login_failed` | `handleAuthLoginFailed` | `auth.login_failed` | User | - | +| `core.auth.account_locked` | `handleAuthAccountLocked` | `auth.account_locked` | User | User | +| `core.auth.account_unlocked` | `handleAuthAccountUnlocked` | `auth.account_unlocked` | User | User | -### Role (6훅, 스냅샷 포함) +### Identity (3훅) + +본인인증(IDV) 훅은 DTO(`VerificationChallenge`/`VerificationResult`)를 인자로 받으므로 `sync => true` 로 등록된다 — 큐 직렬화 대상에 POPO 가 포함되지 않아 큐로 넘기면 `null` 이 전달된다. + +| 훅 이름 | Listener 메서드 | Action (DB) | LogType | Loggable | +|---------|----------------|-------------|---------|----------| +| `core.identity.after_request` | `handleIdentityRequested` | `identity.request` | User | - | +| `core.identity.after_verify` | `handleIdentityVerified` | `identity.verify` / `identity.verify_failed` | User | - | +| `core.identity.challenge_expired` | `handleIdentityExpired` | `identity.expired` | User | - | + +### Role (5훅) | 훅 이름 | Listener 메서드 | Action (DB) | LogType | Loggable | |---------|----------------|-------------|---------|----------| -| `core.role.before_update` | `captureRoleSnapshot` | _(스냅샷 캡처)_ | - | - | | `core.role.after_create` | `handleRoleAfterCreate` | `role.create` | Admin | Role | | `core.role.after_update` | `handleRoleAfterUpdate` | `role.update` | Admin | Role | | `core.role.after_delete` | `handleRoleAfterDelete` | `role.delete` | Admin | Role | | `core.role.after_sync_permissions` | `handleRoleAfterSyncPermissions` | `role.sync_permissions` | Admin | Role | | `core.role.after_toggle_status` | `handleRoleAfterToggleStatus` | `role.toggle_status` | Admin | Role | -### Menu (7훅, 스냅샷 포함) +### Menu (6훅) | 훅 이름 | Listener 메서드 | Action (DB) | LogType | Loggable | |---------|----------------|-------------|---------|----------| -| `core.menu.before_update` | `captureMenuSnapshot` | _(스냅샷 캡처)_ | - | - | | `core.menu.after_create` | `handleMenuAfterCreate` | `menu.create` | Admin | Menu | | `core.menu.after_update` | `handleMenuAfterUpdate` | `menu.update` | Admin | Menu | | `core.menu.after_delete` | `handleMenuAfterDelete` | `menu.delete` | Admin | Menu | @@ -100,11 +110,10 @@ Service → doAction('hook.name') → ActivityLogListener → Log::channel('acti | `core.settings.after_save` | `handleSettingsAfterSave` | `settings.save` | Admin | - | | `core.settings.after_set` | `handleSettingsAfterSet` | `settings.set` | Admin | - | -### Schedule (7훅, 스냅샷 포함) +### Schedule (6훅) | 훅 이름 | Listener 메서드 | Action (DB) | LogType | Loggable | |---------|----------------|-------------|---------|----------| -| `core.schedule.before_update` | `captureScheduleSnapshot` | _(스냅샷 캡처)_ | - | - | | `core.schedule.after_create` | `handleScheduleAfterCreate` | `schedule.create` | Admin | Schedule | | `core.schedule.after_update` | `handleScheduleAfterUpdate` | `schedule.update` | Admin | Schedule | | `core.schedule.after_delete` | `handleScheduleAfterDelete` | `schedule.delete` | Admin | Schedule | @@ -152,6 +161,14 @@ Service → doAction('hook.name') → ActivityLogListener → Log::channel('acti | `core.templates.after_version_update` | `handleTemplateAfterVersionUpdate` | `template.version_update` | Admin | - | | `core.templates.after_refresh_layouts` | `handleTemplateAfterRefreshLayouts` | `template.refresh_layouts` | Admin | - | +### Extension 공통 (1훅) + +템플릿·모듈·플러그인 세 타입이 같은 훅을 공유한다 (권한도 `core.extensions.custom_assets.manage` 하나다). + +| 훅 이름 | Listener 메서드 | Action (DB) | LogType | Loggable | +|---------|----------------|-------------|---------|----------| +| `core.custom_assets.after_change` | `handleCustomAssetAfterChange` | `custom_asset.{save\|upload\|delete}` | Admin | 운영자 CSS·JS 는 사이트 전 화면에서 실행되므로 변경 이력이 남아야 한다 | + ### Layout (2훅) | 훅 이름 | Listener 메서드 | Action (DB) | LogType | Loggable | diff --git a/docs/backend/api/README.md b/docs/backend/api/README.md index d41c588b..8014597c 100644 --- a/docs/backend/api/README.md +++ b/docs/backend/api/README.md @@ -200,7 +200,7 @@ location ~* \.(js|css|json)$ { expires max; access_log off; } ## 코어 API 레퍼런스 -- **문서 수**: 36 · **엔드포인트 수**: 319 +- **문서 수**: 36 · **엔드포인트 수**: 324 | 문서 | 도메인 | 엔드포인트 | | --- | --- | --- | @@ -213,7 +213,7 @@ location ~* \.(js|css|json)$ { expires max; access_log off; } | [changelog.md](changelog.md) | `changelog` | 1 | | [core-update.md](core-update.md) | `core-update` | 2 | | [dashboard.md](dashboard.md) | `dashboard` | 5 | -| [extensions.md](extensions.md) | `extensions` | 3 | +| [extensions.md](extensions.md) | `extensions` | 8 | | [identity.md](identity.md) | `identity` | 27 | | [language-packs.md](language-packs.md) | `language-packs` | 15 | | [layouts.md](layouts.md) | `layouts` | 2 | diff --git a/docs/backend/api/extensions.md b/docs/backend/api/extensions.md index 7e0a2c8a..5a8cbf99 100644 --- a/docs/backend/api/extensions.md +++ b/docs/backend/api/extensions.md @@ -198,4 +198,334 @@ HTTP/1.1 200 **설명** 코어와 재호환된 확장을 원클릭으로 복구(재활성화)합니다. 경로의 `{type}`/`{identifier}`로 대상을 지정하며, 대상이 `IncompatibleCore` 사유로 자동 비활성화된 상태인지 검증한 뒤 코어 버전 재검증을 거쳐 활성화합니다. 잘못된 타입은 422, 미존재 확장은 404, hidden 확장이나 자동 비활성화가 아닌 경우는 error_code와 함께 422를 반환하고, 재검증 실패 시 글로벌 핸들러가 core_version_mismatch로 변환합니다. `core.plugins.activate` 권한이 필요합니다. +### GET /api/admin/extensions/{type}/{identifier}/custom-assets + +- **라우트명**: `api.admin.extensions.custom-assets.index` +- **컨트롤러**: `App\Http\Controllers\Api\Admin\AdminExtensionCustomAssetController@index` +- **인증/권한**: `auth:sanctum` + `permission:core.extensions.custom_assets.manage` + +**요청 파라미터** + +| 이름 | 위치 | 타입 | 필수 | 허용값 | 용도 | +| --- | --- | --- | --- | --- | --- | +| type | path | string | 예 | `module` \| `plugin` \| `template` | 대상 확장 타입 | +| identifier | path | string | 예 | — | 대상 확장 식별자 | + +**요청 예시** + +```http +GET /api/admin/extensions/template/sirsoft-admin_basic/custom-assets HTTP/1.1 +Host: api.example.com +Accept: application/json +Authorization: Bearer {YOUR_TOKEN} +``` + +**응답 필드** (`data` 내부) + +| 필드 | 타입 | 예시값 | 용도/설명 | +| --- | --- | --- | --- | +| files | array | `[{"path":"10-overrides.css", …}]` | `custom/` 이하 파일 목록 (상대 경로 오름차순) | +| files[].path | string | `10-overrides.css` | `custom/` 기준 상대 경로 | +| files[].name | string | `10-overrides.css` | 파일명 | +| files[].extension | string | `css` | 소문자 확장자 | +| files[].size | integer | `42` | 바이트 크기 | +| files[].modified_at | string | `2026-08-26T10:00:00+09:00` | 최종 수정 시각 (ISO 8601) | +| files[].editable | boolean | `true` | 본문을 직접 편집할 수 있는지 (텍스트 형식만 true) | +| files[].loaded | boolean | `true` | 실제로 페이지에 실리는지 (규약 스캔·선언 파일 판정 결과) | +| editable_extensions | array | `["css","js","mjs","json"]` | 본문 편집이 가능한 확장자 | +| uploadable_extensions | array | `["js","css","png","woff2", …]` | 업로드 허용 확장자 (자산 서빙 화이트리스트와 동일) | +| max_text_bytes | integer | `524288` | 본문 편집 최대 크기 | +| max_upload_bytes | integer | `5242880` | 업로드 최대 크기 | + +**응답 예시** + +```json +{ + "success": true, + "message": "목록을 불러왔습니다.", + "data": { + "files": [ + { + "path": "10-overrides.css", + "name": "10-overrides.css", + "extension": "css", + "size": 42, + "modified_at": "2026-08-26T10:00:00+09:00", + "editable": true, + "loaded": true + } + ], + "editable_extensions": ["css", "js", "mjs", "json"], + "uploadable_extensions": ["js", "mjs", "css", "json", "png", "jpg", "jpeg", "svg", "webp", "gif", "woff", "woff2", "ttf", "otf", "eot"], + "max_text_bytes": 524288, + "max_upload_bytes": 5242880 + } +} +``` + +**에러 응답** + +| 상태코드 | 의미 | 발생 조건 | +| --- | --- | --- | +| 401 | Unauthenticated | 유효한 Bearer 토큰이 없거나 만료된 경우 | +| 403 | Forbidden | `core.extensions.custom_assets.manage` 권한이 없는 경우 (레이아웃 편집 권한만으로는 통과하지 못한다) | +| 404 | Not Found | `type` 이 `module`·`plugin`·`template` 이 아닌 경우 (라우트 정규식이 거부) | +| 500 | Server Error | 디렉토리 조회 실패 | + + + +**설명** 운영자가 확장의 `custom/` 디렉토리에 넣은 파일 목록과 편집기 메타(허용 확장자·크기 상한)를 반환합니다. 규약 스캔이 자동으로 싣지 않는 폰트·이미지도 목록에 포함됩니다 — 목록에서 빠지면 지울 방법이 없어지기 때문입니다. 권한은 레이아웃 편집(`core.templates.layouts.edit`)과 분리되어 있습니다: 여기서 올린 스크립트는 레이아웃 한 장이 아니라 사이트 전 화면에서 실행됩니다. + + +### GET /api/admin/extensions/{type}/{identifier}/custom-assets/content + +- **라우트명**: `api.admin.extensions.custom-assets.show` +- **컨트롤러**: `App\Http\Controllers\Api\Admin\AdminExtensionCustomAssetController@show` +- **인증/권한**: `auth:sanctum` + `permission:core.extensions.custom_assets.manage` + +**요청 파라미터** + +| 이름 | 위치 | 타입 | 필수 | 허용값 | 용도 | +| --- | --- | --- | --- | --- | --- | +| type | path | string | 예 | `module` \| `plugin` \| `template` | 대상 확장 타입 | +| identifier | path | string | 예 | — | 대상 확장 식별자 | +| path | query | string | 예 | 최대 255자 | `custom/` 기준 상대 경로 (상위 이동·절대 경로 불가) | + +**요청 예시** + +```http +GET /api/admin/extensions/template/sirsoft-admin_basic/custom-assets/content?path=10-overrides.css HTTP/1.1 +Host: api.example.com +Accept: application/json +Authorization: Bearer {YOUR_TOKEN} +``` + +**응답 필드** (`data` 내부) + +| 필드 | 타입 | 예시값 | 용도/설명 | +| --- | --- | --- | --- | +| path | string | `10-overrides.css` | 요청한 상대 경로 | +| content | string | `body { color: red; }` | 파일 본문 | +| size | integer | `20` | 바이트 크기 | + +**응답 예시** + +```json +{ + "success": true, + "message": "목록을 불러왔습니다.", + "data": { + "path": "10-overrides.css", + "content": "body { color: red; }", + "size": 20 + } +} +``` + +**에러 응답** + +| 상태코드 | 의미 | 발생 조건 | +| --- | --- | --- | +| 401 | Unauthenticated | 유효한 Bearer 토큰이 없거나 만료된 경우 | +| 403 | Forbidden | `core.extensions.custom_assets.manage` 권한이 없는 경우 | +| 422 | Unprocessable Entity | 경로 검증 실패 / 파일 부재 / 편집 불가 형식 / 크기 초과 | +| 500 | Server Error | 파일 읽기 실패 | + + + +**설명** 텍스트 형식(`css`·`js`·`mjs`·`json`) 파일의 본문을 반환합니다. 그 밖의 형식은 422 로 거부합니다 — 바이너리를 텍스트 편집기에 열면 저장 시 내용이 손상되기 때문입니다. + + +### PUT /api/admin/extensions/{type}/{identifier}/custom-assets/content + +- **라우트명**: `api.admin.extensions.custom-assets.store` +- **컨트롤러**: `App\Http\Controllers\Api\Admin\AdminExtensionCustomAssetController@store` +- **인증/권한**: `auth:sanctum` + `permission:core.extensions.custom_assets.manage` + +**요청 파라미터** + +| 이름 | 위치 | 타입 | 필수 | 허용값 | 용도 | +| --- | --- | --- | --- | --- | --- | +| type | path | string | 예 | `module` \| `plugin` \| `template` | 대상 확장 타입 | +| identifier | path | string | 예 | — | 대상 확장 식별자 | +| path | body | string | 예 | 최대 255자, 확장자 `css`\|`js`\|`mjs`\|`json` | 저장할 상대 경로 (없으면 새로 만든다) | +| content | body | string | 예 (빈 문자열 허용) | 최대 524288바이트 | 파일 본문 | + +**요청 예시** + +```http +PUT /api/admin/extensions/template/sirsoft-admin_basic/custom-assets/content HTTP/1.1 +Host: api.example.com +Accept: application/json +Content-Type: application/json +Authorization: Bearer {YOUR_TOKEN} + +{ + "path": "10-overrides.css", + "content": "body { color: red; }" +} +``` + +**응답 필드** (`data` 내부) + +| 필드 | 타입 | 예시값 | 용도/설명 | +| --- | --- | --- | --- | +| path | string | `10-overrides.css` | 저장한 상대 경로 | +| size | integer | `20` | 저장된 바이트 크기 | +| modified_at | string | `2026-08-26T10:00:00+09:00` | 저장 시각 (ISO 8601) | + +**응답 예시** + +```json +{ + "success": true, + "message": "저장했습니다.", + "data": { + "path": "10-overrides.css", + "size": 20, + "modified_at": "2026-08-26T10:00:00+09:00" + } +} +``` + +**에러 응답** + +| 상태코드 | 의미 | 발생 조건 | +| --- | --- | --- | +| 401 | Unauthenticated | 유효한 Bearer 토큰이 없거나 만료된 경우 | +| 403 | Forbidden | `core.extensions.custom_assets.manage` 권한이 없는 경우 | +| 422 | Unprocessable Entity | 경로 검증 실패(상위 이동·절대 경로·빈 세그먼트) / 편집 불가 형식 / 크기 초과 | +| 500 | Server Error | 파일 쓰기 실패 | + + + +**설명** 텍스트 파일을 저장합니다(없으면 생성). 빈 본문 저장을 허용합니다 — 운영자가 CSS 를 통째로 비우는 것은 정당한 조작이고, 그것을 막으면 파일을 지우는 것 말고는 되돌릴 방법이 없어집니다. 저장 성공 시 확장 캐시 버전이 올라 정적 게시본이 다시 만들어지므로, 편집 결과는 다음 화면부터 반영됩니다. + + +### POST /api/admin/extensions/{type}/{identifier}/custom-assets/upload + +- **라우트명**: `api.admin.extensions.custom-assets.upload` +- **컨트롤러**: `App\Http\Controllers\Api\Admin\AdminExtensionCustomAssetController@upload` +- **인증/권한**: `auth:sanctum` + `permission:core.extensions.custom_assets.manage` + +**요청 파라미터** + +| 이름 | 위치 | 타입 | 필수 | 허용값 | 용도 | +| --- | --- | --- | --- | --- | --- | +| type | path | string | 예 | `module` \| `plugin` \| `template` | 대상 확장 타입 | +| identifier | path | string | 예 | — | 대상 확장 식별자 | +| file | body (multipart) | file | 예 | 최대 5MB, 자산 서빙 허용 확장자 | 올릴 파일 | +| directory | body (multipart) | string | 아니오 | 최대 200자 | `custom/` 기준 하위 디렉토리 (없으면 바로 아래) | + +**요청 예시** + +```http +POST /api/admin/extensions/template/sirsoft-admin_basic/custom-assets/upload HTTP/1.1 +Host: api.example.com +Accept: application/json +Content-Type: multipart/form-data; boundary=----g7 +Authorization: Bearer {YOUR_TOKEN} + +------g7 +Content-Disposition: form-data; name="file"; filename="brand.woff2" +Content-Type: font/woff2 + +(binary) +------g7 +Content-Disposition: form-data; name="directory" + +fonts +------g7-- +``` + +**응답 필드** (`data` 내부) + +| 필드 | 타입 | 예시값 | 용도/설명 | +| --- | --- | --- | --- | +| path | string | `fonts/brand.woff2` | 저장된 상대 경로 | +| size | integer | `18240` | 바이트 크기 | +| modified_at | string | `2026-08-26T10:00:00+09:00` | 저장 시각 (ISO 8601) | + +**응답 예시** + +```json +{ + "success": true, + "message": "파일을 올렸습니다.", + "data": { + "path": "fonts/brand.woff2", + "size": 18240, + "modified_at": "2026-08-26T10:00:00+09:00" + } +} +``` + +**에러 응답** + +| 상태코드 | 의미 | 발생 조건 | +| --- | --- | --- | +| 401 | Unauthenticated | 유효한 Bearer 토큰이 없거나 만료된 경우 | +| 403 | Forbidden | `core.extensions.custom_assets.manage` 권한이 없는 경우 | +| 422 | Unprocessable Entity | 허용되지 않는 확장자 / 크기 초과 / 디렉토리 경로 검증 실패 | +| 500 | Server Error | 파일 저장 실패 | + + + +**설명** 폰트·이미지 등 바이너리를 포함한 파일을 올립니다. 파일명은 안전한 문자(`A-Z a-z 0-9 . _ -`)로 정규화되며, 허용 확장자는 자산 서빙 화이트리스트(`AllowedTemplateFileType`)와 동일합니다 — 여기만 넓히면 올릴 수는 있는데 서빙되지 않는 파일이 생기고, 여기만 좁히면 서빙 규칙이 사문화됩니다. + + +### DELETE /api/admin/extensions/{type}/{identifier}/custom-assets + +- **라우트명**: `api.admin.extensions.custom-assets.destroy` +- **컨트롤러**: `App\Http\Controllers\Api\Admin\AdminExtensionCustomAssetController@destroy` +- **인증/권한**: `auth:sanctum` + `permission:core.extensions.custom_assets.manage` + +**요청 파라미터** + +| 이름 | 위치 | 타입 | 필수 | 허용값 | 용도 | +| --- | --- | --- | --- | --- | --- | +| type | path | string | 예 | `module` \| `plugin` \| `template` | 대상 확장 타입 | +| identifier | path | string | 예 | — | 대상 확장 식별자 | +| path | query | string | 예 | 최대 255자 | 삭제할 상대 경로 | + +**요청 예시** + +```http +DELETE /api/admin/extensions/template/sirsoft-admin_basic/custom-assets?path=10-overrides.css HTTP/1.1 +Host: api.example.com +Accept: application/json +Authorization: Bearer {YOUR_TOKEN} +``` + +**응답 필드** (`data` 내부) + +| 필드 | 타입 | 예시값 | 용도/설명 | +| --- | --- | --- | --- | +| path | string | `10-overrides.css` | 삭제한 상대 경로 | + +**응답 예시** + +```json +{ + "success": true, + "message": "파일을 삭제했습니다.", + "data": { + "path": "10-overrides.css" + } +} +``` + +**에러 응답** + +| 상태코드 | 의미 | 발생 조건 | +| --- | --- | --- | +| 401 | Unauthenticated | 유효한 Bearer 토큰이 없거나 만료된 경우 | +| 403 | Forbidden | `core.extensions.custom_assets.manage` 권한이 없는 경우 | +| 422 | Unprocessable Entity | 경로 검증 실패 / 파일 부재 / 삭제 실패 | +| 500 | Server Error | 파일시스템 오류 | + + + +**설명** 파일을 삭제합니다. 편집 불가 형식(폰트·이미지)도 삭제 대상입니다 — 삭제까지 편집 확장자로 좁히면 올린 폰트를 지울 방법이 없어집니다. 삭제 후 확장 캐시 버전이 올라 정적 게시본에서도 제거됩니다. + diff --git a/docs/backend/api/modules.md b/docs/backend/api/modules.md index e6ddd82c..3f6261dc 100644 --- a/docs/backend/api/modules.md +++ b/docs/backend/api/modules.md @@ -1139,14 +1139,29 @@ Authorization: Bearer {YOUR_TOKEN} **응답 필드** (`data` 내부) -_이 엔드포인트는 `data` 를 반환하지 않습니다 (성공 메시지만). 컨트롤러가 `success('module.uninstall_success')` 를 데이터 인자 없이 호출합니다._ +| 이름 | 타입 | 예시 | 용도 | +| --- | --- | --- | --- | +| preserved_backups | array | `[{"directory":"custom","archive":"…/extension-custom-backups/…"}]` | 삭제 전에 보관한 운영자 소유 디렉토리의 사본 목록. 보관 대상이 없으면 빈 배열 | +| preserved_backups[].directory | string | `custom` | 보관된 디렉토리 이름 | +| preserved_backups[].archive | string | `storage/app/extension-custom-backups/{identifier}-{Ymd_His}/custom` | 사본이 놓인 절대 경로 | + +> 운영자가 `custom/` 에 넣은 파일은 확장 삭제와 함께 사라지지만, 삭제 직전에 사본이 +> 보관됩니다. 이 필드가 그 경로를 알리는 유일한 통로이므로 화면에 노출해야 합니다. **응답 예시** ```json { "success": true, - "message": "모듈이 성공적으로 제거되었습니다." + "message": "모듈이 성공적으로 제거되었습니다.", + "data": { + "preserved_backups": [ + { + "directory": "custom", + "archive": "/var/www/g7/storage/app/extension-custom-backups/sirsoft-board-20260825_231500/custom" + } + ] + } } ``` diff --git a/docs/backend/api/plugins.md b/docs/backend/api/plugins.md index 744f6de9..3b410d8b 100644 --- a/docs/backend/api/plugins.md +++ b/docs/backend/api/plugins.md @@ -1166,7 +1166,14 @@ Authorization: Bearer {YOUR_TOKEN} **응답 필드** (`data` 내부) -_이 엔드포인트는 `data` 를 반환하지 않습니다 (성공 메시지만)._ +| 이름 | 타입 | 예시 | 용도 | +| --- | --- | --- | --- | +| preserved_backups | array | `[{"directory":"custom","archive":"…/extension-custom-backups/…"}]` | 삭제 전에 보관한 운영자 소유 디렉토리의 사본 목록. 보관 대상이 없으면 빈 배열 | +| preserved_backups[].directory | string | `custom` | 보관된 디렉토리 이름 | +| preserved_backups[].archive | string | `storage/app/extension-custom-backups/{identifier}-{Ymd_His}/custom` | 사본이 놓인 절대 경로 | + +> 운영자가 `custom/` 에 넣은 파일은 확장 삭제와 함께 사라지지만, 삭제 직전에 사본이 +> 보관됩니다. 이 필드가 그 경로를 알리는 유일한 통로이므로 화면에 노출해야 합니다. **응답 예시** @@ -1174,7 +1181,14 @@ _이 엔드포인트는 `data` 를 반환하지 않습니다 (성공 메시지 { "success": true, "message": "플러그인이 성공적으로 제거되었습니다.", - "data": null + "data": { + "preserved_backups": [ + { + "directory": "custom", + "archive": "/var/www/g7/storage/app/extension-custom-backups/sirsoft-gdpr-20260825_231500/custom" + } + ] + } } ``` diff --git a/docs/backend/api/templates.md b/docs/backend/api/templates.md index b850395a..9f4af6af 100644 --- a/docs/backend/api/templates.md +++ b/docs/backend/api/templates.md @@ -1088,7 +1088,14 @@ Authorization: Bearer {YOUR_TOKEN} **응답 필드** (`data` 내부) -_이 엔드포인트는 `data` 를 반환하지 않습니다 (`data`: `null`, 성공 메시지만)._ +| 이름 | 타입 | 예시 | 용도 | +| --- | --- | --- | --- | +| preserved_backups | array | `[{"directory":"custom","archive":"…/extension-custom-backups/…"}]` | 삭제 전에 보관한 운영자 소유 디렉토리의 사본 목록. 보관 대상이 없으면 빈 배열 | +| preserved_backups[].directory | string | `custom` | 보관된 디렉토리 이름 | +| preserved_backups[].archive | string | `storage/app/extension-custom-backups/{identifier}-{Ymd_His}/custom` | 사본이 놓인 절대 경로 | + +> 운영자가 `custom/` 에 넣은 파일은 확장 삭제와 함께 사라지지만, 삭제 직전에 사본이 +> 보관됩니다. 이 필드가 그 경로를 알리는 유일한 통로이므로 화면에 노출해야 합니다. **응답 예시** @@ -1096,7 +1103,14 @@ _이 엔드포인트는 `data` 를 반환하지 않습니다 (`data`: `null`, { "success": true, "message": "템플릿이 성공적으로 제거되었습니다.", - "data": null + "data": { + "preserved_backups": [ + { + "directory": "custom", + "archive": "/var/www/g7/storage/app/extension-custom-backups/sirsoft-basic-20260825_231500/custom" + } + ] + } } ``` @@ -97374,7 +97388,7 @@ _단건 응답: `data` 객체의 필드._ | error_config | object | `{"layouts":{"401":"errors\/401","403":"errors\/403","404"…` | 에러 표시 설정 객체 | | github_url | string | `https://github.com/gnuboard/g7-templa…` | GitHub 저장소 URL | | github_changelog_url | string | `https://github.com/gnuboard/g7-templa…` | GitHub 변경 내역 URL | -| externals | array | `[{"id":"fontawesome","type":"style","url":"https:\/\/cdnj…` | 외부 의존 라이브러리 목록 (번들에서 제외되고 전역에서 해석) | +| externals | array | `[{"id":"fontawesome","type":"style","url":"\/api\/templat…` | 외부 의존 라이브러리 목록 (번들에서 제외되고 전역에서 해석) | | cache_version | integer | `1784000969` | 에셋 캐시 무효화 버전 (번들 URL 파일명에 포함) | **응답 예시** @@ -97519,20 +97533,17 @@ HTTP/1.1 200 { "id": "fontawesome", "type": "style", - "url": "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css", - "preconnect": "https://cdnjs.cloudflare.com" + "url": "/api/templates/assets/sirsoft-admin_basic?file=vendor%2Ffont-awesome%2F6.4.0%2Fcss%2Fall.inlined.css&v=1785848038" }, { "id": "pretendard", "type": "webfont", - "url": "https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css", - "preconnect": "https://cdn.jsdelivr.net", - "crossorigin": "anonymous" + "url": "/api/templates/assets/sirsoft-admin_basic?file=vendor%2Fpretendard%2F1.3.9%2Fpretendard-variable.css&v=1785848038" }, { "id": "flag-icons", "type": "style", - "url": "https://cdn.jsdelivr.net/npm/flag-icons@7.2.3/css/flag-icons.min.css" + "url": "/api/templates/assets/sirsoft-admin_basic?file=vendor%2Fflag-icons%2F7.2.3%2Fcss%2Fflag-icons.min.css&v=1785848038" } ], "cache_version": 1785848038 diff --git a/docs/backend/static-asset-publishing.md b/docs/backend/static-asset-publishing.md index 5affeb26..72e0026f 100644 --- a/docs/backend/static-asset-publishing.md +++ b/docs/backend/static-asset-publishing.md @@ -5,7 +5,7 @@ ## TL;DR (5초 요약) ```text -1. 게시물: public/build/ext/{cache_version}/ — 수명주기 이벤트마다 terminating 훅이 재생성 +1. 게시물: public/build/ext/{cache_version}/ — 수명주기 이벤트와 운영자 custom 파일 변경마다 terminating 훅이 재생성 (활성 템플릿 + 활성 모듈·플러그인 custom + 병합 번들) 2. 서빙 게이트 3조건: 프로덕션 + G7_STATIC_CACHE(기본 on) + 게시 완료(manifest 존재) 3. 폴백 2층: 태그 계층은 파일 단위 file_exists + 파샬 역변환, fetch 계층은 fetchStaticFirst 4. 무효화는 버전 디렉토리 — 포인터(cache_version)가 바뀔 뿐 파일 덮어쓰기가 없다 @@ -42,6 +42,38 @@ public/build/ext/{cache_version}/ - 쓰기 안전: 식별자(vendor-name)·로케일 패턴 화이트리스트, dist 복사는 허용 확장자 화이트리스트(자산 서빙 검증 규칙과 동일 목록) + `*.map` 제외 + realpath 컨테인먼트. - `config.json` 과 레이아웃 JSON 은 게시 대상이 **아니다** — 전자는 버전 핸드셰이크의 SSoT(항상 신선해야 함), 후자는 인증 문맥(optional.sanctum) 의존. +## 2-1. 동봉 자산(`dist/vendor/`)과 운영자 자산(`custom/`) + +확장이 구동에 필요해 함께 담는 제3자 자산은 `dist/vendor/{라이브러리}/{버전}/` 에 둡니다. +템플릿의 `dist/**` 는 정적 게시 대상이므로 동봉 자산도 웹서버가 직접 서빙합니다. + +운영자가 덧붙이는 자산(`custom/`)도 **모듈·플러그인·템플릿 모두 같은 방식으로 게시됩니다.** +게시하지 않으면 이 자산만 API 경로에 남는데, 그 경로에서는 CSS 내부 상대 `url()` 이 해석되지 +않습니다 — 쿼리 형태(`?file=`)는 기준 URL 이 `/api/{타입}/assets/` 라 `url('./font.woff2')` 가 +그 디렉토리를 가리키고, 확장자 형태는 정적 최적화 서버가 먼저 가로챕니다. 즉 정적 확장자 +URL 은 **public 아래 실제 파일일 때만** 200 이 되므로, "폰트·이미지를 `custom/` 에 두고 상대 +경로로 참조" 를 성립시키는 방법은 게시뿐입니다. + +갱신 축도 확장 자산과 같습니다. 운영자가 파일을 고치면 뷰 컴포저가 파일 서명 변화를 감지해 +확장 캐시 버전을 올리고, 그 단일 지점이 재게시까지 예약합니다. 그 요청은 서술자를 새 버전으로 +다시 해석하므로 고친 내용이 그 화면부터 반영됩니다(게시본이 아직 없는 동안에는 API 경로로 +떨어지고, 그 응답이 디스크 최신 내용을 줍니다). + +모듈·플러그인은 **활성 확장의 `custom/` 만** 게시합니다 — 자산 서빙이 활성 확장에만 응답하므로 +비활성 확장의 파일을 게시해 봐야 아무도 참조하지 않는 사본이 버전 디렉토리마다 쌓입니다. +확장의 빌드 산출물은 개별 파일이 아니라 병합 번들로 게시되므로, `custom/` 이 그 확장에서 +유일한 개별 게시 대상입니다. + +버전 디렉토리를 쓰는 이유는 업그레이드 시 구버전 삭제 대상이 명확해지기 때문입니다. + +동봉 자산을 다시 만드는 절차는 명령으로 고정하고(`npm run vendor:*`), 그 명령은 **설치된 +패키지 버전과 출력 경로의 버전 디렉토리를 대조한 뒤에만** 씁니다. 손으로 복사하면 어느 +버전을 옮겼는지가 어디에도 남지 않아, 설치 트리가 갱신된 뒤 다시 복사하는 순간 `7.2.3/` +디렉토리에 7.5.0 이 들어앉습니다 — 오류도 로그도 없이 배포본의 버전 라벨만 틀리고, +파일은 정상으로 서빙되므로 브라우저에서도 드러나지 않습니다. 두 버전이 어긋나거나 +설치 패키지의 `package.json` 이 없어 확인할 수 없으면 생성기는 아무것도 쓰지 않고 +중단합니다. 재생성 전에는 `npm ci` 로 lock 에 선언된 버전을 설치합니다. + ## 3. 서빙·폴백 모델 - 실파일이므로 Apache(`RewriteCond !-f`)/nginx(`try_files $uri`) 어느 쪽이든 서버 설정 추가 없이 rewrite 전에 직접 서빙된다. 정적 확장자 정규식 location(`location ~* \.(js|css|json)$`)이 있는 서버에서는 그 location 이 곧 서빙 메커니즘이 된다. @@ -57,10 +89,25 @@ public/build/ext/{cache_version}/ | 트리거 | 지점 | 방식 | |---|---|---| | 수명주기 전체 | `incrementExtensionCacheVersion()` 내부 | terminating 게시 예약 — 프로세스당 1회, **실행 시점의 최종 버전**으로 게시 (연속 bump 자연 병합) | -| 자가 치유 | blade 렌더의 `staticExtBase()` 게이트 | 현재 버전 미게시 감지 시 terminating 게시 예약. 이번 응답은 API URL (첫 방문자 1회만 종전 속도) | +| 자가 치유 | blade 렌더의 `staticExtBase()` 게이트 | 현재 버전 미게시 감지 시 terminating 게시 예약. 이번 응답은 API URL — 아래 「자가 치유 창의 실제 비용」 참조 | | 수동/워밍 | `php artisan ext-static:publish [--force]` | 설치기 완료 단계에서도 호출 | | GC | `php artisan ext-static:cleanup` + 게시 성공 직후 인라인 GC | 현재 + 직전 1개 보존. 스케줄 일 1회 등록 | +### 자가 치유 창의 실제 비용 + +확장 수명주기 작업(설치·활성화·비활성화·삭제·업데이트)은 CLI 에서 캐시 버전만 올리고 게시는 다음 웹 렌더에 위임한다. 그래서 그 **직후 첫 페이지 로드 1회**는 API URL 로 나간다. + +이 창의 비용은 속도만이 아니다. `general.asset_url_mode` 가 `extensionless` 인 서버에서는 자산 URL 이 쿼리 형태(`?file=`)가 되는데, **CSS 안의 상대 경로 `url()` 은 그 형태에서 해석되지 않는다.** 실측(관리자 대시보드): + +| 자산 | 게시본 사용 | 자가 치유 창 (API 폴백) | +| --- | --- | --- | +| 아이콘 폰트 (CSS 에 인라인) | 정상 | **정상** — 하위 파일 참조가 없다 | +| 본문 글꼴 (`pretendard-variable.css` → `woff2/…`) | 정상 | **404** — FontFace `status: "error"`, 시스템 글꼴로 대체 | + +기능이 사라지지는 않는다(조작 수단인 아이콘은 인라인이라 영향 없음). 화면이 한 번 다른 글꼴로 보이고, 그 뒤 게시가 끝나면 정상으로 돌아온다. + +이 창을 없애려면 수명주기 작업 뒤에 `php artisan ext-static:publish` 를 명시적으로 실행한다. 다만 그 명령을 **웹 계정이 아닌 사용자로** 돌리면 게시 산출물 소유권이 어긋날 수 있으므로, 위 「소유권」 절의 주의사항을 함께 본다. + - 동시성: 게시는 캐시 락으로 단일 실행. manifest 존재 시 skip(멱등). - 실패 정책: 쓰기 실패는 로그만 남기고 tmp 정리 — 사이트는 API 폴백으로 정상 ("정적 fast path 미적용" 상태이지 장애가 아니다). 다음 렌더의 자가 치유가 재시도한다. - routes 병합이 열화 상태(확장 업데이트 진행 중 등)면 그 산출물은 게시하지 않는다 — 정적 파일은 스스로 회복되지 않으므로 열화가 다음 bump 까지 박제된다. 같은 규율이 폴백 API 의 HTTP 캐시 헤더에도 적용된다 — 열화 응답에는 `public, max-age` 를 부여하지 않는다 (브라우저/CDN 박제 방지). diff --git a/docs/extension/hooks.md b/docs/extension/hooks.md index 8965b663..d82fbca3 100644 --- a/docs/extension/hooks.md +++ b/docs/extension/hooks.md @@ -202,6 +202,17 @@ core.settings.available_mail_drivers # 드라이버 확장 훅 (Action) — 플러그인 드라이버 선택 시 Config 적용 core.settings.apply_driver_config +# 사용자 추가 에셋 훅 (Filter) — 운영자가 확장에 덧붙인 CSS·JS 목록을 보정/추가 +core.assets.custom_assets # applyFilters($assets, $extensionType, $identifier) + +# 사용자 추가 에셋 관리 훅 (Action) — 화면에서 파일을 저장/업로드/삭제한 직후 +core.custom_assets.after_change # doAction($extensionType, $identifier, $operation, $path) + +# 사용자 추가 에셋 관리 검증 훅 (Filter) — 관리 API 의 FormRequest 규칙 확장 +core.extension_custom_asset.read_validation_rules +core.extension_custom_asset.save_validation_rules +core.extension_custom_asset.upload_validation_rules + # SEO 렌더링 훅 (Filter) core.seo.filter_context # DataSource 결합 후 컨텍스트 보강 ($context 배열) core.seo.filter_og_data # OG 태그 분기별 hook ($og 배열) — image_width/site_name/extra 주입 diff --git a/docs/extension/module-assets.md b/docs/extension/module-assets.md index 196f0f2c..f2779cfd 100644 --- a/docs/extension/module-assets.md +++ b/docs/extension/module-assets.md @@ -127,19 +127,35 @@ #### `trusted_script_hosts` — 외부 스크립트 신뢰 호스트 +**구동에 필요한 자산은 확장이 함께 담아 자체 제공하는 것이 원칙입니다.** 브라우저가 화면을 +그리기 위해 제3자 CDN 에 도달해야 하면, 그 도달 실패는 예외도 로그도 남기지 않고 화면 기능만 +조용히 사라집니다 — 폐쇄망·방화벽·광고차단기에서 재현되며 자체 서버 로그에 흔적이 없어 +운영자가 원인을 특정할 수 없습니다. 동봉 위치는 `dist/vendor/{라이브러리}/{버전}/` 입니다. + +이 필드는 **자체 제공이 불가능한 경우**에만 씁니다 — 라이브러리가 아니라 그 회사 서버와 +통신하는 서비스 SDK(주소 검색 등)가 그렇습니다. 자체 호스팅해도 동작하지 않으므로 외부 +의존이 남습니다. + 레이아웃 보안 정책은 `scripts[].src`·`data_sources[].endpoint` 를 기본적으로 same-origin 경로(`/` 로 시작)만 허용하고, 외부 origin·protocol-relative(`//host`)·scheme 포함 URL 은 저장 시점과 렌더 시점 양쪽에서 차단합니다. 확장이 정당하게 외부 CDN 스크립트를 써야 하면 그 호스트를 이 배열에 선언합니다. 활성 확장이 선언한 호스트만 집계되며(편집자는 추가 불가 — manifest 는 배포물), 코어가 활성 확장 전체의 선언을 모아 allowlist 를 구성합니다. -```jsonc -{ - "trusted_script_hosts": ["cdn.ckeditor.com"] -} -``` +- 값은 호스트명만(스킴/경로 없이). 예: `"t1.daumcdn.net"`. +- **`trusted_script_hosts_reason` 에 호스트별 사유를 함께 선언합니다.** 사유가 없는 선언은 + 자체 제공 원칙의 예외로 인정되지 않습니다 — 왜 외부로 나가는지가 코드에 남아야 합니다. -- 값은 호스트명만(스킴/경로 없이). 예: `"cdn.ckeditor.com"`, `"t1.daumcdn.net"`. + ```jsonc + { + "trusted_script_hosts": ["t1.daumcdn.net"], + "trusted_script_hosts_reason": { + "t1.daumcdn.net": "라이브러리가 아니라 Daum 이 운영하는 서비스 SDK 다. 스크립트가 Daum 서버와 통신하므로 자체 호스팅해도 동작하지 않는다." + } + } + ``` +- 외부 의존이 남는 기능은 **그 자산을 못 불러왔을 때의 동작**을 함께 갖춰야 합니다. 예: 주소 + 검색 SDK 가 없으면 우편번호·주소를 직접 입력할 수 있게 두고 안내를 띄웁니다. - 이 기능은 코어 7.0.7 에서 도입되었습니다. 선언하는 확장은 `g7_version` 을 `>=7.0.7` 로 두는 것이 계약상 정확합니다(하위 코어에서는 필드가 무시되어 무해). - 관련 보안 정책 상세: [frontend/security.md](../frontend/security.md). @@ -568,7 +584,45 @@ php artisan template:cache-clear # 전체 번들 파일 정리 포함 ## 외부 라이브러리 -외부 CDN 스크립트를 조건부로 로드할 수 있습니다. +라이브러리는 확장이 함께 담아 자체 제공합니다(`dist/vendor/{라이브러리}/{버전}/`). 외부 CDN +실시간 로드는 그 CDN 에 도달하지 못하는 환경에서 기능이 조용히 사라지게 만듭니다. + +아래 조건부 외부 로드는 **자체 제공이 불가능한 서비스 SDK** 에만 씁니다. 그 경우 manifest 에 +`trusted_script_hosts` 와 `trusted_script_hosts_reason` 을 함께 선언해야 하며, 자산을 못 +불러왔을 때의 동작도 함께 갖춰야 합니다. + +### 동봉 자산의 URL 생성 + +동봉한 자산을 런타임에 불러올 때는 URL 을 문자열로 조립하지 않고 `G7Core.asset` 을 씁니다. +확장 번들은 코어 모듈을 import 할 수 없으므로 이 전역이 유일한 통로입니다. + +```javascript +// 플러그인 — 확장 루트 기준이라 dist/ 를 포함한다 +const url = G7Core.asset.plugin('sirsoft-ckeditor5', 'dist/vendor/ckeditor5/43.3.1/ckeditor5.umd.js'); +await G7Core.asset.loadScript(url, { id: 'ckeditor5' }); + +// 모듈 +G7Core.asset.module('sirsoft-board', 'dist/vendor/chart.js/4.4.0/chart.umd.js'); + +// 템플릿 — 서버가 dist/ 를 자동으로 붙이므로 path 에 포함하지 않는다 +G7Core.asset.template('sirsoft-admin_basic', 'vendor/flag-icons/7.2.3/css/flag-icons.min.css'); +``` + +자산 URL 은 서버 설정과 정적 게시 상태에 따라 확장자 형태(`.../lib.js`), 쿼리 형태 +(`...?file=...`), 정적 게시본 경로(`/build/ext/{버전}/...`) 중 하나로 해석됩니다. 문자열로 +조립하면 그 판정을 건너뛰어, 정규식 location 이 확장자를 먼저 가로채는 서버에서 그 자산만 +조용히 404 가 됩니다. + +AMD 로더나 워커처럼 디렉토리 접두 뒤에 파일명을 이어 붙이는 소비자는 `templateDir()` 을 +씁니다 — 쿼리 형태는 뒤에 파일명을 이어 붙일 수 없기 때문입니다. 확장자 없는 모드에서 404 +일 수 있으므로 그 소비자는 폴백을 갖춰야 합니다. + +로드에 끝내 실패하면 `G7Core.assets.notifyFailure({ id, label, retry })` 로 사용자에게 +알립니다. `console.error` 한 줄로 끝내면 사용자에게는 빈 자리로만 나타나고 자체 서버 로그에도 +흔적이 남지 않아 운영자가 원인을 특정할 수 없습니다. + +전체 시그니처와 `AssetFailure` 필드는 +[G7Core 전역 API 레퍼런스](../frontend/g7core-api.md)의 「확장 자산」 절을 참조하세요. ### module.json 설정 @@ -603,6 +657,149 @@ php artisan template:cache-clear # 전체 번들 파일 정리 포함 --- +## 사용자 추가 에셋 (`custom/`) + +운영자가 자기 CSS·JS·정적 파일을 덧붙일 자리를 각 확장이 제공한다. + +종전에는 그런 자리가 없었다. CSS 한 줄을 더하려면 확장 소스(`src/styles/`)를 고치고 Node.js 로 빌드해야 했고 — 그렇게 넣은 파일은 다음 확장 업데이트에 **통째로 사라졌다**(확장 교체가 활성 디렉토리를 전부 갈아끼우기 때문이다). 빌드 산출물(`dist/`)을 직접 고치는 것도 다음 빌드에 사라진다. + +### 자리 + +``` +templates/{id}/custom/ ← 운영자 소유. 확장 교체가 보존한다 +modules/{id}/custom/ +plugins/{id}/custom/ +├── custom.css 규약 자동 로드 (파일명 오름차순) +├── 10-override.css +├── custom.js +├── fonts/MyFont.woff2 정적 파일 — CSS 가 상대 경로로 참조 +└── assets.json (선택) 선언이 있으면 이것이 우선 +``` + +- 빌드하지 않는다. 파일을 놓으면 다음 요청부터 적용된다. +- 확장 업데이트·재설치가 이 디렉토리만은 보존한다. +- 확장을 **삭제**하면 확장 디렉토리와 함께 사라진다. 삭제 전 백업을 안내한다. +- 번들 확장은 `custom/` 을 담아 배포하지 않는다 — 보존 계층이 덮어쓰지 않으므로 그 파일은 기존 설치본에 영영 반영되지 않는다. 확장이 담을 자산은 `dist/vendor/{lib}/{version}/` 에 둔다. + +### 선언 파일 (`custom/assets.json`) + +순서를 바꾸거나, 일부만 싣거나, 외부 URL 을 등록할 때만 쓴다. 필드는 `template.json` 의 `externals` 와 같은 어휘다. + +```json +{ + "assets": [ + { "type": "style", "file": "10-override.css" }, + { "type": "script", "file": "custom.js" }, + { "type": "style", "url": "https://fonts.example.com/x.css", "reason": "본문 웹폰트" } + ] +} +``` + +- `file` 은 `custom/` 기준 상대 경로다. 상위 디렉토리 이탈은 차단된다. +- `url` 은 운영자가 자기 사이트에 직접 등록하는 외부 자산이다. **`reason`(사유)이 없으면 싣지 않는다** — 왜 외부로 나가는지가 파일에 남아야 한다. 외부 서비스에는 방문자의 IP·UA 가 전달된다. +- 선언 파일이 있으면 규약 스캔은 하지 않는다. 둘을 합치면 "선언에서 뺐는데 왜 아직 로드되나" 가 된다. +- 선언 파일이 깨졌으면(JSON 파싱 실패) **규약 스캔으로 되돌아가지 않고** 그 확장의 custom 을 비운다. 되돌아가면 운영자가 의도적으로 뺀 파일이 되살아난다. + +### 로드 순서 + +``` +① 템플릿 외부 리소스 → 코어 엔진 → 템플릿 CSS +② 확장 병합 번들 (모듈 → 플러그인) +③ 사용자 추가 에셋 (모듈 → 플러그인 → 템플릿) ← 언제나 마지막 +``` + +CSS 는 나중에 온 규칙이 이긴다. 운영자가 덧붙인 스타일이 확장 스타일보다 뒤에 와야 재정의가 성립한다. 템플릿이 ③ 의 마지막인 이유는 화면 외관의 최종 책임이 템플릿에 있어서다. + +같은 확장 안에서는 선언 순서(없으면 파일명 오름차순), CSS 를 JS 보다 먼저 싣는다. + +사용자 추가 에셋은 JS 부팅 이후에 붙으므로 아주 짧은 스타일 적용 지연이 있다. 이는 확장 번들 CSS 가 이미 갖고 있는 성질이며, 순서 정합을 깨는 것보다 낫다. + +### 캐시 무효화 + +파일을 고치면 URL 이 바뀐다 — 캐시를 지우라고 안내할 필요가 없다. 다만 그 방법이 확장 타입에 따라 다르다. + +**세 타입 모두** 확장 자산과 **같은 메커니즘**으로 정적 게시된다. 그래서 URL 도 같은 축(확장 캐시 버전)을 쓴다 — 정적 경로는 언제나 현재 게시 버전이므로, 파일 서명을 URL 에 실으면 버전 일치 게이트에 걸려 정적 분기가 영영 선택되지 않는다. 대신 운영자가 파일을 고치면 뷰 컴포저가 그 변화를 감지해 확장 캐시 버전을 올리고, 그 단일 지점이 재게시까지 예약한다. + +이 게시가 필요한 이유는 성능이 아니라 **상대 경로**다. API 경로에서는 CSS 내부 `url('./font.woff2')` 가 해석되지 않는다(기준 URL 이 자산 디렉토리가 아니다). 정적 확장자 URL 은 public 아래 실제 파일일 때만 200 이 되므로, 게시본만이 상대 참조를 성립시킨다. + +**모듈·플러그인**도 같다. 다만 게시 대상은 **활성** 확장의 `custom/` 뿐이다 — 자산 서빙이 활성 확장에만 응답하므로 비활성 확장의 파일을 게시해 봐야 아무도 참조하지 않는 사본이 쌓인다. 확장의 빌드 산출물은 개별 파일이 아니라 병합 번들로 게시되므로, `custom/` 이 그 확장에서 유일한 개별 게시 대상이다. + +### 확장하기 + +해석기는 **출처에 의존하지 않는 서술자**를 돌려준다. + +```php +['id' => 'custom:templates:sirsoft-basic:10-override.css', + 'type' => 'style', // style | script + 'url' => '/api/templates/assets/sirsoft-basic?file=custom%2F10-override.css&v=…', + 'version' => 1787660208, + 'source' => 'file'] // file | url | (확장이 더한 출처) +``` + +소비자(뷰 컴포저·프론트 로더·서빙·순서 규칙)는 `source` 를 보지 않는다. 다른 출처를 더하려면 해석기 끝의 필터 훅을 쓴다. + +```php +HookManager::addFilter('core.assets.custom_assets', function (array $assets, string $type, string $id): array { + $assets[] = [ + 'id' => 'custom:my-source:'.$id, + 'type' => 'style', + 'url' => '/api/my-endpoint.css', + 'version' => $updatedAt, + 'source' => 'my-source', + ]; + + return $assets; +}, 10, 3); +``` + +훅으로 더한 항목도 자기 `version` 을 실어야 한다 — 캐시 서명이 항목별 버전의 합성이기 때문이다. + +### 화면에서 관리하기 (레이아웃 편집기) + +FTP 나 서버 셸이 유일한 경로였다면, 그 접근이 없는 운영자에게는 이 기능이 없는 것과 +같다. 레이아웃 편집기 상단의 [커스텀 자산] 버튼이 같은 디렉토리를 화면에서 다룬다 — +텍스트(`css`·`js`·`mjs`·`json`)는 본문을 열어 고치고, 폰트·이미지는 올리고 지운다. +모달 상단의 대상 선택기로 **편집 중인 템플릿과 활성 모듈·플러그인**을 오갈 수 있다. + +- 저장·업로드·삭제는 확장 캐시 버전을 올려 **정적 게시본까지 갱신**한다. 파일만 바꾸고 + 게시본이 그대로면 운영자에게는 "고쳤는데 화면이 그대로" 로만 나타난다. +- 바이너리는 본문 편집기를 열지 않는다. 텍스트로 열어 저장하면 내용이 손상된다. +- 업로드 허용 확장자는 자산 서빙 화이트리스트와 **같은 목록**이다. 관리 쪽만 넓히면 + 올릴 수는 있는데 서빙되지 않는 파일이 생기고, 좁히면 서빙 규칙이 사문화된다. + +권한은 레이아웃 편집(`core.templates.layouts.edit`)과 **분리**된 +`core.extensions.custom_assets.manage` 하나다. 확장 타입별로 쪼개지 않는다 — 쪼개면 운영자가 +셋을 다 부여해야 하고, "모듈 CSS 는 되는데 템플릿 CSS 는 안 되는" 상태가 실질적 의미 없이 +생긴다. 여기서 올린 스크립트는 그 레이아웃 한 장이 +아니라 사이트 전 화면에서 실행되므로, 레이아웃을 고칠 수 있다는 것이 곧 그 권한이 될 수 +없다. 기존 사이트에는 코어 업데이트의 표준 권한 동기화로 도달한다(관리자 역할은 자동 부여). + +API 레퍼런스: [docs/backend/api/extensions.md](../backend/api/extensions.md) 의 +`custom-assets` 엔드포인트 5종. 세 타입이 한 엔드포인트 +(`extensions/{type}/{identifier}/custom-assets`)를 공유한다 — 타입별로 나누면 같은 검증·문서· +테스트가 세 벌로 갈리고, 그중 하나만 약해지면 그 경로가 조용한 우회로가 된다. + +### 자기 CSS 에 갇히지 않기 (`?custom=off`) + +운영자가 넣은 CSS 한 줄이 화면을 조작 불능으로 만들 수 있다. 그런데 그것을 고칠 관리자 +화면에도 같은 CSS 가 실려 있어, 고치러 들어갈 수가 없다. + +주소에 `?custom=off` 를 붙여 다시 열면 **서버가 목록을 비운다.** 자산이 페이지에 +도달하지 않으므로, 이미 깨진 화면에서 자바스크립트가 돌기를 기대하지 않아도 된다. +레이아웃 편집기 툴바에도 같은 동작의 토글이 있고, 꺼진 동안에는 지금 화면이 평소와 다른 +상태임을 버튼이 드러낸다. + +이 파라미터는 그 요청 한 번에만 작용하며 저장되지 않는다. 화면을 고친 뒤 파라미터 없이 +열면 곧바로 원래대로 돌아온다. + +### 지원하지 않는 것 + +| 방법 | 판정 | +|---|---| +| `dist/css/components.css` 직접 수정 | 다음 빌드·업데이트에 소실된다 | +| `src/styles/custom.css` + 빌드 | 확장 **저작자**의 방법으로는 유효하다. 운영자에게는 부적합(빌드 필요 + 업데이트 소실) | +| `custom/custom.css` 에 파일만 놓기 | 권장 | + ## AbstractModule 에셋 메서드 AbstractModule은 에셋 관련 헬퍼 메서드를 제공합니다: diff --git a/docs/extension/permissions.md b/docs/extension/permissions.md index 897d1ebc..82caa3ab 100644 --- a/docs/extension/permissions.md +++ b/docs/extension/permissions.md @@ -394,6 +394,18 @@ core.users.view core.users.manage ``` +`[entity]` 가 특정 확장 타입이 아니라 `extensions` 인 권한은 **템플릿·모듈·플러그인 세 타입이 공유**한다. +타입별로 쪼개면 운영자가 같은 성격의 권한을 셋 다 부여해야 하고, "모듈 CSS 는 되는데 템플릿 CSS 는 +안 되는" 상태가 실질적 의미 없이 생긴다. + +```text +core.extensions.custom_assets.manage +``` + +이 권한은 그룹 `core.extensions`(확장 공통) 에 속한다. 레이아웃 편집 권한 +(`core.templates.layouts.edit`) 과 분리한 이유는 여기서 올린 스크립트가 레이아웃 한 장이 아니라 +**사이트 전 화면에서 실행**되기 때문이다 — 레이아웃을 고칠 수 있다는 것이 곧 그 권한이 될 수 없다. + ### 모듈 권한 ```text diff --git a/docs/extension/template-basics.md b/docs/extension/template-basics.md index 872df754..751ef237 100644 --- a/docs/extension/template-basics.md +++ b/docs/extension/template-basics.md @@ -228,8 +228,7 @@ public function restoreVersion(int $layoutId, int $version): TemplateLayout { "id": "fontawesome", "type": "style", - "url": "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css", - "preconnect": "https://cdnjs.cloudflare.com" + "asset": "vendor/font-awesome/6.4.0/css/all.inlined.css" } ] } @@ -249,15 +248,31 @@ public function restoreVersion(int $layoutId, int $version): TemplateLayout ### 외부 리소스 (externals) -`externals`는 admin/user 템플릿에 공통 적용되는 선택 필드입니다. 최초 HTML 문서에 정적으로 필요한 외부 스타일, 웹폰트, 스크립트, 리소스 힌트를 선언합니다. `external_styles`는 사용하지 않습니다. +`externals`는 admin/user 템플릿에 공통 적용되는 선택 필드입니다. 최초 HTML 문서에 정적으로 필요한 스타일, 웹폰트, 스크립트, 리소스 힌트를 선언합니다. `external_styles`는 사용하지 않습니다. + +자산을 가리키는 방법은 `asset`과 `url` 두 가지이며, 항목마다 **하나를 고릅니다**. + +- `asset` — 템플릿이 **자체 제공**하는 파일의 `dist/` 이하 경로. 구동 에셋은 자체 제공이 원칙이므로 이쪽이 기본입니다. +- `url` — 절대 URL. 자체 제공이 불가능한 외부 서비스에만 씁니다. + +```json +{ + "type": "style", + "id": "font-awesome", + "asset": "vendor/font-awesome/6.4.0/css/all.inlined.css" +} +``` + +구동에 필요한 에셋을 제3자 CDN에서 실시간으로 받으면, 그 도달 실패는 예외도 로그도 남기지 않고 화면 기능만 사라집니다. 폐쇄망·방화벽·광고차단기 환경에서 재현되며 자체 서버 로그에 흔적이 없어 운영자가 원인을 특정할 수 없습니다. 라이브러리·웹폰트·아이콘은 `dist/vendor/{lib}/{version}/`에 동봉하고 `asset`으로 가리킵니다. | 속성 | 타입 | 필수 | 적용 type | 허용값/형식 | 렌더링/동작 | |---|---:|---:|---|---|---| | `id` | string | 권장 | all | 영문/숫자/`-`/`_` | HTML `id` 속성 | | `type` | string | 필수 | all | `style`, `webfont`, `script`, `preconnect`, `dns-prefetch`, `preload`, `modulepreload` | 출력 태그와 위치 결정 | -| `url` | string | 필수 | all | `https://...` | link 계열은 `href`, script는 `src` | -| `preconnect` | string | 선택 | `style`, `webfont`, `script`, `preload`, `modulepreload` | `https://cdn.example.com` | 리소스보다 먼저 `` 출력, 중복 제거 | -| `crossorigin` | boolean/string | 선택 | `style`, `webfont`, `script`, `preconnect`, `preload`, `modulepreload` | `true`, `anonymous`, `use-credentials` | `true`는 `anonymous`로 정규화 | +| `asset` | string | `url`과 택일 | `preconnect`·`dns-prefetch` 제외 | `dist/` 이하 상대 경로 (`vendor/font-awesome/6.4.0/css/all.inlined.css`). `/`로 시작 금지, `..` 금지, `A-Za-z0-9._-/`만 허용 | 자산 URL 이중 모드와 정적 게시를 반영한 same-origin URL로 해석. `url`보다 우선하며, 둘 다 선언하면 `url`은 무시되고 경고가 남는다 | +| `url` | string | `asset`과 택일 | all | `https://...` 또는 `/`로 시작하는 same-origin 경로 | link 계열은 `href`, script는 `src` | +| `preconnect` | string | 선택 | `style`, `webfont`, `script`, `preload`, `modulepreload` | `https://cdn.example.com` | 리소스보다 먼저 `` 출력, 중복 제거. **same-origin 항목에서는 무시** | +| `crossorigin` | boolean/string | 선택 | `style`, `webfont`, `script`, `preconnect`, `preload`, `modulepreload` | `true`, `anonymous`, `use-credentials` | `true`는 `anonymous`로 정규화. **same-origin 항목에서는 무시** | | `integrity` | string | 선택 | `style`, `webfont`, `script`, `preload`, `modulepreload` | SRI hash | HTML `integrity` | | `referrerpolicy` | string | 선택 | `style`, `webfont`, `script`, `preload`, `modulepreload` | 표준 referrer policy | HTML `referrerpolicy` | | `media` | string | 선택 | `style`, `webfont` | CSS media query | stylesheet link의 `media` | @@ -552,6 +567,27 @@ Body: { "layout_strategy": "apply_new" } 필수: _bundled 작업 완료 후 반영/검증은 업데이트 프로세스 사용 ``` +### `custom/` 은 운영자 자리입니다 — 저작자가 선점하지 않습니다 + +`templates/{identifier}/custom/` 은 **사이트 운영자**가 자기 CSS·JS 를 덧붙이는 자리입니다. +확장 교체(업데이트·재설치)가 이 디렉토리만은 보존하므로, 운영자가 넣은 파일은 템플릿을 +업데이트해도 살아남습니다. + +그래서 템플릿 저작자는 `_bundled` 에 `custom/` 을 담아 배포하지 않습니다. 보존 계층은 +"덮어쓰지 않음" 이라, 저작자가 담은 파일은 이미 `custom/` 을 가진 사이트에서 **영영 +반영되지 않는 상태**가 됩니다. 저작자의 기본 스타일은 `src/styles/` 에 두고 빌드에 +포함시킵니다. + +| 대상 | 자리 | 빌드 | 업데이트 시 | +|---|---|---|---| +| 저작자 기본 스타일 | `src/styles/` | 필요 | 새 배포본으로 교체 | +| 저작자 동봉 구동 자산 | `dist/vendor/{lib}/{version}/` | 불필요 | 새 배포본으로 교체 | +| **운영자 추가 CSS·JS** | **`custom/`** | **불필요** | **보존** | + +운영자가 `dist/` 를 직접 고치는 것은 방법이 아닙니다 — 다음 빌드와 다음 업데이트에 +사라집니다. 로드 순서·`custom/assets.json` 선언 형식·외부 URL 등록 규칙은 +[module-assets.md 「사용자 추가 에셋」](module-assets.md) 을 참조하세요. + ### 개발 워크플로우 ```text diff --git a/docs/extension/template-workflow.md b/docs/extension/template-workflow.md index f9dd2fb0..c292f13b 100644 --- a/docs/extension/template-workflow.md +++ b/docs/extension/template-workflow.md @@ -132,8 +132,7 @@ Phase 6: 빌드 및 설치 { "id": "fontawesome", "type": "style", - "url": "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css", - "preconnect": "https://cdnjs.cloudflare.com" + "asset": "vendor/font-awesome/6.4.0/css/all.inlined.css" } ] } diff --git a/docs/frontend/components-advanced.md b/docs/frontend/components-advanced.md index ddc329a9..88bdcab8 100644 --- a/docs/frontend/components-advanced.md +++ b/docs/frontend/components-advanced.md @@ -179,14 +179,13 @@ Pro 버전 아이콘은 라이선스가 필요하므로 사용할 수 없습니 { "id": "fontawesome", "type": "style", - "url": "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css", - "preconnect": "https://cdnjs.cloudflare.com" + "asset": "vendor/font-awesome/6.4.0/css/all.inlined.css" } ] } ``` -Font Awesome은 컴포넌트에서 직접 import하지 않고, admin/user 템플릿의 `template.json` `externals`에 선언해 Blade가 최초 HTML에서 로드합니다. +Font Awesome은 컴포넌트에서 직접 import하지 않고, admin/user 템플릿의 `template.json` `externals`에 선언해 Blade가 최초 HTML에서 로드합니다. 구동에 필요한 에셋은 자체 제공이 원칙이므로 `dist/vendor/{lib}/{version}/`에 동봉한 파일을 `asset`으로 가리킵니다 — 제3자 CDN에서 실시간으로 받으면 도달 실패가 예외도 로그도 없이 아이콘만 사라집니다. ### 아이콘 사용 방법 diff --git a/docs/frontend/g7core-api-advanced.md b/docs/frontend/g7core-api-advanced.md index 5b93ae9c..0f5a11e6 100644 --- a/docs/frontend/g7core-api-advanced.md +++ b/docs/frontend/g7core-api-advanced.md @@ -916,6 +916,25 @@ declare global { }; t: (key: string, params?: Record) => string; + // 확장 자산 URL (engine-v1.62.0+) + asset: { + template: (identifier: string, path: string, version?: number | string | null) => string; + templateDir: (identifier: string, path: string) => string; + module: (identifier: string, path: string, version?: number | string | null) => string; + plugin: (identifier: string, path: string, version?: number | string | null) => string; + convertToCurrentMode: (url: string) => string; + loadScript: (url: string, attrs?: Record, options?: Record) => Promise; + loadStylesheet: (url: string, attrs?: Record, options?: Record) => Promise; + }; + + // 자산 실패 안내 (engine-v1.62.0+) + assets: { + notifyFailure: (failure: AssetFailure) => void; + clearFailure: (id: string) => void; + clearAll: () => void; + getFailures: () => AssetFailure[]; + retryAll: () => Promise; + }; // 액션 dispatch: (action: ActionConfig) => Promise; @@ -1012,7 +1031,7 @@ declare global { ## 관련 문서 -- [G7Core 기본 API](g7core-api.md) - 상태 관리, 토스트, 모달, 네비게이션, 플러그인/모듈 설정 +- [G7Core 기본 API](g7core-api.md) - 상태 관리, 토스트, 모달, 네비게이션, 플러그인/모듈 설정, 확장 자산 - [state-management.md](state-management.md) - 전역 상태 관리 상세 - [components.md](components.md) - 컴포넌트 개발 규칙 - [data-binding.md](data-binding.md) - 데이터 바인딩 문법 diff --git a/docs/frontend/g7core-api.md b/docs/frontend/g7core-api.md index 1b94e533..76c7d591 100644 --- a/docs/frontend/g7core-api.md +++ b/docs/frontend/g7core-api.md @@ -23,7 +23,7 @@ | 문서 | 내용 | |------|------| -| **g7core-api.md** (현재) | 개요, 상태 관리, 토스트 알림, 모달 관리, 네비게이션, 스타일 헬퍼, 플러그인/모듈 설정, 위지윅 편집기 | +| **g7core-api.md** (현재) | 개요, 상태 관리, 토스트 알림, 모달 관리, 네비게이션, 스타일 헬퍼, 플러그인/모듈 설정, 확장 자산, 위지윅 편집기 | | [g7core-api-advanced.md](g7core-api-advanced.md) | 다국어, 액션 실행, 컴포넌트 이벤트, 이벤트 생성 헬퍼, 렌더링 헬퍼, 인증/API, WebSocket, 반응형, React Hooks, 타입 정의 | --- @@ -38,7 +38,8 @@ 6. [스타일 헬퍼 (G7Core.style)](#스타일-헬퍼-g7corestyle) 7. [플러그인 설정 (G7Core.plugin)](#플러그인-설정-g7coreplugin) 8. [모듈 설정 (G7Core.module)](#모듈-설정-g7coremodule) -9. [위지윅 편집기 (G7Core.wysiwyg)](#위지윅-편집기-g7corewysiwyg) +9. [확장 자산 (G7Core.asset, G7Core.assets)](#확장-자산-g7coreasset-g7coreassets) +10. [위지윅 편집기 (G7Core.wysiwyg)](#위지윅-편집기-g7corewysiwyg) --- @@ -65,6 +66,8 @@ | 인증 | `G7Core.AuthManager` | 인증 상태 관리 | [고급 API](g7core-api-advanced.md) | | API | `G7Core.api` | API 클라이언트 | [고급 API](g7core-api-advanced.md) | | WebSocket | `G7Core.websocket` | 실시간 통신 | [고급 API](g7core-api-advanced.md) | +| 확장 자산 URL | `G7Core.asset` | 템플릿/모듈/플러그인 자산 URL 생성, 재시도 로더 | 현재 문서 | +| 자산 실패 안내 | `G7Core.assets` | 자산 로드 실패 표면화 및 재시도 | 현재 문서 | | 위지윅 | `G7Core.wysiwyg` | 레이아웃 편집기 | 현재 문서 | | React Hooks | `G7Core.useControllableState` | 상태 패턴 훅 | [고급 API](g7core-api-advanced.md) | @@ -791,6 +794,114 @@ const PriceDisplay: React.FC<{ price: number }> = ({ price }) => { --- +## 확장 자산 (G7Core.asset, G7Core.assets) + +> **버전**: engine-v1.62.0+ + +확장(템플릿·모듈·플러그인)이 **자기 자산을 런타임에 불러올 때** 쓰는 API입니다. 확장 번들은 +코어 모듈을 import 할 수 없으므로, 자산 URL 생성과 실패 표면화는 이 전역을 통해 제공됩니다. + +구동에 필요한 자산(js·css·웹폰트)은 제3자 CDN 에서 실시간으로 받지 않고 확장이 함께 담아 +`dist/vendor/{라이브러리}/{버전}/` 에서 자체 제공합니다. 자세한 규약은 +[module-assets.md](../extension/module-assets.md)를 참조하세요. + +### G7Core.asset — 자산 URL 생성 + +| 메서드 | 시그니처 | 설명 | +|--------|----------|------| +| `template` | `(identifier, path, version?) => string` | 템플릿 자산 URL | +| `templateDir` | `(identifier, path) => string` | 템플릿 자산 **디렉토리** URL | +| `module` | `(identifier, path, version?) => string` | 모듈 자산 URL | +| `plugin` | `(identifier, path, version?) => string` | 플러그인 자산 URL | +| `convertToCurrentMode` | `(url) => string` | 서버가 확장자 형태로 굳혀 내려준 URL 을 현재 모드로 보정 | +| `loadScript` | `(url, attrs?, options?) => Promise` | 재시도 계층을 갖춘 스크립트 로더 | +| `loadStylesheet` | `(url, attrs?, options?) => Promise` | 재시도 계층을 갖춘 스타일시트 로더 | + +`path` 기준이 확장 타입마다 다릅니다. **템플릿은 서버가 `dist/` 를 자동으로 붙이므로 `path` 에 +`dist/` 를 포함하지 않고**, 모듈·플러그인은 확장 루트 기준이라 `dist/` 를 직접 포함합니다. +서버측 `App\Support\AssetUrl` 과 같은 비대칭입니다. + +```javascript +// 템플릿 — dist/ 를 붙이지 않는다 +G7Core.asset.template('sirsoft-admin_basic', 'vendor/monaco-editor/0.54.0/vs/loader.js'); + +// 플러그인 — 확장 루트 기준이라 dist/ 를 포함한다 +G7Core.asset.plugin('sirsoft-ckeditor5', 'dist/vendor/ckeditor5/43.3.1/ckeditor5.umd.js'); + +// 모듈 +G7Core.asset.module('sirsoft-board', 'dist/js/board.js'); +``` + +### 자산 URL 을 문자열로 조립하지 않습니다 + +```javascript +// ❌ 금지 — 확장자를 정적 location 이 가로채는 서버에서 404 가 된다 +const url = '/api/plugins/assets/sirsoft-ckeditor5/dist/vendor/ckeditor5/43.3.1/ckeditor5.umd.js'; + +// ✅ 올바른 사용 +const url = G7Core.asset.plugin('sirsoft-ckeditor5', 'dist/vendor/ckeditor5/43.3.1/ckeditor5.umd.js'); +``` + +자산 URL 은 서버 설정(`general.asset_url_mode`)과 정적 게시 상태에 따라 **확장자 형태** +(`.../ckeditor5.umd.js`)와 **쿼리 형태**(`...?file=...`), **정적 게시본 경로** +(`/build/ext/{버전}/...`) 중 하나로 해석됩니다. 문자열로 조립하면 그 판정을 건너뛰어, 정규식 +location 이 확장자를 먼저 가로채는 서버에서 그 자산만 조용히 404 가 됩니다. + +### templateDir — 디렉토리 접두가 필요한 소비자 + +AMD 로더나 워커처럼 **디렉토리 접두 뒤에 파일명을 이어 붙이는** 소비자는 `template()` 대신 +`templateDir()` 을 씁니다. 쿼리 형태(`?file=`)는 뒤에 파일명을 이어 붙일 수 없기 때문입니다. +확장자 없는 모드에서 404 일 수 있으므로 **소비자가 폴백을 갖춰야 합니다.** + +```javascript +loader.config({ + paths: { vs: G7Core.asset.templateDir('sirsoft-admin_basic', 'vendor/monaco-editor/0.54.0/vs') }, +}); +``` + +### G7Core.assets — 자산 실패 표면화 + +로드에 끝내 실패한 자산을 화면 상단 배너로 알리고 [다시 시도] 를 제공합니다. 실패를 +`console.error` 한 줄로 끝내면 사용자에게는 "빈 자리" 로만 나타나고 자체 서버 로그에도 흔적이 +남지 않아 운영자가 원인을 특정할 수 없습니다. + +| 메서드 | 시그니처 | 설명 | +|--------|----------|------| +| `notifyFailure` | `(failure: AssetFailure) => void` | 실패 등록 (같은 `id` 는 갱신) | +| `clearFailure` | `(id: string) => void` | 해당 실패 해제 | +| `clearAll` | `() => void` | 전체 해제 | +| `getFailures` | `() => AssetFailure[]` | 현재 등록된 실패 목록 | +| `retryAll` | `() => Promise` | 등록된 실패 전부 재시도 — 각 `retry` 를 순차 await 하므로 완료를 기다리려면 반환값을 await 한다 | + +`AssetFailure` 필드: + +| 필드 | 타입 | 설명 | +|------|------|------| +| `id` | `string` | 중복 누적을 막는 식별자 (필수) | +| `label` | `string` | 짧은 항목명 — 여러 건 합산 표시에 쓰인다 | +| `message` | `string?` | 사용자에게 보일 안내 문장. 생략하면 `label` 기반 기본 문구 | +| `retry` | `() => Promise \| void` | 생략하면 [다시 시도] 버튼을 렌더하지 않는다 | + +```javascript +try { + await G7Core.asset.loadStylesheet(url, { id: 'my-plugin-css' }); + G7Core.assets.clearFailure('my-plugin-css'); +} catch (error) { + G7Core.assets.notifyFailure({ + id: 'my-plugin-css', + label: '편집기 스타일', + retry: () => G7Core.asset.loadStylesheet(url, { id: 'my-plugin-css' }), + }); +} +``` + +배너는 독립 레이아웃(`extends` 없음)에서도 떠야 하므로 호스트 컴포넌트에 의존하지 않고 +DOM 에 직접 주입됩니다. Toast 와 달리 **사용자가 닫을 때까지 유지**되며 `role="alert"` 를 +갖습니다. `retry` 가 resolve 되면 그 실패는 자동으로 해제되고, reject 되면 배너를 유지한 채 +재시도 실패를 알립니다. + +--- + ## 위지윅 편집기 (G7Core.wysiwyg) > **engine-v1.11.0+** 추가 diff --git a/docs/frontend/security.md b/docs/frontend/security.md index 34d9d2f1..4c7bac54 100644 --- a/docs/frontend/security.md +++ b/docs/frontend/security.md @@ -203,12 +203,15 @@ HTML을 렌더링해야 하는 경우 (게시판 본문, 상품 설명 등) ** 레이아웃의 `scripts[].src` 와 `data_sources[].endpoint` 는 기본적으로 **same-origin 절대 경로**(`/` 로 시작)만 허용합니다. `//`(protocol-relative)·scheme 포함 외부 URL 은 원격 코드 로드 경로이므로 런타임 스크립트 로더가 차단합니다. -일부 확장은 외부 CDN 스크립트를 정당하게 사용합니다(예: CKEditor5 → `cdn.ckeditor.com`, Daum 우편번호 → `t1.daumcdn.net`). 이런 확장은 자신의 manifest 에 신뢰 호스트를 **선언**하고, 코어가 활성 확장 전수에서 이 목록을 집계해 `window.G7Config.trustedScriptHosts` 로 노출합니다. 런타임 로더·저장측 검증·정적 검사는 모두 이 목록에 속한 호스트만 예외로 허용합니다. +구동에 필요한 자산은 확장이 함께 담아 자체 제공하는 것이 원칙입니다. 자체 제공이 불가능한 경우 — 라이브러리가 아니라 그 회사 서버와 통신하는 **서비스 SDK**(예: Daum 우편번호 → `t1.daumcdn.net`) — 에만 외부 호스트를 씁니다. 이런 확장은 자신의 manifest 에 신뢰 호스트를 **선언**하고, 코어가 활성 확장 전수에서 이 목록을 집계해 `window.G7Config.trustedScriptHosts` 로 노출합니다. 런타임 로더·저장측 검증·정적 검사는 모두 이 목록에 속한 호스트만 예외로 허용합니다. ```json // 확장 manifest (module.json / plugin.json / template.json) { - "trusted_script_hosts": ["cdn.ckeditor.com"] + "trusted_script_hosts": ["t1.daumcdn.net"], + "trusted_script_hosts_reason": { + "t1.daumcdn.net": "Daum 이 운영하는 서비스 SDK 라 자체 호스팅해도 동작하지 않는다." + } } ``` diff --git a/docs/frontend/template-development.md b/docs/frontend/template-development.md index 4c988f6a..72f615ee 100644 --- a/docs/frontend/template-development.md +++ b/docs/frontend/template-development.md @@ -427,6 +427,27 @@ export default defineConfig({ --- +## 4-1. 운영자가 CSS·JS 를 덧붙이는 자리 (`custom/`) + +템플릿 소스(`src/styles/`)를 고치고 빌드하는 방법은 **템플릿 저작자**의 방법입니다. 운영자에게는 +부적합합니다 — Node.js 가 필요하고, 그렇게 넣은 파일은 다음 템플릿 업데이트에 사라집니다. +빌드 산출물(`dist/css/`)을 직접 고치는 것도 다음 빌드에 사라집니다. + +운영자는 활성 템플릿 디렉토리의 `custom/` 에 파일을 놓습니다. + +``` +templates/{템플릿-식별자}/custom/custom.css +``` + +- 빌드하지 않습니다. 파일을 놓으면 다음 요청부터 적용됩니다. +- 템플릿을 업데이트해도 이 디렉토리는 보존됩니다. +- 적용 순서는 **템플릿·확장 스타일보다 뒤**라서 재정의가 그대로 반영됩니다. +- 여러 파일을 놓으면 파일명 오름차순으로 적용됩니다(`10-`, `20-` 접두사로 순서를 정할 수 있습니다). +- 폰트·이미지 같은 파일도 같은 디렉토리에 두고 CSS 에서 상대 경로로 참조합니다. +- 순서를 바꾸거나 일부만 싣고 싶으면 `custom/assets.json` 에 선언합니다. + +모듈·플러그인도 같은 규약을 씁니다. 상세: [module-assets.md](../extension/module-assets.md) "사용자 추가 에셋". + ## 5. 템플릿 네이밍 규칙 ### 형식 diff --git a/docs/requirements.md b/docs/requirements.md index ffcdf11b..949eb9df 100644 --- a/docs/requirements.md +++ b/docs/requirements.md @@ -343,6 +343,19 @@ Composer 설치 방식을 선택할 때만 필요하다. --- +## 7-1. 오프라인·폐쇄망 동작 범위 + +화면 구동에 필요한 자산(아이콘·글꼴·편집기·코드 편집기·국기 아이콘·이미지 압축)은 모두 +설치본에 함께 담겨 사이트 자신의 서버에서 제공됩니다. 외부 인터넷에 나가지 못하는 환경에서도 +관리자·사용자 화면이 정상 동작합니다. + +**외부 연결이 필요한 유일한 기능은 주소 검색(우편번호)입니다.** 이 기능은 라이브러리가 아니라 +Daum 이 운영하는 서비스 SDK 를 쓰므로, 자체 호스팅해도 동작하지 않습니다. 연결하지 못하는 +환경에서는 우편번호·주소를 직접 입력할 수 있으며 안내가 표시됩니다. + +운영자가 별도로 설정한 외부 서비스(검색엔진 분석 도구 등)는 이 범위와 무관하게 그 설정을 +따릅니다. + ## 8. 호스팅 환경별 제한사항 ### 8.1 공유 호스팅 (Shared Hosting) diff --git a/docs/testing/e2e-testing.md b/docs/testing/e2e-testing.md index bd099c88..bf1b404a 100644 --- a/docs/testing/e2e-testing.md +++ b/docs/testing/e2e-testing.md @@ -104,6 +104,25 @@ spec 이 전부 실패한다. `getByText('전체회원수')` 처럼 한국어만 단언하는 곳은 물론이고, `getByRole('button', { name: /저장/ })` 같은 접근 가능한 이름 조회도 함께 깨진다. +### 브라우저 UA 고정 (`userAgent`) + +코어와 확장의 모든 config 은 `use.userAgent` 에 실제 데스크탑 Chrome UA 를 지정한다. + +Playwright 의 기본 UA 에는 `HeadlessChrome` 이 들어 있고, `SeoMiddleware` 의 봇 판정이 그것을 +검색엔진 크롤러로 본다. 그러면 공개 사용자 경로 요청이 SPA 가 아니라 **검색엔진용 정적 HTML** 을 +받는다 — `window.G7Core` 도 엔진 스크립트도 없는 화면이다. + +이 상태가 위험한 이유는 실패가 아니라 **통과**로 나타나기 때문이다. 서버가 심은 글꼴·아이콘은 +그대로 정상이라 "페이지가 잘 뜬다" 로 보이고, 정작 재려던 SPA 동작(테마 적용·핸들러 등록·확장 +번들 로드·상태 바인딩)은 한 번도 실행되지 않은 채 단언이 통과한다. 실측(2026-08-26)에서 +사용자 홈을 재던 spec 들이 전부 이 경로였다. + +봇 화면을 의도적으로 검증하는 spec 은 UA 가 아니라 `?_escaped_fragment_=` 로 그 경로를 유발하므로, +UA 를 실제 브라우저 값으로 고정해도 그 검증은 그대로 동작한다. + +측정으로 확인하려면 `typeof window.G7Core` 가 `'object'` 인지 본다 — `'undefined'` 면 SPA 가 아니라 +봇 화면을 재고 있는 것이다. + ### 실행 시 유의 (경험칙) | 항목 | 내용 | diff --git a/lang-packs/_bundled/g7-core-ja/CHANGELOG.md b/lang-packs/_bundled/g7-core-ja/CHANGELOG.md index 7109d3b3..2eeaa53e 100644 --- a/lang-packs/_bundled/g7-core-ja/CHANGELOG.md +++ b/lang-packs/_bundled/g7-core-ja/CHANGELOG.md @@ -4,6 +4,16 @@ 형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며, [Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다. +## [1.0.9] - 2026-08-25 + +### Added + +- 화면에 필요한 파일을 불러오지 못했을 때 표시되는 안내 문구의 일본어 번역을 추가했습니다 — 안내 제목, 여러 항목이 실패했을 때의 합산 문구, [다시 시도]·[닫기] 버튼과 재시도 실패 안내가 일본어 로케일에서 표시됩니다. +- 운영자가 덧붙인 CSS·JS·글꼴·이미지를 다루는 관리 화면의 일본어 번역을 추가했습니다 — 파일 목록과 본문 편집, 파일 올리기·삭제, 관리 대상 확장 선택, 권한이 없을 때의 안내가 일본어 로케일에서 표시됩니다. +- 레이아웃 편집기 툴바에서 운영자 추가 에셋을 잠시 끄고 켜는 항목의 일본어 번역을 추가했습니다 — 추가한 파일이 화면을 깨뜨렸을 때 그 파일 없이 화면을 다시 여는 안내가 함께 표시됩니다. +- 확장을 제거할 때 운영자가 넣어 둔 파일의 사본을 보관했다는 안내의 일본어 번역을 추가했습니다 — 모듈·플러그인·템플릿 제거 결과 화면에서 보관 경로가 일본어로 표시됩니다. +- 운영자 추가 에셋의 저장·올리기·삭제가 활동 로그에 남을 때 표시되는 문구의 일본어 번역을 추가했습니다. + ## [1.0.8] - 2026-08-24 ### Added diff --git a/lang-packs/_bundled/g7-core-ja/backend/ja/activity_log.php b/lang-packs/_bundled/g7-core-ja/backend/ja/activity_log.php index 31a53df8..07947198 100644 --- a/lang-packs/_bundled/g7-core-ja/backend/ja/activity_log.php +++ b/lang-packs/_bundled/g7-core-ja/backend/ja/activity_log.php @@ -206,6 +206,9 @@ return [ 'activity_log_index' => 'アクティビティログ一覧の閲覧', 'activity_log_delete' => 'アクティビティログ削除 (ID: :log_id)', 'activity_log_bulk_delete' => 'アクティビティログ一括削除 (:count件)', + 'custom_asset_save' => 'カスタム資産保存 (:identifier — :path)', + 'custom_asset_upload' => 'カスタム資産アップロード (:identifier — :path)', + 'custom_asset_delete' => 'カスタム資産削除 (:identifier — :path)', ], 'fields' => [ 'name' => '名前', diff --git a/lang-packs/_bundled/g7-core-ja/backend/ja/custom_assets.php b/lang-packs/_bundled/g7-core-ja/backend/ja/custom_assets.php new file mode 100644 index 00000000..e7323edc --- /dev/null +++ b/lang-packs/_bundled/g7-core-ja/backend/ja/custom_assets.php @@ -0,0 +1,30 @@ + [ + 'not_found' => 'ファイルが見つかりません: :path', + 'not_editable' => 'この形式(:extension)は本文を直接編集できません。ファイルを新しくアップロードして置き換えてください。', + 'too_large_to_edit' => 'ファイルが大きすぎるため、エディターで開くことができません。(最大 :limit バイト)', + 'read_failed' => 'ファイルを読み込めませんでした: :path', + 'write_failed' => 'ファイルを保存できませんでした: :path', + 'delete_failed' => 'ファイルを削除できませんでした: :path', + 'directory_failed' => 'ディレクトリを作成できませんでした: :path', + 'invalid_path' => '許可されていないパスです: :path', + 'invalid_extension_target' => 'ターゲット拡張が見つかりません: :identifier', + 'extension_not_allowed' => '許可されていないファイル形式です: :extension', + 'upload_too_large' => 'アップロードファイルが大きすぎます。(最大 :limit バイト)', + ], + 'validation' => [ + 'path_required' => 'ファイルパスを指定してください。', + 'content_present' => '本文フィールドが必要です。', + 'file_required' => 'アップロードするファイルを選択してください。', + 'file_invalid' => '有効なファイルではありません。', + 'file_mimes' => '許可されていないファイル形式です。(許可: :allowed)', + ], + 'messages' => [ + 'listed' => 'リストを読み込みました。', + 'saved' => '保存しました。', + 'uploaded' => 'ファイルをアップロードしました。', + 'deleted' => 'ファイルを削除しました。', + ], +]; diff --git a/lang-packs/_bundled/g7-core-ja/backend/ja/modules.php b/lang-packs/_bundled/g7-core-ja/backend/ja/modules.php index ca573afa..4e8e12f5 100644 --- a/lang-packs/_bundled/g7-core-ja/backend/ja/modules.php +++ b/lang-packs/_bundled/g7-core-ja/backend/ja/modules.php @@ -66,6 +66,7 @@ return [ 'confirm_question' => '本当に削除してもよろしいですか?', 'aborted' => 'モジュールの削除がキャンセルされました。', 'not_installed' => 'モジュール ":module" がインストールされていません。', + 'custom_preserved' => '運営者ファイル(:directory)を :archive に保管しました。', ], 'cache_clear' => [ 'clearing_all' => 'すべてのモジュールキャッシュを削除します...', diff --git a/lang-packs/_bundled/g7-core-ja/backend/ja/plugins.php b/lang-packs/_bundled/g7-core-ja/backend/ja/plugins.php index f034c34a..74608411 100644 --- a/lang-packs/_bundled/g7-core-ja/backend/ja/plugins.php +++ b/lang-packs/_bundled/g7-core-ja/backend/ja/plugins.php @@ -184,6 +184,7 @@ return [ 'confirm_question' => '本当に削除してもよろしいですか?', 'aborted' => 'プラグイン削除がキャンセルされました。', 'not_installed' => 'プラグイン ":plugin" はインストールされていません。', + 'custom_preserved' => '運営者ファイル(:directory)を:archiveに保管しました。', ], 'cache_clear' => [ 'clearing_all' => 'すべてのプラグインキャッシュを削除します...', diff --git a/lang-packs/_bundled/g7-core-ja/backend/ja/templates.php b/lang-packs/_bundled/g7-core-ja/backend/ja/templates.php index 9219c24e..6f6ea669 100644 --- a/lang-packs/_bundled/g7-core-ja/backend/ja/templates.php +++ b/lang-packs/_bundled/g7-core-ja/backend/ja/templates.php @@ -230,6 +230,7 @@ return [ 'layouts_deleted' => 'レイアウト:count個を削除しました', 'versions_deleted' => 'バージョン履歴:count個を削除しました', 'aborted' => '削除がキャンセルされました。', + 'custom_preserved' => '運営者ファイル(:directory)を:archiveに保管しました。', ], 'list' => [ 'no_templates' => '登録されたテンプレートがありません。', diff --git a/lang-packs/_bundled/g7-core-ja/frontend/ja.json b/lang-packs/_bundled/g7-core-ja/frontend/ja.json index 179baf2d..1858e66d 100644 --- a/lang-packs/_bundled/g7-core-ja/frontend/ja.json +++ b/lang-packs/_bundled/g7-core-ja/frontend/ja.json @@ -2,6 +2,9 @@ "core": { "errors": { "$partial": "partial/errors.json" + }, + "assets": { + "$partial": "partial/assets.json" } }, "layout_editor": { diff --git a/lang-packs/_bundled/g7-core-ja/frontend/partial/assets.json b/lang-packs/_bundled/g7-core-ja/frontend/partial/assets.json new file mode 100644 index 00000000..830d03b2 --- /dev/null +++ b/lang-packs/_bundled/g7-core-ja/frontend/partial/assets.json @@ -0,0 +1,8 @@ +{ + "load_failed": "{label}を読み込めませんでした。", + "load_failed_multiple": "{count}個の項目を読み込めませんでした。", + "retry": "再試行", + "retrying": "再試行中...", + "close": "閉じる", + "retry_failed": "再試行しましたが失敗しました。しばらく後に再度お試しください。" +} diff --git a/lang-packs/_bundled/g7-core-ja/frontend/partial/layout_editor.json b/lang-packs/_bundled/g7-core-ja/frontend/partial/layout_editor.json index 11123248..983cae01 100644 --- a/lang-packs/_bundled/g7-core-ja/frontend/partial/layout_editor.json +++ b/lang-packs/_bundled/g7-core-ja/frontend/partial/layout_editor.json @@ -35,7 +35,13 @@ "translations": "多言語", "data_sources": "データ", "reset": "初期化", - "switch_template": "別のテンプレートに切り替える" + "switch_template": "別のテンプレートに切り替える", + "custom_assets": "カスタムアセット", + "custom_assets_hint": "運営者が追加したCSS·JS·フォント·画像を管理します。", + "custom_assets_off": "カスタムアセット オフ", + "custom_assets_on": "カスタムアセット オン", + "custom_assets_off_hint": "運営者が追加したCSS·JSなしでこの画面を再度開きます。追加されたアセットが画面を破損した場合に使用します。", + "custom_assets_on_hint": "現在、運営者が追加したアセットはオフになっています。クリックして再度適用します。" }, "route_tree": { "panel_title": "画面/ルート", @@ -1357,5 +1363,26 @@ "invalid": "有効なJSON形式ではありません。", "must_be_object": "オブジェクト(JSON)形式である必要があります。例:{ \"名前\": 値 }", "invalid_keys": "値の名前は英文字で始まり、英文字・数字・_ のみ使用できます:{keys}" + }, + "custom_assets": { + "title": "カスタムアセット", + "close": "閉じる", + "loading": "読み込み中…", + "empty": "追加されたファイルがありません。以下にパスを入力して保存するか、ファイルをアップロードして開始してください。", + "forbidden": "カスタムアセットを管理する権限がありません。管理者に「カスタムアセット管理」権限をリクエストしてください。", + "new_path_placeholder": "例:10-overrides.css", + "path_label": "ファイルパス", + "content_label": "ファイル本文", + "new_file": "新しいファイル", + "save": "保存", + "upload": "ファイルアップロード", + "delete": "削除", + "delete_confirm": "このファイルを削除します。元に戻すことはできません。", + "binary_hint": "このフォーマット(:extension)は本文を直接編集できません。同じ名前で再度アップロードして置き換えてください。", + "apply_hint": "保存すると次の画面から適用されます。", + "target_label": "管理対象の拡張", + "type_template": "テンプレート", + "type_module": "モジュール", + "type_plugin": "プラグイン" } } diff --git a/lang-packs/_bundled/g7-core-ja/language-pack.json b/lang-packs/_bundled/g7-core-ja/language-pack.json index cb8bc8e2..eddb5bd1 100644 --- a/lang-packs/_bundled/g7-core-ja/language-pack.json +++ b/lang-packs/_bundled/g7-core-ja/language-pack.json @@ -12,7 +12,7 @@ "en": "G7 core Japanese language pack (bundled)", "ja": "G7 コア 日本語 言語パック(バンドル)" }, - "version": "1.0.8", + "version": "1.0.9", "license": "MIT", "scope": "core", "target_identifier": null, diff --git a/lang-packs/_bundled/g7-plugin-sirsoft-ckeditor5-ja/CHANGELOG.md b/lang-packs/_bundled/g7-plugin-sirsoft-ckeditor5-ja/CHANGELOG.md index 368a5374..bcb93dd3 100644 --- a/lang-packs/_bundled/g7-plugin-sirsoft-ckeditor5-ja/CHANGELOG.md +++ b/lang-packs/_bundled/g7-plugin-sirsoft-ckeditor5-ja/CHANGELOG.md @@ -4,6 +4,13 @@ 형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며, [Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다. +## [1.0.2] - 2026-08-25 + +### Added + +- 편집기를 불러오지 못했을 때 표시되는 안내 문구의 일본어 번역을 추가했습니다 — 임시 입력창으로 전환되었고 작성한 내용은 그대로 저장된다는 안내가 일본어 로케일에서 표시됩니다. +- 그 안내 배너에 표시되는 항목 이름(편집기·편집기 스타일)의 일본어 번역을 추가했습니다 — 여러 항목이 함께 실패했을 때 무엇이 실패했는지 일본어로 구분됩니다. + ## [1.0.1] - 2026-08-19 ### Added diff --git a/lang-packs/_bundled/g7-plugin-sirsoft-ckeditor5-ja/frontend/ja.json b/lang-packs/_bundled/g7-plugin-sirsoft-ckeditor5-ja/frontend/ja.json index d073d1d7..cb96e366 100644 --- a/lang-packs/_bundled/g7-plugin-sirsoft-ckeditor5-ja/frontend/ja.json +++ b/lang-packs/_bundled/g7-plugin-sirsoft-ckeditor5-ja/frontend/ja.json @@ -3,6 +3,11 @@ "data_source": { "settings": "エディター設定", "ckeditor5Uploads": "アップロード画像一覧" + }, + "asset": { + "label": "エディター", + "style_label": "エディタースタイル", + "fallback_notice": "エディターを読み込めませんでした。一時的な入力ウィンドウに切り替えました。作成した内容はそのまま保存されます。" } }, "settings": { diff --git a/lang-packs/_bundled/g7-plugin-sirsoft-ckeditor5-ja/language-pack.json b/lang-packs/_bundled/g7-plugin-sirsoft-ckeditor5-ja/language-pack.json index be35b069..22189b9c 100644 --- a/lang-packs/_bundled/g7-plugin-sirsoft-ckeditor5-ja/language-pack.json +++ b/lang-packs/_bundled/g7-plugin-sirsoft-ckeditor5-ja/language-pack.json @@ -12,7 +12,7 @@ "en": "G7 plugin (sirsoft-ckeditor5) Japanese language pack (bundled)", "ja": "G7 プラグイン (sirsoft-ckeditor5) 日本語 言語パック(バンドル)" }, - "version": "1.0.1", + "version": "1.0.2", "license": "MIT", "scope": "plugin", "target_identifier": "sirsoft-ckeditor5", diff --git a/lang-packs/_bundled/g7-plugin-sirsoft-daum_postcode-ja/CHANGELOG.md b/lang-packs/_bundled/g7-plugin-sirsoft-daum_postcode-ja/CHANGELOG.md new file mode 100644 index 00000000..510b7be6 --- /dev/null +++ b/lang-packs/_bundled/g7-plugin-sirsoft-daum_postcode-ja/CHANGELOG.md @@ -0,0 +1,17 @@ +# Changelog + +이 언어팩의 모든 주요 변경사항을 기록합니다. +형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며, +[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다. + +## [1.0.1] - 2026-08-25 + +### Added + +- 주소 검색을 불러오지 못했을 때 표시되는 안내 문구의 일본어 번역을 추가했습니다 — 주소를 직접 입력하라는 안내가 일본어 로케일에서 표시됩니다. + +## [1.0.0] - 2026-06-11 + +### Added + +- 다음 우편번호 플러그인(sirsoft-daum_postcode)의 일본어 번들 언어팩 초기 제공 diff --git a/lang-packs/_bundled/g7-plugin-sirsoft-daum_postcode-ja/frontend/ja.json b/lang-packs/_bundled/g7-plugin-sirsoft-daum_postcode-ja/frontend/ja.json index 22a407b8..5a4c37d9 100644 --- a/lang-packs/_bundled/g7-plugin-sirsoft-daum_postcode-ja/frontend/ja.json +++ b/lang-packs/_bundled/g7-plugin-sirsoft-daum_postcode-ja/frontend/ja.json @@ -19,7 +19,8 @@ "selected": "住所が選択されました。", "error": { "load_failed": "郵便番号サービスの読み込みに失敗しました。", - "search_failed": "住所検索に失敗しました。" + "search_failed": "住所検索に失敗しました。", + "sdk_unavailable": "住所検索を読み込めませんでした。住所を直接入力してください。" } }, "settings": { diff --git a/lang-packs/_bundled/g7-plugin-sirsoft-daum_postcode-ja/language-pack.json b/lang-packs/_bundled/g7-plugin-sirsoft-daum_postcode-ja/language-pack.json index c43b227a..0386dfa1 100644 --- a/lang-packs/_bundled/g7-plugin-sirsoft-daum_postcode-ja/language-pack.json +++ b/lang-packs/_bundled/g7-plugin-sirsoft-daum_postcode-ja/language-pack.json @@ -12,7 +12,7 @@ "en": "G7 plugin (sirsoft-daum_postcode) Japanese language pack (bundled)", "ja": "G7 プラグイン (sirsoft-daum_postcode) 日本語 言語パック(バンドル)" }, - "version": "1.0.0", + "version": "1.0.1", "license": "MIT", "scope": "plugin", "target_identifier": "sirsoft-daum_postcode", diff --git a/lang-packs/_bundled/g7-template-sirsoft-admin_basic-ja/CHANGELOG.md b/lang-packs/_bundled/g7-template-sirsoft-admin_basic-ja/CHANGELOG.md index 5209359c..af09df17 100644 --- a/lang-packs/_bundled/g7-template-sirsoft-admin_basic-ja/CHANGELOG.md +++ b/lang-packs/_bundled/g7-template-sirsoft-admin_basic-ja/CHANGELOG.md @@ -4,6 +4,13 @@ 형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며, [Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다. +## [1.0.8] - 2026-08-26 + +### Added + +- 확장 제거 시 표시되는 「운영자 파일 사본 보관」 안내 제목·설명의 일본어 번역을 추가했습니다 — 모듈·플러그인·템플릿 제거 결과 화면에서 보관 경로 안내가 일본어 로케일로 표시됩니다. +- 확장 제거가 끝난 뒤 결과 화면 제목(「모듈 제거 완료」·「플러그인 제거 완료」·「템플릿 제거 완료」)의 일본어 번역을 추가했습니다 — 종전에는 결과 화면인데 제목이 「제거 확인」으로 남아 있었습니다. + ## [1.0.7] - 2026-08-24 ### Added diff --git a/lang-packs/_bundled/g7-template-sirsoft-admin_basic-ja/frontend/partial/admin.json b/lang-packs/_bundled/g7-template-sirsoft-admin_basic-ja/frontend/partial/admin.json index 83ae197c..1db0d589 100644 --- a/lang-packs/_bundled/g7-template-sirsoft-admin_basic-ja/frontend/partial/admin.json +++ b/lang-packs/_bundled/g7-template-sirsoft-admin_basic-ja/frontend/partial/admin.json @@ -738,7 +738,10 @@ "no_modified_layouts": "修正されたレイアウトがありません。", "modified_layouts_list_title": "保持される修正レイアウト ({{count}}個)", "modified_layouts_keep_notice": "上記のレイアウトはアップデート後も現在の内容が保持されます。", - "modified_layouts_check_failed": "編集の確認ができませんでした。ネットワークの状態を確認してからもう一度試すか、安全に「編集を保持」を選択してください。" + "modified_layouts_check_failed": "編集の確認ができませんでした。ネットワークの状態を確認してからもう一度試すか、安全に「編集を保持」を選択してください。", + "preserved_title": "管理者ファイルコピー保存", + "preserved_desc": "削除前に custom/ ディレクトリのコピーを以下のパスに保存しました。拡張を再度インストール後、custom/ に移動することでそのまま再利用できます。", + "uninstall_done_title": "モジュール削除完了" }, "tabs": { "file_upload": "ファイル アップロード", @@ -944,7 +947,10 @@ "no_modified_layouts": "編集されたレイアウトがありません。", "modified_layouts_list_title": "維持される編集レイアウト({{count}}個)", "modified_layouts_keep_notice": "上記のレイアウトはアップデート後も現在の内容が維持されます。", - "modified_layouts_check_failed": "編集の確認ができませんでした。ネットワークの状態を確認してからもう一度試すか、安全に「編集を保持」を選択してください。" + "modified_layouts_check_failed": "編集の確認ができませんでした。ネットワークの状態を確認してからもう一度試すか、安全に「編集を保持」を選択してください。", + "preserved_title": "管理者ファイルコピー保存", + "preserved_desc": "削除前に custom/ ディレクトリのコピーを以下のパスに保存しました。拡張を再度インストール後、custom/ に移動することでそのまま再利用できます。", + "uninstall_done_title": "プラグイン削除完了" }, "tabs": { "file_upload": "ファイルアップロード", @@ -2213,7 +2219,10 @@ "lines": "行", "chars": "文字" }, - "modified_layouts_check_failed": "編集の確認ができませんでした。ネットワークの状態を確認してからもう一度試すか、安全に「編集を保持」を選択してください。" + "modified_layouts_check_failed": "編集の確認ができませんでした。ネットワークの状態を確認してからもう一度試すか、安全に「編集を保持」を選択してください。", + "preserved_title": "管理者ファイルコピー保存", + "preserved_desc": "削除前に custom/ ディレクトリのコピーを以下のパスに保存しました。拡張を再度インストール後、custom/ に移動することでそのまま再利用できます。", + "uninstall_done_title": "テンプレート削除完了" }, "tabs_install": { "file_upload": "ファイルアップロード", diff --git a/lang-packs/_bundled/g7-template-sirsoft-admin_basic-ja/language-pack.json b/lang-packs/_bundled/g7-template-sirsoft-admin_basic-ja/language-pack.json index 3d15faac..7c0c015d 100644 --- a/lang-packs/_bundled/g7-template-sirsoft-admin_basic-ja/language-pack.json +++ b/lang-packs/_bundled/g7-template-sirsoft-admin_basic-ja/language-pack.json @@ -12,7 +12,7 @@ "en": "G7 template (sirsoft-admin_basic) Japanese language pack (bundled)", "ja": "G7 テンプレート (sirsoft-admin_basic) 日本語 言語パック(バンドル)" }, - "version": "1.0.7", + "version": "1.0.8", "license": "MIT", "scope": "template", "target_identifier": "sirsoft-admin_basic", diff --git a/lang/en.json b/lang/en.json index e4de8e7c..948ea13f 100644 --- a/lang/en.json +++ b/lang/en.json @@ -2,6 +2,9 @@ "core": { "errors": { "$partial": "partial/en/errors.json" + }, + "assets": { + "$partial": "partial/en/assets.json" } }, "layout_editor": { diff --git a/lang/en/activity_log.php b/lang/en/activity_log.php index 7d7afb06..f5a7ecdc 100644 --- a/lang/en/activity_log.php +++ b/lang/en/activity_log.php @@ -244,6 +244,9 @@ return [ 'template_install_from_file' => 'Template installed from file', 'template_install_from_github' => 'Template installed from GitHub', 'template_refresh_layouts' => 'Template layouts refreshed (:template_name)', + 'custom_asset_save' => 'Custom asset saved (:identifier — :path)', + 'custom_asset_upload' => 'Custom asset uploaded (:identifier — :path)', + 'custom_asset_delete' => 'Custom asset deleted (:identifier — :path)', // Core update 'core_update_check' => 'Core update checked', diff --git a/lang/en/custom_assets.php b/lang/en/custom_assets.php new file mode 100644 index 00000000..46dfea4b --- /dev/null +++ b/lang/en/custom_assets.php @@ -0,0 +1,32 @@ + [ + 'not_found' => 'File not found: :path', + 'not_editable' => 'This file type (:extension) cannot be edited directly. Upload a replacement file instead.', + 'too_large_to_edit' => 'The file is too large to open in the editor. (limit: :limit bytes)', + 'read_failed' => 'Failed to read the file: :path', + 'write_failed' => 'Failed to save the file: :path', + 'delete_failed' => 'Failed to delete the file: :path', + 'directory_failed' => 'Failed to create the directory: :path', + 'invalid_path' => 'The path is not allowed: :path', + 'invalid_extension_target' => 'Target extension not found: :identifier', + 'extension_not_allowed' => 'File type not allowed: :extension', + 'upload_too_large' => 'The uploaded file is too large. (limit: :limit bytes)', + ], + + 'validation' => [ + 'path_required' => 'Please specify the file path.', + 'content_present' => 'The content field is required.', + 'file_required' => 'Please choose a file to upload.', + 'file_invalid' => 'The upload is not a valid file.', + 'file_mimes' => 'File type not allowed. (allowed: :allowed)', + ], + + 'messages' => [ + 'listed' => 'Loaded.', + 'saved' => 'Saved.', + 'uploaded' => 'File uploaded.', + 'deleted' => 'File deleted.', + ], +]; diff --git a/lang/en/modules.php b/lang/en/modules.php index d2d22da8..75f961d5 100644 --- a/lang/en/modules.php +++ b/lang/en/modules.php @@ -58,6 +58,7 @@ return [ 'permissions_deleted' => ':count permissions deleted', 'menus_deleted' => ':count menus deleted', 'layouts_deleted' => ':count layouts deleted', + 'custom_preserved' => 'Operator files (:directory) were archived to :archive.', 'confirm_prompt' => 'Are you sure you want to uninstall module ":module"?', 'confirm_details' => [ 'roles' => '- :count roles will be deleted.', diff --git a/lang/en/plugins.php b/lang/en/plugins.php index 784b315b..7cfdb9fe 100644 --- a/lang/en/plugins.php +++ b/lang/en/plugins.php @@ -172,6 +172,7 @@ return [ 'roles_deleted' => ':count roles deleted', 'permissions_deleted' => ':count permissions deleted', 'layouts_deleted' => ':count layouts deleted', + 'custom_preserved' => 'Operator files (:directory) were archived to :archive.', 'confirm_prompt' => 'Are you sure you want to uninstall plugin ":plugin"?', 'confirm_details' => [ 'roles' => '- :count roles will be deleted.', diff --git a/lang/en/templates.php b/lang/en/templates.php index 7ce43672..a1bfc128 100644 --- a/lang/en/templates.php +++ b/lang/en/templates.php @@ -258,6 +258,7 @@ return [ 'confirm_question' => 'Do you want to continue?', 'layouts_deleted' => ':count layout(s) deleted', 'versions_deleted' => ':count version(s) deleted', + 'custom_preserved' => 'Operator files (:directory) were archived to :archive.', 'aborted' => 'Uninstall aborted.', ], 'list' => [ diff --git a/lang/ko.json b/lang/ko.json index 59736b42..5fdac682 100644 --- a/lang/ko.json +++ b/lang/ko.json @@ -2,6 +2,9 @@ "core": { "errors": { "$partial": "partial/ko/errors.json" + }, + "assets": { + "$partial": "partial/ko/assets.json" } }, "layout_editor": { diff --git a/lang/ko/activity_log.php b/lang/ko/activity_log.php index 6e7452b0..4bd355ff 100644 --- a/lang/ko/activity_log.php +++ b/lang/ko/activity_log.php @@ -244,6 +244,9 @@ return [ 'template_install_from_file' => '파일에서 템플릿 설치', 'template_install_from_github' => 'GitHub에서 템플릿 설치', 'template_refresh_layouts' => '템플릿 레이아웃 갱신 (:template_name)', + 'custom_asset_save' => '커스텀 자산 저장 (:identifier — :path)', + 'custom_asset_upload' => '커스텀 자산 업로드 (:identifier — :path)', + 'custom_asset_delete' => '커스텀 자산 삭제 (:identifier — :path)', // 코어 업데이트 'core_update_check' => '코어 업데이트 확인', diff --git a/lang/ko/custom_assets.php b/lang/ko/custom_assets.php new file mode 100644 index 00000000..2153853b --- /dev/null +++ b/lang/ko/custom_assets.php @@ -0,0 +1,32 @@ + [ + 'not_found' => '파일을 찾을 수 없습니다: :path', + 'not_editable' => '이 형식(:extension)은 본문을 직접 편집할 수 없습니다. 파일을 새로 올려 교체해 주세요.', + 'too_large_to_edit' => '파일이 너무 커서 편집기에서 열 수 없습니다. (최대 :limit 바이트)', + 'read_failed' => '파일을 읽지 못했습니다: :path', + 'write_failed' => '파일을 저장하지 못했습니다: :path', + 'delete_failed' => '파일을 삭제하지 못했습니다: :path', + 'directory_failed' => '디렉토리를 만들지 못했습니다: :path', + 'invalid_path' => '허용되지 않는 경로입니다: :path', + 'invalid_extension_target' => '대상 확장을 찾을 수 없습니다: :identifier', + 'extension_not_allowed' => '허용되지 않는 파일 형식입니다: :extension', + 'upload_too_large' => '업로드 파일이 너무 큽니다. (최대 :limit 바이트)', + ], + + 'validation' => [ + 'path_required' => '파일 경로를 지정해 주세요.', + 'content_present' => '본문 필드가 필요합니다.', + 'file_required' => '올릴 파일을 선택해 주세요.', + 'file_invalid' => '올바른 파일이 아닙니다.', + 'file_mimes' => '허용되지 않는 파일 형식입니다. (허용: :allowed)', + ], + + 'messages' => [ + 'listed' => '목록을 불러왔습니다.', + 'saved' => '저장했습니다.', + 'uploaded' => '파일을 올렸습니다.', + 'deleted' => '파일을 삭제했습니다.', + ], +]; diff --git a/lang/ko/modules.php b/lang/ko/modules.php index 27b01520..ae3ff85f 100644 --- a/lang/ko/modules.php +++ b/lang/ko/modules.php @@ -58,6 +58,7 @@ return [ 'permissions_deleted' => ':count개 권한 삭제됨', 'menus_deleted' => ':count개 메뉴 삭제됨', 'layouts_deleted' => ':count개 레이아웃 삭제됨', + 'custom_preserved' => '운영자 파일(:directory)을 :archive 에 보관했습니다.', 'confirm_prompt' => '모듈 ":module"을(를) 삭제하시겠습니까?', 'confirm_details' => [ 'roles' => '- :count개의 역할이 삭제됩니다.', diff --git a/lang/ko/plugins.php b/lang/ko/plugins.php index 1d25074d..053249c3 100644 --- a/lang/ko/plugins.php +++ b/lang/ko/plugins.php @@ -172,6 +172,7 @@ return [ 'roles_deleted' => ':count개 역할 삭제됨', 'permissions_deleted' => ':count개 권한 삭제됨', 'layouts_deleted' => ':count개 레이아웃 삭제됨', + 'custom_preserved' => '운영자 파일(:directory)을 :archive 에 보관했습니다.', 'confirm_prompt' => '플러그인 ":plugin"을(를) 삭제하시겠습니까?', 'confirm_details' => [ 'roles' => '- :count개의 역할이 삭제됩니다.', diff --git a/lang/ko/templates.php b/lang/ko/templates.php index 72435440..a93e6f42 100644 --- a/lang/ko/templates.php +++ b/lang/ko/templates.php @@ -258,6 +258,7 @@ return [ 'confirm_question' => '계속하시겠습니까?', 'layouts_deleted' => '레이아웃 :count개 삭제됨', 'versions_deleted' => '버전 히스토리 :count개 삭제됨', + 'custom_preserved' => '운영자 파일(:directory)을 :archive 에 보관했습니다.', 'aborted' => '삭제가 취소되었습니다.', ], 'list' => [ diff --git a/lang/partial/en/assets.json b/lang/partial/en/assets.json new file mode 100644 index 00000000..03bbae21 --- /dev/null +++ b/lang/partial/en/assets.json @@ -0,0 +1,8 @@ +{ + "load_failed": "Could not load {label}.", + "load_failed_multiple": "Could not load {count} items.", + "retry": "Retry", + "retrying": "Retrying...", + "close": "Close", + "retry_failed": "The retry failed. Please try again in a moment." +} diff --git a/lang/partial/en/layout_editor.json b/lang/partial/en/layout_editor.json index 01a3c412..e85c12b6 100644 --- a/lang/partial/en/layout_editor.json +++ b/lang/partial/en/layout_editor.json @@ -35,7 +35,13 @@ "translations": "Translations", "data_sources": "Data", "reset": "Reset", - "switch_template": "Switch to another template" + "switch_template": "Switch to another template", + "custom_assets": "Custom assets", + "custom_assets_hint": "Manage operator-added CSS, JS, fonts and images.", + "custom_assets_off": "Disable custom assets", + "custom_assets_on": "Enable custom assets", + "custom_assets_off_hint": "Reopen this screen without operator-added CSS/JS. Use it when an added asset breaks the screen.", + "custom_assets_on_hint": "Operator-added assets are currently disabled. Click to apply them again." }, "route_tree": { "panel_title": "Screens / Routes", @@ -106,6 +112,27 @@ "extension_gated_desc_with_states": "The area this extension injects into only appears in a specific screen state. Switch to that state using the state selector at the top to edit it.", "slot_area_label": "Content area" }, + "custom_assets": { + "target_label": "Target extension", + "type_template": "Template", + "type_module": "Module", + "type_plugin": "Plugin", + "title": "Custom assets", + "close": "Close", + "loading": "Loading…", + "empty": "No files yet. Type a path below and save, or upload a file to start.", + "forbidden": "You do not have permission to manage custom assets. Ask an administrator for the “Manage Custom Assets” permission.", + "new_path_placeholder": "e.g. 10-overrides.css", + "path_label": "File path", + "content_label": "File content", + "new_file": "New file", + "save": "Save", + "upload": "Upload file", + "delete": "Delete", + "delete_confirm": "This file will be deleted. This cannot be undone.", + "binary_hint": "This file type (:extension) cannot be edited directly. Upload a replacement with the same name.", + "apply_hint": "Saved changes apply from the next page load." + }, "version_history": { "title": "Version history", "close": "Close", diff --git a/lang/partial/ko/assets.json b/lang/partial/ko/assets.json new file mode 100644 index 00000000..a4edbfb6 --- /dev/null +++ b/lang/partial/ko/assets.json @@ -0,0 +1,8 @@ +{ + "load_failed": "{label}을(를) 불러오지 못했습니다.", + "load_failed_multiple": "{count}개 항목을 불러오지 못했습니다.", + "retry": "다시 시도", + "retrying": "다시 시도 중...", + "close": "닫기", + "retry_failed": "다시 시도했지만 실패했습니다. 잠시 후 다시 시도해 주세요." +} diff --git a/lang/partial/ko/layout_editor.json b/lang/partial/ko/layout_editor.json index 9f2f7f27..ee8b22ec 100644 --- a/lang/partial/ko/layout_editor.json +++ b/lang/partial/ko/layout_editor.json @@ -35,7 +35,13 @@ "translations": "다국어", "data_sources": "데이터", "reset": "초기화", - "switch_template": "다른 템플릿으로 전환" + "switch_template": "다른 템플릿으로 전환", + "custom_assets": "커스텀 자산", + "custom_assets_hint": "운영자가 추가한 CSS·JS·폰트·이미지를 관리합니다.", + "custom_assets_off": "커스텀 자산 끄기", + "custom_assets_on": "커스텀 자산 켜기", + "custom_assets_off_hint": "운영자가 추가한 CSS·JS 없이 이 화면을 다시 엽니다. 추가 자산이 화면을 망가뜨렸을 때 씁니다.", + "custom_assets_on_hint": "지금은 운영자 추가 자산이 꺼져 있습니다. 눌러서 다시 적용합니다." }, "route_tree": { "panel_title": "화면 / 라우트", @@ -106,6 +112,27 @@ "extension_gated_desc_with_states": "이 확장이 들어가는 영역은 특정 화면 상태에서만 나타납니다. 상단의 상태 선택에서 해당 상태로 바꾸면 편집할 수 있습니다.", "slot_area_label": "콘텐츠 영역" }, + "custom_assets": { + "target_label": "관리 대상 확장", + "type_template": "템플릿", + "type_module": "모듈", + "type_plugin": "플러그인", + "title": "커스텀 자산", + "close": "닫기", + "loading": "불러오는 중…", + "empty": "추가한 파일이 없습니다. 아래에 경로를 적고 저장하거나, 파일을 올려 시작하세요.", + "forbidden": "커스텀 자산을 관리할 권한이 없습니다. 관리자에게 «커스텀 자산 관리» 권한을 요청해 주세요.", + "new_path_placeholder": "예: 10-overrides.css", + "path_label": "파일 경로", + "content_label": "파일 본문", + "new_file": "새 파일", + "save": "저장", + "upload": "파일 올리기", + "delete": "삭제", + "delete_confirm": "이 파일을 삭제합니다. 되돌릴 수 없습니다.", + "binary_hint": "이 형식(:extension)은 본문을 직접 편집할 수 없습니다. 같은 이름으로 다시 올려 교체하세요.", + "apply_hint": "저장하면 다음 화면부터 적용됩니다." + }, "version_history": { "title": "버전 기록", "close": "닫기", diff --git a/modules/_bundled/sirsoft-board/tests/Playwright/playwright.config.ts b/modules/_bundled/sirsoft-board/tests/Playwright/playwright.config.ts index 6de7748f..71c8acf3 100644 --- a/modules/_bundled/sirsoft-board/tests/Playwright/playwright.config.ts +++ b/modules/_bundled/sirsoft-board/tests/Playwright/playwright.config.ts @@ -64,6 +64,18 @@ export default defineConfig({ ['list'], ], use: { + // 실제 브라우저 UA 를 지정한다. + // + // Playwright 기본 UA 에는 `HeadlessChrome` 이 들어 있어 `SeoMiddleware` 의 봇 판정에 + // 걸린다. 그러면 공개 사용자 경로 요청이 SPA 가 아니라 **검색엔진용 정적 HTML** 을 + // 받는다 — `window.G7Core` 도 엔진 스크립트도 없는 화면이다. 그 상태에서도 서버가 + // 심은 글꼴·아이콘은 정상이라 "페이지가 잘 뜬다" 로 보이고, 정작 재려던 SPA 동작 + // (테마 적용·핸들러·확장 번들 로드)은 한 번도 실행되지 않은 채 통과한다. + // + // 봇 경로를 의도적으로 재는 spec 은 UA 가 아니라 `?_escaped_fragment_=` 로 유발하므로 + // 여기서 실제 UA 를 고정해도 그 검증은 그대로 동작한다. + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36', baseURL: resolveBaseUrl(), // spec 이 한국어 화면 문구를 단언하므로 로케일을 고정한다. // 로케일 우선순위는 localStorage g7_locale → 서버 응답값 → 'ko' 이고, 서버값은 미인증 diff --git a/modules/_bundled/sirsoft-ecommerce/tests/Feature/Http/Controllers/Admin/EcommerceSettingsSeoCacheInvalidationTest.php b/modules/_bundled/sirsoft-ecommerce/tests/Feature/Http/Controllers/Admin/EcommerceSettingsSeoCacheInvalidationTest.php index b202eb21..811795e9 100644 --- a/modules/_bundled/sirsoft-ecommerce/tests/Feature/Http/Controllers/Admin/EcommerceSettingsSeoCacheInvalidationTest.php +++ b/modules/_bundled/sirsoft-ecommerce/tests/Feature/Http/Controllers/Admin/EcommerceSettingsSeoCacheInvalidationTest.php @@ -2,6 +2,7 @@ namespace Modules\Sirsoft\Ecommerce\Tests\Feature\Http\Controllers\Admin; +use App\Extension\HookListenerRegistrar; use App\Extension\HookManager; use App\Listeners\CoreActivityLogListener; use App\Models\User; @@ -47,6 +48,19 @@ class EcommerceSettingsSeoCacheInvalidationTest extends ModuleTestCase 'sirsoft-ecommerce.settings.update', ]); + // 모듈 훅 리스너는 부팅 시점의 `getActiveModuleIdentifiers()` 가 이 모듈을 활성으로 + // 봐야 등록된다. 그런데 그 목록은 빈 결과를 캐시하지 않고(빈 값이 굳으면 모든 확장이 + // 꺼진 것처럼 동작하므로 의도된 설계다), 모듈 등록 행은 부팅 **이후** setUp 에서 + // 만들어진다. 그래서 확장 상태 캐시가 비어 있는 채로 부팅하면 이 모듈이 비활성으로 + // 보여 리스너가 조용히 등록되지 않는다 — 예외도 로그도 남지 않고, 훅만 발화하지 + // 않아 "무효화가 수행되지 않았다" 로만 나타난다. + // + // 앞선 테스트가 그 캐시를 비웠는지에 따라 결과가 갈리므로(실행 순서 의존) 이 + // 테스트가 스스로 리스너 등록을 보장한다. 손으로 addAction 하지 않고 실제 등록 + // 경로(`HookListenerRegistrar`)를 태워 큐 래핑·우선순위 계약까지 그대로 재현한다. + // 부팅이 이미 등록했다면 프로세스 내 중복 등록 가드가 이 호출을 skip 한다. + HookListenerRegistrar::register(SeoSettingsCacheListener::class, 'sirsoft-ecommerce'); + $this->received = []; HookManager::addAction('core.module_settings.after_save', function (...$args) { $this->received[] = $args; diff --git a/modules/_bundled/sirsoft-ecommerce/tests/Playwright/playwright.config.ts b/modules/_bundled/sirsoft-ecommerce/tests/Playwright/playwright.config.ts index 25ce1451..fb8a0e1b 100644 --- a/modules/_bundled/sirsoft-ecommerce/tests/Playwright/playwright.config.ts +++ b/modules/_bundled/sirsoft-ecommerce/tests/Playwright/playwright.config.ts @@ -75,6 +75,18 @@ export default defineConfig({ ['list'], ], use: { + // 실제 브라우저 UA 를 지정한다. + // + // Playwright 기본 UA 에는 `HeadlessChrome` 이 들어 있어 `SeoMiddleware` 의 봇 판정에 + // 걸린다. 그러면 공개 사용자 경로 요청이 SPA 가 아니라 **검색엔진용 정적 HTML** 을 + // 받는다 — `window.G7Core` 도 엔진 스크립트도 없는 화면이다. 그 상태에서도 서버가 + // 심은 글꼴·아이콘은 정상이라 "페이지가 잘 뜬다" 로 보이고, 정작 재려던 SPA 동작 + // (테마 적용·핸들러·확장 번들 로드)은 한 번도 실행되지 않은 채 통과한다. + // + // 봇 경로를 의도적으로 재는 spec 은 UA 가 아니라 `?_escaped_fragment_=` 로 유발하므로 + // 여기서 실제 UA 를 고정해도 그 검증은 그대로 동작한다. + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36', baseURL: resolveBaseUrl(), // spec 이 한국어 화면 문구를 단언하므로 로케일을 고정한다. // 로케일 우선순위는 localStorage g7_locale → 서버 응답값 → 'ko' 이고, 서버값은 미인증 diff --git a/modules/_bundled/sirsoft-ecommerce/vite.config.ts b/modules/_bundled/sirsoft-ecommerce/vite.config.ts index 8c0dddf6..acbce73e 100644 --- a/modules/_bundled/sirsoft-ecommerce/vite.config.ts +++ b/modules/_bundled/sirsoft-ecommerce/vite.config.ts @@ -17,7 +17,7 @@ export default defineConfig({ // 빌드 출력 설정 outDir: 'dist', - emptyOutDir: true, + emptyOutDir: false, // 동봉 vendor 보존 — 산출물 정리는 빌드 커맨드가 한다 // 소스맵 생성 // 배포용 빌드(--production)는 G7_BUILD_SOURCEMAP=0 을 주입해 소스맵을 생성하지 않는다. diff --git a/modules/_bundled/sirsoft-page/tests/Playwright/playwright.config.ts b/modules/_bundled/sirsoft-page/tests/Playwright/playwright.config.ts index 702867dd..46a47069 100644 --- a/modules/_bundled/sirsoft-page/tests/Playwright/playwright.config.ts +++ b/modules/_bundled/sirsoft-page/tests/Playwright/playwright.config.ts @@ -75,6 +75,18 @@ export default defineConfig({ ['list'], ], use: { + // 실제 브라우저 UA 를 지정한다. + // + // Playwright 기본 UA 에는 `HeadlessChrome` 이 들어 있어 `SeoMiddleware` 의 봇 판정에 + // 걸린다. 그러면 공개 사용자 경로 요청이 SPA 가 아니라 **검색엔진용 정적 HTML** 을 + // 받는다 — `window.G7Core` 도 엔진 스크립트도 없는 화면이다. 그 상태에서도 서버가 + // 심은 글꼴·아이콘은 정상이라 "페이지가 잘 뜬다" 로 보이고, 정작 재려던 SPA 동작 + // (테마 적용·핸들러·확장 번들 로드)은 한 번도 실행되지 않은 채 통과한다. + // + // 봇 경로를 의도적으로 재는 spec 은 UA 가 아니라 `?_escaped_fragment_=` 로 유발하므로 + // 여기서 실제 UA 를 고정해도 그 검증은 그대로 동작한다. + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36', baseURL: resolveBaseUrl(), // spec 이 한국어 화면 문구를 단언하므로 로케일을 고정한다. // 로케일 우선순위는 localStorage g7_locale → 서버 응답값 → 'ko' 이고, 서버값은 미인증 diff --git a/package.json b/package.json index 715e8545..95087697 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,9 @@ "test:coverage": "vitest run --coverage", "test:e2e": "playwright test", "test:e2e:smoke": "playwright test --grep @smoke", - "test:e2e:ui": "playwright test --ui" + "test:e2e:ui": "playwright test --ui", + "build:core-devdashboard": "vite build --config vite.config.devdashboard.js", + "build:core-devdashboard-watch": "vite build --config vite.config.devdashboard.js --watch" }, "devDependencies": { "@laravel/echo-react": "^2.2.6", diff --git a/playwright.config.ts b/playwright.config.ts index 3d9069b9..17ef7bce 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -76,6 +76,18 @@ export default defineConfig({ ['list'], ], use: { + // 실제 브라우저 UA 를 지정한다. + // + // Playwright 기본 UA 에는 `HeadlessChrome` 이 들어 있어 `SeoMiddleware` 의 봇 판정에 + // 걸린다. 그러면 공개 사용자 경로 요청이 SPA 가 아니라 **검색엔진용 정적 HTML** 을 + // 받는다 — `window.G7Core` 도 엔진 스크립트도 없는 화면이다. 그 상태에서도 서버가 + // 심은 글꼴·아이콘은 정상이라 "페이지가 잘 뜬다" 로 보이고, 정작 재려던 SPA 동작 + // (테마 적용·핸들러·확장 번들 로드)은 한 번도 실행되지 않은 채 통과한다. + // + // 봇 경로를 의도적으로 재는 spec 은 UA 가 아니라 `?_escaped_fragment_=` 로 유발하므로 + // 여기서 실제 UA 를 고정해도 그 검증은 그대로 동작한다. + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36', baseURL: resolveBaseUrl(), // spec 이 한국어 화면 문구를 단언하므로 로케일을 고정한다. // 로케일 우선순위는 localStorage g7_locale → 서버 응답값 → 'ko' 이고, 서버값은 미인증 diff --git a/plugins/_bundled/sirsoft-ckeditor5/CHANGELOG.md b/plugins/_bundled/sirsoft-ckeditor5/CHANGELOG.md index 6cd71ec7..92ce7335 100644 --- a/plugins/_bundled/sirsoft-ckeditor5/CHANGELOG.md +++ b/plugins/_bundled/sirsoft-ckeditor5/CHANGELOG.md @@ -4,6 +4,19 @@ 형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며, [Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다. +## [1.0.3] - 2026-08-25 + +### Added + +- CKEditor 5 본체·스타일·번역 파일을 플러그인에 함께 담았습니다. 이제 외부 CDN 에 연결하지 않고 사이트 자신의 서버에서 불러오므로, 폐쇄망이나 외부 접속이 제한된 환경에서도 에디터가 동작합니다. +- 에디터를 불러오지 못한 경우 안내와 함께 임시 입력창으로 자동 전환됩니다. 작성한 내용은 그대로 저장되고, 이미 저장된 글을 수정할 때는 기존 본문이 임시 입력창에 그대로 실립니다. [다시 시도] 로 편집기를 되살리면 입력해 둔 내용이 그대로 이어집니다. + +### Fixed + +- 관리자 화면에서 글을 수정하다 다른 글의 수정 화면으로 곧바로 옮기면 편집기에 이전 글의 본문이 그대로 남아 있던 문제를 고쳤습니다. 그 상태에서 글자를 입력하면 저장 시 본문이 이전 글의 것으로 덮어써질 수 있었습니다. +- 에디터 스타일과 본문 스타일을 불러오지 못했을 때 아무 표시 없이 서식만 깨지던 문제를 고쳤습니다. 이제 다시 시도한 뒤에도 실패하면 화면에 알립니다. +- 번역 파일을 불러오지 못하면 아무 기록 없이 영어로 표시되던 동작에 경고 기록을 남기고, 일시적인 실패는 다시 시도합니다. + ## [1.0.2] - 2026-08-19 ### Security diff --git a/plugins/_bundled/sirsoft-ckeditor5/LICENSE b/plugins/_bundled/sirsoft-ckeditor5/LICENSE index b9b08f86..5f00d411 100644 --- a/plugins/_bundled/sirsoft-ckeditor5/LICENSE +++ b/plugins/_bundled/sirsoft-ckeditor5/LICENSE @@ -44,4 +44,17 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. + +## 동봉된 제3자 소프트웨어 + +이 플러그인은 아래 소프트웨어를 함께 배포합니다. 각 소프트웨어는 원저작자의 라이선스를 +그대로 따르며, 위 MIT 라이선스는 이 플러그인 자신의 코드에만 적용됩니다. + +| 소프트웨어 | 버전 | 라이선스 | 경로 | +| --- | --- | --- | --- | +| CKEditor 5 | 43.3.1 | GPL-2.0-or-later | `dist/vendor/ckeditor5/43.3.1/` | + +원본 라이선스 전문은 `dist/vendor/ckeditor5/43.3.1/LICENSE.md` 에 수정 없이 포함되어 +있습니다. 동봉본은 배포처(npm `ckeditor5@43.3.1`)의 파일이며, 참조하는 소스맵 파일을 +배포에 포함하지 않으므로 각 파일 끝의 `sourceMappingURL` 주석 한 줄만 제거했습니다. diff --git a/plugins/_bundled/sirsoft-ckeditor5/components.json b/plugins/_bundled/sirsoft-ckeditor5/components.json index 8d2e4e45..d4b60775 100644 --- a/plugins/_bundled/sirsoft-ckeditor5/components.json +++ b/plugins/_bundled/sirsoft-ckeditor5/components.json @@ -1,7 +1,7 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", "identifier": "sirsoft-ckeditor5", - "version": "1.0.2", + "version": "1.0.3", "components": { "basic": [], "composite": [], diff --git a/plugins/_bundled/sirsoft-ckeditor5/composer.json b/plugins/_bundled/sirsoft-ckeditor5/composer.json index 1c74f925..b964f3f4 100644 --- a/plugins/_bundled/sirsoft-ckeditor5/composer.json +++ b/plugins/_bundled/sirsoft-ckeditor5/composer.json @@ -2,7 +2,7 @@ "name": "plugins/sirsoft-ckeditor5", "description": "CKEditor 5 WYSIWYG Editor Plugin for Gnuboard7 platform", "type": "library", - "version": "1.0.2", + "version": "1.0.3", "authors": [ { "name": "sirsoft", diff --git a/plugins/_bundled/sirsoft-ckeditor5/dist/js/plugin.iife.js b/plugins/_bundled/sirsoft-ckeditor5/dist/js/plugin.iife.js index 474882bc..6466b829 100644 --- a/plugins/_bundled/sirsoft-ckeditor5/dist/js/plugin.iife.js +++ b/plugins/_bundled/sirsoft-ckeditor5/dist/js/plugin.iife.js @@ -1,4 +1,4 @@ -var SirsoftCkeditor5=function(G){"use strict";const E=new Map,Y="https://cdn.ckeditor.com/ckeditor5/43.3.1/ckeditor5.css",Z="https://cdn.ckeditor.com/ckeditor5/43.3.1/translations",N="ckeditor5-cdn-css",H="ckeditor5-dark-override",D="ckeditor5-tab-style",O={minimal:["bold","italic","underline","|","link","uploadImage","|","undo","redo"],standard:["heading","|","bold","italic","underline","strikethrough","|","alignment","|","link","blockQuote","|","bulletedList","numberedList","indent","outdent","|","insertTable","uploadImage","|","undo","redo"],full:["heading","|","fontSize","fontColor","fontBackgroundColor","|","bold","italic","underline","strikethrough","|","alignment","|","link","blockQuote","insertTable","uploadImage","mediaEmbed","horizontalLine","|","bulletedList","numberedList","indent","outdent","|","codeBlock","sourceEditing","|","undo","redo"]};function R(t){if(t==="en")return Promise.resolve();const o=`ckeditor5-translations-${t}`;return document.getElementById(o)?Promise.resolve():new Promise(e=>{const r=document.createElement("script");r.id=o,r.src=`${Z}/${t}.umd.js`,r.onload=()=>e(),r.onerror=()=>e(),document.head.appendChild(r)})}function K(){if(document.getElementById(N))return;const t=document.createElement("link");t.id=N,t.rel="stylesheet",t.href=Y,document.head.appendChild(t)}function tt(){if(document.getElementById(D))return;const t=document.createElement("style");t.id=D,t.textContent=` +var SirsoftCkeditor5=function(D){"use strict";const E=new Map;let Z=!1;function _t(){return Z}function K(t){Z=t}const O=new Map;function tt(t,o){const e=O.get(t)??[];e.push(o),O.set(t,e)}function et(t){(O.get(t)??[]).forEach(o=>{try{o.stop()}catch{}}),O.delete(t)}const St=400,vt=1e4;function ot(t,o){const{name:e,locale:n,multilingual:r}=o;let l=location.pathname,i=null,s=!1,k=null,c=0;const a=()=>{const u=window.G7Core?.state?.getLocal?.()?.form;if(!u||!e)return;const f=r?u[e]?.[n]:u[e];return typeof f=="string"?f:void 0},b=window.setInterval(()=>{let d;try{d=t.getData()}catch{window.clearInterval(b);return}location.pathname!==l&&(l=location.pathname,i=null,s=!0,c=Date.now(),k=d);const u=a();if(u!==void 0){if(s){if(u===k){Date.now()-c>vt&&(s=!1,k=null);return}if(u!==d){K(!0);try{t.setData(u)}finally{K(!1)}}s=!1,k=null,i=u;return}if(u===i||u===d){i=u;return}}},St);return{shouldEmit:()=>!s,noteEmitted:d=>{i=d},stop:()=>window.clearInterval(b)}}const Et="43.3.1",F="sirsoft-ckeditor5",H=`dist/vendor/ckeditor5/${Et}`,q="ckeditor5-vendor-css";function V(){const t=window?.G7Core?.asset;if(!t||typeof t.plugin!="function")throw new Error("G7Core.asset is unavailable — core 7.0.10 or later is required to resolve bundled CKEditor5 assets");return t}function xt(){return V().plugin(F,`${H}/ckeditor5.umd.js`)}function nt(){return V().plugin(F,`${H}/ckeditor5.css`)}function Lt(t){return V().plugin(F,`${H}/translations/${t}.umd.js`)}const T="data-ckeditor5-fallback",W=new WeakMap;function j(t,o){const e=window.G7Core;if(!e?.state?.setLocal||!t)return;const n={[`form.${t}_mode`]:"text",hasChanges:!0};if(typeof o=="string")n[`form.${t}`]=o;else for(const[r,l]of Object.entries(o))n[`form.${t}.${r}`]=l;e.state.setLocal(n,{render:!1,selfManaged:!0})}function R(t){const{container:o,name:e,height:n,readOnly:r,placeholder:l,multilingual:i}=t;if(o.querySelector(`[${T}]`))return;o.innerHTML="";const s=i?t.locales??[]:[],k=t.activeLocale??s[0]??"",c=i?{...t.contentMap??{}}:{"":t.initialContent??""},a=document.createElement("textarea");a.setAttribute(T,"1"),a.name=e,a.readOnly=r,a.placeholder=l??"",a.style.cssText=["width:100%",`height:${n}px`,"padding:12px","border:1px solid #d1d5db","border-radius:6px","font-family:inherit","font-size:14px","line-height:1.6","resize:vertical","box-sizing:border-box"].join(";");let b=k;if(i){const d=document.createElement("div");d.className="ckeditor5-locale-tabs";const u=()=>{d.querySelectorAll("button").forEach(f=>{const m=f.dataset.locale??"",w=m===b;f.classList.toggle("is-active",w);const S=(c[m]??"").trim()!=="",v=f.querySelector("[data-check]");v&&(v.style.display=S?"":"none")})};s.forEach((f,m)=>{const w=document.createElement("button");w.type="button",w.dataset.locale=f,m===0&&w.classList.add("is-default"),w.textContent=f.toUpperCase();const S=document.createElement("span");S.dataset.check="1",S.textContent="✓",S.style.display="none",w.appendChild(S),w.addEventListener("click",()=>{c[b]=a.value,b=f,a.value=c[f]??"",a.dataset.locale=f,j(e,c),u()}),d.appendChild(w)}),o.appendChild(d),a.dataset.locale=b,a.value=c[b]??"",u(),a.addEventListener("input",()=>{c[b]=a.value,j(e,c),u()})}else a.value=c[""]??"",a.addEventListener("input",()=>{c[""]=a.value,j(e,a.value)});o.appendChild(a),W.set(o,{multilingual:i,values:c,activeLocale:b}),j(e,i?c:c[""]??"")}function $t(t){const o=W.get(t);if(!o)return null;const e=t.querySelector(`textarea[${T}]`);return e&&(o.values[o.multilingual?e.dataset.locale??o.activeLocale:""]=e.value),o.multilingual?{...o.values}:o.values[""]??""}function It(t){return t.querySelector(`[${T}]`)?(t.innerHTML="",W.delete(t),!0):!1}const rt="ckeditor5-dark-override",lt="ckeditor5-tab-style",ct={minimal:["bold","italic","underline","|","link","uploadImage","|","undo","redo"],standard:["heading","|","bold","italic","underline","strikethrough","|","alignment","|","link","blockQuote","|","bulletedList","numberedList","indent","outdent","|","insertTable","uploadImage","|","undo","redo"],full:["heading","|","fontSize","fontColor","fontBackgroundColor","|","bold","italic","underline","strikethrough","|","alignment","|","link","blockQuote","insertTable","uploadImage","mediaEmbed","horizontalLine","|","bulletedList","numberedList","indent","outdent","|","codeBlock","sourceEditing","|","undo","redo"]};function Gt(t){if(t==="en")return Promise.resolve();const o=`ckeditor5-translations-${t}`;if(document.getElementById(o))return Promise.resolve();const e=window?.G7Core?.asset?.loadScript;return new Promise(n=>{let r;try{r=Lt(t)}catch(i){console.warn("[ckeditor5] 번역 URL 을 만들지 못했습니다 (영어로 동작):",i),n();return}if(typeof e=="function"){e(r,{id:o},{label:`ckeditor5 translations: ${t}`,retries:1}).catch(i=>{console.warn(`[ckeditor5] 번역 로드 실패 (${t}) — 영어로 동작합니다:`,i)}).then(()=>n());return}const l=document.createElement("script");l.id=o,l.src=r,l.onload=()=>n(),l.onerror=()=>{console.warn(`[ckeditor5] 번역 로드 실패 (${t}) — 영어로 동작합니다.`),n()},document.head.appendChild(l)})}async function at(){if(document.getElementById(q))return;const t=window?.G7Core?.asset?.loadStylesheet;let o;try{o=nt()}catch(e){console.warn("[ckeditor5] CSS URL 을 만들지 못했습니다:",e);return}if(typeof t!="function"){const e=document.createElement("link");e.id=q,e.rel="stylesheet",e.href=o,document.head.appendChild(e);return}try{await t(o,{id:q},{label:"ckeditor5 CSS"})}catch(e){console.warn("[ckeditor5] CSS 로드 실패:",e),N("ckeditor5-css",x("editor.asset.style_label","편집기 스타일"),()=>at())}}async function it(){if(window.CKEDITOR)return!0;const t=window?.G7Core?.asset?.loadScript;if(typeof t!="function")return!1;try{await t(xt(),{id:"ckeditor5-vendor-umd"},{label:"ckeditor5 UMD"})}catch(o){return console.warn("[ckeditor5] 편집기 본체를 불러오지 못했습니다:",o),!1}return!!window.CKEDITOR}async function Q(t,o,e,n,r){const l=$t(e);if(!await it())throw new Error("[sirsoft-ckeditor5] 편집기 본체를 여전히 불러올 수 없습니다.");It(e);const i={...t,params:{...t.params??{},content:n?l??{}:l??""}};if(await mt(i,o),!r)return;window.G7Core?.state?.setLocal?.({[`form.${r}_mode`]:"html"})}function N(t,o,e,n){const r=window?.G7Core?.assets?.notifyFailure;if(typeof r=="function"){r({id:t,label:o,retry:e,message:n});return}console.warn(`[ckeditor5] 자산 로드 실패: ${o}`)}function x(t,o){const e=window?.G7Core?.t;if(typeof e!="function")return o;const n=`sirsoft-ckeditor5.${t}`,r=e(n);return typeof r=="string"&&r!==n?r:o}function Mt(){if(document.getElementById(lt))return;const t=document.createElement("style");t.id=lt,t.textContent=` /* 다국어 탭 컨테이너 */ .ckeditor5-locale-tabs { display: flex; @@ -149,7 +149,7 @@ var SirsoftCkeditor5=function(G){"use strict";const E=new Map,Y="https://cdn.cke list-style-type: lower-roman; padding-left: 2em; } - `,document.head.appendChild(t)}function et(){return document.documentElement.classList.contains("dark")}function q(){const t=document.getElementById(H);if(!et()){t&&t.remove();return}if(t)return;const o=document.createElement("style");o.id=H,o.textContent=` + `,document.head.appendChild(t)}function zt(){return document.documentElement.classList.contains("dark")}function st(){const t=document.getElementById(rt);if(!zt()){t&&t.remove();return}if(t)return;const o=document.createElement("style");o.id=rt,o.textContent=` /* CKEditor5 다크 모드 오버라이드 - CSS 변수 전역 적용 */ :root { --ck-color-base-foreground: #1f2937; @@ -332,7 +332,7 @@ var SirsoftCkeditor5=function(G){"use strict";const E=new Map,Y="https://cdn.cke .ck.ck-editor__editable li::marker { color: #d1d5db; } - `,document.head.appendChild(o)}let x=null;function ot(){x||(x=new MutationObserver(()=>{q()}),x.observe(document.documentElement,{attributes:!0,attributeFilter:["class"]}))}function nt(){x&&(x.disconnect(),x=null)}const rt={ko:"한국어",en:"English",ja:"日本語",zh:"中文",fr:"Français",de:"Deutsch",es:"Español"};function ct(t){return rt[t]??t.toUpperCase()}function lt(){const t=window.G7Core;return t?.locale?.supported?t.locale.supported():[localStorage.getItem("g7_locale")||"ko"]}function I(){return window.G7Core?.locale?.current?.()??localStorage.getItem("g7_locale")??"ko"}function at(t,o,e){const r=[t.Essentials,t.Bold,t.Italic,t.Underline,t.Strikethrough,t.Link,t.Paragraph,t.Heading,t.BlockQuote,t.List,t.Alignment,t.Table,t.TableToolbar,t.TableProperties,t.TableCellProperties,t.Indent,t.IndentBlock,t.PasteFromOffice,t.GeneralHtmlSupport,t.Image,t.ImageResize,t.ImageStyle,t.ImageCaption,t.ImageToolbar];return o==="full"&&r.push(t.MediaEmbed,t.HorizontalLine,t.CodeBlock,t.SourceEditing,t.FontSize,t.FontColor,t.FontBackgroundColor),e&&r.push(t.ImageUpload,t.SimpleUploadAdapter),r}function it(){return"/api/plugins/sirsoft-ckeditor5/upload"}function dt(){const t=localStorage.getItem("auth_token");return t?{Authorization:`Bearer ${t}`}:{}}async function F(t,o){const e=window.CKEDITOR;if(!e)throw new Error("[sirsoft-ckeditor5] CKEDITOR 전역 객체를 찾을 수 없습니다. CDN 스크립트가 로드되었는지 확인하세요.");const r=O[o.toolbar]||O.standard,c=o.imageUpload?r:r.filter(n=>n!=="uploadImage"),l={initialData:o.initialContent,plugins:at(e,o.toolbar,o.imageUpload),toolbar:{items:c},table:{contentToolbar:["tableColumn","tableRow","mergeTableCells","|","tableProperties","tableCellProperties"],tableProperties:{defaultProperties:{borderStyle:"solid",borderColor:"#d1d5db",borderWidth:"1px",alignment:"left"}},tableCellProperties:{defaultProperties:{borderStyle:"solid",borderColor:"#d1d5db",borderWidth:"1px",padding:"8px"}}},image:{toolbar:["imageStyle:inline","imageStyle:alignLeft","imageStyle:alignCenter","imageStyle:alignRight","|","toggleImageCaption","|","resizeImage"],resizeOptions:[{name:"resizeImage:original",label:"Original",value:null},{name:"resizeImage:25",label:"25%",value:"25"},{name:"resizeImage:50",label:"50%",value:"50"},{name:"resizeImage:75",label:"75%",value:"75"}],resizeUnit:"%"},indentBlock:{offset:40,unit:"px"},link:{defaultProtocol:"https://",decorators:{openInNewTab:{mode:"automatic",callback:n=>n.startsWith("http://")||n.startsWith("https://"),attributes:{target:"_blank",rel:"noopener noreferrer"}}}},htmlSupport:{allow:[{name:/.*/,attributes:!0,classes:!0,styles:!0}]},placeholder:o.placeholder,language:I()};o.imageUpload&&(l.simpleUpload={uploadUrl:it(),headers:dt()});const i=await e.ClassicEditor.create(t,l),s=`ckeditor5-height-style-${o.containerId}`,m=document.getElementById(s);if(m)m.textContent=`#${o.containerId} .ck-editor__editable { min-height: ${o.height}px !important; }`;else{const n=document.createElement("style");n.id=s,n.textContent=`#${o.containerId} .ck-editor__editable { min-height: ${o.height}px !important; }`,document.head.appendChild(n)}return o.readOnly&&i.enableReadOnlyMode("read-only"),i}function st(t,o,e,r,c){const l=document.createElement("div");l.className="ckeditor5-locale-tabs";const i=new Map;o.forEach(n=>{const a=document.createElement("div");a.dataset.locale=n,n!==e&&(a.style.cssText="display:none;");const C=document.createElement("div");a.appendChild(C),i.set(n,C)});const s=()=>{c&&l.querySelectorAll("button").forEach(n=>{const a=n.dataset.locale;if(!a||n.classList.contains("is-active")){const h=n.querySelector(".ck5-check");h&&h.remove();return}const g=!!c(a)?.trim(),p=n.querySelector(".ck5-check");if(g&&!p){const h=document.createElement("i");h.className="fas fa-check ck5-check",n.appendChild(h)}else!g&&p&&p.remove()})},m=o[0];return o.forEach(n=>{const a=n===m,C=n===e,g=document.createElement("button");g.type="button",g.dataset.locale=n,g.className=[C?"is-active":"",a?"is-default":""].filter(Boolean).join(" "),g.innerHTML=`${ct(n)}${a?'*':""}`,g.addEventListener("click",async()=>{l.querySelectorAll("button").forEach(p=>{const L=p.dataset.locale===n;p.classList.toggle("is-active",L)}),i.forEach((p,h)=>{const L=p.parentElement;L&&(L.style.display=h===n?"block":"none")}),r&&await r(n),s()}),l.appendChild(g)}),t.appendChild(l),i.forEach(n=>{n.parentElement&&t.appendChild(n.parentElement)}),{tabsEl:l,contentEls:i,updateCheckIcons:s}}function T(t,o,e,r){const c=window.G7Core;if(!c?.state?.setLocal)return;const l={[`form.${t}_mode`]:"html",hasChanges:!0};r?l[`form.${t}.${o}`]=e:l[`form.${t}`]=e,c.state.setLocal(l,{debounce:300,debounceKey:`ckeditor-sync-${t}`,render:!1,selfManaged:!0})}async function ut(t,o){const e=t.params??{},c=`ckeditor5-${e.name??"content"}`,l=E.get(c);if(l&&l.size>0){const y=[];l.forEach(u=>{u&&typeof u.destroy=="function"&&y.push(u.destroy().catch(()=>{}))}),await Promise.allSettled(y),E.delete(c)}const i=document.getElementById(c);if(!i){console.warn(`[sirsoft-ckeditor5] 컨테이너 엘리먼트를 찾을 수 없습니다: #${c}`);return}K(),tt(),q(),ot(),await R(I());const s=window.G7Core,m=s?.state?.get()||{},n=m._global?.plugins?.["sirsoft-ckeditor5"]??m.plugins?.["sirsoft-ckeditor5"]??{},a=e.name??"content",C=e.multilingual===!0||e.multilingual==="true",g=e.readOnly===!0||e.readOnly==="true",p=e.imageUpload!==void 0?e.imageUpload===!0||e.imageUpload==="true":n.imageUpload===!0||n.imageUpload==="true",h=e.placeholder??"",L=e.height!==void 0?Number(e.height)||400:Number(n.editorHeight)||400,mt=(e.toolbar!==void 0?e.toolbar:n.toolbar)??"standard";let _={};if(C){try{typeof e.content=="string"&&e.content.startsWith("{")&&!e.content.startsWith("{{")?_=JSON.parse(e.content):typeof e.content=="object"&&e.content!==null&&(_=e.content)}catch{_={}}if(Object.keys(_).length===0&&a){const u=(s?.state?.getLocal?.()??{})?.form?.[a];if(u&&typeof u=="object"&&!Array.isArray(u)?_=u:typeof u=="string"&&u&&(_={[I()]:u}),Object.keys(_).length===0){const k=s?.state?.get?.()??{},d=(k?._global?.selectedItem??k?.selectedItem)?.[a];d&&typeof d=="object"&&!Array.isArray(d)&&(_=d)}}}const P=new Map;E.set(c,P);const J={placeholder:h,readOnly:g,imageUpload:p,height:L,toolbar:mt,containerId:c};if(C){const y=lt(),u=I(),k={current:new Map},$={current:()=>{}},d=async f=>{if(P.has(f))return;const U=k.current.get(f);if(!U)return;const gt=_[f]??"";try{const A=await F(U,{...J,initialContent:gt});P.set(f,A);let X=!0;if(A.model.document.on("change:data",()=>{if(X)return;const M=A.getData();T(a,f,M,!0),$.current()}),X=!1,a){const M=window.G7Core;(M?.state?.getLocal?.()??{}).form?.[`${a}_mode`]!=="html"&&M.state.setLocal({[`form.${a}_mode`]:"html"})}}catch(A){console.error(`[sirsoft-ckeditor5] 에디터 초기화 오류 (locale: ${f}):`,A)}},S=f=>{const U=P.get(f);return U?U.getData?.()??null:null},{contentEls:B,updateCheckIcons:w}=st(i,y,u,d,S);k.current=B,$.current=w,await d(u),setTimeout(()=>{y.filter(f=>f!==u).forEach(f=>{d(f)})},2e3)}else{const y=typeof e.content=="string"?e.content:"";let k=y.startsWith("{{")&&y.endsWith("}}")?"":y;if(!k&&a){const S=(s?.state?.getLocal?.()??{})?.form?.[a];typeof S=="string"&&S&&(k=S)}const $=document.createElement("div");i.appendChild($);try{const d=await F($,{...J,initialContent:k}),S=I();P.set(S,d);let B=!0;if(d.model.document.on("change:data",()=>{if(B)return;const w=d.getData();T(a,S,w,!1)}),B=!1,k){const w=d.getData();(!w||w.trim()==="")&&d.setData(k)}if(a){const w=window.G7Core;(w?.state?.getLocal?.()??{}).form?.[`${a}_mode`]!=="html"&&w.state.setLocal({[`form.${a}_mode`]:"html"})}}catch(d){console.error("[sirsoft-ckeditor5] 에디터 초기화 오류:",d),E.delete(c)}}}async function ft(t,o){const r=`ckeditor5-${t.params?.name??"content"}`,c=E.get(r);if(!c||c.size===0)return;const l=[];c.forEach(s=>{s&&typeof s.destroy=="function"&&l.push(s.destroy().catch(m=>{console.warn("[sirsoft-ckeditor5] destroyEditor error:",m)}))}),await Promise.allSettled(l),E.delete(r);const i=document.getElementById(`ckeditor5-height-style-${r}`);i&&i.remove(),E.size===0&&nt()}const b="sirsoft-ckeditor5",W="ckeditor5-content-styles",V="ckeditor5-content-styles-override",kt="https://cdn.ckeditor.com/ckeditor5/43.3.1/ckeditor5.css";function bt(){if(!document.getElementById(W)){const t=document.createElement("link");t.id=W,t.rel="stylesheet",t.href=kt,document.head.appendChild(t)}if(!document.getElementById(V)){const t=document.createElement("style");t.id=V,t.textContent=` + `,document.head.appendChild(o)}let I=null;function Ut(){I||(I=new MutationObserver(()=>{st()}),I.observe(document.documentElement,{attributes:!0,attributeFilter:["class"]}))}function At(){I&&(I.disconnect(),I=null)}const Pt={ko:"한국어",en:"English",ja:"日本語",zh:"中文",fr:"Français",de:"Deutsch",es:"Español"};function Bt(t){return Pt[t]??t.toUpperCase()}function dt(){const t=window.G7Core;return t?.locale?.supported?t.locale.supported():[localStorage.getItem("g7_locale")||"ko"]}function L(){return window.G7Core?.locale?.current?.()??localStorage.getItem("g7_locale")??"ko"}function Ot(t,o,e){const n=[t.Essentials,t.Bold,t.Italic,t.Underline,t.Strikethrough,t.Link,t.Paragraph,t.Heading,t.BlockQuote,t.List,t.Alignment,t.Table,t.TableToolbar,t.TableProperties,t.TableCellProperties,t.Indent,t.IndentBlock,t.PasteFromOffice,t.GeneralHtmlSupport,t.Image,t.ImageResize,t.ImageStyle,t.ImageCaption,t.ImageToolbar];return o==="full"&&n.push(t.MediaEmbed,t.HorizontalLine,t.CodeBlock,t.SourceEditing,t.FontSize,t.FontColor,t.FontBackgroundColor),e&&n.push(t.ImageUpload,t.SimpleUploadAdapter),n}function Tt(){return"/api/plugins/sirsoft-ckeditor5/upload"}function jt(){const t=localStorage.getItem("auth_token");return t?{Authorization:`Bearer ${t}`}:{}}async function ut(t,o){const e=window.CKEDITOR;if(!e)throw new Error("[sirsoft-ckeditor5] CKEDITOR 전역 객체를 찾을 수 없습니다. CDN 스크립트가 로드되었는지 확인하세요.");const n=ct[o.toolbar]||ct.standard,r=o.imageUpload?n:n.filter(c=>c!=="uploadImage"),l={initialData:o.initialContent,plugins:Ot(e,o.toolbar,o.imageUpload),toolbar:{items:r},table:{contentToolbar:["tableColumn","tableRow","mergeTableCells","|","tableProperties","tableCellProperties"],tableProperties:{defaultProperties:{borderStyle:"solid",borderColor:"#d1d5db",borderWidth:"1px",alignment:"left"}},tableCellProperties:{defaultProperties:{borderStyle:"solid",borderColor:"#d1d5db",borderWidth:"1px",padding:"8px"}}},image:{toolbar:["imageStyle:inline","imageStyle:alignLeft","imageStyle:alignCenter","imageStyle:alignRight","|","toggleImageCaption","|","resizeImage"],resizeOptions:[{name:"resizeImage:original",label:"Original",value:null},{name:"resizeImage:25",label:"25%",value:"25"},{name:"resizeImage:50",label:"50%",value:"50"},{name:"resizeImage:75",label:"75%",value:"75"}],resizeUnit:"%"},indentBlock:{offset:40,unit:"px"},link:{defaultProtocol:"https://",decorators:{openInNewTab:{mode:"automatic",callback:c=>c.startsWith("http://")||c.startsWith("https://"),attributes:{target:"_blank",rel:"noopener noreferrer"}}}},htmlSupport:{allow:[{name:/.*/,attributes:!0,classes:!0,styles:!0}]},placeholder:o.placeholder,language:L()};o.imageUpload&&(l.simpleUpload={uploadUrl:Tt(),headers:jt()});const i=await e.ClassicEditor.create(t,l),s=`ckeditor5-height-style-${o.containerId}`,k=document.getElementById(s);if(k)k.textContent=`#${o.containerId} .ck-editor__editable { min-height: ${o.height}px !important; }`;else{const c=document.createElement("style");c.id=s,c.textContent=`#${o.containerId} .ck-editor__editable { min-height: ${o.height}px !important; }`,document.head.appendChild(c)}return o.readOnly&&i.enableReadOnlyMode("read-only"),i}function Nt(t,o,e,n,r){const l=document.createElement("div");l.className="ckeditor5-locale-tabs";const i=new Map;o.forEach(c=>{const a=document.createElement("div");a.dataset.locale=c,c!==e&&(a.style.cssText="display:none;");const b=document.createElement("div");a.appendChild(b),i.set(c,b)});const s=()=>{r&&l.querySelectorAll("button").forEach(c=>{const a=c.dataset.locale;if(!a||c.classList.contains("is-active")){const f=c.querySelector(".ck5-check");f&&f.remove();return}const d=!!r(a)?.trim(),u=c.querySelector(".ck5-check");if(d&&!u){const f=document.createElement("i");f.className="fas fa-check ck5-check",c.appendChild(f)}else!d&&u&&u.remove()})},k=o[0];return o.forEach(c=>{const a=c===k,b=c===e,d=document.createElement("button");d.type="button",d.dataset.locale=c,d.className=[b?"is-active":"",a?"is-default":""].filter(Boolean).join(" "),d.innerHTML=`${Bt(c)}${a?'*':""}`,d.addEventListener("click",async()=>{l.querySelectorAll("button").forEach(u=>{const m=u.dataset.locale===c;u.classList.toggle("is-active",m)}),i.forEach((u,f)=>{const m=u.parentElement;m&&(m.style.display=f===c?"block":"none")}),n&&await n(c),s()}),l.appendChild(d)}),t.appendChild(l),i.forEach(c=>{c.parentElement&&t.appendChild(c.parentElement)}),{tabsEl:l,contentEls:i,updateCheckIcons:s}}function ft(t,o,e,n){if(_t())return;const r=window.G7Core;if(!r?.state?.setLocal)return;const l={[`form.${t}_mode`]:"html",hasChanges:!0};n?l[`form.${t}.${o}`]=e:l[`form.${t}`]=e,r.state.setLocal(l,{debounce:300,debounceKey:`ckeditor-sync-${t}`,render:!1,selfManaged:!0})}function kt(t,o){const e=window.G7Core,n=typeof t.content=="string"?t.content:"";let l=n.startsWith("{{")&&n.endsWith("}}")?"":n;if(!l&&o){const s=(e?.state?.getLocal?.()??{})?.form?.[o];typeof s=="string"&&s&&(l=s)}return l}function bt(t,o){const e=window.G7Core;let n={};try{typeof t.content=="string"&&t.content.startsWith("{")&&!t.content.startsWith("{{")?n=JSON.parse(t.content):typeof t.content=="object"&&t.content!==null&&(n=t.content)}catch{n={}}if(Object.keys(n).length===0&&o){const l=(e?.state?.getLocal?.()??{})?.form?.[o];if(l&&typeof l=="object"&&!Array.isArray(l)?n=l:typeof l=="string"&&l&&(n={[L()]:l}),Object.keys(n).length===0){const i=e?.state?.get?.()??{},k=(i?._global?.selectedItem??i?.selectedItem)?.[o];k&&typeof k=="object"&&!Array.isArray(k)&&(n=k)}}return n}async function mt(t,o){const e=t.params??{},r=`ckeditor5-${e.name??"content"}`;et(r);const l=E.get(r);if(l&&l.size>0){const g=[];l.forEach(h=>{h&&typeof h.destroy=="function"&&g.push(h.destroy().catch(()=>{}))}),await Promise.allSettled(g),E.delete(r)}const i=document.getElementById(r);if(!i){console.warn(`[sirsoft-ckeditor5] 컨테이너 엘리먼트를 찾을 수 없습니다: #${r}`);return}at(),Mt(),st(),Ut(),await Gt(L());const k=window.G7Core?.state?.get()||{},c=k._global?.plugins?.["sirsoft-ckeditor5"]??k.plugins?.["sirsoft-ckeditor5"]??{},a=e.name??"content",b=e.multilingual===!0||e.multilingual==="true",d=e.readOnly===!0||e.readOnly==="true",u=e.imageUpload!==void 0?e.imageUpload===!0||e.imageUpload==="true":c.imageUpload===!0||c.imageUpload==="true",f=e.placeholder??"",m=e.height!==void 0?Number(e.height)||400:Number(c.editorHeight)||400,w=(e.toolbar!==void 0?e.toolbar:c.toolbar)??"standard";let S=b?bt(e,a):{};if(!await it()){const g={container:i,name:a,height:m,readOnly:d,placeholder:f,multilingual:b,locales:b?dt():void 0,activeLocale:L(),contentMap:b?bt(e,a):void 0,initialContent:b?void 0:kt(e,a)};R(g),N(`ckeditor5-editor:${r}`,x("editor.asset.label","편집기"),()=>Q(t,o,i,g.multilingual,a),x("editor.asset.fallback_notice","편집기를 불러오지 못했습니다. 임시 입력창으로 전환했습니다. 작성한 내용은 그대로 저장됩니다."));return}const v=new Map;E.set(r,v);const yt={placeholder:f,readOnly:d,imageUpload:u,height:m,toolbar:w,containerId:r};if(b){const g=dt(),h=L(),C={current:new Map},G={current:()=>{}},M=async p=>{if(v.has(p))return;const P=C.current.get(p);if(!P)return;const Ft=S[p]??"";try{const z=await ut(P,{...yt,initialContent:Ft});v.set(p,z);let Ct=!0;const Y=ot(z,{name:a,locale:p,multilingual:!0});if(tt(r,Y),z.model.document.on("change:data",()=>{if(Ct||!Y.shouldEmit())return;const B=z.getData();Y.noteEmitted(B),ft(a,p,B,!0),G.current()}),Ct=!1,a){const B=window.G7Core;(B?.state?.getLocal?.()??{}).form?.[`${a}_mode`]!=="html"&&B.state.setLocal({[`form.${a}_mode`]:"html"})}}catch(z){console.error(`[sirsoft-ckeditor5] 에디터 초기화 오류 (locale: ${p}):`,z)}},A=p=>{const P=v.get(p);return P?P.getData?.()??null:null},{contentEls:_,updateCheckIcons:wt}=Nt(i,g,h,M,A);if(C.current=_,G.current=wt,await M(h),!v.has(h)){E.delete(r),R({container:i,name:a,height:m,readOnly:d,placeholder:f,multilingual:!0,locales:g,activeLocale:h,contentMap:S}),N(`ckeditor5-editor:${r}`,x("editor.asset.label","편집기"),()=>Q(t,o,i,!0,a),x("editor.asset.fallback_notice","편집기를 불러오지 못했습니다. 임시 입력창으로 전환했습니다. 작성한 내용은 그대로 저장됩니다."));return}setTimeout(()=>{g.filter(p=>p!==h).forEach(p=>{M(p)})},2e3)}else{const g=kt(e,a),h=document.createElement("div");i.appendChild(h);try{const C=await ut(h,{...yt,initialContent:g}),G=L();v.set(G,C);let M=!0;const A=ot(C,{name:a,locale:G,multilingual:!1});if(tt(r,A),C.model.document.on("change:data",()=>{if(M||!A.shouldEmit())return;const _=C.getData();A.noteEmitted(_),ft(a,G,_,!1)}),M=!1,g){const _=C.getData();(!_||_.trim()==="")&&C.setData(g)}if(a){const _=window.G7Core;(_?.state?.getLocal?.()??{}).form?.[`${a}_mode`]!=="html"&&_.state.setLocal({[`form.${a}_mode`]:"html"})}}catch(C){console.error("[sirsoft-ckeditor5] 에디터 초기화 오류:",C),E.delete(r),R({container:i,name:a,height:m,readOnly:d,placeholder:f,multilingual:!1,activeLocale:L(),initialContent:g}),N(`ckeditor5-editor:${r}`,x("editor.asset.label","편집기"),()=>Q(t,o,i,!1,a),x("editor.asset.fallback_notice","편집기를 불러오지 못했습니다. 임시 입력창으로 전환했습니다. 작성한 내용은 그대로 저장됩니다."))}}}async function Dt(t,o){const n=`ckeditor5-${t.params?.name??"content"}`;et(n);const r=E.get(n);if(!r||r.size===0)return;const l=[];r.forEach(s=>{s&&typeof s.destroy=="function"&&l.push(s.destroy().catch(k=>{console.warn("[sirsoft-ckeditor5] destroyEditor error:",k)}))}),await Promise.allSettled(l),E.delete(n);const i=document.getElementById(`ckeditor5-height-style-${n}`);i&&i.remove(),E.size===0&&At()}const y="sirsoft-ckeditor5",J="ckeditor5-content-styles",gt="ckeditor5-content-styles-override";function pt(){if(!document.getElementById(J)){const t=window?.G7Core?.asset;try{const o=nt();if(typeof t?.loadStylesheet=="function")t.loadStylesheet(o,{id:J},{label:"ckeditor5 content CSS"}).catch(e=>{console.warn("[ckeditor5] 본문 스타일 로드 실패:",e),window?.G7Core?.assets?.notifyFailure?.({id:"ckeditor5-content-css",label:"본문 스타일",retry:()=>pt()})});else{const e=document.createElement("link");e.id=J,e.rel="stylesheet",e.href=o,document.head.appendChild(e)}}catch(o){console.warn("[ckeditor5] 본문 스타일 URL 을 만들지 못했습니다:",o)}}if(!document.getElementById(gt)){const t=document.createElement("style");t.id=gt,t.textContent=` /* 이미지 캡션 - 다크모드 */ html.dark .ck-content .image > figcaption { color: hsl(0, 0%, 80%); background-color: hsl(0, 0%, 15%); } @@ -369,4 +369,4 @@ var SirsoftCkeditor5=function(G){"use strict";const E=new Map,Y="https://cdn.cke .ck-content ul ul ul { list-style-type: square; padding-left: 2em; } .ck-content ol ol { list-style-type: lower-alpha; padding-left: 2em; } .ck-content ol ol ol { list-style-type: lower-roman; padding-left: 2em; } - `,document.head.appendChild(t)}}const v={initEditor:ut,destroyEditor:ft,injectContentCss:bt},z=window.G7Core?.createLogger?.(`Plugin:${b}`)??{log:(...t)=>console.log(`[Plugin:${b}]`,...t),warn:(...t)=>console.warn(`[Plugin:${b}]`,...t),error:(...t)=>console.error(`[Plugin:${b}]`,...t)};function Q(t=!1){const o=window.G7Core?.getActionDispatcher?.();if(o)Object.entries(v).forEach(([e,r])=>{const c=`${b}.${e}`;o.registerHandler(c,r,{category:"plugin",source:b})}),z.log(`${Object.keys(v).length} handler(s) registered:`,Object.keys(v).map(e=>`${b}.${e}`));else if(t){let e=0;const r=50,c=()=>{const l=window.G7Core?.getActionDispatcher?.();l?(Object.entries(v).forEach(([i,s])=>{const m=`${b}.${i}`;l.registerHandler(m,s,{category:"plugin",source:b})}),z.log(`${Object.keys(v).length} handler(s) registered:`,Object.keys(v).map(i=>`${b}.${i}`))):(e++,e<=r?(z.warn(`ActionDispatcher not found, retrying... (${e}/${r})`),setTimeout(c,100)):z.error("Failed to register handlers: ActionDispatcher not available after maximum retries"))};c()}else z.warn("ActionDispatcher not found, handlers not registered")}function j(){if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",()=>Q(!0));else{const t=!!window.G7Core?.getActionDispatcher?.();Q(!t)}}return j(),typeof window<"u"&&(window.__SirsoftCkeditor5={identifier:b,handlers:Object.keys(v),initPlugin:j}),G.initPlugin=j,Object.defineProperty(G,Symbol.toStringTag,{value:"Module"}),G}({}); + `,document.head.appendChild(t)}}const $={initEditor:mt,destroyEditor:Dt,injectContentCss:pt},U=window.G7Core?.createLogger?.(`Plugin:${y}`)??{log:(...t)=>console.log(`[Plugin:${y}]`,...t),warn:(...t)=>console.warn(`[Plugin:${y}]`,...t),error:(...t)=>console.error(`[Plugin:${y}]`,...t)};function ht(t=!1){const o=window.G7Core?.getActionDispatcher?.();if(o)Object.entries($).forEach(([e,n])=>{const r=`${y}.${e}`;o.registerHandler(r,n,{category:"plugin",source:y})}),U.log(`${Object.keys($).length} handler(s) registered:`,Object.keys($).map(e=>`${y}.${e}`));else if(t){let e=0;const n=50,r=()=>{const l=window.G7Core?.getActionDispatcher?.();l?(Object.entries($).forEach(([i,s])=>{const k=`${y}.${i}`;l.registerHandler(k,s,{category:"plugin",source:y})}),U.log(`${Object.keys($).length} handler(s) registered:`,Object.keys($).map(i=>`${y}.${i}`))):(e++,e<=n?(U.warn(`ActionDispatcher not found, retrying... (${e}/${n})`),setTimeout(r,100)):U.error("Failed to register handlers: ActionDispatcher not available after maximum retries"))};r()}else U.warn("ActionDispatcher not found, handlers not registered")}function X(){if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",()=>ht(!0));else{const t=!!window.G7Core?.getActionDispatcher?.();ht(!t)}}return X(),typeof window<"u"&&(window.__SirsoftCkeditor5={identifier:y,handlers:Object.keys($),initPlugin:X}),D.initPlugin=X,Object.defineProperty(D,Symbol.toStringTag,{value:"Module"}),D}({}); diff --git a/plugins/_bundled/sirsoft-ckeditor5/dist/vendor/ckeditor5/43.3.1/LICENSE.md b/plugins/_bundled/sirsoft-ckeditor5/dist/vendor/ckeditor5/43.3.1/LICENSE.md new file mode 100644 index 00000000..8791321c --- /dev/null +++ b/plugins/_bundled/sirsoft-ckeditor5/dist/vendor/ckeditor5/43.3.1/LICENSE.md @@ -0,0 +1,28 @@ +Software License Agreement +========================== + +**CKEditor 5** – https://github.com/ckeditor/ckeditor5
+Copyright (c) 2003–2024, [CKSource Holding sp. z o.o.](https://cksource.com) All rights reserved. + +Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html). + +Sources of Intellectual Property Included in CKEditor +----------------------------------------------------- + +Where not otherwise indicated, all CKEditor content is authored by CKSource engineers and consists of CKSource-owned intellectual property. In some specific instances, CKEditor will incorporate work done by developers outside of CKSource with their express permission. + +The following libraries are included in CKEditor under the [MIT license](https://opensource.org/licenses/MIT): + +* BlurHash - Copyright (c) 2018 Wolt Enterprises (MIT license). +* color-convert - Copyright (c) 2011–2016 Heather Arthur , copyright (c) 2016–2021 Josh Junon . +* color-parse - Copyright (c) 2015 Dmitry Ivanov. +* Lodash - Copyright (c) JS Foundation and other contributors https://js.foundation/. Based on Underscore.js, copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors http://underscorejs.org/. +* Marked - Copyright (c) 2018+, MarkedJS (https://github.com/markedjs/), copyright (c) 2011–2018, Christopher Jeffrey (https://github.com/chjj/). +* Turndown - Copyright (c) 2017+ Dom Christie. +* turndown-plugin-gfm - Copyright (c) 2017+ Dom Christie. +* vanilla-colorful - Copyright (c) 2020 Serhii Kulykov . + +Trademarks +---------- + +**CKEditor** is a trademark of [CKSource Holding sp. z o.o.](https://cksource.com) All other brand and product names are trademarks, registered trademarks or service marks of their respective holders. diff --git a/plugins/_bundled/sirsoft-ckeditor5/dist/vendor/ckeditor5/43.3.1/ckeditor5.css b/plugins/_bundled/sirsoft-ckeditor5/dist/vendor/ckeditor5/43.3.1/ckeditor5.css new file mode 100644 index 00000000..9c27262d --- /dev/null +++ b/plugins/_bundled/sirsoft-ckeditor5/dist/vendor/ckeditor5/43.3.1/ckeditor5.css @@ -0,0 +1,9583 @@ +/** + * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* Reset */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-color-base-foreground: hsl(0, 0%, 98%); + --ck-color-base-background: hsl(0, 0%, 100%); + --ck-color-base-border: hsl(220, 6%, 81%); + --ck-color-base-action: hsl(104, 50.2%, 42.5%); + --ck-color-base-focus: hsl(209, 92%, 70%); + --ck-color-base-text: hsl(0, 0%, 20%); + --ck-color-base-active: hsl(218.1, 100%, 58%); + --ck-color-base-active-focus: hsl(218.2, 100%, 52.5%); + --ck-color-base-error: hsl(15, 100%, 43%); + + /* -- Generic colors ------------------------------------------------------------------------ */ + + --ck-color-focus-border-coordinates: 218, 81.8%, 56.9%; + --ck-color-focus-border: hsl(var(--ck-color-focus-border-coordinates)); + --ck-color-focus-outer-shadow: hsl(212.4, 89.3%, 89%); + --ck-color-focus-disabled-shadow: hsla(209, 90%, 72%,.3); + --ck-color-focus-error-shadow: hsla(9,100%,56%,.3); + --ck-color-text: var(--ck-color-base-text); + --ck-color-shadow-drop: hsla(0, 0%, 0%, 0.15); + --ck-color-shadow-drop-active: hsla(0, 0%, 0%, 0.2); + --ck-color-shadow-inner: hsla(0, 0%, 0%, 0.1); + + /* -- Buttons ------------------------------------------------------------------------------- */ + + --ck-color-button-default-background: transparent; + --ck-color-button-default-hover-background: hsl(0, 0%, 94.1%); + --ck-color-button-default-active-background: hsl(0, 0%, 94.1%); + --ck-color-button-default-disabled-background: transparent; + + --ck-color-button-on-background: hsl(212, 100%, 97.1%); + --ck-color-button-on-hover-background: hsl(211.7, 100%, 92.9%); + --ck-color-button-on-active-background: hsl(211.7, 100%, 92.9%); + --ck-color-button-on-disabled-background: hsl(211, 15%, 95%); + --ck-color-button-on-color: hsl(218.1, 100%, 58%); + + + --ck-color-button-action-background: var(--ck-color-base-action); + --ck-color-button-action-hover-background: hsl(104, 53.2%, 40.2%); + --ck-color-button-action-active-background: hsl(104, 53.2%, 40.2%); + --ck-color-button-action-disabled-background: hsl(104, 44%, 58%); + --ck-color-button-action-text: var(--ck-color-base-background); + + --ck-color-button-save: hsl(120, 100%, 27%); + --ck-color-button-cancel: hsl(15, 100%, 43%); + + --ck-color-switch-button-off-background: hsl(0, 0%, 57.6%); + --ck-color-switch-button-off-hover-background: hsl(0, 0%, 49%); + --ck-color-switch-button-on-background: var(--ck-color-button-action-background); + --ck-color-switch-button-on-hover-background: hsl(104, 53.2%, 40.2%); + --ck-color-switch-button-inner-background: var(--ck-color-base-background); + --ck-color-switch-button-inner-shadow: hsla(0, 0%, 0%, 0.1); + + /* -- Dropdown ------------------------------------------------------------------------------ */ + + --ck-color-dropdown-panel-background: var(--ck-color-base-background); + --ck-color-dropdown-panel-border: var(--ck-color-base-border); + + /* -- Dialog -------------------------------------------------------------------------------- */ + + --ck-color-dialog-background: var(--ck-custom-background); + --ck-color-dialog-form-header-border: var(--ck-custom-border); + + /* -- Input --------------------------------------------------------------------------------- */ + + --ck-color-input-background: var(--ck-color-base-background); + --ck-color-input-border: var(--ck-color-base-border); + --ck-color-input-error-border: var(--ck-color-base-error); + --ck-color-input-text: var(--ck-color-base-text); + --ck-color-input-disabled-background: hsl(0, 0%, 95%); + --ck-color-input-disabled-border: var(--ck-color-base-border); + --ck-color-input-disabled-text: hsl(0, 0%, 46%); + + /* -- List ---------------------------------------------------------------------------------- */ + + --ck-color-list-background: var(--ck-color-base-background); + --ck-color-list-button-hover-background: var(--ck-color-button-default-hover-background); + --ck-color-list-button-on-background: var(--ck-color-button-on-color); + --ck-color-list-button-on-background-focus: var(--ck-color-button-on-color); + --ck-color-list-button-on-text: var(--ck-color-base-background); + + /* -- Panel --------------------------------------------------------------------------------- */ + + --ck-color-panel-background: var(--ck-color-base-background); + --ck-color-panel-border: var(--ck-color-base-border); + + /* -- Toolbar ------------------------------------------------------------------------------- */ + + --ck-color-toolbar-background: var(--ck-color-base-background); + --ck-color-toolbar-border: var(--ck-color-base-border); + + /* -- Tooltip ------------------------------------------------------------------------------- */ + + --ck-color-tooltip-background: var(--ck-color-base-text); + --ck-color-tooltip-text: var(--ck-color-base-background); + + /* -- Engine -------------------------------------------------------------------------------- */ + + --ck-color-engine-placeholder-text: hsl(0, 0%, 44%); + + /* -- Upload -------------------------------------------------------------------------------- */ + + --ck-color-upload-bar-background: hsl(209, 92%, 70%); + + /* -- Link -------------------------------------------------------------------------------- */ + + --ck-color-link-default: hsl(240, 100%, 47%); + --ck-color-link-selected-background: hsla(201, 100%, 56%, 0.1); + --ck-color-link-fake-selection: hsla(201, 100%, 56%, 0.3); + + /* -- Search result highlight ---------------------------------------------------------------- */ + + --ck-color-highlight-background: hsl(60, 100%, 50%); + + /* -- Generic colors ------------------------------------------------------------------------- */ + + --ck-color-light-red: hsl(0, 100%, 90%); +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + /** + * An opacity value of disabled UI item. + */ + --ck-disabled-opacity: .5; +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + /** + * The geometry of the of focused element's outer shadow. + */ + --ck-focus-outer-shadow-geometry: 0 0 0 3px; + + /** + * A visual style of focused element's outer shadow. + */ + --ck-focus-outer-shadow: var(--ck-focus-outer-shadow-geometry) var(--ck-color-focus-outer-shadow); + + /** + * A visual style of focused element's outer shadow (when disabled). + */ + --ck-focus-disabled-outer-shadow: var(--ck-focus-outer-shadow-geometry) var(--ck-color-focus-disabled-shadow); + + /** + * A visual style of focused element's outer shadow (when has errors). + */ + --ck-focus-error-outer-shadow: var(--ck-focus-outer-shadow-geometry) var(--ck-color-focus-error-shadow); + + /** + * A visual style of focused element's border or outline. + */ + --ck-focus-ring: 1px solid var(--ck-color-focus-border); +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-font-size-base: 13px; + --ck-line-height-base: 1.84615; + --ck-font-face: Helvetica, Arial, Tahoma, Verdana, Sans-Serif; + + --ck-font-size-tiny: 0.7em; + --ck-font-size-small: 0.75em; + --ck-font-size-normal: 1em; + --ck-font-size-big: 1.4em; + --ck-font-size-large: 1.8em; +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + /* This is super-important. This is **manually** adjusted so a button without an icon + is never smaller than a button with icon, additionally making sure that text-less buttons + are perfect squares. The value is also shared by other components which should stay "in-line" + with buttons. */ + --ck-ui-component-min-height: 2.3em; +} +/** + * Resets an element, ignoring its children. + */ +.ck.ck-reset, +.ck.ck-reset_all, +.ck-reset_all *:not(.ck-reset_all-excluded *) { + box-sizing: border-box; + width: auto; + height: auto; + position: static; + + /* Do not include inheritable rules here. */ + margin: 0; + padding: 0; + border: 0; + background: transparent; + text-decoration: none; + vertical-align: middle; + transition: none; + + /* https://github.com/ckeditor/ckeditor5-theme-lark/issues/105 */ + word-wrap: break-word; +} +/** + * Resets an element AND its children. + */ +.ck.ck-reset_all, +.ck-reset_all *:not(.ck-reset_all-excluded *) { + /* These are rule inherited by all children elements. */ + border-collapse: collapse; + font: normal normal normal var(--ck-font-size-base)/var(--ck-line-height-base) var(--ck-font-face); + color: var(--ck-color-text); + text-align: left; + white-space: nowrap; + cursor: auto; + float: none; +} +.ck-reset_all .ck-rtl *:not(.ck-reset_all-excluded *) { + text-align: right; + } +.ck-reset_all iframe:not(.ck-reset_all-excluded *) { + /* For IE */ + vertical-align: inherit; + } +.ck-reset_all textarea:not(.ck-reset_all-excluded *) { + white-space: pre-wrap; + } +.ck-reset_all textarea:not(.ck-reset_all-excluded *), + .ck-reset_all input[type="text"]:not(.ck-reset_all-excluded *), + .ck-reset_all input[type="password"]:not(.ck-reset_all-excluded *) { + cursor: text; + } +.ck-reset_all textarea[disabled]:not(.ck-reset_all-excluded *), + .ck-reset_all input[type="text"][disabled]:not(.ck-reset_all-excluded *), + .ck-reset_all input[type="password"][disabled]:not(.ck-reset_all-excluded *) { + cursor: default; + } +.ck-reset_all fieldset:not(.ck-reset_all-excluded *) { + padding: 10px; + border: 2px groove hsl(255, 7%, 88%); + } +.ck-reset_all button:not(.ck-reset_all-excluded *)::-moz-focus-inner { + /* See http://stackoverflow.com/questions/5517744/remove-extra-button-spacing-padding-in-firefox */ + padding: 0; + border: 0 + } +/** + * Default UI rules for RTL languages. + */ +.ck[dir="rtl"], +.ck[dir="rtl"] .ck { + text-align: right; +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Default border-radius value. + */ +:root{ + --ck-border-radius: 2px; +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + /** + * A visual style of element's inner shadow (i.e. input). + */ + --ck-inner-shadow: 2px 2px 3px var(--ck-color-shadow-inner) inset; + + /** + * A visual style of element's drop shadow (i.e. panel). + */ + --ck-drop-shadow: 0 1px 2px 1px var(--ck-color-shadow-drop); + + /** + * A visual style of element's active shadow (i.e. comment or suggestion). + */ + --ck-drop-shadow-active: 0 3px 6px 1px var(--ck-color-shadow-drop-active); +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-spacing-unit: 0.6em; + --ck-spacing-large: calc(var(--ck-spacing-unit) * 1.5); + --ck-spacing-standard: var(--ck-spacing-unit); + --ck-spacing-medium: calc(var(--ck-spacing-unit) * 0.8); + --ck-spacing-small: calc(var(--ck-spacing-unit) * 0.5); + --ck-spacing-tiny: calc(var(--ck-spacing-unit) * 0.3); + --ck-spacing-extra-tiny: calc(var(--ck-spacing-unit) * 0.16); +} + +/* Components */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ +.ck.ck-autocomplete > .ck-search__results { + border-radius: 0; + + max-height: 200px; + overflow-y: auto; + background: var(--ck-color-base-background); + border: 1px solid var(--ck-color-dropdown-panel-border); + min-width: auto; + } +.ck-rounded-corners .ck.ck-autocomplete > .ck-search__results, + .ck.ck-autocomplete > .ck-search__results.ck-rounded-corners { + border-radius: var(--ck-border-radius); + } +.ck.ck-autocomplete > .ck-search__results { + box-shadow: var(--ck-drop-shadow), 0 0; + } +.ck.ck-autocomplete > .ck-search__results.ck-search__results_n { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + + /* Prevent duplicated borders between the input and the results pane. */ + margin-bottom: -1px; + } +.ck.ck-autocomplete > .ck-search__results.ck-search__results_s { + border-top-left-radius: 0; + border-top-right-radius: 0; + + /* Prevent duplicated borders between the input and the results pane. */ + margin-top: -1px; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A visual style of focused element's border. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A class which indicates that an element holding it is disabled. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements a button of given background color. + * + * @param {String} $background - Background color of the button. + * @param {String} $border - Border color of the button. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-button, +a.ck.ck-button { + background: var(--ck-color-button-default-background); + border-radius: 0; + + white-space: nowrap; + cursor: default; + vertical-align: middle; + padding: var(--ck-spacing-tiny); + text-align: center; + + /* A very important piece of styling. Go to variable declaration to learn more. */ + min-width: var(--ck-ui-component-min-height); + min-height: var(--ck-ui-component-min-height); + + /* Normalize the height of the line. Removing this will break consistent height + among text and text-less buttons (with icons). */ + line-height: 1; + + /* Enable font size inheritance, which allows fluid UI scaling. */ + font-size: inherit; + + /* Avoid flickering when the foucs border shows up. */ + border: 1px solid transparent; + + /* Apply some smooth transition to the box-shadow and border. */ + transition: box-shadow .2s ease-in-out, border .2s ease-in-out; + + /* https://github.com/ckeditor/ckeditor5-theme-lark/issues/189 */ + -webkit-appearance: none; +} +.ck.ck-button:not(.ck-disabled):hover, a.ck.ck-button:not(.ck-disabled):hover { + background: var(--ck-color-button-default-hover-background); + } +.ck.ck-button:not(.ck-disabled):active, a.ck.ck-button:not(.ck-disabled):active { + background: var(--ck-color-button-default-active-background); + } +/* https://github.com/ckeditor/ckeditor5-theme-lark/issues/98 */ +.ck.ck-button.ck-disabled, a.ck.ck-button.ck-disabled { + background: var(--ck-color-button-default-disabled-background); + } +.ck-rounded-corners .ck.ck-button, + .ck-rounded-corners a.ck.ck-button, + .ck.ck-button.ck-rounded-corners, + a.ck.ck-button.ck-rounded-corners { + border-radius: var(--ck-border-radius); + } +@media (prefers-reduced-motion: reduce) { +.ck.ck-button, +a.ck.ck-button { + transition: none; +} + } +.ck.ck-button:active, + a.ck.ck-button:active, + .ck.ck-button:focus, + a.ck.ck-button:focus { + /* Disable native outline. */ + outline: none; + border: var(--ck-focus-ring); + box-shadow: var(--ck-focus-outer-shadow), 0 0; + } +/* Allow icon coloring using the text "color" property. */ +.ck.ck-button .ck-button__icon use, + a.ck.ck-button .ck-button__icon use, + .ck.ck-button .ck-button__icon use *, + a.ck.ck-button .ck-button__icon use * { + color: inherit; + } +.ck.ck-button .ck-button__label, a.ck.ck-button .ck-button__label { + /* Enable font size inheritance, which allows fluid UI scaling. */ + font-size: inherit; + font-weight: inherit; + color: inherit; + cursor: inherit; + + /* Must be consistent with .ck-icon's vertical align. Otherwise, buttons with and + without labels (but with icons) have different sizes in Chrome */ + vertical-align: middle; + } +[dir="ltr"] .ck.ck-button .ck-button__label, [dir="ltr"] a.ck.ck-button .ck-button__label { + text-align: left; + } +[dir="rtl"] .ck.ck-button .ck-button__label, [dir="rtl"] a.ck.ck-button .ck-button__label { + text-align: right; + } +.ck.ck-button .ck-button__keystroke, a.ck.ck-button .ck-button__keystroke { + color: inherit; + + opacity: .5; + } +[dir="ltr"] .ck.ck-button .ck-button__keystroke, [dir="ltr"] a.ck.ck-button .ck-button__keystroke { + margin-left: var(--ck-spacing-large); + } +[dir="rtl"] .ck.ck-button .ck-button__keystroke, [dir="rtl"] a.ck.ck-button .ck-button__keystroke { + margin-right: var(--ck-spacing-large); + } +/* https://github.com/ckeditor/ckeditor5-theme-lark/issues/70 */ +.ck.ck-button.ck-disabled:active, + a.ck.ck-button.ck-disabled:active, + .ck.ck-button.ck-disabled:focus, + a.ck.ck-button.ck-disabled:focus { + /* The disabled button should have a slightly less visible shadow when focused. */ + box-shadow: var(--ck-focus-disabled-outer-shadow), 0 0; + } +.ck.ck-button.ck-disabled .ck-button__icon, a.ck.ck-button.ck-disabled .ck-button__icon { + opacity: var(--ck-disabled-opacity); + } +/* https://github.com/ckeditor/ckeditor5-theme-lark/issues/98 */ +.ck.ck-button.ck-disabled .ck-button__label, a.ck.ck-button.ck-disabled .ck-button__label { + opacity: var(--ck-disabled-opacity); + } +.ck.ck-button.ck-disabled .ck-button__keystroke, a.ck.ck-button.ck-disabled .ck-button__keystroke { + opacity: .3; + } +.ck.ck-button.ck-button_with-text, a.ck.ck-button.ck-button_with-text { + padding: var(--ck-spacing-tiny) var(--ck-spacing-standard); + + /* stylelint-disable-next-line no-descending-specificity */ + } +[dir="ltr"] .ck.ck-button.ck-button_with-text .ck-button__icon, [dir="ltr"] a.ck.ck-button.ck-button_with-text .ck-button__icon { + margin-right: var(--ck-spacing-medium); + } +[dir="rtl"] .ck.ck-button.ck-button_with-text .ck-button__icon, [dir="rtl"] a.ck.ck-button.ck-button_with-text .ck-button__icon { + margin-left: var(--ck-spacing-medium); + } +/* stylelint-disable-next-line no-descending-specificity */ +.ck.ck-button.ck-button_with-keystroke .ck-button__label, a.ck.ck-button.ck-button_with-keystroke .ck-button__label { + flex-grow: 1; + } +/* A style of the button which is currently on, e.g. its feature is active. */ +.ck.ck-button.ck-on, a.ck.ck-button.ck-on { + background: var(--ck-color-button-on-background); + + color: var(--ck-color-button-on-color); + } +.ck.ck-button.ck-on:not(.ck-disabled):hover, a.ck.ck-button.ck-on:not(.ck-disabled):hover { + background: var(--ck-color-button-on-hover-background); + } +.ck.ck-button.ck-on:not(.ck-disabled):active, a.ck.ck-button.ck-on:not(.ck-disabled):active { + background: var(--ck-color-button-on-active-background); + } +/* https://github.com/ckeditor/ckeditor5-theme-lark/issues/98 */ +.ck.ck-button.ck-on.ck-disabled, a.ck.ck-button.ck-on.ck-disabled { + background: var(--ck-color-button-on-disabled-background); + } +.ck.ck-button.ck-button-save, a.ck.ck-button.ck-button-save { + color: var(--ck-color-button-save); + } +.ck.ck-button.ck-button-cancel, a.ck.ck-button.ck-button-cancel { + color: var(--ck-color-button-cancel); + } +/* A style of the button which handles the primary action. */ +.ck.ck-button-action, +a.ck.ck-button-action { + background: var(--ck-color-button-action-background); + + color: var(--ck-color-button-action-text); +} +.ck.ck-button-action:not(.ck-disabled):hover, a.ck.ck-button-action:not(.ck-disabled):hover { + background: var(--ck-color-button-action-hover-background); + } +.ck.ck-button-action:not(.ck-disabled):active, a.ck.ck-button-action:not(.ck-disabled):active { + background: var(--ck-color-button-action-active-background); + } +/* https://github.com/ckeditor/ckeditor5-theme-lark/issues/98 */ +.ck.ck-button-action.ck-disabled, a.ck.ck-button-action.ck-disabled { + background: var(--ck-color-button-action-disabled-background); + } +.ck.ck-button-bold, +a.ck.ck-button-bold { + font-weight: bold; +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A class which indicates that an element holding it is disabled. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* Note: To avoid rendering issues (aliasing) but to preserve the responsive nature +of the component, floating–point numbers have been used which, for the default font size +(see: --ck-font-size-base), will generate simple integers. */ +:root { + /* 34px at 13px font-size */ + --ck-switch-button-toggle-width: 2.6153846154em; + /* 14px at 13px font-size */ + --ck-switch-button-toggle-inner-size: calc(1.0769230769em + 1px); + --ck-switch-button-translation: calc( + var(--ck-switch-button-toggle-width) - + var(--ck-switch-button-toggle-inner-size) - + 2px /* Border */ + ); + --ck-switch-button-inner-hover-shadow: 0 0 0 5px var(--ck-color-switch-button-inner-shadow); +} +/* Unlike a regular button, the switch button text color and background should never change. + * Changing toggle switch (background, outline) is enough to carry the information about the + * state of the entire component (https://github.com/ckeditor/ckeditor5/issues/12519) + */ +.ck.ck-button.ck-switchbutton, .ck.ck-button.ck-switchbutton:hover, .ck.ck-button.ck-switchbutton:focus, .ck.ck-button.ck-switchbutton:active, .ck.ck-button.ck-switchbutton.ck-on:hover, .ck.ck-button.ck-switchbutton.ck-on:focus, .ck.ck-button.ck-switchbutton.ck-on:active { + color: inherit; + background: transparent; + } +[dir="ltr"] .ck.ck-button.ck-switchbutton .ck-button__label { + /* Separate the label from the switch */ + margin-right: calc(2 * var(--ck-spacing-large)); + } +[dir="rtl"] .ck.ck-button.ck-switchbutton .ck-button__label { + /* Separate the label from the switch */ + margin-left: calc(2 * var(--ck-spacing-large)); + } +.ck.ck-button.ck-switchbutton .ck-button__toggle { + border-radius: 0; + + /* Apply some smooth transition to the box-shadow and border. */ + /* Gently animate the background color of the toggle switch */ + transition: background 400ms ease, box-shadow .2s ease-in-out, outline .2s ease-in-out; + border: 1px solid transparent; + width: var(--ck-switch-button-toggle-width); + background: var(--ck-color-switch-button-off-background); + } +.ck-rounded-corners .ck.ck-button.ck-switchbutton .ck-button__toggle, + .ck.ck-button.ck-switchbutton .ck-button__toggle.ck-rounded-corners { + border-radius: var(--ck-border-radius); + } +[dir="ltr"] .ck.ck-button.ck-switchbutton .ck-button__toggle { + /* Make sure the toggle is always to the right as far as possible. */ + margin-left: auto; + } +[dir="rtl"] .ck.ck-button.ck-switchbutton .ck-button__toggle { + /* Make sure the toggle is always to the left as far as possible. */ + margin-right: auto; + } +.ck.ck-button.ck-switchbutton .ck-button__toggle .ck-button__toggle__inner { + border-radius: 0; + + width: var(--ck-switch-button-toggle-inner-size); + height: var(--ck-switch-button-toggle-inner-size); + background: var(--ck-color-switch-button-inner-background); + + /* Gently animate the inner part of the toggle switch */ + transition: all 300ms ease; + } +.ck-rounded-corners .ck.ck-button.ck-switchbutton .ck-button__toggle .ck-button__toggle__inner, + .ck.ck-button.ck-switchbutton .ck-button__toggle .ck-button__toggle__inner.ck-rounded-corners { + border-radius: var(--ck-border-radius); + border-radius: calc(.5 * var(--ck-border-radius)); + } +@media (prefers-reduced-motion: reduce) { +.ck.ck-button.ck-switchbutton .ck-button__toggle .ck-button__toggle__inner { + transition: none; + } + } +.ck.ck-button.ck-switchbutton .ck-button__toggle:hover { + background: var(--ck-color-switch-button-off-hover-background); + } +.ck.ck-button.ck-switchbutton .ck-button__toggle:hover .ck-button__toggle__inner { + box-shadow: var(--ck-switch-button-inner-hover-shadow); + } +.ck.ck-button.ck-switchbutton.ck-disabled .ck-button__toggle { + opacity: var(--ck-disabled-opacity); + } +/* Overriding default .ck-button:focus styles + an outline around the toogle */ +.ck.ck-button.ck-switchbutton:focus { + border-color: transparent; + outline: none; + box-shadow: none; + } +.ck.ck-button.ck-switchbutton:focus .ck-button__toggle { + box-shadow: 0 0 0 1px var(--ck-color-base-background), 0 0 0 5px var(--ck-color-focus-outer-shadow); + outline-offset: 1px; + outline: var(--ck-focus-ring); + } +/* stylelint-disable-next-line no-descending-specificity */ +.ck.ck-button.ck-switchbutton.ck-on .ck-button__toggle { + background: var(--ck-color-switch-button-on-background); + } +.ck.ck-button.ck-switchbutton.ck-on .ck-button__toggle:hover { + background: var(--ck-color-switch-button-on-hover-background); + } +/* + * Move the toggle switch to the right. It will be animated. + */ +[dir="ltr"] .ck.ck-button.ck-switchbutton.ck-on .ck-button__toggle .ck-button__toggle__inner { + transform: translateX( var( --ck-switch-button-translation ) ); + } +[dir="rtl"] .ck.ck-button.ck-switchbutton.ck-on .ck-button__toggle .ck-button__toggle__inner { + transform: translateX( calc( -1 * var( --ck-switch-button-translation ) ) ); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-button.ck-list-item-button { + padding: var(--ck-spacing-tiny) calc(2 * var(--ck-spacing-standard)); +} +.ck.ck-button.ck-list-item-button, + .ck.ck-button.ck-list-item-button.ck-on { + background: var(--ck-color-list-background); + color: var(--ck-color-text); + } +[dir="ltr"] .ck.ck-button.ck-list-item-button:has(.ck-list-item-button__check-holder) { + padding-left: var(--ck-spacing-small); + } +[dir="rtl"] .ck.ck-button.ck-list-item-button:has(.ck-list-item-button__check-holder) { + padding-right: var(--ck-spacing-small); + } +/* + * `.ck-on` class and background styling is overridden for `ck-button` in many places. + * This is a workaround to make sure that the background is not overridden and uses similar + * selector specificity as the other overrides. + */ +.ck.ck-button.ck-list-item-button:hover:not(.ck-disabled), + .ck.ck-button.ck-list-item-button.ck-button.ck-on:hover, + .ck.ck-button.ck-list-item-button.ck-on:not(.ck-list-item-button_toggleable), + .ck.ck-button.ck-list-item-button.ck-on:hover { + background: var(--ck-color-list-button-hover-background); + } +.ck.ck-button.ck-list-item-button:hover:not(.ck-disabled):not(.ck-disabled), .ck.ck-button.ck-list-item-button.ck-button.ck-on:hover:not(.ck-disabled), .ck.ck-button.ck-list-item-button.ck-on:not(.ck-list-item-button_toggleable):not(.ck-disabled), .ck.ck-button.ck-list-item-button.ck-on:hover:not(.ck-disabled) { + color: var(--ck-color-text); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-collapsible-arrow-size: calc(0.5 * var(--ck-icon-size)); +} +.ck.ck-collapsible > .ck.ck-button { + width: 100%; + font-weight: bold; + border-radius: 0; + color: inherit; + } +.ck.ck-collapsible > .ck.ck-button:focus { + background: transparent; + } +.ck.ck-collapsible > .ck.ck-button:active, .ck.ck-collapsible > .ck.ck-button:not(:focus), .ck.ck-collapsible > .ck.ck-button:hover:not(:focus) { + background: transparent; + border-color: transparent; + box-shadow: none; + } +.ck.ck-collapsible > .ck.ck-button > .ck-icon { + margin-right: var(--ck-spacing-medium); + width: var(--ck-collapsible-arrow-size); + } +.ck.ck-collapsible > .ck-collapsible__children { + padding: var(--ck-spacing-medium) var(--ck-spacing-large) var(--ck-spacing-large); + } +.ck.ck-collapsible.ck-collapsible_collapsed > .ck.ck-button .ck-icon { + transform: rotate(-90deg); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-color-grid-tile-size: 24px; + + /* Not using global colors here because these may change but some colors in a pallette + * require special treatment. For instance, this ensures no matter what the UI text color is, + * the check icon will look good on the black color tile. */ + --ck-color-color-grid-check-icon: hsl(212, 81%, 46%); +} +.ck.ck-color-grid { + grid-gap: 5px; + padding: 8px; +} +.ck.ck-color-grid__tile { + transition: .2s ease box-shadow; +} +@media (forced-colors: none) { + .ck.ck-color-grid__tile { + width: var(--ck-color-grid-tile-size); + height: var(--ck-color-grid-tile-size); + min-width: var(--ck-color-grid-tile-size); + min-height: var(--ck-color-grid-tile-size); + padding: 0; + border: 0; + } + + .ck.ck-color-grid__tile.ck-on, + .ck.ck-color-grid__tile:focus:not( .ck-disabled ), + .ck.ck-color-grid__tile:hover:not( .ck-disabled ) { + /* Disable the default .ck-button's border ring. */ + border: 0; + } + + .ck.ck-color-grid__tile.ck-color-selector__color-tile_bordered { + box-shadow: 0 0 0 1px var(--ck-color-base-border); + } + + .ck.ck-color-grid__tile.ck-on { + box-shadow: inset 0 0 0 1px var(--ck-color-base-background), 0 0 0 2px var(--ck-color-base-text); + } + + .ck.ck-color-grid__tile:focus:not( .ck-disabled ), + .ck.ck-color-grid__tile:hover:not( .ck-disabled ) { + box-shadow: inset 0 0 0 1px var(--ck-color-base-background), 0 0 0 2px var(--ck-color-focus-border); + } + } +/* + * In high contrast mode, the colors are replaced with text labels. + * See https://github.com/ckeditor/ckeditor5/issues/14907. + */ +@media (forced-colors: active) { + .ck.ck-color-grid__tile { + width: unset; + height: unset; + min-width: unset; + min-height: unset; + padding: 0 var(--ck-spacing-small); + } + + .ck.ck-color-grid__tile .ck-button__label { + display: inline-block; + } + } +@media (prefers-reduced-motion: reduce) { +.ck.ck-color-grid__tile { + transition: none; +} + } +.ck.ck-color-grid__tile.ck-disabled { + cursor: unset; + transition: unset; + } +.ck.ck-color-grid__tile .ck.ck-icon { + display: none; + color: var(--ck-color-color-grid-check-icon); + } +.ck.ck-color-grid__tile.ck-on .ck.ck-icon { + display: block; + } +.ck.ck-color-grid__label { + padding: 0 var(--ck-spacing-standard); +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* View fragment with color grids. */ +.ck.ck-color-selector .ck-color-grids-fragment .ck-button.ck-color-selector__remove-color, + .ck.ck-color-selector .ck-color-grids-fragment .ck-button.ck-color-selector__color-picker { + width: 100%; + } +.ck.ck-color-selector .ck-color-grids-fragment .ck-button.ck-color-selector__color-picker { + padding: calc(var(--ck-spacing-standard) / 2) var(--ck-spacing-standard); + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } +.ck.ck-color-selector .ck-color-grids-fragment .ck-button.ck-color-selector__color-picker:not(:focus) { + border-top: 1px solid var(--ck-color-base-border); + } +[dir="ltr"] .ck.ck-color-selector .ck-color-grids-fragment .ck-button.ck-color-selector__color-picker .ck.ck-icon { + margin-right: var(--ck-spacing-standard); + } +[dir="rtl"] .ck.ck-color-selector .ck-color-grids-fragment .ck-button.ck-color-selector__color-picker .ck.ck-icon { + margin-left: var(--ck-spacing-standard); + } +.ck.ck-color-selector .ck-color-grids-fragment label.ck.ck-color-grid__label { + font-weight: unset; + } +/* View fragment with a color picker. */ +.ck.ck-color-selector .ck-color-picker-fragment .ck.ck-color-picker { + padding: 8px; + } +.ck.ck-color-selector .ck-color-picker-fragment .ck.ck-color-picker .hex-color-picker { + height: 100px; + min-width: 180px; + } +.ck.ck-color-selector .ck-color-picker-fragment .ck.ck-color-picker .hex-color-picker::part(saturation) { + border-radius: var(--ck-border-radius) var(--ck-border-radius) 0 0; + } +.ck.ck-color-selector .ck-color-picker-fragment .ck.ck-color-picker .hex-color-picker::part(hue) { + border-radius: 0 0 var(--ck-border-radius) var(--ck-border-radius); + } +.ck.ck-color-selector .ck-color-picker-fragment .ck.ck-color-picker .hex-color-picker::part(saturation-pointer), + .ck.ck-color-selector .ck-color-picker-fragment .ck.ck-color-picker .hex-color-picker::part(hue-pointer) { + width: 15px; + height: 15px; + } +.ck.ck-color-selector .ck-color-picker-fragment .ck.ck-color-selector_action-bar { + padding: 0 8px 8px; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-dialog-overlay-background-color: hsla( 0, 0%, 0%, .5 ); + --ck-dialog-drop-shadow: 0px 0px 6px 2px hsl(0deg 0% 0% / 15%); + --ck-dialog-max-width: 100vw; + --ck-dialog-max-height: 90vh; + --ck-color-dialog-background: var(--ck-color-base-background); + --ck-color-dialog-form-header-border: var(--ck-color-base-border); +} +.ck.ck-dialog-overlay { + animation: ck-dialog-fade-in .3s; + background: var(--ck-dialog-overlay-background-color); + z-index: var(--ck-z-dialog); +} +.ck.ck-dialog { + border-radius: 0; + + --ck-drop-shadow: var(--ck-dialog-drop-shadow); + + background: var(--ck-color-dialog-background); + max-height: var(--ck-dialog-max-height); + max-width: var(--ck-dialog-max-width); + border: 1px solid var(--ck-color-base-border); + overscroll-behavior: contain; +} +.ck-rounded-corners .ck.ck-dialog, + .ck.ck-dialog.ck-rounded-corners { + border-radius: var(--ck-border-radius); + } +.ck.ck-dialog { + box-shadow: var(--ck-drop-shadow), 0 0; +} +.ck.ck-dialog .ck.ck-form__header { + border-bottom: 1px solid var(--ck-color-dialog-form-header-border); + } +.ck-dialog-scroll-locked { + overflow: hidden; +} +@keyframes ck-dialog-fade-in { + 0% { + background: hsla( 0, 0%, 0%, 0 ); + } + + 100% { + background: var(--ck-dialog-overlay-background-color); + } +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-dialog .ck.ck-dialog__actions { + padding: var(--ck-spacing-large); + } +.ck.ck-dialog .ck.ck-dialog__actions > * + * { + margin-left: var(--ck-spacing-large); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A class which indicates that an element holding it is disabled. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-dropdown-arrow-size: calc(0.5 * var(--ck-icon-size)); +} +.ck.ck-dropdown { + /* Enable font size inheritance, which allows fluid UI scaling. */ + font-size: inherit; +} +.ck.ck-dropdown .ck-dropdown__arrow { + width: var(--ck-dropdown-arrow-size); + } +[dir="ltr"] .ck.ck-dropdown .ck-dropdown__arrow { + right: var(--ck-spacing-standard); + + /* A space to accommodate the triangle. */ + margin-left: var(--ck-spacing-standard); + } +[dir="rtl"] .ck.ck-dropdown .ck-dropdown__arrow { + left: var(--ck-spacing-standard); + + /* A space to accommodate the triangle. */ + margin-right: var(--ck-spacing-small); + } +.ck.ck-dropdown.ck-disabled .ck-dropdown__arrow { + opacity: var(--ck-disabled-opacity); + } +[dir="ltr"] .ck.ck-dropdown .ck-button.ck-dropdown__button:not(.ck-button_with-text) { + /* Make sure dropdowns with just an icon have the right inner spacing */ + padding-left: var(--ck-spacing-small); + } +[dir="rtl"] .ck.ck-dropdown .ck-button.ck-dropdown__button:not(.ck-button_with-text) { + /* Make sure dropdowns with just an icon have the right inner spacing */ + padding-right: var(--ck-spacing-small); + } +/* #23 */ +.ck.ck-dropdown .ck-button.ck-dropdown__button .ck-button__label { + width: 7em; + overflow: hidden; + text-overflow: ellipsis; + } +/* https://github.com/ckeditor/ckeditor5-theme-lark/issues/70 */ +.ck.ck-dropdown .ck-button.ck-dropdown__button.ck-disabled .ck-button__label { + opacity: var(--ck-disabled-opacity); + } +/* https://github.com/ckeditor/ckeditor5/issues/816 */ +.ck.ck-dropdown .ck-button.ck-dropdown__button.ck-on { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } +.ck.ck-dropdown .ck-button.ck-dropdown__button.ck-dropdown__button_label-width_auto .ck-button__label { + width: auto; + } +/* https://github.com/ckeditor/ckeditor5/issues/8699 */ +.ck.ck-dropdown .ck-button.ck-dropdown__button.ck-off:active, + .ck.ck-dropdown .ck-button.ck-dropdown__button.ck-on:active { + box-shadow: none; + } +.ck.ck-dropdown .ck-button.ck-dropdown__button.ck-off:active:focus, .ck.ck-dropdown .ck-button.ck-dropdown__button.ck-on:active:focus { + box-shadow: var(--ck-focus-outer-shadow), 0 0; + } +.ck.ck-dropdown__panel { + border-radius: 0; + + background: var(--ck-color-dropdown-panel-background); + border: 1px solid var(--ck-color-dropdown-panel-border); + bottom: 0; + + /* Make sure the panel is at least as wide as the drop-down's button. */ + min-width: 100%; +} +.ck-rounded-corners .ck.ck-dropdown__panel, + .ck.ck-dropdown__panel.ck-rounded-corners { + border-radius: var(--ck-border-radius); + } +.ck.ck-dropdown__panel { + box-shadow: var(--ck-drop-shadow), 0 0; + + /* Disabled corner border radius to be consistent with the .dropdown__button + https://github.com/ckeditor/ckeditor5/issues/816 */ +} +.ck.ck-dropdown__panel.ck-dropdown__panel_se { + border-top-left-radius: 0; + } +.ck.ck-dropdown__panel.ck-dropdown__panel_sw { + border-top-right-radius: 0; + } +.ck.ck-dropdown__panel.ck-dropdown__panel_ne { + border-bottom-left-radius: 0; + } +.ck.ck-dropdown__panel.ck-dropdown__panel_nw { + border-bottom-right-radius: 0; + } +.ck.ck-dropdown__panel:focus { + outline: none; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +.ck.ck-dropdown > .ck-dropdown__panel > .ck-list { + /* Disabled radius of top-left border to be consistent with .dropdown__button + https://github.com/ckeditor/ckeditor5/issues/816 */ + border-radius: 0; +} +.ck-rounded-corners .ck.ck-dropdown > .ck-dropdown__panel > .ck-list, + .ck.ck-dropdown > .ck-dropdown__panel > .ck-list.ck-rounded-corners { + border-radius: var(--ck-border-radius); + border-top-left-radius: 0; + } +/* Make sure the button belonging to the first/last child of the list goes well with the + border radius of the entire panel. */ +.ck.ck-dropdown > .ck-dropdown__panel > .ck-list .ck-list__item:first-child > .ck-button { + border-radius: 0; + } +.ck-rounded-corners .ck.ck-dropdown > .ck-dropdown__panel > .ck-list .ck-list__item:first-child > .ck-button, + .ck.ck-dropdown > .ck-dropdown__panel > .ck-list .ck-list__item:first-child > .ck-button.ck-rounded-corners { + border-radius: var(--ck-border-radius); + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } +.ck.ck-dropdown > .ck-dropdown__panel > .ck-list .ck-list__item:last-child > .ck-button { + border-radius: 0; + } +.ck-rounded-corners .ck.ck-dropdown > .ck-dropdown__panel > .ck-list .ck-list__item:last-child > .ck-button, + .ck.ck-dropdown > .ck-dropdown__panel > .ck-list .ck-list__item:last-child > .ck-button.ck-rounded-corners { + border-radius: var(--ck-border-radius); + border-top-left-radius: 0; + border-top-right-radius: 0; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +:root { + --ck-color-split-button-hover-background: hsl(0, 0%, 92%); + --ck-color-split-button-hover-border: hsl(0, 0%, 70%); +} +/* + * Note: ck-rounded and ck-dir mixins don't go together (because they both use @nest). + */ +[dir="ltr"] .ck.ck-splitbutton:hover > .ck-splitbutton__action, [dir="ltr"] .ck.ck-splitbutton.ck-splitbutton_open > .ck-splitbutton__action { + /* Don't round the action button on the right side */ + border-top-right-radius: unset; + border-bottom-right-radius: unset; + } +[dir="rtl"] .ck.ck-splitbutton:hover > .ck-splitbutton__action, [dir="rtl"] .ck.ck-splitbutton.ck-splitbutton_open > .ck-splitbutton__action { + /* Don't round the action button on the left side */ + border-top-left-radius: unset; + border-bottom-left-radius: unset; + } +.ck.ck-splitbutton > .ck-splitbutton__arrow { + /* It's a text-less button and since the icon is positioned absolutely in such situation, + it must get some arbitrary min-width. */ + min-width: unset; + } +[dir="ltr"] .ck.ck-splitbutton > .ck-splitbutton__arrow { + /* Don't round the arrow button on the left side */ + border-top-left-radius: unset; + border-bottom-left-radius: unset; + } +[dir="rtl"] .ck.ck-splitbutton > .ck-splitbutton__arrow { + /* Don't round the arrow button on the right side */ + border-top-right-radius: unset; + border-bottom-right-radius: unset; + } +.ck.ck-splitbutton > .ck-splitbutton__arrow svg { + width: var(--ck-dropdown-arrow-size); + } +/* Make sure the divider stretches 100% height of the button + https://github.com/ckeditor/ckeditor5/issues/10936 */ +.ck.ck-splitbutton > .ck-splitbutton__arrow:not(:focus) { + border-top-width: 0px; + border-bottom-width: 0px; + } +/* Don't round the bottom left and right corners of the buttons when "open" + https://github.com/ckeditor/ckeditor5/issues/816 */ +.ck.ck-splitbutton.ck-splitbutton_open { + border-radius: 0; + } +.ck-rounded-corners .ck.ck-splitbutton.ck-splitbutton_open, + .ck.ck-splitbutton.ck-splitbutton_open.ck-rounded-corners { + border-radius: var(--ck-border-radius); + } +.ck-rounded-corners .ck.ck-splitbutton.ck-splitbutton_open > .ck-splitbutton__action, .ck.ck-splitbutton.ck-splitbutton_open.ck-rounded-corners > .ck-splitbutton__action { + border-bottom-left-radius: 0; + } +.ck-rounded-corners .ck.ck-splitbutton.ck-splitbutton_open > .ck-splitbutton__arrow, .ck.ck-splitbutton.ck-splitbutton_open.ck-rounded-corners > .ck-splitbutton__arrow { + border-bottom-right-radius: 0; + } +/* When the split button is "open" (the arrow is on) or being hovered, it should get some styling + as a whole. The background of both buttons should stand out and there should be a visual + separation between both buttons. */ +/* When the split button hovered as a whole, not as individual buttons. */ +.ck.ck-splitbutton.ck-splitbutton_open > .ck-button:not(.ck-on):not(.ck-disabled):not(:hover), .ck.ck-splitbutton:hover > .ck-button:not(.ck-on):not(.ck-disabled):not(:hover) { + background: var(--ck-color-split-button-hover-background); + } +/* Splitbutton separator needs to be set with the ::after pseudoselector + to display properly the borders on focus */ +.ck.ck-splitbutton.ck-splitbutton_open > .ck-splitbutton__arrow:not(.ck-disabled)::after, .ck.ck-splitbutton:hover > .ck-splitbutton__arrow:not(.ck-disabled)::after { + content: ''; + position: absolute; + width: 1px; + height: 100%; + background-color: var(--ck-color-split-button-hover-border); + } +/* Make sure the divider between the buttons looks fine when the button is focused */ +.ck.ck-splitbutton.ck-splitbutton_open > .ck-splitbutton__arrow:focus::after, .ck.ck-splitbutton:hover > .ck-splitbutton__arrow:focus::after { + --ck-color-split-button-hover-border: var(--ck-color-focus-border); + } +[dir="ltr"] .ck.ck-splitbutton.ck-splitbutton_open > .ck-splitbutton__arrow:not(.ck-disabled)::after, [dir="ltr"] .ck.ck-splitbutton:hover > .ck-splitbutton__arrow:not(.ck-disabled)::after { + left: -1px; + } +[dir="rtl"] .ck.ck-splitbutton.ck-splitbutton_open > .ck-splitbutton__arrow:not(.ck-disabled)::after, [dir="rtl"] .ck.ck-splitbutton:hover > .ck-splitbutton__arrow:not(.ck-disabled)::after { + right: -1px; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-toolbar-dropdown .ck-toolbar { + border: 0; +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A class which indicates that an element holding it is disabled. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements a button of given background color. + * + * @param {String} $background - Background color of the button. + * @param {String} $border - Border color of the button. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * All menu buttons. + */ +.ck.ck-button.ck-dropdown-menu-list__nested-menu__button { + width: 100%; + padding: var(--ck-spacing-tiny) calc(2 * var(--ck-spacing-standard)); + border-radius: 0; +} +.ck.ck-button.ck-dropdown-menu-list__nested-menu__button:focus { + border-color: transparent; + box-shadow: none; + } +.ck.ck-button.ck-dropdown-menu-list__nested-menu__button:focus:not(.ck-on) { + background: var(--ck-color-button-default-hover-background); + } +.ck.ck-button.ck-dropdown-menu-list__nested-menu__button > .ck-button__label { + flex-grow: 1; + overflow: hidden; + text-overflow: ellipsis; + } +.ck.ck-button.ck-dropdown-menu-list__nested-menu__button.ck-disabled > .ck-button__label { + opacity: var(--ck-disabled-opacity); + } +/* Spacing in buttons that miss the icon. */ +.ck.ck-button.ck-dropdown-menu-list__nested-menu__button.ck-icon-spacing:not(:has(.ck-button__icon)) > .ck-button__label { + margin-left: calc(var(--ck-icon-size) - var(--ck-spacing-small)); + } +.ck.ck-button.ck-dropdown-menu-list__nested-menu__button > .ck-dropdown-menu-list__nested-menu__button__arrow { + width: var(--ck-dropdown-arrow-size); + } +[dir="ltr"] .ck.ck-button.ck-dropdown-menu-list__nested-menu__button > .ck-dropdown-menu-list__nested-menu__button__arrow { + transform: rotate(-90deg); + + /* Nudge the arrow gently to the right because its center of gravity is to the left */ + margin-right: calc(-1 * var(--ck-spacing-small)); + } +[dir="rtl"] .ck.ck-button.ck-dropdown-menu-list__nested-menu__button > .ck-dropdown-menu-list__nested-menu__button__arrow { + transform: rotate(90deg); + + /* Nudge the arrow gently to the left because its center of gravity is to the right (after rotation). */ + margin-left: calc(-1 * var(--ck-spacing-small)); + } +.ck.ck-button.ck-dropdown-menu-list__nested-menu__button.ck-disabled > .ck-dropdown-menu-list__nested-menu__button__arrow { + opacity: var(--ck-disabled-opacity); + } +[dir="ltr"] .ck.ck-button.ck-dropdown-menu-list__nested-menu__button:not(.ck-button_with-text) { + padding-left: var(--ck-spacing-small); + } +[dir="ltr"] .ck.ck-button.ck-dropdown-menu-list__nested-menu__button > .ck-dropdown-menu-list__nested-menu__button__arrow { + right: var(--ck-spacing-standard); + + /* A space to accommodate the triangle. */ + margin-left: var(--ck-spacing-standard); + } +[dir="rtl"] .ck.ck-button.ck-dropdown-menu-list__nested-menu__button:not(.ck-button_with-text) { + padding-right: var(--ck-spacing-small); + } +[dir="rtl"] .ck.ck-button.ck-dropdown-menu-list__nested-menu__button > .ck-dropdown-menu-list__nested-menu__button__arrow { + left: var(--ck-spacing-standard); + + /* A space to accommodate the triangle. */ + margin-right: var(--ck-spacing-small); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-dropdown-menu-menu-item-min-width: 18em; +} +.ck.ck-dropdown-menu-list__nested-menu__item { + min-width: var(--ck-dropdown-menu-menu-item-min-width); +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * List item buttons. + */ +.ck-button.ck-dropdown-menu-list__nested-menu__item__button { + border-radius: 0; +} +.ck-button.ck-dropdown-menu-list__nested-menu__item__button > .ck-spinner-container, + .ck-button.ck-dropdown-menu-list__nested-menu__item__button > .ck-spinner-container .ck-spinner { + /* These styles correspond to .ck-icon so that the spinner seamlessly replaces the icon. */ + --ck-toolbar-spinner-size: 20px; + } +.ck-button.ck-dropdown-menu-list__nested-menu__item__button > .ck-spinner-container { + /* These margins are the same as for .ck-icon. */ + margin-left: calc(-1 * var(--ck-spacing-small)); + margin-right: var(--ck-spacing-small); + } +/* + * Hovered items automatically get focused. Default focus styles look odd + * while moving across a huge list of items so let's get rid of them + */ +.ck-button.ck-dropdown-menu-list__nested-menu__item__button:focus { + border-color: transparent; + box-shadow: none; + } +.ck-button.ck-dropdown-menu-list__nested-menu__item__button:focus:not(.ck-on) { + background: var(--ck-color-button-default-hover-background); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ +:root { + --ck-dropdown-menu-menu-panel-max-width: 75vw; +} +.ck.ck-balloon-panel.ck-dropdown-menu__nested-menu__panel { + box-shadow: var(--ck-drop-shadow), 0 0; + + background: var(--ck-color-dropdown-panel-background); + border: 1px solid var(--ck-color-dropdown-panel-border); + bottom: 0; + height: fit-content; + max-width: var(--ck-dropdown-menu-menu-panel-max-width); + + /* Reset balloon styling */ +} +.ck.ck-balloon-panel.ck-dropdown-menu__nested-menu__panel::after, + .ck.ck-balloon-panel.ck-dropdown-menu__nested-menu__panel::before { + display: none; + } +/* Corner border radius consistent with the button. */ +.ck.ck-balloon-panel.ck-dropdown-menu__nested-menu__panel.ck-balloon-panel_es, + .ck.ck-balloon-panel.ck-dropdown-menu__nested-menu__panel.ck-balloon-panel_se { + border-top-left-radius: 0; + } +.ck.ck-balloon-panel.ck-dropdown-menu__nested-menu__panel.ck-balloon-panel_ws, + .ck.ck-balloon-panel.ck-dropdown-menu__nested-menu__panel.ck-balloon-panel_sw { + border-top-right-radius: 0; + } +.ck.ck-balloon-panel.ck-dropdown-menu__nested-menu__panel.ck-balloon-panel_en, + .ck.ck-balloon-panel.ck-dropdown-menu__nested-menu__panel.ck-balloon-panel_ne { + border-bottom-left-radius: 0; + } +.ck.ck-balloon-panel.ck-dropdown-menu__nested-menu__panel.ck-balloon-panel_wn, + .ck.ck-balloon-panel.ck-dropdown-menu__nested-menu__panel.ck-balloon-panel_nw { + border-bottom-right-radius: 0; + } +.ck.ck-balloon-panel.ck-dropdown-menu__nested-menu__panel:focus { + outline: none; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A visual style of focused element's border. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ +:root { + --ck-accessibility-help-dialog-max-width: 600px; + --ck-accessibility-help-dialog-max-height: 400px; + --ck-accessibility-help-dialog-border-color: hsl(220, 6%, 81%); + --ck-accessibility-help-dialog-code-background-color: hsl(0deg 0% 92.94%); + --ck-accessibility-help-dialog-kbd-shadow-color: hsl(0deg 0% 61%); +} +.ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content { + padding: var(--ck-spacing-large); + max-width: var(--ck-accessibility-help-dialog-max-width); + max-height: var(--ck-accessibility-help-dialog-max-height); + overflow: auto; + user-select: text; + + border: 1px solid transparent; +} +.ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content:focus { + /* Disable native outline. */ + outline: none; + border: var(--ck-focus-ring); + box-shadow: var(--ck-focus-outer-shadow), 0 0; + } +.ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content * { + white-space: normal; + } +/* Hide the main label of the content container. */ +.ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content .ck-label { + display: none; + } +.ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content h3 { + font-weight: bold; + font-size: 1.2em; + } +.ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content h4 { + font-weight: bold; + font-size: 1em; + } +.ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content p, + .ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content h3, + .ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content h4, + .ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content table { + margin: 1em 0; + } +.ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content dl { + display: grid; + grid-template-columns: 2fr 1fr; + border-top: 1px solid var(--ck-accessibility-help-dialog-border-color); + border-bottom: none; + } +.ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content dl dt, .ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content dl dd { + border-bottom: 1px solid var(--ck-accessibility-help-dialog-border-color); + padding: .4em 0; + } +.ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content dl dt { + grid-column-start: 1; + } +.ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content dl dd { + grid-column-start: 2; + text-align: right; + } +.ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content kbd, .ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content code { + display: inline-block; + background: var(--ck-accessibility-help-dialog-code-background-color); + padding: .4em; + vertical-align: middle; + line-height: 1; + border-radius: 2px; + text-align: center; + font-size: .9em; + } +.ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content code { + font-family: monospace; + } +.ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content kbd { + min-width: 1.8em; + box-shadow: 0px 1px 1px var(--ck-accessibility-help-dialog-kbd-shadow-color); + margin: 0 1px; + } +.ck.ck-accessibility-help-dialog .ck-accessibility-help-dialog__content kbd + kbd { + margin-left: 2px; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A class which indicates that an element holding it is disabled. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A visual style of focused element's border. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements a button of given background color. + * + * @param {String} $background - Background color of the button. + * @param {String} $border - Border color of the button. + */ +:root { + --ck-color-editable-blur-selection: hsl(0, 0%, 85%); +} +.ck.ck-editor__editable:not(.ck-editor__nested-editable) { + border-radius: 0; +} +.ck-rounded-corners .ck.ck-editor__editable:not(.ck-editor__nested-editable), + .ck.ck-editor__editable.ck-rounded-corners:not(.ck-editor__nested-editable) { + border-radius: var(--ck-border-radius); + } +.ck.ck-editor__editable.ck-focused:not(.ck-editor__nested-editable) { + /* Disable native outline. */ + outline: none; + border: var(--ck-focus-ring); + box-shadow: var(--ck-inner-shadow), 0 0; + } +.ck.ck-editor__editable_inline { + overflow: auto; + padding: 0 var(--ck-spacing-standard); + border: 1px solid transparent; +} +.ck.ck-editor__editable_inline[dir="ltr"] { + text-align: left; + } +.ck.ck-editor__editable_inline[dir="rtl"] { + text-align: right; + } +/* https://github.com/ckeditor/ckeditor5-theme-lark/issues/116 */ +.ck.ck-editor__editable_inline > *:first-child { + margin-top: var(--ck-spacing-large); + } +/* https://github.com/ckeditor/ckeditor5/issues/847 */ +.ck.ck-editor__editable_inline > *:last-child { + /* + * This value should match with the default margins of the block elements (like .media or .image) + * to avoid a content jumping when the fake selection container shows up (See https://github.com/ckeditor/ckeditor5/issues/9825). + */ + margin-bottom: var(--ck-spacing-large); + } +/* https://github.com/ckeditor/ckeditor5/issues/6517 */ +.ck.ck-editor__editable_inline.ck-blurred ::selection { + background: var(--ck-color-editable-blur-selection); + } +/* https://github.com/ckeditor/ckeditor5-theme-lark/issues/111 */ +.ck.ck-balloon-panel.ck-toolbar-container[class*="arrow_n"]::after { + border-bottom-color: var(--ck-color-panel-background); + } +.ck.ck-balloon-panel.ck-toolbar-container[class*="arrow_s"]::after { + border-top-color: var(--ck-color-panel-background); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-form-header-height: 44px; +} +.ck.ck-form__header { + padding: var(--ck-spacing-small) var(--ck-spacing-large); + height: var(--ck-form-header-height); + line-height: var(--ck-form-header-height); + border-bottom: 1px solid var(--ck-color-base-border); +} +[dir="ltr"] .ck.ck-form__header > .ck-icon { + margin-right: var(--ck-spacing-medium); + } +[dir="rtl"] .ck.ck-form__header > .ck-icon { + margin-left: var(--ck-spacing-medium); + } +.ck.ck-form__header .ck-form__header__label { + --ck-font-size-base: 15px; + font-weight: bold; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-icon-size: calc(var(--ck-line-height-base) * var(--ck-font-size-normal)); + --ck-icon-font-size: .8333350694em; +} +.ck.ck-icon { + width: var(--ck-icon-size); + height: var(--ck-icon-size); + + /* Multiplied by the height of the line in "px" should give SVG "viewport" dimensions */ + font-size: var(--ck-icon-font-size); + + /* Inherit cursor style (#5). */ + cursor: inherit; + + /* This will prevent blurry icons on Firefox. See #340. */ + will-change: transform; +} +.ck.ck-icon * { + /* Inherit cursor style (#5). */ + cursor: inherit; + } +/* Allows dynamic coloring of an icon by inheriting its color from the parent. */ +.ck.ck-icon.ck-icon_inherit-color { + color: inherit; + } +.ck.ck-icon.ck-icon_inherit-color * { + color: inherit; + } +.ck.ck-icon.ck-icon_inherit-color *:not([fill]) { + /* Needed by FF. */ + fill: currentColor; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A visual style of focused element's border. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ +:root { + --ck-input-width: 18em; + + /* Backward compatibility. */ + --ck-input-text-width: var(--ck-input-width); +} +.ck.ck-input { + border-radius: 0; + + background: var(--ck-color-input-background); + border: 1px solid var(--ck-color-input-border); + padding: var(--ck-spacing-extra-tiny) var(--ck-spacing-medium); + min-width: var(--ck-input-width); + + /* This is important to stay of the same height as surrounding buttons */ + min-height: var(--ck-ui-component-min-height); + + /* Apply some smooth transition to the box-shadow and border. */ + transition: box-shadow .1s ease-in-out, border .1s ease-in-out; +} +.ck-rounded-corners .ck.ck-input, + .ck.ck-input.ck-rounded-corners { + border-radius: var(--ck-border-radius); + } +@media (prefers-reduced-motion: reduce) { +.ck.ck-input { + transition: none; +} + } +.ck.ck-input:focus { + /* Disable native outline. */ + outline: none; + border: var(--ck-focus-ring); + box-shadow: var(--ck-focus-outer-shadow), 0 0; + } +.ck.ck-input[readonly] { + border: 1px solid var(--ck-color-input-disabled-border); + background: var(--ck-color-input-disabled-background); + color: var(--ck-color-input-disabled-text); + } +.ck.ck-input[readonly]:focus { + /* The read-only input should have a slightly less visible shadow when focused. */ + box-shadow: var(--ck-focus-disabled-outer-shadow), 0 0; + } +.ck.ck-input.ck-error { + border-color: var(--ck-color-input-error-border); + animation: ck-input-shake .3s ease both; + } +@media (prefers-reduced-motion: reduce) { +.ck.ck-input.ck-error { + animation: none; + } + } +.ck.ck-input.ck-error:focus { + box-shadow: var(--ck-focus-error-outer-shadow), 0 0; + } +@keyframes ck-input-shake { + 20% { + transform: translateX(-2px); + } + + 40% { + transform: translateX(2px); + } + + 60% { + transform: translateX(-1px); + } + + 80% { + transform: translateX(1px); + } +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-label { + font-weight: bold; +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +:root { + --ck-labeled-field-view-transition: .1s cubic-bezier(0, 0, 0.24, 0.95); + --ck-labeled-field-empty-unfocused-max-width: 100% - 2 * var(--ck-spacing-medium); + --ck-labeled-field-label-default-position-x: var(--ck-spacing-medium); + --ck-labeled-field-label-default-position-y: calc(0.6 * var(--ck-font-size-base)); + --ck-color-labeled-field-label-background: var(--ck-color-base-background); +} +.ck.ck-labeled-field-view { + border-radius: 0; +} +.ck-rounded-corners .ck.ck-labeled-field-view, + .ck.ck-labeled-field-view.ck-rounded-corners { + border-radius: var(--ck-border-radius); + } +.ck.ck-labeled-field-view > .ck.ck-labeled-field-view__input-wrapper { + width: 100%; + } +.ck.ck-labeled-field-view > .ck.ck-labeled-field-view__input-wrapper > .ck.ck-label { + top: 0px; + + pointer-events: none; + + background: var(--ck-color-labeled-field-label-background); + padding: 0 calc(.5 * var(--ck-font-size-tiny)); + line-height: initial; + font-weight: normal; + + /* Prevent overflow when the label is longer than the input */ + text-overflow: ellipsis; + overflow: hidden; + + max-width: 100%; + + transition: + transform var(--ck-labeled-field-view-transition), + padding var(--ck-labeled-field-view-transition), + background var(--ck-labeled-field-view-transition); + } +[dir="ltr"] .ck.ck-labeled-field-view > .ck.ck-labeled-field-view__input-wrapper > .ck.ck-label { + left: 0px; + transform-origin: 0 0; + /* By default, display the label scaled down above the field. */ + transform: translate(var(--ck-spacing-medium), -6px) scale(.75); + } +[dir="rtl"] .ck.ck-labeled-field-view > .ck.ck-labeled-field-view__input-wrapper > .ck.ck-label { + right: 0px; + transform-origin: 100% 0; + transform: translate(calc(-1 * var(--ck-spacing-medium)), -6px) scale(.75); + } +@media (prefers-reduced-motion: reduce) { +.ck.ck-labeled-field-view > .ck.ck-labeled-field-view__input-wrapper > .ck.ck-label { + transition: none; + } + } +.ck.ck-labeled-field-view.ck-error > .ck.ck-labeled-field-view__input-wrapper > .ck.ck-label { + color: var(--ck-color-base-error); + } +.ck.ck-labeled-field-view.ck-error .ck-input:not([readonly]) + .ck.ck-label { + color: var(--ck-color-base-error); + } +.ck.ck-labeled-field-view .ck-labeled-field-view__status { + font-size: var(--ck-font-size-small); + margin-top: var(--ck-spacing-small); + + /* Let the info wrap to the next line to avoid stretching the layout horizontally. + The status could be very long. */ + white-space: normal; + } +.ck.ck-labeled-field-view .ck-labeled-field-view__status.ck-labeled-field-view__status_error { + color: var(--ck-color-base-error); + } +/* Disabled fields and fields that have no focus should fade out. */ +.ck.ck-labeled-field-view.ck-disabled > .ck.ck-labeled-field-view__input-wrapper > .ck.ck-label, + .ck.ck-labeled-field-view.ck-labeled-field-view_empty:not(.ck-labeled-field-view_focused) > .ck.ck-labeled-field-view__input-wrapper > .ck.ck-label { + color: var(--ck-color-input-disabled-text); + } +/* Fields that are disabled or not focused and without a placeholder should have full-sized labels. */ +/* stylelint-disable-next-line no-descending-specificity */ +.ck.ck-labeled-field-view.ck-disabled.ck-labeled-field-view_empty:not(.ck-labeled-field-view_placeholder) > .ck.ck-labeled-field-view__input-wrapper > .ck.ck-label, + .ck.ck-labeled-field-view.ck-labeled-field-view_empty:not(.ck-labeled-field-view_focused):not(.ck-labeled-field-view_placeholder):not(.ck-error) > .ck.ck-labeled-field-view__input-wrapper > .ck.ck-label { + + /* Compensate for the default translate position. */ + max-width: calc(var(--ck-labeled-field-empty-unfocused-max-width)); + + background: transparent; + padding: 0; + } +[dir="ltr"] .ck.ck-labeled-field-view.ck-disabled.ck-labeled-field-view_empty:not(.ck-labeled-field-view_placeholder) > .ck.ck-labeled-field-view__input-wrapper > .ck.ck-label, [dir="ltr"] .ck.ck-labeled-field-view.ck-labeled-field-view_empty:not(.ck-labeled-field-view_focused):not(.ck-labeled-field-view_placeholder):not(.ck-error) > .ck.ck-labeled-field-view__input-wrapper > .ck.ck-label { + transform: translate(var(--ck-labeled-field-label-default-position-x), var(--ck-labeled-field-label-default-position-y)) scale(1); + } +[dir="rtl"] .ck.ck-labeled-field-view.ck-disabled.ck-labeled-field-view_empty:not(.ck-labeled-field-view_placeholder) > .ck.ck-labeled-field-view__input-wrapper > .ck.ck-label, [dir="rtl"] .ck.ck-labeled-field-view.ck-labeled-field-view_empty:not(.ck-labeled-field-view_focused):not(.ck-labeled-field-view_placeholder):not(.ck-error) > .ck.ck-labeled-field-view__input-wrapper > .ck.ck-label { + transform: translate(calc(-1 * var(--ck-labeled-field-label-default-position-x)), var(--ck-labeled-field-label-default-position-y)) scale(1); + } +/*------ DropdownView integration ----------------------------------------------------------------------------------- */ +/* Make sure dropdown' background color in any of dropdown's state does not collide with labeled field. */ +.ck.ck-labeled-field-view > .ck.ck-labeled-field-view__input-wrapper > .ck-dropdown > .ck.ck-button { + background: transparent; + } +/* When the dropdown is "empty", the labeled field label replaces its label. */ +.ck.ck-labeled-field-view.ck-labeled-field-view_empty > .ck.ck-labeled-field-view__input-wrapper > .ck-dropdown > .ck-button > .ck-button__label { + opacity: 0; + } +/* Make sure the label of the empty, unfocused input does not cover the dropdown arrow. */ +.ck.ck-labeled-field-view.ck-labeled-field-view_empty:not(.ck-labeled-field-view_focused):not(.ck-labeled-field-view_placeholder) > .ck.ck-labeled-field-view__input-wrapper > .ck-dropdown + .ck-label { + max-width: calc(var(--ck-labeled-field-empty-unfocused-max-width) - var(--ck-dropdown-arrow-size) - var(--ck-spacing-standard)); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-labeled-input .ck-labeled-input__status { + font-size: var(--ck-font-size-small); + margin-top: var(--ck-spacing-small); + + /* Let the info wrap to the next line to avoid stretching the layout horizontally. + The status could be very long. */ + white-space: normal; +} +.ck.ck-labeled-input .ck-labeled-input__status_error { + color: var(--ck-color-base-error); +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A class which indicates that an element holding it is disabled. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-list { + border-radius: 0; + + list-style-type: none; + background: var(--ck-color-list-background); + + /* A spacing at the beginning and end of the list */ + padding: var(--ck-spacing-small) 0; +} +.ck-rounded-corners .ck.ck-list, + .ck.ck-list.ck-rounded-corners { + border-radius: var(--ck-border-radius); + } +.ck.ck-list__item { + cursor: default; + + /* Almost as wide as menu bar items. */ + min-width: 15em; +} +.ck.ck-list__item > .ck-button:not(.ck-list-item-button) { + padding: var(--ck-spacing-tiny) calc(2 * var(--ck-spacing-standard)); + min-height: unset; + width: 100%; + border-radius: 0; + } +[dir="ltr"] .ck.ck-list__item > .ck-button:not(.ck-list-item-button) { + text-align: left; + } +[dir="rtl"] .ck.ck-list__item > .ck-button:not(.ck-list-item-button) { + text-align: right; + } +.ck.ck-list__item > .ck-button:not(.ck-list-item-button) .ck-button__label { + /* https://github.com/ckeditor/ckeditor5-heading/issues/63 */ + line-height: calc(var(--ck-line-height-base) * var(--ck-font-size-base)); + } +.ck.ck-list__item > .ck-button:not(.ck-list-item-button):active { + box-shadow: none; + } +.ck.ck-list__item > .ck-button.ck-on:not(.ck-list-item-button) { + background: var(--ck-color-list-button-on-background); + color: var(--ck-color-list-button-on-text); + } +.ck.ck-list__item > .ck-button.ck-on:not(.ck-list-item-button):active { + box-shadow: none; + } +.ck.ck-list__item > .ck-button.ck-on:not(.ck-list-item-button):hover:not(.ck-disabled) { + background: var(--ck-color-list-button-on-background-focus); + } +.ck.ck-list__item > .ck-button.ck-on:not(.ck-list-item-button):focus:not(.ck-disabled) { + border-color: var(--ck-color-base-background); + } +.ck.ck-list__item > .ck-button:not(.ck-list-item-button):hover:not(.ck-disabled) { + background: var(--ck-color-list-button-hover-background); + } +/* It's unnecessary to change the background/text of a switch toggle; it has different ways + of conveying its state (like the switcher) */ +.ck.ck-list__item > .ck-button.ck-switchbutton.ck-on { + background: var(--ck-color-list-background); + color: inherit; + } +.ck.ck-list__item > .ck-button.ck-switchbutton.ck-on:hover:not(.ck-disabled) { + background: var(--ck-color-list-button-hover-background); + color: inherit; + } +.ck-list .ck-list__group { + padding-top: var(--ck-spacing-medium); + + /* Lists come with an inner vertical padding. Don't duplicate it. */ +} +.ck-list .ck-list__group:first-child { + padding-top: 0; + } +/* The group should have a border when it's not the first item. */ +*:not(.ck-hidden) ~ .ck-list .ck-list__group { + border-top: 1px solid var(--ck-color-base-border); + } +.ck-list .ck-list__group > .ck-label { + font-size: 11px; + font-weight: bold; + padding: var(--ck-spacing-medium) var(--ck-spacing-large) 0; + } +.ck.ck-list__separator { + height: 1px; + width: 100%; + background: var(--ck-color-base-border); + + /* Give the separator some air */ + margin: var(--ck-spacing-small) 0; +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-menu-bar { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; + background: var(--ck-color-base-background); + padding: var(--ck-spacing-small); + gap: var(--ck-spacing-small); + border: 1px solid var(--ck-color-toolbar-border); + width: 100%; +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-menu-bar__menu { + /* Enable font size inheritance, which allows fluid UI scaling. */ + font-size: inherit; +} +.ck.ck-menu-bar__menu.ck-menu-bar__menu_top-level { + max-width: 100%; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A class which indicates that an element holding it is disabled. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements a button of given background color. + * + * @param {String} $background - Background color of the button. + * @param {String} $border - Border color of the button. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * All menu buttons. + */ +.ck.ck-menu-bar__menu > .ck-menu-bar__menu__button { + width: 100%; + } +.ck.ck-menu-bar__menu > .ck-menu-bar__menu__button > .ck-button__label { + flex-grow: 1; + overflow: hidden; + text-overflow: ellipsis; + } +.ck.ck-menu-bar__menu > .ck-menu-bar__menu__button.ck-disabled > .ck-button__label { + opacity: var(--ck-disabled-opacity); + } +[dir="ltr"] .ck.ck-menu-bar__menu > .ck-menu-bar__menu__button:not(.ck-button_with-text) { + padding-left: var(--ck-spacing-small); + } +[dir="rtl"] .ck.ck-menu-bar__menu > .ck-menu-bar__menu__button:not(.ck-button_with-text) { + padding-right: var(--ck-spacing-small); + } +/* + * Top-level menu buttons only. + */ +.ck.ck-menu-bar__menu.ck-menu-bar__menu_top-level > .ck-menu-bar__menu__button { + padding: var(--ck-spacing-small) var(--ck-spacing-medium); + min-height: unset; + } +.ck.ck-menu-bar__menu.ck-menu-bar__menu_top-level > .ck-menu-bar__menu__button .ck-button__label { + width: unset; + line-height: unset; + } +.ck.ck-menu-bar__menu.ck-menu-bar__menu_top-level > .ck-menu-bar__menu__button.ck-on { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } +.ck.ck-menu-bar__menu.ck-menu-bar__menu_top-level > .ck-menu-bar__menu__button .ck-icon { + display: none; + } +/* + * Sub-menu buttons. + */ +.ck.ck-menu-bar__menu:not(.ck-menu-bar__menu_top-level) .ck-menu-bar__menu__button { + border-radius: 0; + } +.ck.ck-menu-bar__menu:not(.ck-menu-bar__menu_top-level) .ck-menu-bar__menu__button > .ck-menu-bar__menu__button__arrow { + width: var(--ck-dropdown-arrow-size); + } +[dir="ltr"] .ck.ck-menu-bar__menu:not(.ck-menu-bar__menu_top-level) .ck-menu-bar__menu__button > .ck-menu-bar__menu__button__arrow { + transform: rotate(-90deg); + + /* A space to accommodate the triangle. */ + margin-left: var(--ck-spacing-standard); + + /* Nudge the arrow gently to the right because its center of gravity is to the left */ + margin-right: calc(-1 * var(--ck-spacing-small)); + } +[dir="rtl"] .ck.ck-menu-bar__menu:not(.ck-menu-bar__menu_top-level) .ck-menu-bar__menu__button > .ck-menu-bar__menu__button__arrow { + transform: rotate(90deg); + + left: var(--ck-spacing-standard); + + /* A space to accommodate the triangle. */ + margin-right: var(--ck-spacing-small); + + /* Nudge the arrow gently to the left because its center of gravity is to the right (after rotation). */ + margin-left: calc(-1 * var(--ck-spacing-small)); + } +.ck.ck-menu-bar__menu:not(.ck-menu-bar__menu_top-level) .ck-menu-bar__menu__button.ck-disabled > .ck-menu-bar__menu__button__arrow { + opacity: var(--ck-disabled-opacity); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-menu-bar-menu-item-min-width: 18em; +} +.ck.ck-menu-bar__menu .ck.ck-menu-bar__menu__item { + min-width: var(--ck-menu-bar-menu-item-min-width); +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * List item buttons. + */ +.ck.ck-menu-bar__menu .ck-button.ck-menu-bar__menu__item__button { + border-radius: 0; + } +.ck.ck-menu-bar__menu .ck-button.ck-menu-bar__menu__item__button > .ck-spinner-container, + .ck.ck-menu-bar__menu .ck-button.ck-menu-bar__menu__item__button > .ck-spinner-container .ck-spinner { + /* These styles correspond to .ck-icon so that the spinner seamlessly replaces the icon. */ + --ck-toolbar-spinner-size: 20px; + } +.ck.ck-menu-bar__menu .ck-button.ck-menu-bar__menu__item__button > .ck-spinner-container { + /* This ensures margins corresponding to the .ck-icon. */ + font-size: var(--ck-icon-font-size); + } +[dir="ltr"] .ck.ck-menu-bar__menu .ck-button.ck-menu-bar__menu__item__button > .ck-spinner-container { + margin-right: var(--ck-spacing-medium); + } +[dir="rtl"] .ck.ck-menu-bar__menu .ck-button.ck-menu-bar__menu__item__button > .ck-spinner-container { + margin-left: var(--ck-spacing-medium); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A visual style of focused element's border. + */ +:root { + --ck-menu-bar-menu-panel-max-width: 75vw; +} +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel { + border-radius: 0; + + background: var(--ck-color-dropdown-panel-background); + border: 1px solid var(--ck-color-dropdown-panel-border); + bottom: 0; + height: fit-content; + max-width: var(--ck-menu-bar-menu-panel-max-width); +} +.ck-rounded-corners .ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel, + .ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-rounded-corners { + border-radius: var(--ck-border-radius); + } +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel { + box-shadow: var(--ck-drop-shadow), 0 0; + + /* Corner border radius consistent with the button. */ +} +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_es, + .ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_se { + border-top-left-radius: 0; + } +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_ws, + .ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_sw { + border-top-right-radius: 0; + } +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_en, + .ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_ne { + border-bottom-left-radius: 0; + } +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_wn, + .ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_nw { + border-bottom-right-radius: 0; + } +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel:focus { + outline: none; + } +.ck.ck-menu-bar .ck-list-item-button:focus, + .ck.ck-menu-bar .ck-list-item-button:active { + border-color: transparent; + box-shadow: none; + } +.ck.ck-menu-bar.ck-menu-bar_focus-border-enabled .ck-list-item-button:focus, + .ck.ck-menu-bar.ck-menu-bar_focus-border-enabled .ck-list-item-button:active { + /* Fix truncated shadows due to rendering order. */ + position: relative; + z-index: 2; + + /* Disable native outline. */ + + outline: none; + + border: var(--ck-focus-ring); + box-shadow: var(--ck-focus-outer-shadow), 0 0; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ +:root { + --ck-balloon-border-width: 1px; + --ck-balloon-arrow-offset: 2px; + --ck-balloon-arrow-height: 10px; + --ck-balloon-arrow-half-width: 8px; + --ck-balloon-arrow-drop-shadow: 0 2px 2px var(--ck-color-shadow-drop); +} +.ck.ck-balloon-panel { + border-radius: 0; + + min-height: 15px; + + background: var(--ck-color-panel-background); + border: var(--ck-balloon-border-width) solid var(--ck-color-panel-border); +} +.ck-rounded-corners .ck.ck-balloon-panel, + .ck.ck-balloon-panel.ck-rounded-corners { + border-radius: var(--ck-border-radius); + } +.ck.ck-balloon-panel { + box-shadow: var(--ck-drop-shadow), 0 0; +} +.ck.ck-balloon-panel.ck-balloon-panel_with-arrow::before, + .ck.ck-balloon-panel.ck-balloon-panel_with-arrow::after { + width: 0; + height: 0; + border-style: solid; + } +.ck.ck-balloon-panel[class*="arrow_n"]::before, + .ck.ck-balloon-panel[class*="arrow_n"]::after { + border-width: 0 var(--ck-balloon-arrow-half-width) var(--ck-balloon-arrow-height) var(--ck-balloon-arrow-half-width); + } +.ck.ck-balloon-panel[class*="arrow_n"]::before { + border-color: transparent transparent var(--ck-color-panel-border) transparent; + margin-top: calc( -1 * var(--ck-balloon-border-width) ); + } +.ck.ck-balloon-panel[class*="arrow_n"]::after { + border-color: transparent transparent var(--ck-color-panel-background) transparent; + margin-top: calc( var(--ck-balloon-arrow-offset) - var(--ck-balloon-border-width) ); + } +.ck.ck-balloon-panel[class*="arrow_s"]::before, + .ck.ck-balloon-panel[class*="arrow_s"]::after { + border-width: var(--ck-balloon-arrow-height) var(--ck-balloon-arrow-half-width) 0 var(--ck-balloon-arrow-half-width); + } +.ck.ck-balloon-panel[class*="arrow_s"]::before { + border-color: var(--ck-color-panel-border) transparent transparent; + filter: drop-shadow(var(--ck-balloon-arrow-drop-shadow)); + margin-bottom: calc( -1 * var(--ck-balloon-border-width) ); + } +.ck.ck-balloon-panel[class*="arrow_s"]::after { + border-color: var(--ck-color-panel-background) transparent transparent transparent; + margin-bottom: calc( var(--ck-balloon-arrow-offset) - var(--ck-balloon-border-width) ); + } +.ck.ck-balloon-panel[class*="arrow_e"]::before, + .ck.ck-balloon-panel[class*="arrow_e"]::after { + border-width: var(--ck-balloon-arrow-half-width) 0 var(--ck-balloon-arrow-half-width) var(--ck-balloon-arrow-height); + } +.ck.ck-balloon-panel[class*="arrow_e"]::before { + border-color: transparent transparent transparent var(--ck-color-panel-border); + margin-right: calc( -1 * var(--ck-balloon-border-width) ); + } +.ck.ck-balloon-panel[class*="arrow_e"]::after { + border-color: transparent transparent transparent var(--ck-color-panel-background); + margin-right: calc( var(--ck-balloon-arrow-offset) - var(--ck-balloon-border-width) ); + } +.ck.ck-balloon-panel[class*="arrow_w"]::before, + .ck.ck-balloon-panel[class*="arrow_w"]::after { + border-width: var(--ck-balloon-arrow-half-width) var(--ck-balloon-arrow-height) var(--ck-balloon-arrow-half-width) 0; + } +.ck.ck-balloon-panel[class*="arrow_w"]::before { + border-color: transparent var(--ck-color-panel-border) transparent transparent; + margin-left: calc( -1 * var(--ck-balloon-border-width) ); + } +.ck.ck-balloon-panel[class*="arrow_w"]::after { + border-color: transparent var(--ck-color-panel-background) transparent transparent; + margin-left: calc( var(--ck-balloon-arrow-offset) - var(--ck-balloon-border-width) ); + } +.ck.ck-balloon-panel.ck-balloon-panel_arrow_n::before, + .ck.ck-balloon-panel.ck-balloon-panel_arrow_n::after { + left: 50%; + margin-left: calc(-1 * var(--ck-balloon-arrow-half-width)); + top: calc(-1 * var(--ck-balloon-arrow-height)); + } +.ck.ck-balloon-panel.ck-balloon-panel_arrow_nw::before, + .ck.ck-balloon-panel.ck-balloon-panel_arrow_nw::after { + left: calc(2 * var(--ck-balloon-arrow-half-width)); + top: calc(-1 * var(--ck-balloon-arrow-height)); + } +.ck.ck-balloon-panel.ck-balloon-panel_arrow_ne::before, + .ck.ck-balloon-panel.ck-balloon-panel_arrow_ne::after { + right: calc(2 * var(--ck-balloon-arrow-half-width)); + top: calc(-1 * var(--ck-balloon-arrow-height)); + } +.ck.ck-balloon-panel.ck-balloon-panel_arrow_s::before, + .ck.ck-balloon-panel.ck-balloon-panel_arrow_s::after { + left: 50%; + margin-left: calc(-1 * var(--ck-balloon-arrow-half-width)); + bottom: calc(-1 * var(--ck-balloon-arrow-height)); + } +.ck.ck-balloon-panel.ck-balloon-panel_arrow_sw::before, + .ck.ck-balloon-panel.ck-balloon-panel_arrow_sw::after { + left: calc(2 * var(--ck-balloon-arrow-half-width)); + bottom: calc(-1 * var(--ck-balloon-arrow-height)); + } +.ck.ck-balloon-panel.ck-balloon-panel_arrow_se::before, + .ck.ck-balloon-panel.ck-balloon-panel_arrow_se::after { + right: calc(2 * var(--ck-balloon-arrow-half-width)); + bottom: calc(-1 * var(--ck-balloon-arrow-height)); + } +.ck.ck-balloon-panel.ck-balloon-panel_arrow_sme::before, + .ck.ck-balloon-panel.ck-balloon-panel_arrow_sme::after { + right: 25%; + margin-right: calc(2 * var(--ck-balloon-arrow-half-width)); + bottom: calc(-1 * var(--ck-balloon-arrow-height)); + } +.ck.ck-balloon-panel.ck-balloon-panel_arrow_smw::before, + .ck.ck-balloon-panel.ck-balloon-panel_arrow_smw::after { + left: 25%; + margin-left: calc(2 * var(--ck-balloon-arrow-half-width)); + bottom: calc(-1 * var(--ck-balloon-arrow-height)); + } +.ck.ck-balloon-panel.ck-balloon-panel_arrow_nme::before, + .ck.ck-balloon-panel.ck-balloon-panel_arrow_nme::after { + right: 25%; + margin-right: calc(2 * var(--ck-balloon-arrow-half-width)); + top: calc(-1 * var(--ck-balloon-arrow-height)); + } +.ck.ck-balloon-panel.ck-balloon-panel_arrow_nmw::before, + .ck.ck-balloon-panel.ck-balloon-panel_arrow_nmw::after { + left: 25%; + margin-left: calc(2 * var(--ck-balloon-arrow-half-width)); + top: calc(-1 * var(--ck-balloon-arrow-height)); + } +.ck.ck-balloon-panel.ck-balloon-panel_arrow_e::before, + .ck.ck-balloon-panel.ck-balloon-panel_arrow_e::after { + right: calc(-1 * var(--ck-balloon-arrow-height)); + margin-top: calc(-1 * var(--ck-balloon-arrow-half-width)); + top: 50%; + } +.ck.ck-balloon-panel.ck-balloon-panel_arrow_w::before, + .ck.ck-balloon-panel.ck-balloon-panel_arrow_w::after { + left: calc(-1 * var(--ck-balloon-arrow-height)); + margin-top: calc(-1 * var(--ck-balloon-arrow-half-width)); + top: 50%; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck .ck-balloon-rotator__navigation { + background: var(--ck-color-toolbar-background); + border-bottom: 1px solid var(--ck-color-toolbar-border); + padding: 0 var(--ck-spacing-small); + + /* Let's keep similar appearance to `ck-toolbar`. */ +} +.ck .ck-balloon-rotator__navigation > * { + margin-right: var(--ck-spacing-small); + margin-top: var(--ck-spacing-small); + margin-bottom: var(--ck-spacing-small); + } +/* Gives counter more breath than buttons. */ +.ck .ck-balloon-rotator__navigation .ck-balloon-rotator__counter { + margin-right: var(--ck-spacing-standard); + + /* We need to use smaller margin because of previous button's right margin. */ + margin-left: var(--ck-spacing-small); + } +/* Disable default annotation shadow inside rotator with fake panels. */ +.ck .ck-balloon-rotator__content .ck.ck-annotation-wrapper { + box-shadow: none; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ +:root { + --ck-balloon-fake-panel-offset-horizontal: 6px; + --ck-balloon-fake-panel-offset-vertical: 6px; +} +/* Let's use `.ck-balloon-panel` appearance. See: balloonpanel.css. */ +.ck .ck-fake-panel div { + box-shadow: var(--ck-drop-shadow), 0 0; + + min-height: 15px; + + background: var(--ck-color-panel-background); + border: 1px solid var(--ck-color-panel-border); + border-radius: var(--ck-border-radius); + + width: 100%; + height: 100%; +} +.ck .ck-fake-panel div:nth-child( 1 ) { + margin-left: var(--ck-balloon-fake-panel-offset-horizontal); + margin-top: var(--ck-balloon-fake-panel-offset-vertical); +} +.ck .ck-fake-panel div:nth-child( 2 ) { + margin-left: calc(var(--ck-balloon-fake-panel-offset-horizontal) * 2); + margin-top: calc(var(--ck-balloon-fake-panel-offset-vertical) * 2); +} +.ck .ck-fake-panel div:nth-child( 3 ) { + margin-left: calc(var(--ck-balloon-fake-panel-offset-horizontal) * 3); + margin-top: calc(var(--ck-balloon-fake-panel-offset-vertical) * 3); +} +/* If balloon is positioned above element, we need to move fake panel to the top. */ +.ck .ck-balloon-panel_arrow_s + .ck-fake-panel, +.ck .ck-balloon-panel_arrow_se + .ck-fake-panel, +.ck .ck-balloon-panel_arrow_sw + .ck-fake-panel { + --ck-balloon-fake-panel-offset-vertical: -6px; +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ +.ck.ck-sticky-panel .ck-sticky-panel__content_sticky { + box-shadow: var(--ck-drop-shadow), 0 0; + + border-width: 0 1px 1px; + border-top-left-radius: 0; + border-top-right-radius: 0; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck-vertical-form > .ck-button:nth-last-child(2)::after { + border-right: 1px solid var(--ck-color-base-border); +} +.ck.ck-responsive-form { + padding: var(--ck-spacing-large); +} +.ck.ck-responsive-form:focus { + /* See: https://github.com/ckeditor/ckeditor5/issues/4773 */ + outline: none; + } +[dir="ltr"] .ck.ck-responsive-form > :not(:first-child) { + margin-left: var(--ck-spacing-standard); + } +[dir="rtl"] .ck.ck-responsive-form > :not(:last-child) { + margin-left: var(--ck-spacing-standard); + } +@media screen and (max-width: 600px) { +.ck.ck-responsive-form { + padding: 0; + width: calc(.8 * var(--ck-input-width)); +} + + .ck.ck-responsive-form .ck-labeled-field-view { + margin: var(--ck-spacing-large) var(--ck-spacing-large) 0; + } + + .ck.ck-responsive-form .ck-labeled-field-view .ck-input-text, + .ck.ck-responsive-form .ck-labeled-field-view .ck-input-number { + min-width: 0; + width: 100%; + } + + /* Let the long error messages wrap in the narrow form. */ + .ck.ck-responsive-form .ck-labeled-field-view .ck-labeled-field-view__error { + white-space: normal; + } + + /* Styles for two last buttons in the form (save&cancel, edit&unlink, etc.). */ + .ck.ck-responsive-form > .ck-button:nth-last-child(2)::after { + border-right: 1px solid var(--ck-color-base-border); + } + + .ck.ck-responsive-form > .ck-button:nth-last-child(1), + .ck.ck-responsive-form > .ck-button:nth-last-child(2) { + padding: var(--ck-spacing-standard); + margin-top: var(--ck-spacing-large); + border-radius: 0; + } + + .ck.ck-responsive-form > .ck-button:nth-last-child(1):not(:focus), .ck.ck-responsive-form > .ck-button:nth-last-child(2):not(:focus) { + border-top: 1px solid var(--ck-color-base-border); + } + + [dir="ltr"] .ck.ck-responsive-form > .ck-button:nth-last-child(1), [dir="ltr"] .ck.ck-responsive-form > .ck-button:nth-last-child(2) { + margin-left: 0; + } + + [dir="rtl"] .ck.ck-responsive-form > .ck-button:nth-last-child(1), [dir="rtl"] .ck.ck-responsive-form > .ck-button:nth-last-child(2) { + margin-left: 0; + } + + [dir="rtl"] .ck.ck-responsive-form > .ck-button:nth-last-child(1):last-of-type, [dir="rtl"] .ck.ck-responsive-form > .ck-button:nth-last-child(2):last-of-type { + border-right: 1px solid var(--ck-color-base-border); + } + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-search-field-view-horizontal-spacing: calc(var(--ck-icon-size) + var(--ck-spacing-medium)); +} +.ck.ck-search > .ck-labeled-field-view .ck-input { + width: 100%; + } +.ck.ck-search > .ck-labeled-field-view.ck-search__query_with-icon { + --ck-labeled-field-label-default-position-x: var(--ck-search-field-view-horizontal-spacing); + } +.ck.ck-search > .ck-labeled-field-view.ck-search__query_with-icon > .ck-labeled-field-view__input-wrapper > .ck-icon { + opacity: .5; + pointer-events: none; + } +.ck.ck-search > .ck-labeled-field-view.ck-search__query_with-icon .ck-input { + width: 100%; + } +[dir="ltr"] .ck.ck-search > .ck-labeled-field-view.ck-search__query_with-icon .ck-input { + padding-left: var(--ck-search-field-view-horizontal-spacing); + } +[dir="rtl"] .ck.ck-search > .ck-labeled-field-view.ck-search__query_with-icon .ck-input:not(.ck-input-text_empty) { + padding-left: var(--ck-search-field-view-horizontal-spacing); + } +.ck.ck-search > .ck-labeled-field-view.ck-search__query_with-reset { + --ck-labeled-field-empty-unfocused-max-width: 100% - 2 * var(--ck-search-field-view-horizontal-spacing); + } +.ck.ck-search > .ck-labeled-field-view.ck-search__query_with-reset.ck-labeled-field-view_empty { + --ck-labeled-field-empty-unfocused-max-width: 100% - var(--ck-search-field-view-horizontal-spacing) - var(--ck-spacing-medium); + } +.ck.ck-search > .ck-labeled-field-view.ck-search__query_with-reset .ck-search__reset { + min-width: auto; + min-height: auto; + + background: none; + opacity: .5; + padding: 0; + } +[dir="ltr"] .ck.ck-search > .ck-labeled-field-view.ck-search__query_with-reset .ck-search__reset { + right: var(--ck-spacing-medium); + } +[dir="rtl"] .ck.ck-search > .ck-labeled-field-view.ck-search__query_with-reset .ck-search__reset { + left: var(--ck-spacing-medium); + } +.ck.ck-search > .ck-labeled-field-view.ck-search__query_with-reset .ck-search__reset:hover { + opacity: 1; + } +.ck.ck-search > .ck-labeled-field-view.ck-search__query_with-reset .ck-input { + width: 100%; + } +[dir="ltr"] .ck.ck-search > .ck-labeled-field-view.ck-search__query_with-reset .ck-input:not(.ck-input-text_empty) { + padding-right: var(--ck-search-field-view-horizontal-spacing); + } +[dir="rtl"] .ck.ck-search > .ck-labeled-field-view.ck-search__query_with-reset .ck-input { + padding-right: var(--ck-search-field-view-horizontal-spacing); + } +.ck.ck-search > .ck-search__results { + min-width: 100%; + } +.ck.ck-search > .ck-search__results > .ck-search__info { + width: 100%; + padding: var(--ck-spacing-medium) var(--ck-spacing-large); + } +.ck.ck-search > .ck-search__results > .ck-search__info * { + white-space: normal; + } +.ck.ck-search > .ck-search__results > .ck-search__info > span:first-child { + font-weight: bold; + } +.ck.ck-search > .ck-search__results > .ck-search__info > span:last-child { + margin-top: var(--ck-spacing-medium); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-toolbar-spinner-size: 18px; +} +.ck.ck-spinner-container { + width: var(--ck-toolbar-spinner-size); + height: var(--ck-toolbar-spinner-size); + animation: 1.5s infinite ck-spinner-rotate linear; +} +@media (prefers-reduced-motion: reduce) { +.ck.ck-spinner-container { + animation-duration: 3s; +} + } +.ck.ck-spinner { + width: var(--ck-toolbar-spinner-size); + height: var(--ck-toolbar-spinner-size); + border-radius: 50%; + border: 2px solid var(--ck-color-text); + border-top-color: transparent; +} +@keyframes ck-spinner-rotate { + to { + transform: rotate(360deg) + } +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * This fixes a problem in Firefox when the initial height of the complement does not match the number of rows. + * This bug is especially visible when rows=1. + */ +.ck-textarea { + overflow-x: hidden +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-color-block-toolbar-button: var(--ck-color-text); + --ck-block-toolbar-button-size: var(--ck-font-size-normal); +} +.ck.ck-block-toolbar-button { + color: var(--ck-color-block-toolbar-button); + font-size: var(--ck-block-toolbar-size); +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-toolbar { + border-radius: 0; + + background: var(--ck-color-toolbar-background); + padding: 0 var(--ck-spacing-small); + border: 1px solid var(--ck-color-toolbar-border); +} +.ck-rounded-corners .ck.ck-toolbar, + .ck.ck-toolbar.ck-rounded-corners { + border-radius: var(--ck-border-radius); + } +.ck.ck-toolbar .ck.ck-toolbar__separator { + height: var(--ck-icon-size); + width: 1px; + min-width: 1px; + background: var(--ck-color-toolbar-border); + + /* + * These margins make the separators look better in balloon toolbars (when aligned with the "tip"). + * See https://github.com/ckeditor/ckeditor5/issues/7493. + */ + margin-top: var(--ck-spacing-small); + margin-bottom: var(--ck-spacing-small); + } +.ck.ck-toolbar .ck-toolbar__line-break { + height: 0; + } +.ck.ck-toolbar > .ck-toolbar__items > *:not(.ck-toolbar__line-break) { + /* (#11) Separate toolbar items. */ + margin-right: var(--ck-spacing-small); + } +/* Don't display a separator after an empty items container, for instance, + when all items were grouped */ +.ck.ck-toolbar > .ck-toolbar__items:empty + .ck.ck-toolbar__separator { + display: none; + } +.ck.ck-toolbar > .ck-toolbar__items > *:not(.ck-toolbar__line-break), + .ck.ck-toolbar > .ck.ck-toolbar__grouped-dropdown { + /* Make sure items wrapped to the next line have v-spacing */ + margin-top: var(--ck-spacing-small); + margin-bottom: var(--ck-spacing-small); + } +.ck.ck-toolbar.ck-toolbar_vertical { + /* Items in a vertical toolbar span the entire width. */ + padding: 0; + + /* Specificity matters here. See https://github.com/ckeditor/ckeditor5-theme-lark/issues/168. */ + } +.ck.ck-toolbar.ck-toolbar_vertical > .ck-toolbar__items > .ck { + /* Items in a vertical toolbar should span the horizontal space. */ + width: 100%; + + /* Items in a vertical toolbar should have no margin. */ + margin: 0; + + /* Items in a vertical toolbar span the entire width so rounded corners are pointless. */ + border-radius: 0; + } +.ck.ck-toolbar.ck-toolbar_compact { + /* No spacing around items. */ + padding: 0; + } +.ck.ck-toolbar.ck-toolbar_compact > .ck-toolbar__items > * { + /* Compact toolbar items have no spacing between them. */ + margin: 0; + + /* "Middle" children should have no rounded corners. */ + } +.ck.ck-toolbar.ck-toolbar_compact > .ck-toolbar__items > *:not(:first-child):not(:last-child) { + border-radius: 0; + } +/* + * Dropdown button has asymmetric padding to fit the arrow. + * This button has no arrow so let's revert that padding back to normal. + */ +.ck.ck-toolbar > .ck.ck-toolbar__grouped-dropdown > .ck.ck-button.ck-dropdown__button { + padding-left: var(--ck-spacing-tiny); + } +/* A drop-down containing the nested toolbar with configured items. */ +/* Prevent empty space in the panel when the dropdown label is visible and long but the toolbar has few items. */ +.ck.ck-toolbar .ck-toolbar__nested-toolbar-dropdown > .ck-dropdown__panel { + min-width: auto; + } +.ck.ck-toolbar .ck-toolbar__nested-toolbar-dropdown > .ck-button > .ck-button__label { + max-width: 7em; + width: auto; + } +.ck.ck-toolbar:focus { + outline: none; + } +.ck-toolbar-container .ck.ck-toolbar { + border: 0; + } +/* stylelint-disable */ +/* + * Styles for RTL toolbars. + * + * Note: In some cases (e.g. a decoupled editor), the toolbar has its own "dir" + * because its parent is not controlled by the editor framework. + */ +[dir="rtl"] .ck.ck-toolbar > .ck-toolbar__items > .ck, .ck.ck-toolbar[dir="rtl"] > .ck-toolbar__items > .ck { + margin-right: 0; + } +[dir="rtl"] .ck.ck-toolbar:not(.ck-toolbar_compact) > .ck-toolbar__items > .ck, .ck.ck-toolbar[dir="rtl"]:not(.ck-toolbar_compact) > .ck-toolbar__items > .ck { + /* (#11) Separate toolbar items. */ + margin-left: var(--ck-spacing-small); + } +[dir="rtl"] .ck.ck-toolbar > .ck-toolbar__items > .ck:last-child, .ck.ck-toolbar[dir="rtl"] > .ck-toolbar__items > .ck:last-child { + margin-left: 0; + } +/* No rounded corners on the right side of the first child. */ +[dir="rtl"] .ck.ck-toolbar.ck-toolbar_compact > .ck-toolbar__items > .ck:first-child, .ck.ck-toolbar.ck-toolbar_compact[dir="rtl"] > .ck-toolbar__items > .ck:first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } +/* No rounded corners on the left side of the last child. */ +[dir="rtl"] .ck.ck-toolbar.ck-toolbar_compact > .ck-toolbar__items > .ck:last-child, .ck.ck-toolbar.ck-toolbar_compact[dir="rtl"] > .ck-toolbar__items > .ck:last-child { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +/* Separate the the separator form the grouping dropdown when some items are grouped. */ +[dir="rtl"] .ck.ck-toolbar > .ck.ck-toolbar__separator, .ck.ck-toolbar[dir="rtl"] > .ck.ck-toolbar__separator { + margin-left: var(--ck-spacing-small); + } +/* Some spacing between the items and the separator before the grouped items dropdown. */ +[dir="rtl"] .ck.ck-toolbar.ck-toolbar_grouping > .ck-toolbar__items:not(:empty):not(:only-child), .ck.ck-toolbar.ck-toolbar_grouping[dir="rtl"] > .ck-toolbar__items:not(:empty):not(:only-child) { + margin-left: var(--ck-spacing-small); + } +/* + * Styles for LTR toolbars. + * + * Note: In some cases (e.g. a decoupled editor), the toolbar has its own "dir" + * because its parent is not controlled by the editor framework. + */ +[dir="ltr"] .ck.ck-toolbar > .ck-toolbar__items > .ck:last-child, .ck.ck-toolbar[dir="ltr"] > .ck-toolbar__items > .ck:last-child { + margin-right: 0; + } +/* No rounded corners on the right side of the first child. */ +[dir="ltr"] .ck.ck-toolbar.ck-toolbar_compact > .ck-toolbar__items > .ck:first-child, .ck.ck-toolbar.ck-toolbar_compact[dir="ltr"] > .ck-toolbar__items > .ck:first-child { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +/* No rounded corners on the left side of the last child. */ +[dir="ltr"] .ck.ck-toolbar.ck-toolbar_compact > .ck-toolbar__items > .ck:last-child, .ck.ck-toolbar.ck-toolbar_compact[dir="ltr"] > .ck-toolbar__items > .ck:last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } +/* Separate the the separator form the grouping dropdown when some items are grouped. */ +[dir="ltr"] .ck.ck-toolbar > .ck.ck-toolbar__separator, .ck.ck-toolbar[dir="ltr"] > .ck.ck-toolbar__separator { + margin-right: var(--ck-spacing-small); + } +/* Some spacing between the items and the separator before the grouped items dropdown. */ +[dir="ltr"] .ck.ck-toolbar.ck-toolbar_grouping > .ck-toolbar__items:not(:empty):not(:only-child), .ck.ck-toolbar.ck-toolbar_grouping[dir="ltr"] > .ck-toolbar__items:not(:empty):not(:only-child) { + margin-right: var(--ck-spacing-small); + } +/* stylelint-enable */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +.ck.ck-balloon-panel.ck-tooltip { + --ck-balloon-border-width: 0px; + --ck-balloon-arrow-offset: 0px; + --ck-balloon-arrow-half-width: 4px; + --ck-balloon-arrow-height: 4px; + --ck-tooltip-text-padding: 4px; + --ck-color-panel-background: var(--ck-color-tooltip-background); + + padding: 0 var(--ck-spacing-medium); + + /* Reset balloon panel styles */ + box-shadow: none; +} +.ck.ck-balloon-panel.ck-tooltip .ck-tooltip__text { + font-size: .9em; + line-height: 1.5; + color: var(--ck-color-tooltip-text); + } +.ck.ck-balloon-panel.ck-tooltip.ck-tooltip_multi-line .ck-tooltip__text { + white-space: break-spaces; + display: inline-block; + padding: var(--ck-tooltip-text-padding) 0; + max-width: 200px; + } +/* Hide the default shadow of the .ck-balloon-panel tip */ +.ck.ck-balloon-panel.ck-tooltip::before { + display: none; + } + +/* Editor */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +.ck.ck-editor__top .ck-sticky-panel .ck-sticky-panel__content { + border-radius: 0; + + border: 1px solid var(--ck-color-base-border); + border-bottom-width: 0; + } +.ck-rounded-corners .ck.ck-editor__top .ck-sticky-panel .ck-sticky-panel__content, + .ck.ck-editor__top .ck-sticky-panel .ck-sticky-panel__content.ck-rounded-corners { + border-radius: var(--ck-border-radius); + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } +.ck.ck-editor__top .ck-sticky-panel .ck-sticky-panel__content.ck-sticky-panel__content_sticky { + border-bottom-width: 1px; + } +.ck.ck-editor__top .ck-sticky-panel .ck-sticky-panel__content .ck-menu-bar { + border: 0; + border-bottom: 1px solid var(--ck-color-base-border); + } +.ck.ck-editor__top .ck-sticky-panel .ck-sticky-panel__content .ck-toolbar { + border: 0; + } +/* Note: Use ck-editor__main to make sure these styles don't apply to other editor types */ +.ck.ck-editor__main > .ck-editor__editable { + /* https://github.com/ckeditor/ckeditor5-theme-lark/issues/113 */ + background: var(--ck-color-base-background); + + border-radius: 0; +} +.ck-rounded-corners .ck.ck-editor__main > .ck-editor__editable, + .ck.ck-editor__main > .ck-editor__editable.ck-rounded-corners { + border-radius: var(--ck-border-radius); + border-top-left-radius: 0; + border-top-right-radius: 0; + } +.ck.ck-editor__main > .ck-editor__editable:not(.ck-focused) { + border-color: var(--ck-color-base-border); + } + +/* Plugins */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-clipboard-drop-target-dot-width: 12px; + --ck-clipboard-drop-target-dot-height: 8px; + --ck-clipboard-drop-target-color: var(--ck-color-focus-border); +} +/* + * Vertical drop target (in text). + */ +.ck.ck-editor__editable .ck.ck-clipboard-drop-target-position span { + bottom: calc(-.5 * var(--ck-clipboard-drop-target-dot-height)); + top: calc(-.5 * var(--ck-clipboard-drop-target-dot-height)); + border: 1px solid var(--ck-clipboard-drop-target-color); + background: var(--ck-clipboard-drop-target-color); + margin-left: -1px; + + /* The triangle above the marker */ + } +.ck.ck-editor__editable .ck.ck-clipboard-drop-target-position span::after { + content: ''; + width: 0; + height: 0; + + display: block; + position: absolute; + left: 50%; + top: calc(-.5 * var(--ck-clipboard-drop-target-dot-height)); + + transform: translateX(-50%); + border-color: var(--ck-clipboard-drop-target-color) transparent transparent transparent; + border-width: calc(var(--ck-clipboard-drop-target-dot-height)) calc(.5 * var(--ck-clipboard-drop-target-dot-width)) 0 calc(.5 * var(--ck-clipboard-drop-target-dot-width)); + border-style: solid; + } +/* + * Styles of the widget that it a drop target. + */ +.ck.ck-editor__editable .ck-widget.ck-clipboard-drop-target-range { + outline: var(--ck-widget-outline-thickness) solid var(--ck-clipboard-drop-target-color) !important; + } +/* + * Styles of the widget being dragged (its preview). + */ +.ck.ck-editor__editable .ck-widget:-webkit-drag { + zoom: 0.6; + outline: none !important; + } +.ck.ck-clipboard-drop-target-line { + height: 0; + border: 1px solid var(--ck-clipboard-drop-target-color); + background: var(--ck-clipboard-drop-target-color); + margin-top: -1px; +} +.ck.ck-clipboard-drop-target-line::before { + content: ''; + position: absolute; + top: calc(-.5 * var(--ck-clipboard-drop-target-dot-width)); + width: 0; + height: 0; + border-style: solid; + } +[dir="ltr"] .ck.ck-clipboard-drop-target-line::before { + left: -1px; + + border-width: calc(.5 * var(--ck-clipboard-drop-target-dot-width)) 0 calc(.5 * var(--ck-clipboard-drop-target-dot-width)) var(--ck-clipboard-drop-target-dot-height); + border-color: transparent transparent transparent var(--ck-clipboard-drop-target-color); + } +[dir="rtl"] .ck.ck-clipboard-drop-target-line::before { + right: -1px; + + border-width:calc(.5 * var(--ck-clipboard-drop-target-dot-width)) var(--ck-clipboard-drop-target-dot-height) calc(.5 * var(--ck-clipboard-drop-target-dot-width)) 0; + border-color: transparent var(--ck-clipboard-drop-target-color) transparent transparent; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-color-code-block-label-background: hsl(0, 0%, 46%); +} +.ck.ck-editor__editable pre[data-language]::after { + top: -1px; + right: 10px; + background: var(--ck-color-code-block-label-background); + + font-size: 10px; + font-family: var(--ck-font-face); + line-height: 16px; + padding: var(--ck-spacing-tiny) var(--ck-spacing-medium); + color: hsl(0, 0%, 100%); + white-space: nowrap; +} +.ck.ck-code-block-dropdown .ck-dropdown__panel { + /* There could be dozens of languages available. Use scroll to prevent a 10e6px dropdown. */ + max-height: 250px; + overflow-y: auto; + overflow-x: hidden; +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* See ckeditor/ckeditor5#936. */ +@media (forced-colors: active) { + .ck.ck-placeholder, .ck .ck-placeholder { + /* + * This is needed for Edge on Windows to use the right color for the placeholder content (::before). + * See https://github.com/ckeditor/ckeditor5/issues/14907. + */ + forced-color-adjust: preserve-parent-color; + } + } +.ck.ck-placeholder::before, .ck .ck-placeholder::before { + cursor: text; + } +@media (forced-colors: none) { + .ck.ck-placeholder::before, .ck .ck-placeholder::before { + color: var(--ck-color-engine-placeholder-text); + } + } +@media (forced-colors: active) { + .ck.ck-placeholder::before, .ck .ck-placeholder::before { + /* + * In the high contrast mode there is no telling between regular and placeholder text. Using + * italic text to address that issue. See https://github.com/ckeditor/ckeditor5/issues/14907. + */ + font-style: italic; + + /* + * Without this margin, the caret will not show up and blink when the user puts the selection + * in the placeholder (Edge on Windows). See https://github.com/ckeditor/ckeditor5/issues/14907. + */ + margin-left: 1px; + } + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-find-and-replace-form { + width: 400px; + + /* + * The
needs tabindex="-1" for proper Esc handling after being clicked + * but the side effect is that this creates a nasty focus outline in some browsers. + */ +} +.ck.ck-find-and-replace-form:focus { + outline: none; + } +/* Generic styles for the form inputs and actions. */ +.ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs, + .ck.ck-find-and-replace-form .ck-find-and-replace-form__actions { + flex: 1 1 auto; + flex-direction: row; + flex-wrap: wrap; + align-items: center; + align-content: stretch; + + padding: var(--ck-spacing-large); + margin: 0; + + } +.ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs > .ck-button, .ck.ck-find-and-replace-form .ck-find-and-replace-form__actions > .ck-button { + flex: 0 0 auto; + } +[dir="ltr"] .ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs > * + *, [dir="ltr"] .ck.ck-find-and-replace-form .ck-find-and-replace-form__actions > * + * { + margin-left: var(--ck-spacing-standard); + } +[dir="rtl"] .ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs > * + *, [dir="rtl"] .ck.ck-find-and-replace-form .ck-find-and-replace-form__actions > * + * { + margin-right: var(--ck-spacing-standard); + } +.ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs .ck-labeled-field-view, .ck.ck-find-and-replace-form .ck-find-and-replace-form__actions .ck-labeled-field-view { + flex: 1 1 auto; + } +.ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs .ck-labeled-field-view .ck-input, .ck.ck-find-and-replace-form .ck-find-and-replace-form__actions .ck-labeled-field-view .ck-input { + width: 100%; + min-width: 50px; + } +/* Styles specific for inputs area. */ +.ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs { + /* To display all controls in line when there's an error under the input */ + align-items: flex-start; + } +.ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs > .ck-button-prev > .ck-icon { + transform: rotate(90deg); + } +.ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs > .ck-button-next > .ck-icon { + transform: rotate(-90deg); + } +.ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs .ck-results-counter { + top: 50%; + transform: translateY(-50%); + + color: var(--ck-color-base-border); + } +[dir="ltr"] .ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs .ck-results-counter { + right: var(--ck-spacing-standard); + } +[dir="rtl"] .ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs .ck-results-counter { + left: var(--ck-spacing-standard); + } +.ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs > .ck-labeled-field-replace { + flex: 0 0 100%; + padding-top: var(--ck-spacing-standard); + } +[dir="ltr"] .ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs > .ck-labeled-field-replace { + margin-left: 0; + } +[dir="rtl"] .ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs > .ck-labeled-field-replace { + margin-right: 0; + } +/* Styles specific for actions area. */ +.ck.ck-find-and-replace-form .ck-find-and-replace-form__actions { + flex-wrap: wrap; + justify-content: flex-end; + margin-top: calc( -1 * var(--ck-spacing-large) ); + } +.ck.ck-find-and-replace-form .ck-find-and-replace-form__actions > .ck-button-find { + font-weight: bold; + + /* Beef the find button up a little. It's the main action button in the form */ + } +.ck.ck-find-and-replace-form .ck-find-and-replace-form__actions > .ck-button-find .ck-button__label { + padding-left: var(--ck-spacing-large); + padding-right: var(--ck-spacing-large); + } +.ck.ck-find-and-replace-form .ck-switchbutton { + width: 100%; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: space-between; + align-items: center; + } +@media screen and (max-width: 600px) { + .ck.ck-find-and-replace-form { + width: 300px; + + /* Don't let the form overflow from the dialog (https://github.com/cksource/ckeditor5-commercial/issues/5913) */ + max-width: 100%; + + /* Styles specific for inputs area. */ + } + .ck.ck-find-and-replace-form.ck-find-and-replace-form__input { + flex-wrap: wrap; + } + + .ck.ck-find-and-replace-form.ck-find-and-replace-form__input .ck-labeled-field-view { + flex: 1 0 auto; + width: 100%; + margin-bottom: var(--ck-spacing-standard); + } + + .ck.ck-find-and-replace-form.ck-find-and-replace-form__input > .ck-button { + text-align: center; + } + + .ck.ck-find-and-replace-form.ck-find-and-replace-form__input > .ck-button:first-of-type { + flex: 1 1 auto; + } + + [dir="ltr"] .ck.ck-find-and-replace-form.ck-find-and-replace-form__input > .ck-button:first-of-type { + margin-left: 0; + } + + [dir="rtl"] .ck.ck-find-and-replace-form.ck-find-and-replace-form__input > .ck-button:first-of-type { + margin-right: 0; + } + + .ck.ck-find-and-replace-form.ck-find-and-replace-form__input > .ck-button:first-of-type .ck-button__label { + width: 100%; + text-align: center; + } + + /* Styles specific for actions area. */ + .ck.ck-find-and-replace-form.ck-find-and-replace-form__actions > :not(.ck-labeled-field-view) { + flex-wrap: wrap; + flex: 1 1 auto; + } + + .ck.ck-find-and-replace-form.ck-find-and-replace-form__actions > :not(.ck-labeled-field-view) > .ck-button { + text-align: center; + } + + .ck.ck-find-and-replace-form.ck-find-and-replace-form__actions > :not(.ck-labeled-field-view) > .ck-button:first-of-type { + flex: 1 1 auto; + } + + [dir="ltr"] .ck.ck-find-and-replace-form.ck-find-and-replace-form__actions > :not(.ck-labeled-field-view) > .ck-button:first-of-type { + margin-left: 0; + } + + [dir="rtl"] .ck.ck-find-and-replace-form.ck-find-and-replace-form__actions > :not(.ck-labeled-field-view) > .ck-button:first-of-type { + margin-right: 0; + } + + .ck.ck-find-and-replace-form.ck-find-and-replace-form__actions > :not(.ck-labeled-field-view) > .ck-button .ck-button__label { + width: 100%; + text-align: center; + } + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* Resize dropdown's button label. */ +.ck.ck-dropdown.ck-heading-dropdown .ck-dropdown__button .ck-button__label { + width: 8em; + } +.ck.ck-dropdown.ck-heading-dropdown .ck-dropdown__panel .ck-list__item { + min-width: 18em; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Note: This file should contain the wireframe styles only. But since there are no such styles, + * it acts as a message to the builder telling that it should look for the corresponding styles + * **in the theme** when compiling the editor. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-html-embed-content-width: calc(100% - 1.5 * var(--ck-icon-size)); + --ck-html-embed-source-height: 10em; + --ck-html-embed-unfocused-outline-width: 1px; + --ck-html-embed-content-min-height: calc(var(--ck-icon-size) + var(--ck-spacing-standard)); + + --ck-html-embed-source-disabled-background: var(--ck-color-base-foreground); + --ck-html-embed-source-disabled-color: hsl(0deg 0% 45%); +} +/* The feature container. */ +.ck-widget.raw-html-embed { + font-size: var(--ck-font-size-base); + background-color: var(--ck-color-base-foreground); +} +.ck-widget.raw-html-embed:not(.ck-widget_selected):not(:hover) { + outline: var(--ck-html-embed-unfocused-outline-width) dashed var(--ck-color-widget-blurred-border); + } +/* HTML embed widget itself should respect UI language direction */ +.ck-widget.raw-html-embed[dir="ltr"] { + text-align: left; + } +.ck-widget.raw-html-embed[dir="rtl"] { + text-align: right; + } +/* ----- Embed label in the upper left corner ----------------------------------------------- */ +.ck-widget.raw-html-embed::before { + content: attr(data-html-embed-label); + top: calc(-1 * var(--ck-html-embed-unfocused-outline-width)); + left: var(--ck-spacing-standard); + background: hsl(0deg 0% 60%); + transition: background var(--ck-widget-handler-animation-duration) var(--ck-widget-handler-animation-curve); + padding: calc(var(--ck-spacing-tiny) + var(--ck-html-embed-unfocused-outline-width)) var(--ck-spacing-small) var(--ck-spacing-tiny); + border-radius: 0 0 var(--ck-border-radius) var(--ck-border-radius); + color: var(--ck-color-base-background); + font-size: var(--ck-font-size-tiny); + font-family: var(--ck-font-face); + } +.ck-widget.raw-html-embed[dir="rtl"]::before { + left: auto; + right: var(--ck-spacing-standard); + } +/* Make space for label but it only collides in LTR languages */ +.ck-widget.raw-html-embed[dir="ltr"] .ck-widget__type-around .ck-widget__type-around__button.ck-widget__type-around__button_before { + margin-left: 50px; + } +.ck.ck-editor__editable.ck-blurred .ck-widget.raw-html-embed.ck-widget_selected::before { + top: 0px; + padding: var(--ck-spacing-tiny) var(--ck-spacing-small); + } +.ck.ck-editor__editable:not(.ck-blurred) .ck-widget.raw-html-embed.ck-widget_selected::before { + top: 0; + padding: var(--ck-spacing-tiny) var(--ck-spacing-small); + background: var(--ck-color-focus-border); + } +.ck.ck-editor__editable .ck-widget.raw-html-embed:not(.ck-widget_selected):hover::before { + top: 0px; + padding: var(--ck-spacing-tiny) var(--ck-spacing-small); + } +/* ----- Emebed internals --------------------------------------------------------------------- */ +.ck-widget.raw-html-embed .raw-html-embed__content-wrapper { + padding: var(--ck-spacing-standard); + } +/* The switch mode button wrapper. */ +.ck-widget.raw-html-embed .raw-html-embed__buttons-wrapper { + top: var(--ck-spacing-standard); + right: var(--ck-spacing-standard); + } +.ck-widget.raw-html-embed .raw-html-embed__buttons-wrapper .ck-button.raw-html-embed__save-button { + color: var(--ck-color-button-save); + } +.ck-widget.raw-html-embed .raw-html-embed__buttons-wrapper .ck-button.raw-html-embed__cancel-button { + color: var(--ck-color-button-cancel); + } +.ck-widget.raw-html-embed .raw-html-embed__buttons-wrapper .ck-button:not(:first-child) { + margin-top: var(--ck-spacing-small); + } +.ck-widget.raw-html-embed[dir="rtl"] .raw-html-embed__buttons-wrapper { + left: var(--ck-spacing-standard); + right: auto; + } +/* The edit source element. */ +.ck-widget.raw-html-embed .raw-html-embed__source { + box-sizing: border-box; + height: var(--ck-html-embed-source-height); + width: var(--ck-html-embed-content-width); + resize: none; + min-width: 0; + padding: var(--ck-spacing-standard); + + font-family: monospace; + tab-size: 4; + white-space: pre-wrap; + font-size: var(--ck-font-size-base); /* Safari needs this. */ + + /* HTML code is direction–agnostic. */ + text-align: left; + direction: ltr; + } +.ck-widget.raw-html-embed .raw-html-embed__source[disabled] { + background: var(--ck-html-embed-source-disabled-background); + color: var(--ck-html-embed-source-disabled-color); + + /* Safari needs this for the proper text color in disabled input (https://github.com/ckeditor/ckeditor5/issues/8320). */ + -webkit-text-fill-color: var(--ck-html-embed-source-disabled-color); + opacity: 1; + } +/* The preview data container. */ +.ck-widget.raw-html-embed .raw-html-embed__preview { + min-height: var(--ck-html-embed-content-min-height); + width: var(--ck-html-embed-content-width); + + /* Disable all mouse interaction as long as the editor is not read–only. */ + } +.ck-editor__editable:not(.ck-read-only) .ck-widget.raw-html-embed .raw-html-embed__preview { + pointer-events: none; + } +.ck-widget.raw-html-embed .raw-html-embed__preview-content { + box-sizing: border-box; + background-color: var(--ck-color-base-foreground); + } +.ck-widget.raw-html-embed .raw-html-embed__preview-content > * { + margin-left: auto; + margin-right: auto; + } +.ck-widget.raw-html-embed .raw-html-embed__preview-placeholder { + color: var(--ck-html-embed-source-disabled-color) + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-image-insert-insert-by-url-width: 250px; +} +.ck.ck-image-insert-url { + --ck-input-width: 100%; +} +.ck.ck-image-insert-url .ck-image-insert-url__action-row { + grid-column-gap: var(--ck-spacing-large); + margin-top: var(--ck-spacing-large); + } +.ck.ck-image-insert-url .ck-image-insert-url__action-row .ck-button-save, + .ck.ck-image-insert-url .ck-image-insert-url__action-row .ck-button-cancel { + justify-content: center; + min-width: auto; + } +.ck.ck-image-insert-url .ck-image-insert-url__action-row .ck-button .ck-button__label { + color: var(--ck-color-text); + } +.ck.ck-image-insert-form > .ck.ck-button { + display: block; + width: 100%; + } +[dir="ltr"] .ck.ck-image-insert-form > .ck.ck-button { + text-align: left; + } +[dir="rtl"] .ck.ck-image-insert-form > .ck.ck-button { + text-align: right; + } +.ck.ck-image-insert-form > .ck.ck-collapsible { + + min-width: var(--ck-image-insert-insert-by-url-width); + } +.ck.ck-image-insert-form > .ck.ck-collapsible:not(:first-child) { + border-top: 1px solid var(--ck-color-base-border); + } +.ck.ck-image-insert-form > .ck.ck-collapsible:not(:last-child) { + border-bottom: 1px solid var(--ck-color-base-border); + } +/* This is the case when there are no other integrations configured than insert by URL */ +.ck.ck-image-insert-form > .ck.ck-image-insert-url { + min-width: var(--ck-image-insert-insert-by-url-width); + padding: var(--ck-spacing-large); + } +.ck.ck-image-insert-form:focus { + outline: none; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-color-image-upload-icon: hsl(0, 0%, 100%); + --ck-color-image-upload-icon-background: hsl(120, 100%, 27%); + + /* Match the icon size with the linked image indicator brought by the link image feature. */ + --ck-image-upload-icon-size: 20; + --ck-image-upload-icon-width: 2px; + --ck-image-upload-icon-is-visible: clamp(0px, 100% - 50px, 1px); +} +.ck-image-upload-complete-icon { + opacity: 0; + background: var(--ck-color-image-upload-icon-background); + animation-name: ck-upload-complete-icon-show, ck-upload-complete-icon-hide; + animation-fill-mode: forwards, forwards; + animation-duration: 500ms, 500ms; + + /* To make animation scalable. */ + font-size: calc(1px * var(--ck-image-upload-icon-size)); + + /* Hide completed upload icon after 3 seconds. */ + animation-delay: 0ms, 3000ms; + + /* + * Use CSS math to simulate container queries. + * https://css-tricks.com/the-raven-technique-one-step-closer-to-container-queries/#what-about-showing-and-hiding-things + */ + overflow: hidden; + width: calc(var(--ck-image-upload-icon-is-visible) * var(--ck-image-upload-icon-size)); + height: calc(var(--ck-image-upload-icon-is-visible) * var(--ck-image-upload-icon-size)); + + /* This is check icon element made from border-width mixed with animations. */ +} +.ck-image-upload-complete-icon::after { + /* Because of border transformation we need to "hard code" left position. */ + left: 25%; + + top: 50%; + opacity: 0; + height: 0; + width: 0; + + transform: scaleX(-1) rotate(135deg); + transform-origin: left top; + border-top: var(--ck-image-upload-icon-width) solid var(--ck-color-image-upload-icon); + border-right: var(--ck-image-upload-icon-width) solid var(--ck-color-image-upload-icon); + + animation-name: ck-upload-complete-icon-check; + animation-duration: 500ms; + animation-delay: 500ms; + animation-fill-mode: forwards; + + /* #1095. While reset is not providing proper box-sizing for pseudoelements, we need to handle it. */ + box-sizing: border-box; + } +@media (prefers-reduced-motion: reduce) { +.ck-image-upload-complete-icon { + animation-duration: 0ms; +} + + .ck-image-upload-complete-icon::after { + animation: none; + opacity: 1; + width: 0.3em; + height: 0.45em; + } + } +@keyframes ck-upload-complete-icon-show { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} +@keyframes ck-upload-complete-icon-hide { + from { + opacity: 1; + } + + to { + opacity: 0; + } +} +@keyframes ck-upload-complete-icon-check { + 0% { + opacity: 1; + width: 0; + height: 0; + } + 33% { + width: 0.3em; + height: 0; + } + 100% { + opacity: 1; + width: 0.3em; + height: 0.45em; + } +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-color-upload-placeholder-loader: hsl(0, 0%, 70%); + --ck-upload-placeholder-loader-size: 32px; + --ck-upload-placeholder-image-aspect-ratio: 2.8; +} +.ck .ck-image-upload-placeholder { + /* We need to control the full width of the SVG gray background. */ + width: 100%; + margin: 0; +} +.ck .ck-image-upload-placeholder.image-inline { + width: calc( 2 * var(--ck-upload-placeholder-loader-size) * var(--ck-upload-placeholder-image-aspect-ratio) ); + } +.ck .ck-image-upload-placeholder img { + /* + * This is an arbitrary aspect for a 1x1 px GIF to display to the user. Not too tall, not too short. + * There's nothing special about this number except that it should make the image placeholder look like + * a real image during this short period after the upload started and before the image was read from the + * file system (and a rich preview was loaded). + */ + aspect-ratio: var(--ck-upload-placeholder-image-aspect-ratio); + } +.ck .ck-upload-placeholder-loader { + width: 100%; + height: 100%; +} +.ck .ck-upload-placeholder-loader::before { + width: var(--ck-upload-placeholder-loader-size); + height: var(--ck-upload-placeholder-loader-size); + border-radius: 50%; + border-top: 3px solid var(--ck-color-upload-placeholder-loader); + border-right: 2px solid transparent; + animation: ck-upload-placeholder-loader 1s linear infinite; + } +@keyframes ck-upload-placeholder-loader { + to { + transform: rotate( 360deg ); + } +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* Showing animation. */ +.ck.ck-editor__editable .image.ck-appear, .ck.ck-editor__editable .image-inline.ck-appear { + animation: fadeIn 700ms; + } +@media (prefers-reduced-motion: reduce) { +.ck.ck-editor__editable .image.ck-appear, .ck.ck-editor__editable .image-inline.ck-appear { + opacity: 1; + animation: none; + } + } +/* Upload progress bar. */ +.ck.ck-editor__editable .image .ck-progress-bar, + .ck.ck-editor__editable .image-inline .ck-progress-bar { + height: 2px; + width: 0; + background: var(--ck-color-upload-bar-background); + transition: width 100ms; + } +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* Class added to span element surrounding currently selected link. */ +.ck .ck-link_selected { + background: var(--ck-color-link-selected-background); + + /* Give linked inline images some outline to let the user know they are also part of the link. */ +} +.ck .ck-link_selected span.image-inline { + outline: var(--ck-widget-outline-thickness) solid var(--ck-color-link-selected-background); + } +/* + * Classes used by the "fake visual selection" displayed in the content when an input + * in the link UI has focus (the browser does not render the native selection in this state). + */ +.ck .ck-fake-link-selection { + background: var(--ck-color-link-fake-selection); +} +/* A collapsed fake visual selection. */ +.ck .ck-fake-link-selection_collapsed { + height: 100%; + border-right: 1px solid var(--ck-color-base-text); + margin-right: -1px; + outline: solid 1px hsla(0, 0%, 100%, .5); +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Makes element unselectable. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A visual style of focused element's border. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-link-actions .ck-button.ck-link-actions__preview { + padding-left: 0; + padding-right: 0; + } +.ck.ck-link-actions .ck-button.ck-link-actions__preview .ck-button__label { + padding: 0 var(--ck-spacing-medium); + color: var(--ck-color-link-default); + text-overflow: ellipsis; + cursor: pointer; + + /* Match the box model of the link editor form's input so the balloon + does not change width when moving between actions and the form. */ + max-width: var(--ck-input-width); + min-width: 3em; + text-align: center; + } +.ck.ck-link-actions .ck-button.ck-link-actions__preview .ck-button__label:hover { + text-decoration: underline; + } +.ck.ck-link-actions .ck-button.ck-link-actions__preview, + .ck.ck-link-actions .ck-button.ck-link-actions__preview:hover, + .ck.ck-link-actions .ck-button.ck-link-actions__preview:focus, + .ck.ck-link-actions .ck-button.ck-link-actions__preview:active { + background: none; + } +.ck.ck-link-actions .ck-button.ck-link-actions__preview:active { + box-shadow: none; + } +.ck.ck-link-actions .ck-button.ck-link-actions__preview:focus .ck-button__label { + text-decoration: underline; + } +[dir="ltr"] .ck.ck-link-actions .ck-button:not(:first-child) { + margin-left: var(--ck-spacing-standard); + } +[dir="rtl"] .ck.ck-link-actions .ck-button:not(:last-child) { + margin-left: var(--ck-spacing-standard); + } +@media screen and (max-width: 600px) { + .ck.ck-link-actions .ck-button.ck-link-actions__preview { + margin: var(--ck-spacing-standard) var(--ck-spacing-standard) 0; + } + + .ck.ck-link-actions .ck-button.ck-link-actions__preview .ck-button__label { + min-width: 0; + max-width: 100%; + } + [dir="ltr"] .ck.ck-link-actions .ck-button:not(.ck-link-actions__preview) { + margin-left: 0; + } + + [dir="rtl"] .ck.ck-link-actions .ck-button:not(.ck-link-actions__preview) { + margin-left: 0; + } + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Style link form differently when manual decorators are available. + * See: https://github.com/ckeditor/ckeditor5-link/issues/186. + */ +.ck.ck-link-form_layout-vertical { + padding: 0; + min-width: var(--ck-input-width); +} +.ck.ck-link-form_layout-vertical .ck-labeled-field-view { + margin: var(--ck-spacing-large) var(--ck-spacing-large) var(--ck-spacing-small); + } +.ck.ck-link-form_layout-vertical .ck-labeled-field-view .ck-input-text { + min-width: 0; + width: 100%; + } +.ck.ck-link-form_layout-vertical > .ck-button { + padding: var(--ck-spacing-standard); + margin: 0; + width: 50%; + border-radius: 0; + } +.ck.ck-link-form_layout-vertical > .ck-button:not(:focus) { + border-top: 1px solid var(--ck-color-base-border); + } +[dir="ltr"] .ck.ck-link-form_layout-vertical > .ck-button { + margin-left: 0; + } +[dir="rtl"] .ck.ck-link-form_layout-vertical > .ck-button { + margin-left: 0; + } +[dir="rtl"] .ck.ck-link-form_layout-vertical > .ck-button:last-of-type { + border-right: 1px solid var(--ck-color-base-border); + } +/* Using additional `.ck` class for stronger CSS specificity than `.ck.ck-link-form > :not(:first-child)`. */ +.ck.ck-link-form_layout-vertical .ck.ck-list { + margin: 0 var(--ck-spacing-large); + } +.ck.ck-link-form_layout-vertical .ck.ck-list .ck-button.ck-switchbutton { + padding: 0; + width: 100%; + } +.ck.ck-link-form_layout-vertical .ck.ck-list .ck-button.ck-switchbutton:hover { + background: none; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + /* Match the icon size with the upload indicator brought by the image upload feature. */ + --ck-link-image-indicator-icon-size: 20; + --ck-link-image-indicator-icon-is-visible: clamp(0px, 100% - 50px, 1px); +} +/* Linked image indicator */ +.ck.ck-editor__editable figure.image > a::after, .ck.ck-editor__editable a span.image-inline::after { + content: ""; + + /* + * Smaller images should have the icon closer to the border. + * Match the icon position with the upload indicator brought by the image upload feature. + */ + top: min(var(--ck-spacing-medium), 6%); + right: min(var(--ck-spacing-medium), 6%); + + background-color: hsla(0, 0%, 0%, .4); + background-image: url("data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAgMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI2ZmZiIgZD0ibTExLjA3NyAxNSAuOTkxLTEuNDE2YS43NS43NSAwIDEgMSAxLjIyOS44NmwtMS4xNDggMS42NGEuNzQ4Ljc0OCAwIDAgMS0uMjE3LjIwNiA1LjI1MSA1LjI1MSAwIDAgMS04LjUwMy01Ljk1NS43NDEuNzQxIDAgMCAxIC4xMi0uMjc0bDEuMTQ3LTEuNjM5YS43NS43NSAwIDEgMSAxLjIyOC44Nkw0LjkzMyAxMC43bC4wMDYuMDAzYTMuNzUgMy43NSAwIDAgMCA2LjEzMiA0LjI5NGwuMDA2LjAwNHptNS40OTQtNS4zMzVhLjc0OC43NDggMCAwIDEtLjEyLjI3NGwtMS4xNDcgMS42MzlhLjc1Ljc1IDAgMSAxLTEuMjI4LS44NmwuODYtMS4yM2EzLjc1IDMuNzUgMCAwIDAtNi4xNDQtNC4zMDFsLS44NiAxLjIyOWEuNzUuNzUgMCAwIDEtMS4yMjktLjg2bDEuMTQ4LTEuNjRhLjc0OC43NDggMCAwIDEgLjIxNy0uMjA2IDUuMjUxIDUuMjUxIDAgMCAxIDguNTAzIDUuOTU1em0tNC41NjMtMi41MzJhLjc1Ljc1IDAgMCAxIC4xODQgMS4wNDVsLTMuMTU1IDQuNTA1YS43NS43NSAwIDEgMS0xLjIyOS0uODZsMy4xNTUtNC41MDZhLjc1Ljc1IDAgMCAxIDEuMDQ1LS4xODR6Ii8+PC9zdmc+"); + background-size: 14px; + background-repeat: no-repeat; + background-position: center; + border-radius: 100%; + + /* + * Use CSS math to simulate container queries. + * https://css-tricks.com/the-raven-technique-one-step-closer-to-container-queries/#what-about-showing-and-hiding-things + */ + overflow: hidden; + width: calc(var(--ck-link-image-indicator-icon-is-visible) * var(--ck-link-image-indicator-icon-size)); + height: calc(var(--ck-link-image-indicator-icon-is-visible) * var(--ck-link-image-indicator-icon-size)); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* When there are no list styles and there is no collapsible. */ +.ck.ck-list-properties.ck-list-properties_without-styles { + padding: var(--ck-spacing-large); + } +.ck.ck-list-properties.ck-list-properties_without-styles > * { + min-width: 14em; + } +.ck.ck-list-properties.ck-list-properties_without-styles > * + * { + margin-top: var(--ck-spacing-standard); + } +/* + * When the numbered list property fields (start at, reversed) should be displayed, + * more horizontal space is needed. Reconfigure the style grid to create that space. + */ +.ck.ck-list-properties.ck-list-properties_with-numbered-properties > .ck-list-styles-list { + grid-template-columns: repeat( 4, auto ); + } +/* When list styles are rendered and property fields are in a collapsible. */ +.ck.ck-list-properties.ck-list-properties_with-numbered-properties > .ck-collapsible { + border-top: 1px solid var(--ck-color-base-border); + } +.ck.ck-list-properties.ck-list-properties_with-numbered-properties > .ck-collapsible > .ck-collapsible__children > * { + width: 100%; + } +.ck.ck-list-properties.ck-list-properties_with-numbered-properties > .ck-collapsible > .ck-collapsible__children > * + * { + margin-top: var(--ck-spacing-standard); + } +.ck.ck-list-properties .ck.ck-numbered-list-properties__start-index .ck-input { + min-width: auto; + width: 100%; + } +.ck.ck-list-properties .ck.ck-numbered-list-properties__reversed-order { + background: transparent; + padding-left: 0; + padding-right: 0; + margin-bottom: calc(-1 * var(--ck-spacing-tiny)); + } +.ck.ck-list-properties .ck.ck-numbered-list-properties__reversed-order:active, .ck.ck-list-properties .ck.ck-numbered-list-properties__reversed-order:hover { + box-shadow: none; + border-color: transparent; + background: none; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-list-style-button-size: 44px; +} +.ck.ck-list-styles-list { + grid-template-columns: repeat( 3, auto ); + row-gap: var(--ck-spacing-medium); + column-gap: var(--ck-spacing-medium); + padding: var(--ck-spacing-large); +} +.ck.ck-list-styles-list .ck-button { + /* Make the button look like a thumbnail (the icon "takes it all"). */ + width: var(--ck-list-style-button-size); + height: var(--ck-list-style-button-size); + padding: 0; + + /* + * Buttons are aligned by the grid so disable default button margins to not collide with the + * gaps in the grid. + */ + margin: 0; + + /* + * Make sure the button border (which is displayed on focus, BTW) does not steal pixels + * from the button dimensions and, as a result, decrease the size of the icon + * (which becomes blurry as it scales down). + */ + box-sizing: content-box; + } +.ck.ck-list-styles-list .ck-button .ck-icon { + width: var(--ck-list-style-button-size); + height: var(--ck-list-style-button-size); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-media-embed-placeholder-icon-size: 3em; + + --ck-color-media-embed-placeholder-url-text: hsl(0, 0%, 46%); + --ck-color-media-embed-placeholder-url-text-hover: var(--ck-color-base-text); +} +.ck-media__wrapper { + margin: 0 auto; +} +.ck-media__wrapper .ck-media__placeholder { + padding: calc( 3 * var(--ck-spacing-standard) ); + background: var(--ck-color-base-foreground); + } +.ck-media__wrapper .ck-media__placeholder .ck-media__placeholder__icon { + min-width: var(--ck-media-embed-placeholder-icon-size); + height: var(--ck-media-embed-placeholder-icon-size); + margin-bottom: var(--ck-spacing-large); + background-position: center; + background-size: cover; + } +.ck-media__wrapper .ck-media__placeholder .ck-media__placeholder__icon .ck-icon { + width: 100%; + height: 100%; + } +.ck-media__wrapper .ck-media__placeholder .ck-media__placeholder__url__text { + color: var(--ck-color-media-embed-placeholder-url-text); + white-space: nowrap; + text-align: center; + font-style: italic; + text-overflow: ellipsis; + } +.ck-media__wrapper .ck-media__placeholder .ck-media__placeholder__url__text:hover { + color: var(--ck-color-media-embed-placeholder-url-text-hover); + cursor: pointer; + text-decoration: underline; + } +.ck-media__wrapper[data-oembed-url*="open.spotify.com"] { + max-width: 300px; + max-height: 380px; + } +.ck-media__wrapper[data-oembed-url*="google.com/maps"] .ck-media__placeholder__icon, + .ck-media__wrapper[data-oembed-url*="goo.gl/maps"] .ck-media__placeholder__icon, + .ck-media__wrapper[data-oembed-url*="maps.google.com"] .ck-media__placeholder__icon, + .ck-media__wrapper[data-oembed-url*="maps.app.goo.gl"] .ck-media__placeholder__icon { + background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTAuMzc4IiBoZWlnaHQ9IjI1NC4xNjciIHZpZXdCb3g9IjAgMCA2Ni4yNDYgNjcuMjQ4Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTcyLjUzMSAtMjE4LjQ1NSkgc2NhbGUoLjk4MDEyKSI+PHJlY3Qgcnk9IjUuMjM4IiByeD0iNS4yMzgiIHk9IjIzMS4zOTkiIHg9IjE3Ni4wMzEiIGhlaWdodD0iNjAuMDk5IiB3aWR0aD0iNjAuMDk5IiBmaWxsPSIjMzRhNjY4IiBwYWludC1vcmRlcj0ibWFya2VycyBzdHJva2UgZmlsbCIvPjxwYXRoIGQ9Ik0yMDYuNDc3IDI2MC45bC0yOC45ODcgMjguOTg3YTUuMjE4IDUuMjE4IDAgMCAwIDMuNzggMS42MWg0OS42MjFjMS42OTQgMCAzLjE5LS43OTggNC4xNDYtMi4wMzd6IiBmaWxsPSIjNWM4OGM1Ii8+PHBhdGggZD0iTTIyNi43NDIgMjIyLjk4OGMtOS4yNjYgMC0xNi43NzcgNy4xNy0xNi43NzcgMTYuMDE0LjAwNyAyLjc2Mi42NjMgNS40NzQgMi4wOTMgNy44NzUuNDMuNzAzLjgzIDEuNDA4IDEuMTkgMi4xMDcuMzMzLjUwMi42NSAxLjAwNS45NSAxLjUwOC4zNDMuNDc3LjY3My45NTcuOTg4IDEuNDQgMS4zMSAxLjc2OSAyLjUgMy41MDIgMy42MzcgNS4xNjguNzkzIDEuMjc1IDEuNjgzIDIuNjQgMi40NjYgMy45OSAyLjM2MyA0LjA5NCA0LjAwNyA4LjA5MiA0LjYgMTMuOTE0di4wMTJjLjE4Mi40MTIuNTE2LjY2Ni44NzkuNjY3LjQwMy0uMDAxLjc2OC0uMzE0LjkzLS43OTkuNjAzLTUuNzU2IDIuMjM4LTkuNzI5IDQuNTg1LTEzLjc5NC43ODItMS4zNSAxLjY3My0yLjcxNSAyLjQ2NS0zLjk5IDEuMTM3LTEuNjY2IDIuMzI4LTMuNCAzLjYzOC01LjE2OS4zMTUtLjQ4Mi42NDUtLjk2Mi45ODgtMS40MzkuMy0uNTAzLjYxNy0xLjAwNi45NS0xLjUwOC4zNTktLjcuNzYtMS40MDQgMS4xOS0yLjEwNyAxLjQyNi0yLjQwMiAyLTUuMTE0IDIuMDA0LTcuODc1IDAtOC44NDQtNy41MTEtMTYuMDE0LTE2Ljc3Ni0xNi4wMTR6IiBmaWxsPSIjZGQ0YjNlIiBwYWludC1vcmRlcj0ibWFya2VycyBzdHJva2UgZmlsbCIvPjxlbGxpcHNlIHJ5PSI1LjU2NCIgcng9IjUuODI4IiBjeT0iMjM5LjAwMiIgY3g9IjIyNi43NDIiIGZpbGw9IiM4MDJkMjciIHBhaW50LW9yZGVyPSJtYXJrZXJzIHN0cm9rZSBmaWxsIi8+PHBhdGggZD0iTTE5MC4zMDEgMjM3LjI4M2MtNC42NyAwLTguNDU3IDMuODUzLTguNDU3IDguNjA2czMuNzg2IDguNjA3IDguNDU3IDguNjA3YzMuMDQzIDAgNC44MDYtLjk1OCA2LjMzNy0yLjUxNiAxLjUzLTEuNTU3IDIuMDg3LTMuOTEzIDIuMDg3LTYuMjkgMC0uMzYyLS4wMjMtLjcyMi0uMDY0LTEuMDc5aC04LjI1N3YzLjA0M2g0Ljg1Yy0uMTk3Ljc1OS0uNTMxIDEuNDUtMS4wNTggMS45ODYtLjk0Mi45NTgtMi4wMjggMS41NDgtMy45MDEgMS41NDgtMi44NzYgMC01LjIwOC0yLjM3Mi01LjIwOC01LjI5OSAwLTIuOTI2IDIuMzMyLTUuMjk5IDUuMjA4LTUuMjk5IDEuMzk5IDAgMi42MTguNDA3IDMuNTg0IDEuMjkzbDIuMzgxLTIuMzhjMC0uMDAyLS4wMDMtLjAwNC0uMDA0LS4wMDUtMS41ODgtMS41MjQtMy42Mi0yLjIxNS01Ljk1NS0yLjIxNXptNC40MyA1LjY2bC4wMDMuMDA2di0uMDAzeiIgZmlsbD0iI2ZmZiIgcGFpbnQtb3JkZXI9Im1hcmtlcnMgc3Ryb2tlIGZpbGwiLz48cGF0aCBkPSJNMjE1LjE4NCAyNTEuOTI5bC03Ljk4IDcuOTc5IDI4LjQ3NyAyOC40NzVjLjI4Ny0uNjQ5LjQ0OS0xLjM2Ni40NDktMi4xMjN2LTMxLjE2NWMtLjQ2OS42NzUtLjkzNCAxLjM0OS0xLjM4MiAyLjAwNS0uNzkyIDEuMjc1LTEuNjgyIDIuNjQtMi40NjUgMy45OS0yLjM0NyA0LjA2NS0zLjk4MiA4LjAzOC00LjU4NSAxMy43OTQtLjE2Mi40ODUtLjUyNy43OTgtLjkzLjc5OS0uMzYzLS4wMDEtLjY5Ny0uMjU1LS44NzktLjY2N3YtLjAxMmMtLjU5My01LjgyMi0yLjIzNy05LjgyLTQuNi0xMy45MTQtLjc4My0xLjM1LTEuNjczLTIuNzE1LTIuNDY2LTMuOTktMS4xMzctMS42NjYtMi4zMjctMy40LTMuNjM3LTUuMTY5bC0uMDAyLS4wMDN6IiBmaWxsPSIjYzNjM2MzIi8+PHBhdGggZD0iTTIxMi45ODMgMjQ4LjQ5NWwtMzYuOTUyIDM2Ljk1M3YuODEyYTUuMjI3IDUuMjI3IDAgMCAwIDUuMjM4IDUuMjM4aDEuMDE1bDM1LjY2Ni0zNS42NjZhMTM2LjI3NSAxMzYuMjc1IDAgMCAwLTIuNzY0LTMuOSAzNy41NzUgMzcuNTc1IDAgMCAwLS45ODktMS40NGMtLjI5OS0uNTAzLS42MTYtMS4wMDYtLjk1LTEuNTA4LS4wODMtLjE2Mi0uMTc2LS4zMjYtLjI2NC0uNDg5eiIgZmlsbD0iI2ZkZGM0ZiIgcGFpbnQtb3JkZXI9Im1hcmtlcnMgc3Ryb2tlIGZpbGwiLz48cGF0aCBkPSJNMjExLjk5OCAyNjEuMDgzbC02LjE1MiA2LjE1MSAyNC4yNjQgMjQuMjY0aC43ODFhNS4yMjcgNS4yMjcgMCAwIDAgNS4yMzktNS4yMzh2LTEuMDQ1eiIgZmlsbD0iI2ZmZiIgcGFpbnQtb3JkZXI9Im1hcmtlcnMgc3Ryb2tlIGZpbGwiLz48L2c+PC9zdmc+); + } +.ck-media__wrapper[data-oembed-url*="facebook.com"] .ck-media__placeholder { + background: hsl(220, 46%, 48%); + } +.ck-media__wrapper[data-oembed-url*="facebook.com"] .ck-media__placeholder .ck-media__placeholder__icon { + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIxMDI0cHgiIGhlaWdodD0iMTAyNHB4IiB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPiAgICAgICAgPHRpdGxlPkZpbGwgMTwvdGl0bGU+ICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiAgICA8ZGVmcz48L2RlZnM+ICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPiAgICAgICAgPGcgaWQ9ImZMb2dvX1doaXRlIiBmaWxsPSIjRkZGRkZFIj4gICAgICAgICAgICA8cGF0aCBkPSJNOTY3LjQ4NCwwIEw1Ni41MTcsMCBDMjUuMzA0LDAgMCwyNS4zMDQgMCw1Ni41MTcgTDAsOTY3LjQ4MyBDMCw5OTguNjk0IDI1LjI5NywxMDI0IDU2LjUyMiwxMDI0IEw1NDcsMTAyNCBMNTQ3LDYyOCBMNDE0LDYyOCBMNDE0LDQ3MyBMNTQ3LDQ3MyBMNTQ3LDM1OS4wMjkgQzU0NywyMjYuNzY3IDYyNy43NzMsMTU0Ljc0NyA3NDUuNzU2LDE1NC43NDcgQzgwMi4yNjksMTU0Ljc0NyA4NTAuODQyLDE1OC45NTUgODY1LDE2MC44MzYgTDg2NSwyOTkgTDc4My4zODQsMjk5LjAzNyBDNzE5LjM5MSwyOTkuMDM3IDcwNywzMjkuNTI5IDcwNywzNzQuMjczIEw3MDcsNDczIEw4NjAuNDg3LDQ3MyBMODQwLjUwMSw2MjggTDcwNyw2MjggTDcwNywxMDI0IEw5NjcuNDg0LDEwMjQgQzk5OC42OTcsMTAyNCAxMDI0LDk5OC42OTcgMTAyNCw5NjcuNDg0IEwxMDI0LDU2LjUxNSBDMTAyNCwyNS4zMDMgOTk4LjY5NywwIDk2Ny40ODQsMCIgaWQ9IkZpbGwtMSI+PC9wYXRoPiAgICAgICAgPC9nPiAgICA8L2c+PC9zdmc+); + } +.ck-media__wrapper[data-oembed-url*="facebook.com"] .ck-media__placeholder .ck-media__placeholder__url__text { + color: hsl(220, 100%, 90%); + } +.ck-media__wrapper[data-oembed-url*="facebook.com"] .ck-media__placeholder .ck-media__placeholder__url__text:hover { + color: hsl(0, 0%, 100%); + } +.ck-media__wrapper[data-oembed-url*="instagram.com"] .ck-media__placeholder { + background: linear-gradient(-135deg,hsl(246, 100%, 39%),hsl(302, 100%, 36%),hsl(0, 100%, 48%)); + } +.ck-media__wrapper[data-oembed-url*="instagram.com"] .ck-media__placeholder .ck-media__placeholder__icon { + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSI1MDRweCIgaGVpZ2h0PSI1MDRweCIgdmlld0JveD0iMCAwIDUwNCA1MDQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+ICAgICAgICA8dGl0bGU+Z2x5cGgtbG9nb19NYXkyMDE2PC90aXRsZT4gICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+ICAgIDxkZWZzPiAgICAgICAgPHBvbHlnb24gaWQ9InBhdGgtMSIgcG9pbnRzPSIwIDAuMTU5IDUwMy44NDEgMC4xNTkgNTAzLjg0MSA1MDMuOTQgMCA1MDMuOTQiPjwvcG9seWdvbj4gICAgPC9kZWZzPiAgICA8ZyBpZD0iZ2x5cGgtbG9nb19NYXkyMDE2IiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4gICAgICAgIDxnIGlkPSJHcm91cC0zIj4gICAgICAgICAgICA8bWFzayBpZD0ibWFzay0yIiBmaWxsPSJ3aGl0ZSI+ICAgICAgICAgICAgICAgIDx1c2UgeGxpbms6aHJlZj0iI3BhdGgtMSI+PC91c2U+ICAgICAgICAgICAgPC9tYXNrPiAgICAgICAgICAgIDxnIGlkPSJDbGlwLTIiPjwvZz4gICAgICAgICAgICA8cGF0aCBkPSJNMjUxLjkyMSwwLjE1OSBDMTgzLjUwMywwLjE1OSAxNzQuOTI0LDAuNDQ5IDE0OC4wNTQsMS42NzUgQzEyMS4yNCwyLjg5OCAxMDIuOTI3LDcuMTU3IDg2LjkwMywxMy4zODUgQzcwLjMzNywxOS44MjIgNTYuMjg4LDI4LjQzNiA0Mi4yODIsNDIuNDQxIEMyOC4yNzcsNTYuNDQ3IDE5LjY2Myw3MC40OTYgMTMuMjI2LDg3LjA2MiBDNi45OTgsMTAzLjA4NiAyLjczOSwxMjEuMzk5IDEuNTE2LDE0OC4yMTMgQzAuMjksMTc1LjA4MyAwLDE4My42NjIgMCwyNTIuMDggQzAsMzIwLjQ5NyAwLjI5LDMyOS4wNzYgMS41MTYsMzU1Ljk0NiBDMi43MzksMzgyLjc2IDYuOTk4LDQwMS4wNzMgMTMuMjI2LDQxNy4wOTcgQzE5LjY2Myw0MzMuNjYzIDI4LjI3Nyw0NDcuNzEyIDQyLjI4Miw0NjEuNzE4IEM1Ni4yODgsNDc1LjcyMyA3MC4zMzcsNDg0LjMzNyA4Ni45MDMsNDkwLjc3NSBDMTAyLjkyNyw0OTcuMDAyIDEyMS4yNCw1MDEuMjYxIDE0OC4wNTQsNTAyLjQ4NCBDMTc0LjkyNCw1MDMuNzEgMTgzLjUwMyw1MDQgMjUxLjkyMSw1MDQgQzMyMC4zMzgsNTA0IDMyOC45MTcsNTAzLjcxIDM1NS43ODcsNTAyLjQ4NCBDMzgyLjYwMSw1MDEuMjYxIDQwMC45MTQsNDk3LjAwMiA0MTYuOTM4LDQ5MC43NzUgQzQzMy41MDQsNDg0LjMzNyA0NDcuNTUzLDQ3NS43MjMgNDYxLjU1OSw0NjEuNzE4IEM0NzUuNTY0LDQ0Ny43MTIgNDg0LjE3OCw0MzMuNjYzIDQ5MC42MTYsNDE3LjA5NyBDNDk2Ljg0Myw0MDEuMDczIDUwMS4xMDIsMzgyLjc2IDUwMi4zMjUsMzU1Ljk0NiBDNTAzLjU1MSwzMjkuMDc2IDUwMy44NDEsMzIwLjQ5NyA1MDMuODQxLDI1Mi4wOCBDNTAzLjg0MSwxODMuNjYyIDUwMy41NTEsMTc1LjA4MyA1MDIuMzI1LDE0OC4yMTMgQzUwMS4xMDIsMTIxLjM5OSA0OTYuODQzLDEwMy4wODYgNDkwLjYxNiw4Ny4wNjIgQzQ4NC4xNzgsNzAuNDk2IDQ3NS41NjQsNTYuNDQ3IDQ2MS41NTksNDIuNDQxIEM0NDcuNTUzLDI4LjQzNiA0MzMuNTA0LDE5LjgyMiA0MTYuOTM4LDEzLjM4NSBDNDAwLjkxNCw3LjE1NyAzODIuNjAxLDIuODk4IDM1NS43ODcsMS42NzUgQzMyOC45MTcsMC40NDkgMzIwLjMzOCwwLjE1OSAyNTEuOTIxLDAuMTU5IFogTTI1MS45MjEsNDUuNTUgQzMxOS4xODYsNDUuNTUgMzI3LjE1NCw0NS44MDcgMzUzLjcxOCw0Ny4wMTkgQzM3OC4yOCw0OC4xMzkgMzkxLjYxOSw1Mi4yNDMgNDAwLjQ5Niw1NS42OTMgQzQxMi4yNTUsNjAuMjYzIDQyMC42NDcsNjUuNzIyIDQyOS40NjIsNzQuNTM4IEM0MzguMjc4LDgzLjM1MyA0NDMuNzM3LDkxLjc0NSA0NDguMzA3LDEwMy41MDQgQzQ1MS43NTcsMTEyLjM4MSA0NTUuODYxLDEyNS43MiA0NTYuOTgxLDE1MC4yODIgQzQ1OC4xOTMsMTc2Ljg0NiA0NTguNDUsMTg0LjgxNCA0NTguNDUsMjUyLjA4IEM0NTguNDUsMzE5LjM0NSA0NTguMTkzLDMyNy4zMTMgNDU2Ljk4MSwzNTMuODc3IEM0NTUuODYxLDM3OC40MzkgNDUxLjc1NywzOTEuNzc4IDQ0OC4zMDcsNDAwLjY1NSBDNDQzLjczNyw0MTIuNDE0IDQzOC4yNzgsNDIwLjgwNiA0MjkuNDYyLDQyOS42MjEgQzQyMC42NDcsNDM4LjQzNyA0MTIuMjU1LDQ0My44OTYgNDAwLjQ5Niw0NDguNDY2IEMzOTEuNjE5LDQ1MS45MTYgMzc4LjI4LDQ1Ni4wMiAzNTMuNzE4LDQ1Ny4xNCBDMzI3LjE1OCw0NTguMzUyIDMxOS4xOTEsNDU4LjYwOSAyNTEuOTIxLDQ1OC42MDkgQzE4NC42NSw0NTguNjA5IDE3Ni42ODQsNDU4LjM1MiAxNTAuMTIzLDQ1Ny4xNCBDMTI1LjU2MSw0NTYuMDIgMTEyLjIyMiw0NTEuOTE2IDEwMy4zNDUsNDQ4LjQ2NiBDOTEuNTg2LDQ0My44OTYgODMuMTk0LDQzOC40MzcgNzQuMzc5LDQyOS42MjEgQzY1LjU2NCw0MjAuODA2IDYwLjEwNCw0MTIuNDE0IDU1LjUzNCw0MDAuNjU1IEM1Mi4wODQsMzkxLjc3OCA0Ny45OCwzNzguNDM5IDQ2Ljg2LDM1My44NzcgQzQ1LjY0OCwzMjcuMzEzIDQ1LjM5MSwzMTkuMzQ1IDQ1LjM5MSwyNTIuMDggQzQ1LjM5MSwxODQuODE0IDQ1LjY0OCwxNzYuODQ2IDQ2Ljg2LDE1MC4yODIgQzQ3Ljk4LDEyNS43MiA1Mi4wODQsMTEyLjM4MSA1NS41MzQsMTAzLjUwNCBDNjAuMTA0LDkxLjc0NSA2NS41NjMsODMuMzUzIDc0LjM3OSw3NC41MzggQzgzLjE5NCw2NS43MjIgOTEuNTg2LDYwLjI2MyAxMDMuMzQ1LDU1LjY5MyBDMTEyLjIyMiw1Mi4yNDMgMTI1LjU2MSw0OC4xMzkgMTUwLjEyMyw0Ny4wMTkgQzE3Ni42ODcsNDUuODA3IDE4NC42NTUsNDUuNTUgMjUxLjkyMSw0NS41NSBaIiBpZD0iRmlsbC0xIiBmaWxsPSIjRkZGRkZGIiBtYXNrPSJ1cmwoI21hc2stMikiPjwvcGF0aD4gICAgICAgIDwvZz4gICAgICAgIDxwYXRoIGQ9Ik0yNTEuOTIxLDMzNi4wNTMgQzIwNS41NDMsMzM2LjA1MyAxNjcuOTQ3LDI5OC40NTcgMTY3Ljk0NywyNTIuMDggQzE2Ny45NDcsMjA1LjcwMiAyMDUuNTQzLDE2OC4xMDYgMjUxLjkyMSwxNjguMTA2IEMyOTguMjk4LDE2OC4xMDYgMzM1Ljg5NCwyMDUuNzAyIDMzNS44OTQsMjUyLjA4IEMzMzUuODk0LDI5OC40NTcgMjk4LjI5OCwzMzYuMDUzIDI1MS45MjEsMzM2LjA1MyBaIE0yNTEuOTIxLDEyMi43MTUgQzE4MC40NzQsMTIyLjcxNSAxMjIuNTU2LDE4MC42MzMgMTIyLjU1NiwyNTIuMDggQzEyMi41NTYsMzIzLjUyNiAxODAuNDc0LDM4MS40NDQgMjUxLjkyMSwzODEuNDQ0IEMzMjMuMzY3LDM4MS40NDQgMzgxLjI4NSwzMjMuNTI2IDM4MS4yODUsMjUyLjA4IEMzODEuMjg1LDE4MC42MzMgMzIzLjM2NywxMjIuNzE1IDI1MS45MjEsMTIyLjcxNSBaIiBpZD0iRmlsbC00IiBmaWxsPSIjRkZGRkZGIj48L3BhdGg+ICAgICAgICA8cGF0aCBkPSJNNDE2LjYyNywxMTcuNjA0IEM0MTYuNjI3LDEzNC4zIDQwMy4wOTIsMTQ3LjgzNCAzODYuMzk2LDE0Ny44MzQgQzM2OS43MDEsMTQ3LjgzNCAzNTYuMTY2LDEzNC4zIDM1Ni4xNjYsMTE3LjYwNCBDMzU2LjE2NiwxMDAuOTA4IDM2OS43MDEsODcuMzczIDM4Ni4zOTYsODcuMzczIEM0MDMuMDkyLDg3LjM3MyA0MTYuNjI3LDEwMC45MDggNDE2LjYyNywxMTcuNjA0IiBpZD0iRmlsbC01IiBmaWxsPSIjRkZGRkZGIj48L3BhdGg+ICAgIDwvZz48L3N2Zz4=); + } +/* stylelint-disable-next-line no-descending-specificity */ +.ck-media__wrapper[data-oembed-url*="instagram.com"] .ck-media__placeholder .ck-media__placeholder__url__text { + color: hsl(302, 100%, 94%); + } +.ck-media__wrapper[data-oembed-url*="instagram.com"] .ck-media__placeholder .ck-media__placeholder__url__text:hover { + color: hsl(0, 0%, 100%); + } +.ck-media__wrapper[data-oembed-url*="twitter.com"] .ck.ck-media__placeholder { + /* Use gradient to contrast with focused widget (ckeditor/ckeditor5-media-embed#22). */ + background: linear-gradient( to right, hsl(201, 85%, 70%), hsl(201, 85%, 35%) ); + } +.ck-media__wrapper[data-oembed-url*="twitter.com"] .ck.ck-media__placeholder .ck-media__placeholder__icon { + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IldoaXRlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQwMCA0MDAiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDQwMCA0MDA7IiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGUgdHlwZT0idGV4dC9jc3MiPi5zdDB7ZmlsbDojRkZGRkZGO308L3N0eWxlPjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik00MDAsMjAwYzAsMTEwLjUtODkuNSwyMDAtMjAwLDIwMFMwLDMxMC41LDAsMjAwUzg5LjUsMCwyMDAsMFM0MDAsODkuNSw0MDAsMjAweiBNMTYzLjQsMzA1LjVjODguNywwLDEzNy4yLTczLjUsMTM3LjItMTM3LjJjMC0yLjEsMC00LjItMC4xLTYuMmM5LjQtNi44LDE3LjYtMTUuMywyNC4xLTI1Yy04LjYsMy44LTE3LjksNi40LTI3LjcsNy42YzEwLTYsMTcuNi0xNS40LDIxLjItMjYuN2MtOS4zLDUuNS0xOS42LDkuNS0zMC42LDExLjdjLTguOC05LjQtMjEuMy0xNS4yLTM1LjItMTUuMmMtMjYuNiwwLTQ4LjIsMjEuNi00OC4yLDQ4LjJjMCwzLjgsMC40LDcuNSwxLjMsMTFjLTQwLjEtMi03NS42LTIxLjItOTkuNC01MC40Yy00LjEsNy4xLTYuNSwxNS40LTYuNSwyNC4yYzAsMTYuNyw4LjUsMzEuNSwyMS41LDQwLjFjLTcuOS0wLjItMTUuMy0yLjQtMjEuOC02YzAsMC4yLDAsMC40LDAsMC42YzAsMjMuNCwxNi42LDQyLjgsMzguNyw0Ny4zYy00LDEuMS04LjMsMS43LTEyLjcsMS43Yy0zLjEsMC02LjEtMC4zLTkuMS0wLjljNi4xLDE5LjIsMjMuOSwzMy4xLDQ1LDMzLjVjLTE2LjUsMTIuOS0zNy4zLDIwLjYtNTkuOSwyMC42Yy0zLjksMC03LjctMC4yLTExLjUtMC43QzExMC44LDI5Ny41LDEzNi4yLDMwNS41LDE2My40LDMwNS41Ii8+PC9zdmc+); + } +.ck-media__wrapper[data-oembed-url*="twitter.com"] .ck.ck-media__placeholder .ck-media__placeholder__url__text { + color: hsl(201, 100%, 86%); + } +.ck-media__wrapper[data-oembed-url*="twitter.com"] .ck.ck-media__placeholder .ck-media__placeholder__url__text:hover { + color: hsl(0, 0%, 100%); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-color-mention-background: hsla(341, 100%, 30%, 0.1); + --ck-color-mention-text: hsl(341, 100%, 30%); +} +.ck-content .mention { + background: var(--ck-color-mention-background); + color: var(--ck-color-mention-text); +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-color-restricted-editing-exception-background: hsla(31, 100%, 65%, .2); + --ck-color-restricted-editing-exception-hover-background: hsla(31, 100%, 65%, .35); + --ck-color-restricted-editing-exception-brackets: hsla(31, 100%, 40%, .4); + --ck-color-restricted-editing-selected-exception-background: hsla(31, 100%, 65%, .5); + --ck-color-restricted-editing-selected-exception-brackets: hsla(31, 100%, 40%, .6); +} +.ck-editor__editable .restricted-editing-exception { + transition: .2s ease-in-out background; + background-color: var(--ck-color-restricted-editing-exception-background); + border: 1px solid; + border-image: linear-gradient( + to right, + var(--ck-color-restricted-editing-exception-brackets) 0%, + var(--ck-color-restricted-editing-exception-brackets) 5px, + hsla(0, 0%, 0%, 0) 6px, + hsla(0, 0%, 0%, 0) calc(100% - 6px), + var(--ck-color-restricted-editing-exception-brackets) calc(100% - 5px), + var(--ck-color-restricted-editing-exception-brackets) 100% + ) 1; +} +@media (prefers-reduced-motion: reduce) { +.ck-editor__editable .restricted-editing-exception { + transition: none; +} + } +.ck-editor__editable .restricted-editing-exception.restricted-editing-exception_selected { + background-color: var(--ck-color-restricted-editing-selected-exception-background); + border-image: linear-gradient( + to right, + var(--ck-color-restricted-editing-selected-exception-brackets) 0%, + var(--ck-color-restricted-editing-selected-exception-brackets) 5px, + var(--ck-color-restricted-editing-selected-exception-brackets) calc(100% - 5px), + var(--ck-color-restricted-editing-selected-exception-brackets) 100% + ) 1; + } +.ck-editor__editable .restricted-editing-exception.restricted-editing-exception_collapsed { + /* Empty exception should have the same width as exception with at least 1 char */ + padding-left: 1ch; + } +.ck-restricted-editing_mode_restricted { + cursor: default; + + /* We also have to override all elements inside the restricted editable to prevent cursor switching between default and text + during the pointer movement. */ +} +.ck-restricted-editing_mode_restricted * { + cursor: default; + } +.ck-restricted-editing_mode_restricted .restricted-editing-exception { + cursor: text; + } +.ck-restricted-editing_mode_restricted .restricted-editing-exception * { + cursor: text; + } +.ck-restricted-editing_mode_restricted .restricted-editing-exception:hover { + background: var(--ck-color-restricted-editing-exception-hover-background); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +:root { + --ck-character-grid-tile-size: 24px; +} +.ck.ck-character-grid { + overflow-y: auto; + overflow-x: hidden; +} +.ck.ck-character-grid .ck-character-grid__tiles { + grid-template-columns: repeat(auto-fill, minmax(var(--ck-character-grid-tile-size), 1fr)); + margin: var(--ck-spacing-standard) var(--ck-spacing-large); + grid-gap: var(--ck-spacing-standard); + } +.ck.ck-character-grid .ck-character-grid__tile { + width: var(--ck-character-grid-tile-size); + height: var(--ck-character-grid-tile-size); + min-width: var(--ck-character-grid-tile-size); + min-height: var(--ck-character-grid-tile-size); + font-size: 1.5em; + padding: 0; + transition: .2s ease box-shadow; + border: 0; + } +@media (prefers-reduced-motion: reduce) { +.ck.ck-character-grid .ck-character-grid__tile { + transition: none; + } + } +.ck.ck-character-grid .ck-character-grid__tile:focus:not( .ck-disabled ), + .ck.ck-character-grid .ck-character-grid__tile:hover:not( .ck-disabled ) { + /* Disable the default .ck-button's border ring. */ + border: 0; + box-shadow: inset 0 0 0 1px var(--ck-color-base-background), 0 0 0 2px var(--ck-color-focus-border); + } +/* Make sure the glyph is rendered in the center of the button */ +.ck.ck-character-grid .ck-character-grid__tile .ck-button__label { + line-height: var(--ck-character-grid-tile-size); + width: 100%; + text-align: center; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-character-info { + padding: var(--ck-spacing-small) var(--ck-spacing-large); + border-top: 1px solid var(--ck-color-base-border); +} +.ck.ck-character-info > * { + text-transform: uppercase; + font-size: var(--ck-font-size-small); + } +.ck.ck-character-info .ck-character-info__name { + max-width: 280px; + text-overflow: ellipsis; + overflow: hidden; + } +.ck.ck-character-info .ck-character-info__code { + opacity: .6; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-special-characters-navigation > .ck-label { + max-width: 160px; + text-overflow: ellipsis; + overflow: hidden; + } +.ck.ck-special-characters-navigation > .ck-dropdown .ck-dropdown__panel { + /* There could be dozens of categories available. Use scroll to prevent a 10e6px dropdown. */ + max-height: 250px; + overflow-y: auto; + overflow-x: hidden; + } +@media screen and (max-width: 600px) { +.ck.ck-special-characters-navigation { + max-width: 190px; +} + + .ck.ck-special-characters-navigation > .ck-form__header__label { + text-overflow: ellipsis; + overflow: hidden; + } + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-dropdown.ck-style-dropdown.ck-style-dropdown_multiple-active > .ck-button > .ck-button__label { + font-style: italic; +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-style-panel-button-width: 120px; + --ck-style-panel-button-height: 80px; + --ck-style-panel-button-label-background: hsl(0, 0%, 94.1%); + --ck-style-panel-button-hover-label-background: hsl(0, 0%, 92.1%); + --ck-style-panel-button-hover-border-color: hsl(0, 0%, 70%); +} +.ck.ck-style-panel .ck-style-grid { + row-gap: var(--ck-spacing-large); + column-gap: var(--ck-spacing-large); +} +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button { + --ck-color-button-default-hover-background: var(--ck-color-base-background); + --ck-color-button-default-active-background: var(--ck-color-base-background); + + padding: 0; + width: var(--ck-style-panel-button-width); + height: var(--ck-style-panel-button-height); + + /* Let default .ck-button :focus styles apply */ + } +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button:not(:focus) { + border: 1px solid var(--ck-color-base-border); + } +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button .ck-button__label { + height: 22px; + line-height: 22px; + width: 100%; + padding: 0 var(--ck-spacing-medium); + overflow: hidden; + text-overflow: ellipsis; + flex-shrink: 0; + } +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button .ck-style-grid__button__preview { + width: 100%; + overflow: hidden; + opacity: .9; + + padding: var(--ck-spacing-medium); + background: var(--ck-color-base-background); + border: 2px solid var(--ck-color-base-background); + } +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button.ck-disabled { + --ck-color-button-default-disabled-background: var(--ck-color-base-foreground); + + /* Let default .ck-button :focus styles apply */ + } +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button.ck-disabled:not(:focus) { + border-color: var(--ck-style-panel-button-label-background); + } +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button.ck-disabled .ck-style-grid__button__preview { + opacity: .4; + + border-color: var(--ck-color-base-foreground); + filter: saturate(.3); + } +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button.ck-on { + border-color: var(--ck-color-base-active); + } +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button.ck-on .ck-button__label { + box-shadow: 0 -1px 0 var(--ck-color-base-active); + z-index: 1; /* Stay on top of the preview with the shadow. */ + } +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button.ck-on:hover { + border-color: var(--ck-color-base-active-focus); + } +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button:not(.ck-on) .ck-button__label { + background: var(--ck-style-panel-button-label-background); + } +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button:not(.ck-on):hover .ck-button__label { + background: var(--ck-style-panel-button-hover-label-background); + } +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button:hover:not(.ck-disabled):not(.ck-on) { + border-color: var(--ck-style-panel-button-hover-border-color); + } +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button:hover:not(.ck-disabled):not(.ck-on) .ck-style-grid__button__preview { + opacity: 1; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-style-panel .ck-style-panel__style-group > .ck-label { + margin: var(--ck-spacing-large) 0; + } +.ck.ck-style-panel .ck-style-panel__style-group:first-child > .ck-label { + margin-top: 0; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-style-panel-max-height: 470px; +} +.ck.ck-style-panel { + padding: var(--ck-spacing-large); + overflow-y: auto; + max-height: var(--ck-style-panel-max-height); +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +[dir="ltr"] .ck.ck-input-color > .ck.ck-input-text { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +[dir="rtl"] .ck.ck-input-color > .ck.ck-input-text { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } +/* Make sure the focused input is always on top of the dropdown button so its + outline and border are never cropped (also when the input is read-only). */ +.ck.ck-input-color > .ck.ck-input-text:focus { + z-index: 0; + } +.ck.ck-input-color > .ck.ck-dropdown > .ck.ck-button.ck-input-color__button { + padding: 0; + } +[dir="ltr"] .ck.ck-input-color > .ck.ck-dropdown > .ck.ck-button.ck-input-color__button { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } +[dir="ltr"] .ck.ck-input-color > .ck.ck-dropdown > .ck.ck-button.ck-input-color__button:not(:focus) { + border-left: 1px solid transparent; + } +[dir="rtl"] .ck.ck-input-color > .ck.ck-dropdown > .ck.ck-button.ck-input-color__button { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +[dir="rtl"] .ck.ck-input-color > .ck.ck-dropdown > .ck.ck-button.ck-input-color__button:not(:focus) { + border-right: 1px solid transparent; + } +.ck.ck-input-color > .ck.ck-dropdown > .ck.ck-button.ck-input-color__button.ck-disabled { + background: var(--ck-color-input-disabled-background); + } +.ck.ck-input-color > .ck.ck-dropdown > .ck.ck-button.ck-input-color__button > .ck.ck-input-color__button__preview { + border-radius: 0; + + width: 20px; + height: 20px; + border: 1px solid var(--ck-color-input-border); + } +.ck-rounded-corners .ck.ck-input-color > .ck.ck-dropdown > .ck.ck-button.ck-input-color__button > .ck.ck-input-color__button__preview, + .ck.ck-input-color > .ck.ck-dropdown > .ck.ck-button.ck-input-color__button > .ck.ck-input-color__button__preview.ck-rounded-corners { + border-radius: var(--ck-border-radius); + } +.ck.ck-input-color > .ck.ck-dropdown > .ck.ck-button.ck-input-color__button > .ck.ck-input-color__button__preview > .ck.ck-input-color__button__preview__no-color-indicator { + top: -30%; + left: 50%; + height: 150%; + width: 8%; + background: hsl(0, 100%, 50%); + border-radius: 2px; + transform: rotate(45deg); + transform-origin: 50%; + } +.ck.ck-input-color .ck.ck-input-color__remove-color { + width: 100%; + padding: calc(var(--ck-spacing-standard) / 2) var(--ck-spacing-standard); + + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } +.ck.ck-input-color .ck.ck-input-color__remove-color:not(:focus) { + border-bottom: 1px solid var(--ck-color-input-border); + } +[dir="ltr"] .ck.ck-input-color .ck.ck-input-color__remove-color { + border-top-right-radius: 0; + } +[dir="rtl"] .ck.ck-input-color .ck.ck-input-color__remove-color { + border-top-left-radius: 0; + } +.ck.ck-input-color .ck.ck-input-color__remove-color .ck.ck-icon { + margin-right: var(--ck-spacing-standard); + } +[dir="rtl"] .ck.ck-input-color .ck.ck-input-color__remove-color .ck.ck-icon { + margin-right: 0; + margin-left: var(--ck-spacing-standard); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-form { + padding: 0 0 var(--ck-spacing-large); +} +.ck.ck-form:focus { + /* See: https://github.com/ckeditor/ckeditor5/issues/4773 */ + outline: none; + } +.ck.ck-form .ck.ck-input-text { + min-width: 100%; + width: 0; + } +.ck.ck-form .ck.ck-dropdown { + min-width: 100%; + } +.ck.ck-form .ck.ck-dropdown .ck-dropdown__button:not(:focus) { + border: 1px solid var(--ck-color-base-border); + } +.ck.ck-form .ck.ck-dropdown .ck-dropdown__button .ck-button__label { + width: 100%; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-form__row { + padding: var(--ck-spacing-standard) var(--ck-spacing-large) 0; + + /* Ignore labels that work as fieldset legends */ +} +[dir="ltr"] .ck.ck-form__row > *:not(.ck-label) + * { + margin-left: var(--ck-spacing-large); + } +[dir="rtl"] .ck.ck-form__row > *:not(.ck-label) + * { + margin-right: var(--ck-spacing-large); + } +.ck.ck-form__row > .ck-label { + width: 100%; + min-width: 100%; + } +.ck.ck-form__row.ck-table-form__action-row { + margin-top: var(--ck-spacing-large); + } +.ck.ck-form__row.ck-table-form__action-row .ck-button .ck-button__label { + color: var(--ck-color-text); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-insert-table-dropdown-padding: 10px; + --ck-insert-table-dropdown-box-height: 11px; + --ck-insert-table-dropdown-box-width: 12px; + --ck-insert-table-dropdown-box-margin: 1px; +} +.ck .ck-insert-table-dropdown__grid { + /* The width of a container should match 10 items in a row so there will be a 10x10 grid. */ + width: calc(var(--ck-insert-table-dropdown-box-width) * 10 + var(--ck-insert-table-dropdown-box-margin) * 20 + var(--ck-insert-table-dropdown-padding) * 2); + padding: var(--ck-insert-table-dropdown-padding) var(--ck-insert-table-dropdown-padding) 0; +} +.ck .ck-insert-table-dropdown__label, +.ck[dir=rtl] .ck-insert-table-dropdown__label { + text-align: center; +} +.ck .ck-insert-table-dropdown-grid-box { + min-width: var(--ck-insert-table-dropdown-box-width); + min-height: var(--ck-insert-table-dropdown-box-height); + margin: var(--ck-insert-table-dropdown-box-margin); + border: 1px solid var(--ck-color-base-border); + border-radius: 1px; + outline: none; + transition: none; +} +@media (prefers-reduced-motion: reduce) { +.ck .ck-insert-table-dropdown-grid-box { + transition: none; +} + } +.ck .ck-insert-table-dropdown-grid-box:focus { + box-shadow: none; + } +.ck .ck-insert-table-dropdown-grid-box.ck-on { + border-color: var(--ck-color-focus-border); + background: var(--ck-color-focus-outer-shadow); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-table-cell-properties-form { + width: 320px; +} +.ck.ck-table-cell-properties-form .ck-form__row.ck-table-cell-properties-form__padding-row { + align-self: flex-end; + padding: 0; + width: 25%; + } +.ck.ck-table-cell-properties-form .ck-form__row.ck-table-cell-properties-form__alignment-row .ck.ck-toolbar { + background: none; + + /* Compensate for missing input label that would push the margin (toolbar has no inputs). */ + margin-top: var(--ck-spacing-standard); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-color-selector-focused-cell-background: hsla(212, 90%, 80%, .3); +} +/** + * While setting outline is fine, the border should not be modified here + * because it overrides the default table cell border color which is not expected. + * So do not use `@mixin ck-focus-ring;` here, or any other border styles. + * See more: https://github.com/ckeditor/ckeditor5/issues/16979 + */ +.ck-widget.table td.ck-editor__nested-editable.ck-editor__nested-editable_focused, + .ck-widget.table th.ck-editor__nested-editable.ck-editor__nested-editable_focused, + .ck-widget.table td.ck-editor__nested-editable:focus, + .ck-widget.table th.ck-editor__nested-editable:focus { + /* A very slight background to highlight the focused cell */ + background: var(--ck-color-selector-focused-cell-background); + outline: 1px solid var(--ck-color-focus-border); + outline-offset: -1px; /* progressive enhancement - no IE support */ + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +:root { + --ck-table-properties-error-arrow-size: 6px; + --ck-table-properties-min-error-width: 150px; +} +.ck.ck-table-form .ck-form__row.ck-table-form__border-row .ck-labeled-field-view > .ck-label { + font-size: var(--ck-font-size-tiny); + text-align: center; + } +.ck.ck-table-form .ck-form__row.ck-table-form__border-row .ck-table-form__border-style, + .ck.ck-table-form .ck-form__row.ck-table-form__border-row .ck-table-form__border-width { + width: 80px; + min-width: 80px; + max-width: 80px; + } +.ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row { + padding: 0; + } +.ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row .ck-table-form__dimensions-row__width, + .ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row .ck-table-form__dimensions-row__height { + margin: 0 + } +.ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row .ck-table-form__dimension-operator { + align-self: flex-end; + display: inline-block; + height: var(--ck-ui-component-min-height); + line-height: var(--ck-ui-component-min-height); + margin: 0 var(--ck-spacing-small); + } +.ck.ck-table-form .ck.ck-labeled-field-view { + padding-top: var(--ck-spacing-standard); + } +.ck.ck-table-form .ck.ck-labeled-field-view .ck.ck-labeled-field-view__status { + border-radius: 0; + + background: var(--ck-color-base-error); + color: var(--ck-color-base-background); + padding: var(--ck-spacing-small) var(--ck-spacing-medium); + min-width: var(--ck-table-properties-min-error-width); + text-align: center; + + animation: ck-table-form-labeled-view-status-appear .15s ease both; + } +.ck-rounded-corners .ck.ck-table-form .ck.ck-labeled-field-view .ck.ck-labeled-field-view__status, + .ck.ck-table-form .ck.ck-labeled-field-view .ck.ck-labeled-field-view__status.ck-rounded-corners { + border-radius: var(--ck-border-radius); + } +/* The arrow pointing towards the field. */ +.ck.ck-table-form .ck.ck-labeled-field-view .ck.ck-labeled-field-view__status::after { + border-color: transparent transparent var(--ck-color-base-error) transparent; + border-width: 0 var(--ck-table-properties-error-arrow-size) var(--ck-table-properties-error-arrow-size) var(--ck-table-properties-error-arrow-size); + border-style: solid; + } +@media (prefers-reduced-motion: reduce) { +.ck.ck-table-form .ck.ck-labeled-field-view .ck.ck-labeled-field-view__status { + animation: none; + } + } +/* Hide the error balloon when the field is blurred. Makes the experience much more clear. */ +.ck.ck-table-form .ck.ck-labeled-field-view .ck-input.ck-error:not(:focus) + .ck.ck-labeled-field-view__status { + display: none; + } +@keyframes ck-table-form-labeled-view-status-appear { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +.ck.ck-table-properties-form { + width: 320px; +} +.ck.ck-table-properties-form .ck-form__row.ck-table-properties-form__alignment-row { + align-self: flex-end; + padding: 0; + } +.ck.ck-table-properties-form .ck-form__row.ck-table-properties-form__alignment-row .ck.ck-toolbar { + background: none; + + /* Compensate for missing input label that would push the margin (toolbar has no inputs). */ + margin-top: var(--ck-spacing-standard); + } +.ck.ck-table-properties-form .ck-form__row.ck-table-properties-form__alignment-row .ck.ck-toolbar .ck-toolbar__items > * { + width: 40px; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-table-selected-cell-background: hsla(208, 90%, 80%, .3); +} +.ck.ck-editor__editable .table table td.ck-editor__editable_selected, + .ck.ck-editor__editable .table table th.ck-editor__editable_selected { + position: relative; + caret-color: transparent; + outline: unset; + box-shadow: unset; + + /* https://github.com/ckeditor/ckeditor5/issues/6446 */ + } +.ck.ck-editor__editable .table table td.ck-editor__editable_selected:after, .ck.ck-editor__editable .table table th.ck-editor__editable_selected:after { + content: ''; + pointer-events: none; + background-color: var(--ck-table-selected-cell-background); + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + } +.ck.ck-editor__editable .table table td.ck-editor__editable_selected ::selection, + .ck.ck-editor__editable .table table th.ck-editor__editable_selected ::selection, + .ck.ck-editor__editable .table table td.ck-editor__editable_selected:focus, + .ck.ck-editor__editable .table table th.ck-editor__editable_selected:focus { + background-color: transparent; + } +/* + * To reduce the amount of noise, all widgets in the table selection have no outline and no selection handle. + * See https://github.com/ckeditor/ckeditor5/issues/9491. + */ +.ck.ck-editor__editable .table table td.ck-editor__editable_selected .ck-widget, .ck.ck-editor__editable .table table th.ck-editor__editable_selected .ck-widget { + outline: unset; + } +.ck.ck-editor__editable .table table td.ck-editor__editable_selected .ck-widget > .ck-widget__selection-handle, .ck.ck-editor__editable .table table th.ck-editor__editable_selected .ck-widget > .ck-widget__selection-handle { + display: none; + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A visual style of focused element's border. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-widget-outline-thickness: 3px; + --ck-widget-handler-icon-size: 16px; + --ck-widget-handler-animation-duration: 200ms; + --ck-widget-handler-animation-curve: ease; + + --ck-color-widget-blurred-border: hsl(0, 0%, 87%); + --ck-color-widget-hover-border: hsl(43, 100%, 62%); + --ck-color-widget-editable-focus-background: var(--ck-color-base-background); + --ck-color-widget-drag-handler-icon-color: var(--ck-color-base-background); +} +.ck .ck-widget { + outline-width: var(--ck-widget-outline-thickness); + outline-style: solid; + outline-color: transparent; + transition: outline-color var(--ck-widget-handler-animation-duration) var(--ck-widget-handler-animation-curve); +} +@media (prefers-reduced-motion: reduce) { +.ck .ck-widget { + transition: none; +} + } +.ck .ck-widget.ck-widget_selected, + .ck .ck-widget.ck-widget_selected:hover { + outline: var(--ck-widget-outline-thickness) solid var(--ck-color-focus-border); + } +.ck .ck-widget:hover { + outline-color: var(--ck-color-widget-hover-border); + } +.ck .ck-editor__nested-editable { + border: 1px solid transparent; + + /* The :focus style is applied before .ck-editor__nested-editable_focused class is rendered in the view. + These styles show a different border for a blink of an eye, so `:focus` need to have same styles applied. */ +} +.ck .ck-editor__nested-editable.ck-editor__nested-editable_focused, + .ck .ck-editor__nested-editable:focus { + box-shadow: var(--ck-inner-shadow), 0 0; + } +@media (forced-colors: none) { + .ck .ck-editor__nested-editable.ck-editor__nested-editable_focused, .ck .ck-editor__nested-editable:focus { + background-color: var(--ck-color-widget-editable-focus-background); + } + } +/** + * Focus border should not be applied to table cells because it overrides the default table cell border color. + * In other words - in some scenarios, the part of the table cell border has focus color style, which is not expected behavior + * because it should be the same as the table cell border color. + */ +.ck .ck-editor__nested-editable.ck-editor__nested-editable_focused:not(td, th), .ck .ck-editor__nested-editable:focus:not(td, th) { + /* Disable native outline. */ + outline: none; + border: var(--ck-focus-ring); + } +.ck .ck-widget.ck-widget_with-selection-handle .ck-widget__selection-handle { + padding: 4px; + box-sizing: border-box; + + /* Background and opacity will be animated as the handler shows up or the widget gets selected. */ + background-color: transparent; + opacity: 0; + + /* Transition: + * background-color for the .ck-widget_selected state change, + * visibility for hiding the handler, + * opacity for the proper look of the icon when the handler disappears. */ + transition: + background-color var(--ck-widget-handler-animation-duration) var(--ck-widget-handler-animation-curve), + visibility var(--ck-widget-handler-animation-duration) var(--ck-widget-handler-animation-curve), + opacity var(--ck-widget-handler-animation-duration) var(--ck-widget-handler-animation-curve); + + /* Make only top corners round. */ + border-radius: var(--ck-border-radius) var(--ck-border-radius) 0 0; + + /* Place the drag handler outside the widget wrapper. */ + transform: translateY(-100%); + left: calc(0px - var(--ck-widget-outline-thickness)); + top: 0; + } +@media (prefers-reduced-motion: reduce) { +.ck .ck-widget.ck-widget_with-selection-handle .ck-widget__selection-handle { + transition: none; + } + } +.ck .ck-widget.ck-widget_with-selection-handle .ck-widget__selection-handle .ck-icon { + /* Make sure the dimensions of the icon are independent of the fon-size of the content. */ + width: var(--ck-widget-handler-icon-size); + height: var(--ck-widget-handler-icon-size); + color: var(--ck-color-widget-drag-handler-icon-color); + + /* The "selected" part of the icon is invisible by default */ + } +.ck .ck-widget.ck-widget_with-selection-handle .ck-widget__selection-handle .ck-icon .ck-icon__selected-indicator { + opacity: 0; + + /* Note: The animation is longer on purpose. Simply feels better. */ + transition: opacity 300ms var(--ck-widget-handler-animation-curve); + } +@media (prefers-reduced-motion: reduce) { +.ck .ck-widget.ck-widget_with-selection-handle .ck-widget__selection-handle .ck-icon .ck-icon__selected-indicator { + transition: none; + } + } +/* Advertise using the look of the icon that once clicked the handler, the widget will be selected. */ +.ck .ck-widget.ck-widget_with-selection-handle .ck-widget__selection-handle:hover .ck-icon .ck-icon__selected-indicator { + opacity: 1; + } +/* Show the selection handler on mouse hover over the widget, but not for nested widgets. */ +.ck .ck-widget.ck-widget_with-selection-handle:hover > .ck-widget__selection-handle { + opacity: 1; + background-color: var(--ck-color-widget-hover-border); + } +/* Show the selection handler when the widget is selected, but not for nested widgets. */ +.ck .ck-widget.ck-widget_with-selection-handle.ck-widget_selected > .ck-widget__selection-handle, .ck .ck-widget.ck-widget_with-selection-handle.ck-widget_selected:hover > .ck-widget__selection-handle { + opacity: 1; + background-color: var(--ck-color-focus-border); + + /* When the widget is selected, notify the user using the proper look of the icon. */ + } +.ck .ck-widget.ck-widget_with-selection-handle.ck-widget_selected > .ck-widget__selection-handle .ck-icon .ck-icon__selected-indicator, .ck .ck-widget.ck-widget_with-selection-handle.ck-widget_selected:hover > .ck-widget__selection-handle .ck-icon .ck-icon__selected-indicator { + opacity: 1; + } +/* In a RTL environment, align the selection handler to the right side of the widget */ +/* stylelint-disable-next-line no-descending-specificity */ +.ck[dir="rtl"] .ck-widget.ck-widget_with-selection-handle .ck-widget__selection-handle { + left: auto; + right: calc(0px - var(--ck-widget-outline-thickness)); +} +/* https://github.com/ckeditor/ckeditor5/issues/6415 */ +.ck.ck-editor__editable.ck-read-only .ck-widget { + /* Prevent the :hover outline from showing up because of the used outline-color transition. */ + transition: none; +} +.ck.ck-editor__editable.ck-read-only .ck-widget:not(.ck-widget_selected) { + /* Disable visual effects of hover/active widget when CKEditor is in readOnly mode. + * See: https://github.com/ckeditor/ckeditor5/issues/1261 + * + * Leave the unit because this custom property is used in calc() by other features. + * See: https://github.com/ckeditor/ckeditor5/issues/6775 + */ + --ck-widget-outline-thickness: 0px; + } +.ck.ck-editor__editable.ck-read-only .ck-widget.ck-widget_with-selection-handle .ck-widget__selection-handle, + .ck.ck-editor__editable.ck-read-only .ck-widget.ck-widget_with-selection-handle .ck-widget__selection-handle:hover { + background: var(--ck-color-widget-blurred-border); + } +/* Style the widget when it's selected but the editable it belongs to lost focus. */ +/* stylelint-disable-next-line no-descending-specificity */ +.ck.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected, + .ck.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected:hover { + outline-color: var(--ck-color-widget-blurred-border); + } +.ck.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected.ck-widget_with-selection-handle > .ck-widget__selection-handle, + .ck.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected.ck-widget_with-selection-handle:hover > .ck-widget__selection-handle, + .ck.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected.ck-widget_with-selection-handle > .ck-widget__selection-handle:hover, + .ck.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected.ck-widget_with-selection-handle:hover > .ck-widget__selection-handle:hover { + background: var(--ck-color-widget-blurred-border); + } +.ck.ck-editor__editable > .ck-widget.ck-widget_with-selection-handle:first-child, +.ck.ck-editor__editable blockquote > .ck-widget.ck-widget_with-selection-handle:first-child { + /* Do not crop selection handler if a widget is a first-child in the blockquote or in the root editable. + In fact, anything with overflow: hidden. + https://github.com/ckeditor/ckeditor5-block-quote/issues/28 + https://github.com/ckeditor/ckeditor5-widget/issues/44 + https://github.com/ckeditor/ckeditor5-widget/issues/66 */ + margin-top: calc(1em + var(--ck-widget-handler-icon-size)); +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-resizer-size: 10px; + + /* Set the resizer with a 50% offset. */ + --ck-resizer-offset: calc( ( var(--ck-resizer-size) / -2 ) - 2px); + --ck-resizer-border-width: 1px; +} +.ck .ck-widget__resizer { + outline: 1px solid var(--ck-color-resizer); +} +.ck .ck-widget__resizer__handle { + width: var(--ck-resizer-size); + height: var(--ck-resizer-size); + background: var(--ck-color-focus-border); + border: var(--ck-resizer-border-width) solid hsl(0, 0%, 100%); + border-radius: var(--ck-resizer-border-radius); +} +.ck .ck-widget__resizer__handle.ck-widget__resizer__handle-top-left { + top: var(--ck-resizer-offset); + left: var(--ck-resizer-offset); + } +.ck .ck-widget__resizer__handle.ck-widget__resizer__handle-top-right { + top: var(--ck-resizer-offset); + right: var(--ck-resizer-offset); + } +.ck .ck-widget__resizer__handle.ck-widget__resizer__handle-bottom-right { + bottom: var(--ck-resizer-offset); + right: var(--ck-resizer-offset); + } +.ck .ck-widget__resizer__handle.ck-widget__resizer__handle-bottom-left { + bottom: var(--ck-resizer-offset); + left: var(--ck-resizer-offset); + } +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-widget-type-around-button-size: 20px; + --ck-color-widget-type-around-button-active: var(--ck-color-focus-border); + --ck-color-widget-type-around-button-hover: var(--ck-color-widget-hover-border); + --ck-color-widget-type-around-button-blurred-editable: var(--ck-color-widget-blurred-border); + --ck-color-widget-type-around-button-radar-start-alpha: 0; + --ck-color-widget-type-around-button-radar-end-alpha: .3; + --ck-color-widget-type-around-button-icon: var(--ck-color-base-background); +} +/* + * Styles of the type around buttons + */ +.ck .ck-widget .ck-widget__type-around__button { + width: var(--ck-widget-type-around-button-size); + height: var(--ck-widget-type-around-button-size); + background: var(--ck-color-widget-type-around-button); + border-radius: 100px; + transition: opacity var(--ck-widget-handler-animation-duration) var(--ck-widget-handler-animation-curve), background var(--ck-widget-handler-animation-duration) var(--ck-widget-handler-animation-curve); + + opacity: 0; + + pointer-events: none; + } +@media (prefers-reduced-motion: reduce) { +.ck .ck-widget .ck-widget__type-around__button { + transition: none; + } + } +.ck .ck-widget .ck-widget__type-around__button svg { + width: 10px; + height: 8px; + transform: translate(-50%,-50%); + transition: transform .5s ease; + margin-top: 1px; + } +@media (prefers-reduced-motion: reduce) { +.ck .ck-widget .ck-widget__type-around__button svg { + transition: none; + } + } +.ck .ck-widget .ck-widget__type-around__button svg * { + stroke-dasharray: 10; + stroke-dashoffset: 0; + + fill: none; + stroke: var(--ck-color-widget-type-around-button-icon); + stroke-width: 1.5px; + stroke-linecap: round; + stroke-linejoin: round; + } +.ck .ck-widget .ck-widget__type-around__button svg line { + stroke-dasharray: 7; + } +.ck .ck-widget .ck-widget__type-around__button:hover { + /* + * Display the "sonar" around the button when hovered. + */ + animation: ck-widget-type-around-button-sonar 1s ease infinite; + + /* + * Animate active button's icon. + */ + } +.ck .ck-widget .ck-widget__type-around__button:hover svg polyline { + animation: ck-widget-type-around-arrow-dash 2s linear; + } +.ck .ck-widget .ck-widget__type-around__button:hover svg line { + animation: ck-widget-type-around-arrow-tip-dash 2s linear; + } +@media (prefers-reduced-motion: reduce) { +.ck .ck-widget .ck-widget__type-around__button:hover { + animation: none; + } + .ck .ck-widget .ck-widget__type-around__button:hover svg polyline { + animation: none; + } + + .ck .ck-widget .ck-widget__type-around__button:hover svg line { + animation: none; + } + } +/* + * Show type around buttons when the widget gets selected or being hovered. + */ +.ck .ck-widget.ck-widget_selected > .ck-widget__type-around > .ck-widget__type-around__button, .ck .ck-widget:hover > .ck-widget__type-around > .ck-widget__type-around__button { + opacity: 1; + pointer-events: auto; + } +/* + * Styles for the buttons when the widget is NOT selected (but the buttons are visible + * and still can be hovered). + */ +.ck .ck-widget:not(.ck-widget_selected) > .ck-widget__type-around > .ck-widget__type-around__button { + background: var(--ck-color-widget-type-around-button-hover); + } +/* + * Styles for the buttons when: + * - the widget is selected, + * - or the button is being hovered (regardless of the widget state). + */ +.ck .ck-widget.ck-widget_selected > .ck-widget__type-around > .ck-widget__type-around__button, + .ck .ck-widget > .ck-widget__type-around > .ck-widget__type-around__button:hover { + background: var(--ck-color-widget-type-around-button-active); + } +.ck .ck-widget.ck-widget_selected > .ck-widget__type-around > .ck-widget__type-around__button::after, .ck .ck-widget > .ck-widget__type-around > .ck-widget__type-around__button:hover::after { + width: calc(var(--ck-widget-type-around-button-size) - 2px); + height: calc(var(--ck-widget-type-around-button-size) - 2px); + border-radius: 100px; + background: linear-gradient(135deg, hsla(0,0%,100%,0) 0%, hsla(0,0%,100%,.3) 100%); + } +/* + * Styles for the "before" button when the widget has a selection handle. Because some space + * is consumed by the handle, the button must be moved slightly to the right to let it breathe. + */ +.ck .ck-widget.ck-widget_with-selection-handle > .ck-widget__type-around > .ck-widget__type-around__button_before { + margin-left: 20px; + } +/* + * Styles for the horizontal "fake caret" which is displayed when the user navigates using the keyboard. + */ +.ck .ck-widget .ck-widget__type-around__fake-caret { + pointer-events: none; + height: 1px; + animation: ck-widget-type-around-fake-caret-pulse linear 1s infinite normal forwards; + + /* + * The semi-transparent-outline+background combo improves the contrast + * when the background underneath the fake caret is dark. + */ + outline: solid 1px hsla(0, 0%, 100%, .5); + background: var(--ck-color-base-text); + } +/* + * Styles of the widget when the "fake caret" is blinking (e.g. upon keyboard navigation). + * Despite the widget being physically selected in the model, its outline should disappear. + */ +.ck .ck-widget.ck-widget_selected.ck-widget_type-around_show-fake-caret_before, + .ck .ck-widget.ck-widget_selected.ck-widget_type-around_show-fake-caret_after { + outline-color: transparent; + } +/* + * When the "fake caret" is visible we simulate that the widget is not selected + * (despite being physically selected), so the outline color should be for the + * unselected widget. + */ +.ck .ck-widget.ck-widget_type-around_show-fake-caret_before.ck-widget_selected:hover, .ck .ck-widget.ck-widget_type-around_show-fake-caret_after.ck-widget_selected:hover { + outline-color: var(--ck-color-widget-hover-border); + } +/* + * Styles of the type around buttons when the "fake caret" is blinking (e.g. upon keyboard navigation). + * In this state, the type around buttons would collide with the fake carets so they should disappear. + */ +.ck .ck-widget.ck-widget_type-around_show-fake-caret_before > .ck-widget__type-around > .ck-widget__type-around__button, .ck .ck-widget.ck-widget_type-around_show-fake-caret_after > .ck-widget__type-around > .ck-widget__type-around__button { + opacity: 0; + pointer-events: none; + } +/* + * Fake horizontal caret integration with the selection handle. When the caret is visible, simply + * hide the handle because it intersects with the caret (and does not make much sense anyway). + */ +.ck .ck-widget.ck-widget_type-around_show-fake-caret_before.ck-widget_with-selection-handle.ck-widget_selected > .ck-widget__selection-handle, .ck .ck-widget.ck-widget_type-around_show-fake-caret_after.ck-widget_with-selection-handle.ck-widget_selected > .ck-widget__selection-handle, .ck .ck-widget.ck-widget_type-around_show-fake-caret_before.ck-widget_with-selection-handle.ck-widget_selected:hover > .ck-widget__selection-handle, .ck .ck-widget.ck-widget_type-around_show-fake-caret_after.ck-widget_with-selection-handle.ck-widget_selected:hover > .ck-widget__selection-handle { + opacity: 0 + } +/* + * Fake horizontal caret integration with the resize UI. When the caret is visible, simply + * hide the resize UI because it creates too much noise. It can be visible when the user + * hovers the widget, though. + */ +.ck .ck-widget.ck-widget_type-around_show-fake-caret_before.ck-widget_selected.ck-widget_with-resizer > .ck-widget__resizer, .ck .ck-widget.ck-widget_type-around_show-fake-caret_after.ck-widget_selected.ck-widget_with-resizer > .ck-widget__resizer { + opacity: 0 + } +/* + * Styles for the "before" button when the widget has a selection handle in an RTL environment. + * The selection handler is aligned to the right side of the widget so there is no need to create + * additional space for it next to the "before" button. + */ +.ck[dir="rtl"] .ck-widget.ck-widget_with-selection-handle .ck-widget__type-around > .ck-widget__type-around__button_before { + margin-left: 0; + margin-right: 20px; +} +/* + * Hide type around buttons when the widget is selected as a child of a selected + * nested editable (e.g. mulit-cell table selection). + * + * See https://github.com/ckeditor/ckeditor5/issues/7263. + */ +.ck-editor__nested-editable.ck-editor__editable_selected .ck-widget.ck-widget_selected > .ck-widget__type-around > .ck-widget__type-around__button, .ck-editor__nested-editable.ck-editor__editable_selected .ck-widget:hover > .ck-widget__type-around > .ck-widget__type-around__button { + opacity: 0; + pointer-events: none; + } +/* + * Styles for the buttons when the widget is selected but the user clicked outside of the editor (blurred the editor). + */ +.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected > .ck-widget__type-around > .ck-widget__type-around__button:not(:hover) { + background: var(--ck-color-widget-type-around-button-blurred-editable); +} +.ck-editor__editable.ck-blurred .ck-widget.ck-widget_selected > .ck-widget__type-around > .ck-widget__type-around__button:not(:hover) svg * { + stroke: hsl(0,0%,60%); + } +@keyframes ck-widget-type-around-arrow-dash { + 0% { + stroke-dashoffset: 10; + } + 20%, 100% { + stroke-dashoffset: 0; + } +} +@keyframes ck-widget-type-around-arrow-tip-dash { + 0%, 20% { + stroke-dashoffset: 7; + } + 40%, 100% { + stroke-dashoffset: 0; + } +} +@keyframes ck-widget-type-around-button-sonar { + 0% { + box-shadow: 0 0 0 0 hsla(var(--ck-color-focus-border-coordinates), var(--ck-color-widget-type-around-button-radar-start-alpha)); + } + 50% { + box-shadow: 0 0 0 5px hsla(var(--ck-color-focus-border-coordinates), var(--ck-color-widget-type-around-button-radar-end-alpha)); + } + 100% { + box-shadow: 0 0 0 5px hsla(var(--ck-color-focus-border-coordinates), var(--ck-color-widget-type-around-button-radar-start-alpha)); + } +} +@keyframes ck-widget-type-around-fake-caret-pulse { + 0% { + opacity: 1; + } + 49% { + opacity: 1; + } + 50% { + opacity: 0; + } + 99% { + opacity: 0; + } + 100% { + opacity: 1; + } +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck-content code { + background-color: hsla(0, 0%, 78%, 0.3); + padding: .15em; + border-radius: 2px; +} + +.ck.ck-editor__editable .ck-code_selected { + background-color: hsla(0, 0%, 78%, 0.5); +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck-content blockquote { + /* See #12 */ + overflow: hidden; + + /* https://github.com/ckeditor/ckeditor5-block-quote/issues/15 */ + padding-right: 1.5em; + padding-left: 1.5em; + + margin-left: 0; + margin-right: 0; + font-style: italic; + border-left: solid 5px hsl(0, 0%, 80%); +} + +.ck-content[dir="rtl"] blockquote { + border-left: 0; + border-right: solid 5px hsl(0, 0%, 80%); +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + /* Based on default CKBox theme colors */ + --ck-image-processing-highlight-color: hsl(220, 10%, 98%); + --ck-image-processing-background-color: hsl(220, 10%, 90%); +} + +.ck.ck-editor__editable .image.image-processing { + position: relative; + } + +.ck.ck-editor__editable .image.image-processing:before { + content: ''; + + position: absolute; + top: 0; + left: 0; + z-index: 1; + + height: 100%; + width: 100%; + + background: linear-gradient( + 90deg, + var(--ck-image-processing-background-color), + var(--ck-image-processing-highlight-color), + var(--ck-image-processing-background-color) + ); + background-size: 200% 100%; + + animation: ck-image-processing-animation 2s linear infinite; + } + +.ck.ck-editor__editable .image.image-processing img { + height: 100%; + } + +@keyframes ck-image-processing-animation { + 0% { + background-position: 200% 0; + } + 100% { + background-position: -200% 0; + } +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Vertical drop target (in text). + */ + +.ck.ck-editor__editable .ck.ck-clipboard-drop-target-position { + display: inline; + position: relative; + pointer-events: none; + } + +.ck.ck-editor__editable .ck.ck-clipboard-drop-target-position span { + position: absolute; + width: 0; + } + +/* + * Styles of the widget being dragged (its preview). + */ + +.ck.ck-editor__editable .ck-widget:-webkit-drag > .ck-widget__selection-handle { + display: none; + } + +.ck.ck-editor__editable .ck-widget:-webkit-drag > .ck-widget__type-around { + display: none; + } + +.ck.ck-clipboard-drop-target-line { + position: absolute; + pointer-events: none; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck-content pre { + padding: 1em; + color: hsl(0, 0%, 20.8%); + background: hsla(0, 0%, 78%, 0.3); + border: 1px solid hsl(0, 0%, 77%); + border-radius: 2px; + + /* Code block are language direction–agnostic. */ + text-align: left; + direction: ltr; + + tab-size: 4; + white-space: pre-wrap; + + /* Don't inherit the style, e.g. when in a block quote. */ + font-style: normal; + + /* Don't let the code be squashed e.g. when in a table cell. */ + min-width: 200px; +} + +.ck-content pre code { + background: unset; + padding: 0; + border-radius: 0; + } + +.ck.ck-editor__editable pre { + position: relative; +} + +.ck.ck-editor__editable pre[data-language]::after { + content: attr(data-language); + position: absolute; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-editor { + /* All the elements within `.ck-editor` are positioned relatively to it. + If any element needs to be positioned with respect to the , etc., + it must land outside of the `.ck-editor` in DOM. */ + position: relative; +} + +.ck.ck-editor .ck-editor__top .ck-sticky-panel .ck-toolbar { + /* https://github.com/ckeditor/ckeditor5-editor-classic/issues/62 */ + z-index: var(--ck-z-panel); + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-menu-bar { + border: none; + border-bottom: 1px solid var(--ck-color-toolbar-border); +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* See ckeditor/ckeditor5#936. */ +.ck.ck-placeholder, +.ck .ck-placeholder { + position: relative; +} +.ck.ck-placeholder::before, .ck .ck-placeholder::before { + position: absolute; + left: 0; + right: 0; + content: attr(data-placeholder); + + /* See ckeditor/ckeditor5#469. */ + pointer-events: none; + } + +/* See ckeditor/ckeditor5#1987. */ +.ck.ck-read-only .ck-placeholder::before { + display: none; + } + +/* + * Rules for the `ck-placeholder` are loaded before the rules for `ck-reset_all` in the base CKEditor 5 DLL build. + * This fix overwrites the incorrectly set `position: static` from `ck-reset_all`. + * See https://github.com/ckeditor/ckeditor5/issues/11418. + */ +.ck.ck-reset_all .ck-placeholder { + position: relative; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* Elements marked by the Renderer as hidden should be invisible in the editor. */ +.ck.ck-editor__editable span[data-ck-unsafe-element] { + display: none; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck-find-result { + background: var(--ck-color-highlight-background); + color: var(--ck-color-text); +} + +.ck-find-result_selected { + background: hsl(29, 100%, 60%); +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-find-and-replace-form { + max-width: 100%; +} + +.ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs, .ck.ck-find-and-replace-form .ck-find-and-replace-form__actions { + display: flex; + + /* The inputs area styles */ + } + +.ck.ck-find-and-replace-form .ck-find-and-replace-form__inputs.ck-find-and-replace-form__inputs .ck-results-counter, .ck.ck-find-and-replace-form .ck-find-and-replace-form__actions.ck-find-and-replace-form__inputs .ck-results-counter { + position: absolute; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* The values should be synchronized with the "FONT_SIZE_PRESET_UNITS" object in the "/src/fontsize/utils.js" file. */ + +/* Styles should be prefixed with the `.ck-content` class. +See https://github.com/ckeditor/ckeditor5/issues/6636 */ +.ck-content .text-tiny { + font-size: .7em; + } +.ck-content .text-small { + font-size: .85em; + } +.ck-content .text-big { + font-size: 1.4em; + } +.ck-content .text-huge { + font-size: 1.8em; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-heading_heading1 .ck-button__label { + font-size: 20px; +} + +.ck.ck-heading_heading2 .ck-button__label { + font-size: 17px; +} + +.ck.ck-heading_heading3 .ck-button__label { + font-size: 14px; +} + +.ck[class*="ck-heading_heading"] { + font-weight: bold; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-highlight-marker-yellow: hsl(60, 97%, 73%); + --ck-highlight-marker-green: hsl(120, 93%, 68%); + --ck-highlight-marker-pink: hsl(345, 96%, 73%); + --ck-highlight-marker-blue: hsl(201, 97%, 72%); + --ck-highlight-pen-red: hsl(0, 85%, 49%); + --ck-highlight-pen-green: hsl(112, 100%, 27%); +} + +.ck-content .marker-yellow { + background-color: var(--ck-highlight-marker-yellow); + } +.ck-content .marker-green { + background-color: var(--ck-highlight-marker-green); + } +.ck-content .marker-pink { + background-color: var(--ck-highlight-marker-pink); + } +.ck-content .marker-blue { + background-color: var(--ck-highlight-marker-blue); + } + +.ck-content .pen-red { + color: var(--ck-highlight-pen-red); + + /* Override default yellow background of `` from user agent stylesheet */ + background-color: transparent; + } +.ck-content .pen-green { + color: var(--ck-highlight-pen-green); + + /* Override default yellow background of `` from user agent stylesheet */ + background-color: transparent; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + + +.ck-editor__editable .ck-horizontal-line { + /* Necessary to render properly next to floated objects, e.g. side image case. */ + display: flow-root; +} + +.ck-content hr { + margin: 15px 0; + height: 4px; + background: hsl(0, 0%, 87%); + border: 0; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* The feature container. */ +.ck-widget.raw-html-embed { + /* Give the embed some air. */ + /* The first value should be equal to --ck-spacing-large variable if used in the editor context + to avoid the content jumping (See https://github.com/ckeditor/ckeditor5/issues/9825). */ + margin: 0.9em auto; + position: relative; + display: flow-root; + + /* Give the html embed some minimal width in the content to prevent them + from being "squashed" in tight spaces, e.g. in table cells (https://github.com/ckeditor/ckeditor5/issues/8331) */ + min-width: 15em; + + /* Don't inherit the style, e.g. when in a block quote. */ + font-style: normal; + + /* ----- Emebed label in the upper left corner ----------------------------------------------- */ +} +.ck-widget.raw-html-embed::before { + position: absolute; + + /* Make sure the content does not cover the label. */ + z-index: 1; + } +/* ----- Emebed internals --------------------------------------------------------------------- */ +/* The switch mode button wrapper. */ +.ck-widget.raw-html-embed .raw-html-embed__buttons-wrapper { + position: absolute; + display: flex; + flex-direction: column; + } +.ck-widget.raw-html-embed .raw-html-embed__preview { + position: relative; + overflow: hidden; + display: flex; + } +.ck-widget.raw-html-embed .raw-html-embed__preview-content { + width: 100%; + position: relative; + margin: auto; + + /* Gives spacing to the small renderable elements, so they always cover the placeholder. */ + display: table; + border-collapse: separate; + border-spacing: 7px; + } +.ck-widget.raw-html-embed .raw-html-embed__preview-placeholder { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + + display: flex; + align-items: center; + justify-content: center; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-html-object-embed-unfocused-outline-width: 1px; +} + +.ck-widget.html-object-embed { + font-size: var(--ck-font-size-base); + background-color: var(--ck-color-base-foreground); + padding: var(--ck-spacing-small); + /* Leave space for label */ + padding-top: calc(var(--ck-font-size-tiny) + var(--ck-spacing-large)); + min-width: calc(76px + var(--ck-spacing-standard)); +} + +.ck-widget.html-object-embed:not(.ck-widget_selected):not(:hover) { + outline: var(--ck-html-object-embed-unfocused-outline-width) dashed var(--ck-color-widget-blurred-border); + } + +.ck-widget.html-object-embed::before { + font-weight: normal; + font-style: normal; + position: absolute; + content: attr(data-html-object-embed-label); + top: 0; + left: var(--ck-spacing-standard); + background: hsl(0deg 0% 60%); + transition: background var(--ck-widget-handler-animation-duration) var(--ck-widget-handler-animation-curve); + padding: calc(var(--ck-spacing-tiny) + var(--ck-html-object-embed-unfocused-outline-width)) var(--ck-spacing-small) var(--ck-spacing-tiny); + border-radius: 0 0 var(--ck-border-radius) var(--ck-border-radius); + color: var(--ck-color-base-background); + font-size: var(--ck-font-size-tiny); + font-family: var(--ck-font-face); + } + +/* Make space for label. */ + +.ck-widget.html-object-embed .ck-widget__type-around .ck-widget__type-around__button.ck-widget__type-around__button_before { + margin-left: 50px; + } + +.ck-widget.html-object-embed .html-object-embed__content { + /* Disable user interaction with embed content */ + pointer-events: none; + } + +div.ck-widget.html-object-embed { + margin: 1em auto; +} + +span.ck-widget.html-object-embed { + display: inline-block; +} + + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-color-image-caption-background: hsl(0, 0%, 97%); + --ck-color-image-caption-text: hsl(0, 0%, 20%); + --ck-color-image-caption-highlighted-background: hsl(52deg 100% 50%); +} + +/* Content styles */ +.ck-content .image > figcaption { + display: table-caption; + caption-side: bottom; + word-break: break-word; + color: var(--ck-color-image-caption-text); + background-color: var(--ck-color-image-caption-background); + padding: .6em; + font-size: .75em; + outline-offset: -1px; + + /* Improve placeholder rendering in high-constrast mode (https://github.com/ckeditor/ckeditor5/issues/14907). */ +} +@media (forced-colors: active) { +.ck-content .image > figcaption { + background-color: unset; + color: unset; +} + } + +/* Editing styles */ +@media (forced-colors: none) { + .ck.ck-editor__editable .image > figcaption.image__caption_highlighted { + animation: ck-image-caption-highlight .6s ease-out; + } + } +@media (prefers-reduced-motion: reduce) { +.ck.ck-editor__editable .image > figcaption.image__caption_highlighted { + animation: none; +} + } + +@keyframes ck-image-caption-highlight { + 0% { + background-color: var(--ck-color-image-caption-highlighted-background); + } + + 100% { + background-color: var(--ck-color-image-caption-background); + } +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-image-insert-url { + width: 400px; + padding: var(--ck-spacing-large) var(--ck-spacing-large) 0; +} + +.ck.ck-image-insert-url .ck-image-insert-url__action-row { + display: grid; + grid-template-columns: repeat(2, 1fr); + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* Preserve aspect ratio of the resized image after introducing image height attribute. */ +.ck-content img.image_resized { + height: auto; +} + +.ck-content .image.image_resized { + max-width: 100%; + /* + The `
` element for resized images must not use `display:table` as browsers do not support `max-width` for it well. + See https://stackoverflow.com/questions/4019604/chrome-safari-ignoring-max-width-in-table/14420691#14420691 for more. + Fortunately, since we control the width, there is no risk that the image will look bad. + */ + display: block; + box-sizing: border-box; +} + +.ck-content .image.image_resized img { + /* For resized images it is the `
` element that determines the image width. */ + width: 100%; + } + +.ck-content .image.image_resized > figcaption { + /* The `
` element uses `display:block`, so `
` also has to. */ + display: block; + } + +/* The resized inline image nested in the table should respect its parent size. + See https://github.com/ckeditor/ckeditor5/issues/9117. */ + +.ck.ck-editor__editable td .image-inline.image_resized img, .ck.ck-editor__editable th .image-inline.image_resized img { + max-width: 100%; + } + +[dir="ltr"] .ck.ck-button.ck-button_with-text.ck-resize-image-button .ck-button__icon { + margin-right: var(--ck-spacing-standard); +} + +[dir="rtl"] .ck.ck-button.ck-button_with-text.ck-resize-image-button .ck-button__icon { + margin-left: var(--ck-spacing-standard); +} + +.ck.ck-dropdown .ck-button.ck-resize-image-button .ck-button__label { + width: 4em; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-image-custom-resize-form { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + align-items: flex-start; +} + +.ck.ck-image-custom-resize-form .ck-labeled-field-view { + display: inline-block; + } + +.ck.ck-image-custom-resize-form .ck-label { + display: none; + } + +@media screen and (max-width: 600px) { + +.ck.ck-image-custom-resize-form { + flex-wrap: wrap; +} + + .ck.ck-image-custom-resize-form .ck-labeled-field-view { + flex-basis: 100%; + } + + .ck.ck-image-custom-resize-form .ck-button { + flex-basis: 50%; + } + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-image-style-spacing: 1.5em; + --ck-inline-image-style-spacing: calc(var(--ck-image-style-spacing) / 2); +} + +/* See: https://github.com/ckeditor/ckeditor5/issues/16317 */ + +/* Provides a minimal side margin for the left and right aligned images, so that the user has a visual feedback + confirming successful application of the style if image width exceeds the editor's size. + See https://github.com/ckeditor/ckeditor5/issues/9342 */ + +.ck-content .image.image-style-block-align-left, + .ck-content .image.image-style-block-align-right { + max-width: calc(100% - var(--ck-image-style-spacing)); + } + +/* Allows displaying multiple floating images in the same line. + See https://github.com/ckeditor/ckeditor5/issues/9183#issuecomment-804988132 */ + +.ck-content .image.image-style-align-left, + .ck-content .image.image-style-align-right { + clear: none; + } + +.ck-content .image.image-style-side { + float: right; + margin-left: var(--ck-image-style-spacing); + max-width: 50%; + } + +.ck-content .image.image-style-align-left { + float: left; + margin-right: var(--ck-image-style-spacing); + } + +.ck-content .image.image-style-align-right { + float: right; + margin-left: var(--ck-image-style-spacing); + } + +.ck-content .image.image-style-block-align-right { + margin-right: 0; + margin-left: auto; + } + +.ck-content .image.image-style-block-align-left { + margin-left: 0; + margin-right: auto; + } + +.ck-content .image-style-align-center { + margin-left: auto; + margin-right: auto; + } + +.ck-content .image-style-align-left { + float: left; + margin-right: var(--ck-image-style-spacing); + } + +.ck-content .image-style-align-right { + float: right; + margin-left: var(--ck-image-style-spacing); + } + +/* Simulates margin collapsing with the preceding paragraph, which does not work for the floating elements. */ + +.ck-content p + .image.image-style-align-left, + .ck-content p + .image.image-style-align-right, + .ck-content p + .image.image-style-side { + margin-top: 0; + } + +.ck-content .image-inline.image-style-align-left, + .ck-content .image-inline.image-style-align-right { + margin-top: var(--ck-inline-image-style-spacing); + margin-bottom: var(--ck-inline-image-style-spacing); + } + +.ck-content .image-inline.image-style-align-left { + margin-right: var(--ck-inline-image-style-spacing); + } + +.ck-content .image-inline.image-style-align-right { + margin-left: var(--ck-inline-image-style-spacing); + } + +/* The button should display as a regular drop-down if the action button + is forced to fire the same action as the arrow button. */ + +.ck.ck-splitbutton.ck-splitbutton_flatten:hover > .ck-splitbutton__action:not(.ck-disabled), + .ck.ck-splitbutton.ck-splitbutton_flatten.ck-splitbutton_open > .ck-splitbutton__action:not(.ck-disabled), + .ck.ck-splitbutton.ck-splitbutton_flatten:hover > .ck-splitbutton__arrow:not(.ck-disabled), + .ck.ck-splitbutton.ck-splitbutton_flatten.ck-splitbutton_open > .ck-splitbutton__arrow:not(.ck-disabled), + .ck.ck-splitbutton.ck-splitbutton_flatten:hover > .ck-splitbutton__arrow:not(.ck-disabled):not(:hover), + .ck.ck-splitbutton.ck-splitbutton_flatten.ck-splitbutton_open > .ck-splitbutton__arrow:not(.ck-disabled):not(:hover) { + background-color: var(--ck-color-button-on-background); + } + +.ck.ck-splitbutton.ck-splitbutton_flatten:hover > .ck-splitbutton__action:not(.ck-disabled)::after, .ck.ck-splitbutton.ck-splitbutton_flatten.ck-splitbutton_open > .ck-splitbutton__action:not(.ck-disabled)::after, .ck.ck-splitbutton.ck-splitbutton_flatten:hover > .ck-splitbutton__arrow:not(.ck-disabled)::after, .ck.ck-splitbutton.ck-splitbutton_flatten.ck-splitbutton_open > .ck-splitbutton__arrow:not(.ck-disabled)::after, .ck.ck-splitbutton.ck-splitbutton_flatten:hover > .ck-splitbutton__arrow:not(.ck-disabled):not(:hover)::after, .ck.ck-splitbutton.ck-splitbutton_flatten.ck-splitbutton_open > .ck-splitbutton__arrow:not(.ck-disabled):not(:hover)::after { + display: none; + } + +.ck.ck-splitbutton.ck-splitbutton_flatten.ck-splitbutton_open:hover > .ck-splitbutton__action:not(.ck-disabled), + .ck.ck-splitbutton.ck-splitbutton_flatten.ck-splitbutton_open:hover > .ck-splitbutton__arrow:not(.ck-disabled), + .ck.ck-splitbutton.ck-splitbutton_flatten.ck-splitbutton_open:hover > .ck-splitbutton__arrow:not(.ck-disabled):not(:hover) { + background-color: var(--ck-color-button-on-hover-background); + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-text-alternative-form { + display: flex; + flex-direction: row; + flex-wrap: nowrap; +} + +.ck.ck-text-alternative-form .ck-labeled-field-view { + display: inline-block; + } + +.ck.ck-text-alternative-form .ck-label { + display: none; + } + +@media screen and (max-width: 600px) { + +.ck.ck-text-alternative-form { + flex-wrap: wrap; +} + + .ck.ck-text-alternative-form .ck-labeled-field-view { + flex-basis: 100%; + } + + .ck.ck-text-alternative-form .ck-button { + flex-basis: 50%; + } + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-editor__editable .image, + .ck.ck-editor__editable .image-inline { + position: relative; + } + +/* Upload progress bar. */ + +.ck.ck-editor__editable .image .ck-progress-bar, + .ck.ck-editor__editable .image-inline .ck-progress-bar { + position: absolute; + top: 0; + left: 0; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck-image-upload-complete-icon { + display: block; + position: absolute; + + /* + * Smaller images should have the icon closer to the border. + * Match the icon position with the linked image indicator brought by the link image feature. + */ + top: min(var(--ck-spacing-medium), 6%); + right: min(var(--ck-spacing-medium), 6%); + border-radius: 50%; + z-index: 1; +} + +.ck-image-upload-complete-icon::after { + content: ""; + position: absolute; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck .ck-upload-placeholder-loader { + position: absolute; + display: flex; + align-items: center; + justify-content: center; + top: 0; + left: 0; +} + +.ck .ck-upload-placeholder-loader::before { + content: ''; + position: relative; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck-content .image { + display: table; + clear: both; + text-align: center; + + /* Make sure there is some space between the content and the image. Center image by default. */ + /* The first value should be equal to --ck-spacing-large variable if used in the editor context + to avoid the content jumping (See https://github.com/ckeditor/ckeditor5/issues/9825). */ + margin: 0.9em auto; + + /* Make sure the caption will be displayed properly (See: https://github.com/ckeditor/ckeditor5/issues/1870). */ + min-width: 50px; + } + +.ck-content .image img { + /* Prevent unnecessary margins caused by line-height (see #44). */ + display: block; + + /* Center the image if its width is smaller than the content's width. */ + margin: 0 auto; + + /* Make sure the image never exceeds the size of the parent container (ckeditor/ckeditor5-ui#67). */ + max-width: 100%; + + /* Make sure the image is never smaller than the parent container (See: https://github.com/ckeditor/ckeditor5/issues/9300). */ + min-width: 100%; + + /* Keep proportions of the block image if the height is set and the image is wider than the editor width. + See https://github.com/ckeditor/ckeditor5/issues/14542. */ + height: auto; + } + +.ck-content .image-inline { + /* + * Normally, the .image-inline would have "display: inline-block" and "img { width: 100% }" (to follow the wrapper while resizing). + * Unfortunately, together with "srcset", it gets automatically stretched up to the width of the editing root. + * This strange behavior does not happen with inline-flex. + */ + display: inline-flex; + + /* While being resized, don't allow the image to exceed the width of the editing root. */ + max-width: 100%; + + /* This is required by Safari to resize images in a sensible way. Without this, the browser breaks the ratio. */ + align-items: flex-start; + + /* When the picture is present it must act as a flex container to let the img resize properly */ + } + +.ck-content .image-inline picture { + display: flex; + } + +/* When the picture is present, it must act like a resizable img. */ + +.ck-content .image-inline picture, + .ck-content .image-inline img { + /* This is necessary for the img to span the entire .image-inline wrapper and to resize properly. */ + flex-grow: 1; + flex-shrink: 1; + + /* Prevents overflowing the editing root boundaries when an inline image is very wide. */ + max-width: 100%; + } + +/* + * Inhertit the content styles padding of the
in case the integration overrides `text-align: center` + * of `.image` (e.g. to the left/right). This ensures the placeholder stays at the padding just like the native + * caret does, and not at the edge of
. + */ + +.ck.ck-editor__editable .image > figcaption.ck-placeholder::before { + padding-left: inherit; + padding-right: inherit; + + /* + * Make sure the image caption placeholder doesn't overflow the placeholder area. + * See https://github.com/ckeditor/ckeditor5/issues/9162. + */ + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + +/* + * See https://github.com/ckeditor/ckeditor5/issues/15115. + */ + +.ck.ck-editor__editable .image { + z-index: 1; + + /* + * Make sure the selected image always stays on top of its siblings. + * See https://github.com/ckeditor/ckeditor5/issues/9108. + */ + } + +.ck.ck-editor__editable .image.ck-widget_selected { + z-index: 2; + } + +/* + * See https://github.com/ckeditor/ckeditor5/issues/15115. + */ + +.ck.ck-editor__editable .image-inline { + z-index: 1; + + /* + * Make sure the selected inline image always stays on top of its siblings. + * See https://github.com/ckeditor/ckeditor5/issues/9108. + */ + } + +.ck.ck-editor__editable .image-inline.ck-widget_selected { + z-index: 2; + + /* + * Make sure the native browser selection style is not displayed. + * Inline image widgets have their own styles for the selected state and + * leaving this up to the browser is asking for a visual collision. + */ + } + +.ck.ck-editor__editable .image-inline.ck-widget_selected ::selection { + display: none; + } + +/* Keep proportions of the inline image if the height is set and the image is wider than the editor width. + See https://github.com/ckeditor/ckeditor5/issues/14542. */ + +.ck.ck-editor__editable .image-inline img { + height: auto; + } + +/* The inline image nested in the table should have its original size if not resized. + See https://github.com/ckeditor/ckeditor5/issues/9117. */ + +.ck.ck-editor__editable td .image-inline img, .ck.ck-editor__editable th .image-inline img { + max-width: none; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-editor__editable img.image_placeholder { + background-size: 100% 100%; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* Linked image indicator */ + +.ck.ck-editor__editable figure.image > a::after, .ck.ck-editor__editable a span.image-inline::after { + display: block; + position: absolute; + } + + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-link-actions { + display: flex; + flex-direction: row; + flex-wrap: nowrap; +} + +.ck.ck-link-actions .ck-link-actions__preview { + display: inline-block; + } + +.ck.ck-link-actions .ck-link-actions__preview .ck-button__label { + overflow: hidden; + } + +@media screen and (max-width: 600px) { + +.ck.ck-link-actions { + flex-wrap: wrap; +} + + .ck.ck-link-actions .ck-link-actions__preview { + flex-basis: 100%; + } + + .ck.ck-link-actions .ck-button:not(.ck-link-actions__preview) { + flex-basis: 50%; + } + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-link-form { + display: flex; + align-items: flex-start; +} + +.ck.ck-link-form .ck-label { + display: none; + } + +@media screen and (max-width: 600px) { + +.ck.ck-link-form { + flex-wrap: wrap; +} + + .ck.ck-link-form .ck-labeled-field-view { + flex-basis: 100%; + } + + .ck.ck-link-form .ck-button { + flex-basis: 50%; + } + } + +/* + * Style link form differently when manual decorators are available. + * See: https://github.com/ckeditor/ckeditor5-link/issues/186. + */ +.ck.ck-link-form_layout-vertical { + display: block; + + /* + * Whether the form is in the responsive mode or not, if there are decorator buttons + * keep the top margin of action buttons medium. + */ +} +.ck.ck-link-form_layout-vertical .ck-button.ck-button-save, + .ck.ck-link-form_layout-vertical .ck-button.ck-button-cancel { + margin-top: var(--ck-spacing-medium); + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck-editor__editable .ck-list-bogus-paragraph { + display: block; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-list-styles-list { + display: grid; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck-content ol { + list-style-type: decimal; +} + +.ck-content ol ol { + list-style-type: lower-latin; + } + +.ck-content ol ol ol { + list-style-type: lower-roman; + } + +.ck-content ol ol ol ol { + list-style-type: upper-latin; + } + +.ck-content ol ol ol ol ol { + list-style-type: upper-roman; + } + +.ck-content ul { + list-style-type: disc; +} + +.ck-content ul ul { + list-style-type: circle; + } + +.ck-content ul ul ul { + list-style-type: square; + } + +.ck-content ul ul ul ul { + list-style-type: square; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-todo-list-checkmark-size: 16px; +} + +/* + * To-do list content styles. + */ +.ck-content .todo-list { + list-style: none; +} +.ck-content .todo-list li { + position: relative; + margin-bottom: 5px; + } +.ck-content .todo-list li .todo-list { + margin-top: 5px; + } +.ck-content .todo-list .todo-list__label > input { + -webkit-appearance: none; + display: inline-block; + position: relative; + width: var(--ck-todo-list-checkmark-size); + height: var(--ck-todo-list-checkmark-size); + vertical-align: middle; + /* Needed on iOS */ + border: 0; + /* LTR styles */ + left: -25px; + margin-right: -15px; + right: 0; + margin-left: 0; + /* RTL styles */ + } +.ck-content[dir=rtl] .todo-list .todo-list__label > input { + left: 0; + margin-right: 0; + right: -25px; + margin-left: -15px; + } +.ck-content .todo-list .todo-list__label > input::before { + display: block; + position: absolute; + box-sizing: border-box; + content: ''; + width: 100%; + height: 100%; + border: 1px solid hsl(0, 0%, 20%); + border-radius: 2px; + transition: 250ms ease-in-out box-shadow; + } +@media (prefers-reduced-motion: reduce) { +.ck-content .todo-list .todo-list__label > input::before { + transition: none; + } + } +.ck-content .todo-list .todo-list__label > input::after { + display: block; + position: absolute; + box-sizing: content-box; + pointer-events: none; + content: ''; + + /* Calculate tick position, size and border-width proportional to the checkmark size. */ + left: calc( var(--ck-todo-list-checkmark-size) / 3 ); + top: calc( var(--ck-todo-list-checkmark-size) / 5.3 ); + width: calc( var(--ck-todo-list-checkmark-size) / 5.3 ); + height: calc( var(--ck-todo-list-checkmark-size) / 2.6 ); + border-style: solid; + border-color: transparent; + border-width: 0 calc( var(--ck-todo-list-checkmark-size) / 8 ) calc( var(--ck-todo-list-checkmark-size) / 8 ) 0; + transform: rotate(45deg); + } +.ck-content .todo-list .todo-list__label > input[checked]::before { + background: hsl(126, 64%, 41%); + border-color: hsl(126, 64%, 41%); + } +.ck-content .todo-list .todo-list__label > input[checked]::after { + border-color: hsl(0, 0%, 100%); + } +.ck-content .todo-list .todo-list__label .todo-list__label__description { + vertical-align: middle; + } +.ck-content .todo-list .todo-list__label.todo-list__label_without-description input[type=checkbox] { + position: absolute; + } + +/* + * To-do list editing view styles. + */ +/* + * To-do list should be interactive only during the editing + * (https://github.com/ckeditor/ckeditor5/issues/2090). + */ +.ck-editor__editable.ck-content .todo-list .todo-list__label > input, + .ck-editor__editable.ck-content .todo-list .todo-list__label > span[contenteditable=false] > input { + cursor: pointer; + } +.ck-editor__editable.ck-content .todo-list .todo-list__label > input:hover::before, .ck-editor__editable.ck-content .todo-list .todo-list__label > span[contenteditable=false] > input:hover::before { + box-shadow: 0 0 0 5px hsla(0, 0%, 0%, 0.1); + } +/* + * Document Lists - editing view has an additional span around checkbox. + */ +.ck-editor__editable.ck-content .todo-list .todo-list__label > span[contenteditable=false] > input { + -webkit-appearance: none; + display: inline-block; + position: relative; + width: var(--ck-todo-list-checkmark-size); + height: var(--ck-todo-list-checkmark-size); + vertical-align: middle; + /* Needed on iOS */ + border: 0; + /* LTR styles */ + left: -25px; + margin-right: -15px; + right: 0; + margin-left: 0; + /* RTL styles */ + } +.ck-editor__editable.ck-content[dir=rtl] .todo-list .todo-list__label > span[contenteditable=false] > input { + left: 0; + margin-right: 0; + right: -25px; + margin-left: -15px; + } +.ck-editor__editable.ck-content .todo-list .todo-list__label > span[contenteditable=false] > input::before { + display: block; + position: absolute; + box-sizing: border-box; + content: ''; + width: 100%; + height: 100%; + border: 1px solid hsl(0, 0%, 20%); + border-radius: 2px; + transition: 250ms ease-in-out box-shadow; + } +@media (prefers-reduced-motion: reduce) { +.ck-editor__editable.ck-content .todo-list .todo-list__label > span[contenteditable=false] > input::before { + transition: none; + } + } +.ck-editor__editable.ck-content .todo-list .todo-list__label > span[contenteditable=false] > input::after { + display: block; + position: absolute; + box-sizing: content-box; + pointer-events: none; + content: ''; + + /* Calculate tick position, size and border-width proportional to the checkmark size. */ + left: calc( var(--ck-todo-list-checkmark-size) / 3 ); + top: calc( var(--ck-todo-list-checkmark-size) / 5.3 ); + width: calc( var(--ck-todo-list-checkmark-size) / 5.3 ); + height: calc( var(--ck-todo-list-checkmark-size) / 2.6 ); + border-style: solid; + border-color: transparent; + border-width: 0 calc( var(--ck-todo-list-checkmark-size) / 8 ) calc( var(--ck-todo-list-checkmark-size) / 8 ) 0; + transform: rotate(45deg); + } +.ck-editor__editable.ck-content .todo-list .todo-list__label > span[contenteditable=false] > input[checked]::before { + background: hsl(126, 64%, 41%); + border-color: hsl(126, 64%, 41%); + } +.ck-editor__editable.ck-content .todo-list .todo-list__label > span[contenteditable=false] > input[checked]::after { + border-color: hsl(0, 0%, 100%); + } +.ck-editor__editable.ck-content .todo-list .todo-list__label.todo-list__label_without-description input[type=checkbox] { + position: absolute; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck-content .media { + /* Don't allow floated content overlap the media. + https://github.com/ckeditor/ckeditor5-media-embed/issues/53 */ + clear: both; + + /* Make sure there is some space between the content and the media. */ + /* The first value should be equal to --ck-spacing-large variable if used in the editor context + to avoid the content jumping (See https://github.com/ckeditor/ckeditor5/issues/9825). */ + margin: 0.9em 0; + + /* Make sure media is not overriden with Bootstrap default `flex` value. + See: https://github.com/ckeditor/ckeditor5/issues/1373. */ + display: block; + + /* Give the media some minimal width in the content to prevent them + from being "squashed" in tight spaces, e.g. in table cells (#44) */ + min-width: 15em; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck-media__wrapper .ck-media__placeholder { + display: flex; + flex-direction: column; + align-items: center; + } + +.ck-media__wrapper .ck-media__placeholder .ck-media__placeholder__url { + /* Otherwise the URL will overflow when the content is very narrow. */ + max-width: 100%; + + position: relative; + } + +.ck-media__wrapper .ck-media__placeholder .ck-media__placeholder__url .ck-media__placeholder__url__text { + overflow: hidden; + display: block; + } + +.ck-media__wrapper[data-oembed-url*="twitter.com"] .ck-media__placeholder__icon *, .ck-media__wrapper[data-oembed-url*="google.com/maps"] .ck-media__placeholder__icon *, .ck-media__wrapper[data-oembed-url*="goo.gl/maps"] .ck-media__placeholder__icon *, .ck-media__wrapper[data-oembed-url*="maps.google.com"] .ck-media__placeholder__icon *, .ck-media__wrapper[data-oembed-url*="maps.app.goo.gl"] .ck-media__placeholder__icon *, .ck-media__wrapper[data-oembed-url*="facebook.com"] .ck-media__placeholder__icon *, .ck-media__wrapper[data-oembed-url*="instagram.com"] .ck-media__placeholder__icon * { + display: none; + } + +/* Disable all mouse interaction as long as the editor is not read–only. + https://github.com/ckeditor/ckeditor5-media-embed/issues/58 */ +.ck-editor__editable:not(.ck-read-only) .ck-media__wrapper > *:not(.ck-media__placeholder) { + pointer-events: none; +} + +/* Disable all mouse interaction when the widget is not selected (e.g. to avoid opening links by accident). + https://github.com/ckeditor/ckeditor5-media-embed/issues/18 */ +.ck-editor__editable:not(.ck-read-only) .ck-widget:not(.ck-widget_selected) .ck-media__placeholder { + pointer-events: none; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck-vertical-form .ck-button::after { + content: ""; + width: 0; + position: absolute; + right: -1px; + top: -1px; + bottom: -1px; + z-index: 1; + } + +.ck-vertical-form .ck-button:focus::after { + display: none; + } + +@media screen and (max-width: 600px) { + .ck.ck-responsive-form .ck-button::after { + content: ""; + width: 0; + position: absolute; + right: -1px; + top: -1px; + bottom: -1px; + z-index: 1; + } + + .ck.ck-responsive-form .ck-button:focus::after { + display: none; + } + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-media-form { + display: flex; + align-items: flex-start; + flex-direction: row; + flex-wrap: nowrap; + width: 400px; +} + +.ck.ck-media-form .ck-labeled-field-view { + display: inline-block; + width: 100%; + } + +.ck.ck-media-form .ck-label { + display: none; + } + +.ck.ck-media-form .ck-input { + width: 100%; + } + +@media screen and (max-width: 600px) { + +.ck.ck-media-form { + flex-wrap: wrap; +} + + .ck.ck-media-form .ck-labeled-field-view { + flex-basis: 100%; + } + + .ck.ck-media-form .ck-button { + flex-basis: 50%; + } + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-mention-list-max-height: 300px; +} + +.ck.ck-mentions { + max-height: var(--ck-mention-list-max-height); + + overflow-y: auto; + + /* Prevent unnecessary horizontal scrollbar in Safari + https://github.com/ckeditor/ckeditor5-mention/issues/41 */ + overflow-x: hidden; + + overscroll-behavior: contain; + + /* Prevent unnecessary vertical scrollbar in Safari + https://github.com/ckeditor/ckeditor5-mention/issues/41 */ +} + +.ck.ck-mentions > .ck-list__item { + overflow: hidden; + flex-shrink: 0; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-color-minimap-tracker-background: 208, 0%, 51%; + --ck-color-minimap-iframe-outline: hsl(0deg 0% 75%); + --ck-color-minimap-iframe-shadow: hsl(0deg 0% 0% / 11%); + --ck-color-minimap-progress-background: hsl(0,0%,40%); +} + +.ck.ck-minimap { + position: absolute; + user-select: none; + background: var(--ck-color-base-background); +} + +.ck.ck-minimap, + .ck.ck-minimap iframe { + width: 100%; + height: 100%; + } + +.ck.ck-minimap iframe { + border: 0; + pointer-events: none; + position: relative; + outline: 1px solid var(--ck-color-minimap-iframe-outline); + box-shadow: 0 2px 5px var(--ck-color-minimap-iframe-shadow); + margin: 0; + } + +.ck.ck-minimap .ck.ck-minimap__position-tracker { + position: absolute; + width: 100%; + top: 0; + background: hsla( var(--ck-color-minimap-tracker-background), .2 ); + z-index: 1; + transition: background 100ms ease-in-out; + } + +@media (prefers-reduced-motion: reduce) { + +.ck.ck-minimap .ck.ck-minimap__position-tracker { + transition: none; + } + } + +.ck.ck-minimap .ck.ck-minimap__position-tracker:hover { + background:hsla( var(--ck-color-minimap-tracker-background), .3 ); + } + +.ck.ck-minimap .ck.ck-minimap__position-tracker.ck-minimap__position-tracker_dragging, + .ck.ck-minimap .ck.ck-minimap__position-tracker.ck-minimap__position-tracker_dragging:hover { + background:hsla( var(--ck-color-minimap-tracker-background), .4 ); + } + +.ck.ck-minimap .ck.ck-minimap__position-tracker.ck-minimap__position-tracker_dragging::after, .ck.ck-minimap .ck.ck-minimap__position-tracker.ck-minimap__position-tracker_dragging:hover::after { + opacity: 1; + } + +.ck.ck-minimap .ck.ck-minimap__position-tracker::after { + content: attr(data-progress) "%"; + position: absolute; + top: 5px; + right: 5px; + background: var(--ck-color-minimap-progress-background); + color: var(--ck-color-base-background); + border: 1px solid var(--ck-color-base-background); + padding: 2px 4px; + font-size: 10px; + border-radius: 3px; + opacity: 0; + transition: opacity 100ms ease-in-out; + } + +@media (prefers-reduced-motion: reduce) { + +.ck.ck-minimap .ck.ck-minimap__position-tracker::after { + transition: none; + } + } + + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck-content .page-break { + position: relative; + clear: both; + padding: 5px 0; + display: flex; + align-items: center; + justify-content: center; +} + +.ck-content .page-break::after { + content: ''; + position: absolute; + border-bottom: 2px dashed hsl(0, 0%, 77%); + width: 100%; + } + +.ck-content .page-break__label { + position: relative; + z-index: 1; + padding: .3em .6em; + display: block; + text-transform: uppercase; + border: 1px solid hsl(0, 0%, 77%); + border-radius: 2px; + font-family: Helvetica, Arial, Tahoma, Verdana, Sans-Serif; + font-size: 0.75em; + font-weight: bold; + color: hsl(0, 0%, 20%); + background: hsl(0, 0%, 100%); + box-shadow: 2px 2px 1px hsla(0, 0%, 0%, 0.15); + + /* Disable the possibility to select the label text by the user. */ + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +/* Do not show the page break element inside the print preview window. */ +@media print { + .ck-content .page-break { + padding: 0; + } + + .ck-content .page-break::after { + display: none; + } + + /* + * From time to time placing page-break directly after a block element with margin causes appending a new blank page in pagination mode. + * Removing margin-bottom from the block element fixes that issue and the margin is not being moved to the next blank page. + * + * Keep this in sync with the pagination plugins. + */ + .ck-content *:has(+ .page-break) { + margin-bottom: 0; + } +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-show-blocks-border-color: hsl(0, 0%, 46%); +} + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) address { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) address { + background-image: url("data:image/svg+xml;utf8,ADDRESS"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) address { + background-image: url("data:image/svg+xml;utf8,ADDRESS"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) address:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) address { + background-image: url("data:image/svg+xml;utf8,ADDRESS"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) address { + background-image: url("data:image/svg+xml;utf8,ADDRESS"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) aside { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) aside { + background-image: url("data:image/svg+xml;utf8,ASIDE"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) aside { + background-image: url("data:image/svg+xml;utf8,ASIDE"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) aside:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) aside { + background-image: url("data:image/svg+xml;utf8,ASIDE"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) aside { + background-image: url("data:image/svg+xml;utf8,ASIDE"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) blockquote { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) blockquote { + background-image: url("data:image/svg+xml;utf8,BLOCKQUOTE"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) blockquote { + background-image: url("data:image/svg+xml;utf8,BLOCKQUOTE"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) blockquote:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) blockquote { + background-image: url("data:image/svg+xml;utf8,BLOCKQUOTE"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) blockquote { + background-image: url("data:image/svg+xml;utf8,BLOCKQUOTE"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) details { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) details { + background-image: url("data:image/svg+xml;utf8,DETAILS"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) details { + background-image: url("data:image/svg+xml;utf8,DETAILS"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) details:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) details { + background-image: url("data:image/svg+xml;utf8,DETAILS"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) details { + background-image: url("data:image/svg+xml;utf8,DETAILS"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) div:not(.ck-widget, .ck-widget *) { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) div:not(.ck-widget, .ck-widget *) { + background-image: url("data:image/svg+xml;utf8,DIV"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) div:not(.ck-widget, .ck-widget *) { + background-image: url("data:image/svg+xml;utf8,DIV"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) div:not(.ck-widget, .ck-widget *):not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) div:not(.ck-widget, .ck-widget *) { + background-image: url("data:image/svg+xml;utf8,DIV"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) div:not(.ck-widget, .ck-widget *) { + background-image: url("data:image/svg+xml;utf8,DIV"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) footer { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) footer { + background-image: url("data:image/svg+xml;utf8,FOOTER"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) footer { + background-image: url("data:image/svg+xml;utf8,FOOTER"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) footer:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) footer { + background-image: url("data:image/svg+xml;utf8,FOOTER"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) footer { + background-image: url("data:image/svg+xml;utf8,FOOTER"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h1 { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h1 { + background-image: url("data:image/svg+xml;utf8,H1"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h1 { + background-image: url("data:image/svg+xml;utf8,H1"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h1:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h1 { + background-image: url("data:image/svg+xml;utf8,H1"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h1 { + background-image: url("data:image/svg+xml;utf8,H1"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h2 { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h2 { + background-image: url("data:image/svg+xml;utf8,H2"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h2 { + background-image: url("data:image/svg+xml;utf8,H2"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h2:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h2 { + background-image: url("data:image/svg+xml;utf8,H2"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h2 { + background-image: url("data:image/svg+xml;utf8,H2"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h3 { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h3 { + background-image: url("data:image/svg+xml;utf8,H3"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h3 { + background-image: url("data:image/svg+xml;utf8,H3"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h3:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h3 { + background-image: url("data:image/svg+xml;utf8,H3"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h3 { + background-image: url("data:image/svg+xml;utf8,H3"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h4 { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h4 { + background-image: url("data:image/svg+xml;utf8,H4"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h4 { + background-image: url("data:image/svg+xml;utf8,H4"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h4:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h4 { + background-image: url("data:image/svg+xml;utf8,H4"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h4 { + background-image: url("data:image/svg+xml;utf8,H4"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h5 { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h5 { + background-image: url("data:image/svg+xml;utf8,H5"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h5 { + background-image: url("data:image/svg+xml;utf8,H5"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h5:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h5 { + background-image: url("data:image/svg+xml;utf8,H5"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h5 { + background-image: url("data:image/svg+xml;utf8,H5"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h6 { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h6 { + background-image: url("data:image/svg+xml;utf8,H6"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h6 { + background-image: url("data:image/svg+xml;utf8,H6"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h6:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h6 { + background-image: url("data:image/svg+xml;utf8,H6"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) h6 { + background-image: url("data:image/svg+xml;utf8,H6"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) header { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) header { + background-image: url("data:image/svg+xml;utf8,HEADER"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) header { + background-image: url("data:image/svg+xml;utf8,HEADER"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) header:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) header { + background-image: url("data:image/svg+xml;utf8,HEADER"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) header { + background-image: url("data:image/svg+xml;utf8,HEADER"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) main { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) main { + background-image: url("data:image/svg+xml;utf8,MAIN"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) main { + background-image: url("data:image/svg+xml;utf8,MAIN"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) main:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) main { + background-image: url("data:image/svg+xml;utf8,MAIN"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) main { + background-image: url("data:image/svg+xml;utf8,MAIN"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) nav { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) nav { + background-image: url("data:image/svg+xml;utf8,NAV"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) nav { + background-image: url("data:image/svg+xml;utf8,NAV"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) nav:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) nav { + background-image: url("data:image/svg+xml;utf8,NAV"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) nav { + background-image: url("data:image/svg+xml;utf8,NAV"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) pre { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) pre { + background-image: url("data:image/svg+xml;utf8,PRE"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) pre { + background-image: url("data:image/svg+xml;utf8,PRE"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) pre:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) pre { + background-image: url("data:image/svg+xml;utf8,PRE"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) pre { + background-image: url("data:image/svg+xml;utf8,PRE"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) ol { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) ol { + background-image: url("data:image/svg+xml;utf8,OL"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) ol { + background-image: url("data:image/svg+xml;utf8,OL"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) ol:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) ol { + background-image: url("data:image/svg+xml;utf8,OL"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) ol { + background-image: url("data:image/svg+xml;utf8,OL"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) ul { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) ul { + background-image: url("data:image/svg+xml;utf8,UL"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) ul { + background-image: url("data:image/svg+xml;utf8,UL"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) ul:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) ul { + background-image: url("data:image/svg+xml;utf8,UL"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) ul { + background-image: url("data:image/svg+xml;utf8,UL"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) p { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) p { + background-image: url("data:image/svg+xml;utf8,P"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) p { + background-image: url("data:image/svg+xml;utf8,P"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) p:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) p { + background-image: url("data:image/svg+xml;utf8,P"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) p { + background-image: url("data:image/svg+xml;utf8,P"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) section { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) section { + background-image: url("data:image/svg+xml;utf8,SECTION"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) section { + background-image: url("data:image/svg+xml;utf8,SECTION"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) section:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) section { + background-image: url("data:image/svg+xml;utf8,SECTION"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) section { + background-image: url("data:image/svg+xml;utf8,SECTION"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) :where(figure.image, figure.table) figcaption { + background-repeat: no-repeat; + padding-top: 15px; + /* Fix for Multi-root editor + https://github.com/ckeditor/ckeditor5/issues/15969 */ + } + +[dir=ltr] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) :where(figure.image, figure.table) figcaption { + background-image: url("data:image/svg+xml;utf8,FIGCAPTION"); + background-position: 1px 1px; + } + +[dir=rtl] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) :where(figure.image, figure.table) figcaption { + background-image: url("data:image/svg+xml;utf8,FIGCAPTION"); + background-position: calc(100% - 1px) 1px; + } + +.ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) :where(figure.image, figure.table) figcaption:not(.ck-widget_selected):not(.ck-widget:hover) { + outline: 1px dashed var(--ck-show-blocks-border-color); + } + +[dir="ltr"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) :where(figure.image, figure.table) figcaption { + background-image: url("data:image/svg+xml;utf8,FIGCAPTION"); + background-position: 1px 1px; + } + +[dir="rtl"] .ck.ck-editor__editable.ck-editor__editable_inline.ck-show-blocks:not(.ck-widget) :where(figure.image, figure.table) figcaption { + background-image: url("data:image/svg+xml;utf8,FIGCAPTION"); + background-position: calc(100% - 1px) 1px; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/** + * Implements rounded corner interface for .ck-rounded-corners class. + * + * @see $ck-border-radius + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A visual style of focused element's border. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A helper to combine multiple shadows. + */ +/** + * Gives an element a drop shadow so it looks like a floating panel. + */ + +.ck-source-editing-area { + position: relative; + overflow: hidden; +} + +.ck-source-editing-area::after, +.ck-source-editing-area textarea { + padding: var(--ck-spacing-large); + margin: 0; + border: 1px solid transparent; + line-height: var(--ck-line-height-base); + font-size: var(--ck-font-size-normal); + font-family: monospace; + white-space: pre-wrap; +} + +.ck-source-editing-area::after { + content: attr(data-value) " "; + visibility: hidden; + display: block; +} + +.ck-source-editing-area textarea { + position: absolute; + width: 100%; + height: 100%; + resize: none; + outline: none; + overflow: hidden; + box-sizing: border-box; + + border-color: var(--ck-color-base-border); + + border-radius: 0; +} + +.ck-rounded-corners .ck-source-editing-area textarea, + .ck-source-editing-area textarea.ck-rounded-corners { + border-radius: var(--ck-border-radius); + border-top-left-radius: 0; + border-top-right-radius: 0; + } + +.ck-source-editing-area textarea:not([readonly]):focus { + /* Disable native outline. */ + outline: none; + border: var(--ck-focus-ring); + box-shadow: var(--ck-inner-shadow), 0 0; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-character-grid { + max-width: 100%; +} + +.ck.ck-character-grid .ck-character-grid__tiles { + display: grid; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-character-info { + display: flex; + justify-content: space-between; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Note: This file should contain the wireframe styles only. But since there are no such styles, + * it acts as a message to the builder telling that it should look for the corresponding styles + * **in the theme** when compiling the editor. + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-special-characters > .ck-dialog__content > div { + width: 350px; + max-width: 100%; + height: 100%; + + display: grid; + grid-column-gap: 0px; + grid-row-gap: 0px; + grid-template-columns: 1fr; + grid-template-rows: auto 1fr auto; + } + +.ck.ck-special-characters > .ck-dialog__content > div > .ck-character-categories { + grid-area: 1 / 1 / 2 / 2; + padding: var(--ck-spacing-medium) var(--ck-spacing-large); + } + +.ck.ck-special-characters > .ck-dialog__content > div > .ck-character-categories > .ck-labeled-field-view { + padding-top: var(--ck-spacing-standard); + width: 100%; + } + +.ck.ck-special-characters > .ck-dialog__content > div > .ck-character-categories > .ck-labeled-field-view .ck.ck-labeled-field-view__status { + background: var(--ck-color-base-error); + color: var(--ck-color-base-background); + padding: var(--ck-spacing-small) var(--ck-spacing-medium); + min-width: var(--ck-table-properties-min-error-width); + text-align: center; + + animation: ck-table-form-labeled-view-status-appear .15s ease both; + + /* The arrow pointing towards the field. */ + } + +.ck.ck-special-characters > .ck-dialog__content > div > .ck-character-categories > .ck-labeled-field-view .ck.ck-labeled-field-view__status::after { + border-color: transparent transparent var(--ck-color-base-error) transparent; + border-width: 0 var(--ck-table-properties-error-arrow-size) var(--ck-table-properties-error-arrow-size) var(--ck-table-properties-error-arrow-size); + border-style: solid; + } + +@media (prefers-reduced-motion: reduce) { + +.ck.ck-special-characters > .ck-dialog__content > div > .ck-character-categories > .ck-labeled-field-view .ck.ck-labeled-field-view__status { + animation: none; + } + } + +/* Hide the error balloon when the field is blurred. Makes the experience much more clear. */ + +.ck.ck-special-characters > .ck-dialog__content > div > .ck-character-categories > .ck-labeled-field-view .ck-input.ck-error:not(:focus) + .ck.ck-labeled-field-view__status { + display: none; + } + +.ck.ck-special-characters > .ck-dialog__content > div > .ck-character-categories > .ck-labeled-field-view > .ck-label { + font-size: var(--ck-font-size-tiny); + text-align: center; + } + +.ck.ck-special-characters > .ck-dialog__content > div > .ck-character-categories .ck-dropdown { + display: block; + width: 100%; + } + +.ck.ck-special-characters > .ck-dialog__content > div > .ck-character-categories .ck-dropdown > button:not(:focus) { + border: 1px solid var(--ck-color-base-border); + } + +.ck.ck-special-characters > .ck-dialog__content > div > .ck-character-categories .ck-dropdown > button > span { + width: 100%; + } + +.ck.ck-special-characters > .ck-dialog__content > div > .ck-character-grid { + grid-area: 2 / 1 / 3 / 2; + max-height: 200px; + } + +.ck.ck-special-characters > .ck-dialog__content > div > .ck-character-info { + grid-area: 3 / 1 / 4 / 2; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-style-panel-columns: 3; +} + +.ck.ck-style-panel .ck-style-grid { + display: grid; + grid-template-columns: repeat(var(--ck-style-panel-columns),auto); + justify-content: start; +} + +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button { + display: flex; + justify-content: space-between; + flex-direction: column; + } + +.ck.ck-style-panel .ck-style-grid .ck-style-grid__button .ck-style-grid__button__preview { + display: flex; + align-content: center; + justify-content: flex-start; + align-items: center; + flex-grow: 1; + flex-basis: 100%; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck-content .table { + /* Give the table widget some air and center it horizontally */ + /* The first value should be equal to --ck-spacing-large variable if used in the editor context + to avoid the content jumping (See https://github.com/ckeditor/ckeditor5/issues/9825). */ + margin: 0.9em auto; + display: table; +} + +.ck-content .table table { + /* The table cells should have slight borders */ + border-collapse: collapse; + border-spacing: 0; + + /* Table width and height are set on the parent
. Make sure the table inside stretches + to the full dimensions of the container (https://github.com/ckeditor/ckeditor5/issues/6186). */ + width: 100%; + height: 100%; + + /* The outer border of the table should be slightly darker than the inner lines. + Also see https://github.com/ckeditor/ckeditor5-table/issues/50. */ + border: 1px double hsl(0, 0%, 70%); + } + +.ck-content .table table td, + .ck-content .table table th { + min-width: 2em; + padding: .4em; + + /* The border is inherited from .ck-editor__nested-editable styles, so theoretically it's not necessary here. + However, the border is a content style, so it should use .ck-content (so it works outside the editor). + Hence, the duplication. See https://github.com/ckeditor/ckeditor5/issues/6314 */ + border: 1px solid hsl(0, 0%, 75%); + } + +.ck-content .table table th { + font-weight: bold; + background: hsla(0, 0%, 0%, 5%); + } + +/** + * Expanding the table to the full height of the parent container is necessary because tables + * are rendered inside
elements, which is kinda buggy in table height calculation. + * While setting `height: 100%` fixes the issue in the editing mode described here: + * https://github.com/ckeditor/ckeditor5/issues/6186 + * + * it's causing another issue with the table height in the print preview mode here: + * https://github.com/ckeditor/ckeditor5/issues/16856 + * + * For now, resetting the height to `initial` in the print mode works as a workaround. + */ +@media print { + .ck-content .table table { + height: initial; + } +} + +/* Text alignment of the table header should match the editor settings and override the native browser styling, +when content is available outside the editor. See https://github.com/ckeditor/ckeditor5/issues/6638 */ +.ck-content[dir="rtl"] .table th { + text-align: right; +} + +.ck-content[dir="ltr"] .table th { + text-align: left; +} + +.ck-editor__editable .ck-table-bogus-paragraph { + /* + * Use display:inline-block to force Chrome/Safari to limit text mutations to this element. + * See https://github.com/ckeditor/ckeditor5/issues/6062. + */ + display: inline-block; + + /* + * Inline HTML elements nested in the span should always be dimensioned in relation to the whole cell width. + * See https://github.com/ckeditor/ckeditor5/issues/9117. + */ + width: 100%; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck .ck-insert-table-dropdown__grid { + display: flex; + flex-direction: row; + flex-wrap: wrap; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-form__row { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: space-between; + + /* Ignore labels that work as fieldset legends */ +} + +.ck.ck-form__row > *:not(.ck-label) { + flex-grow: 1; + } + +.ck.ck-form__row.ck-table-form__action-row .ck-button-save, + .ck.ck-form__row.ck-table-form__action-row .ck-button-cancel { + justify-content: center; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-table-cell-properties-form .ck-form__row.ck-table-cell-properties-form__alignment-row { + flex-wrap: wrap; + } + +.ck.ck-table-cell-properties-form .ck-form__row.ck-table-cell-properties-form__alignment-row .ck.ck-toolbar:first-of-type { + /* 4 buttons out of 7 (h-alignment + v-alignment) = 0.57 */ + flex-grow: 0.57; + } + +.ck.ck-table-cell-properties-form .ck-form__row.ck-table-cell-properties-form__alignment-row .ck.ck-toolbar:last-of-type { + /* 3 buttons out of 7 (h-alignment + v-alignment) = 0.43 */ + flex-grow: 0.43; + } + +.ck.ck-table-cell-properties-form .ck-form__row.ck-table-cell-properties-form__alignment-row .ck.ck-toolbar .ck-button { + flex-grow: 1; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-input-color { + width: 100%; + display: flex; + flex-direction: row-reverse; +} + +.ck.ck-input-color > input.ck.ck-input-text { + min-width: auto; + flex-grow: 1; + } + +.ck.ck-input-color > div.ck.ck-dropdown { + min-width: auto; + + /* This dropdown has no arrow but a color preview instead. */ + } + +.ck.ck-input-color > div.ck.ck-dropdown > .ck-input-color__button .ck-dropdown__arrow { + display: none; + } + +.ck.ck-input-color .ck.ck-input-color__button { + /* Resolving issue with misaligned buttons on Safari (see #10589) */ + display: flex; + } + +.ck.ck-input-color .ck.ck-input-color__button .ck.ck-input-color__button__preview { + position: relative; + overflow: hidden; + } + +.ck.ck-input-color .ck.ck-input-color__button .ck.ck-input-color__button__preview > .ck.ck-input-color__button__preview__no-color-indicator { + position: absolute; + display: block; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-table-form .ck-form__row.ck-table-form__border-row { + flex-wrap: wrap; + } + +.ck.ck-table-form .ck-form__row.ck-table-form__background-row { + flex-wrap: wrap; + } + +.ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row { + flex-wrap: wrap; + align-items: center; + } + +.ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row .ck-labeled-field-view { + display: flex; + flex-direction: column-reverse; + align-items: center; + } + +.ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row .ck-labeled-field-view .ck.ck-dropdown { + flex-grow: 0; + } + +.ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row .ck-table-form__dimension-operator { + flex-grow: 0; + } + +.ck.ck-table-form .ck.ck-labeled-field-view { + /* Allow absolute positioning of the status (error) balloons. */ + position: relative; + } + +.ck.ck-table-form .ck.ck-labeled-field-view .ck.ck-labeled-field-view__status { + position: absolute; + left: 50%; + bottom: calc( -1 * var(--ck-table-properties-error-arrow-size) ); + transform: translate(-50%,100%); + + /* Make sure the balloon status stays on top of other form elements. */ + z-index: 1; + + /* The arrow pointing towards the field. */ + } + +.ck.ck-table-form .ck.ck-labeled-field-view .ck.ck-labeled-field-view__status::after { + content: ""; + position: absolute; + top: calc( -1 * var(--ck-table-properties-error-arrow-size) ); + left: 50%; + transform: translateX( -50% ); + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-table-properties-form .ck-form__row.ck-table-properties-form__alignment-row { + flex-wrap: wrap; + flex-basis: 0; + align-content: baseline; + } + +.ck.ck-table-properties-form .ck-form__row.ck-table-properties-form__alignment-row .ck.ck-toolbar .ck-toolbar__items { + flex-wrap: nowrap; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-color-selector-caption-background: hsl(0, 0%, 97%); + --ck-color-selector-caption-text: hsl(0, 0%, 20%); + --ck-color-selector-caption-highlighted-background: hsl(52deg 100% 50%); +} + +/* Content styles */ +.ck-content .table > figcaption { + display: table-caption; + caption-side: top; + word-break: break-word; + text-align: center; + color: var(--ck-color-selector-caption-text); + background-color: var(--ck-color-selector-caption-background); + padding: .6em; + font-size: .75em; + outline-offset: -1px; + + /* Improve placeholder rendering in high-constrast mode (https://github.com/ckeditor/ckeditor5/issues/14907). */ +} +@media (forced-colors: active) { + .ck-content .table > figcaption { + background-color: unset; + color: unset; + } + } + +/* Editing styles */ +@media (forced-colors: none) { + .ck.ck-editor__editable .table > figcaption.table__caption_highlighted { + animation: ck-table-caption-highlight .6s ease-out; + } + } +.ck.ck-editor__editable .table > figcaption.ck-placeholder::before { + padding-left: inherit; + padding-right: inherit; + + /* + * Make sure the table caption placeholder doesn't overflow the placeholder area. + * See https://github.com/ckeditor/ckeditor5/issues/9162. + */ + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + +@keyframes ck-table-caption-highlight { + 0% { + background-color: var(--ck-color-selector-caption-highlighted-background); + } + + 100% { + background-color: var(--ck-color-selector-caption-background); + } +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-color-selector-column-resizer-hover: var(--ck-color-base-active); + --ck-table-column-resizer-width: 7px; + + /* The offset used for absolute positioning of the resizer element, so that it is placed exactly above the cell border. + The value is: minus half the width of the resizer decreased additionaly by the half the width of the border (0.5px). */ + --ck-table-column-resizer-position-offset: calc(var(--ck-table-column-resizer-width) * -0.5 - 0.5px); +} + +.ck-content .table .ck-table-resized { + table-layout: fixed; +} + +.ck-content .table table { + overflow: hidden; +} + +.ck-content .table td, +.ck-content .table th { + /* To prevent text overflowing beyond its cell when columns are resized by resize handler + (https://github.com/ckeditor/ckeditor5/pull/14379#issuecomment-1589460978). */ + overflow-wrap: break-word; + position: relative; +} + +.ck.ck-editor__editable .table .ck-table-column-resizer { + position: absolute; + top: 0; + bottom: 0; + right: var(--ck-table-column-resizer-position-offset); + width: var(--ck-table-column-resizer-width); + cursor: col-resize; + user-select: none; + z-index: var(--ck-z-default); +} + +.ck.ck-editor__editable.ck-column-resize_disabled .table .ck-table-column-resizer { + display: none; +} + +/* The resizer elements, which are extended to an extremely high height, break the drag & drop feature in Chrome. To make it work again, + all resizers must be hidden while the table is dragged. */ +.ck.ck-editor__editable .table[draggable] .ck-table-column-resizer { + display: none; +} + +.ck.ck-editor__editable .table .ck-table-column-resizer:hover, +.ck.ck-editor__editable .table .ck-table-column-resizer__active { + background-color: var(--ck-color-selector-column-resizer-hover); + opacity: 0.25; + /* The resizer element resides in each cell so to occupy the entire height of the table, which is unknown from a CSS point of view, + it is extended to an extremely high height. Even for screens with a very high pixel density, the resizer will fulfill its role as + it should, i.e. for a screen of 476 ppi the total height of the resizer will take over 350 sheets of A4 format, which is totally + unrealistic height for a single table. */ + top: -999999px; + bottom: -999999px; +} + +.ck.ck-editor__editable[dir=rtl] .table .ck-table-column-resizer { + left: var(--ck-table-column-resizer-position-offset); + right: unset; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/** + * A class which hides an element in DOM. + */ + +.ck-hidden { + /* Override selector specificity. Otherwise, all elements with some display + style defined will override this one, which is not a desired result. */ + display: none !important; +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-z-default: 1; + --ck-z-panel: calc( var(--ck-z-default) + 999 ); + --ck-z-dialog: 9999; +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +/** + * A class that disables all transitions of the element and its children. + */ +.ck-transitions-disabled, +.ck-transitions-disabled * { + transition: none !important; +} +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ +:root { + --ck-powered-by-line-height: 10px; + --ck-powered-by-padding-vertical: 2px; + --ck-powered-by-padding-horizontal: 4px; + --ck-powered-by-text-color: hsl(0, 0%, 31%); + --ck-powered-by-border-radius: var(--ck-border-radius); + --ck-powered-by-background: hsl(0, 0%, 100%); + --ck-powered-by-border-color: var(--ck-color-focus-border); +} +.ck.ck-balloon-panel.ck-powered-by-balloon { + --ck-border-radius: var(--ck-powered-by-border-radius); + + box-shadow: none; + background: var(--ck-powered-by-background); + min-height: unset; + z-index: calc( var(--ck-z-panel) - 1 ); +} +.ck.ck-balloon-panel.ck-powered-by-balloon .ck.ck-powered-by { + line-height: var(--ck-powered-by-line-height); + } +.ck.ck-balloon-panel.ck-powered-by-balloon .ck.ck-powered-by a { + cursor: pointer; + display: flex; + align-items: center; + opacity: .66; + filter: grayscale(80%); + line-height: var(--ck-powered-by-line-height); + padding: var(--ck-powered-by-padding-vertical) var(--ck-powered-by-padding-horizontal); + } +.ck.ck-balloon-panel.ck-powered-by-balloon .ck.ck-powered-by .ck-powered-by__label { + font-size: 7.5px; + letter-spacing: -.2px; + padding-left: 2px; + text-transform: uppercase; + font-weight: bold; + margin-right: 4px; + cursor: pointer; + line-height: normal; + color: var(--ck-powered-by-text-color); + + } +.ck.ck-balloon-panel.ck-powered-by-balloon .ck.ck-powered-by .ck-icon { + display: block; + cursor: pointer; + } +.ck.ck-balloon-panel.ck-powered-by-balloon .ck.ck-powered-by:hover a { + filter: grayscale(0%); + opacity: 1; + } +.ck.ck-balloon-panel.ck-powered-by-balloon[class*="position_inside"] { + border-color: transparent; + } +.ck.ck-balloon-panel.ck-powered-by-balloon[class*="position_border"] { + border: var(--ck-focus-ring); + border-color: var(--ck-powered-by-border-color); + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/** + * Makes element unselectable. + */ +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-button, +a.ck.ck-button { + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + + position: relative; + display: inline-flex; + align-items: center; +} + +[dir="ltr"] .ck.ck-button, [dir="ltr"] a.ck.ck-button { + justify-content: left; + } + +[dir="rtl"] .ck.ck-button, [dir="rtl"] a.ck.ck-button { + justify-content: right; + } + +.ck.ck-button .ck-button__label, a.ck.ck-button .ck-button__label { + display: none; + } + +.ck.ck-button.ck-button_with-text .ck-button__label, a.ck.ck-button.ck-button_with-text .ck-button__label { + display: inline-block; + } + +/* Center the icon horizontally in a button without text. */ + +.ck.ck-button:not(.ck-button_with-text), a.ck.ck-button:not(.ck-button_with-text) { + justify-content: center; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-button.ck-switchbutton .ck-button__toggle { + display: block; + } + +.ck.ck-button.ck-switchbutton .ck-button__toggle .ck-button__toggle__inner { + display: block; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-list-item-button { + min-height: unset; + width: 100%; + border-radius: 0; +} + +[dir="ltr"] .ck.ck-list-item-button { + text-align: left; + } + +[dir="rtl"] .ck.ck-list-item-button { + text-align: right; + } + +[dir="ltr"] .ck.ck-list-item-button.ck-list-item-button_toggleable { + padding-left: var(--ck-spacing-small); + } + +[dir="rtl"] .ck.ck-list-item-button.ck-list-item-button_toggleable { + padding-right: var(--ck-spacing-small); + } + +.ck.ck-list-item-button .ck-list-item-button__check-holder { + display: inline-flex; + width: .9em; + height: .9em; + } + +[dir="ltr"] .ck.ck-list-item-button .ck-list-item-button__check-holder { + margin-right: var(--ck-spacing-small); + } + +[dir="rtl"] .ck.ck-list-item-button .ck-list-item-button__check-holder { + margin-left: var(--ck-spacing-small); + } + +.ck.ck-list-item-button .ck-list-item-button__check-icon { + height: 100%; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-collapsible.ck-collapsible_collapsed > .ck-collapsible__children { + display: none; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-color-grid { + display: grid; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.color-picker-hex-input { + width: max-content; +} + +.color-picker-hex-input .ck.ck-input { + min-width: unset; + } + +.ck.ck-color-picker__row { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: space-between; + margin: var(--ck-spacing-large) 0 0; + width: unset; +} + +.ck.ck-color-picker__row .ck.ck-labeled-field-view { + padding-top: unset; + } + +.ck.ck-color-picker__row .ck.ck-input-text { + width: unset; + } + +.ck.ck-color-picker__row .ck-color-picker__hash-view { + padding-top: var(--ck-spacing-tiny); + padding-right: var(--ck-spacing-medium); + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* View fragment with color grids. */ + +.ck.ck-color-selector .ck-color-grids-fragment .ck-button.ck-color-selector__remove-color, + .ck.ck-color-selector .ck-color-grids-fragment .ck-button.ck-color-selector__color-picker { + display: flex; + align-items: center; + } + +[dir="rtl"] .ck.ck-color-selector .ck-color-grids-fragment .ck-button.ck-color-selector__remove-color, [dir="rtl"] .ck.ck-color-selector .ck-color-grids-fragment .ck-button.ck-color-selector__color-picker { + justify-content: flex-start; + } + +/* View fragment with a color picker. */ + +.ck.ck-color-selector .ck-color-picker-fragment .ck.ck-color-selector_action-bar { + display: flex; + flex-direction: row; + justify-content: space-around; + } + +.ck.ck-color-selector .ck-color-picker-fragment .ck.ck-color-selector_action-bar .ck-button-save, + .ck.ck-color-selector .ck-color-picker-fragment .ck.ck-color-selector_action-bar .ck-button-cancel { + flex: 1 + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-dialog .ck.ck-dialog__actions { + display: flex; + justify-content: flex-end; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-dialog-overlay { + user-select: none; + overscroll-behavior: none; + + position: fixed; + bottom: 0; + left: 0; + right: 0; + top: 0; +} + +.ck.ck-dialog-overlay.ck-dialog-overlay__transparent { + pointer-events: none; + animation: none; + background: none; + } + +.ck.ck-dialog { + overscroll-behavior: none; + width: fit-content; + position: absolute; +} + +.ck.ck-dialog .ck.ck-form__header { + flex-shrink: 0; + } + +/* Modals should not be draggable. */ + +.ck.ck-dialog:not(.ck-dialog_modal) .ck.ck-form__header .ck-form__header__label { + cursor: grab; + } + +.ck.ck-dialog-overlay.ck-dialog-overlay__transparent .ck.ck-dialog { + pointer-events: all; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-dropdown-max-width: 75vw; +} + +.ck.ck-dropdown { + display: inline-block; + position: relative; +} + +.ck.ck-dropdown .ck-dropdown__arrow { + pointer-events: none; + z-index: var(--ck-z-default); + } + +/* Dropdown button should span horizontally, e.g. in vertical toolbars */ + +.ck.ck-dropdown .ck-button.ck-dropdown__button { + width: 100%; + } + +.ck.ck-dropdown .ck-dropdown__panel { + display: none; + z-index: var(--ck-z-panel); + max-width: var(--ck-dropdown-max-width); + + position: absolute; + } + +.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel-visible { + display: inline-block; + } + +.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_ne, + .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_nw, + .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_n, + .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_nmw, + .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_nme { + bottom: 100%; + } + +.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_se, + .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sw, + .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_smw, + .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sme, + .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_s { + /* + * Using transform: translate3d( 0, 100%, 0 ) causes blurry dropdown on Chrome 67-78+ on non-retina displays. + * See https://github.com/ckeditor/ckeditor5/issues/1053. + */ + top: 100%; + bottom: auto; + } + +.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_ne, + .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_se { + left: 0px; + } + +.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_nw, + .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sw { + right: 0px; + } + +.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_s, + .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_n { + /* Positioning panels relative to the center of the button */ + left: 50%; + transform: translateX(-50%); + } + +.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_nmw, + .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_smw { + /* Positioning panels relative to the middle-west of the button */ + left: 75%; + transform: translateX(-75%); + } + +.ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_nme, + .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sme { + /* Positioning panels relative to the middle-east of the button */ + left: 25%; + transform: translateX(-25%); + } + +/* + * Toolbar dropdown panels should be always above the UI (eg. other dropdown panels) from the editor's content. + * See https://github.com/ckeditor/ckeditor5/issues/7874 + */ +.ck.ck-toolbar .ck-dropdown__panel { + z-index: calc( var(--ck-z-panel) + 1 ); +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-splitbutton { + /* Enable font size inheritance, which allows fluid UI scaling. */ + font-size: inherit; +} + +.ck.ck-splitbutton .ck-splitbutton__action:focus { + z-index: calc(var(--ck-z-default) + 1); + } + + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-toolbar-dropdown-max-width: 60vw; +} + +.ck.ck-toolbar-dropdown > .ck-dropdown__panel { + /* https://github.com/ckeditor/ckeditor5/issues/5586 */ + width: max-content; + max-width: var(--ck-toolbar-dropdown-max-width); +} + +.ck.ck-toolbar-dropdown > .ck-dropdown__panel .ck-button:focus { + z-index: calc(var(--ck-z-default) + 1); + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-dropdown-menu-list__nested-menu__button > .ck-dropdown-menu-list__nested-menu__button__arrow { + pointer-events: none; + z-index: var(--ck-z-default); +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-balloon-panel.ck-dropdown-menu__nested-menu__panel { + position: absolute; + max-height: 314px; /* With the default settings, this is equal to 10 menu items. */ + overflow-y: auto; + z-index: calc(var(--ck-z-panel) + 1); +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-dropdown-menu-list__nested-menu { + display: block; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-aria-live-announcer { + position: absolute; + left: -10000px; + top: -10000px; +} + +.ck.ck-aria-live-region-list { + list-style-type: none; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-form__header { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + align-items: center; + justify-content: space-between; +} + +.ck.ck-form__header h2.ck-form__header__label { + flex-grow: 1; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-icon { + vertical-align: middle; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-label { + display: block; +} + +.ck.ck-voice-label { + display: none; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-labeled-field-view > .ck.ck-labeled-field-view__input-wrapper { + display: flex; + position: relative; + } + +.ck.ck-labeled-field-view .ck.ck-label { + display: block; + position: absolute; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/** + * Makes element unselectable. + */ + +.ck.ck-list { + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + + display: flex; + flex-direction: column; +} + +.ck.ck-list .ck-list__item, + .ck.ck-list .ck-list__separator { + display: block; + } + +/* Make sure that whatever child of the list item gets focus, it remains on the + top. Thanks to that, styles like box-shadow, outline, etc. are not masked by + adjacent list items. */ + +.ck.ck-list .ck-list__item > *:focus { + position: relative; + z-index: var(--ck-z-default); + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + /* Make sure the balloon arrow does not float over its children. */ + --ck-balloon-panel-arrow-z-index: calc(var(--ck-z-default) - 3); +} + +.ck.ck-balloon-panel { + display: none; + position: absolute; + + z-index: var(--ck-z-panel); +} + +.ck.ck-balloon-panel.ck-balloon-panel_with-arrow::before, + .ck.ck-balloon-panel.ck-balloon-panel_with-arrow::after { + content: ""; + position: absolute; + } + +.ck.ck-balloon-panel.ck-balloon-panel_with-arrow::before { + z-index: var(--ck-balloon-panel-arrow-z-index); + } + +.ck.ck-balloon-panel.ck-balloon-panel_with-arrow::after { + z-index: calc(var(--ck-balloon-panel-arrow-z-index) + 1); + } + +.ck.ck-balloon-panel[class*="arrow_n"]::before { + z-index: var(--ck-balloon-panel-arrow-z-index); + } + +.ck.ck-balloon-panel[class*="arrow_n"]::after { + z-index: calc(var(--ck-balloon-panel-arrow-z-index) + 1); + } + +.ck.ck-balloon-panel[class*="arrow_s"]::before { + z-index: var(--ck-balloon-panel-arrow-z-index); + } + +.ck.ck-balloon-panel[class*="arrow_s"]::after { + z-index: calc(var(--ck-balloon-panel-arrow-z-index) + 1); + } + +.ck.ck-balloon-panel.ck-balloon-panel_visible { + display: block; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck .ck-balloon-rotator__navigation { + display: flex; + align-items: center; + justify-content: center; +} + +/* Buttons inside a toolbar should be centered when rotator bar is wider. + * See: https://github.com/ckeditor/ckeditor5-ui/issues/495 + */ +.ck .ck-balloon-rotator__content .ck-toolbar { + justify-content: center; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck .ck-fake-panel { + position: absolute; + + /* Fake panels should be placed under main balloon content. */ + z-index: calc(var(--ck-z-panel) - 1); +} + +.ck .ck-fake-panel div { + position: absolute; +} + +.ck .ck-fake-panel div:nth-child( 1 ) { + z-index: 2; +} + +.ck .ck-fake-panel div:nth-child( 2 ) { + z-index: 1; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-sticky-panel .ck-sticky-panel__content_sticky { + z-index: var(--ck-z-panel); /* #315 */ + position: fixed; + top: 0; + } + +.ck.ck-sticky-panel .ck-sticky-panel__content_sticky_bottom-limit { + top: auto; + position: absolute; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-autocomplete { + position: relative; +} + +.ck.ck-autocomplete > .ck-search__results { + position: absolute; + z-index: var(--ck-z-panel); + } + +.ck.ck-autocomplete > .ck-search__results.ck-search__results_n { + bottom: 100%; + } + +.ck.ck-autocomplete > .ck-search__results.ck-search__results_s { + top: 100%; + bottom: auto; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-search > .ck-labeled-field-view > .ck-labeled-field-view__input-wrapper > .ck-icon { + position: absolute; + top: 50%; + transform: translateY(-50%); + } + +[dir="ltr"] .ck.ck-search > .ck-labeled-field-view > .ck-labeled-field-view__input-wrapper > .ck-icon { + left: var(--ck-spacing-medium); + } + +[dir="rtl"] .ck.ck-search > .ck-labeled-field-view > .ck-labeled-field-view__input-wrapper > .ck-icon { + right: var(--ck-spacing-medium); + } + +.ck.ck-search > .ck-labeled-field-view .ck-search__reset { + position: absolute; + top: 50%; + transform: translateY(-50%); + } + +.ck.ck-search > .ck-search__results > .ck-search__info > span:first-child { + display: block; + } + +/* Hide the filtered view when nothing was found */ + +.ck.ck-search > .ck-search__results > .ck-search__info:not(.ck-hidden) ~ * { + display: none; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-highlighted-text mark { + background: var(--ck-color-highlight-background); + vertical-align: initial; + font-weight: inherit; + line-height: inherit; + font-size: inherit; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/** + * Makes element unselectable. + */ + +.ck.ck-balloon-panel.ck-tooltip { + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + + z-index: calc( var(--ck-z-dialog) + 100 ); +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-toolbar-spinner-size: 18px; +} + +.ck.ck-spinner-container { + display: block; + position: relative; +} + +.ck.ck-spinner { + position: absolute; + top: 50%; + left: 0; + right: 0; + margin: 0 auto; + transform: translateY(-50%); + z-index: 1; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/** + * Makes element unselectable. + */ + +.ck.ck-toolbar { + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + + display: flex; + flex-flow: row nowrap; + align-items: center; +} + +.ck.ck-toolbar > .ck-toolbar__items { + display: flex; + flex-flow: row wrap; + align-items: center; + flex-grow: 1; + + } + +.ck.ck-toolbar .ck.ck-toolbar__separator { + display: inline-block; + + /* + * A leading or trailing separator makes no sense (separates from nothing on one side). + * For instance, it can happen when toolbar items (also separators) are getting grouped one by one and + * moved to another toolbar in the dropdown. + */ + } + +.ck.ck-toolbar .ck.ck-toolbar__separator:first-child, + .ck.ck-toolbar .ck.ck-toolbar__separator:last-child { + display: none; + } + +.ck.ck-toolbar .ck-toolbar__line-break { + flex-basis: 100%; + } + +.ck.ck-toolbar.ck-toolbar_grouping > .ck-toolbar__items { + flex-wrap: nowrap; + } + +.ck.ck-toolbar.ck-toolbar_vertical > .ck-toolbar__items { + flex-direction: column; + } + +.ck.ck-toolbar.ck-toolbar_floating > .ck-toolbar__items { + flex-wrap: nowrap; + } + +.ck.ck-toolbar > .ck.ck-toolbar__grouped-dropdown > .ck-dropdown__button .ck-dropdown__arrow { + display: none; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-block-toolbar-button { + position: absolute; + z-index: var(--ck-z-default); +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-menu-bar__menu > .ck-menu-bar__menu__button > .ck-menu-bar__menu__button__arrow { + pointer-events: none; + z-index: var(--ck-z-default); + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-menu-bar-menu-max-width: 75vw; + --ck-menu-bar-nested-menu-horizontal-offset: 5px; +} + +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel { + z-index: var(--ck-z-panel); + max-width: var(--ck-menu-bar-menu-max-width); + position: absolute; +} + +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_ne, + .ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_nw { + bottom: 100%; + } + +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_se, + .ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_sw { + top: 100%; + bottom: auto; + } + +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_ne, + .ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_se { + left: 0px; + } + +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_nw, + .ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_sw { + right: 0px; + } + +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_es, + .ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_en { + left: calc( 100% - var(--ck-menu-bar-nested-menu-horizontal-offset) ); + } + +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_es { + top: 0px; + } + +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_en { + bottom: 0px; + } + +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_ws, + .ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_wn { + right: calc( 100% - var(--ck-menu-bar-nested-menu-horizontal-offset) ); + } + +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_ws { + top: 0px; + } + +.ck.ck-menu-bar__menu > .ck.ck-menu-bar__menu__panel.ck-menu-bar__menu__panel_position_wn { + bottom: 0px; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck.ck-menu-bar__menu { + display: block; + position: relative; +} + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +:root { + --ck-color-resizer: var(--ck-color-focus-border); + --ck-color-resizer-tooltip-background: hsl(0, 0%, 15%); + --ck-color-resizer-tooltip-text: hsl(0, 0%, 95%); + + --ck-resizer-border-radius: var(--ck-border-radius); + --ck-resizer-tooltip-offset: 10px; + --ck-resizer-tooltip-height: calc(var(--ck-spacing-small) * 2 + 10px); +} + +.ck .ck-widget { + /* This is neccessary for type around UI to be positioned properly. */ + position: relative; +} + +.ck .ck-widget.ck-widget_with-selection-handle { + /* Make the widget wrapper a relative positioning container for the drag handle. */ + position: relative; +} + +.ck .ck-widget.ck-widget_with-selection-handle .ck-widget__selection-handle { + position: absolute; + } + +.ck .ck-widget.ck-widget_with-selection-handle .ck-widget__selection-handle .ck-icon { + /* Make sure the icon in not a subject to font-size or line-height to avoid + unnecessary spacing around it. */ + display: block; + } + +/* Show the selection handle on mouse hover over the widget, but not for nested widgets. */ + +.ck .ck-widget.ck-widget_with-selection-handle:hover > .ck-widget__selection-handle { + visibility: visible; + } + +/* Show the selection handle when the widget is selected, but not for nested widgets. */ + +.ck .ck-widget.ck-widget_with-selection-handle.ck-widget_selected > .ck-widget__selection-handle { + visibility: visible; + } + +.ck .ck-size-view { + background: var(--ck-color-resizer-tooltip-background); + color: var(--ck-color-resizer-tooltip-text); + border: 1px solid var(--ck-color-resizer-tooltip-text); + border-radius: var(--ck-resizer-border-radius); + font-size: var(--ck-font-size-tiny); + display: block; + padding: 0 var(--ck-spacing-small); + height: var(--ck-resizer-tooltip-height); + line-height: var(--ck-resizer-tooltip-height); +} + +.ck .ck-size-view.ck-orientation-top-left, + .ck .ck-size-view.ck-orientation-top-right, + .ck .ck-size-view.ck-orientation-bottom-right, + .ck .ck-size-view.ck-orientation-bottom-left, + .ck .ck-size-view.ck-orientation-above-center { + position: absolute; + } + +.ck .ck-size-view.ck-orientation-top-left { + top: var(--ck-resizer-tooltip-offset); + left: var(--ck-resizer-tooltip-offset); + } + +.ck .ck-size-view.ck-orientation-top-right { + top: var(--ck-resizer-tooltip-offset); + right: var(--ck-resizer-tooltip-offset); + } + +.ck .ck-size-view.ck-orientation-bottom-right { + bottom: var(--ck-resizer-tooltip-offset); + right: var(--ck-resizer-tooltip-offset); + } + +.ck .ck-size-view.ck-orientation-bottom-left { + bottom: var(--ck-resizer-tooltip-offset); + left: var(--ck-resizer-tooltip-offset); + } + +/* Class applied if the widget is too small to contain the size label */ + +.ck .ck-size-view.ck-orientation-above-center { + top: calc(var(--ck-resizer-tooltip-height) * -1); + left: 50%; + transform: translate(-50%); + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +.ck .ck-widget_with-resizer { + /* Make the widget wrapper a relative positioning container for the drag handle. */ + position: relative; +} + +.ck .ck-widget__resizer { + display: none; + position: absolute; + + /* The wrapper itself should not interfere with the pointer device, only the handles should. */ + pointer-events: none; + + left: 0; + top: 0; +} + +.ck-focused .ck-widget_with-resizer.ck-widget_selected > .ck-widget__resizer { + display: block; + } + +.ck .ck-widget__resizer__handle { + position: absolute; + + /* Resizers are the only UI elements that should interfere with a pointer device. */ + pointer-events: all; +} + +.ck .ck-widget__resizer__handle.ck-widget__resizer__handle-top-left, + .ck .ck-widget__resizer__handle.ck-widget__resizer__handle-bottom-right { + cursor: nwse-resize; + } + +.ck .ck-widget__resizer__handle.ck-widget__resizer__handle-top-right, + .ck .ck-widget__resizer__handle.ck-widget__resizer__handle-bottom-left { + cursor: nesw-resize; + } + +/* + * Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/* + * Styles of the type around buttons + */ + +.ck .ck-widget .ck-widget__type-around__button { + display: block; + position: absolute; + overflow: hidden; + z-index: var(--ck-z-default); + } + +.ck .ck-widget .ck-widget__type-around__button svg { + position: absolute; + top: 50%; + left: 50%; + z-index: calc(var(--ck-z-default) + 2); + } + +.ck .ck-widget .ck-widget__type-around__button.ck-widget__type-around__button_before { + /* Place it in the middle of the outline */ + top: calc(-0.5 * var(--ck-widget-outline-thickness)); + left: min(10%, 30px); + + transform: translateY(-50%); + } + +.ck .ck-widget .ck-widget__type-around__button.ck-widget__type-around__button_after { + /* Place it in the middle of the outline */ + bottom: calc(-0.5 * var(--ck-widget-outline-thickness)); + right: min(10%, 30px); + + transform: translateY(50%); + } + +/* + * Styles for the buttons when: + * - the widget is selected, + * - or the button is being hovered (regardless of the widget state). + */ + +.ck .ck-widget.ck-widget_selected > .ck-widget__type-around > .ck-widget__type-around__button::after, .ck .ck-widget > .ck-widget__type-around > .ck-widget__type-around__button:hover::after { + content: ""; + display: block; + position: absolute; + top: 1px; + left: 1px; + z-index: calc(var(--ck-z-default) + 1); + } + +/* + * Styles for the horizontal "fake caret" which is displayed when the user navigates using the keyboard. + */ + +.ck .ck-widget > .ck-widget__type-around > .ck-widget__type-around__fake-caret { + display: none; + position: absolute; + left: 0; + right: 0; + } + +/* + * When the widget is hovered the "fake caret" would normally be narrower than the + * extra outline displayed around the widget. Let's extend the "fake caret" to match + * the full width of the widget. + */ + +.ck .ck-widget:hover > .ck-widget__type-around > .ck-widget__type-around__fake-caret { + left: calc( -1 * var(--ck-widget-outline-thickness) ); + right: calc( -1 * var(--ck-widget-outline-thickness) ); + } + +/* + * Styles for the horizontal "fake caret" when it should be displayed before the widget (backward keyboard navigation). + */ + +.ck .ck-widget.ck-widget_type-around_show-fake-caret_before > .ck-widget__type-around > .ck-widget__type-around__fake-caret { + top: calc( -1 * var(--ck-widget-outline-thickness) - 1px ); + display: block; + } + +/* + * Styles for the horizontal "fake caret" when it should be displayed after the widget (forward keyboard navigation). + */ + +.ck .ck-widget.ck-widget_type-around_show-fake-caret_after > .ck-widget__type-around > .ck-widget__type-around__fake-caret { + bottom: calc( -1 * var(--ck-widget-outline-thickness) - 1px ); + display: block; + } + +/* + * Integration with the read-only mode of the editor. + */ +.ck.ck-editor__editable.ck-read-only .ck-widget__type-around { + display: none; +} + +/* + * Integration with the restricted editing mode (feature) of the editor. + */ +.ck.ck-editor__editable.ck-restricted-editing_mode_restricted .ck-widget__type-around { + display: none; +} + +/* + * Integration with the #isEnabled property of the WidgetTypeAround plugin. + */ +.ck.ck-editor__editable.ck-widget__type-around_disabled .ck-widget__type-around { + display: none; +} + diff --git a/plugins/_bundled/sirsoft-ckeditor5/dist/vendor/ckeditor5/43.3.1/ckeditor5.umd.js b/plugins/_bundled/sirsoft-ckeditor5/dist/vendor/ckeditor5/43.3.1/ckeditor5.umd.js new file mode 100644 index 00000000..58317368 --- /dev/null +++ b/plugins/_bundled/sirsoft-ckeditor5/dist/vendor/ckeditor5/43.3.1/ckeditor5.umd.js @@ -0,0 +1,583 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.CKEDITOR = {})); +})(this, (function (exports) { 'use strict'; + + /** + * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + function e(e,t){return t.forEach((function(t){t&&"string"!=typeof t&&!Array.isArray(t)&&Object.keys(t).forEach((function(i){if("default"!==i&&!(i in e)){var n=Object.getOwnPropertyDescriptor(t,i);Object.defineProperty(e,i,n.get?n:{enumerable:!0,get:function(){return t[i]}});}}));})),Object.freeze(e)}let t;try{t={window:window,document:document};}catch(e){t={window:{},document:{}};}var i=t;function n(){try{return navigator.userAgent.toLowerCase()}catch(e){return ""}}const s=n(),o={isMac:r(s),isWindows:a(s),isGecko:l(s),isSafari:c(s),isiOS:d(s),isAndroid:u(s),isBlink:h(s),get isMediaForcedColors(){return !!i.window.matchMedia&&i.window.matchMedia("(forced-colors: active)").matches},get isMotionReduced(){return !!i.window.matchMedia&&i.window.matchMedia("(prefers-reduced-motion)").matches},features:{isRegExpUnicodePropertySupported:m()}};function r(e){return e.indexOf("macintosh")>-1}function a(e){return e.indexOf("windows")>-1}function l(e){return !!e.match(/gecko\/\d+/)}function c(e){return e.indexOf(" applewebkit/")>-1&&-1===e.indexOf("chrome")}function d(e){return !!e.match(/iphone|ipad/i)||r(e)&&navigator.maxTouchPoints>0}function u(e){return e.indexOf("android")>-1}function h(e){return e.indexOf("chrome/")>-1&&e.indexOf("edge/")<0}function m(){let e=!1;try{e=0==="ć".search(new RegExp("[\\p{L}]","u"));}catch(e){}return e}function g(e,t,i,n){i=i||function(e,t){return e===t};const s=Array.isArray(e)?e:Array.prototype.slice.call(e),o=Array.isArray(t)?t:Array.prototype.slice.call(t),r=function(e,t,i){const n=f(e,t,i);if(-1===n)return {firstIndex:-1,lastIndexOld:-1,lastIndexNew:-1};const s=p(e,n),o=p(t,n),r=f(s,o,i),a=e.length-r,l=t.length-r;return {firstIndex:n,lastIndexOld:a,lastIndexNew:l}}(s,o,i),a=n?function(e,t){const{firstIndex:i,lastIndexOld:n,lastIndexNew:s}=e;if(-1===i)return Array(t).fill("equal");let o=[];i>0&&(o=o.concat(Array(i).fill("equal")));s-i>0&&(o=o.concat(Array(s-i).fill("insert")));n-i>0&&(o=o.concat(Array(n-i).fill("delete")));s0&&i.push({index:n,type:"insert",values:e.slice(n,o)});s-n>0&&i.push({index:n+(o-n),type:"delete",howMany:s-n});return i}(o,r);return a}function f(e,t,i){for(let n=0;n200||s>200||n+s>300)return b.fastDiff(e,t,i,!0);let o,r;if(sc?-1:1;d[n+h]&&(d[n]=d[n+h].slice(0)),d[n]||(d[n]=[]),d[n].push(s>c?o:r);let m=Math.max(s,c),g=m-n;for(;gc;m--)u[m]=h(m);u[c]=h(c),g++;}while(u[c]!==l);return d[c].slice(1)}function w(e,t){const i=[];let n=0,s=null;return e.forEach((e=>{"equal"==e?(o(),n++):"insert"==e?(s&&"insert"==s.type?s.values.push(t[n]):(o(),s={type:"insert",index:n,values:[t[n]]}),n++):s&&"delete"==s.type?s.howMany++:(o(),s={type:"delete",index:n,howMany:1});})),o(),i;function o(){s&&(i.push(s),s=null);}}function _(e,...t){t.forEach((t=>{const i=Object.getOwnPropertyNames(t),n=Object.getOwnPropertySymbols(t);i.concat(n).forEach((i=>{if(i in e.prototype)return;if("function"==typeof t&&("length"==i||"name"==i||"prototype"==i))return;const n=Object.getOwnPropertyDescriptor(t,i);n.enumerable=!1,Object.defineProperty(e.prototype,i,n);}));}));}b.fastDiff=g;class v{source;name;path;stop;off;return;constructor(e,t){this.source=e,this.name=t,this.path=[],this.stop=function e(){e.called=!0;},this.off=function e(){e.called=!0;};}}const y=new Array(256).fill("").map(((e,t)=>("0"+t.toString(16)).slice(-2)));function k(){const[e,t,i,n]=crypto.getRandomValues(new Uint32Array(4));return "e"+y[255&e]+y[e>>8&255]+y[e>>16&255]+y[e>>24&255]+y[255&t]+y[t>>8&255]+y[t>>16&255]+y[t>>24&255]+y[255&i]+y[i>>8&255]+y[i>>16&255]+y[i>>24&255]+y[255&n]+y[n>>8&255]+y[n>>16&255]+y[n>>24&255]}const C={get(e="normal"){return "number"!=typeof e?this[e]||this.normal:e},highest:1e5,high:1e3,normal:0,low:-1e3,lowest:-1e5};function x(e,t){const i=C.get(t.priority);for(let n=0;n{if("object"==typeof t&&null!==t){if(i.has(t))return `[object ${t.constructor.name}]`;i.add(t);}return t},s=t?` ${JSON.stringify(t,n)}`:"",o=P(e);return e+s+o}(e,i)),this.name="CKEditorError",this.context=t,this.data=i;}is(e){return "CKEditorError"===e}static rethrowUnexpectedError(e,t){if(e.is&&e.is("CKEditorError"))throw e;const i=new A(e.message,t);throw i.stack=e.stack,i}}function E(e,t){console.warn(...S(e,t));}function T(e,t){console.error(...S(e,t));}function P(e){return `\nRead more: https://ckeditor.com/docs/ckeditor5/latest/support/error-codes.html#error-${e}`}function S(e,t){const i=P(e);return t?[e,t,i]:[e,i]}const I="43.3.1",V=new Date(2024,10,6);if(globalThis.CKEDITOR_VERSION)throw new A("ckeditor-duplicated-modules",null);globalThis.CKEDITOR_VERSION=I;const R=Symbol("listeningTo"),O=Symbol("emitterId"),B=Symbol("delegations"),M=L(Object);function L(e){if(!e)return M;return class extends e{on(e,t,i){this.listenTo(this,e,t,i);}once(e,t,i){let n=!1;this.listenTo(this,e,((e,...i)=>{n||(n=!0,e.off(),t.call(this,e,...i));}),i);}off(e,t){this.stopListening(this,e,t);}listenTo(e,t,i,n={}){let s,o;this[R]||(this[R]={});const r=this[R];N(e)||F(e);const a=N(e);(s=r[a])||(s=r[a]={emitter:e,callbacks:{}}),(o=s.callbacks[t])||(o=s.callbacks[t]=[]),o.push(i),function(e,t,i,n,s){t._addEventListener?t._addEventListener(i,n,s):e._addEventListener.call(t,i,n,s);}(this,e,t,i,n);}stopListening(e,t,i){const n=this[R];let s=e&&N(e);const o=n&&s?n[s]:void 0,r=o&&t?o.callbacks[t]:void 0;if(!(!n||e&&!o||t&&!r))if(i){U(this,e,t,i);-1!==r.indexOf(i)&&(1===r.length?delete o.callbacks[t]:U(this,e,t,i));}else if(r){for(;i=r.pop();)U(this,e,t,i);delete o.callbacks[t];}else if(o){for(t in o.callbacks)this.stopListening(e,t);delete n[s];}else {for(s in n)this.stopListening(n[s].emitter);delete this[R];}}fire(e,...t){try{const i=e instanceof v?e:new v(this,e),n=i.name;let s=H(this,n);if(i.path.push(this),s){const e=[i,...t];s=Array.from(s);for(let t=0;t{this[B]||(this[B]=new Map),e.forEach((e=>{const n=this[B].get(e);n?n.set(t,i):this[B].set(e,new Map([[t,i]]));}));}}}stopDelegating(e,t){if(this[B])if(e)if(t){const i=this[B].get(e);i&&i.delete(t);}else this[B].delete(e);else this[B].clear();}_addEventListener(e,t,i){!function(e,t){const i=D(e);if(i[t])return;let n=t,s=null;const o=[];for(;""!==n&&!i[n];)i[n]={callbacks:[],childEvents:[]},o.push(i[n]),s&&i[n].childEvents.push(s),s=n,n=n.substr(0,n.lastIndexOf(":"));if(""!==n){for(const e of o)e.callbacks=i[n].callbacks.slice();i[n].childEvents.push(s);}}(this,e);const n=z(this,e),s={callback:t,priority:C.get(i.priority)};for(const e of n)x(e,s);}_removeEventListener(e,t){const i=z(this,e);for(const e of i)for(let i=0;i-1?H(e,t.substr(0,t.lastIndexOf(":"))):null}function $(e,t,i){for(let[n,s]of e){s?"function"==typeof s&&(s=s(t.name)):s=t.name;const e=new v(t.source,s);e.path=[...t.path],n.fire(e,...i);}}function U(e,t,i,n){t._removeEventListener?t._removeEventListener(i,n):e._removeEventListener.call(t,i,n);}["on","once","off","listenTo","stopListening","fire","delegate","stopDelegating","_addEventListener","_removeEventListener"].forEach((e=>{L[e]=M.prototype[e];}));var W="object"==typeof global&&global&&global.Object===Object&&global,j="object"==typeof self&&self&&self.Object===Object&&self,q=W||j||Function("return this")(),G=q.Symbol,K=Object.prototype,Z=K.hasOwnProperty,J=K.toString,Q=G?G.toStringTag:void 0;var Y=Object.prototype.toString;var X=G?G.toStringTag:void 0;function ee(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":X&&X in Object(e)?function(e){var t=Z.call(e,Q),i=e[Q];try{e[Q]=void 0;var n=!0;}catch(e){}var s=J.call(e);return n&&(t?e[Q]=i:delete e[Q]),s}(e):function(e){return Y.call(e)}(e)}function te(e){return null!=e&&"object"==typeof e}function ie(e){return "symbol"==typeof e||te(e)&&"[object Symbol]"==ee(e)}function ne(e,t){for(var i=-1,n=null==e?0:e.length,s=Array(n);++i0){if(++t>=800)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}(Le?function(e,t){return Le(e,"toString",{configurable:!0,enumerable:!1,value:(i=t,function(){return i}),writable:!0});var i;}:be);var Ne=/^(?:0|[1-9]\d*)$/;function De(e,t){var i=typeof e;return !!(t=null==t?9007199254740991:t)&&("number"==i||"symbol"!=i&&Ne.test(e))&&e>-1&&e%1==0&&e-1&&e%1==0&&e<=9007199254740991}function Ke(e){return null!=e&&Ge(e.length)&&!we(e)}function Ze(e){return qe((function(t,i){var n=-1,s=i.length,o=s>1?i[s-1]:void 0,r=s>2?i[2]:void 0;for(o=e.length>3&&"function"==typeof o?(s--,o):void 0,r&&function(e,t,i){if(!ue(i))return !1;var n=typeof t;return !!("number"==n?Ke(i)&&De(t,i.length):"string"==n&&t in i)&&He(i[t],e)}(i[0],i[1],r)&&(o=s<3?void 0:o,s=1),t=Object(t);++n-1},Bt.prototype.set=function(e,t){var i=this.__data__,n=Rt(i,e);return n<0?(++this.size,i.push([e,t])):i[n][1]=t,this};var Mt=Ie(q,"Map");function Lt(e,t){var i,n,s=e.__data__;return ("string"==(n=typeof(i=t))||"number"==n||"symbol"==n||"boolean"==n?"__proto__"!==i:null===i)?s["string"==typeof t?"string":"hash"]:s.map}function Ft(e){var t=-1,i=null==e?0:e.length;for(this.clear();++ts?0:s+t),(i=i>s?s:i)<0&&(i+=s),s=t>i?0:i-t>>>0,t>>>=0;for(var o=Array(s);++n=s?t:ti(t,i,n)).join(""):e.slice(1);return r[bi]()+a});function _i(e){return function(t){return null==e?void 0:e[t]}}var vi=_i({"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss","Ā":"A","Ă":"A","Ą":"A","ā":"a","ă":"a","ą":"a","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","ć":"c","ĉ":"c","ċ":"c","č":"c","Ď":"D","Đ":"D","ď":"d","đ":"d","Ē":"E","Ĕ":"E","Ė":"E","Ę":"E","Ě":"E","ē":"e","ĕ":"e","ė":"e","ę":"e","ě":"e","Ĝ":"G","Ğ":"G","Ġ":"G","Ģ":"G","ĝ":"g","ğ":"g","ġ":"g","ģ":"g","Ĥ":"H","Ħ":"H","ĥ":"h","ħ":"h","Ĩ":"I","Ī":"I","Ĭ":"I","Į":"I","İ":"I","ĩ":"i","ī":"i","ĭ":"i","į":"i","ı":"i","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","ĸ":"k","Ĺ":"L","Ļ":"L","Ľ":"L","Ŀ":"L","Ł":"L","ĺ":"l","ļ":"l","ľ":"l","ŀ":"l","ł":"l","Ń":"N","Ņ":"N","Ň":"N","Ŋ":"N","ń":"n","ņ":"n","ň":"n","ŋ":"n","Ō":"O","Ŏ":"O","Ő":"O","ō":"o","ŏ":"o","ő":"o","Ŕ":"R","Ŗ":"R","Ř":"R","ŕ":"r","ŗ":"r","ř":"r","Ś":"S","Ŝ":"S","Ş":"S","Š":"S","ś":"s","ŝ":"s","ş":"s","š":"s","Ţ":"T","Ť":"T","Ŧ":"T","ţ":"t","ť":"t","ŧ":"t","Ũ":"U","Ū":"U","Ŭ":"U","Ů":"U","Ű":"U","Ų":"U","ũ":"u","ū":"u","ŭ":"u","ů":"u","ű":"u","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","Ż":"Z","Ž":"Z","ź":"z","ż":"z","ž":"z","IJ":"IJ","ij":"ij","Œ":"Oe","œ":"oe","ʼn":"'n","ſ":"s"}),yi=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,ki=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g");var Ci=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;var xi=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;var Ai="\\ud800-\\udfff",Ei="\\u2700-\\u27bf",Ti="a-z\\xdf-\\xf6\\xf8-\\xff",Pi="A-Z\\xc0-\\xd6\\xd8-\\xde",Si="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",Ii="["+Si+"]",Vi="\\d+",Ri="["+Ei+"]",Oi="["+Ti+"]",Bi="[^"+Ai+Si+Vi+Ei+Ti+Pi+"]",Mi="(?:\\ud83c[\\udde6-\\uddff]){2}",Li="[\\ud800-\\udbff][\\udc00-\\udfff]",Fi="["+Pi+"]",Ni="(?:"+Oi+"|"+Bi+")",Di="(?:"+Fi+"|"+Bi+")",zi="(?:['’](?:d|ll|m|re|s|t|ve))?",Hi="(?:['’](?:D|LL|M|RE|S|T|VE))?",$i="(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?",Ui="[\\ufe0e\\ufe0f]?",Wi=Ui+$i+("(?:\\u200d(?:"+["[^"+Ai+"]",Mi,Li].join("|")+")"+Ui+$i+")*"),ji="(?:"+[Ri,Mi,Li].join("|")+")"+Wi,qi=RegExp([Fi+"?"+Oi+"+"+zi+"(?="+[Ii,Fi,"$"].join("|")+")",Di+"+"+Hi+"(?="+[Ii,Fi+Ni,"$"].join("|")+")",Fi+"?"+Ni+"+"+zi,Fi+"+"+Hi,"\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",Vi,ji].join("|"),"g");function Gi(e,t,i){return e=$t(e),void 0===t?function(e){return xi.test(e)}(e)?function(e){return e.match(qi)||[]}(e):function(e){return e.match(Ci)||[]}(e):e.match(t)||[]}var Ki=RegExp("['’]","g");function Zi(e){var t=this.__data__=new Bt(e);this.size=t.size;}Zi.prototype.clear=function(){this.__data__=new Bt,this.size=0;},Zi.prototype.delete=function(e){var t=this.__data__,i=t.delete(e);return this.size=t.size,i},Zi.prototype.get=function(e){return this.__data__.get(e)},Zi.prototype.has=function(e){return this.__data__.has(e)},Zi.prototype.set=function(e,t){var i=this.__data__;if(i instanceof Bt){var n=i.__data__;if(!Mt||n.length<199)return n.push([e,t]),this.size=++i.size,this;i=this.__data__=new Ft(n);}return i.set(e,t),this.size=i.size,this};var Ji="object"==typeof exports&&exports&&!exports.nodeType&&exports,Qi=Ji&&"object"==typeof module&&module&&!module.nodeType&&module,Yi=Qi&&Qi.exports===Ji?q.Buffer:void 0,Xi=Yi?Yi.allocUnsafe:void 0;function en(e,t){if(t)return e.slice();var i=e.length,n=Xi?Xi(i):new e.constructor(i);return e.copy(n),n}function tn(){return []}var nn=Object.prototype.propertyIsEnumerable,sn=Object.getOwnPropertySymbols,on=sn?function(e){return null==e?[]:(e=Object(e),function(e,t){for(var i=-1,n=null==e?0:e.length,s=0,o=[];++ia))return !1;var c=o.get(e),d=o.get(t);if(c&&d)return c==t&&d==e;var u=-1,h=!0,m=2&i?new jn:void 0;for(o.set(e,t),o.set(t,e);++u=t||i<0||u&&e-c>=o}function f(){var e=bs();if(g(e))return p(e);a=setTimeout(f,function(e){var i=t-(e-l);return u?_s(i,o-(e-c)):i}(e));}function p(e){return a=void 0,h&&n?m(e):(n=s=void 0,r)}function b(){var e=bs(),i=g(e);if(n=arguments,s=this,l=e,i){if(void 0===a)return function(e){return c=e,a=setTimeout(f,t),d?m(e):r}(l);if(u)return clearTimeout(a),a=setTimeout(f,t),m(l)}return void 0===a&&(a=setTimeout(f,t)),r}return t=pe(t)||0,ue(i)&&(d=!!i.leading,o=(u="maxWait"in i)?ws(pe(i.maxWait)||0,t):o,h="trailing"in i?!!i.trailing:h),b.cancel=function(){void 0!==a&&clearTimeout(a),c=0,n=l=s=a=void 0;},b.flush=function(){return void 0===a?r:p(bs())},b}function ys(e,t,i){(void 0!==i&&!He(e[t],i)||void 0===i&&!(t in e))&&ze(e,t,i);}function ks(e,t){if(("constructor"!==t||"function"!=typeof e[t])&&"__proto__"!=t)return e[t]}function Cs(e,t,i,n,s,o,r){var a=ks(e,i),l=ks(t,i),c=r.get(l);if(c)ys(e,i,c);else {var d,u=o?o(a,l,i+"",e,t,r):void 0,h=void 0===u;if(h){var m=se(l),g=!m&&rt(l),f=!m&&!g&>(l);u=l,m||g||f?se(a)?u=a:te(d=a)&&Ke(d)?u=Be(a):g?(h=!1,u=en(l,!0)):f?(h=!1,u=In(l,!0)):u=[]:ei(l)||it(l)?(u=a,it(a)?u=function(e){return We(e,Ct(e))}(a):ue(a)&&!we(a)||(u=Rn(l))):h=!1;}h&&(r.set(l,u),s(u,l,n,o,r),r.delete(l)),ys(e,i,u);}}function xs(e,t,i,n,s){e!==t&&ms(t,(function(o,r){if(s||(s=new Zi),ue(o))Cs(e,t,r,i,xs,n,s);else {var a=n?n(ks(e,r),o,r+"",e,t,s):void 0;void 0===a&&(a=o),ys(e,r,a);}}),Ct);}var As=Ze((function(e,t,i,n){xs(e,t,i,n);}));var Es=_i({"&":"&","<":"<",">":">",'"':""","'":"'"}),Ts=/[&<>"']/g,Ps=RegExp(Ts.source);function Ss(e){return (e=$t(e))&&Ps.test(e)?e.replace(Ts,Es):e}var Is=/[\\^$.*+?()[\]{}|]/g,Vs=RegExp(Is.source);function Rs(e){return (e=$t(e))&&Vs.test(e)?e.replace(Is,"\\$&"):e}function Os(e,t){var i=-1,n=Ke(e)?Array(e.length):[];return ps(e,(function(e,s,o){n[++i]=t(e,s,o);})),n}function Bs(e){return "string"==typeof e||!se(e)&&te(e)&&"[object String]"==ee(e)}function Ms(e){return te(e)&&1===e.nodeType&&!ei(e)}function Ls(e,t){return os(e,t)}var Fs=Ze((function(e,t,i){xs(e,t,i);}));function Ns(e,t){return null==(e=function(e,t){return t.length<2?e:jt(e,ti(t,0,-1))}(e,t=Ut(t,e)))||delete e[Wt((i=t,n=null==i?0:i.length,n?i[n-1]:void 0))];var i,n;}function Ds(e,t,i){return null==e?e:function(e,t,i){if(!ue(e))return e;for(var n=-1,s=(t=Ut(t,e)).length,o=s-1,r=e;null!=r&&++n{this.set(t,e[t]);}),this);Js(this);const i=this[Us];if(e in this&&!i.has(e))throw new A("observable-set-cannot-override",this);Object.defineProperty(this,e,{enumerable:!0,configurable:!0,get:()=>i.get(e),set(t){const n=i.get(e);let s=this.fire(`set:${e}`,e,t,n);void 0===s&&(s=t),n===s&&i.has(e)||(i.set(e,s),this.fire(`change:${e}`,e,s,n));}}),this[e]=t;}bind(...e){if(!e.length||!Xs(e))throw new A("observable-bind-wrong-properties",this);if(new Set(e).size!==e.length)throw new A("observable-bind-duplicate-properties",this);Js(this);const t=this[js];e.forEach((e=>{if(t.has(e))throw new A("observable-bind-rebind",this)}));const i=new Map;return e.forEach((e=>{const n={property:e,to:[]};t.set(e,n),i.set(e,n);})),{to:Qs,toMany:Ys,_observable:this,_bindProperties:e,_to:[],_bindings:i}}unbind(...e){if(!this[Us])return;const t=this[js],i=this[Ws];if(e.length){if(!Xs(e))throw new A("observable-unbind-wrong-properties",this);e.forEach((e=>{const n=t.get(e);n&&(n.to.forEach((([e,t])=>{const s=i.get(e),o=s[t];o.delete(n),o.size||delete s[t],Object.keys(s).length||(i.delete(e),this.stopListening(e,"change"));})),t.delete(e));}));}else i.forEach(((e,t)=>{this.stopListening(t,"change");})),i.clear(),t.clear();}decorate(e){Js(this);const t=this[e];if(!t)throw new A("observablemixin-cannot-decorate-undefined",this,{object:this,methodName:e});this.on(e,((e,i)=>{e.return=t.apply(this,i);})),this[e]=function(...t){return this.fire(e,t)},this[e][Gs]=t,this[qs]||(this[qs]=[]),this[qs].push(e);}stopListening(e,t,i){if(!e&&this[qs]){for(const e of this[qs])this[e]=this[e][Gs];delete this[qs];}super.stopListening(e,t,i);}[Us];[qs];[js];[Ws]}}function Js(e){e[Us]||(Object.defineProperty(e,Us,{value:new Map}),Object.defineProperty(e,Ws,{value:new Map}),Object.defineProperty(e,js,{value:new Map}));}function Qs(...e){const t=function(...e){if(!e.length)throw new A("observable-bind-to-parse-error",null);const t={to:[]};let i;"function"==typeof e[e.length-1]&&(t.callback=e.pop());return e.forEach((e=>{if("string"==typeof e)i.properties.push(e);else {if("object"!=typeof e)throw new A("observable-bind-to-parse-error",null);i={observable:e,properties:[]},t.to.push(i);}})),t}(...e),i=Array.from(this._bindings.keys()),n=i.length;if(!t.callback&&t.to.length>1)throw new A("observable-bind-to-no-callback",this);if(n>1&&t.callback)throw new A("observable-bind-to-extra-callback",this);var s;t.to.forEach((e=>{if(e.properties.length&&e.properties.length!==n)throw new A("observable-bind-to-properties-length",this);e.properties.length||(e.properties=this._bindProperties);})),this._to=t.to,t.callback&&(this._bindings.get(i[0]).callback=t.callback),s=this._observable,this._to.forEach((e=>{const t=s[Ws];let i;t.get(e.observable)||s.listenTo(e.observable,"change",((n,o)=>{i=t.get(e.observable)[o],i&&i.forEach((e=>{eo(s,e.property);}));}));})),function(e){let t;e._bindings.forEach(((i,n)=>{e._to.forEach((s=>{t=s.properties[i.callback?0:e._bindProperties.indexOf(n)],i.to.push([s.observable,t]),function(e,t,i,n){const s=e[Ws],o=s.get(i),r=o||{};r[n]||(r[n]=new Set);r[n].add(t),o||s.set(i,r);}(e._observable,i,s.observable,t);}));}));}(this),this._bindProperties.forEach((e=>{eo(this._observable,e);}));}function Ys(e,t,i){if(this._bindings.size>1)throw new A("observable-bind-to-many-not-one-binding",this);this.to(...function(e,t){const i=e.map((e=>[e,t]));return Array.prototype.concat.apply([],i)}(e,t),i);}function Xs(e){return e.every((e=>"string"==typeof e))}function eo(e,t){const i=e[js].get(t);let n;i.callback?n=i.callback.apply(e,i.to.map((e=>e[0][e[1]]))):(n=i.to[0],n=n[0][n[1]]),Object.prototype.hasOwnProperty.call(e,t)?e[t]=n:e.set(t,n);}["set","bind","unbind","decorate","on","once","off","listenTo","stopListening","fire","delegate","stopDelegating","_addEventListener","_removeEventListener"].forEach((e=>{Zs[e]=Ks.prototype[e];}));class to{_replacedElements;constructor(){this._replacedElements=[];}replace(e,t){this._replacedElements.push({element:e,newElement:t}),e.style.display="none",t&&e.parentNode.insertBefore(t,e.nextSibling);}restore(){this._replacedElements.forEach((({element:e,newElement:t})=>{e.style.display="",t&&t.remove();})),this._replacedElements=[];}}function io(e){let t=new AbortController;function i(...i){return t.abort(),t=new AbortController,e(t.signal,...i)}return i.abort=()=>t.abort(),i}function no(e){let t=0;for(const i of e)t++;return t}function so(e,t){const i=Math.min(e.length,t.length);for(let n=0;n{this._setToTarget(e,n,t[n],i);}));}}function lo(e){return Wn(e,co)}function co(e){return Ms(e)||"function"==typeof e?e:void 0}function uo(e){if(e){if(e.defaultView)return e instanceof e.defaultView.Document;if(e.ownerDocument&&e.ownerDocument.defaultView)return e instanceof e.ownerDocument.defaultView.Node}return !1}function ho(e){const t=Object.prototype.toString.apply(e);return "[object Window]"==t||"[object global]"==t}const mo=go(L());function go(e){if(!e)return mo;return class extends e{listenTo(e,t,i,n={}){if(uo(e)||ho(e)){const s={capture:!!n.useCapture,passive:!!n.usePassive},o=this._getProxyEmitter(e,s)||new fo(e,s);this.listenTo(o,t,i,n);}else super.listenTo(e,t,i,n);}stopListening(e,t,i){if(uo(e)||ho(e)){const n=this._getAllProxyEmitters(e);for(const e of n)this.stopListening(e,t,i);}else super.stopListening(e,t,i);}_getProxyEmitter(e,t){return function(e,t){const i=e[R];return i&&i[t]?i[t].emitter:null}(this,po(e,t))}_getAllProxyEmitters(e){return [{capture:!1,passive:!1},{capture:!1,passive:!0},{capture:!0,passive:!1},{capture:!0,passive:!0}].map((t=>this._getProxyEmitter(e,t))).filter((e=>!!e))}}}["_getProxyEmitter","_getAllProxyEmitters","on","once","off","listenTo","stopListening","fire","delegate","stopDelegating","_addEventListener","_removeEventListener"].forEach((e=>{go[e]=mo.prototype[e];}));class fo extends(L()){_domNode;_options;constructor(e,t){super(),F(this,po(e,t)),this._domNode=e,this._options=t;}_domListeners;attach(e){if(this._domListeners&&this._domListeners[e])return;const t=this._createDomListener(e);this._domNode.addEventListener(e,t,this._options),this._domListeners||(this._domListeners={}),this._domListeners[e]=t;}detach(e){let t;!this._domListeners[e]||(t=this._events[e])&&t.callbacks.length||this._domListeners[e].removeListener();}_addEventListener(e,t,i){this.attach(e),L().prototype._addEventListener.call(this,e,t,i);}_removeEventListener(e,t){L().prototype._removeEventListener.call(this,e,t),this.detach(e);}_createDomListener(e){const t=t=>{this.fire(e,t);};return t.removeListener=()=>{this._domNode.removeEventListener(e,t,this._options),delete this._domListeners[e];},t}}function po(e,t){let i=function(e){return e["data-ck-expando"]||(e["data-ck-expando"]=k())}(e);for(const e of Object.keys(t).sort())t[e]&&(i+="-"+e);return i}function bo(e){let t=e.parentElement;if(!t)return null;for(;"BODY"!=t.tagName;){const e=t.style.overflowY||i.window.getComputedStyle(t).overflowY;if("auto"===e||"scroll"===e)break;if(t=t.parentElement,!t)return null}return t}function wo(e){const t=[];let i=e;for(;i&&i.nodeType!=Node.DOCUMENT_NODE;)t.unshift(i),i=i.parentNode;return t}function _o(e){return e instanceof HTMLTextAreaElement?e.value:e.innerHTML}function vo(e){const t=e.ownerDocument.defaultView.getComputedStyle(e);return {top:parseInt(t.borderTopWidth,10),right:parseInt(t.borderRightWidth,10),bottom:parseInt(t.borderBottomWidth,10),left:parseInt(t.borderLeftWidth,10)}}function yo(e){if(!e.target)return null;const t=e.target.ownerDocument,i=e.clientX,n=e.clientY;let s=null;return t.caretRangeFromPoint&&t.caretRangeFromPoint(i,n)?s=t.caretRangeFromPoint(i,n):e.rangeParent&&(s=t.createRange(),s.setStart(e.rangeParent,e.rangeOffset),s.collapse(!0)),s}function ko(e){return "[object Text]"==Object.prototype.toString.call(e)}function Co(e){return "[object Range]"==Object.prototype.toString.apply(e)}function xo(e){return e&&e.parentNode?e.offsetParent===i.document.body?null:e.offsetParent:null}const Ao=["top","right","bottom","left","width","height"];class Eo{top;right;bottom;left;width;height;_source;constructor(e){const t=Co(e);if(Object.defineProperty(this,"_source",{value:e._source||e,writable:!0,enumerable:!1}),So(e)||t)if(t){const t=Eo.getDomRangeRects(e);To(this,Eo.getBoundingRect(t));}else To(this,e.getBoundingClientRect());else if(ho(e)){const{innerWidth:t,innerHeight:i}=e;To(this,{top:0,right:t,bottom:i,left:0,width:t,height:i});}else To(this,e);}clone(){return new Eo(this)}moveTo(e,t){return this.top=t,this.right=e+this.width,this.bottom=t+this.height,this.left=e,this}moveBy(e,t){return this.top+=t,this.right+=e,this.left+=e,this.bottom+=t,this}getIntersection(e){const t={top:Math.max(this.top,e.top),right:Math.min(this.right,e.right),bottom:Math.min(this.bottom,e.bottom),left:Math.max(this.left,e.left),width:0,height:0};if(t.width=t.right-t.left,t.height=t.bottom-t.top,t.width<0||t.height<0)return null;{const e=new Eo(t);return e._source=this._source,e}}getIntersectionArea(e){const t=this.getIntersection(e);return t?t.getArea():0}getArea(){return this.width*this.height}getVisible(){const e=this._source;let t=this.clone();if(Po(e))return t;let i,n=e,s=e.parentNode||e.commonAncestorContainer;for(;s&&!Po(s);){const e="visible"===((o=s)instanceof HTMLElement?o.ownerDocument.defaultView.getComputedStyle(o).overflow:"visible");n instanceof HTMLElement&&"absolute"===Io(n)&&(i=n);const r=Io(s);if(e||i&&("relative"===r&&e||"relative"!==r)){n=s,s=s.parentNode;continue}const a=new Eo(s),l=t.getIntersection(a);if(!l)return null;l.getArea(){for(const t of e){const e=Vo._getElementCallbacks(t.target);if(e)for(const i of e)i(t);}}));}}function Ro(e,t){e instanceof HTMLTextAreaElement&&(e.value=t),e.innerHTML=t;}function Oo(e){return t=>t+e}function Bo(e){let t=0;for(;e.previousSibling;)e=e.previousSibling,t++;return t}function Mo(e,t,i){e.insertBefore(i,e.childNodes[t]||null);}function Lo(e){return e&&e.nodeType===Node.COMMENT_NODE}function Fo(e){try{i.document.createAttribute(e);}catch(e){return !1}return !0}function No(e){return !!e&&(ko(e)?No(e.parentElement):!!e.getClientRects&&!!e.getClientRects().length)}function Do({element:e,target:t,positions:n,limiter:s,fitInViewport:o,viewportOffsetConfig:r}){we(t)&&(t=t()),we(s)&&(s=s());const a=xo(e),l=function(e){e=Object.assign({top:0,bottom:0,left:0,right:0},e);const t=new Eo(i.window);return t.top+=e.top,t.height-=e.top,t.bottom-=e.bottom,t.height-=e.bottom,t}(r),c=new Eo(e),d=zo(t,l);let u;if(!d||!l.getIntersection(d))return null;const h={targetRect:d,elementRect:c,positionedElementAncestor:a,viewportRect:l};if(s||o){if(s){const e=zo(s,l);e&&(h.limiterRect=e);}u=function(e,t){const{elementRect:i}=t,n=i.getArea(),s=e.map((e=>new Ho(e,t))).filter((e=>!!e.name));let o=0,r=null;for(const e of s){const{limiterIntersectionArea:t,viewportIntersectionArea:i}=e;if(t===n)return e;const s=i**2+t**2;s>o&&(o=s,r=e);}return r}(n,h);}else u=new Ho(n[0],h);return u}function zo(e,t){const i=new Eo(e).getVisible();return i?i.getIntersection(t):null}class Ho{name;config;_positioningFunctionCoordinates;_options;_cachedRect;_cachedAbsoluteRect;constructor(e,t){const i=e(t.targetRect,t.elementRect,t.viewportRect,t.limiterRect);if(!i)return;const{left:n,top:s,name:o,config:r}=i;this.name=o,this.config=r,this._positioningFunctionCoordinates={left:n,top:s},this._options=t;}get left(){return this._absoluteRect.left}get top(){return this._absoluteRect.top}get limiterIntersectionArea(){const e=this._options.limiterRect;return e?e.getIntersectionArea(this._rect):0}get viewportIntersectionArea(){return this._options.viewportRect.getIntersectionArea(this._rect)}get _rect(){return this._cachedRect||(this._cachedRect=this._options.elementRect.clone().moveTo(this._positioningFunctionCoordinates.left,this._positioningFunctionCoordinates.top)),this._cachedRect}get _absoluteRect(){return this._cachedAbsoluteRect||(this._cachedAbsoluteRect=this._rect.toAbsoluteRect()),this._cachedAbsoluteRect}}function $o(e){const t=e.parentNode;t&&t.removeChild(e);}function Uo({target:e,viewportOffset:t=0,ancestorOffset:i=0,alignToTop:n,forceScroll:s}){const o=Qo(e);let r=o,a=null;for(t=function(e){if("number"==typeof e)return {top:e,bottom:e,left:e,right:e};return e}(t);r;){let l;l=Yo(r==o?e:a),qo({parent:l,getRect:()=>Xo(e,r),alignToTop:n,ancestorOffset:i,forceScroll:s});const c=Xo(e,r);if(jo({window:r,rect:c,viewportOffset:t,alignToTop:n,forceScroll:s}),r.parent!=r){if(a=r.frameElement,r=r.parent,!a)return}else r=null;}}function Wo(e,t,i){qo({parent:Yo(e),getRect:()=>new Eo(e),ancestorOffset:t,limiterElement:i});}function jo({window:e,rect:t,alignToTop:i,forceScroll:n,viewportOffset:s}){const o=t.clone().moveBy(0,s.bottom),r=t.clone().moveBy(0,-s.top),a=new Eo(e).excludeScrollbarsAndBorders(),l=i&&n,c=[r,o].every((e=>a.contains(e)));let{scrollX:d,scrollY:u}=e;const h=d,m=u;l?u-=a.top-t.top+s.top:c||(Ko(r,a)?u-=a.top-t.top+s.top:Go(o,a)&&(u+=i?t.top-a.top-s.top:t.bottom-a.bottom+s.bottom)),c||(Zo(t,a)?d-=a.left-t.left+s.left:Jo(t,a)&&(d+=t.right-a.right+s.right)),d==h&&u===m||e.scrollTo(d,u);}function qo({parent:e,getRect:t,alignToTop:i,forceScroll:n,ancestorOffset:s=0,limiterElement:o}){const r=Qo(e),a=i&&n;let l,c,d;const u=o||r.document.body;for(;e!=u;)c=t(),l=new Eo(e).excludeScrollbarsAndBorders(),d=l.contains(c),a?e.scrollTop-=l.top-c.top+s:d||(Ko(c,l)?e.scrollTop-=l.top-c.top+s:Go(c,l)&&(e.scrollTop+=i?c.top-l.top-s:c.bottom-l.bottom+s)),d||(Zo(c,l)?e.scrollLeft-=l.left-c.left+s:Jo(c,l)&&(e.scrollLeft+=c.right-l.right+s)),e=e.parentNode;}function Go(e,t){return e.bottom>t.bottom}function Ko(e,t){return e.topt.right}function Qo(e){return Co(e)?e.startContainer.ownerDocument.defaultView:e.ownerDocument.defaultView}function Yo(e){if(Co(e)){let t=e.commonAncestorContainer;return ko(t)&&(t=t.parentNode),t}return e.parentNode}function Xo(e,t){const i=Qo(e),n=new Eo(e);if(i===t)return n;{let e=i;for(;e!=t;){const t=e.frameElement,i=new Eo(t).excludeScrollbarsAndBorders();n.moveBy(i.left,i.top),e=e.parent;}}return n}const er={ctrl:"⌃",cmd:"⌘",alt:"⌥",shift:"⇧"},tr={ctrl:"Ctrl+",alt:"Alt+",shift:"Shift+"},ir={37:"←",38:"↑",39:"→",40:"↓",9:"⇥",33:"Page Up",34:"Page Down"},nr=ur(),sr=Object.fromEntries(Object.entries(nr).map((([e,t])=>{let i;return i=t in ir?ir[t]:e.charAt(0).toUpperCase()+e.slice(1),[t,i]})));function or(e){let t;if("string"==typeof e){if(t=nr[e.toLowerCase()],!t)throw new A("keyboard-unknown-key",null,{key:e})}else t=e.keyCode+(e.altKey?nr.alt:0)+(e.ctrlKey?nr.ctrl:0)+(e.shiftKey?nr.shift:0)+(e.metaKey?nr.cmd:0);return t}function rr(e){return "string"==typeof e&&(e=function(e){return e.split("+").map((e=>e.trim()))}(e)),e.map((e=>"string"==typeof e?function(e){if(e.endsWith("!"))return or(e.slice(0,-1));const t=or(e);return (o.isMac||o.isiOS)&&t==nr.ctrl?nr.cmd:t}(e):e)).reduce(((e,t)=>t+e),0)}function ar(e){let t=rr(e);return Object.entries(o.isMac||o.isiOS?er:tr).reduce(((e,[i,n])=>(t&nr[i]&&(t&=~nr[i],e+=n),e)),"")+(t?sr[t]:"")}function lr(e){return e==nr.arrowright||e==nr.arrowleft||e==nr.arrowup||e==nr.arrowdown}function cr(e,t){const i="ltr"===t;switch(e){case nr.arrowleft:return i?"left":"right";case nr.arrowright:return i?"right":"left";case nr.arrowup:return "up";case nr.arrowdown:return "down"}}function dr(e,t){const i=cr(e,t);return "down"===i||"right"===i}function ur(){const e={pageup:33,pagedown:34,arrowleft:37,arrowup:38,arrowright:39,arrowdown:40,backspace:8,delete:46,enter:13,space:32,esc:27,tab:9,ctrl:1114112,shift:2228224,alt:4456448,cmd:8912896};for(let t=65;t<=90;t++){e[String.fromCharCode(t).toLowerCase()]=t;}for(let t=48;t<=57;t++)e[t-48]=t;for(let t=112;t<=123;t++)e["f"+(t-111)]=t;return Object.assign(e,{"'":222,",":108,"-":109,".":110,"/":111,";":186,"=":187,"[":219,"\\":220,"]":221,"`":223}),e}const hr=["ar","ara","dv","div","fa","per","fas","he","heb","ku","kur","ug","uig"];function mr(e){return hr.includes(e)?"rtl":"ltr"}function gr(e){return Array.isArray(e)?e:[e]}function fr(e,t,n=1,s){if("number"!=typeof n)throw new A("translation-service-quantity-not-a-number",null,{quantity:n});const o=s||i.window.CKEDITOR_TRANSLATIONS,r=function(e){return Object.keys(e).length}(o);1===r&&(e=Object.keys(o)[0]);const a=t.id||t.string;if(0===r||!function(e,t,i){return !!i[e]&&!!i[e].dictionary[t]}(e,a,o))return 1!==n?t.plural:t.string;const l=o[e].dictionary,c=o[e].getPluralForm||(e=>1===e?0:1),d=l[a];if("string"==typeof d)return d;return d[Number(c(n))]}i.window.CKEDITOR_TRANSLATIONS||(i.window.CKEDITOR_TRANSLATIONS={});class pr{uiLanguage;uiLanguageDirection;contentLanguage;contentLanguageDirection;t;translations;constructor({uiLanguage:e="en",contentLanguage:t,translations:i}={}){this.uiLanguage=e,this.contentLanguage=t||this.uiLanguage,this.uiLanguageDirection=mr(this.uiLanguage),this.contentLanguageDirection=mr(this.contentLanguage),this.translations=function(e){return Array.isArray(e)?e.reduce(((e,t)=>Fs(e,t))):e}(i),this.t=(e,t)=>this._t(e,t);}get language(){return console.warn("locale-deprecated-language-property: The Locale#language property has been deprecated and will be removed in the near future. Please use #uiLanguage and #contentLanguage properties instead."),this.uiLanguage}_t(e,t=[]){t=gr(t),"string"==typeof e&&(e={string:e});const i=!!e.plural?t[0]:1;return function(e,t){return e.replace(/%(\d+)/g,((e,i)=>ithis._items.length||t<0)throw new A("collection-add-item-invalid-index",this);let i=0;for(const n of e){const e=this._getItemIdBeforeAdding(n),s=t+i;this._items.splice(s,0,n),this._itemMap.set(e,n),this.fire("add",n,s),i++;}return this.fire("change",{added:e,removed:[],index:t}),this}get(e){let t;if("string"==typeof e)t=this._itemMap.get(e);else {if("number"!=typeof e)throw new A("collection-get-invalid-arg",this);t=this._items[e];}return t||null}has(e){if("string"==typeof e)return this._itemMap.has(e);{const t=e[this._idProperty];return t&&this._itemMap.has(t)}}getIndex(e){let t;return t="string"==typeof e?this._itemMap.get(e):e,t?this._items.indexOf(t):-1}remove(e){const[t,i]=this._remove(e);return this.fire("change",{added:[],removed:[t],index:i}),t}map(e,t){return this._items.map(e,t)}forEach(e,t){this._items.forEach(e,t);}find(e,t){return this._items.find(e,t)}filter(e,t){return this._items.filter(e,t)}clear(){this._bindToCollection&&(this.stopListening(this._bindToCollection),this._bindToCollection=null);const e=Array.from(this._items);for(;this.length;)this._remove(0);this.fire("change",{added:[],removed:e,index:0});}bindTo(e){if(this._bindToCollection)throw new A("collection-bind-to-rebind",this);return this._bindToCollection=e,{as:e=>{this._setUpBindToBinding((t=>new e(t)));},using:e=>{"function"==typeof e?this._setUpBindToBinding(e):this._setUpBindToBinding((t=>t[e]));}}}_setUpBindToBinding(e){const t=this._bindToCollection,i=(i,n,s)=>{const o=t._bindToCollection==this,r=t._bindToInternalToExternalMap.get(n);if(o&&r)this._bindToExternalToInternalMap.set(n,r),this._bindToInternalToExternalMap.set(r,n);else {const i=e(n);if(!i)return void this._skippedIndexesFromExternal.push(s);let o=s;for(const e of this._skippedIndexesFromExternal)s>e&&o--;for(const e of t._skippedIndexesFromExternal)o>=e&&o++;this._bindToExternalToInternalMap.set(n,i),this._bindToInternalToExternalMap.set(i,n),this.add(i,o);for(let e=0;e{const n=this._bindToExternalToInternalMap.get(t);n&&this.remove(n),this._skippedIndexesFromExternal=this._skippedIndexesFromExternal.reduce(((e,t)=>(it&&e.push(t),e)),[]);}));}_getItemIdBeforeAdding(e){const t=this._idProperty;let i;if(t in e){if(i=e[t],"string"!=typeof i)throw new A("collection-add-invalid-id",this);if(this.get(i))throw new A("collection-add-item-already-exists",this)}else e[t]=i=k();return i}_remove(e){let t,i,n,s=!1;const o=this._idProperty;if("string"==typeof e?(i=e,n=this._itemMap.get(i),s=!n,n&&(t=this._items.indexOf(n))):"number"==typeof e?(t=e,n=this._items[t],s=!n,n&&(i=n[o])):(n=e,i=n[o],t=this._items.indexOf(n),s=-1==t||!this._itemMap.get(i)),s)throw new A("collection-remove-404",this);this._items.splice(t,1),this._itemMap.delete(i);const r=this._bindToInternalToExternalMap.get(n);return this._bindToInternalToExternalMap.delete(n),this._bindToExternalToInternalMap.delete(r),this.fire("remove",n,t),[n,t]}[Symbol.iterator](){return this._items[Symbol.iterator]()}}function wr(e){const t=e.next();return t.done?null:t.value}class _r extends(go(Zs())){_elements=new Set;_externalViews=new Set;_blurTimeout=null;constructor(){super(),this.set("isFocused",!1),this.set("focusedElement",null);}get elements(){return Array.from(this._elements.values())}get externalViews(){return Array.from(this._externalViews.values())}add(e){if(yr(e))this._addElement(e);else if(vr(e))this._addView(e);else {if(!e.element)throw new A("focustracker-add-view-missing-element",{focusTracker:this,view:e});this._addElement(e.element);}}remove(e){yr(e)?this._removeElement(e):vr(e)?this._removeView(e):this._removeElement(e.element);}_addElement(e){if(this._elements.has(e))throw new A("focustracker-add-element-already-exist",this);this.listenTo(e,"focus",(()=>{const t=this.externalViews.find((t=>function(e,t){if(kr(e,t))return !0;return !!t.focusTracker.externalViews.find((t=>kr(e,t)))}(e,t)));t?this._focus(t.element):this._focus(e);}),{useCapture:!0}),this.listenTo(e,"blur",(()=>{this._blur();}),{useCapture:!0}),this._elements.add(e);}_removeElement(e){this._elements.has(e)&&(this.stopListening(e),this._elements.delete(e)),e===this.focusedElement&&this._blur();}_addView(e){e.element&&this._addElement(e.element),this.listenTo(e.focusTracker,"change:focusedElement",(()=>{e.focusTracker.focusedElement?e.element&&this._focus(e.element):this._blur();})),this._externalViews.add(e);}_removeView(e){e.element&&this._removeElement(e.element),this.stopListening(e.focusTracker),this._externalViews.delete(e);}destroy(){this.stopListening(),this._elements.clear(),this._externalViews.clear(),this.isFocused=!1,this.focusedElement=null;}_focus(e){this._clearBlurTimeout(),this.focusedElement=e,this.isFocused=!0;}_blur(){if(this.elements.find((e=>e.contains(document.activeElement))))return;this.externalViews.find((e=>e.focusTracker.isFocused&&!e.focusTracker._blurTimeout))||(this._clearBlurTimeout(),this._blurTimeout=setTimeout((()=>{this.focusedElement=null,this.isFocused=!1;}),0));}_clearBlurTimeout(){clearTimeout(this._blurTimeout),this._blurTimeout=null;}}function vr(e){return "focusTracker"in e&&e.focusTracker instanceof _r}function yr(e){return Ms(e)}function kr(e,t){return !!t.element&&t.element.contains(document.activeElement)&&e.contains(t.element)}class Cr{_listener;constructor(){this._listener=new(go());}listenTo(e){this._listener.listenTo(e,"keydown",((e,t)=>{this._listener.fire("_keydown:"+or(t),t);}));}set(e,t,i={}){const n=rr(e),s=i.priority;this._listener.listenTo(this._listener,"_keydown:"+n,((e,n)=>{i.filter&&!i.filter(n)||(t(n,(()=>{n.preventDefault(),n.stopPropagation(),e.stop();})),e.return=!0);}),{priority:s});}press(e){return !!this._listener.fire("_keydown:"+or(e),e)}stopListening(e){this._listener.stopListening(e);}destroy(){this.stopListening();}}function xr(e){return oo(e)?new Map(e):function(e){const t=new Map;for(const i in e)t.set(i,e[i]);return t}(e)}function Ar(e,t={}){return new Promise(((i,n)=>{const s=t.signal||(new AbortController).signal;s.throwIfAborted();const o=setTimeout((function(){s.removeEventListener("abort",r),i();}),e);function r(){clearTimeout(o),n(s.reason);}s.addEventListener("abort",r,{once:!0});}))}async function Er(e,t={}){const{maxAttempts:i=4,retryDelay:n=Tr(),signal:s=(new AbortController).signal}=t;s.throwIfAborted();for(let t=0;;t++){try{return await e()}catch(e){if(t+1>=i)throw e}await Ar(n(t),{signal:s});}}function Tr(e={}){const{delay:t=1e3,factor:i=2,maxDelay:n=1e4}=e;return e=>Math.min(i**e*t,n)}function Pr(e,t,i,n){if(Math.max(t.length,e.length)>1e4)return e.slice(0,i).concat(t).concat(e.slice(i+n,e.length));{const s=Array.from(e);return s.splice(i,n,...t),s}}function Sr(e,t){let i;function n(...s){n.cancel(),i=setTimeout((()=>e(...s)),t);}return n.cancel=()=>{clearTimeout(i);},n}function Ir(e){function t(e){return e.length>=40&&e.length<=255?"VALID":"INVALID"}if(!e)return "INVALID";let i="";try{i=atob(e);}catch(e){return "INVALID"}const n=i.split("-"),s=n[0],o=n[1];if(!o)return t(e);try{atob(o);}catch(i){try{if(atob(s),!atob(s).length)return t(e)}catch(i){return t(e)}}if(s.length<40||s.length>255)return "INVALID";let r="";try{atob(s),r=atob(o);}catch(e){return "INVALID"}if(8!==r.length)return "INVALID";const a=Number(r.substring(0,4)),l=Number(r.substring(4,6))-1,c=Number(r.substring(6,8)),d=new Date(a,l,c);return de.indexe.source)).join("|")+")";return new RegExp(`${e}|${t}(?:‍${t})*`,"ug")}class Dr extends(Zs()){editor;_disableStack=new Set;constructor(e){super(),this.editor=e,this.set("isEnabled",!0);}forceDisabled(e){this._disableStack.add(e),1==this._disableStack.size&&(this.on("set:isEnabled",zr,{priority:"highest"}),this.isEnabled=!1);}clearForceDisabled(e){this._disableStack.delete(e),0==this._disableStack.size&&(this.off("set:isEnabled",zr),this.isEnabled=!0);}destroy(){this.stopListening();}static get isContextPlugin(){return !1}static get isOfficialPlugin(){return !1}static get isPremiumPlugin(){return !1}}function zr(e){e.return=!1,e.stop();}class Hr extends(Zs()){editor;_isEnabledBasedOnSelection;_affectsData;_disableStack;constructor(e){super(),this.editor=e,this.set("value",void 0),this.set("isEnabled",!1),this._affectsData=!0,this._isEnabledBasedOnSelection=!0,this._disableStack=new Set,this.decorate("execute"),this.listenTo(this.editor.model.document,"change",(()=>{this.refresh();})),this.listenTo(e,"change:isReadOnly",(()=>{this.refresh();})),this.on("set:isEnabled",(t=>{if(!this.affectsData)return;const i=e.model.document.selection,n=!("$graveyard"==i.getFirstPosition().root.rootName)&&e.model.canEditAt(i);(e.isReadOnly||this._isEnabledBasedOnSelection&&!n)&&(t.return=!1,t.stop());}),{priority:"highest"}),this.on("execute",(e=>{this.isEnabled||e.stop();}),{priority:"high"});}get affectsData(){return this._affectsData}set affectsData(e){this._affectsData=e;}refresh(){this.isEnabled=!0;}forceDisabled(e){this._disableStack.add(e),1==this._disableStack.size&&(this.on("set:isEnabled",$r,{priority:"highest"}),this.isEnabled=!1);}clearForceDisabled(e){this._disableStack.delete(e),0==this._disableStack.size&&(this.off("set:isEnabled",$r),this.refresh());}execute(...e){}destroy(){this.stopListening();}}function $r(e){e.return=!1,e.stop();}class Ur extends Hr{_childCommandsDefinitions=[];refresh(){}execute(...e){const t=this._getFirstEnabledCommand();return !!t&&t.execute(e)}registerChildCommand(e,t={}){x(this._childCommandsDefinitions,{command:e,priority:t.priority||"normal"}),e.on("change:isEnabled",(()=>this._checkEnabled())),this._checkEnabled();}_checkEnabled(){this.isEnabled=!!this._getFirstEnabledCommand();}_getFirstEnabledCommand(){const e=this._childCommandsDefinitions.find((({command:e})=>e.isEnabled));return e&&e.command}}class Wr extends(L()){_context;_plugins=new Map;_availablePlugins;_contextPlugins;constructor(e,t=[],i=[]){super(),this._context=e,this._availablePlugins=new Map;for(const e of t)e.pluginName&&this._availablePlugins.set(e.pluginName,e);this._contextPlugins=new Map;for(const[e,t]of i)this._contextPlugins.set(e,t),this._contextPlugins.set(t,e),e.pluginName&&this._availablePlugins.set(e.pluginName,e);}*[Symbol.iterator](){for(const e of this._plugins)"function"==typeof e[0]&&(yield e);}get(e){const t=this._plugins.get(e);if(!t){let t=e;throw "function"==typeof e&&(t=e.pluginName||e.name),new A("plugincollection-plugin-not-loaded",this._context,{plugin:t})}return t}has(e){return this._plugins.has(e)}init(e,t=[],i=[]){const n=this,s=this._context;!function e(t,i=new Set){t.forEach((t=>{a(t)&&(i.has(t)||(i.add(t),t.pluginName&&!n._availablePlugins.has(t.pluginName)&&n._availablePlugins.set(t.pluginName,t),t.requires&&e(t.requires,i)));}));}(e),u(e);const o=[...function e(t,i=new Set){return t.map((e=>a(e)?e:n._availablePlugins.get(e))).reduce(((t,n)=>i.has(n)?t:(i.add(n),n.requires&&(u(n.requires,n),e(n.requires,i).forEach((e=>t.add(e)))),t.add(n))),new Set)}(e.filter((e=>!c(e,t))))];!function(e,t){for(const i of t){if("function"!=typeof i)throw new A("plugincollection-replace-plugin-invalid-type",null,{pluginItem:i});const t=i.pluginName;if(!t)throw new A("plugincollection-replace-plugin-missing-name",null,{pluginItem:i});if(i.requires&&i.requires.length)throw new A("plugincollection-plugin-for-replacing-cannot-have-dependencies",null,{pluginName:t});const s=n._availablePlugins.get(t);if(!s)throw new A("plugincollection-plugin-for-replacing-not-exist",null,{pluginName:t});const o=e.indexOf(s);if(-1===o){if(n._contextPlugins.has(s))return;throw new A("plugincollection-plugin-for-replacing-not-loaded",null,{pluginName:t})}if(s.requires&&s.requires.length)throw new A("plugincollection-replaced-plugin-cannot-have-dependencies",null,{pluginName:t});e.splice(o,1,i),n._availablePlugins.set(t,i);}}(o,i);const r=function(e){return e.map((e=>{let t=n._contextPlugins.get(e);return t=t||new e(s),n._add(e,t),t}))}(o);return h(r,"init").then((()=>h(r,"afterInit"))).then((()=>r));function a(e){return "function"==typeof e}function l(e){return a(e)&&!!e.isContextPlugin}function c(e,t){return t.some((t=>t===e||(d(e)===t||d(t)===e)))}function d(e){return a(e)?e.pluginName||e.name:e}function u(e,i=null){e.map((e=>a(e)?e:n._availablePlugins.get(e)||e)).forEach((e=>{!function(e,t){if(a(e))return;if(t)throw new A("plugincollection-soft-required",s,{missingPlugin:e,requiredBy:d(t)});throw new A("plugincollection-plugin-not-found",s,{plugin:e})}(e,i),function(e,t){if(!l(t))return;if(l(e))return;throw new A("plugincollection-context-required",s,{plugin:d(e),requiredBy:d(t)})}(e,i),function(e,i){if(!i)return;if(!c(e,t))return;throw new A("plugincollection-required",s,{plugin:d(e),requiredBy:d(i)})}(e,i);}));}function h(e,t){return e.reduce(((e,i)=>i[t]?n._contextPlugins.has(i)?e:e.then(i[t].bind(i)):e),Promise.resolve())}}destroy(){const e=[];for(const[,t]of this)"function"!=typeof t.destroy||this._contextPlugins.has(t)||e.push(t.destroy());return Promise.all(e)}_add(e,t){this._plugins.set(e,t);const i=e.pluginName;if(i){if(this._plugins.has(i))throw new A("plugincollection-plugin-name-conflict",null,{pluginName:i,plugin1:this._plugins.get(i).constructor,plugin2:e});this._plugins.set(i,t);}}}class jr{config;plugins;locale;t;editors;static defaultConfig;static builtinPlugins;_contextOwner=null;constructor(e){const{translations:t,...i}=e||{};this.config=new ao(i,this.constructor.defaultConfig);const n=this.constructor.builtinPlugins;this.config.define("plugins",n),this.plugins=new Wr(this,n);const s=this.config.get("language")||{};this.locale=new pr({uiLanguage:"string"==typeof s?s:s.ui,contentLanguage:this.config.get("language.content"),translations:t}),this.t=this.locale.t,this.editors=new br;}initPlugins(){const e=this.config.get("plugins")||[],t=this.config.get("substitutePlugins")||[];for(const i of e.concat(t)){if("function"!=typeof i)throw new A("context-initplugins-constructor-only",null,{Plugin:i});if(!0!==i.isContextPlugin)throw new A("context-initplugins-invalid-plugin",null,{Plugin:i})}return this.plugins.init(e,[],t)}destroy(){return Promise.all(Array.from(this.editors,(e=>e.destroy()))).then((()=>this.plugins.destroy()))}_addEditor(e,t){if(this._contextOwner)throw new A("context-addeditor-private-context");this.editors.add(e),t&&(this._contextOwner=e);}_removeEditor(e){return this.editors.has(e)&&this.editors.remove(e),this._contextOwner===e?this.destroy():Promise.resolve()}_getEditorConfig(){const e={};for(const t of this.config.names())["plugins","removePlugins","extraPlugins"].includes(t)||(e[t]=this.config.get(t));return e}static create(e){return new Promise((t=>{const i=new this(e);t(i.initPlugins().then((()=>i)));}))}}class qr extends(Zs()){context;constructor(e){super(),this.context=e;}destroy(){this.stopListening();}static get isContextPlugin(){return !0}static get isOfficialPlugin(){return !1}static get isPremiumPlugin(){return !1}}const Gr=new WeakMap;let Kr=!1;function Zr({view:e,element:t,text:i,isDirectHost:n=!0,keepOnFocus:s=!1}){const o=e.document;function r(i){Gr.get(o).set(t,{text:i,isDirectHost:n,keepOnFocus:s,hostElement:n?t:null}),e.change((e=>ea(o,e)));}Gr.has(o)||(Gr.set(o,new Map),o.registerPostFixer((e=>ea(o,e))),o.on("change:isComposing",(()=>{e.change((e=>ea(o,e)));}),{priority:"high"})),t.is("editableElement")&&t.on("change:placeholder",((e,t,i)=>{r(i);})),t.placeholder?r(t.placeholder):i&&r(i),i&&function(){Kr||E("enableplaceholder-deprecated-text-option");Kr=!0;}();}function Jr(e,t){const i=t.document;Gr.has(i)&&e.change((e=>{const n=Gr.get(i),s=n.get(t);e.removeAttribute("data-placeholder",s.hostElement),Yr(e,s.hostElement),n.delete(t);}));}function Qr(e,t){return !t.hasClass("ck-placeholder")&&(e.addClass("ck-placeholder",t),!0)}function Yr(e,t){return !!t.hasClass("ck-placeholder")&&(e.removeClass("ck-placeholder",t),!0)}function Xr(e,t){if(!e.isAttached())return !1;const i=Array.from(e.getChildren()).some((e=>!e.is("uiElement")));if(i)return !1;const n=e.document,s=n.selection.anchor;return (!n.isComposing||!s||s.parent!==e)&&(!!t||(!n.isFocused||!!s&&s.parent!==e))}function ea(e,t){const i=Gr.get(e),n=[];let s=!1;for(const[e,o]of i)o.isDirectHost&&(n.push(e),ta(t,e,o)&&(s=!0));for(const[e,o]of i){if(o.isDirectHost)continue;const i=ia(e);i&&(n.includes(i)||(o.hostElement=i,ta(t,e,o)&&(s=!0)));}return s}function ta(e,t,i){const{text:n,isDirectHost:s,hostElement:o}=i;let r=!1;o.getAttribute("data-placeholder")!==n&&(e.setAttribute("data-placeholder",n,o),r=!0);return (s||1==t.childCount)&&Xr(o,i.keepOnFocus)?Qr(e,o)&&(r=!0):Yr(e,o)&&(r=!0),r}function ia(e){if(e.childCount){const t=e.getChild(0);if(t.is("element")&&!t.is("uiElement")&&!t.is("attributeElement"))return t}return null}let na=class{is(){throw new Error("is() method is abstract")}},sa=class extends(L(na)){document;parent;constructor(e){super(),this.document=e,this.parent=null;}get index(){let e;if(!this.parent)return null;if(-1==(e=this.parent.getChildIndex(this)))throw new A("view-node-not-found-in-parent",this);return e}get nextSibling(){const e=this.index;return null!==e&&this.parent.getChild(e+1)||null}get previousSibling(){const e=this.index;return null!==e&&this.parent.getChild(e-1)||null}get root(){let e=this;for(;e.parent;)e=e.parent;return e}isAttached(){return this.root.is("rootElement")}getPath(){const e=[];let t=this;for(;t.parent;)e.unshift(t.index),t=t.parent;return e}getAncestors(e={}){const t=[];let i=e.includeSelf?this:this.parent;for(;i;)t[e.parentFirst?"push":"unshift"](i),i=i.parent;return t}getCommonAncestor(e,t={}){const i=this.getAncestors(t),n=e.getAncestors(t);let s=0;for(;i[s]==n[s]&&i[s];)s++;return 0===s?null:i[s-1]}isBefore(e){if(this==e)return !1;if(this.root!==e.root)return !1;const t=this.getPath(),i=e.getPath(),n=so(t,i);switch(n){case"prefix":return !0;case"extension":return !1;default:return t[n]e.data.length)throw new A("view-textproxy-wrong-offsetintext",this);if(i<0||t+i>e.data.length)throw new A("view-textproxy-wrong-length",this);this.data=e.data.substring(t,t+i),this.offsetInText=t;}get offsetSize(){return this.data.length}get isPartial(){return this.data.length!==this.textNode.data.length}get parent(){return this.textNode.parent}get root(){return this.textNode.root}get document(){return this.textNode.document}getAncestors(e={}){const t=[];let i=e.includeSelf?this.textNode:this.parent;for(;null!==i;)t[e.parentFirst?"push":"unshift"](i),i=i.parent;return t}};ra.prototype.is=function(e){return "$textProxy"===e||"view:$textProxy"===e||"textProxy"===e||"view:textProxy"===e};class aa{_patterns=[];constructor(...e){this.add(...e);}add(...e){for(let t of e)("string"==typeof t||t instanceof RegExp)&&(t={name:t}),this._patterns.push(t);}match(...e){for(const t of e)for(const e of this._patterns){const i=la(t,e);if(i)return {element:t,pattern:e,match:i}}return null}matchAll(...e){const t=[];for(const i of e)for(const e of this._patterns){const n=la(i,e);n&&t.push({element:i,pattern:e,match:n});}return t.length>0?t:null}getElementName(){if(1!==this._patterns.length)return null;const e=this._patterns[0],t=e.name;return "function"==typeof e||!t||t instanceof RegExp?null:t}}function la(e,t){if("function"==typeof t)return t(e);const i={};return t.name&&(i.name=function(e,t){if(e instanceof RegExp)return !!t.match(e);return e===t}(t.name,e.name),!i.name)||t.attributes&&(i.attributes=function(e,t){const i=new Set(t.getAttributeKeys());ei(e)?(void 0!==e.style&&E("matcher-pattern-deprecated-attributes-style-key",e),void 0!==e.class&&E("matcher-pattern-deprecated-attributes-class-key",e)):(i.delete("style"),i.delete("class"));return ca(e,i,(e=>t.getAttribute(e)))}(t.attributes,e),!i.attributes)||t.classes&&(i.classes=function(e,t){return ca(e,t.getClassNames(),(()=>{}))}(t.classes,e),!i.classes)||t.styles&&(i.styles=function(e,t){return ca(e,t.getStyleNames(!0),(e=>t.getStyle(e)))}(t.styles,e),!i.styles)?null:i}function ca(e,t,i){const n=function(e){if(Array.isArray(e))return e.map((e=>ei(e)?(void 0!==e.key&&void 0!==e.value||E("matcher-pattern-missing-key-or-value",e),[e.key,e.value]):[e,!0]));if(ei(e))return Object.entries(e);return [[e,!0]]}(e),s=Array.from(t),o=[];if(n.forEach((([e,t])=>{s.forEach((n=>{(function(e,t){return !0===e||e===t||e instanceof RegExp&&t.match(e)})(e,n)&&function(e,t,i){if(!0===e)return !0;const n=i(t);return e===n||e instanceof RegExp&&!!String(n).match(e)}(t,n,i)&&o.push(n);}));})),n.length&&!(o.lengtht===e));return Array.isArray(t)}set(e,t){if(ue(e))for(const[t,i]of Object.entries(e))this._styleProcessor.toNormalizedForm(t,i,this._styles);else this._styleProcessor.toNormalizedForm(e,t,this._styles);}remove(e){const t=ha(e);!function(e,t){null==e||Ns(e,t);}(this._styles,t),delete this._styles[e],this._cleanEmptyObjectsOnPath(t);}getNormalized(e){return this._styleProcessor.getNormalized(e,this._styles)}toString(){return this.isEmpty?"":this.getStylesEntries().map((e=>e.join(":"))).sort().join(";")+";"}getAsString(e){if(this.isEmpty)return;if(this._styles[e]&&!ue(this._styles[e]))return this._styles[e];const t=this._styleProcessor.getReducedForm(e,this._styles).find((([t])=>t===e));return Array.isArray(t)?t[1]:void 0}getStyleNames(e=!1){if(this.isEmpty)return [];if(e)return this._styleProcessor.getStyleNames(this._styles);return this.getStylesEntries().map((([e])=>e))}clear(){this._styles={};}getStylesEntries(){const e=[],t=Object.keys(this._styles);for(const i of t)e.push(...this._styleProcessor.getReducedForm(i,this._styles));return e}_cleanEmptyObjectsOnPath(e){const t=e.split(".");if(!(t.length>1))return;const i=t.splice(0,t.length-1).join("."),n=qt(this._styles,i);if(!n)return;!Object.keys(n).length&&this.remove(i);}}class ua{_normalizers;_extractors;_reducers;_consumables;constructor(){this._normalizers=new Map,this._extractors=new Map,this._reducers=new Map,this._consumables=new Map;}toNormalizedForm(e,t,i){if(ue(t))ma(i,ha(e),t);else if(this._normalizers.has(e)){const n=this._normalizers.get(e),{path:s,value:o}=n(t);ma(i,s,o);}else ma(i,e,t);}getNormalized(e,t){if(!e)return Fs({},t);if(void 0!==t[e])return t[e];if(this._extractors.has(e)){const i=this._extractors.get(e);if("string"==typeof i)return qt(t,i);const n=i(e,t);if(n)return n}return qt(t,ha(e))}getReducedForm(e,t){const i=this.getNormalized(e,t);if(void 0===i)return [];if(this._reducers.has(e)){return this._reducers.get(e)(i)}return [[e,i]]}getStyleNames(e){const t=new Set;for(const i of this._consumables.keys()){const n=this.getNormalized(i,e);n&&("object"!=typeof n||Object.keys(n).length)&&t.add(i);}for(const i of Object.keys(e))t.add(i);return Array.from(t)}getRelatedStyles(e){return this._consumables.get(e)||[]}setNormalizer(e,t){this._normalizers.set(e,t);}setExtractor(e,t){this._extractors.set(e,t);}setReducer(e,t){this._reducers.set(e,t);}setStyleRelation(e,t){this._mapStyleNames(e,t);for(const i of t)this._mapStyleNames(i,[e]);}_mapStyleNames(e,t){this._consumables.has(e)||this._consumables.set(e,[]),this._consumables.get(e).push(...t);}}function ha(e){return e.replace("-",".")}function ma(e,t,i){let n=i;ue(i)&&(n=Fs({},qt(e,t),i)),Ds(e,t,n);}let ga=class e extends sa{name;_unsafeAttributesToRender=[];_attrs;_children;_classes;_styles;_customProperties=new Map;constructor(e,t,i,n){if(super(e),this.name=t,this._attrs=function(e){const t=xr(e);for(const[e,i]of t)null===i?t.delete(e):"string"!=typeof i&&t.set(e,String(i));return t}(i),this._children=[],n&&this._insertChild(0,n),this._classes=new Set,this._attrs.has("class")){const e=this._attrs.get("class");fa(this._classes,e),this._attrs.delete("class");}this._styles=new da(this.document.stylesProcessor),this._attrs.has("style")&&(this._styles.setTo(this._attrs.get("style")),this._attrs.delete("style"));}get childCount(){return this._children.length}get isEmpty(){return 0===this._children.length}getChild(e){return this._children[e]}getChildIndex(e){return this._children.indexOf(e)}getChildren(){return this._children[Symbol.iterator]()}*getAttributeKeys(){this._classes.size>0&&(yield "class"),this._styles.isEmpty||(yield "style"),yield*this._attrs.keys();}*getAttributes(){yield*this._attrs.entries(),this._classes.size>0&&(yield ["class",this.getAttribute("class")]),this._styles.isEmpty||(yield ["style",this.getAttribute("style")]);}getAttribute(e){if("class"==e)return this._classes.size>0?[...this._classes].join(" "):void 0;if("style"==e){const e=this._styles.toString();return ""==e?void 0:e}return this._attrs.get(e)}hasAttribute(e){return "class"==e?this._classes.size>0:"style"==e?!this._styles.isEmpty:this._attrs.has(e)}isSimilar(t){if(!(t instanceof e))return !1;if(this===t)return !0;if(this.name!=t.name)return !1;if(this._attrs.size!==t._attrs.size||this._classes.size!==t._classes.size||this._styles.size!==t._styles.size)return !1;for(const[e,i]of this._attrs)if(!t._attrs.has(e)||t._attrs.get(e)!==i)return !1;for(const e of this._classes)if(!t._classes.has(e))return !1;for(const e of this._styles.getStyleNames())if(!t._styles.has(e)||t._styles.getAsString(e)!==this._styles.getAsString(e))return !1;return !0}hasClass(...e){for(const t of e)if(!this._classes.has(t))return !1;return !0}getClassNames(){return this._classes.keys()}getStyle(e){return this._styles.getAsString(e)}getNormalizedStyle(e){return this._styles.getNormalized(e)}getStyleNames(e){return this._styles.getStyleNames(e)}hasStyle(...e){for(const t of e)if(!this._styles.has(t))return !1;return !0}findAncestor(...e){const t=new aa(...e);let i=this.parent;for(;i&&!i.is("documentFragment");){if(t.match(i))return i;i=i.parent;}return null}getCustomProperty(e){return this._customProperties.get(e)}*getCustomProperties(){yield*this._customProperties.entries();}getIdentity(){const e=Array.from(this._classes).sort().join(","),t=this._styles.toString(),i=Array.from(this._attrs).map((e=>`${e[0]}="${e[1]}"`)).sort().join(" ");return this.name+(""==e?"":` class="${e}"`)+(t?` style="${t}"`:"")+(""==i?"":` ${i}`)}shouldRenderUnsafeAttribute(e){return this._unsafeAttributesToRender.includes(e)}_clone(e=!1){const t=[];if(e)for(const i of this.getChildren())t.push(i._clone(e));const i=new this.constructor(this.document,this.name,this._attrs,t);return i._classes=new Set(this._classes),i._styles.set(this._styles.getNormalized()),i._customProperties=new Map(this._customProperties),i.getFillerOffset=this.getFillerOffset,i._unsafeAttributesToRender=this._unsafeAttributesToRender,i}_appendChild(e){return this._insertChild(this.childCount,e)}_insertChild(e,t){this._fireChange("children",this);let i=0;const n=function(e,t){if("string"==typeof t)return [new oa(e,t)];oo(t)||(t=[t]);return Array.from(t).map((t=>"string"==typeof t?new oa(e,t):t instanceof ra?new oa(e,t.data):t))}(this.document,t);for(const t of n)null!==t.parent&&t._remove(),t.parent=this,t.document=this.document,this._children.splice(e,0,t),e++,i++;return i}_removeChildren(e,t=1){this._fireChange("children",this);for(let i=e;i0&&(this._classes.clear(),!0):"style"==e?!this._styles.isEmpty&&(this._styles.clear(),!0):this._attrs.delete(e)}_addClass(e){this._fireChange("attributes",this);for(const t of gr(e))this._classes.add(t);}_removeClass(e){this._fireChange("attributes",this);for(const t of gr(e))this._classes.delete(t);}_setStyle(e,t){this._fireChange("attributes",this),"string"!=typeof e?this._styles.set(e):this._styles.set(e,t);}_removeStyle(e){this._fireChange("attributes",this);for(const t of gr(e))this._styles.remove(t);}_setCustomProperty(e,t){this._customProperties.set(e,t);}_removeCustomProperty(e){return this._customProperties.delete(e)}};function fa(e,t){const i=t.split(/\s+/);e.clear(),i.forEach((t=>e.add(t)));}ga.prototype.is=function(e,t){return t?t===this.name&&("element"===e||"view:element"===e):"element"===e||"view:element"===e||"node"===e||"view:node"===e};class pa extends ga{constructor(e,t,i,n){super(e,t,i,n),this.getFillerOffset=ba;}}function ba(){const e=[...this.getChildren()],t=e[this.childCount-1];if(t&&t.is("element","br"))return this.childCount;for(const t of e)if(!t.is("uiElement"))return null;return this.childCount}pa.prototype.is=function(e,t){return t?t===this.name&&("containerElement"===e||"view:containerElement"===e||"element"===e||"view:element"===e):"containerElement"===e||"view:containerElement"===e||"element"===e||"view:element"===e||"node"===e||"view:node"===e};class wa extends(Zs(pa)){constructor(e,t,i,n){super(e,t,i,n),this.set("isReadOnly",!1),this.set("isFocused",!1),this.set("placeholder",void 0),this.bind("isReadOnly").to(e),this.bind("isFocused").to(e,"isFocused",(t=>t&&e.selection.editableElement==this)),this.listenTo(e.selection,"change",(()=>{this.isFocused=e.isFocused&&e.selection.editableElement==this;}));}destroy(){this.stopListening();}}wa.prototype.is=function(e,t){return t?t===this.name&&("editableElement"===e||"view:editableElement"===e||"containerElement"===e||"view:containerElement"===e||"element"===e||"view:element"===e):"editableElement"===e||"view:editableElement"===e||"containerElement"===e||"view:containerElement"===e||"element"===e||"view:element"===e||"node"===e||"view:node"===e};const _a=Symbol("rootName");class va extends wa{constructor(e,t){super(e,t),this.rootName="main";}get rootName(){return this.getCustomProperty(_a)}set rootName(e){this._setCustomProperty(_a,e);}set _name(e){this.name=e;}}va.prototype.is=function(e,t){return t?t===this.name&&("rootElement"===e||"view:rootElement"===e||"editableElement"===e||"view:editableElement"===e||"containerElement"===e||"view:containerElement"===e||"element"===e||"view:element"===e):"rootElement"===e||"view:rootElement"===e||"editableElement"===e||"view:editableElement"===e||"containerElement"===e||"view:containerElement"===e||"element"===e||"view:element"===e||"node"===e||"view:node"===e};let ya=class{direction;boundaries;singleCharacters;shallow;ignoreElementEnd;_position;_boundaryStartParent;_boundaryEndParent;constructor(e={}){if(!e.boundaries&&!e.startPosition)throw new A("view-tree-walker-no-start-position",null);if(e.direction&&"forward"!=e.direction&&"backward"!=e.direction)throw new A("view-tree-walker-unknown-direction",e.startPosition,{direction:e.direction});this.boundaries=e.boundaries||null,e.startPosition?this._position=ka._createAt(e.startPosition):this._position=ka._createAt(e.boundaries["backward"==e.direction?"end":"start"]),this.direction=e.direction||"forward",this.singleCharacters=!!e.singleCharacters,this.shallow=!!e.shallow,this.ignoreElementEnd=!!e.ignoreElementEnd,this._boundaryStartParent=this.boundaries?this.boundaries.start.parent:null,this._boundaryEndParent=this.boundaries?this.boundaries.end.parent:null;}[Symbol.iterator](){return this}get position(){return this._position}skip(e){let t,i;do{i=this.position,t=this.next();}while(!t.done&&e(t.value));t.done||(this._position=i);}next(){return "forward"==this.direction?this._next():this._previous()}_next(){let e=this.position.clone();const t=this.position,i=e.parent;if(null===i.parent&&e.offset===i.childCount)return {done:!0,value:void 0};if(i===this._boundaryEndParent&&e.offset==this.boundaries.end.offset)return {done:!0,value:void 0};let n;if(i instanceof oa){if(e.isAtEnd)return this._position=ka._createAfter(i),this._next();n=i.data[e.offset];}else n=i.getChild(e.offset);if(n instanceof ga){if(this.shallow){if(this.boundaries&&this.boundaries.end.isBefore(e))return {done:!0,value:void 0};e.offset++;}else e=new ka(n,0);return this._position=e,this._formatReturnValue("elementStart",n,t,e,1)}if(n instanceof oa){if(this.singleCharacters)return e=new ka(n,0),this._position=e,this._next();let i,s=n.data.length;return n==this._boundaryEndParent?(s=this.boundaries.end.offset,i=new ra(n,0,s),e=ka._createAfter(i)):(i=new ra(n,0,n.data.length),e.offset++),this._position=e,this._formatReturnValue("text",i,t,e,s)}if("string"==typeof n){let n;if(this.singleCharacters)n=1;else {n=(i===this._boundaryEndParent?this.boundaries.end.offset:i.data.length)-e.offset;}const s=new ra(i,e.offset,n);return e.offset+=n,this._position=e,this._formatReturnValue("text",s,t,e,n)}return e=ka._createAfter(i),this._position=e,this.ignoreElementEnd?this._next():this._formatReturnValue("elementEnd",i,t,e)}_previous(){let e=this.position.clone();const t=this.position,i=e.parent;if(null===i.parent&&0===e.offset)return {done:!0,value:void 0};if(i==this._boundaryStartParent&&e.offset==this.boundaries.start.offset)return {done:!0,value:void 0};let n;if(i instanceof oa){if(e.isAtStart)return this._position=ka._createBefore(i),this._previous();n=i.data[e.offset-1];}else n=i.getChild(e.offset-1);if(n instanceof ga)return this.shallow?(e.offset--,this._position=e,this._formatReturnValue("elementStart",n,t,e,1)):(e=new ka(n,n.childCount),this._position=e,this.ignoreElementEnd?this._previous():this._formatReturnValue("elementEnd",n,t,e));if(n instanceof oa){if(this.singleCharacters)return e=new ka(n,n.data.length),this._position=e,this._previous();let i,s=n.data.length;if(n==this._boundaryStartParent){const t=this.boundaries.start.offset;i=new ra(n,t,n.data.length-t),s=i.data.length,e=ka._createBefore(i);}else i=new ra(n,0,n.data.length),e.offset--;return this._position=e,this._formatReturnValue("text",i,t,e,s)}if("string"==typeof n){let n;if(this.singleCharacters)n=1;else {const t=i===this._boundaryStartParent?this.boundaries.start.offset:0;n=e.offset-t;}e.offset-=n;const s=new ra(i,e.offset,n);return this._position=e,this._formatReturnValue("text",s,t,e,n)}return e=ka._createBefore(i),this._position=e,this._formatReturnValue("elementStart",i,t,e,1)}_formatReturnValue(e,t,i,n,s){return t instanceof ra&&(t.offsetInText+t.data.length==t.textNode.data.length&&("forward"!=this.direction||this.boundaries&&this.boundaries.end.isEqual(this.position)?i=ka._createAfter(t.textNode):(n=ka._createAfter(t.textNode),this._position=n)),0===t.offsetInText&&("backward"!=this.direction||this.boundaries&&this.boundaries.start.isEqual(this.position)?i=ka._createBefore(t.textNode):(n=ka._createBefore(t.textNode),this._position=n))),{done:!1,value:{type:e,item:t,previousPosition:i,nextPosition:n,length:s}}}},ka=class e extends na{parent;offset;constructor(e,t){super(),this.parent=e,this.offset=t;}get nodeAfter(){return this.parent.is("$text")?null:this.parent.getChild(this.offset)||null}get nodeBefore(){return this.parent.is("$text")?null:this.parent.getChild(this.offset-1)||null}get isAtStart(){return 0===this.offset}get isAtEnd(){const e=this.parent.is("$text")?this.parent.data.length:this.parent.childCount;return this.offset===e}get root(){return this.parent.root}get editableElement(){let e=this.parent;for(;!(e instanceof wa);){if(!e.parent)return null;e=e.parent;}return e}getShiftedBy(t){const i=e._createAt(this),n=i.offset+t;return i.offset=n<0?0:n,i}getLastMatchingPosition(e,t={}){t.startPosition=this;const i=new ya(t);return i.skip(e),i.position}getAncestors(){return this.parent.is("documentFragment")?[this.parent]:this.parent.getAncestors({includeSelf:!0})}getCommonAncestor(e){const t=this.getAncestors(),i=e.getAncestors();let n=0;for(;t[n]==i[n]&&t[n];)n++;return 0===n?null:t[n-1]}isEqual(e){return this.parent==e.parent&&this.offset==e.offset}isBefore(e){return "before"==this.compareWith(e)}isAfter(e){return "after"==this.compareWith(e)}compareWith(e){if(this.root!==e.root)return "different";if(this.isEqual(e))return "same";const t=this.parent.is("node")?this.parent.getPath():[],i=e.parent.is("node")?e.parent.getPath():[];t.push(this.offset),i.push(e.offset);const n=so(t,i);switch(n){case"prefix":return "before";case"extension":return "after";default:return t[n]0?new this(i,n):new this(n,i)}static _createIn(e){return this._createFromParentsAndOffsets(e,0,e,e.childCount)}static _createOn(e){const t=e.is("$textProxy")?e.offsetSize:1;return this._createFromPositionAndShift(ka._createBefore(e),t)}};function xa(e){return !(!e.item.is("attributeElement")&&!e.item.is("uiElement"))}Ca.prototype.is=function(e){return "range"===e||"view:range"===e};let Aa=class e extends(L(na)){_ranges;_lastRangeBackward;_isFake;_fakeSelectionLabel;constructor(...e){super(),this._ranges=[],this._lastRangeBackward=!1,this._isFake=!1,this._fakeSelectionLabel="",e.length&&this.setTo(...e);}get isFake(){return this._isFake}get fakeSelectionLabel(){return this._fakeSelectionLabel}get anchor(){if(!this._ranges.length)return null;const e=this._ranges[this._ranges.length-1];return (this._lastRangeBackward?e.end:e.start).clone()}get focus(){if(!this._ranges.length)return null;const e=this._ranges[this._ranges.length-1];return (this._lastRangeBackward?e.start:e.end).clone()}get isCollapsed(){return 1===this.rangeCount&&this._ranges[0].isCollapsed}get rangeCount(){return this._ranges.length}get isBackward(){return !this.isCollapsed&&this._lastRangeBackward}get editableElement(){return this.anchor?this.anchor.editableElement:null}*getRanges(){for(const e of this._ranges)yield e.clone();}getFirstRange(){let e=null;for(const t of this._ranges)e&&!t.start.isBefore(e.start)||(e=t);return e?e.clone():null}getLastRange(){let e=null;for(const t of this._ranges)e&&!t.end.isAfter(e.end)||(e=t);return e?e.clone():null}getFirstPosition(){const e=this.getFirstRange();return e?e.start.clone():null}getLastPosition(){const e=this.getLastRange();return e?e.end.clone():null}isEqual(e){if(this.isFake!=e.isFake)return !1;if(this.isFake&&this.fakeSelectionLabel!=e.fakeSelectionLabel)return !1;if(this.rangeCount!=e.rangeCount)return !1;if(0===this.rangeCount)return !0;if(!this.anchor.isEqual(e.anchor)||!this.focus.isEqual(e.focus))return !1;for(const t of this._ranges){let i=!1;for(const n of e._ranges)if(t.isEqual(n)){i=!0;break}if(!i)return !1}return !0}isSimilar(e){if(this.isBackward!=e.isBackward)return !1;const t=no(this.getRanges());if(t!=no(e.getRanges()))return !1;if(0==t)return !0;for(let t of this.getRanges()){t=t.getTrimmed();let i=!1;for(let n of e.getRanges())if(n=n.getTrimmed(),t.start.isEqual(n.start)&&t.end.isEqual(n.end)){i=!0;break}if(!i)return !1}return !0}getSelectedElement(){return 1!==this.rangeCount?null:this.getFirstRange().getContainedElement()}setTo(...t){let[i,n,s]=t;if("object"==typeof n&&(s=n,n=void 0),null===i)this._setRanges([]),this._setFakeOptions(s);else if(i instanceof e||i instanceof Ea)this._setRanges(i.getRanges(),i.isBackward),this._setFakeOptions({fake:i.isFake,label:i.fakeSelectionLabel});else if(i instanceof Ca)this._setRanges([i],s&&s.backward),this._setFakeOptions(s);else if(i instanceof ka)this._setRanges([new Ca(i)]),this._setFakeOptions(s);else if(i instanceof sa){const e=!!s&&!!s.backward;let t;if(void 0===n)throw new A("view-selection-setto-required-second-parameter",this);t="in"==n?Ca._createIn(i):"on"==n?Ca._createOn(i):new Ca(ka._createAt(i,n)),this._setRanges([t],e),this._setFakeOptions(s);}else {if(!oo(i))throw new A("view-selection-setto-not-selectable",this);this._setRanges(i,s&&s.backward),this._setFakeOptions(s);}this.fire("change");}setFocus(e,t){if(null===this.anchor)throw new A("view-selection-setfocus-no-ranges",this);const i=ka._createAt(e,t);if("same"==i.compareWith(this.focus))return;const n=this.anchor;this._ranges.pop(),"before"==i.compareWith(n)?this._addRange(new Ca(i,n),!0):this._addRange(new Ca(n,i)),this.fire("change");}_setRanges(e,t=!1){e=Array.from(e),this._ranges=[];for(const t of e)this._addRange(t);this._lastRangeBackward=!!t;}_setFakeOptions(e={}){this._isFake=!!e.fake,this._fakeSelectionLabel=e.fake&&e.label||"";}_addRange(e,t=!1){if(!(e instanceof Ca))throw new A("view-selection-add-range-not-range",this);this._pushRange(e),this._lastRangeBackward=!!t;}_pushRange(e){for(const t of this._ranges)if(e.isIntersecting(t))throw new A("view-selection-range-intersects",this,{addedRange:e,intersectingRange:t});this._ranges.push(new Ca(e.start,e.end));}};Aa.prototype.is=function(e){return "selection"===e||"view:selection"===e};let Ea=class extends(L(na)){_selection;constructor(...e){super(),this._selection=new Aa,this._selection.delegate("change").to(this),e.length&&this._selection.setTo(...e);}get isFake(){return this._selection.isFake}get fakeSelectionLabel(){return this._selection.fakeSelectionLabel}get anchor(){return this._selection.anchor}get focus(){return this._selection.focus}get isCollapsed(){return this._selection.isCollapsed}get rangeCount(){return this._selection.rangeCount}get isBackward(){return this._selection.isBackward}get editableElement(){return this._selection.editableElement}get _ranges(){return this._selection._ranges}*getRanges(){yield*this._selection.getRanges();}getFirstRange(){return this._selection.getFirstRange()}getLastRange(){return this._selection.getLastRange()}getFirstPosition(){return this._selection.getFirstPosition()}getLastPosition(){return this._selection.getLastPosition()}getSelectedElement(){return this._selection.getSelectedElement()}isEqual(e){return this._selection.isEqual(e)}isSimilar(e){return this._selection.isSimilar(e)}_setTo(...e){this._selection.setTo(...e);}_setFocus(e,t){this._selection.setFocus(e,t);}};Ea.prototype.is=function(e){return "selection"===e||"documentSelection"==e||"view:selection"==e||"view:documentSelection"==e};class Ta extends v{startRange;_eventPhase;_currentTarget;constructor(e,t,i){super(e,t),this.startRange=i,this._eventPhase="none",this._currentTarget=null;}get eventPhase(){return this._eventPhase}get currentTarget(){return this._currentTarget}}const Pa=Symbol("bubbling contexts");function Sa(e){return class extends e{fire(e,...t){try{const i=e instanceof v?e:new v(this,e),n=Oa(this);if(!n.size)return;if(Ia(i,"capturing",this),Va(n,"$capture",i,...t))return i.return;const s=i.startRange||this.selection.getFirstRange(),o=s?s.getContainedElement():null,r=!!o&&Boolean(Ra(n,o));let a=o||function(e){if(!e)return null;const t=e.start.parent,i=e.end.parent,n=t.getPath(),s=i.getPath();return n.length>s.length?t:i}(s);if(Ia(i,"atTarget",a),!r){if(Va(n,"$text",i,...t))return i.return;Ia(i,"bubbling",a);}for(;a;){if(a.is("rootElement")){if(Va(n,"$root",i,...t))return i.return}else if(a.is("element")&&Va(n,a.name,i,...t))return i.return;if(Va(n,a,i,...t))return i.return;a=a.parent,Ia(i,"bubbling",a);}return Ia(i,"bubbling",this),Va(n,"$document",i,...t),i.return}catch(e){A.rethrowUnexpectedError(e,this);}}_addEventListener(e,t,i){const n=gr(i.context||"$document"),s=Oa(this);for(const o of n){let n=s.get(o);n||(n=new(L()),s.set(o,n)),this.listenTo(n,e,t,i);}}_removeEventListener(e,t){const i=Oa(this);for(const n of i.values())this.stopListening(n,e,t);}}}{const e=Sa(Object);["fire","_addEventListener","_removeEventListener"].forEach((t=>{Sa[t]=e.prototype[t];}));}function Ia(e,t,i){e instanceof Ta&&(e._eventPhase=t,e._currentTarget=i);}function Va(e,t,i,...n){const s="string"==typeof t?e.get(t):Ra(e,t);return !!s&&(s.fire(i,...n),i.stop.called)}function Ra(e,t){for(const[i,n]of e)if("function"==typeof i&&i(t))return n;return null}function Oa(e){return e[Pa]||(e[Pa]=new Map),e[Pa]}let Ba=class extends(Sa(Zs())){selection;roots;stylesProcessor;_postFixers=new Set;constructor(e){super(),this.selection=new Ea,this.roots=new br({idProperty:"rootName"}),this.stylesProcessor=e,this.set("isReadOnly",!1),this.set("isFocused",!1),this.set("isSelecting",!1),this.set("isComposing",!1);}getRoot(e="main"){return this.roots.get(e)}registerPostFixer(e){this._postFixers.add(e);}destroy(){this.roots.forEach((e=>e.destroy())),this.stopListening();}_callPostFixers(e){let t=!1;do{for(const i of this._postFixers)if(t=i(e),t)break}while(t)}};class Ma extends ga{static DEFAULT_PRIORITY=10;_priority=10;_id=null;_clonesGroup=null;constructor(e,t,i,n){super(e,t,i,n),this.getFillerOffset=La;}get priority(){return this._priority}get id(){return this._id}getElementsWithSameId(){if(null===this.id)throw new A("attribute-element-get-elements-with-same-id-no-id",this);return new Set(this._clonesGroup)}isSimilar(e){return null!==this.id||null!==e.id?this.id===e.id:super.isSimilar(e)&&this.priority==e.priority}_clone(e=!1){const t=super._clone(e);return t._priority=this._priority,t._id=this._id,t}}function La(){if(Fa(this))return null;let e=this.parent;for(;e&&e.is("attributeElement");){if(Fa(e)>1)return null;e=e.parent;}return !e||Fa(e)>1?null:this.childCount}function Fa(e){return Array.from(e.getChildren()).filter((e=>!e.is("uiElement"))).length}Ma.prototype.is=function(e,t){return t?t===this.name&&("attributeElement"===e||"view:attributeElement"===e||"element"===e||"view:element"===e):"attributeElement"===e||"view:attributeElement"===e||"element"===e||"view:element"===e||"node"===e||"view:node"===e};class Na extends ga{constructor(e,t,i,n){super(e,t,i,n),this.getFillerOffset=Da;}_insertChild(e,t){if(t&&(t instanceof sa||Array.from(t).length>0))throw new A("view-emptyelement-cannot-add",[this,t]);return 0}}function Da(){return null}Na.prototype.is=function(e,t){return t?t===this.name&&("emptyElement"===e||"view:emptyElement"===e||"element"===e||"view:element"===e):"emptyElement"===e||"view:emptyElement"===e||"element"===e||"view:element"===e||"node"===e||"view:node"===e};class za extends ga{constructor(e,t,i,n){super(e,t,i,n),this.getFillerOffset=$a;}_insertChild(e,t){if(t&&(t instanceof sa||Array.from(t).length>0))throw new A("view-uielement-cannot-add",[this,t]);return 0}render(e,t){return this.toDomElement(e)}toDomElement(e){const t=e.createElement(this.name);for(const e of this.getAttributeKeys())t.setAttribute(e,this.getAttribute(e));return t}}function Ha(e){e.document.on("arrowKey",((t,i)=>function(e,t,i){if(t.keyCode==nr.arrowright){const e=t.domTarget.ownerDocument.defaultView.getSelection(),n=1==e.rangeCount&&e.getRangeAt(0).collapsed;if(n||t.shiftKey){const t=e.focusNode,s=e.focusOffset,o=i.domPositionToView(t,s);if(null===o)return;let r=!1;const a=o.getLastMatchingPosition((e=>(e.item.is("uiElement")&&(r=!0),!(!e.item.is("uiElement")&&!e.item.is("attributeElement")))));if(r){const t=i.viewPositionToDom(a);n?e.collapse(t.parent,t.offset):e.extend(t.parent,t.offset);}}}}(0,i,e.domConverter)),{priority:"low"});}function $a(){return null}za.prototype.is=function(e,t){return t?t===this.name&&("uiElement"===e||"view:uiElement"===e||"element"===e||"view:element"===e):"uiElement"===e||"view:uiElement"===e||"element"===e||"view:element"===e||"node"===e||"view:node"===e};class Ua extends ga{constructor(e,t,i,n){super(e,t,i,n),this.getFillerOffset=Wa;}_insertChild(e,t){if(t&&(t instanceof sa||Array.from(t).length>0))throw new A("view-rawelement-cannot-add",[this,t]);return 0}render(e,t){}}function Wa(){return null}Ua.prototype.is=function(e,t){return t?t===this.name&&("rawElement"===e||"view:rawElement"===e||"element"===e||"view:element"===e):"rawElement"===e||"view:rawElement"===e||e===this.name||e==="view:"+this.name||"element"===e||"view:element"===e||"node"===e||"view:node"===e};let ja=class extends(L(na)){document;_children=[];_customProperties=new Map;constructor(e,t){super(),this.document=e,t&&this._insertChild(0,t);}[Symbol.iterator](){return this._children[Symbol.iterator]()}get childCount(){return this._children.length}get isEmpty(){return 0===this.childCount}get root(){return this}get parent(){return null}get name(){}get getFillerOffset(){}getCustomProperty(e){return this._customProperties.get(e)}*getCustomProperties(){yield*this._customProperties.entries();}_appendChild(e){return this._insertChild(this.childCount,e)}getChild(e){return this._children[e]}getChildIndex(e){return this._children.indexOf(e)}getChildren(){return this._children[Symbol.iterator]()}_insertChild(e,t){this._fireChange("children",this);let i=0;const n=function(e,t){if("string"==typeof t)return [new oa(e,t)];oo(t)||(t=[t]);return Array.from(t).map((t=>"string"==typeof t?new oa(e,t):t instanceof ra?new oa(e,t.data):t))}(this.document,t);for(const t of n)null!==t.parent&&t._remove(),t.parent=this,this._children.splice(e,0,t),e++,i++;return i}_removeChildren(e,t=1){this._fireChange("children",this);for(let i=e;i{const i=e[e.length-1],n=!t.is("uiElement");return i&&i.breakAttributes==n?i.nodes.push(t):e.push({breakAttributes:n,nodes:[t]}),e}),[]);let n=null,s=e;for(const{nodes:e,breakAttributes:t}of i){const i=this._insertNodes(s,e,t);n||(n=i.start),s=i.end;}return n?new Ca(n,s):new Ca(e)}remove(e){const t=e instanceof Ca?e:Ca._createOn(e);if(tl(t,this.document),t.isCollapsed)return new ja(this.document);const{start:i,end:n}=this._breakAttributesRange(t,!0),s=i.parent,o=n.offset-i.offset,r=s._removeChildren(i.offset,o);for(const e of r)this._removeFromClonedElementsGroup(e);const a=this.mergeAttributes(i);return t.start=a,t.end=a.clone(),new ja(this.document,r)}clear(e,t){tl(e,this.document);const i=e.getWalker({direction:"backward",ignoreElementEnd:!0});for(const n of i){const i=n.item;let s;if(i.is("element")&&t.isSimilar(i))s=Ca._createOn(i);else if(!n.nextPosition.isAfter(e.start)&&i.is("$textProxy")){const e=i.getAncestors().find((e=>e.is("element")&&t.isSimilar(e)));e&&(s=Ca._createIn(e));}s&&(s.end.isAfter(e.end)&&(s.end=e.end),s.start.isBefore(e.start)&&(s.start=e.start),this.remove(s));}}move(e,t){let i;if(t.isAfter(e.end)){const n=(t=this._breakAttributes(t,!0)).parent,s=n.childCount;e=this._breakAttributesRange(e,!0),i=this.remove(e),t.offset+=n.childCount-s;}else i=this.remove(e);return this.insert(t,i)}wrap(e,t){if(!(t instanceof Ma))throw new A("view-writer-wrap-invalid-attribute",this.document);if(tl(e,this.document),e.isCollapsed){let i=e.start;i.parent.is("element")&&!function(e){return Array.from(e.getChildren()).some((e=>!e.is("uiElement")))}(i.parent)&&(i=i.getLastMatchingPosition((e=>e.item.is("uiElement")))),i=this._wrapPosition(i,t);const n=this.document.selection;return n.isCollapsed&&n.getFirstPosition().isEqual(e.start)&&this.setSelection(i),new Ca(i)}return this._wrapRange(e,t)}unwrap(e,t){if(!(t instanceof Ma))throw new A("view-writer-unwrap-invalid-attribute",this.document);if(tl(e,this.document),e.isCollapsed)return e;const{start:i,end:n}=this._breakAttributesRange(e,!0),s=i.parent,o=this._unwrapChildren(s,i.offset,n.offset,t),r=this.mergeAttributes(o.start);r.isEqual(o.start)||o.end.offset--;const a=this.mergeAttributes(o.end);return new Ca(r,a)}rename(e,t){const i=new pa(this.document,e,t.getAttributes());return this.insert(ka._createAfter(t),i),this.move(Ca._createIn(t),ka._createAt(i,0)),this.remove(Ca._createOn(t)),i}clearClonedElementsGroup(e){this._cloneGroups.delete(e);}createPositionAt(e,t){return ka._createAt(e,t)}createPositionAfter(e){return ka._createAfter(e)}createPositionBefore(e){return ka._createBefore(e)}createRange(e,t){return new Ca(e,t)}createRangeOn(e){return Ca._createOn(e)}createRangeIn(e){return Ca._createIn(e)}createSelection(...e){return new Aa(...e)}createSlot(e="children"){if(!this._slotFactory)throw new A("view-writer-invalid-create-slot-context",this.document);return this._slotFactory(this,e)}_registerSlotFactory(e){this._slotFactory=e;}_clearSlotFactory(){this._slotFactory=null;}_insertNodes(e,t,i){let n,s;if(n=i?Ga(e):e.parent.is("$text")?e.parent.parent:e.parent,!n)throw new A("view-writer-invalid-position-container",this.document);s=i?this._breakAttributes(e,!0):e.parent.is("$text")?Ja(e):e;const o=n._insertChild(s.offset,t);for(const e of t)this._addToClonedElementsGroup(e);const r=s.getShiftedBy(o),a=this.mergeAttributes(s);a.isEqual(s)||r.offset--;const l=this.mergeAttributes(r);return new Ca(a,l)}_wrapChildren(e,t,i,n){let s=t;const o=[];for(;s!1,e.parent._insertChild(e.offset,i);const n=new Ca(e,e.getShiftedBy(1));this.wrap(n,t);const s=new ka(i.parent,i.index);i._remove();const o=s.nodeBefore,r=s.nodeAfter;return o instanceof oa&&r instanceof oa?Qa(o,r):Za(s)}_wrapAttributeElement(e,t){if(!il(e,t))return !1;if(e.name!==t.name||e.priority!==t.priority)return !1;for(const i of e.getAttributeKeys())if("class"!==i&&"style"!==i&&t.hasAttribute(i)&&t.getAttribute(i)!==e.getAttribute(i))return !1;for(const i of e.getStyleNames())if(t.hasStyle(i)&&t.getStyle(i)!==e.getStyle(i))return !1;for(const i of e.getAttributeKeys())"class"!==i&&"style"!==i&&(t.hasAttribute(i)||this.setAttribute(i,e.getAttribute(i),t));for(const i of e.getStyleNames())t.hasStyle(i)||this.setStyle(i,e.getStyle(i),t);for(const i of e.getClassNames())t.hasClass(i)||this.addClass(i,t);return !0}_unwrapAttributeElement(e,t){if(!il(e,t))return !1;if(e.name!==t.name||e.priority!==t.priority)return !1;for(const i of e.getAttributeKeys())if("class"!==i&&"style"!==i&&(!t.hasAttribute(i)||t.getAttribute(i)!==e.getAttribute(i)))return !1;if(!t.hasClass(...e.getClassNames()))return !1;for(const i of e.getStyleNames())if(!t.hasStyle(i)||t.getStyle(i)!==e.getStyle(i))return !1;for(const i of e.getAttributeKeys())"class"!==i&&"style"!==i&&this.removeAttribute(i,t);return this.removeClass(Array.from(e.getClassNames()),t),this.removeStyle(Array.from(e.getStyleNames()),t),!0}_breakAttributesRange(e,t=!1){const i=e.start,n=e.end;if(tl(e,this.document),e.isCollapsed){const i=this._breakAttributes(e.start,t);return new Ca(i,i)}const s=this._breakAttributes(n,t),o=s.parent.childCount,r=this._breakAttributes(i,t);return s.offset+=s.parent.childCount-o,new Ca(r,s)}_breakAttributes(e,t=!1){const i=e.offset,n=e.parent;if(e.parent.is("emptyElement"))throw new A("view-writer-cannot-break-empty-element",this.document);if(e.parent.is("uiElement"))throw new A("view-writer-cannot-break-ui-element",this.document);if(e.parent.is("rawElement"))throw new A("view-writer-cannot-break-raw-element",this.document);if(!t&&n.is("$text")&&el(n.parent))return e.clone();if(el(n))return e.clone();if(n.is("$text"))return this._breakAttributes(Ja(e),t);if(i==n.childCount){const e=new ka(n.parent,n.index+1);return this._breakAttributes(e,t)}if(0===i){const e=new ka(n.parent,n.index);return this._breakAttributes(e,t)}{const e=n.index+1,s=n._clone();n.parent._insertChild(e,s),this._addToClonedElementsGroup(s);const o=n.childCount-i,r=n._removeChildren(i,o);s._appendChild(r);const a=new ka(n.parent,e);return this._breakAttributes(a,t)}}_addToClonedElementsGroup(e){if(!e.root.is("rootElement"))return;if(e.is("element"))for(const t of e.getChildren())this._addToClonedElementsGroup(t);const t=e.id;if(!t)return;let i=this._cloneGroups.get(t);i||(i=new Set,this._cloneGroups.set(t,i)),i.add(e),e._clonesGroup=i;}_removeFromClonedElementsGroup(e){if(e.is("element"))for(const t of e.getChildren())this._removeFromClonedElementsGroup(t);const t=e.id;if(!t)return;const i=this._cloneGroups.get(t);i&&i.delete(e);}}function Ga(e){let t=e.parent;for(;!el(t);){if(!t)return;t=t.parent;}return t}function Ka(e,t){return e.priorityt.priority)&&e.getIdentity()i instanceof e)))throw new A("view-writer-insert-invalid-node-type",t);i.is("$text")||Xa(i.getChildren(),t);}}function el(e){return e&&(e.is("containerElement")||e.is("documentFragment"))}function tl(e,t){const i=Ga(e.start),n=Ga(e.end);if(!i||!n||i!==n)throw new A("view-writer-invalid-range-container",t)}function il(e,t){return null===e.id&&null===t.id}const nl=e=>e.createTextNode(" "),sl=e=>{const t=e.createElement("span");return t.dataset.ckeFiller="true",t.innerText=" ",t},ol=e=>{const t=e.createElement("br");return t.dataset.ckeFiller="true",t},rl="⁠".repeat(7);function al(e){return "string"==typeof e?e.substr(0,7)===rl:ko(e)&&e.data.substr(0,7)===rl}function ll(e){return 7==e.data.length&&al(e)}function cl(e){const t="string"==typeof e?e:e.data;return al(e)?t.slice(7):t}function dl(e,t){if(t.keyCode==nr.arrowleft){const e=t.domTarget.ownerDocument.defaultView.getSelection();if(1==e.rangeCount&&e.getRangeAt(0).collapsed){const t=e.getRangeAt(0).startContainer,i=e.getRangeAt(0).startOffset;al(t)&&i<=7&&e.collapse(t,0);}}}let ul=class extends(Zs()){domDocuments=new Set;domConverter;markedAttributes=new Set;markedChildren=new Set;markedTexts=new Set;selection;_inlineFiller=null;_fakeSelectionContainer=null;constructor(e,t){super(),this.domConverter=e,this.selection=t,this.set("isFocused",!1),this.set("isSelecting",!1),this.set("isComposing",!1),o.isBlink&&!o.isAndroid&&this.on("change:isSelecting",(()=>{this.isSelecting||this.render();}));}markToSync(e,t){if("text"===e)this.domConverter.mapViewToDom(t.parent)&&this.markedTexts.add(t);else {if(!this.domConverter.mapViewToDom(t))return;if("attributes"===e)this.markedAttributes.add(t);else {if("children"!==e)throw new A("view-renderer-unknown-type",this);this.markedChildren.add(t);}}}render(){if(this.isComposing&&!o.isAndroid)return;let e=null;const t=!(o.isBlink&&!o.isAndroid)||!this.isSelecting;for(const e of this.markedChildren)this._updateChildrenMappings(e);t?(this._inlineFiller&&!this._isSelectionInInlineFiller()&&this._removeInlineFiller(),this._inlineFiller?e=this._getInlineFillerPosition():this._needsInlineFillerAtSelection()&&(e=this.selection.getFirstPosition(),this.markedChildren.add(e.parent))):this._inlineFiller&&this._inlineFiller.parentNode&&(e=this.domConverter.domPositionToView(this._inlineFiller),e&&e.parent.is("$text")&&(e=ka._createBefore(e.parent)));for(const e of this.markedAttributes)this._updateAttrs(e);for(const t of this.markedChildren)this._updateChildren(t,{inlineFillerPosition:e});for(const t of this.markedTexts)!this.markedChildren.has(t.parent)&&this.domConverter.mapViewToDom(t.parent)&&this._updateText(t,{inlineFillerPosition:e});if(t)if(e){const t=this.domConverter.viewPositionToDom(e),i=t.parent.ownerDocument;al(t.parent)?this._inlineFiller=t.parent:this._inlineFiller=hl(i,t.parent,t.offset);}else this._inlineFiller=null;this._updateFocus(),this._updateSelection(),this.domConverter._clearTemporaryCustomProperties(),this.markedTexts.clear(),this.markedAttributes.clear(),this.markedChildren.clear();}_updateChildrenMappings(e){const t=this.domConverter.mapViewToDom(e);if(!t)return;const i=Array.from(t.childNodes),n=Array.from(this.domConverter.viewChildrenToDom(e,{withChildren:!1})),s=this._diffNodeLists(i,n),o=this._findUpdateActions(s,i,n,ml);if(-1!==o.indexOf("update")){const t={equal:0,insert:0,delete:0};for(const s of o)if("update"===s){const s=t.equal+t.insert,o=t.equal+t.delete,r=e.getChild(s);!r||r.is("uiElement")||r.is("rawElement")||this._updateElementMappings(r,i[o]),$o(n[s]),t.equal++;}else t[s]++;}}_updateElementMappings(e,t){this.domConverter.unbindDomElement(t),this.domConverter.bindElements(t,e),this.markedChildren.add(e),this.markedAttributes.add(e);}_getInlineFillerPosition(){const e=this.selection.getFirstPosition();return e.parent.is("$text")?ka._createBefore(e.parent):e}_isSelectionInInlineFiller(){if(1!=this.selection.rangeCount||!this.selection.isCollapsed)return !1;const e=this.selection.getFirstPosition(),t=this.domConverter.viewPositionToDom(e);return !!(t&&ko(t.parent)&&al(t.parent))}_removeInlineFiller(){const e=this._inlineFiller;if(!al(e))throw new A("view-renderer-filler-was-lost",this);ll(e)?e.remove():e.data=e.data.substr(7),this._inlineFiller=null;}_needsInlineFillerAtSelection(){if(1!=this.selection.rangeCount||!this.selection.isCollapsed)return !1;const e=this.selection.getFirstPosition(),t=e.parent,i=e.offset;if(!this.domConverter.mapViewToDom(t.root))return !1;if(!t.is("element"))return !1;if(!function(e){if("false"==e.getAttribute("contenteditable"))return !1;const t=e.findAncestor((e=>e.hasAttribute("contenteditable")));return !t||"true"==t.getAttribute("contenteditable")}(t))return !1;const n=e.nodeBefore,s=e.nodeAfter;return !(n instanceof oa||s instanceof oa)&&(!!(i!==t.getFillerOffset()||n&&n.is("element","br"))&&(!o.isAndroid||!n&&!s))}_updateText(e,t){const i=this.domConverter.findCorrespondingDomText(e);let n=this.domConverter.viewToDom(e).data;const s=t.inlineFillerPosition;s&&s.parent==e.parent&&s.offset==e.index&&(n=rl+n),this._updateTextNode(i,n);}_updateAttrs(e){const t=this.domConverter.mapViewToDom(e);if(t){for(const i of t.attributes){const n=i.name;e.hasAttribute(n)||this.domConverter.removeDomElementAttribute(t,n);}for(const i of e.getAttributeKeys())this.domConverter.setDomElementAttribute(t,i,e.getAttribute(i),e);}}_updateChildren(e,t){const i=this.domConverter.mapViewToDom(e);if(!i)return;if(o.isAndroid){let e=null;for(const t of Array.from(i.childNodes)){if(e&&ko(e)&&ko(t)){i.normalize();break}e=t;}}const n=t.inlineFillerPosition,s=i.childNodes,r=Array.from(this.domConverter.viewChildrenToDom(e,{bind:!0}));n&&n.parent===e&&hl(i.ownerDocument,r,n.offset);const a=this._diffNodeLists(s,r),l=this._findUpdateActions(a,s,r,gl);let c=0;const d=new Set;for(const e of l)"delete"===e?(d.add(s[c]),$o(s[c])):"equal"!==e&&"update"!==e||c++;c=0;for(const e of l)"insert"===e?(Mo(i,c,r[c]),c++):"update"===e?(this._updateTextNode(s[c],r[c].data),c++):"equal"===e&&(this._markDescendantTextToSync(this.domConverter.domToView(r[c])),c++);for(const e of d)e.parentNode||this.domConverter.unbindDomElement(e);}_diffNodeLists(e,t){return e=function(e,t){const i=Array.from(e);if(0==i.length||!t)return i;const n=i[i.length-1];n==t&&i.pop();return i}(e,this._fakeSelectionContainer),b(e,t,fl.bind(null,this.domConverter))}_findUpdateActions(e,t,i,n){if(-1===e.indexOf("insert")||-1===e.indexOf("delete"))return e;let s=[],o=[],r=[];const a={equal:0,insert:0,delete:0};for(const l of e)"insert"===l?r.push(i[a.equal+a.insert]):"delete"===l?o.push(t[a.equal+a.delete]):(s=s.concat(b(o,r,n).map((e=>"equal"===e?"update":e))),s.push("equal"),o=[],r=[]),a[l]++;return s.concat(b(o,r,n).map((e=>"equal"===e?"update":e)))}_updateTextNode(e,t){const i=e.data;i!=t&&(o.isAndroid&&this.isComposing&&i.replace(/\u00A0/g," ")==t.replace(/\u00A0/g," ")||this._updateTextNodeInternal(e,t));}_updateTextNodeInternal(e,t){const i=g(e.data,t);for(const t of i)"insert"===t.type?e.insertData(t.index,t.values.join("")):e.deleteData(t.index,t.howMany);}_markDescendantTextToSync(e){if(e)if(e.is("$text"))this.markedTexts.add(e);else if(e.is("element"))for(const t of e.getChildren())this._markDescendantTextToSync(t);}_updateSelection(){if(o.isBlink&&!o.isAndroid&&this.isSelecting&&!this.markedChildren.size)return;if(0===this.selection.rangeCount)return this._removeDomSelection(),void this._removeFakeSelection();const e=this.domConverter.mapViewToDom(this.selection.editableElement);this.isFocused&&e&&(this.selection.isFake?this._updateFakeSelection(e):this._fakeSelectionContainer&&this._fakeSelectionContainer.isConnected?(this._removeFakeSelection(),this._updateDomSelection(e)):this.isComposing&&o.isAndroid||this._updateDomSelection(e));}_updateFakeSelection(e){const t=e.ownerDocument;this._fakeSelectionContainer||(this._fakeSelectionContainer=function(e){const t=e.createElement("div");return t.className="ck-fake-selection-container",Object.assign(t.style,{position:"fixed",top:0,left:"-9999px",width:"42px"}),t.textContent=" ",t}(t));const i=this._fakeSelectionContainer;if(this.domConverter.bindFakeSelection(i,this.selection),!this._fakeSelectionNeedsUpdate(e))return;i.parentElement&&i.parentElement==e||e.appendChild(i),i.textContent=this.selection.fakeSelectionLabel||" ";const n=t.getSelection(),s=t.createRange();n.removeAllRanges(),s.selectNodeContents(i),n.addRange(s);}_updateDomSelection(e){const t=e.ownerDocument.defaultView.getSelection();if(!this._domSelectionNeedsUpdate(t))return;const i=this.domConverter.viewPositionToDom(this.selection.anchor),n=this.domConverter.viewPositionToDom(this.selection.focus);t.setBaseAndExtent(i.parent,i.offset,n.parent,n.offset),o.isGecko&&function(e,t){let i=e.parent,n=e.offset;ko(i)&&ll(i)&&(n=Bo(i)+1,i=i.parentNode);if(i.nodeType!=Node.ELEMENT_NODE||n!=i.childNodes.length-1)return;const s=i.childNodes[n];s&&"BR"==s.tagName&&t.addRange(t.getRangeAt(0));}(n,t);}_domSelectionNeedsUpdate(e){if(!this.domConverter.isDomSelectionCorrect(e))return !0;const t=e&&this.domConverter.domSelectionToView(e);return (!t||!this.selection.isEqual(t))&&!(!this.selection.isCollapsed&&this.selection.isSimilar(t))}_fakeSelectionNeedsUpdate(e){const t=this._fakeSelectionContainer,i=e.ownerDocument.getSelection();return !t||t.parentElement!==e||(i.anchorNode!==t&&!t.contains(i.anchorNode)||t.textContent!==this.selection.fakeSelectionLabel)}_removeDomSelection(){for(const e of this.domDocuments){const t=e.getSelection();if(t.rangeCount){const i=e.activeElement,n=this.domConverter.mapDomToView(i);i&&n&&t.removeAllRanges();}}}_removeFakeSelection(){const e=this._fakeSelectionContainer;e&&e.remove();}_updateFocus(){if(this.isFocused){const e=this.selection.editableElement;e&&this.domConverter.focus(e);}}};function hl(e,t,i){const n=t instanceof Array?t:t.childNodes,s=n[i];if(ko(s))return s.data=rl+s.data,s;{const s=e.createTextNode(rl);return Array.isArray(t)?n.splice(i,0,s):Mo(t,i,s),s}}function ml(e,t){return uo(e)&&uo(t)&&!ko(e)&&!ko(t)&&!Lo(e)&&!Lo(t)&&e.tagName.toLowerCase()===t.tagName.toLowerCase()}function gl(e,t){return uo(e)&&uo(t)&&ko(e)&&ko(t)}function fl(e,t,i){return t===i||(ko(t)&&ko(i)?t.data===i.data:!(!e.isBlockFiller(t)||!e.isBlockFiller(i)))}const pl=ol(i.document),bl=nl(i.document),wl=sl(i.document),_l="data-ck-unsafe-attribute-",vl="data-ck-unsafe-element";class yl{document;renderingMode;blockFillerMode;preElements;blockElements;inlineObjectElements;unsafeElements;_domDocument;_domToViewMapping=new WeakMap;_viewToDomMapping=new WeakMap;_fakeSelectionMapping=new WeakMap;_rawContentElementMatcher=new aa;_inlineObjectElementMatcher=new aa;_elementsWithTemporaryCustomProperties=new Set;constructor(e,{blockFillerMode:t,renderingMode:n="editing"}={}){this.document=e,this.renderingMode=n,this.blockFillerMode=t||("editing"===n?"br":"nbsp"),this.preElements=["pre","textarea"],this.blockElements=["address","article","aside","blockquote","caption","center","dd","details","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","legend","li","main","menu","nav","ol","p","pre","section","summary","table","tbody","td","tfoot","th","thead","tr","ul"],this.inlineObjectElements=["object","iframe","input","button","textarea","select","option","video","embed","audio","img","canvas"],this.unsafeElements=["script","style"],this._domDocument="editing"===this.renderingMode?i.document:i.document.implementation.createHTMLDocument("");}bindFakeSelection(e,t){this._fakeSelectionMapping.set(e,new Aa(t));}fakeSelectionToView(e){return this._fakeSelectionMapping.get(e)}bindElements(e,t){this._domToViewMapping.set(e,t),this._viewToDomMapping.set(t,e);}unbindDomElement(e){const t=this._domToViewMapping.get(e);if(t){this._domToViewMapping.delete(e),this._viewToDomMapping.delete(t);for(const t of e.children)this.unbindDomElement(t);}}bindDocumentFragments(e,t){this._domToViewMapping.set(e,t),this._viewToDomMapping.set(t,e);}shouldRenderAttribute(e,t,i){return "data"===this.renderingMode||!(e=e.toLowerCase()).startsWith("on")&&(("srcdoc"!==e||!t.match(/\bon\S+\s*=|javascript:|<\s*\/*script/i))&&("img"===i&&("src"===e||"srcset"===e)||("source"===i&&"srcset"===e||!t.match(/^\s*(javascript:|data:(image\/svg|text\/x?html))/i))))}setContentOf(e,t){if("data"===this.renderingMode)return void(e.innerHTML=t);const i=(new DOMParser).parseFromString(t,"text/html"),n=i.createDocumentFragment(),s=i.body.childNodes;for(;s.length>0;)n.appendChild(s[0]);const o=i.createTreeWalker(n,NodeFilter.SHOW_ELEMENT),r=[];let a;for(;a=o.nextNode();)r.push(a);for(const e of r){for(const t of e.getAttributeNames())this.setDomElementAttribute(e,t,e.getAttribute(t));const t=e.tagName.toLowerCase();this._shouldRenameElement(t)&&(xl(t),e.replaceWith(this._createReplacementDomElement(t,e)));}for(;e.firstChild;)e.firstChild.remove();e.append(n);}viewToDom(e,t={}){if(e.is("$text")){const t=this._processDataFromViewText(e);return this._domDocument.createTextNode(t)}{const i=e;if(this.mapViewToDom(i)){if(!i.getCustomProperty("editingPipeline:doNotReuseOnce"))return this.mapViewToDom(i);this._elementsWithTemporaryCustomProperties.add(i);}let n;if(i.is("documentFragment"))n=this._domDocument.createDocumentFragment(),t.bind&&this.bindDocumentFragments(n,i);else {if(i.is("uiElement"))return n="$comment"===i.name?this._domDocument.createComment(i.getCustomProperty("$rawContent")):i.render(this._domDocument,this),t.bind&&this.bindElements(n,i),n;this._shouldRenameElement(i.name)?(xl(i.name),n=this._createReplacementDomElement(i.name)):n=i.hasAttribute("xmlns")?this._domDocument.createElementNS(i.getAttribute("xmlns"),i.name):this._domDocument.createElement(i.name),i.is("rawElement")&&i.render(n,this),t.bind&&this.bindElements(n,i);for(const e of i.getAttributeKeys())this.setDomElementAttribute(n,e,i.getAttribute(e),i);}if(!1!==t.withChildren)for(const e of this.viewChildrenToDom(i,t))n instanceof HTMLTemplateElement?n.content.appendChild(e):n.appendChild(e);return n}}setDomElementAttribute(e,t,i,n){const s=this.shouldRenderAttribute(t,i,e.tagName.toLowerCase())||n&&n.shouldRenderUnsafeAttribute(t);s||E("domconverter-unsafe-attribute-detected",{domElement:e,key:t,value:i}),Fo(t)?(e.hasAttribute(t)&&!s?e.removeAttribute(t):e.hasAttribute(_l+t)&&s&&e.removeAttribute(_l+t),e.setAttribute(s?t:_l+t,i)):E("domconverter-invalid-attribute-detected",{domElement:e,key:t,value:i});}removeDomElementAttribute(e,t){t!=vl&&(e.removeAttribute(t),e.removeAttribute(_l+t));}*viewChildrenToDom(e,t={}){const i=e.getFillerOffset&&e.getFillerOffset();let n=0;for(const s of e.getChildren()){i===n&&(yield this._getBlockFiller());const e=s.is("element")&&!!s.getCustomProperty("dataPipeline:transparentRendering")&&!wr(s.getAttributes());if(e&&"data"==this.renderingMode)if(s.is("rawElement")){const e=this._domDocument.createElement(s.name);s.render(e,this),yield*[...e.childNodes];}else yield*this.viewChildrenToDom(s,t);else e&&E("domconverter-transparent-rendering-unsupported-in-editing-pipeline",{viewElement:s}),yield this.viewToDom(s,t);n++;}i===n&&(yield this._getBlockFiller());}viewRangeToDom(e){const t=this.viewPositionToDom(e.start),i=this.viewPositionToDom(e.end),n=this._domDocument.createRange();return n.setStart(t.parent,t.offset),n.setEnd(i.parent,i.offset),n}viewPositionToDom(e){const t=e.parent;if(t.is("$text")){const i=this.findCorrespondingDomText(t);if(!i)return null;let n=e.offset;return al(i)&&(n+=7),{parent:i,offset:n}}{let i,n,s;if(0===e.offset){if(i=this.mapViewToDom(t),!i)return null;s=i.childNodes[0];}else {const t=e.nodeBefore;if(n=t.is("$text")?this.findCorrespondingDomText(t):this.mapViewToDom(t),!n)return null;i=n.parentNode,s=n.nextSibling;}if(ko(s)&&al(s))return {parent:s,offset:7};return {parent:i,offset:n?Bo(n)+1:0}}}domToView(e,t={}){const i=[],n=this._domToView(e,t,i),s=n.next().value;return s?(n.next(),this._processDomInlineNodes(null,i,t),s.is("$text")&&0==s.data.length?null:s):null}*domChildrenToView(e,t={},i=[]){let n=[];n=e instanceof HTMLTemplateElement?[...e.content.childNodes]:[...e.childNodes];for(let s=0;s{const{scrollLeft:t,scrollTop:i}=e;s.push([t,i]);})),t.focus(),kl(t,(e=>{const[t,i]=s.shift();e.scrollLeft=t,e.scrollTop=i;})),i.window.scrollTo(e,n);}}_clearDomSelection(){const e=this.mapViewToDom(this.document.selection.editableElement);if(!e)return;const t=e.ownerDocument.defaultView.getSelection(),i=this.domSelectionToView(t);i&&i.rangeCount>0&&t.removeAllRanges();}isElement(e){return e&&e.nodeType==Node.ELEMENT_NODE}isDocumentFragment(e){return e&&e.nodeType==Node.DOCUMENT_FRAGMENT_NODE}isBlockFiller(e){return "br"==this.blockFillerMode?e.isEqualNode(pl):!("BR"!==e.tagName||!Cl(e,this.blockElements)||1!==e.parentNode.childNodes.length)||(e.isEqualNode(wl)||function(e,t){const i=e.isEqualNode(bl);return i&&Cl(e,t)&&1===e.parentNode.childNodes.length}(e,this.blockElements))}isDomSelectionBackward(e){if(e.isCollapsed)return !1;const t=this._domDocument.createRange();try{t.setStart(e.anchorNode,e.anchorOffset),t.setEnd(e.focusNode,e.focusOffset);}catch(e){return !1}const i=t.collapsed;return t.detach(),i}getHostViewElement(e){const t=wo(e);for(t.pop();t.length;){const e=t.pop(),i=this._domToViewMapping.get(e);if(i&&(i.is("uiElement")||i.is("rawElement")))return i}return null}isDomSelectionCorrect(e){return this._isDomSelectionPositionCorrect(e.anchorNode,e.anchorOffset)&&this._isDomSelectionPositionCorrect(e.focusNode,e.focusOffset)}registerRawContentMatcher(e){this._rawContentElementMatcher.add(e);}registerInlineObjectMatcher(e){this._inlineObjectElementMatcher.add(e);}_clearTemporaryCustomProperties(){for(const e of this._elementsWithTemporaryCustomProperties)e._removeCustomProperty("editingPipeline:doNotReuseOnce");this._elementsWithTemporaryCustomProperties.clear();}_getBlockFiller(){switch(this.blockFillerMode){case"nbsp":return nl(this._domDocument);case"markedNbsp":return sl(this._domDocument);case"br":return ol(this._domDocument)}}_isDomSelectionPositionCorrect(e,t){if(ko(e)&&al(e)&&t<7)return !1;if(this.isElement(e)&&al(e.childNodes[t]))return !1;const i=this.mapDomToView(e);return !i||!i.is("uiElement")&&!i.is("rawElement")}*_domToView(e,t,i){if(this.isBlockFiller(e))return null;const n=this.getHostViewElement(e);if(n)return n;if(Lo(e)&&t.skipComments)return null;if(ko(e)){if(ll(e))return null;{const t=e.data;if(""===t)return null;const n=new oa(this.document,t);return i.push(n),n}}{let n=this.mapDomToView(e);if(n)return this._isInlineObjectElement(n)&&i.push(n),n;if(this.isDocumentFragment(e))n=new ja(this.document),t.bind&&this.bindDocumentFragments(e,n);else {n=this._createViewElement(e,t),t.bind&&this.bindElements(e,n);const s=e.attributes;if(s)for(let e=s.length,t=0;t0?t[e-1]:null,l=e+1e.is("element")&&t.includes(e.name)))}(e,this.preElements))return !0;for(const t of e.getAncestors({parentFirst:!0}))if(t.is("element")&&t.hasStyle("white-space")&&"inherit"!==t.getStyle("white-space"))return ["pre","pre-wrap","break-spaces"].includes(t.getStyle("white-space"));return !1}_getTouchingInlineViewNode(e,t){const i=new ya({startPosition:t?ka._createAfter(e):ka._createBefore(e),direction:t?"forward":"backward"});for(const{item:e}of i){if(e.is("$textProxy"))return e;if(!e.is("element")||!e.getCustomProperty("dataPipeline:transparentRendering")){if(e.is("element","br"))return null;if(this._isInlineObjectElement(e))return e;if(e.is("containerElement"))return null}}return null}_isBlockDomElement(e){return this.isElement(e)&&this.blockElements.includes(e.tagName.toLowerCase())}_isBlockViewElement(e){return e.is("element")&&this.blockElements.includes(e.name)}_isInlineObjectElement(e){return !!e.is("element")&&("br"==e.name||this.inlineObjectElements.includes(e.name)||!!this._inlineObjectElementMatcher.match(e))}_createViewElement(e,t){if(Lo(e))return new za(this.document,"$comment");const i=t.keepOriginalCase?e.tagName:e.tagName.toLowerCase();return new ga(this.document,i)}_isViewElementWithRawContent(e,t){return !1!==t.withChildren&&e.is("element")&&!!this._rawContentElementMatcher.match(e)}_shouldRenameElement(e){const t=e.toLowerCase();return "editing"===this.renderingMode&&this.unsafeElements.includes(t)}_createReplacementDomElement(e,t){const i=this._domDocument.createElement("span");if(i.setAttribute(vl,e),t){for(;t.firstChild;)i.appendChild(t.firstChild);for(const e of t.getAttributeNames())i.setAttribute(e,t.getAttribute(e));}return i}}function kl(e,t){let i=e;for(;i;)t(i),i=i.parentElement;}function Cl(e,t){const i=e.parentNode;return !!i&&!!i.tagName&&t.includes(i.tagName.toLowerCase())}function xl(e){"script"===e&&E("domconverter-unsafe-script-element-detected"),"style"===e&&E("domconverter-unsafe-style-element-detected");}class Al extends(go()){view;document;_isEnabled=!1;constructor(e){super(),this.view=e,this.document=e.document;}get isEnabled(){return this._isEnabled}enable(){this._isEnabled=!0;}disable(){this._isEnabled=!1;}destroy(){this.disable(),this.stopListening();}checkShouldIgnoreEventFromTarget(e){return e&&3===e.nodeType&&(e=e.parentNode),!(!e||1!==e.nodeType)&&e.matches("[data-cke-ignore-events], [data-cke-ignore-events] *")}}class El{view;document;domEvent;domTarget;constructor(e,t,i){this.view=e,this.document=e.document,this.domEvent=t,this.domTarget=t.target,xt(this,i);}get target(){return this.view.domConverter.mapDomToView(this.domTarget)}preventDefault(){this.domEvent.preventDefault();}stopPropagation(){this.domEvent.stopPropagation();}}class Tl extends Al{useCapture=!1;usePassive=!1;observe(e){("string"==typeof this.domEventType?[this.domEventType]:this.domEventType).forEach((t=>{this.listenTo(e,t,((e,t)=>{this.isEnabled&&!this.checkShouldIgnoreEventFromTarget(t.target)&&this.onDomEvent(t);}),{useCapture:this.useCapture,usePassive:this.usePassive});}));}stopObserving(e){this.stopListening(e);}fire(e,t,i){this.isEnabled&&this.document.fire(e,new El(this.view,t,i));}}class Pl extends Tl{domEventType=["keydown","keyup"];onDomEvent(e){const t={keyCode:e.keyCode,altKey:e.altKey,ctrlKey:e.ctrlKey,shiftKey:e.shiftKey,metaKey:e.metaKey,get keystroke(){return or(this)}};this.fire(e.type,e,t);}}class Sl extends Al{_fireSelectionChangeDoneDebounced;constructor(e){super(e),this._fireSelectionChangeDoneDebounced=vs((e=>{this.document.fire("selectionChangeDone",e);}),200);}observe(){const e=this.document;e.on("arrowKey",((t,i)=>{e.selection.isFake&&this.isEnabled&&i.preventDefault();}),{context:"$capture"}),e.on("arrowKey",((t,i)=>{e.selection.isFake&&this.isEnabled&&this._handleSelectionMove(i.keyCode);}),{priority:"lowest"});}stopObserving(){}destroy(){super.destroy(),this._fireSelectionChangeDoneDebounced.cancel();}_handleSelectionMove(e){const t=this.document.selection,i=new Aa(t.getRanges(),{backward:t.isBackward,fake:!1});e!=nr.arrowleft&&e!=nr.arrowup||i.setTo(i.getFirstPosition()),e!=nr.arrowright&&e!=nr.arrowdown||i.setTo(i.getLastPosition());const n={oldSelection:t,newSelection:i,domSelection:null};this.document.fire("selectionChange",n),this._fireSelectionChangeDoneDebounced(n);}}let Il=class extends Al{domConverter;_config;_domElements;_mutationObserver;constructor(e){super(e),this._config={childList:!0,characterData:!0,subtree:!0},this.domConverter=e.domConverter,this._domElements=new Set,this._mutationObserver=new window.MutationObserver(this._onMutations.bind(this));}flush(){this._onMutations(this._mutationObserver.takeRecords());}observe(e){this._domElements.add(e),this.isEnabled&&this._mutationObserver.observe(e,this._config);}stopObserving(e){if(this._domElements.delete(e),this.isEnabled){this._mutationObserver.disconnect();for(const e of this._domElements)this._mutationObserver.observe(e,this._config);}}enable(){super.enable();for(const e of this._domElements)this._mutationObserver.observe(e,this._config);}disable(){super.disable(),this._mutationObserver.disconnect();}destroy(){super.destroy(),this._mutationObserver.disconnect();}_onMutations(e){if(0===e.length)return;const t=this.domConverter,i=new Set,n=new Set;for(const i of e){const e=t.mapDomToView(i.target);e&&(e.is("uiElement")||e.is("rawElement")||"childList"!==i.type||this._isBogusBrMutation(i)||n.add(e));}for(const s of e){const e=t.mapDomToView(s.target);if((!e||!e.is("uiElement")&&!e.is("rawElement"))&&"characterData"===s.type){const e=t.findCorrespondingViewText(s.target);e&&!n.has(e.parent)?i.add(e):!e&&al(s.target)&&n.add(t.mapDomToView(s.target.parentNode));}}const s=[];for(const e of i)s.push({type:"text",node:e});for(const e of n){const i=t.mapViewToDom(e),n=Array.from(e.getChildren()),c=Array.from(t.domChildrenToView(i,{withChildren:!1}));o=n,r=c,l=void 0,(void 0===(l=(a="function"==typeof(a=Vl)?a:void 0)?a(o,r):void 0)?os(o,r,void 0,a):l)||s.push({type:"children",node:e});}var o,r,a,l;s.length&&this.document.fire("mutations",{mutations:s});}_isBogusBrMutation(e){let t=null;return null===e.nextSibling&&0===e.removedNodes.length&&1==e.addedNodes.length&&(t=this.domConverter.domToView(e.addedNodes[0],{withChildren:!1})),t&&t.is("element","br")}};function Vl(e,t){if(!Array.isArray(e))return e===t||!(!e.is("$text")||!t.is("$text"))&&e.data===t.data}class Rl extends Tl{_renderTimeoutId=null;_isFocusChanging=!1;domEventType=["focus","blur"];constructor(e){super(e),this.useCapture=!0;const t=this.document;t.on("focus",(()=>this._handleFocus())),t.on("blur",((e,t)=>this._handleBlur(t))),t.on("beforeinput",(()=>{t.isFocused||this._handleFocus();}),{priority:"highest"});}flush(){this._isFocusChanging&&(this._isFocusChanging=!1,this.document.isFocused=!0);}onDomEvent(e){this.fire(e.type,e);}destroy(){this._clearTimeout(),super.destroy();}_handleFocus(){this._clearTimeout(),this._isFocusChanging=!0,this._renderTimeoutId=setTimeout((()=>{this._renderTimeoutId=null,this.flush(),this.view.change((()=>{}));}),50);}_handleBlur(e){const t=this.document.selection.editableElement;null!==t&&t!==e.target||(this.document.isFocused=!1,this._isFocusChanging=!1,this.view.change((()=>{})));}_clearTimeout(){this._renderTimeoutId&&(clearTimeout(this._renderTimeoutId),this._renderTimeoutId=null);}}class Ol extends Al{mutationObserver;focusObserver;selection;domConverter;_documents;_fireSelectionChangeDoneDebounced;_clearInfiniteLoopInterval;_documentIsSelectingInactivityTimeoutDebounced;_loopbackCounter;constructor(e){super(e),this.mutationObserver=e.getObserver(Il),this.focusObserver=e.getObserver(Rl),this.selection=this.document.selection,this.domConverter=e.domConverter,this._documents=new WeakSet,this._fireSelectionChangeDoneDebounced=vs((e=>{this.document.fire("selectionChangeDone",e);}),200),this._clearInfiniteLoopInterval=setInterval((()=>this._clearInfiniteLoop()),1e3),this._documentIsSelectingInactivityTimeoutDebounced=vs((()=>this.document.isSelecting=!1),5e3),this._loopbackCounter=0;}observe(e){const t=e.ownerDocument,i=()=>{this.document.isSelecting&&(this._handleSelectionChange(t),this.document.isSelecting=!1,this._documentIsSelectingInactivityTimeoutDebounced.cancel());};this.listenTo(e,"selectstart",(()=>{this.document.isSelecting=!0,this._documentIsSelectingInactivityTimeoutDebounced();}),{priority:"highest"}),this.listenTo(e,"keydown",i,{priority:"highest",useCapture:!0}),this.listenTo(e,"keyup",i,{priority:"highest",useCapture:!0}),this._documents.has(t)||(this.listenTo(t,"mouseup",i,{priority:"highest",useCapture:!0}),this.listenTo(t,"selectionchange",(()=>{this.document.isComposing&&!o.isAndroid||(this._handleSelectionChange(t),this._documentIsSelectingInactivityTimeoutDebounced());})),this.listenTo(this.view.document,"compositionstart",(()=>{this._handleSelectionChange(t);}),{priority:"lowest"}),this._documents.add(t));}stopObserving(e){this.stopListening(e);}destroy(){super.destroy(),clearInterval(this._clearInfiniteLoopInterval),this._fireSelectionChangeDoneDebounced.cancel(),this._documentIsSelectingInactivityTimeoutDebounced.cancel();}_reportInfiniteLoop(){}_handleSelectionChange(e){if(!this.isEnabled)return;const t=e.defaultView.getSelection();if(this.checkShouldIgnoreEventFromTarget(t.anchorNode))return;this.mutationObserver.flush();const i=this.domConverter.domSelectionToView(t);if(0!=i.rangeCount){if(this.view.hasDomSelection=!0,this.focusObserver.flush(),!this.selection.isEqual(i)||!this.domConverter.isDomSelectionCorrect(t))if(++this._loopbackCounter>60)this._reportInfiniteLoop();else if(this.selection.isSimilar(i))this.view.forceRender();else {const e={oldSelection:this.selection,newSelection:i,domSelection:t};this.document.fire("selectionChange",e),this._fireSelectionChangeDoneDebounced(e);}}else this.view.hasDomSelection=!1;}_clearInfiniteLoop(){this._loopbackCounter=0;}}class Bl extends Tl{domEventType=["compositionstart","compositionupdate","compositionend"];constructor(e){super(e);const t=this.document;t.on("compositionstart",(()=>{t.isComposing=!0;}),{priority:"low"}),t.on("compositionend",(()=>{t.isComposing=!1;}),{priority:"low"});}onDomEvent(e){this.fire(e.type,e,{data:e.data});}}class Ml{_files;_native;constructor(e,t={}){this._files=t.cacheFiles?Ll(e):null,this._native=e;}get files(){return this._files||(this._files=Ll(this._native)),this._files}get types(){return this._native.types}getData(e){return this._native.getData(e)}setData(e,t){this._native.setData(e,t);}set effectAllowed(e){this._native.effectAllowed=e;}get effectAllowed(){return this._native.effectAllowed}set dropEffect(e){this._native.dropEffect=e;}get dropEffect(){return this._native.dropEffect}setDragImage(e,t,i){this._native.setDragImage(e,t,i);}get isCanceled(){return "none"==this._native.dropEffect||!!this._native.mozUserCancelled}}function Ll(e){const t=Array.from(e.files||[]),i=Array.from(e.items||[]);return t.length?t:i.filter((e=>"file"===e.kind)).map((e=>e.getAsFile()))}class Fl extends Tl{domEventType="beforeinput";onDomEvent(e){const t=e.getTargetRanges(),i=this.view,n=i.document;let s=null,r=null,a=[];if(e.dataTransfer&&(s=new Ml(e.dataTransfer)),null!==e.data?r=e.data:s&&(r=s.getData("text/plain")),n.selection.isFake)a=Array.from(n.selection.getRanges());else if(t.length)a=t.map((e=>{const t=i.domConverter.domPositionToView(e.startContainer,e.startOffset),n=i.domConverter.domPositionToView(e.endContainer,e.endOffset);return t?i.createRange(t,n):n?i.createRange(n):void 0})).filter((e=>!!e));else if(o.isAndroid){const t=e.target.ownerDocument.defaultView.getSelection();a=Array.from(i.domConverter.domSelectionToView(t).getRanges());}if(o.isAndroid&&"insertCompositionText"==e.inputType&&r&&r.endsWith("\n"))this.fire(e.type,e,{inputType:"insertParagraph",targetRanges:[i.createRange(a[0].end)]});else if("insertText"==e.inputType&&r&&r.includes("\n")){const t=r.split(/\n{1,2}/g);let i=a;for(let o=0;o{if(this.isEnabled&&lr(t.keyCode)){const i=new Ta(this.document,"arrowKey",this.document.selection.getFirstRange());this.document.fire(i,t),i.stop.called&&e.stop();}}));}observe(){}stopObserving(){}}class Dl extends Al{constructor(e){super(e);const t=this.document;t.on("keydown",((e,i)=>{if(!this.isEnabled||i.keyCode!=nr.tab||i.ctrlKey)return;const n=new Ta(t,"tab",t.selection.getFirstRange());t.fire(n,i),n.stop.called&&e.stop();}));}observe(){}stopObserving(){}}let zl=class extends(Zs()){document;domConverter;domRoots=new Map;_renderer;_initialDomRootAttributes=new WeakMap;_observers=new Map;_writer;_ongoingChange=!1;_postFixersInProgress=!1;_renderingDisabled=!1;_hasChangedSinceTheLastRendering=!1;constructor(e){super(),this.document=new Ba(e),this.domConverter=new yl(this.document),this.set("isRenderingInProgress",!1),this.set("hasDomSelection",!1),this._renderer=new ul(this.domConverter,this.document.selection),this._renderer.bind("isFocused","isSelecting","isComposing").to(this.document,"isFocused","isSelecting","isComposing"),this._writer=new qa(this.document),this.addObserver(Il),this.addObserver(Rl),this.addObserver(Ol),this.addObserver(Pl),this.addObserver(Sl),this.addObserver(Bl),this.addObserver(Nl),this.addObserver(Fl),this.addObserver(Dl),this.document.on("arrowKey",dl,{priority:"low"}),Ha(this),this.on("render",(()=>{this._render(),this.document.fire("layoutChanged"),this._hasChangedSinceTheLastRendering=!1;})),this.listenTo(this.document.selection,"change",(()=>{this._hasChangedSinceTheLastRendering=!0;})),this.listenTo(this.document,"change:isFocused",(()=>{this._hasChangedSinceTheLastRendering=!0;})),o.isiOS&&this.listenTo(this.document,"blur",((e,t)=>{this.domConverter.mapDomToView(t.domEvent.relatedTarget)||this.domConverter._clearDomSelection();})),this.listenTo(this.document,"mutations",((e,{mutations:t})=>{t.forEach((e=>this._renderer.markToSync(e.type,e.node)));}),{priority:"low"}),this.listenTo(this.document,"mutations",(()=>{this.forceRender();}),{priority:"lowest"});}attachDomRoot(e,t="main"){const i=this.document.getRoot(t);i._name=e.tagName.toLowerCase();const n={};for(const{name:t,value:s}of Array.from(e.attributes))n[t]=s,"class"===t?this._writer.addClass(s.split(" "),i):i.hasAttribute(t)||this._writer.setAttribute(t,s,i);this._initialDomRootAttributes.set(e,n);const s=()=>{this._writer.setAttribute("contenteditable",(!i.isReadOnly).toString(),i),i.isReadOnly?this._writer.addClass("ck-read-only",i):this._writer.removeClass("ck-read-only",i);};s(),this.domRoots.set(t,e),this.domConverter.bindElements(e,i),this._renderer.markToSync("children",i),this._renderer.markToSync("attributes",i),this._renderer.domDocuments.add(e.ownerDocument),i.on("change:children",((e,t)=>this._renderer.markToSync("children",t))),i.on("change:attributes",((e,t)=>this._renderer.markToSync("attributes",t))),i.on("change:text",((e,t)=>this._renderer.markToSync("text",t))),i.on("change:isReadOnly",(()=>this.change(s))),i.on("change",(()=>{this._hasChangedSinceTheLastRendering=!0;}));for(const i of this._observers.values())i.observe(e,t);}detachDomRoot(e){const t=this.domRoots.get(e);Array.from(t.attributes).forEach((({name:e})=>t.removeAttribute(e)));const i=this._initialDomRootAttributes.get(t);for(const e in i)t.setAttribute(e,i[e]);this.domRoots.delete(e),this.domConverter.unbindDomElement(t);for(const e of this._observers.values())e.stopObserving(t);}getDomRoot(e="main"){return this.domRoots.get(e)}addObserver(e){let t=this._observers.get(e);if(t)return t;t=new e(this),this._observers.set(e,t);for(const[e,i]of this.domRoots)t.observe(i,e);return t.enable(),t}getObserver(e){return this._observers.get(e)}disableObservers(){for(const e of this._observers.values())e.disable();}enableObservers(){for(const e of this._observers.values())e.enable();}scrollToTheSelection({alignToTop:e,forceScroll:t,viewportOffset:i=20,ancestorOffset:n=20}={}){const s=this.document.selection.getFirstRange();if(!s)return;const o=Un({alignToTop:e,forceScroll:t,viewportOffset:i,ancestorOffset:n});"number"==typeof i&&(i={top:i,bottom:i,left:i,right:i});const r={target:this.domConverter.viewRangeToDom(s),viewportOffset:i,ancestorOffset:n,alignToTop:e,forceScroll:t};this.fire("scrollToTheSelection",r,o),Uo(r);}focus(){if(!this.document.isFocused){const e=this.document.selection.editableElement;e&&(this.domConverter.focus(e),this.forceRender());}}change(e){if(this.isRenderingInProgress||this._postFixersInProgress)throw new A("cannot-change-view-tree",this);try{if(this._ongoingChange)return e(this._writer);this._ongoingChange=!0;const t=e(this._writer);return this._ongoingChange=!1,!this._renderingDisabled&&this._hasChangedSinceTheLastRendering&&(this._postFixersInProgress=!0,this.document._callPostFixers(this._writer),this._postFixersInProgress=!1,this.fire("render")),t}catch(e){A.rethrowUnexpectedError(e,this);}}forceRender(){this._hasChangedSinceTheLastRendering=!0,this.getObserver(Rl).flush(),this.change((()=>{}));}destroy(){for(const e of this._observers.values())e.destroy();this.document.destroy(),this.stopListening();}createPositionAt(e,t){return ka._createAt(e,t)}createPositionAfter(e){return ka._createAfter(e)}createPositionBefore(e){return ka._createBefore(e)}createRange(e,t){return new Ca(e,t)}createRangeOn(e){return Ca._createOn(e)}createRangeIn(e){return Ca._createIn(e)}createSelection(...e){return new Aa(...e)}_disableRendering(e){this._renderingDisabled=e,0==e&&this.change((()=>{}));}_render(){this.isRenderingInProgress=!0,this.disableObservers(),this._renderer.render(),this.enableObservers(),this.isRenderingInProgress=!1;}};class Hl{is(){throw new Error("is() method is abstract")}}let $l=class extends Hl{parent=null;_attrs;_index=null;_startOffset=null;constructor(e){super(),this._attrs=xr(e);}get document(){return null}get index(){return this._index}get startOffset(){return this._startOffset}get offsetSize(){return 1}get endOffset(){return null===this.startOffset?null:this.startOffset+this.offsetSize}get nextSibling(){const e=this.index;return null!==e&&this.parent.getChild(e+1)||null}get previousSibling(){const e=this.index;return null!==e&&this.parent.getChild(e-1)||null}get root(){let e=this;for(;e.parent;)e=e.parent;return e}isAttached(){return null!==this.parent&&this.root.isAttached()}getPath(){const e=[];let t=this;for(;t.parent;)e.unshift(t.startOffset),t=t.parent;return e}getAncestors(e={}){const t=[];let i=e.includeSelf?this:this.parent;for(;i;)t[e.parentFirst?"push":"unshift"](i),i=i.parent;return t}getCommonAncestor(e,t={}){const i=this.getAncestors(t),n=e.getAncestors(t);let s=0;for(;i[s]==n[s]&&i[s];)s++;return 0===s?null:i[s-1]}isBefore(e){if(this==e)return !1;if(this.root!==e.root)return !1;const t=this.getPath(),i=e.getPath(),n=so(t,i);switch(n){case"prefix":return !0;case"extension":return !1;default:return t[n](e[t[0]]=t[1],e)),{})),e}_clone(e){return new this.constructor(this._attrs)}_remove(){this.parent._removeChildren(this.index);}_setAttribute(e,t){this._attrs.set(e,t);}_setAttributesTo(e){this._attrs=xr(e);}_removeAttribute(e){return this._attrs.delete(e)}_clearAttributes(){this._attrs.clear();}};$l.prototype.is=function(e){return "node"===e||"model:node"===e};class Ul{_nodes=[];_offsetToNode=[];constructor(e){e&&this._insertNodes(0,e);}[Symbol.iterator](){return this._nodes[Symbol.iterator]()}get length(){return this._nodes.length}get maxOffset(){return this._offsetToNode.length}getNode(e){return this._nodes[e]||null}getNodeAtOffset(e){return this._offsetToNode[e]||null}getNodeIndex(e){return e.index}getNodeStartOffset(e){return e.startOffset}indexToOffset(e){if(e==this._nodes.length)return this.maxOffset;const t=this._nodes[e];if(!t)throw new A("model-nodelist-index-out-of-bounds",this);return this.getNodeStartOffset(t)}offsetToIndex(e){if(e==this._offsetToNode.length)return this._nodes.length;const t=this._offsetToNode[e];if(!t)throw new A("model-nodelist-offset-out-of-bounds",this,{offset:e,nodeList:this});return this.getNodeIndex(t)}_insertNodes(e,t){for(const e of t)if(!(e instanceof $l))throw new A("model-nodelist-insertnodes-not-node",this);const i=Array.from(t),n=function(e){const t=[];for(const i of e){const e=t.length;t.length+=i.offsetSize,t.fill(i,e);}return t}(i);let s=this.indexToOffset(e);this._nodes=Pr(this._nodes,i,e,0),this._offsetToNode=Pr(this._offsetToNode,n,s,0);for(let t=e;te.toJSON()))}}class Wl extends $l{_data;constructor(e,t){super(t),this._data=e||"";}get offsetSize(){return this.data.length}get data(){return this._data}toJSON(){const e=super.toJSON();return e.data=this.data,e}_clone(){return new Wl(this.data,this.getAttributes())}static fromJSON(e){return new Wl(e.data,e.attributes)}}Wl.prototype.is=function(e){return "$text"===e||"model:$text"===e||"text"===e||"model:text"===e||"node"===e||"model:node"===e};class jl extends Hl{textNode;data;offsetInText;constructor(e,t,i){if(super(),this.textNode=e,t<0||t>e.offsetSize)throw new A("model-textproxy-wrong-offsetintext",this);if(i<0||t+i>e.offsetSize)throw new A("model-textproxy-wrong-length",this);this.data=e.data.substring(t,t+i),this.offsetInText=t;}get startOffset(){return null!==this.textNode.startOffset?this.textNode.startOffset+this.offsetInText:null}get offsetSize(){return this.data.length}get endOffset(){return null!==this.startOffset?this.startOffset+this.offsetSize:null}get isPartial(){return this.offsetSize!==this.textNode.offsetSize}get parent(){return this.textNode.parent}get root(){return this.textNode.root}getPath(){const e=this.textNode.getPath();return e.length>0&&(e[e.length-1]+=this.offsetInText),e}getAncestors(e={}){const t=[];let i=e.includeSelf?this:this.parent;for(;i;)t[e.parentFirst?"push":"unshift"](i),i=i.parent;return t}hasAttribute(e){return this.textNode.hasAttribute(e)}getAttribute(e){return this.textNode.getAttribute(e)}getAttributes(){return this.textNode.getAttributes()}getAttributeKeys(){return this.textNode.getAttributeKeys()}}jl.prototype.is=function(e){return "$textProxy"===e||"model:$textProxy"===e||"textProxy"===e||"model:textProxy"===e};class ql extends $l{name;_children=new Ul;constructor(e,t,i){super(t),this.name=e,i&&this._insertChild(0,i);}get childCount(){return this._children.length}get maxOffset(){return this._children.maxOffset}get isEmpty(){return 0===this.childCount}getChild(e){return this._children.getNode(e)}getChildAtOffset(e){return this._children.getNodeAtOffset(e)}getChildren(){return this._children[Symbol.iterator]()}getChildIndex(e){return this._children.getNodeIndex(e)}getChildStartOffset(e){return this._children.getNodeStartOffset(e)}offsetToIndex(e){return this._children.offsetToIndex(e)}getNodeByPath(e){let t=this;for(const i of e)t=t.getChildAtOffset(i);return t}findAncestor(e,t={}){let i=t.includeSelf?this:this.parent;for(;i;){if(i.name===e)return i;i=i.parent;}return null}toJSON(){const e=super.toJSON();if(e.name=this.name,this._children.length>0){e.children=[];for(const t of this._children)e.children.push(t.toJSON());}return e}_clone(e=!1){const t=e?Array.from(this._children).map((e=>e._clone(!0))):void 0;return new ql(this.name,this.getAttributes(),t)}_appendChild(e){this._insertChild(this.childCount,e);}_insertChild(e,t){const i=function(e){if("string"==typeof e)return [new Wl(e)];oo(e)||(e=[e]);return Array.from(e).map((e=>"string"==typeof e?new Wl(e):e instanceof jl?new Wl(e.data,e.getAttributes()):e))}(t);for(const e of i)null!==e.parent&&e._remove(),e.parent=this;this._children._insertNodes(e,i);}_removeChildren(e,t=1){const i=this._children._removeNodes(e,t);for(const e of i)e.parent=null;return i}static fromJSON(e){let t;if(e.children){t=[];for(const i of e.children)i.name?t.push(ql.fromJSON(i)):t.push(Wl.fromJSON(i));}return new ql(e.name,e.attributes,t)}}ql.prototype.is=function(e,t){return t?t===this.name&&("element"===e||"model:element"===e):"element"===e||"model:element"===e||"node"===e||"model:node"===e};class Gl{direction;boundaries;singleCharacters;shallow;ignoreElementEnd;_position;_boundaryStartParent;_boundaryEndParent;_visitedParent;constructor(e){if(!e||!e.boundaries&&!e.startPosition)throw new A("model-tree-walker-no-start-position",null);const t=e.direction||"forward";if("forward"!=t&&"backward"!=t)throw new A("model-tree-walker-unknown-direction",e,{direction:t});this.direction=t,this.boundaries=e.boundaries||null,e.startPosition?this._position=e.startPosition.clone():this._position=Zl._createAt(this.boundaries["backward"==this.direction?"end":"start"]),this.position.stickiness="toNone",this.singleCharacters=!!e.singleCharacters,this.shallow=!!e.shallow,this.ignoreElementEnd=!!e.ignoreElementEnd,this._boundaryStartParent=this.boundaries?this.boundaries.start.parent:null,this._boundaryEndParent=this.boundaries?this.boundaries.end.parent:null,this._visitedParent=this.position.parent;}[Symbol.iterator](){return this}get position(){return this._position}skip(e){let t,i,n,s;do{n=this.position,s=this._visitedParent,({done:t,value:i}=this.next());}while(!t&&e(i));t||(this._position=n,this._visitedParent=s);}next(){return "forward"==this.direction?this._next():this._previous()}_next(){const e=this.position,t=this.position.clone(),i=this._visitedParent;if(null===i.parent&&t.offset===i.maxOffset)return {done:!0,value:void 0};if(i===this._boundaryEndParent&&t.offset==this.boundaries.end.offset)return {done:!0,value:void 0};const n=Jl(t,i),s=n||Ql(t,i,n);if(s instanceof ql){if(this.shallow){if(this.boundaries&&this.boundaries.end.isBefore(t))return {done:!0,value:void 0};t.offset++;}else t.path.push(0),this._visitedParent=s;return this._position=t,Kl("elementStart",s,e,t,1)}if(s instanceof Wl){let n;if(this.singleCharacters)n=1;else {let e=s.endOffset;this._boundaryEndParent==i&&this.boundaries.end.offsete&&(e=this.boundaries.start.offset),n=t.offset-e;}const s=t.offset-o.startOffset,r=new jl(o,s-n,n);return t.offset-=n,this._position=t,Kl("text",r,e,t,n)}return t.path.pop(),this._position=t,this._visitedParent=i.parent,Kl("elementStart",i,e,t,1)}}function Kl(e,t,i,n,s){return {done:!1,value:{type:e,item:t,previousPosition:i,nextPosition:n,length:s}}}class Zl extends Hl{root;path;stickiness;constructor(e,t,i="toNone"){if(super(),!e.is("element")&&!e.is("documentFragment"))throw new A("model-position-root-invalid",e);if(!(t instanceof Array)||0===t.length)throw new A("model-position-path-incorrect-format",e,{path:t});e.is("rootElement")?t=t.slice():(t=[...e.getPath(),...t],e=e.root),this.root=e,this.path=t,this.stickiness=i;}get offset(){return this.path[this.path.length-1]}set offset(e){this.path[this.path.length-1]=e;}get parent(){let e=this.root;for(let t=0;t1)return !1;if(1===t)return Xl(e,this,i);if(-1===t)return Xl(this,e,i)}return this.path.length===e.path.length||(this.path.length>e.path.length?ec(this.path,t):ec(e.path,t))}hasSameParentAs(e){if(this.root!==e.root)return !1;return "same"==so(this.getParentPath(),e.getParentPath())}getTransformedByOperation(e){let t;switch(e.type){case"insert":t=this._getTransformedByInsertOperation(e);break;case"move":case"remove":case"reinsert":t=this._getTransformedByMoveOperation(e);break;case"split":t=this._getTransformedBySplitOperation(e);break;case"merge":t=this._getTransformedByMergeOperation(e);break;default:t=Zl._createAt(this);}return t}_getTransformedByInsertOperation(e){return this._getTransformedByInsertion(e.position,e.howMany)}_getTransformedByMoveOperation(e){return this._getTransformedByMove(e.sourcePosition,e.targetPosition,e.howMany)}_getTransformedBySplitOperation(e){const t=e.movedRange;return t.containsPosition(this)||t.start.isEqual(this)&&"toNext"==this.stickiness?this._getCombined(e.splitPosition,e.moveTargetPosition):e.graveyardPosition?this._getTransformedByMove(e.graveyardPosition,e.insertionPosition,1):this._getTransformedByInsertion(e.insertionPosition,1)}_getTransformedByMergeOperation(e){const t=e.movedRange;let i;return t.containsPosition(this)||t.start.isEqual(this)?(i=this._getCombined(e.sourcePosition,e.targetPosition),e.sourcePosition.isBefore(e.targetPosition)&&(i=i._getTransformedByDeletion(e.deletionPosition,1))):i=this.isEqual(e.deletionPosition)?Zl._createAt(e.deletionPosition):this._getTransformedByMove(e.deletionPosition,e.graveyardPosition,1),i}_getTransformedByDeletion(e,t){const i=Zl._createAt(this);if(this.root!=e.root)return i;if("same"==so(e.getParentPath(),this.getParentPath())){if(e.offsetthis.offset)return null;i.offset-=t;}}else if("prefix"==so(e.getParentPath(),this.getParentPath())){const n=e.path.length-1;if(e.offset<=this.path[n]){if(e.offset+t>this.path[n])return null;i.path[n]-=t;}}return i}_getTransformedByInsertion(e,t){const i=Zl._createAt(this);if(this.root!=e.root)return i;if("same"==so(e.getParentPath(),this.getParentPath()))(e.offset=t;){if(e.path[n]+s!==i.maxOffset)return !1;s=1,n--,i=i.parent;}return !0}(e,i+1))}function ec(e,t){for(;tt+1;){const t=n.maxOffset-i.offset;0!==t&&e.push(new tc(i,i.getShiftedBy(t))),i.path=i.path.slice(0,-1),i.offset++,n=n.parent;}for(;i.path.length<=this.end.path.length;){const t=this.end.path[i.path.length-1],n=t-i.offset;0!==n&&e.push(new tc(i,i.getShiftedBy(n))),i.offset=t,i.path.push(0);}return e}getWalker(e={}){return e.boundaries=this,new Gl(e)}*getItems(e={}){e.boundaries=this,e.ignoreElementEnd=!0;const t=new Gl(e);for(const e of t)yield e.item;}*getPositions(e={}){e.boundaries=this;const t=new Gl(e);yield t.position;for(const e of t)yield e.nextPosition;}getTransformedByOperation(e){switch(e.type){case"insert":return this._getTransformedByInsertOperation(e);case"move":case"remove":case"reinsert":return this._getTransformedByMoveOperation(e);case"split":return [this._getTransformedBySplitOperation(e)];case"merge":return [this._getTransformedByMergeOperation(e)]}return [new tc(this.start,this.end)]}getTransformedByOperations(e){const t=[new tc(this.start,this.end)];for(const i of e)for(let e=0;e0?new this(i,n):new this(n,i)}static _createIn(e){return new this(Zl._createAt(e,0),Zl._createAt(e,e.maxOffset))}static _createOn(e){return this._createFromPositionAndShift(Zl._createBefore(e),e.offsetSize)}static _createFromRanges(e){if(0===e.length)throw new A("range-create-from-ranges-empty-array",null);if(1==e.length)return e[0].clone();const t=e[0];e.sort(((e,t)=>e.start.isAfter(t.start)?1:-1));const i=e.indexOf(t),n=new this(t.start,t.end);for(let t=i-1;t>=0&&e[t].end.isEqual(n.start);t--)n.start=Zl._createAt(e[t].start);for(let t=i+1;t{if(t.viewPosition)return;const i=this._modelToViewMapping.get(t.modelPosition.parent);if(!i)throw new A("mapping-model-position-view-parent-not-found",this,{modelPosition:t.modelPosition});t.viewPosition=this.findPositionIn(i,t.modelPosition.offset);}),{priority:"low"}),this.on("viewToModelPosition",((e,t)=>{if(t.modelPosition)return;const i=this.findMappedViewAncestor(t.viewPosition),n=this._viewToModelMapping.get(i),s=this._toModelOffset(t.viewPosition.parent,t.viewPosition.offset,i);t.modelPosition=Zl._createAt(n,s);}),{priority:"low"});}bindElements(e,t){this._modelToViewMapping.set(e,t),this._viewToModelMapping.set(t,e);}unbindViewElement(e,t={}){const i=this.toModelElement(e);if(this._elementToMarkerNames.has(e))for(const t of this._elementToMarkerNames.get(e))this._unboundMarkerNames.add(t);t.defer?this._deferredBindingRemovals.set(e,e.root):(this._viewToModelMapping.delete(e),this._modelToViewMapping.get(i)==e&&this._modelToViewMapping.delete(i));}unbindModelElement(e){const t=this.toViewElement(e);this._modelToViewMapping.delete(e),this._viewToModelMapping.get(t)==e&&this._viewToModelMapping.delete(t);}bindElementToMarker(e,t){const i=this._markerNameToElements.get(t)||new Set;i.add(e);const n=this._elementToMarkerNames.get(e)||new Set;n.add(t),this._markerNameToElements.set(t,i),this._elementToMarkerNames.set(e,n);}unbindElementFromMarkerName(e,t){const i=this._markerNameToElements.get(t);i&&(i.delete(e),0==i.size&&this._markerNameToElements.delete(t));const n=this._elementToMarkerNames.get(e);n&&(n.delete(t),0==n.size&&this._elementToMarkerNames.delete(e));}flushUnboundMarkerNames(){const e=Array.from(this._unboundMarkerNames);return this._unboundMarkerNames.clear(),e}flushDeferredBindings(){for(const[e,t]of this._deferredBindingRemovals)e.root==t&&this.unbindViewElement(e);this._deferredBindingRemovals=new Map;}clearBindings(){this._modelToViewMapping=new WeakMap,this._viewToModelMapping=new WeakMap,this._markerNameToElements=new Map,this._elementToMarkerNames=new Map,this._unboundMarkerNames=new Set,this._deferredBindingRemovals=new Map;}toModelElement(e){return this._viewToModelMapping.get(e)}toViewElement(e){return this._modelToViewMapping.get(e)}toModelRange(e){return new tc(this.toModelPosition(e.start),this.toModelPosition(e.end))}toViewRange(e){return new Ca(this.toViewPosition(e.start),this.toViewPosition(e.end))}toModelPosition(e){const t={viewPosition:e,mapper:this};return this.fire("viewToModelPosition",t),t.modelPosition}toViewPosition(e,t={}){const i={modelPosition:e,mapper:this,isPhantom:t.isPhantom};return this.fire("modelToViewPosition",i),i.viewPosition}markerNameToElements(e){const t=this._markerNameToElements.get(e);if(!t)return null;const i=new Set;for(const e of t)if(e.is("attributeElement"))for(const t of e.getElementsWithSameId())i.add(t);else i.add(e);return i}registerViewToModelLength(e,t){this._viewToModelLengthCallbacks.set(e,t);}findMappedViewAncestor(e){let t=e.parent;for(;!this._viewToModelMapping.has(t);)t=t.parent;return t}_toModelOffset(e,t,i){if(i!=e){return this._toModelOffset(e.parent,e.index,i)+this._toModelOffset(e,t,e)}if(e.is("$text"))return t;let n=0;for(let i=0;i1?t[0]+":"+t[1]:t[0]}class oc extends(L()){_conversionApi;_firedEventsMap;constructor(e){super(),this._conversionApi={dispatcher:this,...e},this._firedEventsMap=new WeakMap;}convertChanges(e,t,i){const n=this._createConversionApi(i,e.getRefreshedItems());for(const t of e.getMarkersToRemove())this._convertMarkerRemove(t.name,t.range,n);const s=this._reduceChanges(e.getChanges());for(const e of s)"insert"===e.type?this._convertInsert(tc._createFromPositionAndShift(e.position,e.length),n):"reinsert"===e.type?this._convertReinsert(tc._createFromPositionAndShift(e.position,e.length),n):"remove"===e.type?this._convertRemove(e.position,e.length,e.name,n):this._convertAttribute(e.range,e.attributeKey,e.attributeOldValue,e.attributeNewValue,n);n.mapper.flushDeferredBindings();for(const e of n.mapper.flushUnboundMarkerNames()){const i=t.get(e).getRange();this._convertMarkerRemove(e,i,n),this._convertMarkerAdd(e,i,n);}for(const t of e.getMarkersToAdd())this._convertMarkerAdd(t.name,t.range,n);n.consumable.verifyAllConsumed("insert");}convert(e,t,i,n={}){const s=this._createConversionApi(i,void 0,n);this._convertInsert(e,s);for(const[e,i]of t)this._convertMarkerAdd(e,i,s);s.consumable.verifyAllConsumed("insert");}convertSelection(e,t,i){const n=this._createConversionApi(i);this.fire("cleanSelection",{selection:e},n);const s=e.getFirstPosition().root;if(!n.mapper.toViewElement(s))return;const o=Array.from(t.getMarkersAtPosition(e.getFirstPosition()));if(this._addConsumablesForSelection(n.consumable,e,o),this.fire("selection",{selection:e},n),e.isCollapsed){for(const t of o)if(n.consumable.test(e,"addMarker:"+t.name)){const i=t.getRange();if(!rc(e.getFirstPosition(),t,n.mapper))continue;const s={item:e,markerName:t.name,markerRange:i};this.fire(`addMarker:${t.name}`,s,n);}for(const t of e.getAttributeKeys())if(n.consumable.test(e,"attribute:"+t)){const i={item:e,range:e.getFirstRange(),attributeKey:t,attributeOldValue:null,attributeNewValue:e.getAttribute(t)};this.fire(`attribute:${t}:$text`,i,n);}}}_convertInsert(e,t,i={}){i.doNotAddConsumables||this._addConsumablesForInsert(t.consumable,e);for(const i of Array.from(e.getWalker({shallow:!0})).map(ac))this._testAndFire("insert",i,t);}_convertRemove(e,t,i,n){this.fire(`remove:${i}`,{position:e,length:t},n);}_convertAttribute(e,t,i,n,s){this._addConsumablesForRange(s.consumable,e,`attribute:${t}`);for(const o of e){const e={item:o.item,range:tc._createFromPositionAndShift(o.previousPosition,o.length),attributeKey:t,attributeOldValue:i,attributeNewValue:n};this._testAndFire(`attribute:${t}`,e,s);}}_convertReinsert(e,t){const i=Array.from(e.getWalker({shallow:!0}));this._addConsumablesForInsert(t.consumable,i);for(const e of i.map(ac))this._testAndFire("insert",{...e,reconversion:!0},t);}_convertMarkerAdd(e,t,i){if("$graveyard"==t.root.rootName)return;const n=`addMarker:${e}`;if(i.consumable.add(t,n),this.fire(n,{markerName:e,markerRange:t},i),i.consumable.consume(t,n)){this._addConsumablesForRange(i.consumable,t,n);for(const s of t.getItems()){if(!i.consumable.test(s,n))continue;const o={item:s,range:tc._createOn(s),markerName:e,markerRange:t};this.fire(n,o,i);}}}_convertMarkerRemove(e,t,i){"$graveyard"!=t.root.rootName&&this.fire(`removeMarker:${e}`,{markerName:e,markerRange:t},i);}_reduceChanges(e){const t={changes:e};return this.fire("reduceChanges",t),t.changes}_addConsumablesForInsert(e,t){for(const i of t){const t=i.item;if(null===e.test(t,"insert")){e.add(t,"insert");for(const i of t.getAttributeKeys())e.add(t,"attribute:"+i);}}return e}_addConsumablesForRange(e,t,i){for(const n of t.getItems())e.add(n,i);return e}_addConsumablesForSelection(e,t,i){e.add(t,"selection");for(const n of i)e.add(t,"addMarker:"+n.name);for(const i of t.getAttributeKeys())e.add(t,"attribute:"+i);return e}_testAndFire(e,t,i){const n=function(e,t){const i=t.item.is("element")?t.item.name:"$text";return `${e}:${i}`}(e,t),s=t.item.is("$textProxy")?i.consumable._getSymbolForTextProxy(t.item):t.item,o=this._firedEventsMap.get(i),r=o.get(s);if(r){if(r.has(n))return;r.add(n);}else o.set(s,new Set([n]));this.fire(n,t,i);}_testAndFireAddAttributes(e,t){const i={item:e,range:tc._createOn(e)};for(const e of i.item.getAttributeKeys())i.attributeKey=e,i.attributeOldValue=null,i.attributeNewValue=i.item.getAttribute(e),this._testAndFire(`attribute:${e}`,i,t);}_createConversionApi(e,t=new Set,i={}){const n={...this._conversionApi,consumable:new nc,writer:e,options:i,convertItem:e=>this._convertInsert(tc._createOn(e),n),convertChildren:e=>this._convertInsert(tc._createIn(e),n,{doNotAddConsumables:!0}),convertAttributes:e=>this._testAndFireAddAttributes(e,n),canReuseView:e=>!t.has(n.mapper.toModelElement(e))};return this._firedEventsMap.set(n,new Map),n}}function rc(e,t,i){const n=t.getRange(),s=Array.from(e.getAncestors());s.shift(),s.reverse();return !s.some((e=>{if(n.containsItem(e)){return !!i.toViewElement(e).getCustomProperty("addHighlight")}}))}function ac(e){return {item:e.item,range:tc._createFromPositionAndShift(e.previousPosition,e.length)}}class lc extends(L(Hl)){_lastRangeBackward=!1;_attrs=new Map;_ranges=[];constructor(...e){super(),e.length&&this.setTo(...e);}get anchor(){if(this._ranges.length>0){const e=this._ranges[this._ranges.length-1];return this._lastRangeBackward?e.end:e.start}return null}get focus(){if(this._ranges.length>0){const e=this._ranges[this._ranges.length-1];return this._lastRangeBackward?e.start:e.end}return null}get isCollapsed(){return 1===this._ranges.length&&this._ranges[0].isCollapsed}get rangeCount(){return this._ranges.length}get isBackward(){return !this.isCollapsed&&this._lastRangeBackward}isEqual(e){if(this.rangeCount!=e.rangeCount)return !1;if(0===this.rangeCount)return !0;if(!this.anchor.isEqual(e.anchor)||!this.focus.isEqual(e.focus))return !1;for(const t of this._ranges){let i=!1;for(const n of e._ranges)if(t.isEqual(n)){i=!0;break}if(!i)return !1}return !0}*getRanges(){for(const e of this._ranges)yield new tc(e.start,e.end);}getFirstRange(){let e=null;for(const t of this._ranges)e&&!t.start.isBefore(e.start)||(e=t);return e?new tc(e.start,e.end):null}getLastRange(){let e=null;for(const t of this._ranges)e&&!t.end.isAfter(e.end)||(e=t);return e?new tc(e.start,e.end):null}getFirstPosition(){const e=this.getFirstRange();return e?e.start.clone():null}getLastPosition(){const e=this.getLastRange();return e?e.end.clone():null}setTo(...e){let[t,i,n]=e;if("object"==typeof i&&(n=i,i=void 0),null===t)this._setRanges([]);else if(t instanceof lc)this._setRanges(t.getRanges(),t.isBackward);else if(t&&"function"==typeof t.getRanges)this._setRanges(t.getRanges(),t.isBackward);else if(t instanceof tc)this._setRanges([t],!!n&&!!n.backward);else if(t instanceof Zl)this._setRanges([new tc(t)]);else if(t instanceof $l){const e=!!n&&!!n.backward;let s;if("in"==i)s=tc._createIn(t);else if("on"==i)s=tc._createOn(t);else {if(void 0===i)throw new A("model-selection-setto-required-second-parameter",[this,t]);s=new tc(Zl._createAt(t,i));}this._setRanges([s],e);}else {if(!oo(t))throw new A("model-selection-setto-not-selectable",[this,t]);this._setRanges(t,n&&!!n.backward);}}_setRanges(e,t=!1){const i=Array.from(e),n=i.some((t=>{if(!(t instanceof tc))throw new A("model-selection-set-ranges-not-range",[this,e]);return this._ranges.every((e=>!e.isEqual(t)))}));(i.length!==this._ranges.length||n)&&(this._replaceAllRanges(i),this._lastRangeBackward=!!t,this.fire("change:range",{directChange:!0}));}setFocus(e,t){if(null===this.anchor)throw new A("model-selection-setfocus-no-ranges",[this,e]);const i=Zl._createAt(e,t);if("same"==i.compareWith(this.focus))return;const n=this.anchor;this._ranges.length&&this._popRange(),"before"==i.compareWith(n)?(this._pushRange(new tc(i,n)),this._lastRangeBackward=!0):(this._pushRange(new tc(n,i)),this._lastRangeBackward=!1),this.fire("change:range",{directChange:!0});}getAttribute(e){return this._attrs.get(e)}getAttributes(){return this._attrs.entries()}getAttributeKeys(){return this._attrs.keys()}hasAttribute(e){return this._attrs.has(e)}removeAttribute(e){this.hasAttribute(e)&&(this._attrs.delete(e),this.fire("change:attribute",{attributeKeys:[e],directChange:!0}));}setAttribute(e,t){this.getAttribute(e)!==t&&(this._attrs.set(e,t),this.fire("change:attribute",{attributeKeys:[e],directChange:!0}));}getSelectedElement(){return 1!==this.rangeCount?null:this.getFirstRange().getContainedElement()}*getSelectedBlocks(){const e=new WeakSet;for(const t of this.getRanges()){const i=uc(t.start,e);mc(i,t)&&(yield i);for(const i of t.getWalker()){const n=i.item;"elementEnd"==i.type&&dc(n,e,t)&&(yield n);}const n=uc(t.end,e);gc(n,t)&&(yield n);}}containsEntireContent(e=this.anchor.root){const t=Zl._createAt(e,0),i=Zl._createAt(e,"end");return t.isTouching(this.getFirstPosition())&&i.isTouching(this.getLastPosition())}_pushRange(e){this._checkRange(e),this._ranges.push(new tc(e.start,e.end));}_checkRange(e){for(let t=0;t0;)this._popRange();}_popRange(){this._ranges.pop();}}function cc(e,t){return !t.has(e)&&(t.add(e),e.root.document.model.schema.isBlock(e)&&!!e.parent)}function dc(e,t,i){return cc(e,t)&&hc(e,i)}function uc(e,t){const i=e.parent.root.document.model.schema,n=e.parent.getAncestors({parentFirst:!0,includeSelf:!0});let s=!1;const o=n.find((e=>!s&&(s=i.isLimit(e),!s&&cc(e,t))));return n.forEach((e=>t.add(e))),o}function hc(e,t){const i=function(e){const t=e.root.document.model.schema;let i=e.parent;for(;i;){if(t.isBlock(i))return i;i=i.parent;}}(e);if(!i)return !0;return !t.containsRange(tc._createOn(i),!0)}function mc(e,t){return !!e&&(!(!t.isCollapsed&&!e.isEmpty)||!t.start.isTouching(Zl._createAt(e,e.maxOffset))&&hc(e,t))}function gc(e,t){return !!e&&(!(!t.isCollapsed&&!e.isEmpty)||!t.end.isTouching(Zl._createAt(e,0))&&hc(e,t))}lc.prototype.is=function(e){return "selection"===e||"model:selection"===e};class fc extends(L(tc)){constructor(e,t){super(e,t),pc.call(this);}detach(){this.stopListening();}toRange(){return new tc(this.start,this.end)}static fromRange(e){return new fc(e.start,e.end)}}function pc(){this.listenTo(this.root.document.model,"applyOperation",((e,t)=>{const i=t[0];i.isDocumentOperation&&bc.call(this,i);}),{priority:"low"});}function bc(e){const t=this.getTransformedByOperation(e),i=tc._createFromRanges(t),n=!i.isEqual(this),s=function(e,t){switch(t.type){case"insert":return e.containsPosition(t.position);case"move":case"remove":case"reinsert":case"merge":return e.containsPosition(t.sourcePosition)||e.start.isEqual(t.sourcePosition)||e.containsPosition(t.targetPosition);case"split":return e.containsPosition(t.splitPosition)||e.containsPosition(t.insertionPosition)}return !1}(this,e);let o=null;if(n){"$graveyard"==i.root.rootName&&(o="remove"==e.type?e.sourcePosition:e.deletionPosition);const t=this.toRange();this.start=i.start,this.end=i.end,this.fire("change:range",t,{deletionPosition:o});}else s&&this.fire("change:content",this.toRange(),{deletionPosition:o});}fc.prototype.is=function(e){return "liveRange"===e||"model:liveRange"===e||"range"==e||"model:range"===e};const wc="selection:";class _c extends(L(Hl)){_selection;constructor(e){super(),this._selection=new vc(e),this._selection.delegate("change:range").to(this),this._selection.delegate("change:attribute").to(this),this._selection.delegate("change:marker").to(this);}get isCollapsed(){return this._selection.isCollapsed}get anchor(){return this._selection.anchor}get focus(){return this._selection.focus}get rangeCount(){return this._selection.rangeCount}get hasOwnRange(){return this._selection.hasOwnRange}get isBackward(){return this._selection.isBackward}get isGravityOverridden(){return this._selection.isGravityOverridden}get markers(){return this._selection.markers}get _ranges(){return this._selection._ranges}getRanges(){return this._selection.getRanges()}getFirstPosition(){return this._selection.getFirstPosition()}getLastPosition(){return this._selection.getLastPosition()}getFirstRange(){return this._selection.getFirstRange()}getLastRange(){return this._selection.getLastRange()}getSelectedBlocks(){return this._selection.getSelectedBlocks()}getSelectedElement(){return this._selection.getSelectedElement()}containsEntireContent(e){return this._selection.containsEntireContent(e)}destroy(){this._selection.destroy();}getAttributeKeys(){return this._selection.getAttributeKeys()}getAttributes(){return this._selection.getAttributes()}getAttribute(e){return this._selection.getAttribute(e)}hasAttribute(e){return this._selection.hasAttribute(e)}refresh(){this._selection.updateMarkers(),this._selection._updateAttributes(!1);}observeMarkers(e){this._selection.observeMarkers(e);}_setFocus(e,t){this._selection.setFocus(e,t);}_setTo(...e){this._selection.setTo(...e);}_setAttribute(e,t){this._selection.setAttribute(e,t);}_removeAttribute(e){this._selection.removeAttribute(e);}_getStoredAttributes(){return this._selection.getStoredAttributes()}_overrideGravity(){return this._selection.overrideGravity()}_restoreGravity(e){this._selection.restoreGravity(e);}static _getStoreAttributeKey(e){return wc+e}static _isStoreAttributeKey(e){return e.startsWith(wc)}}_c.prototype.is=function(e){return "selection"===e||"model:selection"==e||"documentSelection"==e||"model:documentSelection"==e};class vc extends lc{markers=new br({idProperty:"name"});_model;_document;_attributePriority=new Map;_selectionRestorePosition=null;_hasChangedRange=!1;_overriddenGravityRegister=new Set;_observedMarkers=new Set;constructor(e){super(),this._model=e.model,this._document=e,this.listenTo(this._model,"applyOperation",((e,t)=>{const i=t[0];i.isDocumentOperation&&"marker"!=i.type&&"rename"!=i.type&&"noop"!=i.type&&(0==this._ranges.length&&this._selectionRestorePosition&&this._fixGraveyardSelection(this._selectionRestorePosition),this._selectionRestorePosition=null,this._hasChangedRange&&(this._hasChangedRange=!1,this.fire("change:range",{directChange:!1})));}),{priority:"lowest"}),this.on("change:range",(()=>{this._validateSelectionRanges(this.getRanges());})),this.listenTo(this._model.markers,"update",((e,t,i,n)=>{this._updateMarker(t,n);})),this.listenTo(this._document,"change",((e,t)=>{!function(e,t){const i=e.document.differ;for(const n of i.getChanges()){if("insert"!=n.type)continue;const i=n.position.parent;n.length===i.maxOffset&&e.enqueueChange(t,(e=>{const t=Array.from(i.getAttributeKeys()).filter((e=>e.startsWith(wc)));for(const n of t)e.removeAttribute(n,i);}));}}(this._model,t);}));}get isCollapsed(){return 0===this._ranges.length?this._document._getDefaultRange().isCollapsed:super.isCollapsed}get anchor(){return super.anchor||this._document._getDefaultRange().start}get focus(){return super.focus||this._document._getDefaultRange().end}get rangeCount(){return this._ranges.length?this._ranges.length:1}get hasOwnRange(){return this._ranges.length>0}get isGravityOverridden(){return !!this._overriddenGravityRegister.size}destroy(){for(let e=0;e{if(this._hasChangedRange=!0,t.root==this._document.graveyard){this._selectionRestorePosition=n.deletionPosition;const e=this._ranges.indexOf(t);this._ranges.splice(e,1),t.detach();}})),t}updateMarkers(){if(!this._observedMarkers.size)return;const e=[];let t=!1;for(const t of this._model.markers){const i=t.name.split(":",1)[0];if(!this._observedMarkers.has(i))continue;const n=t.getRange();for(const i of this.getRanges())n.containsRange(i,!i.isCollapsed)&&e.push(t);}const i=Array.from(this.markers);for(const i of e)this.markers.has(i)||(this.markers.add(i),t=!0);for(const i of Array.from(this.markers))e.includes(i)||(this.markers.remove(i),t=!0);t&&this.fire("change:marker",{oldMarkers:i,directChange:!1});}_updateMarker(e,t){const i=e.name.split(":",1)[0];if(!this._observedMarkers.has(i))return;let n=!1;const s=Array.from(this.markers),o=this.markers.has(e);if(t){let i=!1;for(const e of this.getRanges())if(t.containsRange(e,!e.isCollapsed)){i=!0;break}i&&!o?(this.markers.add(e),n=!0):!i&&o&&(this.markers.remove(e),n=!0);}else o&&(this.markers.remove(e),n=!0);n&&this.fire("change:marker",{oldMarkers:s,directChange:!1});}_updateAttributes(e){const t=xr(this._getSurroundingAttributes()),i=xr(this.getAttributes());if(e)this._attributePriority=new Map,this._attrs=new Map;else for(const[e,t]of this._attributePriority)"low"==t&&(this._attrs.delete(e),this._attributePriority.delete(e));this._setAttributesTo(t);const n=[];for(const[e,t]of this.getAttributes())i.has(e)&&i.get(e)===t||n.push(e);for(const[e]of i)this.hasAttribute(e)||n.push(e);n.length>0&&this.fire("change:attribute",{attributeKeys:n,directChange:!1});}_setAttribute(e,t,i=!0){const n=i?"normal":"low";if("low"==n&&"normal"==this._attributePriority.get(e))return !1;return super.getAttribute(e)!==t&&(this._attrs.set(e,t),this._attributePriority.set(e,n),!0)}_removeAttribute(e,t=!0){const i=t?"normal":"low";return ("low"!=i||"normal"!=this._attributePriority.get(e))&&(this._attributePriority.set(e,i),!!super.hasAttribute(e)&&(this._attrs.delete(e),!0))}_setAttributesTo(e){const t=new Set;for(const[t,i]of this.getAttributes())e.get(t)!==i&&this._removeAttribute(t,!1);for(const[i,n]of e){this._setAttribute(i,n,!1)&&t.add(i);}return t}*getStoredAttributes(){const e=this.getFirstPosition().parent;if(this.isCollapsed&&e.isEmpty)for(const t of e.getAttributeKeys())if(t.startsWith(wc)){const i=t.substr(10);yield [i,e.getAttribute(t)];}}_getSurroundingAttributes(){const e=this.getFirstPosition(),t=this._model.schema;if("$graveyard"==e.root.rootName)return null;let i=null;if(this.isCollapsed){const n=e.textNode?e.textNode:e.nodeBefore,s=e.textNode?e.textNode:e.nodeAfter;if(this.isGravityOverridden||(i=yc(n,t)),i||(i=yc(s,t)),!this.isGravityOverridden&&!i){let e=n;for(;e&&!i;)e=e.previousSibling,i=yc(e,t);}if(!i){let e=s;for(;e&&!i;)e=e.nextSibling,i=yc(e,t);}i||(i=this.getStoredAttributes());}else {const e=this.getFirstRange();for(const n of e){if(n.item.is("element")&&t.isObject(n.item)){i=yc(n.item,t);break}if("text"==n.type){i=n.item.getAttributes();break}}}return i}_fixGraveyardSelection(e){const t=this._model.schema.getNearestSelectionRange(e);t&&this._pushRange(t);}}function yc(e,t){if(!e)return null;if(e instanceof jl||e instanceof Wl)return e.getAttributes();if(!t.isInline(e))return null;if(!t.isObject(e))return [];const i=[];for(const[n,s]of e.getAttributes())t.checkAttribute("$text",n)&&!1!==t.getAttributeProperties(n).copyFromObject&&i.push([n,s]);return i}class kc{_dispatchers;constructor(e){this._dispatchers=e;}add(e){for(const t of this._dispatchers)e(t);return this}}class Cc extends kc{elementToElement(e){return this.add(function(e){const t=Sc(e.model),i=Ic(e.view,"container");t.attributes.length&&(t.children=!0);return n=>{n.on(`insert:${t.name}`,Ec(i,Mc(t)),{priority:e.converterPriority||"normal"}),(t.children||t.attributes.length)&&n.on("reduceChanges",Bc(t),{priority:"low"});}}(e))}elementToStructure(e){return this.add(function(e){const t=Sc(e.model),i=Ic(e.view,"container");return t.children=!0,n=>{if(n._conversionApi.schema.checkChild(t.name,"$text"))throw new A("conversion-element-to-structure-disallowed-text",n,{elementName:t.name});var s,o;n.on(`insert:${t.name}`,(s=i,o=Mc(t),(e,t,i)=>{if(!o(t.item,i.consumable,{preflight:!0}))return;const n=new Map;i.writer._registerSlotFactory(function(e,t,i){return (n,s)=>{const o=n.createContainerElement("$slot");let r=null;if("children"===s)r=Array.from(e.getChildren());else {if("function"!=typeof s)throw new A("conversion-slot-mode-unknown",i.dispatcher,{modeOrFilter:s});r=Array.from(e.getChildren()).filter((e=>s(e)));}return t.set(o,r),o}}(t.item,n,i));const r=s(t.item,i,t);if(i.writer._clearSlotFactory(),!r)return;!function(e,t,i){const n=Array.from(t.values()).flat(),s=new Set(n);if(s.size!=n.length)throw new A("conversion-slot-filter-overlap",i.dispatcher,{element:e});if(s.size!=e.childCount)throw new A("conversion-slot-filter-incomplete",i.dispatcher,{element:e})}(t.item,n,i),o(t.item,i.consumable);const a=i.mapper.toViewPosition(t.range.start);i.mapper.bindElements(t.item,r),i.writer.insert(a,r),i.convertAttributes(t.item),function(e,t,i,n){i.mapper.on("modelToViewPosition",r,{priority:"highest"});let s=null,o=null;for([s,o]of t)Lc(e,o,i,n),i.writer.move(i.writer.createRangeIn(s),i.writer.createPositionBefore(s)),i.writer.remove(s);function r(e,t){const i=t.modelPosition.nodeAfter,n=o.indexOf(i);n<0||(t.viewPosition=t.mapper.findPositionIn(s,n));}i.mapper.off("modelToViewPosition",r);}(r,n,i,{reconversion:t.reconversion});}),{priority:e.converterPriority||"normal"}),n.on("reduceChanges",Bc(t),{priority:"low"});}}(e))}attributeToElement(e){return this.add(function(e){e=Un(e);let t=e.model;"string"==typeof t&&(t={key:t});let i=`attribute:${t.key}`;t.name&&(i+=":"+t.name);if(t.values)for(const i of t.values)e.view[i]=Ic(e.view[i],"attribute");else e.view=Ic(e.view,"attribute");const n=Vc(e);return t=>{t.on(i,Ac(n),{priority:e.converterPriority||"normal"});}}(e))}attributeToAttribute(e){return this.add(function(e){e=Un(e);let t=e.model;"string"==typeof t&&(t={key:t});let i=`attribute:${t.key}`;t.name&&(i+=":"+t.name);if(t.values)for(const i of t.values)e.view[i]=Rc(e.view[i]);else e.view=Rc(e.view);const n=Vc(e);return t=>{var s;t.on(i,(s=n,(e,t,i)=>{if(!i.consumable.test(t.item,e.name))return;const n=s(t.attributeOldValue,i,t),o=s(t.attributeNewValue,i,t);if(!n&&!o)return;i.consumable.consume(t.item,e.name);const r=i.mapper.toViewElement(t.item),a=i.writer;if(!r)throw new A("conversion-attribute-to-attribute-on-text",i.dispatcher,t);if(null!==t.attributeOldValue&&n)if("class"==n.key){const e="string"==typeof n.value?n.value.split(/\s+/):n.value;for(const t of e)a.removeClass(t,r);}else if("style"==n.key)if("string"==typeof n.value){const e=new da(a.document.stylesProcessor);e.setTo(n.value);for(const[t]of e.getStylesEntries())a.removeStyle(t,r);}else {const e=Object.keys(n.value);for(const t of e)a.removeStyle(t,r);}else a.removeAttribute(n.key,r);if(null!==t.attributeNewValue&&o)if("class"==o.key){const e="string"==typeof o.value?o.value.split(/\s+/):o.value;for(const t of e)a.addClass(t,r);}else if("style"==o.key)if("string"==typeof o.value){const e=new da(a.document.stylesProcessor);e.setTo(o.value);for(const[t,i]of e.getStylesEntries())a.setStyle(t,i,r);}else {const e=Object.keys(o.value);for(const t of e)a.setStyle(t,o.value[t],r);}else a.setAttribute(o.key,o.value,r);}),{priority:e.converterPriority||"normal"});}}(e))}markerToElement(e){return this.add(function(e){const t=Ic(e.view,"ui");return i=>{i.on(`addMarker:${e.model}`,Tc(t),{priority:e.converterPriority||"normal"}),i.on(`removeMarker:${e.model}`,((e,t,i)=>{const n=i.mapper.markerNameToElements(t.markerName);if(n){for(const e of n)i.mapper.unbindElementFromMarkerName(e,t.markerName),i.writer.clear(i.writer.createRangeOn(e),e);i.writer.clearClonedElementsGroup(t.markerName),e.stop();}}),{priority:e.converterPriority||"normal"});}}(e))}markerToHighlight(e){return this.add(function(e){return t=>{var i;t.on(`addMarker:${e.model}`,(i=e.view,(e,t,n)=>{if(!t.item)return;if(!(t.item instanceof lc||t.item instanceof _c||t.item.is("$textProxy")))return;const s=Oc(i,t,n);if(!s)return;if(!n.consumable.consume(t.item,e.name))return;const o=n.writer,r=xc(o,s),a=o.document.selection;if(t.item instanceof lc||t.item instanceof _c)o.wrap(a.getFirstRange(),r);else {const e=n.mapper.toViewRange(t.range),i=o.wrap(e,r);for(const e of i.getItems())if(e.is("attributeElement")&&e.isSimilar(r)){n.mapper.bindElementToMarker(e,t.markerName);break}}}),{priority:e.converterPriority||"normal"}),t.on(`addMarker:${e.model}`,function(e){return (t,i,n)=>{if(!i.item)return;if(!(i.item instanceof ql))return;const s=Oc(e,i,n);if(!s)return;if(!n.consumable.test(i.item,t.name))return;const o=n.mapper.toViewElement(i.item);if(o&&o.getCustomProperty("addHighlight")){n.consumable.consume(i.item,t.name);for(const e of tc._createIn(i.item))n.consumable.consume(e.item,t.name);o.getCustomProperty("addHighlight")(o,s,n.writer),n.mapper.bindElementToMarker(o,i.markerName);}}}(e.view),{priority:e.converterPriority||"normal"}),t.on(`removeMarker:${e.model}`,function(e){return (t,i,n)=>{if(i.markerRange.isCollapsed)return;const s=Oc(e,i,n);if(!s)return;const o=xc(n.writer,s),r=n.mapper.markerNameToElements(i.markerName);if(r){for(const e of r)if(n.mapper.unbindElementFromMarkerName(e,i.markerName),e.is("attributeElement"))n.writer.unwrap(n.writer.createRangeOn(e),o);else {e.getCustomProperty("removeHighlight")(e,s.id,n.writer);}n.writer.clearClonedElementsGroup(i.markerName),t.stop();}}}(e.view),{priority:e.converterPriority||"normal"});}}(e))}markerToData(e){return this.add(function(e){e=Un(e);const t=e.model;let i=e.view;i||(i=i=>({group:t,name:i.substr(e.model.length+1)}));return n=>{var s;n.on(`addMarker:${t}`,(s=i,(e,t,i)=>{const n=s(t.markerName,i);if(!n)return;const o=t.markerRange;i.consumable.consume(o,e.name)&&(Pc(o,!1,i,t,n),Pc(o,!0,i,t,n),e.stop());}),{priority:e.converterPriority||"normal"}),n.on(`removeMarker:${t}`,function(e){return (t,i,n)=>{const s=e(i.markerName,n);if(!s)return;const o=n.mapper.markerNameToElements(i.markerName);if(o){for(const e of o)n.mapper.unbindElementFromMarkerName(e,i.markerName),e.is("containerElement")?(r(`data-${s.group}-start-before`,e),r(`data-${s.group}-start-after`,e),r(`data-${s.group}-end-before`,e),r(`data-${s.group}-end-after`,e)):n.writer.clear(n.writer.createRangeOn(e),e);n.writer.clearClonedElementsGroup(i.markerName),t.stop();}function r(e,t){if(t.hasAttribute(e)){const i=new Set(t.getAttribute(e).split(","));i.delete(s.name),0==i.size?n.writer.removeAttribute(e,t):n.writer.setAttribute(e,Array.from(i).join(","),t);}}}}(i),{priority:e.converterPriority||"normal"});}}(e))}}function xc(e,t){const i=e.createAttributeElement("span",t.attributes);return t.classes&&i._addClass(t.classes),"number"==typeof t.priority&&(i._priority=t.priority),i._id=t.id,i}function Ac(e){return (t,i,n)=>{if(!n.consumable.test(i.item,t.name))return;const s=e(i.attributeOldValue,n,i),o=e(i.attributeNewValue,n,i);if(!s&&!o)return;n.consumable.consume(i.item,t.name);const r=n.writer,a=r.document.selection;if(i.item instanceof lc||i.item instanceof _c)r.wrap(a.getFirstRange(),o);else {let e=n.mapper.toViewRange(i.range);null!==i.attributeOldValue&&s&&(e=r.unwrap(e,s)),null!==i.attributeNewValue&&o&&r.wrap(e,o);}}}function Ec(e,t=Nc){return (i,n,s)=>{if(!t(n.item,s.consumable,{preflight:!0}))return;const o=e(n.item,s,n);if(!o)return;t(n.item,s.consumable);const r=s.mapper.toViewPosition(n.range.start);s.mapper.bindElements(n.item,o),s.writer.insert(r,o),s.convertAttributes(n.item),Lc(o,n.item.getChildren(),s,{reconversion:n.reconversion});}}function Tc(e){return (t,i,n)=>{i.isOpening=!0;const s=e(i,n);i.isOpening=!1;const o=e(i,n);if(!s||!o)return;const r=i.markerRange;if(r.isCollapsed&&!n.consumable.consume(r,t.name))return;for(const e of r)if(!n.consumable.consume(e.item,t.name))return;const a=n.mapper,l=n.writer;l.insert(a.toViewPosition(r.start),s),n.mapper.bindElementToMarker(s,i.markerName),r.isCollapsed||(l.insert(a.toViewPosition(r.end),o),n.mapper.bindElementToMarker(o,i.markerName)),t.stop();}}function Pc(e,t,i,n,s){const o=t?e.start:e.end,r=o.nodeAfter&&o.nodeAfter.is("element")?o.nodeAfter:null,a=o.nodeBefore&&o.nodeBefore.is("element")?o.nodeBefore:null;if(r||a){let e,o;t&&r||!t&&!a?(e=r,o=!0):(e=a,o=!1);const l=i.mapper.toViewElement(e);if(l)return void function(e,t,i,n,s,o){const r=`data-${o.group}-${t?"start":"end"}-${i?"before":"after"}`,a=e.hasAttribute(r)?e.getAttribute(r).split(","):[];a.unshift(o.name),n.writer.setAttribute(r,a.join(","),e),n.mapper.bindElementToMarker(e,s.markerName);}(l,t,o,i,n,s)}!function(e,t,i,n,s){const o=`${s.group}-${t?"start":"end"}`,r=s.name?{name:s.name}:null,a=i.writer.createUIElement(o,r);i.writer.insert(e,a),i.mapper.bindElementToMarker(a,n.markerName);}(i.mapper.toViewPosition(o),t,i,n,s);}function Sc(e){return "string"==typeof e&&(e={name:e}),{name:e.name,attributes:e.attributes?gr(e.attributes):[],children:!!e.children}}function Ic(e,t){return "function"==typeof e?e:(i,n)=>function(e,t,i){"string"==typeof e&&(e={name:e});let n;const s=t.writer,o=Object.assign({},e.attributes);if("container"==i)n=s.createContainerElement(e.name,o);else if("attribute"==i){const t={priority:e.priority||Ma.DEFAULT_PRIORITY};n=s.createAttributeElement(e.name,o,t);}else n=s.createUIElement(e.name,o);if(e.styles){const t=Object.keys(e.styles);for(const i of t)s.setStyle(i,e.styles[i],n);}if(e.classes){const t=e.classes;if("string"==typeof t)s.addClass(t,n);else for(const e of t)s.addClass(e,n);}return n}(e,n,t)}function Vc(e){return e.model.values?(t,i,n)=>{const s=e.view[t];return s?s(t,i,n):null}:e.view}function Rc(e){return "string"==typeof e?t=>({key:e,value:t}):"object"==typeof e?e.value?()=>e:t=>({key:e.key,value:t}):e}function Oc(e,t,i){const n="function"==typeof e?e(t,i):e;return n?(n.priority||(n.priority=10),n.id||(n.id=t.markerName),n):null}function Bc(e){const t=function(e){return (t,i)=>{if(!t.is("element",e.name))return !1;if("attribute"==i.type){if(e.attributes.includes(i.attributeKey))return !0}else if(e.children)return !0;return !1}}(e);return (e,i)=>{const n=[];i.reconvertedElements||(i.reconvertedElements=new Set);for(const e of i.changes){const s="attribute"==e.type?e.range.start.nodeAfter:e.position.parent;if(s&&t(s,e)){if(!i.reconvertedElements.has(s)){i.reconvertedElements.add(s);const e=Zl._createBefore(s);let t=n.length;for(let i=n.length-1;i>=0;i--){const s=n[i],o=("attribute"==s.type?s.range.start:s.position).compareWith(e);if("before"==o||"remove"==s.type&&"same"==o)break;t=i;}n.splice(t,0,{type:"remove",name:s.name,position:e,length:1},{type:"reinsert",name:s.name,position:e,length:1});}}else n.push(e);}i.changes=n;}}function Mc(e){return (t,i,n={})=>{const s=["insert"];for(const i of e.attributes)t.hasAttribute(i)&&s.push(`attribute:${i}`);return !!s.every((e=>i.test(t,e)))&&(n.preflight||s.forEach((e=>i.consume(t,e))),!0)}}function Lc(e,t,i,n){for(const s of t)Fc(e.root,s,i,n)||i.convertItem(s);}function Fc(e,t,i,n){const{writer:s,mapper:o}=i;if(!n.reconversion)return !1;const r=o.toViewElement(t);return !(!r||r.root==e)&&(!!i.canReuseView(r)&&(s.move(s.createRangeOn(r),o.toViewPosition(Zl._createBefore(t))),!0))}function Nc(e,t,{preflight:i}={}){return i?t.test(e,"insert"):t.consume(e,"insert")}function Dc(e){const{schema:t,document:i}=e.model;for(const n of i.getRoots())if(n.isEmpty&&!t.checkChild(n,"$text")&&t.checkChild(n,"paragraph"))return e.insertElement("paragraph",n),!0;return !1}function zc(e,t,i){const n=i.createContext(e);return !!i.checkChild(n,"paragraph")&&!!i.checkChild(n.push("paragraph"),t)}function Hc(e,t){const i=t.createElement("paragraph");return t.insert(i,e),t.createPositionAt(i,0)}class $c extends kc{elementToElement(e){return this.add(Uc(e))}elementToAttribute(e){return this.add(function(e){e=Un(e),qc(e);const t=Gc(e,!1),i=Wc(e.view),n=i?`element:${i}`:"element";return i=>{i.on(n,t,{priority:e.converterPriority||"low"});}}(e))}attributeToAttribute(e){return this.add(function(e){e=Un(e);let t=null;("string"==typeof e.view||e.view.key)&&(t=function(e){"string"==typeof e.view&&(e.view={key:e.view});const t=e.view.key,i=void 0===e.view.value?/[\s\S]*/:e.view.value;let n;if("class"==t||"style"==t){const e="class"==t?"classes":"styles";n={[e]:i};}else n={attributes:{[t]:i}};e.view.name&&(n.name=e.view.name);return e.view=n,t}(e));qc(e,t);const i=Gc(e,!0);return t=>{t.on("element",i,{priority:e.converterPriority||"low"});}}(e))}elementToMarker(e){return this.add(function(e){const t=function(e){return (t,i)=>{const n="string"==typeof e?e:e(t,i);return i.writer.createElement("$marker",{"data-name":n})}}(e.model);return Uc({...e,model:t})}(e))}dataToMarker(e){return this.add(function(e){e=Un(e),e.model||(e.model=t=>t?e.view+":"+t:e.view);const t={view:e.view,model:e.model},i=jc(Kc(t,"start")),n=jc(Kc(t,"end"));return s=>{s.on(`element:${e.view}-start`,i,{priority:e.converterPriority||"normal"}),s.on(`element:${e.view}-end`,n,{priority:e.converterPriority||"normal"});const o=C.low,r=C.highest,a=C.get(e.converterPriority)/r;s.on("element",function(e){return (t,i,n)=>{const s=`data-${e.view}`;function o(t,s){for(const o of s){const s=e.model(o,n),r=n.writer.createElement("$marker",{"data-name":s});n.writer.insert(r,t),i.modelCursor.isEqual(t)?i.modelCursor=i.modelCursor.getShiftedBy(1):i.modelCursor=i.modelCursor._getTransformedByInsertion(t,1),i.modelRange=i.modelRange._getTransformedByInsertion(t,1)[0];}}(n.consumable.test(i.viewItem,{attributes:s+"-end-after"})||n.consumable.test(i.viewItem,{attributes:s+"-start-after"})||n.consumable.test(i.viewItem,{attributes:s+"-end-before"})||n.consumable.test(i.viewItem,{attributes:s+"-start-before"}))&&(i.modelRange||Object.assign(i,n.convertChildren(i.viewItem,i.modelCursor)),n.consumable.consume(i.viewItem,{attributes:s+"-end-after"})&&o(i.modelRange.end,i.viewItem.getAttribute(s+"-end-after").split(",")),n.consumable.consume(i.viewItem,{attributes:s+"-start-after"})&&o(i.modelRange.end,i.viewItem.getAttribute(s+"-start-after").split(",")),n.consumable.consume(i.viewItem,{attributes:s+"-end-before"})&&o(i.modelRange.start,i.viewItem.getAttribute(s+"-end-before").split(",")),n.consumable.consume(i.viewItem,{attributes:s+"-start-before"})&&o(i.modelRange.start,i.viewItem.getAttribute(s+"-start-before").split(",")));}}(t),{priority:o+a});}}(e))}}function Uc(e){const t=jc(e=Un(e)),i=Wc(e.view),n=i?`element:${i}`:"element";return i=>{i.on(n,t,{priority:e.converterPriority||"normal"});}}function Wc(e){return "string"==typeof e?e:"object"==typeof e&&"string"==typeof e.name?e.name:null}function jc(e){const t=new aa(e.view);return (i,n,s)=>{const o=t.match(n.viewItem);if(!o)return;const r=o.match;if(r.name=!0,!s.consumable.test(n.viewItem,r))return;const a=function(e,t,i){return e instanceof Function?e(t,i):i.writer.createElement(e)}(e.model,n.viewItem,s);a&&s.safeInsert(a,n.modelCursor)&&(s.consumable.consume(n.viewItem,r),s.convertChildren(n.viewItem,a),s.updateConversionResult(a,n));}}function qc(e,t=null){const i=null===t||(e=>e.getAttribute(t)),n="object"!=typeof e.model?e.model:e.model.key,s="object"!=typeof e.model||void 0===e.model.value?i:e.model.value;e.model={key:n,value:s};}function Gc(e,t){const i=new aa(e.view);return (n,s,o)=>{if(!s.modelRange&&t)return;const r=i.match(s.viewItem);if(!r)return;if(!function(e,t){const i="function"==typeof e?e(t):e;if("object"==typeof i&&!Wc(i))return !1;return !i.classes&&!i.attributes&&!i.styles}(e.view,s.viewItem)?delete r.match.name:r.match.name=!0,!o.consumable.test(s.viewItem,r.match))return;const a=e.model.key,l="function"==typeof e.model.value?e.model.value(s.viewItem,o):e.model.value;if(null===l)return;s.modelRange||Object.assign(s,o.convertChildren(s.viewItem,s.modelCursor));const c=function(e,t,i,n){let s=!1;for(const o of Array.from(e.getItems({shallow:i})))n.schema.checkAttribute(o,t.key)&&(s=!0,o.hasAttribute(t.key)||n.writer.setAttribute(t.key,t.value,o));return s}(s.modelRange,{key:a,value:l},t,o);c&&(o.consumable.test(s.viewItem,{name:!0})&&(r.match.name=!0),o.consumable.consume(s.viewItem,r.match));}}function Kc(e,t){return {view:`${e.view}-${t}`,model:(t,i)=>{const n=t.getAttribute("name"),s=e.model(n,i);return i.writer.createElement("$marker",{"data-name":s})}}}function Zc(e){e.document.registerPostFixer((t=>function(e,t){const i=t.document.selection,n=t.schema,s=[];let o=!1;for(const e of i.getRanges()){const t=Jc(e,n);t&&!t.isEqual(e)?(s.push(t),o=!0):s.push(e);}o&&e.setSelection(function(e){const t=[...e],i=new Set;let n=1;for(;n!i.has(t)))}(s),{backward:i.isBackward});return !1}(t,e)));}function Jc(e,t){return e.isCollapsed?function(e,t){const i=e.start,n=t.getNearestSelectionRange(i);if(!n){const e=i.getAncestors().reverse().find((e=>t.isObject(e)));return e?tc._createOn(e):null}if(!n.isCollapsed)return n;const s=n.start;if(i.isEqual(s))return null;return new tc(s)}(e,t):function(e,t){const{start:i,end:n}=e,s=t.checkChild(i,"$text"),o=t.checkChild(n,"$text"),r=t.getLimitElement(i),a=t.getLimitElement(n);if(r===a){if(s&&o)return null;if(function(e,t,i){const n=e.nodeAfter&&!i.isLimit(e.nodeAfter)||i.checkChild(e,"$text"),s=t.nodeBefore&&!i.isLimit(t.nodeBefore)||i.checkChild(t,"$text");return n||s}(i,n,t)){const e=i.nodeAfter&&t.isSelectable(i.nodeAfter)?null:t.getNearestSelectionRange(i,"forward"),s=n.nodeBefore&&t.isSelectable(n.nodeBefore)?null:t.getNearestSelectionRange(n,"backward"),o=e?e.start:i,r=s?s.end:n;return new tc(o,r)}}const l=r&&!r.is("rootElement"),c=a&&!a.is("rootElement");if(l||c){const e=i.nodeAfter&&n.nodeBefore&&i.nodeAfter.parent===n.nodeBefore.parent,s=l&&(!e||!Yc(i.nodeAfter,t)),o=c&&(!e||!Yc(n.nodeBefore,t));let d=i,u=n;return s&&(d=Zl._createBefore(Qc(r,t))),o&&(u=Zl._createAfter(Qc(a,t))),new tc(d,u)}return null}(e,t)}function Qc(e,t){let i=e,n=i;for(;t.isLimit(n)&&n.parent;)i=n,n=n.parent;return i}function Yc(e,t){return e&&t.isSelectable(e)}class Xc extends(Zs()){model;view;mapper;downcastDispatcher;constructor(e,t){super(),this.model=e,this.view=new zl(t),this.mapper=new ic,this.downcastDispatcher=new oc({mapper:this.mapper,schema:e.schema});const i=this.model.document,n=i.selection,s=this.model.markers;var r,a,l;this.listenTo(this.model,"_beforeChanges",(()=>{this.view._disableRendering(!0);}),{priority:"highest"}),this.listenTo(this.model,"_afterChanges",(()=>{this.view._disableRendering(!1);}),{priority:"lowest"}),this.listenTo(i,"change",(()=>{this.view.change((e=>{this.downcastDispatcher.convertChanges(i.differ,s,e),this.downcastDispatcher.convertSelection(n,s,e);}));}),{priority:"low"}),this.listenTo(this.view.document,"selectionChange",function(e,t){return (i,n)=>{const s=n.newSelection,o=[];for(const e of s.getRanges())o.push(t.toModelRange(e));const r=e.createSelection(o,{backward:s.isBackward});r.isEqual(e.document.selection)||e.change((e=>{e.setSelection(r);}));}}(this.model,this.mapper)),this.listenTo(this.view.document,"beforeinput",(r=this.mapper,a=this.model.schema,l=this.view,(e,t)=>{if(!l.document.isComposing||o.isAndroid)for(let e=0;e{if(!i.consumable.consume(t.item,e.name))return;const n=i.writer,s=i.mapper.toViewPosition(t.range.start),o=n.createText(t.item.data);n.insert(s,o);}),{priority:"lowest"}),this.downcastDispatcher.on("insert",((e,t,i)=>{i.convertAttributes(t.item),t.reconversion||!t.item.is("element")||t.item.isEmpty||i.convertChildren(t.item);}),{priority:"lowest"}),this.downcastDispatcher.on("remove",((e,t,i)=>{const n=i.mapper.toViewPosition(t.position),s=t.position.getShiftedBy(t.length),o=i.mapper.toViewPosition(s,{isPhantom:!0}),r=i.writer.createRange(n,o),a=i.writer.remove(r.getTrimmed());for(const e of i.writer.createRangeIn(a).getItems())i.mapper.unbindViewElement(e,{defer:!0});}),{priority:"low"}),this.downcastDispatcher.on("cleanSelection",((e,t,i)=>{const n=i.writer,s=n.document.selection;for(const e of s.getRanges())e.isCollapsed&&e.end.parent.isAttached()&&i.writer.mergeAttributes(e.start);n.setSelection(null);})),this.downcastDispatcher.on("selection",((e,t,i)=>{const n=t.selection;if(n.isCollapsed)return;if(!i.consumable.consume(n,"selection"))return;const s=[];for(const e of n.getRanges())s.push(i.mapper.toViewRange(e));i.writer.setSelection(s,{backward:n.isBackward});}),{priority:"low"}),this.downcastDispatcher.on("selection",((e,t,i)=>{const n=t.selection;if(!n.isCollapsed)return;if(!i.consumable.consume(n,"selection"))return;const s=i.writer,o=n.getFirstPosition(),r=i.mapper.toViewPosition(o),a=s.breakAttributes(r);s.setSelection(a);}),{priority:"low"}),this.view.document.roots.bindTo(this.model.document.roots).using((e=>{if("$graveyard"==e.rootName)return null;const t=new va(this.view.document,e.name);return t.rootName=e.rootName,this.mapper.bindElements(e,t),t}));}destroy(){this.view.destroy(),this.stopListening();}reconvertMarker(e){const t="string"==typeof e?e:e.name,i=this.model.markers.get(t);if(!i)throw new A("editingcontroller-reconvertmarker-marker-not-exist",this,{markerName:t});this.model.change((()=>{this.model.markers._refresh(i);}));}reconvertItem(e){this.model.change((()=>{this.model.document.differ._refreshItem(e);}));}}class ed{_consumables=new Map;add(e,t){let i;e.is("$text")||e.is("documentFragment")?this._consumables.set(e,!0):(this._consumables.has(e)?i=this._consumables.get(e):(i=new id(e),this._consumables.set(e,i)),i.add(t));}test(e,t){const i=this._consumables.get(e);return void 0===i?null:e.is("$text")||e.is("documentFragment")?i:i.test(t)}consume(e,t){return !!this.test(e,t)&&(e.is("$text")||e.is("documentFragment")?this._consumables.set(e,!1):this._consumables.get(e).consume(t),!0)}revert(e,t){const i=this._consumables.get(e);void 0!==i&&(e.is("$text")||e.is("documentFragment")?this._consumables.set(e,!0):i.revert(t));}static consumablesFromElement(e){const t={element:e,name:!0,attributes:[],classes:[],styles:[]},i=e.getAttributeKeys();for(const e of i)"style"!=e&&"class"!=e&&t.attributes.push(e);const n=e.getClassNames();for(const e of n)t.classes.push(e);const s=e.getStyleNames();for(const e of s)t.styles.push(e);return t}static createFrom(e,t){if(t||(t=new ed),e.is("$text"))return t.add(e),t;e.is("element")&&t.add(e,ed.consumablesFromElement(e)),e.is("documentFragment")&&t.add(e);for(const i of e.getChildren())t=ed.createFrom(i,t);return t}}const td=["attributes","classes","styles"];class id{element;_canConsumeName;_consumables;constructor(e){this.element=e,this._canConsumeName=null,this._consumables={attributes:new Map,styles:new Map,classes:new Map};}add(e){e.name&&(this._canConsumeName=!0);for(const t of td)t in e&&this._add(t,e[t]);}test(e){if(e.name&&!this._canConsumeName)return this._canConsumeName;for(const t of td)if(t in e){const i=this._test(t,e[t]);if(!0!==i)return i}return !0}consume(e){e.name&&(this._canConsumeName=!1);for(const t of td)t in e&&this._consume(t,e[t]);}revert(e){e.name&&(this._canConsumeName=!0);for(const t of td)t in e&&this._revert(t,e[t]);}_add(e,t){const i=gr(t),n=this._consumables[e];for(const t of i){if("attributes"===e&&("class"===t||"style"===t))throw new A("viewconsumable-invalid-attribute",this);if(n.set(t,!0),"styles"===e)for(const e of this.element.document.stylesProcessor.getRelatedStyles(t))n.set(e,!0);}}_test(e,t){const i=gr(t),n=this._consumables[e];for(const t of i)if("attributes"!==e||"class"!==t&&"style"!==t){const e=n.get(t);if(void 0===e)return null;if(!e)return !1}else {const e="class"==t?"classes":"styles",i=this._test(e,[...this._consumables[e].keys()]);if(!0!==i)return i}return !0}_consume(e,t){const i=gr(t),n=this._consumables[e];for(const t of i)if("attributes"!==e||"class"!==t&&"style"!==t){if(n.set(t,!1),"styles"==e)for(const e of this.element.document.stylesProcessor.getRelatedStyles(t))n.set(e,!1);}else {const e="class"==t?"classes":"styles";this._consume(e,[...this._consumables[e].keys()]);}}_revert(e,t){const i=gr(t),n=this._consumables[e];for(const t of i)if("attributes"!==e||"class"!==t&&"style"!==t){!1===n.get(t)&&n.set(t,!0);}else {const e="class"==t?"classes":"styles";this._revert(e,[...this._consumables[e].keys()]);}}}class nd extends(Zs()){_sourceDefinitions={};_attributeProperties=Object.create(null);_customChildChecks=new Map;_customAttributeChecks=new Map;_genericCheckSymbol=Symbol("$generic");_compiledDefinitions;constructor(){super(),this.decorate("checkChild"),this.decorate("checkAttribute"),this.on("checkAttribute",((e,t)=>{t[0]=new sd(t[0]);}),{priority:"highest"}),this.on("checkChild",((e,t)=>{t[0]=new sd(t[0]),t[1]=this.getDefinition(t[1]);}),{priority:"highest"});}register(e,t){if(this._sourceDefinitions[e])throw new A("schema-cannot-register-item-twice",this,{itemName:e});this._sourceDefinitions[e]=[Object.assign({},t)],this._clearCache();}extend(e,t){if(!this._sourceDefinitions[e])throw new A("schema-cannot-extend-missing-item",this,{itemName:e});this._sourceDefinitions[e].push(Object.assign({},t)),this._clearCache();}getDefinitions(){return this._compiledDefinitions||this._compile(),this._compiledDefinitions}getDefinition(e){let t;return t="string"==typeof e?e:"is"in e&&(e.is("$text")||e.is("$textProxy"))?"$text":e.name,this.getDefinitions()[t]}isRegistered(e){return !!this.getDefinition(e)}isBlock(e){const t=this.getDefinition(e);return !(!t||!t.isBlock)}isLimit(e){const t=this.getDefinition(e);return !!t&&!(!t.isLimit&&!t.isObject)}isObject(e){const t=this.getDefinition(e);return !!t&&!!(t.isObject||t.isLimit&&t.isSelectable&&t.isContent)}isInline(e){const t=this.getDefinition(e);return !(!t||!t.isInline)}isSelectable(e){const t=this.getDefinition(e);return !!t&&!(!t.isSelectable&&!t.isObject)}isContent(e){const t=this.getDefinition(e);return !!t&&!(!t.isContent&&!t.isObject)}checkChild(e,t){return !!t&&this._checkContextMatch(e,t)}checkAttribute(e,t){const i=this.getDefinition(e.last);if(!i)return !1;const n=this._evaluateAttributeChecks(e,t);return void 0!==n?n:i.allowAttributes.includes(t)}checkMerge(e,t){if(e instanceof Zl){const t=e.nodeBefore,i=e.nodeAfter;if(!(t instanceof ql))throw new A("schema-check-merge-no-element-before",this);if(!(i instanceof ql))throw new A("schema-check-merge-no-element-after",this);return this.checkMerge(t,i)}if(this.isLimit(e)||this.isLimit(t))return !1;for(const i of t.getChildren())if(!this.checkChild(e,i))return !1;return !0}addChildCheck(e,t){const i=void 0!==t?t:this._genericCheckSymbol,n=this._customChildChecks.get(i)||[];n.push(e),this._customChildChecks.set(i,n);}addAttributeCheck(e,t){const i=void 0!==t?t:this._genericCheckSymbol,n=this._customAttributeChecks.get(i)||[];n.push(e),this._customAttributeChecks.set(i,n);}setAttributeProperties(e,t){this._attributeProperties[e]=Object.assign(this.getAttributeProperties(e),t);}getAttributeProperties(e){return this._attributeProperties[e]||Object.create(null)}getLimitElement(e){let t;if(e instanceof Zl)t=e.parent;else {t=(e instanceof tc?[e]:Array.from(e.getRanges())).reduce(((e,t)=>{const i=t.getCommonAncestor();return e?e.getCommonAncestor(i,{includeSelf:!0}):i}),null);}for(;!this.isLimit(t)&&t.parent;)t=t.parent;return t}checkAttributeInSelection(e,t){if(e.isCollapsed){const i=[...e.getFirstPosition().getAncestors(),new Wl("",e.getAttributes())];return this.checkAttribute(i,t)}{const i=e.getRanges();for(const e of i)for(const i of e)if(this.checkAttribute(i.item,t))return !0}return !1}*getValidRanges(e,t){e=function*(e){for(const t of e)yield*t.getMinimalFlatRanges();}(e);for(const i of e)yield*this._getValidRangesForRange(i,t);}getNearestSelectionRange(e,t="both"){if("$graveyard"==e.root.rootName)return null;if(this.checkChild(e,"$text"))return new tc(e);let i,n;const s=e.getAncestors().reverse().find((e=>this.isLimit(e)))||e.root;"both"!=t&&"backward"!=t||(i=new Gl({boundaries:tc._createIn(s),startPosition:e,direction:"backward"})),"both"!=t&&"forward"!=t||(n=new Gl({boundaries:tc._createIn(s),startPosition:e}));for(const e of function*(e,t){let i=!1;for(;!i;){if(i=!0,e){const t=e.next();t.done||(i=!1,yield {walker:e,value:t.value});}if(t){const e=t.next();e.done||(i=!1,yield {walker:t,value:e.value});}}}(i,n)){const t=e.walker==i?"elementEnd":"elementStart",n=e.value;if(n.type==t&&this.isObject(n.item))return tc._createOn(n.item);if(this.checkChild(n.nextPosition,"$text"))return new tc(n.nextPosition)}return null}findAllowedParent(e,t){let i=e.parent;for(;i;){if(this.checkChild(i,t))return i;if(this.isLimit(i))return null;i=i.parent;}return null}setAllowedAttributes(e,t,i){const n=i.model;for(const[s,o]of Object.entries(t))n.schema.checkAttribute(e,s)&&i.setAttribute(s,o,e);}removeDisallowedAttributes(e,t){for(const i of e)if(i.is("$text"))bd(this,i,t);else {const e=tc._createIn(i).getPositions();for(const i of e){bd(this,i.nodeBefore||i.parent,t);}}}getAttributesWithProperty(e,t,i){const n={};for(const[s,o]of e.getAttributes()){const e=this.getAttributeProperties(s);void 0!==e[t]&&(void 0!==i&&i!==e[t]||(n[s]=o));}return n}createContext(e){return new sd(e)}_clearCache(){this._compiledDefinitions=null;}_compile(){const e={},t=this._sourceDefinitions,i=Object.keys(t);for(const n of i)e[n]=od(t[n],n);const n=Object.values(e);for(const t of n)rd(e,t),ad(e,t),ld(e,t),cd(e,t);for(const t of n)dd(e,t);for(const t of n)ud(e,t);for(const t of n)hd(e,t);for(const t of n)md(e,t);for(const t of n)gd(e,t);this._compiledDefinitions=function(e){const t={};for(const i of Object.values(e))t[i.name]={name:i.name,isBlock:!!i.isBlock,isContent:!!i.isContent,isInline:!!i.isInline,isLimit:!!i.isLimit,isObject:!!i.isObject,isSelectable:!!i.isSelectable,allowIn:Array.from(i.allowIn).filter((t=>!!e[t])),allowChildren:Array.from(i.allowChildren).filter((t=>!!e[t])),allowAttributes:Array.from(i.allowAttributes)};return t}(e);}_checkContextMatch(e,t){const i=e.last;let n=this._evaluateChildChecks(e,t);if(n=void 0!==n?n:t.allowIn.includes(i.name),!n)return !1;const s=this.getDefinition(i),o=e.trimLast();return !!s&&(0==o.length||this._checkContextMatch(o,s))}_evaluateChildChecks(e,t){const i=this._customChildChecks.get(this._genericCheckSymbol)||[],n=this._customChildChecks.get(t.name)||[];for(const s of [...i,...n]){const i=s(e,t);if(void 0!==i)return i}}_evaluateAttributeChecks(e,t){const i=this._customAttributeChecks.get(this._genericCheckSymbol)||[],n=this._customAttributeChecks.get(t)||[];for(const s of [...i,...n]){const i=s(e,t);if(void 0!==i)return i}}*_getValidRangesForRange(e,t){let i=e.start,n=e.start;for(const s of e.getItems({shallow:!0}))s.is("element")&&(yield*this._getValidRangesForRange(tc._createIn(s),t)),this.checkAttribute(s,t)||(i.isEqual(n)||(yield new tc(i,n)),i=Zl._createAfter(s)),n=Zl._createAfter(s);i.isEqual(n)||(yield new tc(i,n));}findOptimalInsertionRange(e,t){const i=e.getSelectedElement();if(i&&this.isObject(i)&&!this.isInline(i))return "before"==t||"after"==t?new tc(Zl._createAt(i,t)):tc._createOn(i);const n=wr(e.getSelectedBlocks());if(!n)return new tc(e.focus);if(n.isEmpty)return new tc(Zl._createAt(n,0));const s=Zl._createAfter(n);return e.focus.isTouching(s)?new tc(s):new tc(Zl._createBefore(n))}}class sd{_items;constructor(e){if(e instanceof sd)return e;let t;t="string"==typeof e?[e]:Array.isArray(e)?e:e.getAncestors({includeSelf:!0}),this._items=t.map(pd);}get length(){return this._items.length}get last(){return this._items[this._items.length-1]}[Symbol.iterator](){return this._items[Symbol.iterator]()}push(e){const t=new sd([e]);return t._items=[...this._items,...t._items],t}trimLast(){const e=new sd([]);return e._items=this._items.slice(0,-1),e}getItem(e){return this._items[e]}*getNames(){yield*this._items.map((e=>e.name));}endsWith(e){return Array.from(this.getNames()).join(" ").endsWith(e)}startsWith(e){return Array.from(this.getNames()).join(" ").startsWith(e)}}function od(e,t){const i={name:t,allowIn:new Set,allowChildren:new Set,disallowIn:new Set,disallowChildren:new Set,allowContentOf:new Set,allowWhere:new Set,allowAttributes:new Set,disallowAttributes:new Set,allowAttributesOf:new Set,inheritTypesFrom:new Set};return function(e,t){for(const i of e){const e=Object.keys(i).filter((e=>e.startsWith("is")));for(const n of e)t[n]=!!i[n];}}(e,i),fd(e,i,"allowIn"),fd(e,i,"allowChildren"),fd(e,i,"disallowIn"),fd(e,i,"disallowChildren"),fd(e,i,"allowContentOf"),fd(e,i,"allowWhere"),fd(e,i,"allowAttributes"),fd(e,i,"disallowAttributes"),fd(e,i,"allowAttributesOf"),fd(e,i,"inheritTypesFrom"),function(e,t){for(const i of e){const e=i.inheritAllFrom;e&&(t.allowContentOf.add(e),t.allowWhere.add(e),t.allowAttributesOf.add(e),t.inheritTypesFrom.add(e));}}(e,i),i}function rd(e,t){for(const i of t.allowIn){const n=e[i];n?n.allowChildren.add(t.name):t.allowIn.delete(i);}}function ad(e,t){for(const i of t.allowChildren){const n=e[i];n?n.allowIn.add(t.name):t.allowChildren.delete(i);}}function ld(e,t){for(const i of t.disallowIn){const n=e[i];n?n.disallowChildren.add(t.name):t.disallowIn.delete(i);}}function cd(e,t){for(const i of t.disallowChildren){const n=e[i];n?n.disallowIn.add(t.name):t.disallowChildren.delete(i);}}function dd(e,t){for(const e of t.disallowChildren)t.allowChildren.delete(e);for(const e of t.disallowIn)t.allowIn.delete(e);for(const e of t.disallowAttributes)t.allowAttributes.delete(e);}function ud(e,t){for(const i of t.allowContentOf){const n=e[i];n&&(n.disallowChildren.forEach((i=>{t.allowChildren.has(i)||(t.disallowChildren.add(i),e[i].disallowIn.add(t.name));})),n.allowChildren.forEach((i=>{t.disallowChildren.has(i)||(t.allowChildren.add(i),e[i].allowIn.add(t.name));})));}}function hd(e,t){for(const i of t.allowWhere){const n=e[i];n&&(n.disallowIn.forEach((i=>{t.allowIn.has(i)||(t.disallowIn.add(i),e[i].disallowChildren.add(t.name));})),n.allowIn.forEach((i=>{t.disallowIn.has(i)||(t.allowIn.add(i),e[i].allowChildren.add(t.name));})));}}function md(e,t){for(const i of t.allowAttributesOf){const n=e[i];if(!n)return;n.allowAttributes.forEach((e=>{t.disallowAttributes.has(e)||t.allowAttributes.add(e);}));}}function gd(e,t){for(const i of t.inheritTypesFrom){const n=e[i];if(n){const e=Object.keys(n).filter((e=>e.startsWith("is")));for(const i of e)i in t||(t[i]=n[i]);}}}function fd(e,t,i){for(const n of e){let e=n[i];"string"==typeof e&&(e=[e]),Array.isArray(e)&&e.forEach((e=>t[i].add(e)));}}function pd(e){return "string"==typeof e||e.is("documentFragment")?{name:"string"==typeof e?e:"$documentFragment",*getAttributeKeys(){},getAttribute(){}}:{name:e.is("element")?e.name:"$text",*getAttributeKeys(){yield*e.getAttributeKeys();},getAttribute:t=>e.getAttribute(t)}}function bd(e,t,i){for(const n of t.getAttributeKeys())e.checkAttribute(t,n)||i.removeAttribute(n,t);}class wd extends(L()){conversionApi;_splitParts=new Map;_cursorParents=new Map;_modelCursor=null;_emptyElementsToKeep=new Set;constructor(e){super(),this.conversionApi={...e,consumable:null,writer:null,store:null,convertItem:(e,t)=>this._convertItem(e,t),convertChildren:(e,t)=>this._convertChildren(e,t),safeInsert:(e,t)=>this._safeInsert(e,t),updateConversionResult:(e,t)=>this._updateConversionResult(e,t),splitToAllowedParent:(e,t)=>this._splitToAllowedParent(e,t),getSplitParts:e=>this._getSplitParts(e),keepEmptyElement:e=>this._keepEmptyElement(e)};}convert(e,t,i=["$root"]){this.fire("viewCleanup",e),this._modelCursor=function(e,t){let i;for(const n of new sd(e)){const e={};for(const t of n.getAttributeKeys())e[t]=n.getAttribute(t);const s=t.createElement(n.name,e);i&&t.insert(s,i),i=Zl._createAt(s,0);}return i}(i,t),this.conversionApi.writer=t,this.conversionApi.consumable=ed.createFrom(e),this.conversionApi.store={};const{modelRange:n}=this._convertItem(e,this._modelCursor),s=t.createDocumentFragment();if(n){this._removeEmptyElements();for(const e of Array.from(this._modelCursor.parent.getChildren()))t.append(e,s);s.markers=function(e,t){const i=new Set,n=new Map,s=tc._createIn(e).getItems();for(const e of s)e.is("element","$marker")&&i.add(e);for(const e of i){const i=e.getAttribute("data-name"),s=t.createPositionBefore(e);n.has(i)?n.get(i).end=s.clone():n.set(i,new tc(s.clone())),t.remove(e);}return n}(s,t);}return this._modelCursor=null,this._splitParts.clear(),this._cursorParents.clear(),this._emptyElementsToKeep.clear(),this.conversionApi.writer=null,this.conversionApi.store=null,s}_convertItem(e,t){const i={viewItem:e,modelCursor:t,modelRange:null};if(e.is("element")?this.fire(`element:${e.name}`,i,this.conversionApi):e.is("$text")?this.fire("text",i,this.conversionApi):this.fire("documentFragment",i,this.conversionApi),i.modelRange&&!(i.modelRange instanceof tc))throw new A("view-conversion-dispatcher-incorrect-result",this);return {modelRange:i.modelRange,modelCursor:i.modelCursor}}_convertChildren(e,t){let i=t.is("position")?t:Zl._createAt(t,0);const n=new tc(i);for(const t of Array.from(e.getChildren())){const e=this._convertItem(t,i);e.modelRange instanceof tc&&(n.end=e.modelRange.end,i=e.modelCursor);}return {modelRange:n,modelCursor:i}}_safeInsert(e,t){const i=this._splitToAllowedParent(e,t);return !!i&&(this.conversionApi.writer.insert(e,i.position),!0)}_updateConversionResult(e,t){const i=this._getSplitParts(e),n=this.conversionApi.writer;t.modelRange||(t.modelRange=n.createRange(n.createPositionBefore(e),n.createPositionAfter(i[i.length-1])));const s=this._cursorParents.get(e);t.modelCursor=s?n.createPositionAt(s,0):t.modelRange.end;}_splitToAllowedParent(e,t){const{schema:i,writer:n}=this.conversionApi;let s=i.findAllowedParent(t,e);if(s){if(s===t.parent)return {position:t};this._modelCursor.parent.getAncestors().includes(s)&&(s=null);}if(!s)return zc(t,e,i)?{position:Hc(t,n)}:null;const o=this.conversionApi.writer.split(t,s),r=[];for(const e of o.range.getWalker())if("elementEnd"==e.type)r.push(e.item);else {const t=r.pop(),i=e.item;this._registerSplitPair(t,i);}const a=o.range.end.parent;return this._cursorParents.set(e,a),{position:o.position,cursorParent:a}}_registerSplitPair(e,t){this._splitParts.has(e)||this._splitParts.set(e,[e]);const i=this._splitParts.get(e);this._splitParts.set(t,i),i.push(t);}_getSplitParts(e){let t;return t=this._splitParts.has(e)?this._splitParts.get(e):[e],t}_keepEmptyElement(e){this._emptyElementsToKeep.add(e);}_removeEmptyElements(){let e=!1;for(const t of this._splitParts.keys())t.isEmpty&&!this._emptyElementsToKeep.has(t)&&(this.conversionApi.writer.remove(t),this._splitParts.delete(t),e=!0);e&&this._removeEmptyElements();}}class _d{getHtml(e){const t=i.document.implementation.createHTMLDocument("").createElement("div");return t.appendChild(e),t.innerHTML}}class vd{domParser;domConverter;htmlWriter;skipComments=!0;constructor(e){this.domParser=new DOMParser,this.domConverter=new yl(e,{renderingMode:"data"}),this.htmlWriter=new _d;}toData(e){const t=this.domConverter.viewToDom(e);return this.htmlWriter.getHtml(t)}toView(e){const t=this._toDom(e);return this.domConverter.domToView(t,{skipComments:this.skipComments})}registerRawContentMatcher(e){this.domConverter.registerRawContentMatcher(e);}useFillerType(e){this.domConverter.blockFillerMode="marked"==e?"markedNbsp":"nbsp";}_toDom(e){/<(?:html|body|head|meta)(?:\s[^>]*)?>/i.test(e.trim().slice(0,1e4))||(e=`${e}`);const t=this.domParser.parseFromString(e,"text/html"),i=t.createDocumentFragment(),n=t.body.childNodes;for(;n.length>0;)i.appendChild(n[0]);return i}}class yd extends(L()){model;mapper;downcastDispatcher;upcastDispatcher;viewDocument;stylesProcessor;htmlProcessor;processor;_viewWriter;constructor(e,t){super(),this.model=e,this.mapper=new ic,this.downcastDispatcher=new oc({mapper:this.mapper,schema:e.schema}),this.downcastDispatcher.on("insert:$text",((e,t,i)=>{if(!i.consumable.consume(t.item,e.name))return;const n=i.writer,s=i.mapper.toViewPosition(t.range.start),o=n.createText(t.item.data);n.insert(s,o);}),{priority:"lowest"}),this.downcastDispatcher.on("insert",((e,t,i)=>{i.convertAttributes(t.item),t.reconversion||!t.item.is("element")||t.item.isEmpty||i.convertChildren(t.item);}),{priority:"lowest"}),this.upcastDispatcher=new wd({schema:e.schema}),this.viewDocument=new Ba(t),this.stylesProcessor=t,this.htmlProcessor=new vd(this.viewDocument),this.processor=this.htmlProcessor,this._viewWriter=new qa(this.viewDocument),this.upcastDispatcher.on("text",((e,t,{schema:i,consumable:n,writer:s})=>{let o=t.modelCursor;if(!n.test(t.viewItem))return;if(!i.checkChild(o,"$text")){if(!zc(o,"$text",i))return;if(0==t.viewItem.data.trim().length)return;o=Hc(o,s);}n.consume(t.viewItem);const r=s.createText(t.viewItem.data);s.insert(r,o),t.modelRange=s.createRange(o,o.getShiftedBy(r.offsetSize)),t.modelCursor=t.modelRange.end;}),{priority:"lowest"}),this.upcastDispatcher.on("element",((e,t,i)=>{if(!t.modelRange&&i.consumable.consume(t.viewItem,{name:!0})){const{modelRange:e,modelCursor:n}=i.convertChildren(t.viewItem,t.modelCursor);t.modelRange=e,t.modelCursor=n;}}),{priority:"lowest"}),this.upcastDispatcher.on("documentFragment",((e,t,i)=>{if(!t.modelRange&&i.consumable.consume(t.viewItem,{name:!0})){const{modelRange:e,modelCursor:n}=i.convertChildren(t.viewItem,t.modelCursor);t.modelRange=e,t.modelCursor=n;}}),{priority:"lowest"}),Zs().prototype.decorate.call(this,"init"),Zs().prototype.decorate.call(this,"set"),Zs().prototype.decorate.call(this,"get"),Zs().prototype.decorate.call(this,"toView"),Zs().prototype.decorate.call(this,"toModel"),this.on("init",(()=>{this.fire("ready");}),{priority:"lowest"}),this.on("ready",(()=>{this.model.enqueueChange({isUndoable:!1},Dc);}),{priority:"lowest"});}get(e={}){const{rootName:t="main",trim:i="empty"}=e;if(!this._checkIfRootsExists([t]))throw new A("datacontroller-get-non-existent-root",this);const n=this.model.document.getRoot(t);return n.isAttached()||E("datacontroller-get-detached-root",this),"empty"!==i||this.model.hasContent(n,{ignoreWhitespaces:!0})?this.stringify(n,e):""}stringify(e,t={}){const i=this.toView(e,t);return this.processor.toData(i)}toView(e,t={}){const i=this.viewDocument,n=this._viewWriter;this.mapper.clearBindings();const s=tc._createIn(e),o=new ja(i);this.mapper.bindElements(e,o);const r=e.is("documentFragment")?e.markers:function(e){const t=[],i=e.root.document;if(!i)return new Map;const n=tc._createIn(e);for(const e of i.model.markers){const i=e.getRange(),s=i.isCollapsed,o=i.start.isEqual(n.start)||i.end.isEqual(n.end);if(s&&o)t.push([e.name,i]);else {const s=n.getIntersection(i);s&&t.push([e.name,s]);}}return t.sort((([e,t],[i,n])=>{if("after"!==t.end.compareWith(n.start))return 1;if("before"!==t.start.compareWith(n.end))return -1;switch(t.start.compareWith(n.start)){case"before":return 1;case"after":return -1;default:switch(t.end.compareWith(n.end)){case"before":return 1;case"after":return -1;default:return i.localeCompare(e)}}})),new Map(t)}(e);return this.downcastDispatcher.convert(s,r,n,t),o}init(e){if(this.model.document.version)throw new A("datacontroller-init-document-not-empty",this);let t={};if("string"==typeof e?t.main=e:t=e,!this._checkIfRootsExists(Object.keys(t)))throw new A("datacontroller-init-non-existent-root",this);return this.model.enqueueChange({isUndoable:!1},(e=>{for(const i of Object.keys(t)){const n=this.model.document.getRoot(i);e.insert(this.parse(t[i],n),n,0);}})),Promise.resolve()}set(e,t={}){let i={};if("string"==typeof e?i.main=e:i=e,!this._checkIfRootsExists(Object.keys(i)))throw new A("datacontroller-set-non-existent-root",this);this.model.enqueueChange(t.batchType||{},(e=>{e.setSelection(null),e.removeSelectionAttribute(this.model.document.selection.getAttributeKeys());for(const t of Object.keys(i)){const n=this.model.document.getRoot(t);e.remove(e.createRangeIn(n)),e.insert(this.parse(i[t],n),n,0);}}));}parse(e,t="$root"){const i=this.processor.toView(e);return this.toModel(i,t)}toModel(e,t="$root"){return this.model.change((i=>this.upcastDispatcher.convert(e,i,t)))}addStyleProcessorRules(e){e(this.stylesProcessor);}registerRawContentMatcher(e){this.processor&&this.processor!==this.htmlProcessor&&this.processor.registerRawContentMatcher(e),this.htmlProcessor.registerRawContentMatcher(e);}destroy(){this.stopListening();}_checkIfRootsExists(e){for(const t of e)if(!this.model.document.getRoot(t))return !1;return !0}}class kd{_helpers=new Map;_downcast;_upcast;constructor(e,t){this._downcast=gr(e),this._createConversionHelpers({name:"downcast",dispatchers:this._downcast,isDowncast:!0}),this._upcast=gr(t),this._createConversionHelpers({name:"upcast",dispatchers:this._upcast,isDowncast:!1});}addAlias(e,t){const i=this._downcast.includes(t);if(!this._upcast.includes(t)&&!i)throw new A("conversion-add-alias-dispatcher-not-registered",this);this._createConversionHelpers({name:e,dispatchers:[t],isDowncast:i});}for(e){if(!this._helpers.has(e))throw new A("conversion-for-unknown-group",this);return this._helpers.get(e)}elementToElement(e){this.for("downcast").elementToElement(e);for(const{model:t,view:i}of Cd(e))this.for("upcast").elementToElement({model:t,view:i,converterPriority:e.converterPriority});}attributeToElement(e){this.for("downcast").attributeToElement(e);for(const{model:t,view:i}of Cd(e))this.for("upcast").elementToAttribute({view:i,model:t,converterPriority:e.converterPriority});}attributeToAttribute(e){this.for("downcast").attributeToAttribute(e);for(const{model:t,view:i}of Cd(e))this.for("upcast").attributeToAttribute({view:i,model:t});}_createConversionHelpers({name:e,dispatchers:t,isDowncast:i}){if(this._helpers.has(e))throw new A("conversion-group-exists",this);const n=i?new Cc(t):new $c(t);this._helpers.set(e,n);}}function*Cd(e){if(e.model.values)for(const t of e.model.values){const i={key:e.model.key,value:t},n=e.view[t],s=e.upcastAlso?e.upcastAlso[t]:void 0;yield*xd(i,n,s);}else yield*xd(e.model,e.view,e.upcastAlso);}function*xd(e,t,i){if(yield {model:e,view:t},i)for(const t of gr(i))yield {model:e,view:t};}class Ad{namespaces;domParser;domConverter;htmlWriter;skipComments=!0;constructor(e,t={}){this.namespaces=t.namespaces||[],this.domParser=new DOMParser,this.domConverter=new yl(e,{renderingMode:"data"}),this.htmlWriter=new _d;}toData(e){const t=this.domConverter.viewToDom(e);return this.htmlWriter.getHtml(t)}toView(e){const t=this._toDom(e);return this.domConverter.domToView(t,{keepOriginalCase:!0,skipComments:this.skipComments})}registerRawContentMatcher(e){this.domConverter.registerRawContentMatcher(e);}useFillerType(e){this.domConverter.blockFillerMode="marked"==e?"markedNbsp":"nbsp";}_toDom(e){e=``xmlns:${e}="nsp"`)).join(" ")}>${e}`;const t=this.domParser.parseFromString(e,"text/xml"),i=t.querySelector("parsererror");if(i)throw new Error("Parse error - "+i.textContent);const n=t.createDocumentFragment(),s=t.documentElement.childNodes;for(;s.length>0;)n.appendChild(s[0]);return n}}class Ed{baseVersion;isDocumentOperation;batch;constructor(e){this.baseVersion=e,this.isDocumentOperation=null!==this.baseVersion,this.batch=null;}_validate(){}toJSON(){const e=Object.assign({},this);return e.__className=this.constructor.className,delete e.batch,delete e.isDocumentOperation,e}static get className(){return "Operation"}static fromJSON(e,t){return new this(e.baseVersion)}}function Td(e,t){const i=Id(t),n=i.reduce(((e,t)=>e+t.offsetSize),0),s=e.parent;Rd(e);const o=e.index;return s._insertChild(o,i),Vd(s,o+i.length),Vd(s,o),new tc(e,e.getShiftedBy(n))}function Pd(e){if(!e.isFlat)throw new A("operation-utils-remove-range-not-flat",this);const t=e.start.parent;Rd(e.start),Rd(e.end);const i=t._removeChildren(e.start.index,e.end.index-e.start.index);return Vd(t,e.start.index),i}function Sd(e,t){if(!e.isFlat)throw new A("operation-utils-move-range-not-flat",this);const i=Pd(e);return Td(t=t._getTransformedByDeletion(e.start,e.end.offset-e.start.offset),i)}function Id(e){const t=[];!function e(i){if("string"==typeof i)t.push(new Wl(i));else if(i instanceof jl)t.push(new Wl(i.data,i.getAttributes()));else if(i instanceof $l)t.push(i);else if(oo(i))for(const t of i)e(t);}(e);for(let e=1;ee.maxOffset)throw new A("move-operation-nodes-do-not-exist",this);if(e===t&&i=i&&this.targetPosition.path[e]e._clone(!0)))),t=new Md(this.position,e,this.baseVersion);return t.shouldReceiveAttributes=this.shouldReceiveAttributes,t}getReversed(){const e=this.position.root.document.graveyard,t=new Zl(e,[0]);return new Bd(this.position,this.nodes.maxOffset,t,this.baseVersion+1)}_validate(){const e=this.position.parent;if(!e||e.maxOffsete._clone(!0)))),Td(this.position,e);}toJSON(){const e=super.toJSON();return e.position=this.position.toJSON(),e.nodes=this.nodes.toJSON(),e}static get className(){return "InsertOperation"}static fromJSON(e,t){const i=[];for(const t of e.nodes)t.name?i.push(ql.fromJSON(t)):i.push(Wl.fromJSON(t));const n=new Md(Zl.fromJSON(e.position,t),i,e.baseVersion);return n.shouldReceiveAttributes=e.shouldReceiveAttributes,n}}class Ld extends Ed{splitPosition;howMany;insertionPosition;graveyardPosition;constructor(e,t,i,n,s){super(s),this.splitPosition=e.clone(),this.splitPosition.stickiness="toNext",this.howMany=t,this.insertionPosition=i,this.graveyardPosition=n?n.clone():null,this.graveyardPosition&&(this.graveyardPosition.stickiness="toNext");}get type(){return "split"}get moveTargetPosition(){const e=this.insertionPosition.path.slice();return e.push(0),new Zl(this.insertionPosition.root,e)}get movedRange(){const e=this.splitPosition.getShiftedBy(Number.POSITIVE_INFINITY);return new tc(this.splitPosition,e)}get affectedSelectable(){const e=[tc._createFromPositionAndShift(this.splitPosition,0),tc._createFromPositionAndShift(this.insertionPosition,0)];return this.graveyardPosition&&e.push(tc._createFromPositionAndShift(this.graveyardPosition,0)),e}clone(){return new Ld(this.splitPosition,this.howMany,this.insertionPosition,this.graveyardPosition,this.baseVersion)}getReversed(){const e=this.splitPosition.root.document.graveyard,t=new Zl(e,[0]);return new Fd(this.moveTargetPosition,this.howMany,this.splitPosition,t,this.baseVersion+1)}_validate(){const e=this.splitPosition.parent,t=this.splitPosition.offset;if(!e||e.maxOffset0&&(e.sourcePosition.isEqual(t.sourcePosition.getShiftedBy(t.howMany))&&this._setRelation(e,t,"mergeSourceAffected"),e.targetPosition.isEqual(t.sourcePosition)&&this._setRelation(e,t,"mergeTargetWasBefore"));else if(e instanceof Nd){const i=e.newRange;if(!i)return;if(t instanceof Fd){const n=i.start.isEqual(t.targetPosition),s=i.start.isEqual(t.deletionPosition),o=i.end.isEqual(t.deletionPosition),r=i.end.isEqual(t.sourcePosition);(n||s||o||r)&&this._setRelation(e,t,{wasInLeftElement:n,wasStartBeforeMergedElement:s,wasEndBeforeMergedElement:o,wasInRightElement:r});}}}getContext(e,t,i){return {aIsStrong:i,aWasUndone:this._wasUndone(e),bWasUndone:this._wasUndone(t),abRelation:this._useRelations?this._getRelation(e,t):null,baRelation:this._useRelations?this._getRelation(t,e):null,forceWeakRemove:this._forceWeakRemove}}_wasUndone(e){const t=this.originalOperations.get(e);return t.wasUndone||this._history.isUndoneOperation(t)}_getRelation(e,t){const i=this.originalOperations.get(t),n=this._history.getUndoneOperation(i);if(!n)return null;const s=this.originalOperations.get(e),o=this._relations.get(s);return o&&o.get(n)||null}_setRelation(e,t,i){const n=this.originalOperations.get(e),s=this.originalOperations.get(t);let o=this._relations.get(n);o||(o=new Map,this._relations.set(n,o)),o.set(s,i);}}function Yd(e,t){for(const i of e)i.baseVersion=t++;}function Xd(e,t){for(let i=0;i{if(e.key===t.key&&e.range.start.hasSameParentAs(t.range.start)){const n=e.range.getDifference(t.range).map((t=>new Dd(t,e.key,e.oldValue,e.newValue,0))),s=e.range.getIntersection(t.range);return s&&i.aIsStrong&&n.push(new Dd(s,t.key,t.newValue,e.newValue,0)),0==n.length?[new zd(0)]:n}return [e]})),Gd(Dd,Md,((e,t)=>{if(e.range.start.hasSameParentAs(t.position)&&e.range.containsPosition(t.position)){const i=e.range._getTransformedByInsertion(t.position,t.howMany,!t.shouldReceiveAttributes).map((t=>new Dd(t,e.key,e.oldValue,e.newValue,e.baseVersion)));if(t.shouldReceiveAttributes){const n=tu(t,e.key,e.oldValue);n&&i.unshift(n);}return i}return e.range=e.range._getTransformedByInsertion(t.position,t.howMany,!1)[0],[e]})),Gd(Dd,Fd,((e,t)=>{const i=[];e.range.start.hasSameParentAs(t.deletionPosition)&&(e.range.containsPosition(t.deletionPosition)||e.range.start.isEqual(t.deletionPosition))&&i.push(tc._createFromPositionAndShift(t.graveyardPosition,1));const n=e.range._getTransformedByMergeOperation(t);return n.isCollapsed||i.push(n),i.map((t=>new Dd(t,e.key,e.oldValue,e.newValue,e.baseVersion)))})),Gd(Dd,Bd,((e,t)=>{const i=function(e,t){const i=tc._createFromPositionAndShift(t.sourcePosition,t.howMany);let n=null,s=[];i.containsRange(e,!0)?n=e:e.start.hasSameParentAs(i.start)?(s=e.getDifference(i),n=e.getIntersection(i)):s=[e];const o=[];for(let e of s){e=e._getTransformedByDeletion(t.sourcePosition,t.howMany);const i=t.getMovedRangeStart(),n=e.start.hasSameParentAs(i),s=e._getTransformedByInsertion(i,t.howMany,n);o.push(...s);}n&&o.push(n._getTransformedByMove(t.sourcePosition,t.targetPosition,t.howMany,!1)[0]);return o}(e.range,t);return i.map((t=>new Dd(t,e.key,e.oldValue,e.newValue,e.baseVersion)))})),Gd(Dd,Ld,((e,t)=>{if(e.range.end.isEqual(t.insertionPosition))return t.graveyardPosition||e.range.end.offset++,[e];if(e.range.start.hasSameParentAs(t.splitPosition)&&e.range.containsPosition(t.splitPosition)){const i=e.clone();return i.range=new tc(t.moveTargetPosition.clone(),e.range.end._getCombined(t.splitPosition,t.moveTargetPosition)),e.range.end=t.splitPosition.clone(),e.range.end.stickiness="toPrevious",[e,i]}return e.range=e.range._getTransformedBySplitOperation(t),[e]})),Gd(Md,Dd,((e,t)=>{const i=[e];if(e.shouldReceiveAttributes&&e.position.hasSameParentAs(t.range.start)&&t.range.containsPosition(e.position)){const n=tu(e,t.key,t.newValue);n&&i.push(n);}return i})),Gd(Md,Md,((e,t,i)=>(e.position.isEqual(t.position)&&i.aIsStrong||(e.position=e.position._getTransformedByInsertOperation(t)),[e]))),Gd(Md,Bd,((e,t)=>(e.position=e.position._getTransformedByMoveOperation(t),[e]))),Gd(Md,Ld,((e,t)=>(e.position=e.position._getTransformedBySplitOperation(t),[e]))),Gd(Md,Fd,((e,t)=>(e.position=e.position._getTransformedByMergeOperation(t),[e]))),Gd(Nd,Md,((e,t)=>(e.oldRange&&(e.oldRange=e.oldRange._getTransformedByInsertOperation(t)[0]),e.newRange&&(e.newRange=e.newRange._getTransformedByInsertOperation(t)[0]),[e]))),Gd(Nd,Nd,((e,t,i)=>{if(e.name==t.name){if(!i.aIsStrong)return [new zd(0)];e.oldRange=t.newRange?t.newRange.clone():null;}return [e]})),Gd(Nd,Fd,((e,t)=>(e.oldRange&&(e.oldRange=e.oldRange._getTransformedByMergeOperation(t)),e.newRange&&(e.newRange=e.newRange._getTransformedByMergeOperation(t)),[e]))),Gd(Nd,Bd,((e,t)=>{const i=[e];if(e.oldRange&&(e.oldRange=tc._createFromRanges(e.oldRange._getTransformedByMoveOperation(t))),e.newRange){const n=e.newRange._getTransformedByMoveOperation(t);e.newRange=n[0];for(let t=1;t{if(e.oldRange&&(e.oldRange=e.oldRange._getTransformedBySplitOperation(t)),e.newRange){if(i.abRelation){const n=e.newRange._getTransformedBySplitOperation(t);return e.newRange.start.isEqual(t.splitPosition)&&i.abRelation.wasStartBeforeMergedElement?e.newRange.start=Zl._createAt(t.insertionPosition):e.newRange.start.isEqual(t.splitPosition)&&!i.abRelation.wasInLeftElement?e.newRange.start=Zl._createAt(t.moveTargetPosition):e.newRange.start=n.start,e.newRange.end.isEqual(t.splitPosition)&&i.abRelation.wasInRightElement?e.newRange.end=Zl._createAt(t.moveTargetPosition):e.newRange.end.isEqual(t.splitPosition)&&i.abRelation.wasEndBeforeMergedElement?e.newRange.end=Zl._createAt(t.insertionPosition):e.newRange.end=n.end,[e]}e.newRange=e.newRange._getTransformedBySplitOperation(t);}return [e]})),Gd(Fd,Md,((e,t)=>(e.sourcePosition.hasSameParentAs(t.position)&&(e.howMany+=t.howMany),e.sourcePosition=e.sourcePosition._getTransformedByInsertOperation(t),e.targetPosition=e.targetPosition._getTransformedByInsertOperation(t),[e]))),Gd(Fd,Fd,((e,t,i)=>{if(e.sourcePosition.isEqual(t.sourcePosition)&&e.targetPosition.isEqual(t.targetPosition)){if(i.bWasUndone){const i=t.graveyardPosition.path.slice();return i.push(0),e.sourcePosition=new Zl(t.graveyardPosition.root,i),e.howMany=0,[e]}return [new zd(0)]}if(e.sourcePosition.isEqual(t.sourcePosition)&&!e.targetPosition.isEqual(t.targetPosition)&&!i.bWasUndone&&"splitAtSource"!=i.abRelation){const n="$graveyard"==e.targetPosition.root.rootName,s="$graveyard"==t.targetPosition.root.rootName;if(s&&!n||!(n&&!s)&&i.aIsStrong){const i=t.targetPosition._getTransformedByMergeOperation(t),n=e.targetPosition._getTransformedByMergeOperation(t);return [new Bd(i,e.howMany,n,0)]}return [new zd(0)]}return e.sourcePosition.hasSameParentAs(t.targetPosition)&&(e.howMany+=t.howMany),e.sourcePosition=e.sourcePosition._getTransformedByMergeOperation(t),e.targetPosition=e.targetPosition._getTransformedByMergeOperation(t),e.graveyardPosition.isEqual(t.graveyardPosition)&&i.aIsStrong||(e.graveyardPosition=e.graveyardPosition._getTransformedByMergeOperation(t)),[e]})),Gd(Fd,Bd,((e,t,i)=>{const n=tc._createFromPositionAndShift(t.sourcePosition,t.howMany);return "remove"==t.type&&!i.bWasUndone&&e.deletionPosition.hasSameParentAs(t.sourcePosition)&&n.containsPosition(e.sourcePosition)?[new zd(0)]:(t.sourcePosition.getShiftedBy(t.howMany).isEqual(e.sourcePosition)?e.sourcePosition.stickiness="toNone":t.targetPosition.isEqual(e.sourcePosition)&&"mergeSourceAffected"==i.abRelation?e.sourcePosition.stickiness="toNext":t.sourcePosition.isEqual(e.targetPosition)?(e.targetPosition.stickiness="toNone",e.howMany-=t.howMany):t.targetPosition.isEqual(e.targetPosition)&&"mergeTargetWasBefore"==i.abRelation?(e.targetPosition.stickiness="toPrevious",e.howMany+=t.howMany):(e.sourcePosition.hasSameParentAs(t.targetPosition)&&(e.howMany+=t.howMany),e.sourcePosition.hasSameParentAs(t.sourcePosition)&&(e.howMany-=t.howMany)),e.sourcePosition=e.sourcePosition._getTransformedByMoveOperation(t),e.targetPosition=e.targetPosition._getTransformedByMoveOperation(t),e.sourcePosition.stickiness="toPrevious",e.targetPosition.stickiness="toNext",e.graveyardPosition.isEqual(t.targetPosition)||(e.graveyardPosition=e.graveyardPosition._getTransformedByMoveOperation(t)),[e])})),Gd(Fd,Ld,((e,t,i)=>{if(t.graveyardPosition&&(e.graveyardPosition=e.graveyardPosition._getTransformedByDeletion(t.graveyardPosition,1),e.deletionPosition.isEqual(t.graveyardPosition)&&(e.howMany=t.howMany)),e.targetPosition.isEqual(t.splitPosition)){if(t.graveyardPosition&&e.deletionPosition.isEqual(t.graveyardPosition)||"mergeTargetNotMoved"==i.abRelation)return e.sourcePosition=e.sourcePosition._getTransformedBySplitOperation(t),[e]}if(e.sourcePosition.isEqual(t.splitPosition)){if("mergeSourceNotMoved"==i.abRelation)return e.howMany=0,e.targetPosition=e.targetPosition._getTransformedBySplitOperation(t),[e];if("mergeSameElement"==i.abRelation||e.sourcePosition.offset>0)return e.sourcePosition=t.moveTargetPosition.clone(),e.targetPosition=e.targetPosition._getTransformedBySplitOperation(t),[e]}return e.sourcePosition.hasSameParentAs(t.splitPosition)&&(e.howMany=t.splitPosition.offset),e.sourcePosition=e.sourcePosition._getTransformedBySplitOperation(t),e.targetPosition=e.targetPosition._getTransformedBySplitOperation(t),[e]})),Gd(Bd,Md,((e,t)=>{const i=tc._createFromPositionAndShift(e.sourcePosition,e.howMany)._getTransformedByInsertOperation(t,!1)[0];return e.sourcePosition=i.start,e.howMany=i.end.offset-i.start.offset,e.targetPosition.isEqual(t.position)||(e.targetPosition=e.targetPosition._getTransformedByInsertOperation(t)),[e]})),Gd(Bd,Bd,((e,t,i)=>{const n=tc._createFromPositionAndShift(e.sourcePosition,e.howMany),s=tc._createFromPositionAndShift(t.sourcePosition,t.howMany);let o,r=i.aIsStrong,a=!i.aIsStrong;if("insertBefore"==i.abRelation||"insertAfter"==i.baRelation?a=!0:"insertAfter"!=i.abRelation&&"insertBefore"!=i.baRelation||(a=!1),o=e.targetPosition.isEqual(t.targetPosition)&&a?e.targetPosition._getTransformedByDeletion(t.sourcePosition,t.howMany):e.targetPosition._getTransformedByMove(t.sourcePosition,t.targetPosition,t.howMany),iu(e,t)&&iu(t,e))return [t.getReversed()];if(n.containsPosition(t.targetPosition)&&n.containsRange(s,!0))return n.start=n.start._getTransformedByMove(t.sourcePosition,t.targetPosition,t.howMany),n.end=n.end._getTransformedByMove(t.sourcePosition,t.targetPosition,t.howMany),nu([n],o);if(s.containsPosition(e.targetPosition)&&s.containsRange(n,!0))return n.start=n.start._getCombined(t.sourcePosition,t.getMovedRangeStart()),n.end=n.end._getCombined(t.sourcePosition,t.getMovedRangeStart()),nu([n],o);const l=so(e.sourcePosition.getParentPath(),t.sourcePosition.getParentPath());if("prefix"==l||"extension"==l)return n.start=n.start._getTransformedByMove(t.sourcePosition,t.targetPosition,t.howMany),n.end=n.end._getTransformedByMove(t.sourcePosition,t.targetPosition,t.howMany),nu([n],o);"remove"!=e.type||"remove"==t.type||i.aWasUndone||i.forceWeakRemove?"remove"==e.type||"remove"!=t.type||i.bWasUndone||i.forceWeakRemove||(r=!1):r=!0;const c=[],d=n.getDifference(s);for(const e of d){e.start=e.start._getTransformedByDeletion(t.sourcePosition,t.howMany),e.end=e.end._getTransformedByDeletion(t.sourcePosition,t.howMany);const i="same"==so(e.start.getParentPath(),t.getMovedRangeStart().getParentPath()),n=e._getTransformedByInsertion(t.getMovedRangeStart(),t.howMany,i);c.push(...n);}const u=n.getIntersection(s);return null!==u&&r&&(u.start=u.start._getCombined(t.sourcePosition,t.getMovedRangeStart()),u.end=u.end._getCombined(t.sourcePosition,t.getMovedRangeStart()),0===c.length?c.push(u):1==c.length?s.start.isBefore(n.start)||s.start.isEqual(n.start)?c.unshift(u):c.push(u):c.splice(1,0,u)),0===c.length?[new zd(e.baseVersion)]:nu(c,o)})),Gd(Bd,Ld,((e,t,i)=>{let n=e.targetPosition.clone();e.targetPosition.isEqual(t.insertionPosition)&&t.graveyardPosition&&"moveTargetAfter"!=i.abRelation||(n=e.targetPosition._getTransformedBySplitOperation(t));const s=tc._createFromPositionAndShift(e.sourcePosition,e.howMany);if(s.end.isEqual(t.insertionPosition))return t.graveyardPosition||e.howMany++,e.targetPosition=n,[e];if(s.start.hasSameParentAs(t.splitPosition)&&s.containsPosition(t.splitPosition)){let e=new tc(t.splitPosition,s.end);e=e._getTransformedBySplitOperation(t);return nu([new tc(s.start,t.splitPosition),e],n)}e.targetPosition.isEqual(t.splitPosition)&&"insertAtSource"==i.abRelation&&(n=t.moveTargetPosition),e.targetPosition.isEqual(t.insertionPosition)&&"insertBetween"==i.abRelation&&(n=e.targetPosition);const o=[s._getTransformedBySplitOperation(t)];if(t.graveyardPosition){const n=s.start.isEqual(t.graveyardPosition)||s.containsPosition(t.graveyardPosition);e.howMany>1&&n&&!i.aWasUndone&&o.push(tc._createFromPositionAndShift(t.insertionPosition,1));}return nu(o,n)})),Gd(Bd,Fd,((e,t,i)=>{const n=tc._createFromPositionAndShift(e.sourcePosition,e.howMany);if(t.deletionPosition.hasSameParentAs(e.sourcePosition)&&n.containsPosition(t.sourcePosition))if("remove"!=e.type||i.forceWeakRemove){if(1==e.howMany)return i.bWasUndone?(e.sourcePosition=t.graveyardPosition.clone(),e.targetPosition=e.targetPosition._getTransformedByMergeOperation(t),[e]):[new zd(0)]}else if(!i.aWasUndone){const i=[];let n=t.graveyardPosition.clone(),s=t.targetPosition._getTransformedByMergeOperation(t);const o=e.targetPosition.getTransformedByOperation(t);e.howMany>1&&(i.push(new Bd(e.sourcePosition,e.howMany-1,o,0)),n=n._getTransformedByMove(e.sourcePosition,o,e.howMany-1),s=s._getTransformedByMove(e.sourcePosition,o,e.howMany-1));const r=t.deletionPosition._getCombined(e.sourcePosition,o),a=new Bd(n,1,r,0),l=a.getMovedRangeStart().path.slice();l.push(0);const c=new Zl(a.targetPosition.root,l);s=s._getTransformedByMove(n,r,1);const d=new Bd(s,t.howMany,c,0);return i.push(a),i.push(d),i}const s=tc._createFromPositionAndShift(e.sourcePosition,e.howMany)._getTransformedByMergeOperation(t);return e.sourcePosition=s.start,e.howMany=s.end.offset-s.start.offset,e.targetPosition=e.targetPosition._getTransformedByMergeOperation(t),[e]})),Gd(Hd,Md,((e,t)=>(e.position=e.position._getTransformedByInsertOperation(t),[e]))),Gd(Hd,Fd,((e,t)=>e.position.isEqual(t.deletionPosition)?(e.position=t.graveyardPosition.clone(),e.position.stickiness="toNext",[e]):(e.position=e.position._getTransformedByMergeOperation(t),[e]))),Gd(Hd,Bd,((e,t)=>(e.position=e.position._getTransformedByMoveOperation(t),[e]))),Gd(Hd,Hd,((e,t,i)=>{if(e.position.isEqual(t.position)){if(!i.aIsStrong)return [new zd(0)];e.oldName=t.newName;}return [e]})),Gd(Hd,Ld,((e,t)=>{if("same"==so(e.position.path,t.splitPosition.getParentPath())&&!t.graveyardPosition){const t=new Hd(e.position.getShiftedBy(1),e.oldName,e.newName,0);return [e,t]}return e.position=e.position._getTransformedBySplitOperation(t),[e]})),Gd($d,$d,((e,t,i)=>{if(e.root===t.root&&e.key===t.key){if(!i.aIsStrong||e.newValue===t.newValue)return [new zd(0)];e.oldValue=t.newValue;}return [e]})),Gd(Ud,Ud,((e,t)=>e.rootName===t.rootName&&e.isAdd===t.isAdd?[new zd(0)]:[e])),Gd(Ld,Md,((e,t)=>(e.splitPosition.hasSameParentAs(t.position)&&e.splitPosition.offset{if(!e.graveyardPosition&&!i.bWasUndone&&e.splitPosition.hasSameParentAs(t.sourcePosition)){const i=t.graveyardPosition.path.slice();i.push(0);const n=new Zl(t.graveyardPosition.root,i),s=Ld.getInsertionPosition(new Zl(t.graveyardPosition.root,i)),o=new Ld(n,0,s,null,0);return e.splitPosition=e.splitPosition._getTransformedByMergeOperation(t),e.insertionPosition=Ld.getInsertionPosition(e.splitPosition),e.graveyardPosition=o.insertionPosition.clone(),e.graveyardPosition.stickiness="toNext",[o,e]}return e.splitPosition.hasSameParentAs(t.deletionPosition)&&!e.splitPosition.isAfter(t.deletionPosition)&&e.howMany--,e.splitPosition.hasSameParentAs(t.targetPosition)&&(e.howMany+=t.howMany),e.splitPosition=e.splitPosition._getTransformedByMergeOperation(t),e.insertionPosition=Ld.getInsertionPosition(e.splitPosition),e.graveyardPosition&&(e.graveyardPosition=e.graveyardPosition._getTransformedByMergeOperation(t)),[e]})),Gd(Ld,Bd,((e,t,i)=>{const n=tc._createFromPositionAndShift(t.sourcePosition,t.howMany);if(e.graveyardPosition){const s=n.start.isEqual(e.graveyardPosition)||n.containsPosition(e.graveyardPosition);if(!i.bWasUndone&&s){const i=e.splitPosition._getTransformedByMoveOperation(t),n=e.graveyardPosition._getTransformedByMoveOperation(t),s=n.path.slice();s.push(0);const o=new Zl(n.root,s);return [new Bd(i,e.howMany,o,0)]}e.graveyardPosition=e.graveyardPosition._getTransformedByMoveOperation(t);}const s=e.splitPosition.isEqual(t.targetPosition);if(s&&("insertAtSource"==i.baRelation||"splitBefore"==i.abRelation))return e.howMany+=t.howMany,e.splitPosition=e.splitPosition._getTransformedByDeletion(t.sourcePosition,t.howMany),e.insertionPosition=Ld.getInsertionPosition(e.splitPosition),[e];if(s&&i.abRelation&&i.abRelation.howMany){const{howMany:t,offset:n}=i.abRelation;return e.howMany+=t,e.splitPosition=e.splitPosition.getShiftedBy(n),[e]}if(e.splitPosition.hasSameParentAs(t.sourcePosition)&&n.containsPosition(e.splitPosition)){const i=t.howMany-(e.splitPosition.offset-t.sourcePosition.offset);return e.howMany-=i,e.splitPosition.hasSameParentAs(t.targetPosition)&&e.splitPosition.offset{if(e.splitPosition.isEqual(t.splitPosition)){if(!e.graveyardPosition&&!t.graveyardPosition)return [new zd(0)];if(e.graveyardPosition&&t.graveyardPosition&&e.graveyardPosition.isEqual(t.graveyardPosition))return [new zd(0)];if("splitBefore"==i.abRelation)return e.howMany=0,e.graveyardPosition=e.graveyardPosition._getTransformedBySplitOperation(t),[e]}if(e.graveyardPosition&&t.graveyardPosition&&e.graveyardPosition.isEqual(t.graveyardPosition)){const n="$graveyard"==e.splitPosition.root.rootName,s="$graveyard"==t.splitPosition.root.rootName;if(s&&!n||!(n&&!s)&&i.aIsStrong){const i=[];return t.howMany&&i.push(new Bd(t.moveTargetPosition,t.howMany,t.splitPosition,0)),e.howMany&&i.push(new Bd(e.splitPosition,e.howMany,e.moveTargetPosition,0)),i}return [new zd(0)]}if(e.graveyardPosition&&(e.graveyardPosition=e.graveyardPosition._getTransformedBySplitOperation(t)),e.splitPosition.isEqual(t.insertionPosition)&&"splitBefore"==i.abRelation)return e.howMany++,[e];if(t.splitPosition.isEqual(e.insertionPosition)&&"splitBefore"==i.baRelation){const i=t.insertionPosition.path.slice();i.push(0);const n=new Zl(t.insertionPosition.root,i);return [e,new Bd(e.insertionPosition,1,n,0)]}return e.splitPosition.hasSameParentAs(t.splitPosition)&&e.splitPosition.offset{const i=t[0];i.isDocumentOperation&&ru.call(this,i);}),{priority:"low"});}function ru(e){const t=this.getTransformedByOperation(e);if(!this.isEqual(t)){const e=this.toPosition();this.path=t.path,this.root=t.root,this.fire("change",e);}}su.prototype.is=function(e){return "livePosition"===e||"model:livePosition"===e||"position"==e||"model:position"===e};class au{operations;isUndoable;isLocal;isUndo;isTyping;constructor(e={}){"string"==typeof e&&(e="transparent"===e?{isUndoable:!1}:{},E("batch-constructor-deprecated-string-type"));const{isUndoable:t=!0,isLocal:i=!0,isUndo:n=!1,isTyping:s=!1}=e;this.operations=[],this.isUndoable=t,this.isLocal=i,this.isUndo=n,this.isTyping=s;}get type(){return E("batch-type-deprecated"),"default"}get baseVersion(){for(const e of this.operations)if(null!==e.baseVersion)return e.baseVersion;return null}addOperation(e){return e.batch=this,this.operations.push(e),e}}class lu{static _statesPriority=[void 0,"refresh","rename","move"];_markerCollection;_changesInElement=new Map;_elementsSnapshots=new Map;_elementChildrenSnapshots=new Map;_elementState=new Map;_changedMarkers=new Map;_changedRoots=new Map;_changeCount=0;_cachedChanges=null;_cachedChangesWithGraveyard=null;_refreshedItems=new Set;constructor(e){this._markerCollection=e;}get isEmpty(){return 0==this._changesInElement.size&&0==this._changedMarkers.size&&0==this._changedRoots.size}bufferOperation(e){const t=e;switch(t.type){case"insert":if(this._isInInsertedElement(t.position.parent))return;this._markInsert(t.position.parent,t.position.offset,t.nodes.maxOffset);break;case"addAttribute":case"removeAttribute":case"changeAttribute":for(const e of t.range.getItems({shallow:!0}))this._isInInsertedElement(e.parent)||this._markAttribute(e);break;case"remove":case"move":case"reinsert":{if(t.sourcePosition.isEqual(t.targetPosition)||t.sourcePosition.getShiftedBy(t.howMany).isEqual(t.targetPosition))return;const e=this._isInInsertedElement(t.sourcePosition.parent),i=this._isInInsertedElement(t.targetPosition.parent);e||this._markRemove(t.sourcePosition.parent,t.sourcePosition.offset,t.howMany),i||this._markInsert(t.targetPosition.parent,t.getMovedRangeStart().offset,t.howMany);const n=tc._createFromPositionAndShift(t.sourcePosition,t.howMany);for(const e of n.getItems({shallow:!0}))this._setElementState(e,"move");break}case"rename":{if(this._isInInsertedElement(t.position.parent))return;this._markRemove(t.position.parent,t.position.offset,1),this._markInsert(t.position.parent,t.position.offset,1);const e=tc._createFromPositionAndShift(t.position,1);for(const t of this._markerCollection.getMarkersIntersectingRange(e)){const e=t.getData();this.bufferMarkerChange(t.name,e,e);}this._setElementState(t.position.nodeAfter,"rename");break}case"split":{const e=t.splitPosition.parent;if(!this._isInInsertedElement(e)){this._markRemove(e,t.splitPosition.offset,t.howMany);const i=tc._createFromPositionAndShift(t.splitPosition,t.howMany);for(const e of i.getItems({shallow:!0}))this._setElementState(e,"move");}this._isInInsertedElement(t.insertionPosition.parent)||this._markInsert(t.insertionPosition.parent,t.insertionPosition.offset,1),t.graveyardPosition&&(this._markRemove(t.graveyardPosition.parent,t.graveyardPosition.offset,1),this._setElementState(t.graveyardPosition.nodeAfter,"move"));break}case"merge":{const e=t.sourcePosition.parent;this._isInInsertedElement(e.parent)||this._markRemove(e.parent,e.startOffset,1);const i=t.graveyardPosition.parent;this._markInsert(i,t.graveyardPosition.offset,1),this._setElementState(e,"move");const n=t.targetPosition.parent;if(!this._isInInsertedElement(n)){this._markInsert(n,t.targetPosition.offset,e.maxOffset);const i=tc._createFromPositionAndShift(t.sourcePosition,t.howMany);for(const e of i.getItems({shallow:!0}))this._setElementState(e,"move");}break}case"detachRoot":case"addRoot":{const e=t.affectedSelectable;if(!e._isLoaded)return;if(e.isAttached()==t.isAdd)return;this._bufferRootStateChange(t.rootName,t.isAdd);break}case"addRootAttribute":case"removeRootAttribute":case"changeRootAttribute":{if(!t.root._isLoaded)return;const e=t.root.rootName;this._bufferRootAttributeChange(e,t.key,t.oldValue,t.newValue);break}}this._cachedChanges=null;}bufferMarkerChange(e,t,i){t.range&&t.range.root.is("rootElement")&&!t.range.root._isLoaded&&(t.range=null),i.range&&i.range.root.is("rootElement")&&!i.range.root._isLoaded&&(i.range=null);let n=this._changedMarkers.get(e);n?n.newMarkerData=i:(n={newMarkerData:i,oldMarkerData:t},this._changedMarkers.set(e,n)),null==n.oldMarkerData.range&&null==i.range&&this._changedMarkers.delete(e);}getMarkersToRemove(){const e=[];for(const[t,i]of this._changedMarkers)null!=i.oldMarkerData.range&&e.push({name:t,range:i.oldMarkerData.range});return e}getMarkersToAdd(){const e=[];for(const[t,i]of this._changedMarkers)null!=i.newMarkerData.range&&e.push({name:t,range:i.newMarkerData.range});return e}getChangedMarkers(){return Array.from(this._changedMarkers).map((([e,t])=>({name:e,data:{oldRange:t.oldMarkerData.range,newRange:t.newMarkerData.range}})))}hasDataChanges(){if(this.getChanges().length)return !0;if(this._changedRoots.size>0)return !0;for(const{newMarkerData:e,oldMarkerData:t}of this._changedMarkers.values()){if(e.affectsData!==t.affectsData)return !0;if(e.affectsData){const i=e.range&&!t.range,n=!e.range&&t.range,s=e.range&&t.range&&!e.range.isEqual(t.range);if(i||n||s)return !0}}return !1}getChanges(e={}){if(this._cachedChanges)return e.includeChangesInGraveyard?this._cachedChangesWithGraveyard.slice():this._cachedChanges.slice();let t=[];for(const e of this._changesInElement.keys()){const i=this._changesInElement.get(e).sort(((e,t)=>e.offset===t.offset?e.type!=t.type?"remove"==e.type?-1:1:0:e.offsete.position.root!=t.position.root?e.position.root.rootNamee));for(const e of t)delete e.changeCount,"attribute"==e.type&&(delete e.position,delete e.length);return this._changeCount=0,this._cachedChangesWithGraveyard=t,this._cachedChanges=t.filter(hu),e.includeChangesInGraveyard?this._cachedChangesWithGraveyard.slice():this._cachedChanges.slice()}getChangedRoots(){return Array.from(this._changedRoots.values()).map((e=>{const t={...e};return void 0!==t.state&&delete t.attributes,t}))}getRefreshedItems(){return new Set(this._refreshedItems)}reset(){this._changesInElement.clear(),this._elementChildrenSnapshots.clear(),this._elementsSnapshots.clear(),this._elementState.clear(),this._changedMarkers.clear(),this._changedRoots.clear(),this._refreshedItems.clear(),this._cachedChanges=null;}_refreshItem(e){if(this._isInInsertedElement(e.parent))return;this._markRemove(e.parent,e.startOffset,e.offsetSize),this._markInsert(e.parent,e.startOffset,e.offsetSize),this._refreshedItems.add(e),this._setElementState(e,"refresh");const t=tc._createOn(e);for(const e of this._markerCollection.getMarkersIntersectingRange(t)){const t=e.getData();this.bufferMarkerChange(e.name,t,t);}this._cachedChanges=null;}_bufferRootLoad(e){if(e.isAttached()){this._bufferRootStateChange(e.rootName,!0),this._markInsert(e,0,e.maxOffset);for(const t of e.getAttributeKeys())this._bufferRootAttributeChange(e.rootName,t,null,e.getAttribute(t));for(const t of this._markerCollection)if(t.getRange().root==e){const e=t.getData();this.bufferMarkerChange(t.name,{...e,range:null},e);}}}_bufferRootStateChange(e,t){if(!this._changedRoots.has(e))return void this._changedRoots.set(e,{name:e,state:t?"attached":"detached"});const i=this._changedRoots.get(e);void 0!==i.state?(delete i.state,void 0===i.attributes&&this._changedRoots.delete(e)):i.state=t?"attached":"detached";}_bufferRootAttributeChange(e,t,i,n){const s=this._changedRoots.get(e)||{name:e},o=s.attributes||{};if(o[t]){const e=o[t];n===e.oldValue?delete o[t]:e.newValue=n;}else o[t]={oldValue:i,newValue:n};0===Object.entries(o).length?(delete s.attributes,void 0===s.state&&this._changedRoots.delete(e)):(s.attributes=o,this._changedRoots.set(e,s));}_markInsert(e,t,i){if(e.root.is("rootElement")&&!e.root._isLoaded)return;const n={type:"insert",offset:t,howMany:i,count:this._changeCount++};this._markChange(e,n);}_markRemove(e,t,i){if(e.root.is("rootElement")&&!e.root._isLoaded)return;const n={type:"remove",offset:t,howMany:i,count:this._changeCount++};this._markChange(e,n),this._removeAllNestedChanges(e,t,i);}_markAttribute(e){if(e.root.is("rootElement")&&!e.root._isLoaded)return;const t={type:"attribute",offset:e.startOffset,howMany:e.offsetSize,count:this._changeCount++};this._markChange(e.parent,t);}_markChange(e,t){this._makeSnapshots(e);const i=this._getChangesForElement(e);this._handleChange(t,i),i.push(t);for(let e=0;ei&&this._elementState.set(e,t);}_getDiffActionForNode(e,t){if(!e.is("element"))return t;if(!this._elementsSnapshots.has(e))return t;const i=this._elementState.get(e);return i&&"move"!=i?i:t}_getChangesForElement(e){let t;return this._changesInElement.has(e)?t=this._changesInElement.get(e):(t=[],this._changesInElement.set(e,t)),t}_makeSnapshots(e){if(this._elementChildrenSnapshots.has(e))return;const t=du(e.getChildren());this._elementChildrenSnapshots.set(e,t);for(const e of t)this._elementsSnapshots.set(e.node,e);}_handleChange(e,t){e.nodesToHandle=e.howMany;for(const i of t){const n=e.offset+e.howMany,s=i.offset+i.howMany;if("insert"==e.type&&("insert"==i.type&&(e.offset<=i.offset?i.offset+=e.howMany:e.offseti.offset){if(n>s){const e={type:"attribute",offset:s,howMany:n-s,count:this._changeCount++};this._handleChange(e,t),t.push(e);}e.nodesToHandle=i.offset-e.offset,e.howMany=e.nodesToHandle;}else e.offset>=i.offset&&e.offsets?(e.nodesToHandle=n-s,e.offset=s):e.nodesToHandle=0);if("remove"==i.type&&e.offseti.offset){const s={type:"attribute",offset:i.offset,howMany:n-i.offset,count:this._changeCount++};this._handleChange(s,t),t.push(s),e.nodesToHandle=i.offset-e.offset,e.howMany=e.nodesToHandle;}"attribute"==i.type&&(e.offset>=i.offset&&n<=s?(e.nodesToHandle=0,e.howMany=0,e.offset=0):e.offset<=i.offset&&n>=s&&(i.howMany=0));}}e.howMany=e.nodesToHandle,delete e.nodesToHandle;}_getInsertDiff(e,t,i,n,s){const o={type:"insert",position:Zl._createAt(e,t),name:n.name,attributes:new Map(n.attributes),length:1,changeCount:this._changeCount++,action:i};return "insert"!=i&&s&&(o.before={name:s.name,attributes:new Map(s.attributes)}),o}_getRemoveDiff(e,t,i,n){return {type:"remove",action:i,position:Zl._createAt(e,t),name:n.name,attributes:new Map(n.attributes),length:1,changeCount:this._changeCount++}}_getAttributesDiff(e,t,i){const n=[];i=new Map(i);for(const[s,o]of t){const t=i.has(s)?i.get(s):null;t!==o&&n.push({type:"attribute",position:e.start,range:e.clone(),length:1,attributeKey:s,attributeOldValue:o,attributeNewValue:t,changeCount:this._changeCount++}),i.delete(s);}for(const[t,s]of i)n.push({type:"attribute",position:e.start,range:e.clone(),length:1,attributeKey:t,attributeOldValue:null,attributeNewValue:s,changeCount:this._changeCount++});return n}_isInInsertedElement(e){const t=e.parent;if(!t)return !1;const i=this._changesInElement.get(t),n=e.startOffset;if(i)for(const e of i)if("insert"==e.type&&n>=e.offset&&nn){for(let t=0;t1500)for(let t=0;tthis._version+1&&this._gaps.set(this._version,e),this._version=e;}get lastOperation(){return this._operations[this._operations.length-1]}addOperation(e){if(e.baseVersion!==this.version)throw new A("model-document-history-addoperation-incorrect-version",this,{operation:e,historyVersion:this.version});this._operations.push(e),this._version++,this._baseVersionToOperationIndex.set(e.baseVersion,this._operations.length-1);}getOperations(e,t=this.version){if(!this._operations.length)return [];const i=this._operations[0];void 0===e&&(e=i.baseVersion);let n=t-1;for(const[t,i]of this._gaps)e>t&&et&&nthis.lastOperation.baseVersion)return [];let s=this._baseVersionToOperationIndex.get(e);void 0===s&&(s=0);let o=this._baseVersionToOperationIndex.get(n);return void 0===o&&(o=this._operations.length-1),this._operations.slice(s,o+1)}getOperation(e){const t=this._baseVersionToOperationIndex.get(e);if(void 0!==t)return this._operations[t]}setOperationAsUndone(e,t){this._undoPairs.set(t,e),this._undoneOperations.add(e);}isUndoingOperation(e){return this._undoPairs.has(e)}isUndoneOperation(e){return this._undoneOperations.has(e)}getUndoneOperation(e){return this._undoPairs.get(e)}reset(){this._version=0,this._undoPairs=new Map,this._operations=[],this._undoneOperations=new Set,this._gaps=new Map,this._baseVersionToOperationIndex=new Map;}}class gu extends ql{rootName;_document;_isAttached=!0;_isLoaded=!0;constructor(e,t,i="main"){super(t),this._document=e,this.rootName=i;}get document(){return this._document}isAttached(){return this._isAttached}toJSON(){return this.rootName}}gu.prototype.is=function(e,t){return t?t===this.name&&("rootElement"===e||"model:rootElement"===e||"element"===e||"model:element"===e):"rootElement"===e||"model:rootElement"===e||"element"===e||"model:element"===e||"node"===e||"model:node"===e};const fu="$graveyard";class pu extends(L()){model;history;selection;roots;differ;isReadOnly;_postFixers;_hasSelectionChangedFromTheLastChangeBlock;constructor(e){super(),this.model=e,this.history=new mu,this.selection=new _c(this),this.roots=new br({idProperty:"rootName"}),this.differ=new lu(e.markers),this.isReadOnly=!1,this._postFixers=new Set,this._hasSelectionChangedFromTheLastChangeBlock=!1,this.createRoot("$root",fu),this.listenTo(e,"applyOperation",((e,t)=>{const i=t[0];i.isDocumentOperation&&this.differ.bufferOperation(i);}),{priority:"high"}),this.listenTo(e,"applyOperation",((e,t)=>{const i=t[0];i.isDocumentOperation&&this.history.addOperation(i);}),{priority:"low"}),this.listenTo(this.selection,"change",(()=>{this._hasSelectionChangedFromTheLastChangeBlock=!0;})),this.listenTo(e.markers,"update",((e,t,i,n,s)=>{const o={...t.getData(),range:n};this.differ.bufferMarkerChange(t.name,s,o),null===i&&t.on("change",((e,i)=>{const n=t.getData();this.differ.bufferMarkerChange(t.name,{...n,range:i},n);}));})),this.registerPostFixer((e=>{let t=!1;for(const i of this.roots)i.isAttached()||i.isEmpty||(e.remove(e.createRangeIn(i)),t=!0);for(const i of this.model.markers)i.getRange().root.isAttached()||(e.removeMarker(i),t=!0);return t}));}get version(){return this.history.version}set version(e){this.history.version=e;}get graveyard(){return this.getRoot(fu)}createRoot(e="$root",t="main"){if(this.roots.get(t))throw new A("model-document-createroot-name-exists",this,{name:t});const i=new gu(this,e,t);return this.roots.add(i),i}destroy(){this.selection.destroy(),this.stopListening();}getRoot(e="main"){return this.roots.get(e)}getRootNames(e=!1){return this.getRoots(e).map((e=>e.rootName))}getRoots(e=!1){return this.roots.filter((t=>t!=this.graveyard&&(e||t.isAttached())&&t._isLoaded))}registerPostFixer(e){this._postFixers.add(e);}toJSON(){const e=$n(this);return e.selection="[engine.model.DocumentSelection]",e.model="[engine.model.Model]",e}_handleChangeBlock(e){this._hasDocumentChangedFromTheLastChangeBlock()&&(this._callPostFixers(e),this.selection.refresh(),this.differ.hasDataChanges()?this.fire("change:data",e.batch):this.fire("change",e.batch),this.selection.refresh(),this.differ.reset()),this._hasSelectionChangedFromTheLastChangeBlock=!1;}_hasDocumentChangedFromTheLastChangeBlock(){return !this.differ.isEmpty||this._hasSelectionChangedFromTheLastChangeBlock}_getDefaultRoot(){const e=this.getRoots();return e.length?e[0]:this.graveyard}_getDefaultRange(){const e=this._getDefaultRoot(),t=this.model,i=t.schema,n=t.createPositionFromPath(e,[0]);return i.getNearestSelectionRange(n)||t.createRange(n)}_validateSelectionRange(e){return e.start.isValid()&&e.end.isValid()&&bu(e.start)&&bu(e.end)}_callPostFixers(e){let t=!1;do{for(const i of this._postFixers)if(this.selection.refresh(),t=i(e),t)break}while(t)}}function bu(e){const t=e.textNode;if(t){const i=t.data,n=e.offset-t.startOffset;return !Br(i,n)&&!Mr(i,n)}return !0}class wu extends(L()){_markers=new Map;[Symbol.iterator](){return this._markers.values()}has(e){const t=e instanceof _u?e.name:e;return this._markers.has(t)}get(e){return this._markers.get(e)||null}_set(e,t,i=!1,n=!1){const s=e instanceof _u?e.name:e;if(s.includes(","))throw new A("markercollection-incorrect-marker-name",this);const o=this._markers.get(s);if(o){const e=o.getData(),r=o.getRange();let a=!1;return r.isEqual(t)||(o._attachLiveRange(fc.fromRange(t)),a=!0),i!=o.managedUsingOperations&&(o._managedUsingOperations=i,a=!0),"boolean"==typeof n&&n!=o.affectsData&&(o._affectsData=n,a=!0),a&&this.fire(`update:${s}`,o,r,t,e),o}const r=fc.fromRange(t),a=new _u(s,r,i,n);return this._markers.set(s,a),this.fire(`update:${s}`,a,null,t,{...a.getData(),range:null}),a}_remove(e){const t=e instanceof _u?e.name:e,i=this._markers.get(t);return !!i&&(this._markers.delete(t),this.fire(`update:${t}`,i,i.getRange(),null,i.getData()),this._destroyMarker(i),!0)}_refresh(e){const t=e instanceof _u?e.name:e,i=this._markers.get(t);if(!i)throw new A("markercollection-refresh-marker-not-exists",this);const n=i.getRange();this.fire(`update:${t}`,i,n,n,i.getData());}*getMarkersAtPosition(e){for(const t of this)t.getRange().containsPosition(e)&&(yield t);}*getMarkersIntersectingRange(e){for(const t of this)null!==t.getRange().getIntersection(e)&&(yield t);}destroy(){for(const e of this._markers.values())this._destroyMarker(e);this._markers=null,this.stopListening();}*getMarkersGroup(e){for(const t of this._markers.values())t.name.startsWith(e+":")&&(yield t);}_destroyMarker(e){e.stopListening(),e._detachLiveRange();}}class _u extends(L(Hl)){name;_managedUsingOperations;_affectsData;_liveRange;constructor(e,t,i,n){super(),this.name=e,this._liveRange=this._attachLiveRange(t),this._managedUsingOperations=i,this._affectsData=n;}get managedUsingOperations(){if(!this._liveRange)throw new A("marker-destroyed",this);return this._managedUsingOperations}get affectsData(){if(!this._liveRange)throw new A("marker-destroyed",this);return this._affectsData}getData(){return {range:this.getRange(),affectsData:this.affectsData,managedUsingOperations:this.managedUsingOperations}}getStart(){if(!this._liveRange)throw new A("marker-destroyed",this);return this._liveRange.start.clone()}getEnd(){if(!this._liveRange)throw new A("marker-destroyed",this);return this._liveRange.end.clone()}getRange(){if(!this._liveRange)throw new A("marker-destroyed",this);return this._liveRange.toRange()}_attachLiveRange(e){return this._liveRange&&this._detachLiveRange(),e.delegate("change:range").to(this),e.delegate("change:content").to(this),this._liveRange=e,e}_detachLiveRange(){this._liveRange.stopDelegating("change:range",this),this._liveRange.stopDelegating("change:content",this),this._liveRange.detach(),this._liveRange=null;}}_u.prototype.is=function(e){return "marker"===e||"model:marker"===e};class vu extends Ed{sourcePosition;howMany;constructor(e,t){super(null),this.sourcePosition=e.clone(),this.howMany=t;}get type(){return "detach"}get affectedSelectable(){return null}toJSON(){const e=super.toJSON();return e.sourcePosition=this.sourcePosition.toJSON(),e}_validate(){if(this.sourcePosition.root.document)throw new A("detach-operation-on-document-node",this)}_execute(){Pd(tc._createFromPositionAndShift(this.sourcePosition,this.howMany));}static get className(){return "DetachOperation"}}class yu extends Hl{markers=new Map;_children=new Ul;constructor(e){super(),e&&this._insertChild(0,e);}[Symbol.iterator](){return this.getChildren()}get childCount(){return this._children.length}get maxOffset(){return this._children.maxOffset}get isEmpty(){return 0===this.childCount}get nextSibling(){return null}get previousSibling(){return null}get root(){return this}get parent(){return null}get document(){return null}isAttached(){return !1}getAncestors(){return []}getChild(e){return this._children.getNode(e)}getChildAtOffset(e){return this._children.getNodeAtOffset(e)}getChildren(){return this._children[Symbol.iterator]()}getChildIndex(e){return this._children.getNodeIndex(e)}getChildStartOffset(e){return this._children.getNodeStartOffset(e)}getPath(){return []}getNodeByPath(e){let t=this;for(const i of e)t=t.getChildAtOffset(i);return t}offsetToIndex(e){return this._children.offsetToIndex(e)}toJSON(){const e=[];for(const t of this._children)e.push(t.toJSON());return e}static fromJSON(e){const t=[];for(const i of e)i.name?t.push(ql.fromJSON(i)):t.push(Wl.fromJSON(i));return new yu(t)}_appendChild(e){this._insertChild(this.childCount,e);}_insertChild(e,t){const i=function(e){if("string"==typeof e)return [new Wl(e)];oo(e)||(e=[e]);return Array.from(e).map((e=>"string"==typeof e?new Wl(e):e instanceof jl?new Wl(e.data,e.getAttributes()):e))}(t);for(const e of i)null!==e.parent&&e._remove(),e.parent=this;this._children._insertNodes(e,i);}_removeChildren(e,t=1){const i=this._children._removeNodes(e,t);for(const e of i)e.parent=null;return i}}yu.prototype.is=function(e){return "documentFragment"===e||"model:documentFragment"===e};class ku{model;batch;constructor(e,t){this.model=e,this.batch=t;}createText(e,t){return new Wl(e,t)}createElement(e,t){return new ql(e,t)}createDocumentFragment(){return new yu}cloneElement(e,t=!0){return e._clone(t)}insert(e,t,i=0){if(this._assertWriterUsedCorrectly(),e instanceof Wl&&""==e.data)return;const n=Zl._createAt(t,i);if(e.parent){if(Tu(e.root,n.root))return void this.move(tc._createOn(e),n);if(e.root.document)throw new A("model-writer-insert-forbidden-move",this);this.remove(e);}const s=n.root.document?n.root.document.version:null,o=new Md(n,e,s);if(e instanceof Wl&&(o.shouldReceiveAttributes=!0),this.batch.addOperation(o),this.model.applyOperation(o),e instanceof yu)for(const[t,i]of e.markers){const e=Zl._createAt(i.root,0),s={range:new tc(i.start._getCombined(e,n),i.end._getCombined(e,n)),usingOperation:!0,affectsData:!0};this.model.markers.has(t)?this.updateMarker(t,s):this.addMarker(t,s);}}insertText(e,t,i,n){t instanceof yu||t instanceof ql||t instanceof Zl?this.insert(this.createText(e),t,i):this.insert(this.createText(e,t),i,n);}insertElement(e,t,i,n){t instanceof yu||t instanceof ql||t instanceof Zl?this.insert(this.createElement(e),t,i):this.insert(this.createElement(e,t),i,n);}append(e,t){this.insert(e,t,"end");}appendText(e,t,i){t instanceof yu||t instanceof ql?this.insert(this.createText(e),t,"end"):this.insert(this.createText(e,t),i,"end");}appendElement(e,t,i){t instanceof yu||t instanceof ql?this.insert(this.createElement(e),t,"end"):this.insert(this.createElement(e,t),i,"end");}setAttribute(e,t,i){if(this._assertWriterUsedCorrectly(),i instanceof tc){const n=i.getMinimalFlatRanges();for(const i of n)Cu(this,e,t,i);}else xu(this,e,t,i);}setAttributes(e,t){for(const[i,n]of xr(e))this.setAttribute(i,n,t);}removeAttribute(e,t){if(this._assertWriterUsedCorrectly(),t instanceof tc){const i=t.getMinimalFlatRanges();for(const t of i)Cu(this,e,null,t);}else xu(this,e,null,t);}clearAttributes(e){this._assertWriterUsedCorrectly();const t=e=>{for(const t of e.getAttributeKeys())this.removeAttribute(t,e);};if(e instanceof tc)for(const i of e.getItems())t(i);else t(e);}move(e,t,i){if(this._assertWriterUsedCorrectly(),!(e instanceof tc))throw new A("writer-move-invalid-range",this);if(!e.isFlat)throw new A("writer-move-range-not-flat",this);const n=Zl._createAt(t,i);if(n.isEqual(e.start))return;if(this._addOperationForAffectedMarkers("move",e),!Tu(e.root,n.root))throw new A("writer-move-different-document",this);const s=e.root.document?e.root.document.version:null,o=new Bd(e.start,e.end.offset-e.start.offset,n,s);this.batch.addOperation(o),this.model.applyOperation(o);}remove(e){this._assertWriterUsedCorrectly();const t=(e instanceof tc?e:tc._createOn(e)).getMinimalFlatRanges().reverse();for(const e of t)this._addOperationForAffectedMarkers("move",e),Eu(e.start,e.end.offset-e.start.offset,this.batch,this.model);}merge(e){this._assertWriterUsedCorrectly();const t=e.nodeBefore,i=e.nodeAfter;if(this._addOperationForAffectedMarkers("merge",e),!(t instanceof ql))throw new A("writer-merge-no-element-before",this);if(!(i instanceof ql))throw new A("writer-merge-no-element-after",this);e.root.document?this._merge(e):this._mergeDetached(e);}createPositionFromPath(e,t,i){return this.model.createPositionFromPath(e,t,i)}createPositionAt(e,t){return this.model.createPositionAt(e,t)}createPositionAfter(e){return this.model.createPositionAfter(e)}createPositionBefore(e){return this.model.createPositionBefore(e)}createRange(e,t){return this.model.createRange(e,t)}createRangeIn(e){return this.model.createRangeIn(e)}createRangeOn(e){return this.model.createRangeOn(e)}createSelection(...e){return this.model.createSelection(...e)}_mergeDetached(e){const t=e.nodeBefore,i=e.nodeAfter;this.move(tc._createIn(i),Zl._createAt(t,"end")),this.remove(i);}_merge(e){const t=Zl._createAt(e.nodeBefore,"end"),i=Zl._createAt(e.nodeAfter,0),n=e.root.document.graveyard,s=new Zl(n,[0]),o=e.root.document.version,r=new Fd(i,e.nodeAfter.maxOffset,t,s,o);this.batch.addOperation(r),this.model.applyOperation(r);}rename(e,t){if(this._assertWriterUsedCorrectly(),!(e instanceof ql))throw new A("writer-rename-not-element-instance",this);const i=e.root.document?e.root.document.version:null,n=new Hd(Zl._createBefore(e),e.name,t,i);this.batch.addOperation(n),this.model.applyOperation(n);}split(e,t){this._assertWriterUsedCorrectly();let i,n,s=e.parent;if(!s.parent)throw new A("writer-split-element-no-parent",this);if(t||(t=s.parent),!e.parent.getAncestors({includeSelf:!0}).includes(t))throw new A("writer-split-invalid-limit-element",this);do{const t=s.root.document?s.root.document.version:null,o=s.maxOffset-e.offset,r=Ld.getInsertionPosition(e),a=new Ld(e,o,r,null,t);this.batch.addOperation(a),this.model.applyOperation(a),i||n||(i=s,n=e.parent.nextSibling),s=(e=this.createPositionAfter(e.parent)).parent;}while(s!==t);return {position:e,range:new tc(Zl._createAt(i,"end"),Zl._createAt(n,0))}}wrap(e,t){if(this._assertWriterUsedCorrectly(),!e.isFlat)throw new A("writer-wrap-range-not-flat",this);const i=t instanceof ql?t:new ql(t);if(i.childCount>0)throw new A("writer-wrap-element-not-empty",this);if(null!==i.parent)throw new A("writer-wrap-element-attached",this);this.insert(i,e.start);const n=new tc(e.start.getShiftedBy(1),e.end.getShiftedBy(1));this.move(n,Zl._createAt(i,0));}unwrap(e){if(this._assertWriterUsedCorrectly(),null===e.parent)throw new A("writer-unwrap-element-no-parent",this);this.move(tc._createIn(e),this.createPositionAfter(e)),this.remove(e);}addMarker(e,t){if(this._assertWriterUsedCorrectly(),!t||"boolean"!=typeof t.usingOperation)throw new A("writer-addmarker-no-usingoperation",this);const i=t.usingOperation,n=t.range,s=void 0!==t.affectsData&&t.affectsData;if(this.model.markers.has(e))throw new A("writer-addmarker-marker-exists",this);if(!n)throw new A("writer-addmarker-no-range",this);return i?(Au(this,e,null,n,s),this.model.markers.get(e)):this.model.markers._set(e,n,i,s)}updateMarker(e,t){this._assertWriterUsedCorrectly();const i="string"==typeof e?e:e.name,n=this.model.markers.get(i);if(!n)throw new A("writer-updatemarker-marker-not-exists",this);if(!t)return E("writer-updatemarker-reconvert-using-editingcontroller",{markerName:i}),void this.model.markers._refresh(n);const s="boolean"==typeof t.usingOperation,o="boolean"==typeof t.affectsData,r=o?t.affectsData:n.affectsData;if(!s&&!t.range&&!o)throw new A("writer-updatemarker-wrong-options",this);const a=n.getRange(),l=t.range?t.range:a;s&&t.usingOperation!==n.managedUsingOperations?t.usingOperation?Au(this,i,null,l,r):(Au(this,i,a,null,r),this.model.markers._set(i,l,void 0,r)):n.managedUsingOperations?Au(this,i,a,l,r):this.model.markers._set(i,l,void 0,r);}removeMarker(e){this._assertWriterUsedCorrectly();const t="string"==typeof e?e:e.name;if(!this.model.markers.has(t))throw new A("writer-removemarker-no-marker",this);const i=this.model.markers.get(t);if(!i.managedUsingOperations)return void this.model.markers._remove(t);Au(this,t,i.getRange(),null,i.affectsData);}addRoot(e,t="$root"){this._assertWriterUsedCorrectly();const i=this.model.document.getRoot(e);if(i&&i.isAttached())throw new A("writer-addroot-root-exists",this);const n=this.model.document,s=new Ud(e,t,!0,n,n.version);return this.batch.addOperation(s),this.model.applyOperation(s),this.model.document.getRoot(e)}detachRoot(e){this._assertWriterUsedCorrectly();const t="string"==typeof e?this.model.document.getRoot(e):e;if(!t||!t.isAttached())throw new A("writer-detachroot-no-root",this);for(const e of this.model.markers)e.getRange().root===t&&this.removeMarker(e);for(const e of t.getAttributeKeys())this.removeAttribute(e,t);this.remove(this.createRangeIn(t));const i=this.model.document,n=new Ud(t.rootName,t.name,!1,i,i.version);this.batch.addOperation(n),this.model.applyOperation(n);}setSelection(...e){this._assertWriterUsedCorrectly(),this.model.document.selection._setTo(...e);}setSelectionFocus(e,t){this._assertWriterUsedCorrectly(),this.model.document.selection._setFocus(e,t);}setSelectionAttribute(e,t){if(this._assertWriterUsedCorrectly(),"string"==typeof e)this._setSelectionAttribute(e,t);else for(const[t,i]of xr(e))this._setSelectionAttribute(t,i);}removeSelectionAttribute(e){if(this._assertWriterUsedCorrectly(),"string"==typeof e)this._removeSelectionAttribute(e);else for(const t of e)this._removeSelectionAttribute(t);}overrideSelectionGravity(){return this.model.document.selection._overrideGravity()}restoreSelectionGravity(e){this.model.document.selection._restoreGravity(e);}_setSelectionAttribute(e,t){const i=this.model.document.selection;if(i.isCollapsed&&i.anchor.parent.isEmpty){const n=_c._getStoreAttributeKey(e);this.setAttribute(n,t,i.anchor.parent);}i._setAttribute(e,t);}_removeSelectionAttribute(e){const t=this.model.document.selection;if(t.isCollapsed&&t.anchor.parent.isEmpty){const i=_c._getStoreAttributeKey(e);this.removeAttribute(i,t.anchor.parent);}t._removeAttribute(e);}_assertWriterUsedCorrectly(){if(this.model._currentWriter!==this)throw new A("writer-incorrect-use",this)}_addOperationForAffectedMarkers(e,t){for(const i of this.model.markers){if(!i.managedUsingOperations)continue;const n=i.getRange();let s=!1;if("move"===e){const e=t;s=e.containsPosition(n.start)||e.start.isEqual(n.start)||e.containsPosition(n.end)||e.end.isEqual(n.end);}else {const e=t,i=e.nodeBefore,o=e.nodeAfter,r=n.start.parent==i&&n.start.isAtEnd,a=n.end.parent==o&&0==n.end.offset,l=n.end.nodeAfter==o,c=n.start.nodeAfter==o;s=r||a||l||c;}s&&this.updateMarker(i.name,{range:n});}}}function Cu(e,t,i,n){const s=e.model,o=s.document;let r,a,l,c=n.start;for(const e of n.getWalker({shallow:!0}))l=e.item.getAttribute(t),r&&a!=l&&(a!=i&&d(),c=r),r=e.nextPosition,a=l;function d(){const n=new tc(c,r),l=n.root.document?o.version:null,d=new Dd(n,t,a,i,l);e.batch.addOperation(d),s.applyOperation(d);}r instanceof Zl&&r!=c&&a!=i&&d();}function xu(e,t,i,n){const s=e.model,o=s.document,r=n.getAttribute(t);let a,l;if(r!=i){if(n.root===n){const e=n.document?o.version:null;l=new $d(n,t,r,i,e);}else {a=new tc(Zl._createBefore(n),e.createPositionAfter(n));const s=a.root.document?o.version:null;l=new Dd(a,t,r,i,s);}e.batch.addOperation(l),s.applyOperation(l);}}function Au(e,t,i,n,s){const o=e.model,r=o.document,a=new Nd(t,i,n,o.markers,!!s,r.version);e.batch.addOperation(a),o.applyOperation(a);}function Eu(e,t,i,n){let s;if(e.root.document){const i=n.document,o=new Zl(i.graveyard,[0]);s=new Bd(e,t,o,i.version);}else s=new vu(e,t);i.addOperation(s),n.applyOperation(s);}function Tu(e,t){return e===t||e instanceof gu&&t instanceof gu}function Pu(e,t,i={}){if(t.isCollapsed)return;const n=t.getFirstRange();if("$graveyard"==n.root.rootName)return;const s=e.schema;e.change((e=>{if(!i.doNotResetEntireContent&&function(e,t){const i=e.getLimitElement(t);if(!t.containsEntireContent(i))return !1;const n=t.getFirstRange();if(n.start.parent==n.end.parent)return !1;return e.checkChild(i,"paragraph")}(s,t))return void function(e,t){const i=e.model.schema.getLimitElement(t);e.remove(e.createRangeIn(i)),Ru(e,e.createPositionAt(i,0),t);}(e,t);const o={};if(!i.doNotAutoparagraph){const e=t.getSelectedElement();e&&Object.assign(o,s.getAttributesWithProperty(e,"copyOnReplace",!0));}const[r,a]=function(e){const t=e.root.document.model,i=e.start;let n=e.end;if(t.hasContent(e,{ignoreMarkers:!0})){const i=function(e){const t=e.parent,i=t.root.document.model.schema,n=t.getAncestors({parentFirst:!0,includeSelf:!0});for(const e of n){if(i.isLimit(e))return null;if(i.isBlock(e))return e}}(n);if(i&&n.isTouching(t.createPositionAt(i,0))){const i=t.createSelection(e);t.modifySelection(i,{direction:"backward"});const s=i.getLastPosition(),o=t.createRange(s,n);t.hasContent(o,{ignoreMarkers:!0})||(n=s);}}return [su.fromPosition(i,"toPrevious"),su.fromPosition(n,"toNext")]}(n);r.isTouching(a)||e.remove(e.createRange(r,a)),i.leaveUnmerged||(!function(e,t,i){const n=e.model;if(!Vu(e.model.schema,t,i))return;const[s,o]=function(e,t){const i=e.getAncestors(),n=t.getAncestors();let s=0;for(;i[s]&&i[s]==n[s];)s++;return [i[s],n[s]]}(t,i);if(!s||!o)return;!n.hasContent(s,{ignoreMarkers:!0})&&n.hasContent(o,{ignoreMarkers:!0})?Iu(e,t,i,s.parent):Su(e,t,i,s.parent);}(e,r,a),s.removeDisallowedAttributes(r.parent.getChildren(),e)),Ou(e,t,r),!i.doNotAutoparagraph&&function(e,t){const i=e.checkChild(t,"$text"),n=e.checkChild(t,"paragraph");return !i&&n}(s,r)&&Ru(e,r,t,o),r.detach(),a.detach();}));}function Su(e,t,i,n){const s=t.parent,o=i.parent;if(s!=n&&o!=n){for(t=e.createPositionAfter(s),(i=e.createPositionBefore(o)).isEqual(t)||e.insert(o,t),e.merge(t);i.parent.isEmpty;){const t=i.parent;i=e.createPositionBefore(t),e.remove(t);}Vu(e.model.schema,t,i)&&Su(e,t,i,n);}}function Iu(e,t,i,n){const s=t.parent,o=i.parent;if(s!=n&&o!=n){for(t=e.createPositionAfter(s),(i=e.createPositionBefore(o)).isEqual(t)||e.insert(s,i);t.parent.isEmpty;){const i=t.parent;t=e.createPositionBefore(i),e.remove(i);}i=e.createPositionBefore(o),function(e,t){const i=t.nodeBefore,n=t.nodeAfter;i.name!=n.name&&e.rename(i,n.name);e.clearAttributes(i),e.setAttributes(Object.fromEntries(n.getAttributes()),i),e.merge(t);}(e,i),Vu(e.model.schema,t,i)&&Iu(e,t,i,n);}}function Vu(e,t,i){const n=t.parent,s=i.parent;return n!=s&&(!e.isLimit(n)&&!e.isLimit(s)&&function(e,t,i){const n=new tc(e,t);for(const e of n.getWalker())if(i.isLimit(e.item))return !1;return !0}(t,i,e))}function Ru(e,t,i,n={}){const s=e.createElement("paragraph");e.model.schema.setAllowedAttributes(s,n,e),e.insert(s,t),Ou(e,i,e.createPositionAt(s,0));}function Ou(e,t,i){t instanceof _c?e.setSelection(i):t.setTo(i);}function Bu(e,t){const i=[];Array.from(e.getItems({direction:"backward"})).map((e=>t.createRangeOn(e))).filter((t=>(t.start.isAfter(e.start)||t.start.isEqual(e.start))&&(t.end.isBefore(e.end)||t.end.isEqual(e.end)))).forEach((e=>{i.push(e.start.parent),t.remove(e);})),i.forEach((e=>{let i=e;for(;i.parent&&i.isEmpty;){const e=t.createRangeOn(i);i=i.parent,t.remove(e);}}));}class Mu{model;writer;position;canMergeWith;schema;_documentFragment;_documentFragmentPosition;_firstNode=null;_lastNode=null;_lastAutoParagraph=null;_filterAttributesOf=[];_affectedStart=null;_affectedEnd=null;_nodeToSelect=null;constructor(e,t,i){this.model=e,this.writer=t,this.position=i,this.canMergeWith=new Set([this.position.parent]),this.schema=e.schema,this._documentFragment=t.createDocumentFragment(),this._documentFragmentPosition=t.createPositionAt(this._documentFragment,0);}handleNodes(e){for(const t of Array.from(e))this._handleNode(t);this._insertPartialFragment(),this._lastAutoParagraph&&this._updateLastNodeFromAutoParagraph(this._lastAutoParagraph),this._mergeOnRight(),this.schema.removeDisallowedAttributes(this._filterAttributesOf,this.writer),this._filterAttributesOf=[];}_updateLastNodeFromAutoParagraph(e){const t=this.writer.createPositionAfter(this._lastNode),i=this.writer.createPositionAfter(e);if(i.isAfter(t)){if(this._lastNode=e,this.position.parent!=e||!this.position.isAtEnd)throw new A("insertcontent-invalid-insertion-position",this);this.position=i,this._setAffectedBoundaries(this.position);}}getSelectionRange(){return this._nodeToSelect?tc._createOn(this._nodeToSelect):this.model.schema.getNearestSelectionRange(this.position)}getAffectedRange(){return this._affectedStart?new tc(this._affectedStart,this._affectedEnd):null}destroy(){this._affectedStart&&this._affectedStart.detach(),this._affectedEnd&&this._affectedEnd.detach();}_handleNode(e){this._checkAndSplitToAllowedPosition(e)?(this._appendToFragment(e),this._firstNode||(this._firstNode=e),this._lastNode=e):this.schema.isObject(e)||this._handleDisallowedNode(e);}_insertPartialFragment(){if(this._documentFragment.isEmpty)return;const e=su.fromPosition(this.position,"toNext");this._setAffectedBoundaries(this.position),this._documentFragment.getChild(0)==this._firstNode&&(this.writer.insert(this._firstNode,this.position),this._mergeOnLeft(),this.position=e.toPosition()),this._documentFragment.isEmpty||this.writer.insert(this._documentFragment,this.position),this._documentFragmentPosition=this.writer.createPositionAt(this._documentFragment,0),this.position=e.toPosition(),e.detach();}_handleDisallowedNode(e){e.is("element")&&this.handleNodes(e.getChildren());}_appendToFragment(e){if(!this.schema.checkChild(this.position,e))throw new A("insertcontent-wrong-position",this,{node:e,position:this.position});this.writer.insert(e,this._documentFragmentPosition),this._documentFragmentPosition=this._documentFragmentPosition.getShiftedBy(e.offsetSize),this.schema.isObject(e)&&!this.schema.checkChild(this.position,"$text")?this._nodeToSelect=e:this._nodeToSelect=null,this._filterAttributesOf.push(e);}_setAffectedBoundaries(e){this._affectedStart||(this._affectedStart=su.fromPosition(e,"toPrevious")),this._affectedEnd&&!this._affectedEnd.isBefore(e)||(this._affectedEnd&&this._affectedEnd.detach(),this._affectedEnd=su.fromPosition(e,"toNext"));}_mergeOnLeft(){const e=this._firstNode;if(!(e instanceof ql))return;if(!this._canMergeLeft(e))return;const t=su._createBefore(e);t.stickiness="toNext";const i=su.fromPosition(this.position,"toNext");this._affectedStart.isEqual(t)&&(this._affectedStart.detach(),this._affectedStart=su._createAt(t.nodeBefore,"end","toPrevious")),this._firstNode===this._lastNode&&(this._firstNode=t.nodeBefore,this._lastNode=t.nodeBefore),this.writer.merge(t),t.isEqual(this._affectedEnd)&&this._firstNode===this._lastNode&&(this._affectedEnd.detach(),this._affectedEnd=su._createAt(t.nodeBefore,"end","toNext")),this.position=i.toPosition(),i.detach(),this._filterAttributesOf.push(this.position.parent),t.detach();}_mergeOnRight(){const e=this._lastNode;if(!(e instanceof ql))return;if(!this._canMergeRight(e))return;const t=su._createAfter(e);if(t.stickiness="toNext",!this.position.isEqual(t))throw new A("insertcontent-invalid-insertion-position",this);this.position=Zl._createAt(t.nodeBefore,"end");const i=su.fromPosition(this.position,"toPrevious");this._affectedEnd.isEqual(t)&&(this._affectedEnd.detach(),this._affectedEnd=su._createAt(t.nodeBefore,"end","toNext")),this._firstNode===this._lastNode&&(this._firstNode=t.nodeBefore,this._lastNode=t.nodeBefore),this.writer.merge(t),t.getShiftedBy(-1).isEqual(this._affectedStart)&&this._firstNode===this._lastNode&&(this._affectedStart.detach(),this._affectedStart=su._createAt(t.nodeBefore,0,"toPrevious")),this.position=i.toPosition(),i.detach(),this._filterAttributesOf.push(this.position.parent),t.detach();}_canMergeLeft(e){const t=e.previousSibling;return t instanceof ql&&this.canMergeWith.has(t)&&this.model.schema.checkMerge(t,e)}_canMergeRight(e){const t=e.nextSibling;return t instanceof ql&&this.canMergeWith.has(t)&&this.model.schema.checkMerge(e,t)}_insertAutoParagraph(){this._insertPartialFragment();const e=this.writer.createElement("paragraph");this.writer.insert(e,this.position),this._setAffectedBoundaries(this.position),this._lastAutoParagraph=e,this.position=this.writer.createPositionAt(e,0);}_checkAndSplitToAllowedPosition(e){const t=this._getAllowedIn(this.position.parent,e);if(!t)return !1;for(t!=this.position.parent&&this._insertPartialFragment();t!=this.position.parent;)if(this.position.isAtStart){const e=this.position.parent;this.position=this.writer.createPositionBefore(e),e.isEmpty&&e.parent===t&&this.writer.remove(e);}else if(this.position.isAtEnd)this.position=this.writer.createPositionAfter(this.position.parent);else {const e=this.writer.createPositionAfter(this.position.parent);this._setAffectedBoundaries(this.position),this.writer.split(this.position),this.position=e,this.canMergeWith.add(this.position.nodeAfter);}return this.schema.checkChild(this.position.parent,e)||this._insertAutoParagraph(),!0}_getAllowedIn(e,t){return this.schema.checkChild(e,t)||this.schema.checkChild(e,"paragraph")&&this.schema.checkChild("paragraph",t)?e:this.schema.isLimit(e)?null:this._getAllowedIn(e.parent,t)}}function Lu(e,t,i,n={}){if(!e.schema.isObject(t))throw new A("insertobject-element-not-an-object",e,{object:t});const s=i||e.document.selection;let o=s;n.findOptimalPosition&&e.schema.isBlock(t)&&(o=e.createSelection(e.schema.findOptimalInsertionRange(s,n.findOptimalPosition)));const r=wr(s.getSelectedBlocks()),a={};return r&&Object.assign(a,e.schema.getAttributesWithProperty(r,"copyOnReplace",!0)),e.change((i=>{o.isCollapsed||e.deleteContent(o,{doNotAutoparagraph:!0});let s=t;const r=o.anchor.parent;!e.schema.checkChild(r,t)&&e.schema.checkChild(r,"paragraph")&&e.schema.checkChild("paragraph",t)&&(s=i.createElement("paragraph"),i.insert(t,s)),e.schema.setAllowedAttributes(s,a,i);const l=e.insertContent(s,o);return l.isCollapsed||n.setSelection&&function(e,t,i,n){const s=e.model;if("on"==i)return void e.setSelection(t,"on");if("after"!=i)throw new A("insertobject-invalid-place-parameter-value",s);let o=t.nextSibling;if(s.schema.isInline(t))return void e.setSelection(t,"after");const r=o&&s.schema.checkChild(o,"$text");!r&&s.schema.checkChild(t.parent,"paragraph")&&(o=e.createElement("paragraph"),s.schema.setAllowedAttributes(o,n,e),s.insertContent(o,e.createPositionAfter(t)));o&&e.setSelection(o,0);}(i,t,n.setSelection,a),l}))}function Fu(e,t){const{isForward:i,walker:n,unit:s,schema:o,treatEmojiAsSingleUnit:r}=e,{type:a,item:l,nextPosition:c}=t;if("text"==a)return "word"===e.unit?function(e,t){let i=e.position.textNode;i||(i=t?e.position.nodeAfter:e.position.nodeBefore);for(;i&&i.is("$text");){const n=e.position.offset-i.startOffset;if(zu(i,n,t))i=t?e.position.nodeAfter:e.position.nodeBefore;else {if(Du(i.data,n,t))break;e.next();}}return e.position}(n,i):function(e,t,i){const n=e.position.textNode;if(n){const s=n.data;let o=e.position.offset-n.startOffset;for(;Br(s,o)||"character"==t&&Mr(s,o)||i&&Fr(s,o);)e.next(),o=e.position.offset-n.startOffset;}return e.position}(n,s,r);if(a==(i?"elementStart":"elementEnd")){if(o.isSelectable(l))return Zl._createAt(l,i?"after":"before");if(o.checkChild(c,"$text"))return c}else {if(o.isLimit(l))return void n.skip((()=>!0));if(o.checkChild(c,"$text"))return c}}function Nu(e,t){const i=e.root,n=Zl._createAt(i,t?"end":0);return t?new tc(e,n):new tc(n,e)}function Du(e,t,i){const n=t+(i?0:-1);return ' ,.?!:;"-()'.includes(e.charAt(n))}function zu(e,t,i){return t===(i?e.offsetSize:0)}let Hu=class extends(Zs()){markers;document;schema;_pendingChanges;_currentWriter;constructor(){super(),this.markers=new wu,this.document=new pu(this),this.schema=new nd,this._pendingChanges=[],this._currentWriter=null,["deleteContent","modifySelection","getSelectedContent","applyOperation"].forEach((e=>this.decorate(e))),this.on("applyOperation",((e,t)=>{t[0]._validate();}),{priority:"highest"}),this.schema.register("$root",{isLimit:!0}),this.schema.register("$container",{allowIn:["$root","$container"]}),this.schema.register("$block",{allowIn:["$root","$container"],isBlock:!0}),this.schema.register("$blockObject",{allowWhere:"$block",isBlock:!0,isObject:!0}),this.schema.register("$inlineObject",{allowWhere:"$text",allowAttributesOf:"$text",isInline:!0,isObject:!0}),this.schema.register("$text",{allowIn:"$block",isInline:!0,isContent:!0}),this.schema.register("$clipboardHolder",{allowContentOf:"$root",allowChildren:"$text",isLimit:!0}),this.schema.register("$documentFragment",{allowContentOf:"$root",allowChildren:"$text",isLimit:!0}),this.schema.register("$marker"),this.schema.addChildCheck((()=>!0),"$marker"),Zc(this),this.document.registerPostFixer(Dc),this.on("insertContent",((e,[t,i])=>{e.return=function(e,t,i){return e.change((n=>{const s=i||e.document.selection;s.isCollapsed||e.deleteContent(s,{doNotAutoparagraph:!0});const o=new Mu(e,n,s.anchor),r=[];let a;if(t.is("documentFragment")){if(t.markers.size){const e=[];for(const[i,n]of t.markers){const{start:t,end:s}=n,o=t.isEqual(s);e.push({position:t,name:i,isCollapsed:o},{position:s,name:i,isCollapsed:o});}e.sort((({position:e},{position:t})=>e.isBefore(t)?1:-1));for(const{position:i,name:s,isCollapsed:o}of e){let e=null,a=null;const l=i.parent===t&&i.isAtStart,c=i.parent===t&&i.isAtEnd;l||c?o&&(a=l?"start":"end"):(e=n.createElement("$marker"),n.insert(e,i)),r.push({name:s,element:e,collapsed:a});}}a=t.getChildren();}else a=[t];o.handleNodes(a);let l=o.getSelectionRange();if(t.is("documentFragment")&&r.length){const e=l?fc.fromRange(l):null,t={};for(let e=r.length-1;e>=0;e--){const{name:i,element:s,collapsed:a}=r[e],l=!t[i];if(l&&(t[i]=[]),s){const e=n.createPositionAt(s,"before");t[i].push(e),n.remove(s);}else {const e=o.getAffectedRange();if(!e){a&&t[i].push(o.position);continue}a?t[i].push(e[a]):t[i].push(l?e.start:e.end);}}for(const[e,[i,s]]of Object.entries(t))i&&s&&i.root===s.root&&i.root.document&&!n.model.markers.has(e)&&n.addMarker(e,{usingOperation:!0,affectsData:!0,range:new tc(i,s)});e&&(l=e.toRange(),e.detach());}l&&(s instanceof _c?n.setSelection(l):s.setTo(l));const c=o.getAffectedRange()||e.createRange(s.anchor);return o.destroy(),c}))}(this,t,i);})),this.on("insertObject",((e,[t,i,n])=>{e.return=Lu(this,t,i,n);})),this.on("canEditAt",(e=>{const t=!this.document.isReadOnly;e.return=t,t||e.stop();}));}change(e){try{return 0===this._pendingChanges.length?(this._pendingChanges.push({batch:new au,callback:e}),this._runPendingChanges()[0]):e(this._currentWriter)}catch(e){A.rethrowUnexpectedError(e,this);}}enqueueChange(e,t){try{e?"function"==typeof e?(t=e,e=new au):e instanceof au||(e=new au(e)):e=new au,this._pendingChanges.push({batch:e,callback:t}),1==this._pendingChanges.length&&this._runPendingChanges();}catch(e){A.rethrowUnexpectedError(e,this);}}applyOperation(e){e._execute();}insertContent(e,t,i,...n){const s=$u(t,i);return this.fire("insertContent",[e,s,i,...n])}insertObject(e,t,i,n,...s){const o=$u(t,i);return this.fire("insertObject",[e,o,n,n,...s])}deleteContent(e,t){Pu(this,e,t);}modifySelection(e,t){!function(e,t,i={}){const n=e.schema,s="backward"!=i.direction,o=i.unit?i.unit:"character",r=!!i.treatEmojiAsSingleUnit,a=t.focus,l=new Gl({boundaries:Nu(a,s),singleCharacters:!0,direction:s?"forward":"backward"}),c={walker:l,schema:n,isForward:s,unit:o,treatEmojiAsSingleUnit:r};let d;for(;d=l.next();){if(d.done)return;const i=Fu(c,d.value);if(i)return void(t instanceof _c?e.change((e=>{e.setSelectionFocus(i);})):t.setFocus(i))}}(this,e,t);}getSelectedContent(e){return function(e,t){return e.change((e=>{const i=e.createDocumentFragment(),n=t.getFirstRange();if(!n||n.isCollapsed)return i;const s=n.start.root,o=n.start.getCommonPath(n.end),r=s.getNodeByPath(o);let a;a=n.start.parent==n.end.parent?n:e.createRange(e.createPositionAt(r,n.start.path[o.length]),e.createPositionAt(r,n.end.path[o.length]+1));const l=a.end.offset-a.start.offset;for(const t of a.getItems({shallow:!0}))t.is("$textProxy")?e.appendText(t.data,t.getAttributes(),i):e.append(e.cloneElement(t,!0),i);if(a!=n){const t=n._getTransformedByMove(a.start,e.createPositionAt(i,0),l)[0],s=e.createRange(e.createPositionAt(i,0),t.start);Bu(e.createRange(t.end,e.createPositionAt(i,"end")),e),Bu(s,e);}return i}))}(this,e)}hasContent(e,t={}){const i=e instanceof tc?e:tc._createIn(e);if(i.isCollapsed)return !1;const{ignoreWhitespaces:n=!1,ignoreMarkers:s=!1}=t;if(!s)for(const e of this.markers.getMarkersIntersectingRange(i))if(e.affectsData)return !0;for(const e of i.getItems())if(this.schema.isContent(e)){if(!e.is("$textProxy"))return !0;if(!n)return !0;if(-1!==e.data.search(/\S/))return !0}return !1}canEditAt(e){const t=$u(e);return this.fire("canEditAt",[t])}createPositionFromPath(e,t,i){return new Zl(e,t,i)}createPositionAt(e,t){return Zl._createAt(e,t)}createPositionAfter(e){return Zl._createAfter(e)}createPositionBefore(e){return Zl._createBefore(e)}createRange(e,t){return new tc(e,t)}createRangeIn(e){return tc._createIn(e)}createRangeOn(e){return tc._createOn(e)}createSelection(...e){return new lc(...e)}createBatch(e){return new au(e)}createOperationFromJSON(e){return jd.fromJSON(e,this.document)}destroy(){this.document.destroy(),this.stopListening();}_runPendingChanges(){const e=[];this.fire("_beforeChanges");try{for(;this._pendingChanges.length;){const t=this._pendingChanges[0].batch;this._currentWriter=new ku(this,t);const i=this._pendingChanges[0].callback(this._currentWriter);e.push(i),this.document._handleChangeBlock(this._currentWriter),this._pendingChanges.shift(),this._currentWriter=null;}}finally{this._pendingChanges.length=0,this._currentWriter=null,this.fire("_afterChanges");}return e}};function $u(e,t){if(e)return e instanceof lc||e instanceof _c?e:e instanceof $l?t||0===t?new lc(e,t):e.is("rootElement")?new lc(e,"in"):new lc(e,"on"):new lc(e)}class Uu extends Tl{domEventType="click";onDomEvent(e){this.fire(e.type,e);}}class Wu extends Tl{domEventType=["mousedown","mouseup","mouseover","mouseout"];onDomEvent(e){this.fire(e.type,e);}}class ju{document;constructor(e){this.document=e;}createDocumentFragment(e){return new ja(this.document,e)}createElement(e,t,i){return new ga(this.document,e,t,i)}createText(e){return new oa(this.document,e)}clone(e,t=!1){return e._clone(t)}appendChild(e,t){return t._appendChild(e)}insertChild(e,t,i){return i._insertChild(e,t)}removeChildren(e,t,i){return i._removeChildren(e,t)}remove(e){const t=e.parent;return t?this.removeChildren(t.getChildIndex(e),1,t):[]}replace(e,t){const i=e.parent;if(i){const n=i.getChildIndex(e);return this.removeChildren(n,1,i),this.insertChild(n,t,i),!0}return !1}unwrapElement(e){const t=e.parent;if(t){const i=t.getChildIndex(e);this.remove(e),this.insertChild(i,e.getChildren(),t);}}rename(e,t){const i=new ga(this.document,e,t.getAttributes(),t.getChildren());return this.replace(t,i)?i:null}setAttribute(e,t,i){i._setAttribute(e,t);}removeAttribute(e,t){t._removeAttribute(e);}addClass(e,t){t._addClass(e);}removeClass(e,t){t._removeClass(e);}setStyle(e,t,i){ei(e)&&void 0===i?t._setStyle(e):i._setStyle(e,t);}removeStyle(e,t){t._removeStyle(e);}setCustomProperty(e,t,i){i._setCustomProperty(e,t);}removeCustomProperty(e,t){return t._removeCustomProperty(e)}createPositionAt(e,t){return ka._createAt(e,t)}createPositionAfter(e){return ka._createAfter(e)}createPositionBefore(e){return ka._createBefore(e)}createRange(e,t){return new Ca(e,t)}createRangeOn(e){return Ca._createOn(e)}createRangeIn(e){return Ca._createIn(e)}createSelection(...e){return new Aa(...e)}}const qu=/^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i,Gu=/^rgb\([ ]?([0-9]{1,3}[ %]?,[ ]?){2,3}[0-9]{1,3}[ %]?\)$/i,Ku=/^rgba\([ ]?([0-9]{1,3}[ %]?,[ ]?){3}(1|[0-9]+%|[0]?\.?[0-9]+)\)$/i,Zu=/^hsl\([ ]?([0-9]{1,3}[ %]?[,]?[ ]*){3}(1|[0-9]+%|[0]?\.?[0-9]+)?\)$/i,Ju=/^hsla\([ ]?([0-9]{1,3}[ %]?,[ ]?){2,3}(1|[0-9]+%|[0]?\.?[0-9]+)\)$/i,Qu=/\w+\((?:[^()]|\([^()]*\))*\)|\S+/gi,Yu=new Set(["black","silver","gray","white","maroon","red","purple","fuchsia","green","lime","olive","yellow","navy","blue","teal","aqua","orange","aliceblue","antiquewhite","aquamarine","azure","beige","bisque","blanchedalmond","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","gainsboro","ghostwhite","gold","goldenrod","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","limegreen","linen","magenta","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","oldlace","olivedrab","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","thistle","tomato","turquoise","violet","wheat","whitesmoke","yellowgreen","activeborder","activecaption","appworkspace","background","buttonface","buttonhighlight","buttonshadow","buttontext","captiontext","graytext","highlight","highlighttext","inactiveborder","inactivecaption","inactivecaptiontext","infobackground","infotext","menu","menutext","scrollbar","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","window","windowframe","windowtext","rebeccapurple","currentcolor","transparent"]);function Xu(e){return e.startsWith("#")?qu.test(e):e.startsWith("rgb")?Gu.test(e)||Ku.test(e):e.startsWith("hsl")?Zu.test(e)||Ju.test(e):Yu.has(e.toLowerCase())}const eh=["none","hidden","dotted","dashed","solid","double","groove","ridge","inset","outset"];function th(e){return eh.includes(e)}const ih=/^([+-]?[0-9]*([.][0-9]+)?(px|cm|mm|in|pc|pt|ch|em|ex|rem|vh|vw|vmin|vmax)|0)$/;function nh(e){return ih.test(e)}const sh=/^[+-]?[0-9]*([.][0-9]+)?%$/;function oh(e){return sh.test(e)}const rh=["repeat-x","repeat-y","repeat","space","round","no-repeat"];function ah(e){return rh.includes(e)}const lh=["center","top","bottom","left","right"];function ch(e){return lh.includes(e)}const dh=["fixed","scroll","local"];function uh(e){return dh.includes(e)}const hh=/^url\(/;function mh(e){return hh.test(e)}function gh(e=""){if(""===e)return {top:void 0,right:void 0,bottom:void 0,left:void 0};const t=wh(e),i=t[0],n=t[2]||i,s=t[1]||i;return {top:i,bottom:n,right:s,left:t[3]||s}}function fh(e){return t=>{const{top:i,right:n,bottom:s,left:o}=t,r=[];return [i,n,o,s].every((e=>!!e))?r.push([e,ph(t)]):(i&&r.push([e+"-top",i]),n&&r.push([e+"-right",n]),s&&r.push([e+"-bottom",s]),o&&r.push([e+"-left",o])),r}}function ph({top:e,right:t,bottom:i,left:n}){const s=[];return n!==t?s.push(e,t,i,n):i!==e?s.push(e,t,i):t!==e?s.push(e,t):s.push(e),s.join(" ")}function bh(e){return t=>({path:e,value:gh(t)})}function wh(e){const t=e.trim().slice(0,1500).matchAll(Qu);return Array.from(t).map((e=>e[0]))}function _h(e){e.setNormalizer("background",(e=>{const t={},i=wh(e);for(const e of i)ah(e)?(t.repeat=t.repeat||[],t.repeat.push(e)):ch(e)?(t.position=t.position||[],t.position.push(e)):uh(e)?t.attachment=e:Xu(e)?t.color=e:mh(e)&&(t.image=e);return {path:"background",value:t}})),e.setNormalizer("background-color",(e=>({path:"background.color",value:e}))),e.setReducer("background",(e=>{const t=[];return t.push(["background-color",e.color]),t})),e.setStyleRelation("background",["background-color"]);}function vh(e){e.setNormalizer("border",(e=>{const{color:t,style:i,width:n}=Th(e);return {path:"border",value:{color:gh(t),style:gh(i),width:gh(n)}}})),e.setNormalizer("border-top",yh("top")),e.setNormalizer("border-right",yh("right")),e.setNormalizer("border-bottom",yh("bottom")),e.setNormalizer("border-left",yh("left")),e.setNormalizer("border-color",kh("color")),e.setNormalizer("border-width",kh("width")),e.setNormalizer("border-style",kh("style")),e.setNormalizer("border-top-color",xh("color","top")),e.setNormalizer("border-top-style",xh("style","top")),e.setNormalizer("border-top-width",xh("width","top")),e.setNormalizer("border-right-color",xh("color","right")),e.setNormalizer("border-right-style",xh("style","right")),e.setNormalizer("border-right-width",xh("width","right")),e.setNormalizer("border-bottom-color",xh("color","bottom")),e.setNormalizer("border-bottom-style",xh("style","bottom")),e.setNormalizer("border-bottom-width",xh("width","bottom")),e.setNormalizer("border-left-color",xh("color","left")),e.setNormalizer("border-left-style",xh("style","left")),e.setNormalizer("border-left-width",xh("width","left")),e.setExtractor("border-top",Ah("top")),e.setExtractor("border-right",Ah("right")),e.setExtractor("border-bottom",Ah("bottom")),e.setExtractor("border-left",Ah("left")),e.setExtractor("border-top-color","border.color.top"),e.setExtractor("border-right-color","border.color.right"),e.setExtractor("border-bottom-color","border.color.bottom"),e.setExtractor("border-left-color","border.color.left"),e.setExtractor("border-top-width","border.width.top"),e.setExtractor("border-right-width","border.width.right"),e.setExtractor("border-bottom-width","border.width.bottom"),e.setExtractor("border-left-width","border.width.left"),e.setExtractor("border-top-style","border.style.top"),e.setExtractor("border-right-style","border.style.right"),e.setExtractor("border-bottom-style","border.style.bottom"),e.setExtractor("border-left-style","border.style.left"),e.setReducer("border-color",fh("border-color")),e.setReducer("border-style",fh("border-style")),e.setReducer("border-width",fh("border-width")),e.setReducer("border-top",Ph("top")),e.setReducer("border-right",Ph("right")),e.setReducer("border-bottom",Ph("bottom")),e.setReducer("border-left",Ph("left")),e.setReducer("border",function(){return t=>{const i=Eh(t,"top"),n=Eh(t,"right"),s=Eh(t,"bottom"),o=Eh(t,"left"),r=[i,n,s,o],a={width:e(r,"width"),style:e(r,"style"),color:e(r,"color")},l=Sh(a,"all");if(l.length)return l;const c=Object.entries(a).reduce(((e,[t,i])=>(i&&(e.push([`border-${t}`,i]),r.forEach((e=>delete e[t]))),e)),[]);return [...c,...Sh(i,"top"),...Sh(n,"right"),...Sh(s,"bottom"),...Sh(o,"left")]};function e(e,t){return e.map((e=>e[t])).reduce(((e,t)=>e==t?e:null))}}()),e.setStyleRelation("border",["border-color","border-style","border-width","border-top","border-right","border-bottom","border-left","border-top-color","border-right-color","border-bottom-color","border-left-color","border-top-style","border-right-style","border-bottom-style","border-left-style","border-top-width","border-right-width","border-bottom-width","border-left-width"]),e.setStyleRelation("border-color",["border-top-color","border-right-color","border-bottom-color","border-left-color"]),e.setStyleRelation("border-style",["border-top-style","border-right-style","border-bottom-style","border-left-style"]),e.setStyleRelation("border-width",["border-top-width","border-right-width","border-bottom-width","border-left-width"]),e.setStyleRelation("border-top",["border-top-color","border-top-style","border-top-width"]),e.setStyleRelation("border-right",["border-right-color","border-right-style","border-right-width"]),e.setStyleRelation("border-bottom",["border-bottom-color","border-bottom-style","border-bottom-width"]),e.setStyleRelation("border-left",["border-left-color","border-left-style","border-left-width"]);}function yh(e){return t=>{const{color:i,style:n,width:s}=Th(t),o={};return void 0!==i&&(o.color={[e]:i}),void 0!==n&&(o.style={[e]:n}),void 0!==s&&(o.width={[e]:s}),{path:"border",value:o}}}function kh(e){return t=>({path:"border",value:Ch(t,e)})}function Ch(e,t){return {[t]:gh(e)}}function xh(e,t){return i=>({path:"border",value:{[e]:{[t]:i}}})}function Ah(e){return (t,i)=>{if(i.border)return Eh(i.border,e)}}function Eh(e,t){const i={};return e.width&&e.width[t]&&(i.width=e.width[t]),e.style&&e.style[t]&&(i.style=e.style[t]),e.color&&e.color[t]&&(i.color=e.color[t]),i}function Th(e){const t={},i=wh(e);for(const e of i)nh(e)||/thin|medium|thick/.test(e)?t.width=e:th(e)?t.style=e:t.color=e;return t}function Ph(e){return t=>Sh(t,e)}function Sh(e,t){const i=[];if(e&&e.width&&i.push("width"),e&&e.style&&i.push("style"),e&&e.color&&i.push("color"),3==i.length){const n=i.map((t=>e[t])).join(" ");return ["all"==t?["border",n]:[`border-${t}`,n]]}return "all"==t?[]:i.map((i=>[`border-${t}-${i}`,e[i]]))}function Ih(e){e.setNormalizer("margin",bh("margin")),e.setNormalizer("margin-top",(e=>({path:"margin.top",value:e}))),e.setNormalizer("margin-right",(e=>({path:"margin.right",value:e}))),e.setNormalizer("margin-bottom",(e=>({path:"margin.bottom",value:e}))),e.setNormalizer("margin-left",(e=>({path:"margin.left",value:e}))),e.setReducer("margin",fh("margin")),e.setStyleRelation("margin",["margin-top","margin-right","margin-bottom","margin-left"]);}function Vh(e){e.setNormalizer("padding",bh("padding")),e.setNormalizer("padding-top",(e=>({path:"padding.top",value:e}))),e.setNormalizer("padding-right",(e=>({path:"padding.right",value:e}))),e.setNormalizer("padding-bottom",(e=>({path:"padding.bottom",value:e}))),e.setNormalizer("padding-left",(e=>({path:"padding.left",value:e}))),e.setReducer("padding",fh("padding")),e.setStyleRelation("padding",["padding-top","padding-right","padding-bottom","padding-left"]);}const Rh="[",Oh="]",Bh="{",Mh="}",Lh={container:pa,attribute:Ma,empty:Na,ui:za,raw:Ua},Fh={setContentOf:(e,t)=>{e.innerHTML=t;}};function Nh(e,t={}){if(!(e instanceof zl))throw new TypeError("View needs to be an instance of module:engine/view/view~View.");const i=e.document,n=!!t.withoutSelection,s=t.rootName||"main",o=i.getRoot(s),r={showType:t.showType,showPriority:t.showPriority,renderUIElements:t.renderUIElements,renderRawElements:t.renderRawElements,ignoreRoot:!0,domConverter:t.domConverter};return n?Nh._stringify(o,null,r):Nh._stringify(o,i.selection,r)}function Dh(e,t,i={}){if(!(e instanceof zl))throw new TypeError("View needs to be an instance of module:engine/view/view~View.");const n=e.document,s=i.rootName||"main",o=n.getRoot(s);e.change((e=>{const i=Dh._parse(t,{rootElement:o});i.view&&i.selection&&e.setSelection(i.selection);}));}function zh(e,t=null,i={}){let n;n=t instanceof ka||t instanceof Ca?new Ea(t):t;return new Uh(e,n,i).stringify()}function Hh(e,t={}){const i=new Ba(new ua);t.order=t.order||[];const n=new $h({sameSelectionCharacters:t.sameSelectionCharacters}),s=new Ad(i,{namespaces:Object.keys(Lh)});t.inlineObjectElements&&s.domConverter.inlineObjectElements.push(...t.inlineObjectElements);let o=s.toView(e);if(o=Wh(o),t.rootElement){const e=t.rootElement,i=o._removeChildren(0,o.childCount);e._removeChildren(0,e.childCount),e._appendChild(i),o=e;}const r=n.parse(o,t.order);if(o.is("documentFragment")&&1===o.childCount&&(o=o.getChild(0)),r.length){return {view:o,selection:new Ea(r,{backward:!!t.lastRangeBackward})}}return o.parent&&o._remove(),o}Nh._stringify=zh,Dh._parse=Hh;class $h{sameSelectionCharacters;_positions;constructor(e){this.sameSelectionCharacters=!!e.sameSelectionCharacters;}parse(e,t){this._positions=[],this._getPositions(e);let i=this._createRanges();if(t.length){if(t.length!=i.length)throw new Error(`Parse error - there are ${i.length} ranges found, but ranges order array contains ${t.length} elements.`);i=this._sortRanges(i,t);}return i}_getPositions(e){if(e.is("documentFragment")||e.is("element")){const t=[...e.getChildren()];for(const e of t)this._getPositions(e);}if(e.is("$text")){const t=new RegExp(`[${Bh}${Mh}\\${Oh}\\${Rh}]`,"g");let i,n=e.data,s=0;const o=[];for(;i=t.exec(n);){const e=i.index,t=i[0];o.push({bracket:t,textOffset:e-s}),s++;}n=n.replace(t,""),e._data=n;const r=e.index,a=e.parent;n||e._remove();for(const t of o)if(n)if(this.sameSelectionCharacters||!this.sameSelectionCharacters&&(t.bracket==Bh||t.bracket==Mh))this._positions.push({bracket:t.bracket,position:new ka(e,t.textOffset)});else {if(!this.sameSelectionCharacters&&0!==t.textOffset&&t.textOffset!==n.length)throw new Error(`Parse error - range delimiter '${t.bracket}' is placed inside text node.`);const e=0===t.textOffset?r:r+1;this._positions.push({bracket:t.bracket,position:new ka(a,e)});}else {if(!this.sameSelectionCharacters&&t.bracket==Bh||t.bracket==Mh)throw new Error(`Parse error - text range delimiter '${t.bracket}' is placed inside empty text node. `);this._positions.push({bracket:t.bracket,position:new ka(a,r)});}}}_sortRanges(e,t){const i=[];let n=0;for(const s of t){if(void 0===e[s-1])throw new Error("Parse error - provided ranges order is invalid.");i[s-1]=e[n],n++;}return i}_createRanges(){const e=[];let t=null;for(const i of this._positions){if(!t&&(i.bracket==Oh||i.bracket==Mh))throw new Error(`Parse error - end of range was found '${i.bracket}' but range was not started before.`);if(t&&(i.bracket==Rh||i.bracket==Bh))throw new Error(`Parse error - start of range was found '${i.bracket}' but one range is already started.`);i.bracket==Rh||i.bracket==Bh?t=new Ca(i.position,i.position):(t.end=i.position,e.push(t),t=null);}if(null!==t)throw new Error("Parse error - range was started but no end delimiter was found.");return e}}class Uh{root;selection;ranges;showType;showPriority;showAttributeElementId;ignoreRoot;sameSelectionCharacters;renderUIElements;renderRawElements;domConverter;constructor(e,t,i){this.root=e,this.selection=t,this.ranges=[],t&&(this.ranges=[...t.getRanges()]),this.showType=!!i.showType,this.showPriority=!!i.showPriority,this.showAttributeElementId=!!i.showAttributeElementId,this.ignoreRoot=!!i.ignoreRoot,this.sameSelectionCharacters=!!i.sameSelectionCharacters,this.renderUIElements=!!i.renderUIElements,this.renderRawElements=!!i.renderRawElements,this.domConverter=i.domConverter||Fh;}stringify(){let e="";return this._walkView(this.root,(t=>{e+=t;})),e}_walkView(e,t){const i=this.ignoreRoot&&this.root===e;if(e.is("element")||e.is("documentFragment")){if(e.is("element")&&!i&&t(this._stringifyElementOpen(e)),this.renderUIElements&&e.is("uiElement"))t(e.render(document,this.domConverter).innerHTML);else if(this.renderRawElements&&e.is("rawElement")){const i=document.createElement("div");e.render(i,this.domConverter),t(i.innerHTML);}else {let i=0;t(this._stringifyElementRanges(e,i));for(const n of e.getChildren())this._walkView(n,t),i++,t(this._stringifyElementRanges(e,i));}e.is("element")&&!i&&t(this._stringifyElementClose(e));}e.is("$text")&&t(this._stringifyTextRanges(e));}_stringifyElementRanges(e,t){let i="",n="",s="";for(const o of this.ranges)o.start.parent==e&&o.start.offset===t&&(o.isCollapsed?s+=Rh+Oh:i+=Rh),o.end.parent!==e||o.end.offset!==t||o.isCollapsed||(n+=Oh);return n+s+i}_stringifyTextRanges(e){const t=e.data.length,i=e.data.split("");let n,s;this.sameSelectionCharacters?(n=Rh,s=Oh):(n=Bh,s=Mh),i[t]="";const o=i.map((e=>({letter:e,start:"",end:"",collapsed:""})));for(const i of this.ranges){const r=i.start,a=i.end;r.parent==e&&r.offset>=0&&r.offset<=t&&(i.isCollapsed?o[a.offset].collapsed+=n+s:o[r.offset].start+=n),a.parent==e&&a.offset>=0&&a.offset<=t&&!i.isCollapsed&&(o[a.offset].end+=s);}return o.map((e=>e.end+e.collapsed+e.start+e.letter)).join("")}_stringifyElementOpen(e){const t=this._stringifyElementPriority(e),i=this._stringifyElementId(e);return `<${[[this._stringifyElementType(e),e.name].filter((e=>""!==e)).join(":"),t,i,this._stringifyElementAttributes(e)].filter((e=>""!==e)).join(" ")}>`}_stringifyElementClose(e){return `""!==e)).join(":")}>`}_stringifyElementType(e){if(this.showType)for(const t in Lh)if(e instanceof Lh[t])return t;return ""}_stringifyElementPriority(e){return this.showPriority&&e.is("attributeElement")?`view-priority="${e.priority}"`:""}_stringifyElementId(e){return this.showAttributeElementId&&e.is("attributeElement")&&e.id?`view-id="${e.id}"`:""}_stringifyElementAttributes(e){const t=[],i=[...e.getAttributeKeys()].sort();for(const n of i){let i;i="class"===n?[...e.getClassNames()].sort().join(" "):"style"===n?[...e.getStyleNames()].sort().map((t=>`${t}:${e.getStyle(t).replace(/"/g,""")}`)).join(";"):e.getAttribute(n),t.push(`${n}="${i}"`);}return t.join(" ")}}function Wh(e){if(e.is("element")||e.is("documentFragment")){const t=e.is("documentFragment")?new ja(e.document):function(e,t){const i=function(e){const t=e.name.split(":"),i=function(e){const t=parseInt(e,10);if(!isNaN(t))return t;return null}(e.getAttribute("view-priority")),n=e.hasAttribute("view-id")?e.getAttribute("view-id"):null;if(e._removeAttribute("view-priority"),e._removeAttribute("view-id"),1==t.length)return {name:t[0],type:null!==i?"attribute":null,priority:i,id:n};const s=function(e){return e in Lh?e:null}(t[0]);if(s)return {name:t[1],type:s,priority:i,id:n};throw new Error(`Parse error - cannot parse element's name: ${e.name}.`)}(t),n=Lh[i.type],s=n?new n(e,i.name):new ga(e,i.name);s.is("attributeElement")&&(null!==i.priority&&(s._priority=i.priority),null!==i.id&&(s._id=i.id));for(const e of t.getAttributeKeys())s._setAttribute(e,t.getAttribute(e));return s}(e.document,e);for(const i of [...e.getChildren()]){if(t.is("emptyElement"))throw new Error("Parse error - cannot parse inside EmptyElement.");if(t.is("uiElement"))throw new Error("Parse error - cannot parse inside UIElement.");if(t.is("rawElement"))throw new Error("Parse error - cannot parse inside RawElement.");t._appendChild(Wh(i));}return t}return e}function jh(e,t={}){if(!(e instanceof Hu))throw new TypeError("Model needs to be an instance of module:engine/model/model~Model.");const i=t.rootName||"main",n=e.document.getRoot(i);return jh._stringify(n,t.withoutSelection?null:e.document.selection,t.convertMarkers?e.markers:null)}function qh(e,t,i={}){if(!(e instanceof Hu))throw new TypeError("Model needs to be an instance of module:engine/model/model~Model.");let n,s=null;const o=e.document.getRoot(i.rootName||"main"),r=qh._parse(t,e.schema,{lastRangeBackward:i.lastRangeBackward,selectionAttributes:i.selectionAttributes,context:[o.name],inlineObjectElements:i.inlineObjectElements});function a(t){if(t.remove(t.createRangeIn(o)),t.insert(n,o),t.setSelection(null),t.removeSelectionAttribute(e.document.selection.getAttributeKeys()),s){const e=[];for(const t of s.getRanges()){const i=new Zl(o,t.start.path),n=new Zl(o,t.end.path);e.push(new tc(i,n));}t.setSelection(e,{backward:s.isBackward}),i.selectionAttributes&&t.setSelectionAttribute(s.getAttributes());}}"model"in r?(n=r.model,s=r.selection):n=r,void 0!==i.batchType?e.enqueueChange(i.batchType,a):e.change(a);}function Gh(e,t=null,i=null){const n=new Hu,s=new ic;let o,r=null;if(e instanceof gu||e instanceof yu)o=n.createRangeIn(e);else if(e.parent)o=new tc(n.createPositionBefore(e),n.createPositionAfter(e));else {const t=new yu(e);o=n.createRangeIn(t);}t instanceof lc||t instanceof _c?r=t:(t instanceof tc||t instanceof Zl)&&(r=new lc(t));const a=new ua,l=new zl(a),c=l.document,d=new va(c,"div");d.rootName="main",c.roots.add(d);const u=new oc({mapper:s,schema:n.schema});s.bindElements(e.root,d),u.on("insert:$text",((e,t,i)=>{if(!i.consumable.consume(t.item,e.name))return;const n=i.writer,s=i.mapper.toViewPosition(t.range.start),o=n.createText(t.item.data);n.insert(s,o);})),u.on("insert",((e,t,i)=>{i.convertAttributes(t.item),t.reconversion||!t.item.is("element")||t.item.isEmpty||i.convertChildren(t.item);}),{priority:"lowest"}),u.on("attribute",((e,t,i)=>{if(t.item instanceof lc||t.item instanceof _c||t.item.is("$textProxy")){const n=Ac(((e,{writer:i})=>i.createAttributeElement("model-text-with-attributes",{[t.attributeKey]:Qh(e)})));n(e,t,i);}})),u.on("insert",Ec((e=>{const t=Yh(e.getAttributes(),Qh);return new pa(c,e.name,t)}))),u.on("selection",((e,t,i)=>{const n=t.selection;if(n.isCollapsed)return;if(!i.consumable.consume(n,"selection"))return;const s=[];for(const e of n.getRanges())s.push(i.mapper.toViewRange(e));i.writer.setSelection(s,{backward:n.isBackward});})),u.on("selection",((e,t,i)=>{const n=t.selection;if(!n.isCollapsed)return;if(!i.consumable.consume(n,"selection"))return;const s=i.writer,o=n.getFirstPosition(),r=i.mapper.toViewPosition(o),a=s.breakAttributes(r);s.setSelection(a);})),u.on("addMarker",Tc(((e,{writer:t})=>{const i=e.markerName+":"+(e.isOpening?"start":"end");return t.createUIElement(i)})));const h=new Map;if(i)for(const e of Array.from(i).sort(((e,t)=>e.name{const s=n.convertChildren(i.viewItem,i.modelCursor);e.bindElements(i.modelCursor.parent,i.viewItem),i=Object.assign(i,s),t.stop();}}(n)),c.on("element:model-text-with-attributes",Zh()),c.on("element",function(e){return (t,i,n)=>{const s=i.viewItem.name;if(!n.schema.checkChild(i.modelCursor,s))throw new Error(`Element '${s}' was not allowed in given position.`);const o=Yh(i.viewItem.getAttributes(),Jh),r=n.writer.createElement(i.viewItem.name,o);n.writer.insert(r,i.modelCursor),e.bindElements(r,i.viewItem),n.convertChildren(i.viewItem,r),i.modelRange=tc._createOn(r),i.modelCursor=i.modelRange.end,t.stop();}}(n)),c.on("text",Zh());let d=l.change((e=>c.convert(o.root,e,i.context||"$root")));if(n.bindElements(d,o.root),1==d.childCount&&(d=d.getChild(0)),r){const e=[];for(const t of r.getRanges())e.push(n.toModelRange(t));a=new lc(e,{backward:r.isBackward});for(const[e,t]of xr(i.selectionAttributes||[]))a.setAttribute(e,t);}return a?{model:d,selection:a}:d}function Zh(){return (e,t,i)=>{if(!i.schema.checkChild(t.modelCursor,"$text"))throw new Error("Text was not allowed in given position.");let n;if(t.viewItem.is("element")){const e=Yh(t.viewItem.getAttributes(),Jh),s=t.viewItem.getChild(0);n=i.writer.createText(s.data,e);}else n=i.writer.createText(t.viewItem.data);i.writer.insert(n,t.modelCursor),t.modelRange=tc._createFromPositionAndShift(t.modelCursor,n.offsetSize),t.modelCursor=t.modelRange.end,e.stop();}}function Jh(e){try{return JSON.parse(e)}catch(t){return e}}function Qh(e){return ei(e)?JSON.stringify(e):e}function*Yh(e,t){for(const[i,n]of e)yield [i,t(n)];}jh._stringify=Gh,qh._parse=Kh;class Xh{crashes=[];state="initializing";_crashNumberLimit;_now=Date.now;_minimumNonErrorTimePeriod;_boundErrorHandler;_listeners;constructor(e){if(this.crashes=[],this._crashNumberLimit="number"==typeof e.crashNumberLimit?e.crashNumberLimit:3,this._minimumNonErrorTimePeriod="number"==typeof e.minimumNonErrorTimePeriod?e.minimumNonErrorTimePeriod:5e3,this._boundErrorHandler=e=>{const t="error"in e?e.error:e.reason;t instanceof Error&&this._handleError(t,e);},this._listeners={},!this._restart)throw new Error("The Watchdog class was split into the abstract `Watchdog` class and the `EditorWatchdog` class. Please, use `EditorWatchdog` if you have used the `Watchdog` class previously.")}destroy(){this._stopErrorHandling(),this._listeners={};}on(e,t){this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push(t);}off(e,t){this._listeners[e]=this._listeners[e].filter((e=>e!==t));}_fire(e,...t){const i=this._listeners[e]||[];for(const e of i)e.apply(this,[null,...t]);}_startErrorHandling(){window.addEventListener("error",this._boundErrorHandler),window.addEventListener("unhandledrejection",this._boundErrorHandler);}_stopErrorHandling(){window.removeEventListener("error",this._boundErrorHandler),window.removeEventListener("unhandledrejection",this._boundErrorHandler);}_handleError(e,t){if(this._shouldReactToError(e)){this.crashes.push({message:e.message,stack:e.stack,filename:t instanceof ErrorEvent?t.filename:void 0,lineno:t instanceof ErrorEvent?t.lineno:void 0,colno:t instanceof ErrorEvent?t.colno:void 0,date:this._now()});const i=this._shouldRestart();this.state="crashed",this._fire("stateChange"),this._fire("error",{error:e,causesRestart:i}),i?this._restart():(this.state="crashedPermanently",this._fire("stateChange"));}}_shouldReactToError(e){return e.is&&e.is("CKEditorError")&&void 0!==e.context&&null!==e.context&&"ready"===this.state&&this._isErrorComingFromThisItem(e)}_shouldRestart(){if(this.crashes.length<=this._crashNumberLimit)return !0;return (this.crashes[this.crashes.length-1].date-this.crashes[this.crashes.length-1-this._crashNumberLimit].date)/this._crashNumberLimit>this._minimumNonErrorTimePeriod}}function em(e,t=new Set){const i=[e],n=new Set;let s=0;for(;i.length>s;){const e=i[s++];if(!n.has(e)&&tm(e)&&!t.has(e))if(n.add(e),Symbol.iterator in e)try{for(const t of e)i.push(t);}catch(e){}else for(const t in e)"defaultValue"!==t&&i.push(e[t]);}return n}function tm(e){const t=Object.prototype.toString.call(e),i=typeof e;return !("number"===i||"boolean"===i||"string"===i||"symbol"===i||"function"===i||"[object Date]"===t||"[object RegExp]"===t||"[object Module]"===t||null==e||e._watchdogExcluded||e instanceof EventTarget||e instanceof Event)}function im(e,t,i=new Set){if(e===t&&("object"==typeof(n=e)&&null!==n))return !0;var n;const s=em(e,i),o=em(t,i);for(const e of s)if(o.has(e))return !0;return !1}class nm extends Xh{_editor=null;_lifecyclePromise=null;_throttledSave;_data;_lastDocumentVersion;_elementOrData;_initUsingData=!0;_editables={};_config;_excludedProps;constructor(e,t={}){super(t),this._throttledSave=$s(this._save.bind(this),"number"==typeof t.saveInterval?t.saveInterval:5e3),e&&(this._creator=(t,i)=>e.create(t,i)),this._destructor=e=>e.destroy();}get editor(){return this._editor}get _item(){return this._editor}setCreator(e){this._creator=e;}setDestructor(e){this._destructor=e;}_restart(){return Promise.resolve().then((()=>(this.state="initializing",this._fire("stateChange"),this._destroy()))).catch((e=>{console.error("An error happened during the editor destroying.",e);})).then((()=>{const e={},t=[],i=this._config.rootsAttributes||{},n={};for(const[s,o]of Object.entries(this._data.roots))o.isLoaded?(e[s]="",n[s]=i[s]||{}):t.push(s);const s={...this._config,extraPlugins:this._config.extraPlugins||[],lazyRoots:t,rootsAttributes:n,_watchdogInitialData:this._data};return delete s.initialData,s.extraPlugins.push(sm),this._initUsingData?this.create(e,s,s.context):Ms(this._elementOrData)?this.create(this._elementOrData,s,s.context):this.create(this._editables,s,s.context)})).then((()=>{this._fire("restart");}))}create(e=this._elementOrData,t=this._config,i){return this._lifecyclePromise=Promise.resolve(this._lifecyclePromise).then((()=>(super._startErrorHandling(),this._elementOrData=e,this._initUsingData="string"==typeof e||Object.keys(e).length>0&&"string"==typeof Object.values(e)[0],this._config=this._cloneEditorConfiguration(t)||{},this._config.context=i,this._creator(e,this._config)))).then((e=>{this._editor=e,e.model.document.on("change:data",this._throttledSave),this._lastDocumentVersion=e.model.document.version,this._data=this._getData(),this._initUsingData||(this._editables=this._getEditables()),this.state="ready",this._fire("stateChange");})).finally((()=>{this._lifecyclePromise=null;})),this._lifecyclePromise}destroy(){return this._lifecyclePromise=Promise.resolve(this._lifecyclePromise).then((()=>(this.state="destroyed",this._fire("stateChange"),super.destroy(),this._destroy()))).finally((()=>{this._lifecyclePromise=null;})),this._lifecyclePromise}_destroy(){return Promise.resolve().then((()=>{this._stopErrorHandling(),this._throttledSave.cancel();const e=this._editor;return this._editor=null,e.model.document.off("change:data",this._throttledSave),this._destructor(e)}))}_save(){const e=this._editor.model.document.version;try{this._data=this._getData(),this._initUsingData||(this._editables=this._getEditables()),this._lastDocumentVersion=e;}catch(e){console.error(e,"An error happened during restoring editor data. Editor will be restored from the previously saved data.");}}_setExcludedProperties(e){this._excludedProps=e;}_getData(){const e=this._editor,t=e.model.document.roots.filter((e=>e.isAttached()&&"$graveyard"!=e.rootName)),{plugins:i}=e,n=i.has("CommentsRepository")&&i.get("CommentsRepository"),s=i.has("TrackChanges")&&i.get("TrackChanges"),o={roots:{},markers:{},commentThreads:JSON.stringify([]),suggestions:JSON.stringify([])};t.forEach((e=>{o.roots[e.rootName]={content:JSON.stringify(Array.from(e.getChildren())),attributes:JSON.stringify(Array.from(e.getAttributes())),isLoaded:e._isLoaded};}));for(const t of e.model.markers)t._affectsData&&(o.markers[t.name]={rangeJSON:t.getRange().toJSON(),usingOperation:t._managedUsingOperations,affectsData:t._affectsData});return n&&(o.commentThreads=JSON.stringify(n.getCommentThreads({toJSON:!0,skipNotAttached:!0}))),s&&(o.suggestions=JSON.stringify(s.getSuggestions({toJSON:!0,skipNotAttached:!0}))),o}_getEditables(){const e={};for(const t of this.editor.model.document.getRootNames()){const i=this.editor.ui.getEditableElement(t);i&&(e[t]=i);}return e}_isErrorComingFromThisItem(e){return im(this._editor,e.context,this._excludedProps)}_cloneEditorConfiguration(e){return Wn(e,((e,t)=>Ms(e)||"context"===t?e:void 0))}}class sm{editor;_data;constructor(e){this.editor=e,this._data=e.config.get("_watchdogInitialData");}init(){this.editor.data.on("init",(e=>{e.stop(),this.editor.model.enqueueChange({isUndoable:!1},(e=>{this._restoreCollaborationData(),this._restoreEditorData(e);})),this.editor.data.fire("ready");}),{priority:999});}_createNode(e,t){if("name"in t){const i=e.createElement(t.name,t.attributes);if(t.children)for(const n of t.children)i._appendChild(this._createNode(e,n));return i}return e.createText(t.data,t.attributes)}_restoreEditorData(e){const t=this.editor;Object.entries(this._data.roots).forEach((([i,{content:n,attributes:s}])=>{const o=JSON.parse(n),r=JSON.parse(s),a=t.model.document.getRoot(i);for(const[t,i]of r)e.setAttribute(t,i,a);for(const t of o){const i=this._createNode(e,t);e.insert(i,a,"end");}})),Object.entries(this._data.markers).forEach((([i,n])=>{const{document:s}=t.model,{rangeJSON:{start:o,end:r},...a}=n,l=s.getRoot(o.root),c=e.createPositionFromPath(l,o.path,o.stickiness),d=e.createPositionFromPath(l,r.path,r.stickiness),u=e.createRange(c,d);e.addMarker(i,{range:u,...a});}));}_restoreCollaborationData(){const e=JSON.parse(this._data.commentThreads),t=JSON.parse(this._data.suggestions);e.forEach((e=>{const t=this.editor.config.get("collaboration.channelId"),i=this.editor.plugins.get("CommentsRepository");if(i.hasCommentThread(e.threadId)){i.getCommentThread(e.threadId).remove();}i.addCommentThread({channelId:t,...e});})),t.forEach((e=>{const t=this.editor.plugins.get("TrackChangesEditing");if(t.hasSuggestion(e.id)){t.getSuggestion(e.id).attributes=e.attributes;}else t.addSuggestionData(e);}));}}const om=Symbol("MainQueueId");class rm extends Xh{_watchdogs=new Map;_watchdogConfig;_context=null;_contextProps=new Set;_actionQueues=new am;_contextConfig;_item;constructor(e,t={}){super(t),this._watchdogConfig=t,this._creator=t=>e.create(t),this._destructor=e=>e.destroy(),this._actionQueues.onEmpty((()=>{"initializing"===this.state&&(this.state="ready",this._fire("stateChange"));}));}setCreator(e){this._creator=e;}setDestructor(e){this._destructor=e;}get context(){return this._context}create(e={}){return this._actionQueues.enqueue(om,(()=>(this._contextConfig=e,this._create())))}getItem(e){return this._getWatchdog(e)._item}getItemState(e){return this._getWatchdog(e).state}add(e){const t=lm(e);return Promise.all(t.map((e=>this._actionQueues.enqueue(e.id,(()=>{if("destroyed"===this.state)throw new Error("Cannot add items to destroyed watchdog.");if(!this._context)throw new Error("Context was not created yet. You should call the `ContextWatchdog#create()` method first.");let t;if(this._watchdogs.has(e.id))throw new Error(`Item with the given id is already added: '${e.id}'.`);if("editor"===e.type)return t=new nm(null,this._watchdogConfig),t.setCreator(e.creator),t._setExcludedProperties(this._contextProps),e.destructor&&t.setDestructor(e.destructor),this._watchdogs.set(e.id,t),t.on("error",((i,{error:n,causesRestart:s})=>{this._fire("itemError",{itemId:e.id,error:n}),s&&this._actionQueues.enqueue(e.id,(()=>new Promise((i=>{const n=()=>{t.off("restart",n),this._fire("itemRestart",{itemId:e.id}),i();};t.on("restart",n);}))));})),t.create(e.sourceElementOrData,e.config,this._context);throw new Error(`Not supported item type: '${e.type}'.`)})))))}remove(e){const t=lm(e);return Promise.all(t.map((e=>this._actionQueues.enqueue(e,(()=>{const t=this._getWatchdog(e);return this._watchdogs.delete(e),t.destroy()})))))}destroy(){return this._actionQueues.enqueue(om,(()=>(this.state="destroyed",this._fire("stateChange"),super.destroy(),this._destroy())))}_restart(){return this._actionQueues.enqueue(om,(()=>(this.state="initializing",this._fire("stateChange"),this._destroy().catch((e=>{console.error("An error happened during destroying the context or items.",e);})).then((()=>this._create())).then((()=>this._fire("restart"))))))}_create(){return Promise.resolve().then((()=>(this._startErrorHandling(),this._creator(this._contextConfig)))).then((e=>(this._context=e,this._contextProps=em(this._context),Promise.all(Array.from(this._watchdogs.values()).map((e=>(e._setExcludedProperties(this._contextProps),e.create(void 0,void 0,this._context))))))))}_destroy(){return Promise.resolve().then((()=>{this._stopErrorHandling();const e=this._context;return this._context=null,this._contextProps=new Set,Promise.all(Array.from(this._watchdogs.values()).map((e=>e.destroy()))).then((()=>this._destructor(e)))}))}_getWatchdog(e){const t=this._watchdogs.get(e);if(!t)throw new Error(`Item with the given id was not registered: ${e}.`);return t}_isErrorComingFromThisItem(e){for(const t of this._watchdogs.values())if(t._isErrorComingFromThisItem(e))return !1;return im(this._context,e.context)}}class am{_onEmptyCallbacks=[];_queues=new Map;_activeActions=0;onEmpty(e){this._onEmptyCallbacks.push(e);}enqueue(e,t){const i=e===om;this._activeActions++,this._queues.get(e)||this._queues.set(e,Promise.resolve());const n=(i?Promise.all(this._queues.values()):Promise.all([this._queues.get(om),this._queues.get(e)])).then(t),s=n.catch((()=>{}));return this._queues.set(e,s),n.finally((()=>{this._activeActions--,this._queues.get(e)===s&&0===this._activeActions&&this._onEmptyCallbacks.forEach((e=>e()));}))}}function lm(e){return Array.isArray(e)?e:[e]}class cm{_commands;constructor(){this._commands=new Map;}add(e,t){this._commands.set(e,t);}get(e){return this._commands.get(e)}execute(e,...t){const i=this.get(e);if(!i)throw new A("commandcollection-command-not-found",this,{commandName:e});return i.execute(...t)}*names(){yield*this._commands.keys();}*commands(){yield*this._commands.values();}[Symbol.iterator](){return this._commands[Symbol.iterator]()}destroy(){for(const e of this.commands())e.destroy();}}class dm extends Cr{editor;constructor(e){super(),this.editor=e;}set(e,t,i={}){if("string"==typeof t){const e=t;t=(t,i)=>{this.editor.execute(e),i();};}super.set(e,t,i);}}const um="contentEditing",hm="common";class mm{keystrokeInfos=new Map;_editor;constructor(e){this._editor=e;const t=e.config.get("menuBar.isVisible"),i=e.locale.t;this.addKeystrokeInfoCategory({id:um,label:i("Content editing keystrokes"),description:i("These keyboard shortcuts allow for quick access to content editing features.")});const n=[{label:i("Close contextual balloons, dropdowns, and dialogs"),keystroke:"Esc"},{label:i("Open the accessibility help dialog"),keystroke:"Alt+0"},{label:i("Move focus between form fields (inputs, buttons, etc.)"),keystroke:[["Tab"],["Shift+Tab"]]},{label:i("Move focus to the toolbar, navigate between toolbars"),keystroke:"Alt+F10",mayRequireFn:!0},{label:i("Navigate through the toolbar or menu bar"),keystroke:[["arrowup"],["arrowright"],["arrowdown"],["arrowleft"]]},{label:i("Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content."),keystroke:[["Enter"],["Space"]]}];t&&n.push({label:i("Move focus to the menu bar, navigate between menu bars"),keystroke:"Alt+F9",mayRequireFn:!0}),this.addKeystrokeInfoCategory({id:"navigation",label:i("User interface and content navigation keystrokes"),description:i("Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface."),groups:[{id:"common",keystrokes:n}]});}addKeystrokeInfoCategory({id:e,label:t,description:i,groups:n}){this.keystrokeInfos.set(e,{id:e,label:t,description:i,groups:new Map}),this.addKeystrokeInfoGroup({categoryId:e,id:hm}),n&&n.forEach((t=>{this.addKeystrokeInfoGroup({categoryId:e,...t});}));}addKeystrokeInfoGroup({categoryId:e=um,id:t,label:i,keystrokes:n}){const s=this.keystrokeInfos.get(e);if(!s)throw new A("accessibility-unknown-keystroke-info-category",this._editor,{groupId:t,categoryId:e});s.groups.set(t,{id:t,label:i,keystrokes:n||[]});}addKeystrokeInfos({categoryId:e=um,groupId:t=hm,keystrokes:i}){if(!this.keystrokeInfos.has(e))throw new A("accessibility-unknown-keystroke-info-category",this._editor,{categoryId:e,keystrokes:i});const n=this.keystrokeInfos.get(e);if(!n.groups.has(t))throw new A("accessibility-unknown-keystroke-info-group",this._editor,{groupId:t,categoryId:e,keystrokes:i});n.groups.get(t).keystrokes.push(...i);}}class gm extends(Zs()){accessibility;commands;config;conversion;data;editing;locale;model;plugins;keystrokes;t;static defaultConfig;static builtinPlugins;_context;_readOnlyLocks;constructor(e={}){if(super(),"sanitizeHtml"in e)throw new A("editor-config-sanitizehtml-not-supported");const t=this.constructor,{translations:i,...n}=t.defaultConfig||{},{translations:s=i,...o}=e,r=e.language||n.language;this._context=e.context||new jr({language:r,translations:s}),this._context._addEditor(this,!e.context);const a=Array.from(t.builtinPlugins||[]);this.config=new ao(o,n),this.config.define("plugins",a),this.config.define(this._context._getEditorConfig()),this.plugins=new Wr(this,a,this._context.plugins),this.locale=this._context.locale,this.t=this.locale.t,this._readOnlyLocks=new Set,this.commands=new cm,this.set("state","initializing"),this.once("ready",(()=>this.state="ready"),{priority:"high"}),this.once("destroy",(()=>this.state="destroyed"),{priority:"high"}),this.model=new Hu,this.on("change:isReadOnly",(()=>{this.model.document.isReadOnly=this.isReadOnly;}));const l=new ua;this.data=new yd(this.model,l),this.editing=new Xc(this.model,l),this.editing.view.document.bind("isReadOnly").to(this),this.conversion=new kd([this.editing.downcastDispatcher,this.data.downcastDispatcher],this.data.upcastDispatcher),this.conversion.addAlias("dataDowncast",this.data.downcastDispatcher),this.conversion.addAlias("editingDowncast",this.editing.downcastDispatcher),this.keystrokes=new dm(this),this.keystrokes.listenTo(this.editing.view.document),this.accessibility=new mm(this);}get isReadOnly(){return this._readOnlyLocks.size>0}set isReadOnly(e){throw new A("editor-isreadonly-has-no-setter")}enableReadOnlyMode(e){if("string"!=typeof e&&"symbol"!=typeof e)throw new A("editor-read-only-lock-id-invalid",null,{lockId:e});this._readOnlyLocks.has(e)||(this._readOnlyLocks.add(e),1===this._readOnlyLocks.size&&this.fire("change:isReadOnly","isReadOnly",!0,!1));}disableReadOnlyMode(e){if("string"!=typeof e&&"symbol"!=typeof e)throw new A("editor-read-only-lock-id-invalid",null,{lockId:e});this._readOnlyLocks.has(e)&&(this._readOnlyLocks.delete(e),0===this._readOnlyLocks.size&&this.fire("change:isReadOnly","isReadOnly",!1,!0));}setData(e){this.data.set(e);}getData(e){return this.data.get(e)}initPlugins(){const e=this.config,t=e.get("plugins"),i=e.get("removePlugins")||[],n=e.get("extraPlugins")||[],s=e.get("substitutePlugins")||[];return this.plugins.init(t.concat(n),i,s)}destroy(){let e=Promise.resolve();return "initializing"==this.state&&(e=new Promise((e=>this.once("ready",e)))),e.then((()=>{this.fire("destroy"),this.stopListening(),this.commands.destroy();})).then((()=>this.plugins.destroy())).then((()=>{this.model.destroy(),this.data.destroy(),this.editing.destroy(),this.keystrokes.destroy();})).then((()=>this._context._removeEditor(this)))}execute(e,...t){try{return this.commands.execute(e,...t)}catch(e){A.rethrowUnexpectedError(e,this);}}focus(){this.editing.view.focus();}static create(...e){throw new Error("This is an abstract method.")}static Context=jr;static EditorWatchdog=nm;static ContextWatchdog=rm}function fm(e){if(!we(e.updateSourceElement))throw new A("attachtoform-missing-elementapi-interface",e);const t=e.sourceElement;if(function(e){return !!e&&"textarea"===e.tagName.toLowerCase()}(t)&&t.form){let i;const n=t.form,s=()=>e.updateSourceElement();we(n.submit)&&(i=n.submit,n.submit=()=>{s(),i.apply(n);}),n.addEventListener("submit",s),e.on("destroy",(()=>{n.removeEventListener("submit",s),i&&(n.submit=i);}));}}function pm(e){return e}function bm(e){return class extends e{sourceElement;updateSourceElement(e){if(!this.sourceElement)throw new A("editor-missing-sourceelement",this);const t=this.config.get("updateSourceElementOnDestroy"),i=this.sourceElement instanceof HTMLTextAreaElement;if(!t&&!i)return void Ro(this.sourceElement,"");const n="string"==typeof e?e:this.data.get();Ro(this.sourceElement,n);}}}function wm(e,t){if(t.ckeditorInstance)throw new A("editor-source-element-already-used",e);t.ckeditorInstance=e,e.once("destroy",(()=>{delete t.ckeditorInstance;}));}bm.updateSourceElement=bm(Object).prototype.updateSourceElement;class _m extends qr{_actions;static get pluginName(){return "PendingActions"}static get isOfficialPlugin(){return !0}init(){this.set("hasAny",!1),this._actions=new br({idProperty:"_id"}),this._actions.delegate("add","remove").to(this);}add(e){if("string"!=typeof e)throw new A("pendingactions-add-invalid-message",this);const t=new(Zs());return t.set("message",e),this._actions.add(t),this.hasAny=!0,t}remove(e){this._actions.remove(e),this.hasAny=!!this._actions.length;}get first(){return this._actions.get(0)}[Symbol.iterator](){return this._actions[Symbol.iterator]()}}const vm={bold:'',cancel:'',caption:'',check:'',cog:'',colorPalette:'',eraser:'',history:'',image:'',imageUpload:'',imageAssetManager:'',imageUrl:'',lowVision:'',textAlternative:'',loupe:'',previousArrow:'',nextArrow:'',importExport:'',paragraph:'',plus:'',text:'',alignBottom:'',alignMiddle:'',alignTop:'',alignLeft:'',alignCenter:'',alignRight:'',alignJustify:'',objectLeft:'',objectCenter:'',objectRight:'',objectFullWidth:'',objectInline:'',objectBlockLeft:'',objectBlockRight:'',objectSizeCustom:'',objectSizeFull:'',objectSizeLarge:'',objectSizeSmall:'',objectSizeMedium:'',pencil:'',pilcrow:'',quote:'',threeVerticalDots:'',dragIndicator:'',redo:'',undo:'',bulletedList:'',numberedList:'',todoList:'',codeBlock:'',browseFiles:'',heading1:'',heading2:'',heading3:'',heading4:'',heading5:'',heading6:'',horizontalLine:'',html:'',indent:'',outdent:'',table:''};class ym extends(Zs()){total;_reader;_data;constructor(){super();const e=new window.FileReader;this._reader=e,this._data=void 0,this.set("loaded",0),e.onprogress=e=>{this.loaded=e.loaded;};}get error(){return this._reader.error}get data(){return this._data}read(e){const t=this._reader;return this.total=e.size,new Promise(((i,n)=>{t.onload=()=>{const e=t.result;this._data=e,i(e);},t.onerror=()=>{n("error");},t.onabort=()=>{n("aborted");},this._reader.readAsDataURL(e);}))}abort(){this._reader.abort();}}class km extends Dr{loaders=new br;_loadersMap=new Map;_pendingAction=null;static get pluginName(){return "FileRepository"}static get isOfficialPlugin(){return !0}static get requires(){return [_m]}init(){this.loaders.on("change",(()=>this._updatePendingAction())),this.set("uploaded",0),this.set("uploadTotal",null),this.bind("uploadedPercent").to(this,"uploaded",this,"uploadTotal",((e,t)=>t?e/t*100:0));}getLoader(e){return this._loadersMap.get(e)||null}createLoader(e){if(!this.createUploadAdapter)return E("filerepository-no-upload-adapter"),null;const t=new Cm(Promise.resolve(e),this.createUploadAdapter);return this.loaders.add(t),this._loadersMap.set(e,t),e instanceof Promise&&t.file.then((e=>{this._loadersMap.set(e,t);})).catch((()=>{})),t.on("change:uploaded",(()=>{let e=0;for(const t of this.loaders)e+=t.uploaded;this.uploaded=e;})),t.on("change:uploadTotal",(()=>{let e=0;for(const t of this.loaders)t.uploadTotal&&(e+=t.uploadTotal);this.uploadTotal=e;})),t}destroyLoader(e){const t=e instanceof Cm?e:this.getLoader(e);t._destroy(),this.loaders.remove(t),this._loadersMap.forEach(((e,i)=>{e===t&&this._loadersMap.delete(i);}));}_updatePendingAction(){const e=this.editor.plugins.get(_m);if(this.loaders.length){if(!this._pendingAction){const t=this.editor.t,i=e=>`${t("Upload in progress")} ${parseInt(e)}%.`;this._pendingAction=e.add(i(this.uploadedPercent)),this._pendingAction.bind("message").to(this,"uploadedPercent",i);}}else e.remove(this._pendingAction),this._pendingAction=null;}}class Cm extends(Zs()){id;_filePromiseWrapper;_adapter;_reader;constructor(e,t){super(),this.id=k(),this._filePromiseWrapper=this._createFilePromiseWrapper(e),this._adapter=t(this),this._reader=new ym,this.set("status","idle"),this.set("uploaded",0),this.set("uploadTotal",null),this.bind("uploadedPercent").to(this,"uploaded",this,"uploadTotal",((e,t)=>t?e/t*100:0)),this.set("uploadResponse",null);}get file(){return this._filePromiseWrapper?this._filePromiseWrapper.promise.then((e=>this._filePromiseWrapper?e:null)):Promise.resolve(null)}get data(){return this._reader.data}read(){if("idle"!=this.status)throw new A("filerepository-read-wrong-status",this);return this.status="reading",this.file.then((e=>this._reader.read(e))).then((e=>{if("reading"!==this.status)throw this.status;return this.status="idle",e})).catch((e=>{if("aborted"===e)throw this.status="aborted","aborted";throw this.status="error",this._reader.error?this._reader.error:e}))}upload(){if("idle"!=this.status)throw new A("filerepository-upload-wrong-status",this);return this.status="uploading",this.file.then((()=>this._adapter.upload())).then((e=>(this.uploadResponse=e,this.status="idle",e))).catch((e=>{if("aborted"===this.status)throw "aborted";throw this.status="error",e}))}abort(){const e=this.status;this.status="aborted",this._filePromiseWrapper.isFulfilled?"reading"==e?this._reader.abort():"uploading"==e&&this._adapter.abort&&this._adapter.abort():(this._filePromiseWrapper.promise.catch((()=>{})),this._filePromiseWrapper.rejecter("aborted")),this._destroy();}_destroy(){this._filePromiseWrapper=void 0,this._reader=void 0,this._adapter=void 0,this.uploadResponse=void 0;}_createFilePromiseWrapper(e){const t={};return t.promise=new Promise(((i,n)=>{t.rejecter=n,t.isFulfilled=!1,e.then((e=>{t.isFulfilled=!0,i(e);})).catch((e=>{t.isFulfilled=!0,n(e);}));})),t}}class xm extends Dr{static get requires(){return [km]}static get pluginName(){return "Base64UploadAdapter"}static get isOfficialPlugin(){return !0}init(){this.editor.plugins.get(km).createUploadAdapter=e=>new Am(e);}}let Am=class{loader;reader;constructor(e){this.loader=e;}upload(){return new Promise(((e,t)=>{const i=this.reader=new window.FileReader;i.addEventListener("load",(()=>{e({default:i.result});})),i.addEventListener("error",(e=>{t(e);})),i.addEventListener("abort",(()=>{t();})),this.loader.file.then((e=>{i.readAsDataURL(e);}));}))}abort(){this.reader.abort();}};class Em extends Dr{static get requires(){return [km]}static get pluginName(){return "SimpleUploadAdapter"}static get isOfficialPlugin(){return !0}init(){const e=this.editor.config.get("simpleUpload");e&&(e.uploadUrl?this.editor.plugins.get(km).createUploadAdapter=t=>new Tm(t,e):E("simple-upload-adapter-missing-uploadurl"));}}let Tm=class{loader;options;xhr;constructor(e,t){this.loader=e,this.options=t;}upload(){return this.loader.file.then((e=>new Promise(((t,i)=>{this._initRequest(),this._initListeners(t,i,e),this._sendRequest(e);}))))}abort(){this.xhr&&this.xhr.abort();}_initRequest(){const e=this.xhr=new XMLHttpRequest;e.open("POST",this.options.uploadUrl,!0),e.responseType="json";}_initListeners(e,t,i){const n=this.xhr,s=this.loader,o=`Couldn't upload file: ${i.name}.`;n.addEventListener("error",(()=>t(o))),n.addEventListener("abort",(()=>t())),n.addEventListener("load",(()=>{const i=n.response;if(!i||i.error)return t(i&&i.error&&i.error.message?i.error.message:o);const s=i.url?{default:i.url}:i.urls;e({...i,urls:s});})),n.upload&&n.upload.addEventListener("progress",(e=>{e.lengthComputable&&(s.uploadTotal=e.total,s.uploaded=e.loaded);}));}_sendRequest(e){const t=this.options.headers||{},i=this.options.withCredentials||!1;for(const e of Object.keys(t))this.xhr.setRequestHeader(e,t[e]);this.xhr.withCredentials=i;const n=new FormData;n.append("upload",e),this.xhr.send(n);}};const Pm="ckCsrfToken",Sm="abcdefghijklmnopqrstuvwxyz0123456789";function Im(){let e=function(e){e=e.toLowerCase();const t=document.cookie.split(";");for(const i of t){const t=i.split("=");if(decodeURIComponent(t[0].trim().toLowerCase())===e)return decodeURIComponent(t[1])}return null}(Pm);var t,i;return e&&40==e.length||(e=function(e){let t="";const i=new Uint8Array(e);window.crypto.getRandomValues(i);for(let e=0;e.5?n.toUpperCase():n;}return t}(40),t=Pm,i=e,document.cookie=encodeURIComponent(t)+"="+encodeURIComponent(i)+";path=/"),e}class Vm extends Dr{static get requires(){return [km]}static get pluginName(){return "CKFinderUploadAdapter"}static get isOfficialPlugin(){return !0}init(){const e=this.editor.config.get("ckfinder.uploadUrl");e&&(this.editor.plugins.get(km).createUploadAdapter=t=>new Rm(t,e,this.editor.t));}}class Rm{loader;url;t;xhr;constructor(e,t,i){this.loader=e,this.url=t,this.t=i;}upload(){return this.loader.file.then((e=>new Promise(((t,i)=>{this._initRequest(),this._initListeners(t,i,e),this._sendRequest(e);}))))}abort(){this.xhr&&this.xhr.abort();}_initRequest(){const e=this.xhr=new XMLHttpRequest;e.open("POST",this.url,!0),e.responseType="json";}_initListeners(e,t,i){const n=this.xhr,s=this.loader,o=(0, this.t)("Cannot upload file:")+` ${i.name}.`;n.addEventListener("error",(()=>t(o))),n.addEventListener("abort",(()=>t())),n.addEventListener("load",(()=>{const i=n.response;if(!i||!i.uploaded)return t(i&&i.error&&i.error.message?i.error.message:o);e({default:i.url});})),n.upload&&n.upload.addEventListener("progress",(e=>{e.lengthComputable&&(s.uploadTotal=e.total,s.uploaded=e.loaded);}));}_sendRequest(e){const t=new FormData;t.append("upload",e),t.append("ckCsrfToken",Im()),this.xhr.send(t);}}const Om=["left","right","center","justify"];function Bm(e){return Om.includes(e)}function Mm(e,t){return "rtl"==t.contentLanguageDirection?"right"===e:"left"===e}function Lm(e){const t=e.map((e=>{let t;return t="string"==typeof e?{name:e}:e,t})).filter((e=>{const t=Om.includes(e.name);return t||E("alignment-config-name-not-recognized",{option:e}),t})),i=t.filter((e=>Boolean(e.className))).length;if(i&&i{const s=n.slice(i+1);if(s.some((e=>e.name==t.name)))throw new A("alignment-config-name-already-defined",{option:t,configuredOptions:e});if(t.className){if(s.some((e=>e.className==t.className)))throw new A("alignment-config-classname-already-defined",{option:t,configuredOptions:e})}})),t}const Fm="alignment";class Nm extends Hr{refresh(){const e=this.editor.locale,t=wr(this.editor.model.document.selection.getSelectedBlocks());this.isEnabled=Boolean(t)&&this._canBeAligned(t),this.isEnabled&&t.hasAttribute("alignment")?this.value=t.getAttribute("alignment"):this.value="rtl"===e.contentLanguageDirection?"right":"left";}execute(e={}){const t=this.editor,i=t.locale,n=t.model,s=n.document,o=e.value;n.change((e=>{const t=Array.from(s.selection.getSelectedBlocks()).filter((e=>this._canBeAligned(e))),n=t[0].getAttribute("alignment");Mm(o,i)||n===o||!o?function(e,t){for(const i of e)t.removeAttribute(Fm,i);}(t,e):function(e,t,i){for(const n of e)t.setAttribute(Fm,i,n);}(t,e,o);}));}_canBeAligned(e){return this.editor.model.schema.checkAttribute(e,Fm)}}class Dm extends Dr{static get pluginName(){return "AlignmentEditing"}static get isOfficialPlugin(){return !0}constructor(e){super(e),e.config.define("alignment",{options:Om.map((e=>({name:e})))});}init(){const e=this.editor,t=e.locale,i=e.model.schema,n=Lm(e.config.get("alignment.options")).filter((e=>Bm(e.name)&&!Mm(e.name,t))),s=n.some((e=>!!e.className));i.extend("$block",{allowAttributes:"alignment"}),e.model.schema.setAttributeProperties("alignment",{isFormatting:!0}),s?e.conversion.attributeToAttribute(function(e){const t={};for(const i of e)t[i.name]={key:"class",value:i.className};const i={model:{key:"alignment",values:e.map((e=>e.name))},view:t};return i}(n)):e.conversion.for("downcast").attributeToAttribute(function(e){const t={};for(const{name:i}of e)t[i]={key:"style",value:{"text-align":i}};const i={model:{key:"alignment",values:e.map((e=>e.name))},view:t};return i}(n));const o=function(e){const t=[];for(const{name:i}of e)t.push({view:{key:"style",value:{"text-align":i}},model:{key:"alignment",value:i}});return t}(n);for(const t of o)e.conversion.for("upcast").attributeToAttribute(t);const r=function(e){const t=[];for(const{name:i}of e)t.push({view:{key:"align",value:i},model:{key:"alignment",value:i}});return t}(n);for(const t of r)e.conversion.for("upcast").attributeToAttribute(t);e.commands.add("alignment",new Nm(e));}}class zm extends br{_parentElement;constructor(e=[]){super(e,{idProperty:"viewUid"}),this.on("add",((e,t,i)=>{this._renderViewIntoCollectionParent(t,i);})),this.on("remove",((e,t)=>{t.element&&this._parentElement&&t.element.remove();})),this._parentElement=null;}destroy(){this.map((e=>e.destroy()));}setParent(e){this._parentElement=e;for(const e of this)this._renderViewIntoCollectionParent(e);}delegate(...e){if(!e.length||!e.every((e=>"string"==typeof e)))throw new A("ui-viewcollection-delegate-wrong-events",this);return {to:t=>{for(const i of this)for(const n of e)i.delegate(n).to(t);this.on("add",((i,n)=>{for(const i of e)n.delegate(i).to(t);})),this.on("remove",((i,n)=>{for(const i of e)n.stopDelegating(i,t);}));}}}_renderViewIntoCollectionParent(e,t){e.isRendered||e.render(),e.element&&this._parentElement&&this._parentElement.insertBefore(e.element,this._parentElement.children[t]);}remove(e){return super.remove(e)}}class Hm extends(L()){ns;tag;text;attributes;children;eventListeners;_isRendered;_revertData;constructor(e){super(),Object.assign(this,Qm(Jm(e))),this._isRendered=!1,this._revertData=null;}render(){const e=this._renderNode({intoFragment:!0});return this._isRendered=!0,e}apply(e){return this._revertData={children:[],bindings:[],attributes:{}},this._renderNode({node:e,intoFragment:!1,isApplying:!0,revertData:this._revertData}),e}revert(e){if(!this._revertData)throw new A("ui-template-revert-not-applied",[this,e]);this._revertTemplateFromNode(e,this._revertData);}*getViews(){yield*function*e(t){if(t.children)for(const i of t.children)ng(i)?yield i:sg(i)&&(yield*e(i));}(this);}static bind(e,t){return {to:(i,n)=>new Um({eventNameOrFunction:i,attribute:i,observable:e,emitter:t,callback:n}),if:(i,n,s)=>new Wm({observable:e,emitter:t,attribute:i,valueIfTrue:n,callback:s})}}static extend(e,t){if(e._isRendered)throw new A("template-extend-render",[this,e]);tg(e,Qm(Jm(t)));}_renderNode(e){let t;if(t=e.node?this.tag&&this.text:this.tag?this.text:!this.text,t)throw new A("ui-template-wrong-syntax",this);return this.text?this._renderText(e):this._renderElement(e)}_renderElement(e){let t=e.node;return t||(t=e.node=document.createElementNS(this.ns||"http://www.w3.org/1999/xhtml",this.tag)),this._renderAttributes(e),this._renderElementChildren(e),this._setUpListeners(e),t}_renderText(e){let t=e.node;return t?e.revertData.text=t.textContent:t=e.node=document.createTextNode(""),jm(this.text)?this._bindToObservable({schema:this.text,updater:Gm(t),data:e}):t.textContent=this.text.join(""),t}_renderAttributes(e){if(!this.attributes)return;const t=e.node,i=e.revertData;for(const n in this.attributes){const s=t.getAttribute(n),o=this.attributes[n];i&&(i.attributes[n]=s);const r=rg(o)?o[0].ns:null;if(jm(o)){const a=rg(o)?o[0].value:o;i&&ag(n)&&a.unshift(s),this._bindToObservable({schema:a,updater:Km(t,n,r),data:e});}else if("style"==n&&"string"!=typeof o[0])this._renderStyleAttribute(o[0],e);else {i&&s&&ag(n)&&o.unshift(s);const e=o.map((e=>e&&e.value||e)).reduce(((e,t)=>e.concat(t)),[]).reduce(Xm,"");ig(e)||t.setAttributeNS(r,n,e);}}}_renderStyleAttribute(e,t){const i=t.node;for(const n in e){const s=e[n];jm(s)?this._bindToObservable({schema:[s],updater:Zm(i,n),data:t}):i.style[n]=s;}}_renderElementChildren(e){const t=e.node,i=e.intoFragment?document.createDocumentFragment():t,n=e.isApplying;let s=0;for(const o of this.children)if(og(o)){if(!n){o.setParent(t);for(const e of o)i.appendChild(e.element);}}else if(ng(o))n||(o.isRendered||o.render(),i.appendChild(o.element));else if(uo(o))i.appendChild(o);else if(n){const t={children:[],bindings:[],attributes:{}};e.revertData.children.push(t),o._renderNode({intoFragment:!1,node:i.childNodes[s++],isApplying:!0,revertData:t});}else i.appendChild(o.render());e.intoFragment&&t.appendChild(i);}_setUpListeners(e){if(this.eventListeners)for(const t in this.eventListeners){const i=this.eventListeners[t].map((i=>{const[n,s]=t.split("@");return i.activateDomEventListener(n,s,e)}));e.revertData&&e.revertData.bindings.push(i);}}_bindToObservable({schema:e,updater:t,data:i}){const n=i.revertData;qm(e,t,i);const s=e.filter((e=>!ig(e))).filter((e=>e.observable)).map((n=>n.activateAttributeListener(e,t,i)));n&&n.bindings.push(s);}_revertTemplateFromNode(e,t){for(const e of t.bindings)for(const t of e)t();if(t.text)return void(e.textContent=t.text);const i=e;for(const e in t.attributes){const n=t.attributes[e];null===n?i.removeAttribute(e):i.setAttribute(e,n);}for(let e=0;eqm(e,t,i);return this.emitter.listenTo(this.observable,`change:${this.attribute}`,n),()=>{this.emitter.stopListening(this.observable,`change:${this.attribute}`,n);}}}class Um extends $m{eventNameOrFunction;constructor(e){super(e),this.eventNameOrFunction=e.eventNameOrFunction;}activateDomEventListener(e,t,i){const n=(e,i)=>{t&&!i.target.matches(t)||("function"==typeof this.eventNameOrFunction?this.eventNameOrFunction(i):this.observable.fire(this.eventNameOrFunction,i));};return this.emitter.listenTo(i.node,e,n),()=>{this.emitter.stopListening(i.node,e,n);}}}class Wm extends $m{valueIfTrue;constructor(e){super(e),this.valueIfTrue=e.valueIfTrue;}getValue(e){return !ig(super.getValue(e))&&(this.valueIfTrue||!0)}}function jm(e){return !!e&&(e.value&&(e=e.value),Array.isArray(e)?e.some(jm):e instanceof $m)}function qm(e,t,{node:i}){const n=function(e,t){return e.map((e=>e instanceof $m?e.getValue(t):e))}(e,i);let s;s=1==e.length&&e[0]instanceof Wm?n[0]:n.reduce(Xm,""),ig(s)?t.remove():t.set(s);}function Gm(e){return {set(t){e.textContent=t;},remove(){e.textContent="";}}}function Km(e,t,i){return {set(n){e.setAttributeNS(i,t,n);},remove(){e.removeAttributeNS(i,t);}}}function Zm(e,t){return {set(i){e.style[t]=i;},remove(){e.style[t]=null;}}}function Jm(e){return Wn(e,(e=>{if(e&&(e instanceof $m||sg(e)||ng(e)||og(e)))return e}))}function Qm(e){if("string"==typeof e?e=function(e){return {text:[e]}}(e):e.text&&function(e){e.text=gr(e.text);}(e),e.on&&(e.eventListeners=function(e){for(const t in e)Ym(e,t);return e}(e.on),delete e.on),!e.text){e.attributes&&function(e){for(const t in e)e[t].value&&(e[t].value=gr(e[t].value)),Ym(e,t);}(e.attributes);const t=[];if(e.children)if(og(e.children))t.push(e.children);else for(const i of e.children)sg(i)||ng(i)||uo(i)?t.push(i):t.push(new Hm(i));e.children=t;}return e}function Ym(e,t){e[t]=gr(e[t]);}function Xm(e,t){return ig(t)?e:ig(e)?t:`${e} ${t}`}function eg(e,t){for(const i in t)e[i]?e[i].push(...t[i]):e[i]=t[i];}function tg(e,t){if(t.attributes&&(e.attributes||(e.attributes={}),eg(e.attributes,t.attributes)),t.eventListeners&&(e.eventListeners||(e.eventListeners={}),eg(e.eventListeners,t.eventListeners)),t.text&&e.text.push(...t.text),t.children&&t.children.length){if(e.children.length!=t.children.length)throw new A("ui-template-extend-children-mismatch",e);let i=0;for(const n of t.children)tg(e.children[i++],n);}}function ig(e){return !e&&0!==e}function ng(e){return e instanceof lg}function sg(e){return e instanceof Hm}function og(e){return e instanceof zm}function rg(e){return ue(e[0])&&e[0].ns}function ag(e){return "class"==e||"style"==e}class lg extends(go(Zs())){element;isRendered;locale;t;template;_viewCollections;_unboundChildren;_bindTemplate;constructor(e){super(),this.element=null,this.isRendered=!1,this.locale=e,this.t=e&&e.t,this._viewCollections=new br,this._unboundChildren=this.createCollection(),this._viewCollections.on("add",((t,i)=>{i.locale=e,i.t=e&&e.t;})),this.decorate("render");}get bindTemplate(){return this._bindTemplate?this._bindTemplate:this._bindTemplate=Hm.bind(this,this)}createCollection(e){const t=new zm(e);return this._viewCollections.add(t),t}registerChild(e){oo(e)||(e=[e]);for(const t of e)this._unboundChildren.add(t);}deregisterChild(e){oo(e)||(e=[e]);for(const t of e)this._unboundChildren.remove(t);}setTemplate(e){this.template=new Hm(e);}extendTemplate(e){Hm.extend(this.template,e);}render(){if(this.isRendered)throw new A("ui-view-render-already-rendered",this);this.template&&(this.element=this.template.render(),this.registerChild(this.template.getViews())),this.isRendered=!0;}destroy(){this.stopListening(),this._viewCollections.map((e=>e.destroy())),this.template&&this.template._revertData&&this.template.revert(this.element);}}function cg({emitter:e,activator:t,callback:i,contextElements:n,listenerOptions:s}){e.listenTo(document,"mousedown",((e,s)=>{if(!t())return;const o="function"==typeof s.composedPath?s.composedPath():[],r="function"==typeof n?n():n;for(const e of r)if(e.contains(s.target)||o.includes(e))return;i();}),s);}function dg(e){const t=e;t.set("_isCssTransitionsDisabled",!1),t.disableCssTransitions=()=>{t._isCssTransitionsDisabled=!0;},t.enableCssTransitions=()=>{t._isCssTransitionsDisabled=!1;},t.extendTemplate({attributes:{class:[t.bindTemplate.if("_isCssTransitionsDisabled","ck-transitions-disabled")]}});}function ug(e){return class extends e{disableCssTransitions(){this._isCssTransitionsDisabled=!0;}enableCssTransitions(){this._isCssTransitionsDisabled=!1;}constructor(...e){super(...e),this.set("_isCssTransitionsDisabled",!1),this.initializeCssTransitionDisablerMixin();}initializeCssTransitionDisablerMixin(){this.extendTemplate({attributes:{class:[this.bindTemplate.if("_isCssTransitionsDisabled","ck-transitions-disabled")]}});}}}function hg({view:e}){e.listenTo(e.element,"submit",((t,i)=>{i.preventDefault(),e.fire("submit");}),{useCapture:!0});}function mg({keystrokeHandler:e,focusTracker:t,gridItems:i,numberOfColumns:n,uiLanguageDirection:s}){const o="number"==typeof n?()=>n:n;function r(e){return n=>{const s=i.find((e=>e.element===t.focusedElement)),o=i.getIndex(s),r=e(o,i);i.get(r).focus(),n.stopPropagation(),n.preventDefault();}}function a(e,t){return e===t-1?0:e+1}function l(e,t){return 0===e?t-1:e-1}e.set("arrowright",r(((e,t)=>"rtl"===s?l(e,t.length):a(e,t.length)))),e.set("arrowleft",r(((e,t)=>"rtl"===s?a(e,t.length):l(e,t.length)))),e.set("arrowup",r(((e,t)=>{let i=e-o();return i<0&&(i=e+o()*Math.floor(t.length/o()),i>t.length-1&&(i-=o())),i}))),e.set("arrowdown",r(((e,t)=>{let i=e+o();return i>t.length-1&&(i=e%o()),i})));}class gg extends lg{static presentationalAttributeNames=["alignment-baseline","baseline-shift","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-rendering","cursor","direction","display","dominant-baseline","fill","fill-opacity","fill-rule","filter","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","image-rendering","letter-spacing","lighting-color","marker-end","marker-mid","marker-start","mask","opacity","overflow","paint-order","pointer-events","shape-rendering","stop-color","stop-opacity","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-anchor","text-decoration","text-overflow","text-rendering","transform","unicode-bidi","vector-effect","visibility","white-space","word-spacing","writing-mode"];constructor(){super();const e=this.bindTemplate;this.set("content",""),this.set("viewBox","0 0 20 20"),this.set("fillColor",""),this.set("isColorInherited",!0),this.set("isVisible",!0),this.setTemplate({tag:"svg",ns:"http://www.w3.org/2000/svg",attributes:{class:["ck","ck-icon",e.if("isVisible","ck-hidden",(e=>!e)),"ck-reset_all-excluded",e.if("isColorInherited","ck-icon_inherit-color")],viewBox:e.to("viewBox")}});}render(){super.render(),this._updateXMLContent(),this._colorFillPaths(),this.on("change:content",(()=>{this._updateXMLContent(),this._colorFillPaths();})),this.on("change:fillColor",(()=>{this._colorFillPaths();}));}_updateXMLContent(){if(this.content){const e=(new DOMParser).parseFromString(this.content.trim(),"image/svg+xml").querySelector("svg"),t=e.getAttribute("viewBox");t&&(this.viewBox=t);for(const{name:t,value:i}of Array.from(e.attributes))gg.presentationalAttributeNames.includes(t)&&this.element.setAttribute(t,i);for(;this.element.firstChild;)this.element.removeChild(this.element.firstChild);for(;e.childNodes.length>0;)this.element.appendChild(e.childNodes[0]);}}_colorFillPaths(){this.fillColor&&this.element.querySelectorAll(".ck-icon__fill").forEach((e=>{e.style.fill=this.fillColor;}));}}class fg extends lg{constructor(){super(),this.set({style:void 0,text:void 0,id:void 0});const e=this.bindTemplate;this.setTemplate({tag:"span",attributes:{class:["ck","ck-button__label"],style:e.to("style"),id:e.to("id")},children:[{text:e.to("text")}]});}}class pg extends lg{children;labelView;iconView;keystrokeView;_focusDelayed=null;constructor(e,t=new fg){super(e);const i=this.bindTemplate,n=k();this.set("_ariaPressed",!1),this.set("_ariaChecked",!1),this.set("ariaLabel",void 0),this.set("ariaLabelledBy",`ck-editor__aria-label_${n}`),this.set("class",void 0),this.set("labelStyle",void 0),this.set("icon",void 0),this.set("isEnabled",!0),this.set("isOn",!1),this.set("isVisible",!0),this.set("isToggleable",!1),this.set("keystroke",void 0),this.set("label",void 0),this.set("role",void 0),this.set("tabindex",-1),this.set("tooltip",!1),this.set("tooltipPosition","s"),this.set("type","button"),this.set("withText",!1),this.set("withKeystroke",!1),this.children=this.createCollection(),this.labelView=this._setupLabelView(t),this.iconView=new gg,this.iconView.extendTemplate({attributes:{class:"ck-button__icon"}}),this.keystrokeView=this._createKeystrokeView(),this.bind("_tooltipString").to(this,"tooltip",this,"label",this,"keystroke",this._getTooltipString.bind(this));const s={tag:"button",attributes:{class:["ck","ck-button",i.to("class"),i.if("isEnabled","ck-disabled",(e=>!e)),i.if("isVisible","ck-hidden",(e=>!e)),i.to("isOn",(e=>e?"ck-on":"ck-off")),i.if("withText","ck-button_with-text"),i.if("withKeystroke","ck-button_with-keystroke")],role:i.to("role"),type:i.to("type",(e=>e||"button")),tabindex:i.to("tabindex"),"aria-checked":i.to("_ariaChecked"),"aria-pressed":i.to("_ariaPressed"),"aria-label":i.to("ariaLabel"),"aria-labelledby":i.to("ariaLabelledBy"),"aria-disabled":i.if("isEnabled",!0,(e=>!e)),"data-cke-tooltip-text":i.to("_tooltipString"),"data-cke-tooltip-position":i.to("tooltipPosition")},children:this.children,on:{click:i.to((e=>{this.isEnabled?this.fire("execute"):e.preventDefault();}))}};this.bind("_ariaPressed").to(this,"isOn",this,"isToggleable",this,"role",((e,t,i)=>!(!t||bg(i))&&String(!!e))),this.bind("_ariaChecked").to(this,"isOn",this,"isToggleable",this,"role",((e,t,i)=>!(!t||!bg(i))&&String(!!e))),o.isSafari&&(this._focusDelayed||(this._focusDelayed=Sr((()=>this.focus()),0)),s.on.mousedown=i.to((()=>{this._focusDelayed();})),s.on.mouseup=i.to((()=>{this._focusDelayed.cancel();}))),this.setTemplate(s);}render(){super.render(),this.icon&&(this.iconView.bind("content").to(this,"icon"),this.children.add(this.iconView)),this.children.add(this.labelView),this.withKeystroke&&this.keystroke&&this.children.add(this.keystrokeView);}focus(){this.element.focus();}destroy(){this._focusDelayed&&this._focusDelayed.cancel(),super.destroy();}_setupLabelView(e){return e.bind("text","style","id").to(this,"label","labelStyle","ariaLabelledBy"),e}_createKeystrokeView(){const e=new lg;return e.setTemplate({tag:"span",attributes:{class:["ck","ck-button__keystroke"]},children:[{text:this.bindTemplate.to("keystroke",(e=>ar(e)))}]}),e}_getTooltipString(e,t,i){return e?"string"==typeof e?e:(i&&(i=ar(i)),e instanceof Function?e(t,i):`${t}${i?` (${i})`:""}`):""}}function bg(e){switch(e){case"radio":case"checkbox":case"option":case"switch":case"menuitemcheckbox":case"menuitemradio":return !0;default:return !1}}class wg extends lg{children;iconView;constructor(e,t={}){super(e);const i=this.bindTemplate;this.set("label",t.label||""),this.set("class",t.class||null),this.children=this.createCollection(),this.setTemplate({tag:"div",attributes:{class:["ck","ck-form__header",i.to("class")]},children:this.children}),t.icon&&(this.iconView=new gg,this.iconView.content=t.icon,this.children.add(this.iconView));const n=new lg(e);n.setTemplate({tag:"h2",attributes:{class:["ck","ck-form__header__label"],role:"presentation"},children:[{text:i.to("label")}]}),this.children.add(n);}}class _g extends(L()){focusables;focusTracker;keystrokeHandler;actions;constructor(e){if(super(),this.focusables=e.focusables,this.focusTracker=e.focusTracker,this.keystrokeHandler=e.keystrokeHandler,this.actions=e.actions,e.actions&&e.keystrokeHandler)for(const t in e.actions){let i=e.actions[t];"string"==typeof i&&(i=[i]);for(const n of i)e.keystrokeHandler.set(n,((e,i)=>{this[t](),i();}),e.keystrokeHandlerOptions);}this.on("forwardCycle",(()=>this.focusFirst()),{priority:"low"}),this.on("backwardCycle",(()=>this.focusLast()),{priority:"low"});}get first(){return this.focusables.find(vg)||null}get last(){return this.focusables.filter(vg).slice(-1)[0]||null}get next(){return this._getDomFocusableItem(1)}get previous(){return this._getDomFocusableItem(-1)}get current(){let e=null;return null===this.focusTracker.focusedElement?null:(this.focusables.find(((t,i)=>{const n=t.element===this.focusTracker.focusedElement;return n&&(e=i),n})),e)}focusFirst(){this._focus(this.first,1);}focusLast(){this._focus(this.last,-1);}focusNext(){const e=this.next;e&&this.focusables.getIndex(e)===this.current||e===this.first?this.fire("forwardCycle"):this._focus(e,1);}focusPrevious(){const e=this.previous;e&&this.focusables.getIndex(e)===this.current||e===this.last?this.fire("backwardCycle"):this._focus(e,-1);}chain(e){const t=()=>null===this.current?null:this.focusables.get(this.current);this.listenTo(e,"forwardCycle",(e=>{const i=t();this.focusNext(),i!==t()&&e.stop();}),{priority:"low"}),this.listenTo(e,"backwardCycle",(e=>{const i=t();this.focusPrevious(),i!==t()&&e.stop();}),{priority:"low"});}unchain(e){this.stopListening(e);}_focus(e,t){e&&this.focusTracker.focusedElement!==e.element&&e.focus(t);}_getDomFocusableItem(e){const t=this.focusables.length;if(!t)return null;const i=this.current;if(null===i)return this[1===e?"first":"last"];let n=this.focusables.get(i),s=(i+t+e)%t;do{const i=this.focusables.get(s);if(vg(i)){n=i;break}s=(s+t+e)%t;}while(s!==i);return n}}function vg(e){return yg(e)&&No(e.element)}function yg(e){return !(!("focus"in e)||"function"!=typeof e.focus)}function kg(e){return yg(e)&&"focusCycler"in e&&e.focusCycler instanceof _g}function Cg(e){return class extends e{_onDragBound=this._onDrag.bind(this);_onDragEndBound=this._onDragEnd.bind(this);_lastDraggingCoordinates={x:0,y:0};constructor(...e){super(...e),this.on("render",(()=>{this._attachListeners();})),this.set("isDragging",!1);}_attachListeners(){this.listenTo(this.element,"mousedown",this._onDragStart.bind(this)),this.listenTo(this.element,"touchstart",this._onDragStart.bind(this));}_attachDragListeners(){this.listenTo(i.document,"mouseup",this._onDragEndBound),this.listenTo(i.document,"touchend",this._onDragEndBound),this.listenTo(i.document,"mousemove",this._onDragBound),this.listenTo(i.document,"touchmove",this._onDragBound);}_detachDragListeners(){this.stopListening(i.document,"mouseup",this._onDragEndBound),this.stopListening(i.document,"touchend",this._onDragEndBound),this.stopListening(i.document,"mousemove",this._onDragBound),this.stopListening(i.document,"touchmove",this._onDragBound);}_onDragStart(e,t){if(!this._isHandleElementPressed(t))return;this._attachDragListeners();let i=0,n=0;t instanceof MouseEvent?(i=t.clientX,n=t.clientY):(i=t.touches[0].clientX,n=t.touches[0].clientY),this._lastDraggingCoordinates={x:i,y:n},this.isDragging=!0;}_onDrag(e,t){if(!this.isDragging)return void this._detachDragListeners();let i=0,n=0;t instanceof MouseEvent?(i=t.clientX,n=t.clientY):(i=t.touches[0].clientX,n=t.touches[0].clientY),t.preventDefault(),this.fire("drag",{deltaX:Math.round(i-this._lastDraggingCoordinates.x),deltaY:Math.round(n-this._lastDraggingCoordinates.y)}),this._lastDraggingCoordinates={x:i,y:n};}_onDragEnd(){this._detachDragListeners(),this.isDragging=!1;}_isHandleElementPressed(e){return !!this.dragHandleElement&&(this.dragHandleElement===e.target||e.target instanceof HTMLElement&&this.dragHandleElement.contains(e.target))}}}class xg extends lg{children;keystrokes;focusCycler;_focusTracker;_focusables;constructor(e){super(e),this.children=this.createCollection(),this.keystrokes=new Cr,this._focusTracker=new _r,this._focusables=new zm,this.focusCycler=new _g({focusables:this._focusables,focusTracker:this._focusTracker,keystrokeHandler:this.keystrokes,actions:{focusPrevious:"shift + tab",focusNext:"tab"}}),this.setTemplate({tag:"div",attributes:{class:["ck","ck-dialog__actions"]},children:this.children});}render(){super.render(),this.keystrokes.listenTo(this.element);}setButtons(e){for(const t of e){const e=new pg(this.locale);let i;for(i in e.on("execute",(()=>t.onExecute())),t.onCreate&&t.onCreate(e),t)"onExecute"!=i&&"onCreate"!=i&&e.set(i,t[i]);this.children.add(e);}this._updateFocusCyclableItems();}focus(e){-1===e?this.focusCycler.focusLast():this.focusCycler.focusFirst();}_updateFocusCyclableItems(){Array.from(this.children).forEach((e=>{this._focusables.add(e),this._focusTracker.add(e.element);}));}}class Ag extends lg{children;constructor(e){super(e),this.children=this.createCollection(),this.setTemplate({tag:"div",attributes:{class:["ck","ck-dialog__content"]},children:this.children});}reset(){for(;this.children.length;)this.children.remove(0);}}const Eg={SCREEN_CENTER:"screen-center",EDITOR_CENTER:"editor-center",EDITOR_TOP_SIDE:"editor-top-side",EDITOR_TOP_CENTER:"editor-top-center",EDITOR_BOTTOM_CENTER:"editor-bottom-center",EDITOR_ABOVE_CENTER:"editor-above-center",EDITOR_BELOW_CENTER:"editor-below-center"},Tg=Oo("px");class Pg extends(Cg(lg)){parts;headerView;closeButtonView;actionsView;static defaultOffset=15;contentView;keystrokes;focusTracker;wasMoved=!1;_getCurrentDomRoot;_getViewportOffset;_focusables;_focusCycler;constructor(e,{getCurrentDomRoot:t,getViewportOffset:i}){super(e);const n=this.bindTemplate,s=e.t;this.set("className",""),this.set("ariaLabel",s("Editor dialog")),this.set("isModal",!1),this.set("position",Eg.SCREEN_CENTER),this.set("_isVisible",!1),this.set("_isTransparent",!1),this.set("_top",0),this.set("_left",0),this._getCurrentDomRoot=t,this._getViewportOffset=i,this.decorate("moveTo"),this.parts=this.createCollection(),this.keystrokes=new Cr,this.focusTracker=new _r,this._focusables=new zm,this._focusCycler=new _g({focusables:this._focusables,focusTracker:this.focusTracker,keystrokeHandler:this.keystrokes,actions:{focusPrevious:"shift + tab",focusNext:"tab"}}),this.setTemplate({tag:"div",attributes:{class:["ck","ck-dialog-overlay",n.if("isModal","ck-dialog-overlay__transparent",(e=>!e)),n.if("_isVisible","ck-hidden",(e=>!e))],tabindex:"-1"},children:[{tag:"div",attributes:{tabindex:"-1",class:["ck","ck-dialog",n.if("isModal","ck-dialog_modal"),n.to("className")],role:"dialog","aria-label":n.to("ariaLabel"),style:{top:n.to("_top",(e=>Tg(e))),left:n.to("_left",(e=>Tg(e))),visibility:n.if("_isTransparent","hidden")}},children:this.parts}]});}render(){super.render(),this.keystrokes.set("Esc",((e,t)=>{this.fire("close",{source:"escKeyPress"}),t();})),this.on("drag",((e,{deltaX:t,deltaY:i})=>{this.wasMoved=!0,this.moveBy(t,i);})),this.listenTo(i.window,"resize",(()=>{this._isVisible&&!this.wasMoved&&this.updatePosition();})),this.listenTo(i.document,"scroll",(()=>{this._isVisible&&!this.wasMoved&&this.updatePosition();})),this.on("change:_isVisible",((e,t,i)=>{i&&(this._isTransparent=!0,setTimeout((()=>{this.updatePosition(),this._isTransparent=!1,this.focus();}),10));})),this.keystrokes.listenTo(this.element);}get dragHandleElement(){return this.headerView&&!this.isModal?this.headerView.element:null}setupParts({icon:e,title:t,hasCloseButton:i=!0,content:n,actionButtons:s}){t&&(this.headerView=new wg(this.locale,{icon:e}),i&&(this.closeButtonView=this._createCloseButton(),this.headerView.children.add(this.closeButtonView)),this.headerView.label=t,this.ariaLabel=t,this.parts.add(this.headerView,0)),n&&(n instanceof lg&&(n=[n]),this.contentView=new Ag(this.locale),this.contentView.children.addMany(n),this.parts.add(this.contentView)),s&&(this.actionsView=new xg(this.locale),this.actionsView.setButtons(s),this.parts.add(this.actionsView)),this._updateFocusCyclableItems();}focus(){this._focusCycler.focusFirst();}moveTo(e,t){const i=this._getViewportRect(),n=this._getDialogRect();e+n.width>i.right&&(e=i.right-n.width),e{this._focusables.add(e),this.focusTracker.add(e.element),kg(e)&&this._focusCycler.chain(e.focusCycler);}));}_createCloseButton(){const e=new pg(this.locale),t=this.locale.t;return e.set({label:t("Close"),tooltip:!0,icon:vm.cancel}),e.on("execute",(()=>this.fire("close",{source:"closeButton"}))),e}}class Sg extends Dr{view;static _visibleDialogPlugin;_onHide;static get pluginName(){return "Dialog"}static get isOfficialPlugin(){return !0}constructor(e){super(e);const t=e.t;this._initShowHideListeners(),this._initFocusToggler(),this._initMultiRootIntegration(),this.set({id:null,isOpen:!1}),e.accessibility.addKeystrokeInfos({categoryId:"navigation",keystrokes:[{label:t("Move focus in and out of an active dialog window"),keystroke:"Ctrl+F6",mayRequireFn:!0}]});}destroy(){super.destroy(),this._unlockBodyScroll();}_initShowHideListeners(){this.on("show",((e,t)=>{this._show(t);})),this.on("show",((e,t)=>{t.onShow&&t.onShow(this);}),{priority:"low"}),this.on("hide",(()=>{Sg._visibleDialogPlugin&&Sg._visibleDialogPlugin._hide();})),this.on("hide",(()=>{this._onHide&&(this._onHide(this),this._onHide=void 0);}),{priority:"low"});}_initFocusToggler(){const e=this.editor;e.keystrokes.set("Ctrl+F6",((t,i)=>{this.isOpen&&!this.view.isModal&&(this.view.focusTracker.isFocused?e.editing.view.focus():this.view.focus(),i());}));}_initMultiRootIntegration(){const e=this.editor.model;e.document.on("change:data",(()=>{if(!this.view)return;const t=e.document.differ.getChangedRoots();for(const e of t)e.state&&this.view.updatePosition();}));}show(e){this.hide(),this.fire(`show:${e.id}`,e);}_show({id:e,icon:t,title:i,hasCloseButton:n=!0,content:s,actionButtons:o,className:r,isModal:a,position:l,onHide:c}){const d=this.editor;this.view=new Pg(d.locale,{getCurrentDomRoot:()=>d.editing.view.getDomRoot(d.model.document.selection.anchor.root.rootName),getViewportOffset:()=>d.ui.viewportOffset});const u=this.view;u.on("close",(()=>{this.hide();})),d.ui.view.body.add(u),d.keystrokes.listenTo(u.element),l||(l=a?Eg.SCREEN_CENTER:Eg.EDITOR_CENTER),a&&this._lockBodyScroll(),u.set({position:l,_isVisible:!0,className:r,isModal:a}),u.setupParts({icon:t,title:i,hasCloseButton:n,content:s,actionButtons:o}),this.id=e,c&&(this._onHide=c),this.isOpen=!0,Sg._visibleDialogPlugin=this;}hide(){Sg._visibleDialogPlugin&&Sg._visibleDialogPlugin.fire(`hide:${Sg._visibleDialogPlugin.id}`);}_hide(){if(!this.view)return;const e=this.editor,t=this.view;t.isModal&&this._unlockBodyScroll(),t.contentView&&t.contentView.reset(),e.ui.view.body.remove(t),e.ui.focusTracker.remove(t.element),e.keystrokes.stopListening(t.element),t.destroy(),e.editing.view.focus(),this.id=null,this.isOpen=!1,Sg._visibleDialogPlugin=null;}_lockBodyScroll(){document.documentElement.classList.add("ck-dialog-scroll-locked");}_unlockBodyScroll(){document.documentElement.classList.remove("ck-dialog-scroll-locked");}}class Ig extends pg{_checkIconHolderView=new Vg;constructor(e,t=new fg){super(e,t),this.set({hasCheckSpace:!1,_hasCheck:this.isToggleable});const i=this.bindTemplate;this.extendTemplate({attributes:{class:["ck-list-item-button",i.if("isToggleable","ck-list-item-button_toggleable")]}}),this.bind("_hasCheck").to(this,"hasCheckSpace",this,"isToggleable",((e,t)=>e||t));}render(){super.render(),this._hasCheck&&this.children.add(this._checkIconHolderView,0),this._watchCheckIconHolderMount();}_watchCheckIconHolderMount(){this._checkIconHolderView.bind("isOn").to(this,"isOn",(e=>this.isToggleable&&e)),this.on("change:_hasCheck",((e,t,i)=>{const{children:n,_checkIconHolderView:s}=this;i?n.add(s,0):n.remove(s);}));}}class Vg extends lg{children;_checkIconView=this._createCheckIconView();constructor(){super();const e=this.bindTemplate;this.children=this.createCollection(),this.set("isOn",!1),this.setTemplate({tag:"span",children:this.children,attributes:{class:["ck","ck-list-item-button__check-holder",e.to("isOn",(e=>e?"ck-on":"ck-off"))]}});}render(){super.render(),this.isOn&&this.children.add(this._checkIconView,0),this._watchCheckIconMount();}_watchCheckIconMount(){this.on("change:isOn",((e,t,i)=>{const{children:n,_checkIconView:s}=this;i&&!n.has(s)?n.add(s):!i&&n.has(s)&&n.remove(s);}));}_createCheckIconView(){const e=new gg;return e.content=vm.check,e.extendTemplate({attributes:{class:"ck-list-item-button__check-icon"}}),e}}class Rg extends Ig{constructor(e){super(e),this.set({withText:!0,withKeystroke:!0,tooltip:!1,role:"menuitem"}),this.extendTemplate({attributes:{class:["ck-menu-bar__menu__item__button"]}});}}class Og extends lg{id;constructor(e){super(e),this.set("text",void 0),this.set("for",void 0),this.id=`ck-editor__label_${k()}`;const t=this.bindTemplate;this.setTemplate({tag:"label",attributes:{class:["ck","ck-label"],id:this.id,for:t.to("for")},children:[{text:t.to("text")}]});}}class Bg extends lg{constructor(e,t){super(e);const i=e.t,n=new Og;n.text=i("Help Contents. To close this dialog press ESC."),this.setTemplate({tag:"div",attributes:{class:["ck","ck-accessibility-help-dialog__content"],"aria-labelledby":n.id,role:"document",tabindex:-1},children:[ro(document,"p",{},i("Below, you can find a list of keyboard shortcuts that can be used in the editor.")),...this._createCategories(Array.from(t.values())),n]});}focus(){this.element.focus();}_createCategories(e){return e.map((e=>{const t=[ro(document,"h3",{},e.label),...Array.from(e.groups.values()).map((e=>this._createGroup(e))).flat()];return e.description&&t.splice(1,0,ro(document,"p",{},e.description)),ro(document,"section",{},t)}))}_createGroup(e){const t=e.keystrokes.sort(((e,t)=>e.label.localeCompare(t.label))).map((e=>this._createGroupRow(e))).flat(),i=[ro(document,"dl",{},t)];return e.label&&i.unshift(ro(document,"h4",{},e.label)),i}_createGroupRow(e){const t=this.locale.t,i=ro(document,"dt"),n=ro(document,"dd"),s=function(e){if("string"==typeof e)return [[e]];if("string"==typeof e[0])return [e];return e}(e.keystroke),r=[];for(const e of s)r.push(e.map(Mg).join(""));return i.innerHTML=e.label,n.innerHTML=r.join(", ")+(e.mayRequireFn&&o.isMac?` ${t("(may require Fn)")}`:""),[i,n]}}function Mg(e){return ar(e).split("+").map((e=>`${e}`)).join("+")}var Lg='';class Fg extends Dr{contentView=null;static get requires(){return [Sg]}static get pluginName(){return "AccessibilityHelp"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.locale.t;e.ui.componentFactory.add("accessibilityHelp",(()=>{const e=this._createButton(pg);return e.set({tooltip:!0,withText:!1,label:t("Accessibility help")}),e})),e.ui.componentFactory.add("menuBar:accessibilityHelp",(()=>{const e=this._createButton(Rg);return e.label=t("Accessibility"),e})),e.keystrokes.set("Alt+0",((e,t)=>{this._toggleDialog(),t();})),this._setupRootLabels();}_createButton(e){const t=this.editor,i=t.plugins.get("Dialog"),n=new e(t.locale);return n.set({keystroke:"Alt+0",icon:Lg,isToggleable:!0}),n.on("execute",(()=>this._toggleDialog())),n.bind("isOn").to(i,"id",(e=>"accessibilityHelp"===e)),n}_setupRootLabels(){const e=this.editor,t=e.editing.view,i=e.t;function n(e,t){const n=[t.getAttribute("aria-label"),i("Press %0 for help.",[ar("Alt+0")])].filter((e=>e)).join(". ");e.setAttribute("aria-label",n,t);}e.ui.on("ready",(()=>{t.change((e=>{for(const i of t.document.roots)n(e,i);})),e.on("addRoot",((i,s)=>{const o=e.editing.view.document.getRoot(s.rootName);t.change((e=>n(e,o)));}),{priority:"low"});}));}_toggleDialog(){const e=this.editor,t=e.plugins.get("Dialog"),i=e.locale.t;this.contentView||(this.contentView=new Bg(e.locale,e.accessibility.keystrokeInfos)),"accessibilityHelp"===t.id?t.hide():t.show({id:"accessibilityHelp",className:"ck-accessibility-help-dialog",title:i("Accessibility help"),icon:Lg,hasCloseButton:!0,content:this.contentView});}}class Ng extends zm{locale;_bodyCollectionContainer;constructor(e,t=[]){super(t),this.locale=e;}get bodyCollectionContainer(){return this._bodyCollectionContainer}attachToDom(){this._bodyCollectionContainer=new Hm({tag:"div",attributes:{class:["ck","ck-reset_all","ck-body","ck-rounded-corners"],dir:this.locale.uiLanguageDirection,role:"application"},children:this}).render();let e=document.querySelector(".ck-body-wrapper");e||(e=ro(document,"div",{class:"ck-body-wrapper"}),document.body.appendChild(e)),e.appendChild(this._bodyCollectionContainer);}detachFromDom(){super.destroy(),this._bodyCollectionContainer&&this._bodyCollectionContainer.remove();const e=document.querySelector(".ck-body-wrapper");e&&0==e.childElementCount&&e.remove();}}class Dg extends pg{toggleSwitchView;constructor(e){super(e),this.isToggleable=!0,this.toggleSwitchView=this._createToggleView(),this.extendTemplate({attributes:{class:"ck-switchbutton"}});}render(){super.render(),this.children.add(this.toggleSwitchView);}_createToggleView(){const e=new lg;return e.setTemplate({tag:"span",attributes:{class:["ck","ck-button__toggle"]},children:[{tag:"span",attributes:{class:["ck","ck-button__toggle__inner"]}}]}),e}}class zg extends($g(pg)){}class Hg extends($g(Ig)){}function $g(e){return class extends e{buttonView;_fileInputView;constructor(...e){super(...e),this.buttonView=this,this._fileInputView=new Ug(this.locale),this._fileInputView.bind("acceptedType").to(this),this._fileInputView.bind("allowMultipleFiles").to(this),this._fileInputView.delegate("done").to(this),this.on("execute",(()=>{this._fileInputView.open();})),this.extendTemplate({attributes:{class:"ck-file-dialog-button"}});}render(){super.render(),this.children.add(this._fileInputView);}}}class Ug extends lg{constructor(e){super(e),this.set("acceptedType",void 0),this.set("allowMultipleFiles",!1);const t=this.bindTemplate;this.setTemplate({tag:"input",attributes:{class:["ck-hidden"],type:"file",tabindex:"-1",accept:t.to("acceptedType"),multiple:t.to("allowMultipleFiles")},on:{change:t.to((()=>{this.element&&this.element.files&&this.element.files.length&&this.fire("done",this.element.files),this.element.value="";}))}});}open(){this.element.click();}}var Wg='';class jg extends lg{buttonView;children;constructor(e,t){super(e);const i=this.bindTemplate;this.set("isCollapsed",!1),this.set("label",""),this.buttonView=this._createButtonView(),this.children=this.createCollection(),this.set("_collapsibleAriaLabelUid",void 0),t&&this.children.addMany(t),this.setTemplate({tag:"div",attributes:{class:["ck","ck-collapsible",i.if("isCollapsed","ck-collapsible_collapsed")]},children:[this.buttonView,{tag:"div",attributes:{class:["ck","ck-collapsible__children"],role:"region",hidden:i.if("isCollapsed","hidden"),"aria-labelledby":i.to("_collapsibleAriaLabelUid")},children:this.children}]});}render(){super.render(),this._collapsibleAriaLabelUid=this.buttonView.labelView.element.id;}focus(){this.buttonView.focus();}_createButtonView(){const e=new pg(this.locale),t=e.bindTemplate;return e.set({withText:!0,icon:Wg}),e.extendTemplate({attributes:{"aria-expanded":t.to("isOn",(e=>String(e)))}}),e.bind("label").to(this),e.bind("isOn").to(this,"isCollapsed",(e=>!e)),e.on("execute",(()=>{this.isCollapsed=!this.isCollapsed;})),e}}function qg(e,t){const i=e.t,n={Black:i("Black"),"Dim grey":i("Dim grey"),Grey:i("Grey"),"Light grey":i("Light grey"),White:i("White"),Red:i("Red"),Orange:i("Orange"),Yellow:i("Yellow"),"Light green":i("Light green"),Green:i("Green"),Aquamarine:i("Aquamarine"),Turquoise:i("Turquoise"),"Light blue":i("Light blue"),Blue:i("Blue"),Purple:i("Purple")};return t.map((e=>{const t=n[e.label];return t&&t!=e.label&&(e.label=t),e}))}function Gg(e){return e.map(Kg).filter((e=>!!e))}function Kg(e){return "string"==typeof e?{model:e,label:e,hasBorder:!1,view:{name:"span",styles:{color:e}}}:{model:e.color,label:e.label||e.color,hasBorder:void 0!==e.hasBorder&&e.hasBorder,view:{name:"span",styles:{color:`${e.color}`}}}}class Zg extends pg{constructor(e){super(e);const t=this.bindTemplate;this.set("color",void 0),this.set("hasBorder",!1),this.icon='',this.extendTemplate({attributes:{style:{backgroundColor:t.to("color",(e=>o.isMediaForcedColors?null:e))},class:["ck","ck-color-grid__tile",t.if("hasBorder","ck-color-selector__color-tile_bordered")]}});}render(){super.render(),this.iconView.fillColor="hsl(0, 0%, 100%)";}}class Jg extends lg{columns;items;focusTracker;keystrokes;constructor(e,t){super(e);const i=t&&t.colorDefinitions?t.colorDefinitions:[];this.columns=t&&t.columns?t.columns:5;const n={gridTemplateColumns:`repeat( ${this.columns}, 1fr)`};this.set("selectedColor",void 0),this.items=this.createCollection(),this.focusTracker=new _r,this.keystrokes=new Cr,this.items.on("add",((e,t)=>{t.isOn=t.color===this.selectedColor;})),i.forEach((e=>{const t=new Zg;t.set({color:e.color,label:e.label,tooltip:!0,hasBorder:e.options.hasBorder}),t.on("execute",(()=>{this.fire("execute",{value:e.color,hasBorder:e.options.hasBorder,label:e.label});})),this.items.add(t);})),this.setTemplate({tag:"div",children:this.items,attributes:{class:["ck","ck-color-grid"],style:n}}),this.on("change:selectedColor",((e,t,i)=>{for(const e of this.items)e.isOn=e.color===i;}));}focus(){this.items.length&&this.items.first.focus();}focusLast(){this.items.length&&this.items.last.focus();}render(){super.render();for(const e of this.items)this.focusTracker.add(e.element);this.items.on("add",((e,t)=>{this.focusTracker.add(t.element);})),this.items.on("remove",((e,t)=>{this.focusTracker.remove(t.element);})),this.keystrokes.listenTo(this.element),mg({keystrokeHandler:this.keystrokes,focusTracker:this.focusTracker,gridItems:this.items,numberOfColumns:this.columns,uiLanguageDirection:this.locale&&this.locale.uiLanguageDirection});}destroy(){super.destroy(),this.focusTracker.destroy(),this.keystrokes.destroy();}}var Qg={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},Yg={red:0,orange:60,yellow:120,green:180,blue:240,purple:300};function Xg(e){var t,i,n=[],s=1;if("string"==typeof e)if(Qg[e])n=Qg[e].slice(),i="rgb";else if("transparent"===e)s=0,i="rgb",n=[0,0,0];else if(/^#[A-Fa-f0-9]+$/.test(e)){var o=e.slice(1);s=1,(l=o.length)<=4?(n=[parseInt(o[0]+o[0],16),parseInt(o[1]+o[1],16),parseInt(o[2]+o[2],16)],4===l&&(s=parseInt(o[3]+o[3],16)/255)):(n=[parseInt(o[0]+o[1],16),parseInt(o[2]+o[3],16),parseInt(o[4]+o[5],16)],8===l&&(s=parseInt(o[6]+o[7],16)/255)),n[0]||(n[0]=0),n[1]||(n[1]=0),n[2]||(n[2]=0),i="rgb";}else if(t=/^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\s*\(([^\)]*)\)/.exec(e)){var r=t[1],a="rgb"===r;i=o=r.replace(/a$/,"");var l="cmyk"===o?4:"gray"===o?1:3;n=t[2].trim().split(/\s*[,\/]\s*|\s+/).map((function(e,t){if(/%$/.test(e))return t===l?parseFloat(e)/100:"rgb"===o?255*parseFloat(e)/100:parseFloat(e);if("h"===o[t]){if(/deg$/.test(e))return parseFloat(e);if(void 0!==Yg[e])return Yg[e]}return parseFloat(e)})),r===o&&n.push(1),s=a||void 0===n[l]?1:n[l],n=n.slice(0,l);}else e.length>10&&/[0-9](?:\s|\/)/.test(e)&&(n=e.match(/([0-9]+)/g).map((function(e){return parseFloat(e)})),i=e.match(/([a-z])/gi).join("").toLowerCase());else isNaN(e)?Array.isArray(e)||e.length?(n=[e[0],e[1],e[2]],i="rgb",s=4===e.length?e[3]:1):e instanceof Object&&(null!=e.r||null!=e.red||null!=e.R?(i="rgb",n=[e.r||e.red||e.R||0,e.g||e.green||e.G||0,e.b||e.blue||e.B||0]):(i="hsl",n=[e.h||e.hue||e.H||0,e.s||e.saturation||e.S||0,e.l||e.lightness||e.L||e.b||e.brightness]),s=e.a||e.alpha||e.opacity||1,null!=e.opacity&&(s/=100)):(i="rgb",n=[e>>>16,(65280&e)>>>8,255&e]);return {space:i,values:n,alpha:s}}const ef=Qg,tf={};for(const e of Object.keys(ef))tf[ef[e]]=e;const nf={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};var sf=nf;for(const e of Object.keys(nf)){if(!("channels"in nf[e]))throw new Error("missing channels property: "+e);if(!("labels"in nf[e]))throw new Error("missing channel labels property: "+e);if(nf[e].labels.length!==nf[e].channels)throw new Error("channel and label counts mismatch: "+e);const{channels:t,labels:i}=nf[e];delete nf[e].channels,delete nf[e].labels,Object.defineProperty(nf[e],"channels",{value:t}),Object.defineProperty(nf[e],"labels",{value:i});}function of(e,t){return (e[0]-t[0])**2+(e[1]-t[1])**2+(e[2]-t[2])**2}nf.rgb.hsl=function(e){const t=e[0]/255,i=e[1]/255,n=e[2]/255,s=Math.min(t,i,n),o=Math.max(t,i,n),r=o-s;let a,l;o===s?a=0:t===o?a=(i-n)/r:i===o?a=2+(n-t)/r:n===o&&(a=4+(t-i)/r),a=Math.min(60*a,360),a<0&&(a+=360);const c=(s+o)/2;return l=o===s?0:c<=.5?r/(o+s):r/(2-o-s),[a,100*l,100*c]},nf.rgb.hsv=function(e){let t,i,n,s,o;const r=e[0]/255,a=e[1]/255,l=e[2]/255,c=Math.max(r,a,l),d=c-Math.min(r,a,l),u=function(e){return (c-e)/6/d+.5};return 0===d?(s=0,o=0):(o=d/c,t=u(r),i=u(a),n=u(l),r===c?s=n-i:a===c?s=1/3+t-n:l===c&&(s=2/3+i-t),s<0?s+=1:s>1&&(s-=1)),[360*s,100*o,100*c]},nf.rgb.hwb=function(e){const t=e[0],i=e[1];let n=e[2];const s=nf.rgb.hsl(e)[0],o=1/255*Math.min(t,Math.min(i,n));return n=1-1/255*Math.max(t,Math.max(i,n)),[s,100*o,100*n]},nf.rgb.cmyk=function(e){const t=e[0]/255,i=e[1]/255,n=e[2]/255,s=Math.min(1-t,1-i,1-n);return [100*((1-t-s)/(1-s)||0),100*((1-i-s)/(1-s)||0),100*((1-n-s)/(1-s)||0),100*s]},nf.rgb.keyword=function(e){const t=tf[e];if(t)return t;let i,n=1/0;for(const t of Object.keys(ef)){const s=of(e,ef[t]);s.04045?((t+.055)/1.055)**2.4:t/12.92,i=i>.04045?((i+.055)/1.055)**2.4:i/12.92,n=n>.04045?((n+.055)/1.055)**2.4:n/12.92;return [100*(.4124*t+.3576*i+.1805*n),100*(.2126*t+.7152*i+.0722*n),100*(.0193*t+.1192*i+.9505*n)]},nf.rgb.lab=function(e){const t=nf.rgb.xyz(e);let i=t[0],n=t[1],s=t[2];i/=95.047,n/=100,s/=108.883,i=i>.008856?i**(1/3):7.787*i+16/116,n=n>.008856?n**(1/3):7.787*n+16/116,s=s>.008856?s**(1/3):7.787*s+16/116;return [116*n-16,500*(i-n),200*(n-s)]},nf.hsl.rgb=function(e){const t=e[0]/360,i=e[1]/100,n=e[2]/100;let s,o,r;if(0===i)return r=255*n,[r,r,r];s=n<.5?n*(1+i):n+i-n*i;const a=2*n-s,l=[0,0,0];for(let e=0;e<3;e++)o=t+1/3*-(e-1),o<0&&o++,o>1&&o--,r=6*o<1?a+6*(s-a)*o:2*o<1?s:3*o<2?a+(s-a)*(2/3-o)*6:a,l[e]=255*r;return l},nf.hsl.hsv=function(e){const t=e[0];let i=e[1]/100,n=e[2]/100,s=i;const o=Math.max(n,.01);n*=2,i*=n<=1?n:2-n,s*=o<=1?o:2-o;return [t,100*(0===n?2*s/(o+s):2*i/(n+i)),100*((n+i)/2)]},nf.hsv.rgb=function(e){const t=e[0]/60,i=e[1]/100;let n=e[2]/100;const s=Math.floor(t)%6,o=t-Math.floor(t),r=255*n*(1-i),a=255*n*(1-i*o),l=255*n*(1-i*(1-o));switch(n*=255,s){case 0:return [n,l,r];case 1:return [a,n,r];case 2:return [r,n,l];case 3:return [r,a,n];case 4:return [l,r,n];case 5:return [n,r,a]}},nf.hsv.hsl=function(e){const t=e[0],i=e[1]/100,n=e[2]/100,s=Math.max(n,.01);let o,r;r=(2-i)*n;const a=(2-i)*s;return o=i*s,o/=a<=1?a:2-a,o=o||0,r/=2,[t,100*o,100*r]},nf.hwb.rgb=function(e){const t=e[0]/360;let i=e[1]/100,n=e[2]/100;const s=i+n;let o;s>1&&(i/=s,n/=s);const r=Math.floor(6*t),a=1-n;o=6*t-r,1&r&&(o=1-o);const l=i+o*(a-i);let c,d,u;switch(r){default:case 6:case 0:c=a,d=l,u=i;break;case 1:c=l,d=a,u=i;break;case 2:c=i,d=a,u=l;break;case 3:c=i,d=l,u=a;break;case 4:c=l,d=i,u=a;break;case 5:c=a,d=i,u=l;}return [255*c,255*d,255*u]},nf.cmyk.rgb=function(e){const t=e[0]/100,i=e[1]/100,n=e[2]/100,s=e[3]/100;return [255*(1-Math.min(1,t*(1-s)+s)),255*(1-Math.min(1,i*(1-s)+s)),255*(1-Math.min(1,n*(1-s)+s))]},nf.xyz.rgb=function(e){const t=e[0]/100,i=e[1]/100,n=e[2]/100;let s,o,r;return s=3.2406*t+-1.5372*i+-.4986*n,o=-.9689*t+1.8758*i+.0415*n,r=.0557*t+-.204*i+1.057*n,s=s>.0031308?1.055*s**(1/2.4)-.055:12.92*s,o=o>.0031308?1.055*o**(1/2.4)-.055:12.92*o,r=r>.0031308?1.055*r**(1/2.4)-.055:12.92*r,s=Math.min(Math.max(0,s),1),o=Math.min(Math.max(0,o),1),r=Math.min(Math.max(0,r),1),[255*s,255*o,255*r]},nf.xyz.lab=function(e){let t=e[0],i=e[1],n=e[2];t/=95.047,i/=100,n/=108.883,t=t>.008856?t**(1/3):7.787*t+16/116,i=i>.008856?i**(1/3):7.787*i+16/116,n=n>.008856?n**(1/3):7.787*n+16/116;return [116*i-16,500*(t-i),200*(i-n)]},nf.lab.xyz=function(e){let t,i,n;i=(e[0]+16)/116,t=e[1]/500+i,n=i-e[2]/200;const s=i**3,o=t**3,r=n**3;return i=s>.008856?s:(i-16/116)/7.787,t=o>.008856?o:(t-16/116)/7.787,n=r>.008856?r:(n-16/116)/7.787,t*=95.047,i*=100,n*=108.883,[t,i,n]},nf.lab.lch=function(e){const t=e[0],i=e[1],n=e[2];let s;s=360*Math.atan2(n,i)/2/Math.PI,s<0&&(s+=360);return [t,Math.sqrt(i*i+n*n),s]},nf.lch.lab=function(e){const t=e[0],i=e[1],n=e[2]/360*2*Math.PI;return [t,i*Math.cos(n),i*Math.sin(n)]},nf.rgb.ansi16=function(e,t=null){const[i,n,s]=e;let o=null===t?nf.rgb.hsv(e)[2]:t;if(o=Math.round(o/50),0===o)return 30;let r=30+(Math.round(s/255)<<2|Math.round(n/255)<<1|Math.round(i/255));return 2===o&&(r+=60),r},nf.hsv.ansi16=function(e){return nf.rgb.ansi16(nf.hsv.rgb(e),e[2])},nf.rgb.ansi256=function(e){const t=e[0],i=e[1],n=e[2];if(t===i&&i===n)return t<8?16:t>248?231:Math.round((t-8)/247*24)+232;return 16+36*Math.round(t/255*5)+6*Math.round(i/255*5)+Math.round(n/255*5)},nf.ansi16.rgb=function(e){let t=e%10;if(0===t||7===t)return e>50&&(t+=3.5),t=t/10.5*255,[t,t,t];const i=.5*(1+~~(e>50));return [(1&t)*i*255,(t>>1&1)*i*255,(t>>2&1)*i*255]},nf.ansi256.rgb=function(e){if(e>=232){const t=10*(e-232)+8;return [t,t,t]}let t;e-=16;return [Math.floor(e/36)/5*255,Math.floor((t=e%36)/6)/5*255,t%6/5*255]},nf.rgb.hex=function(e){const t=(((255&Math.round(e[0]))<<16)+((255&Math.round(e[1]))<<8)+(255&Math.round(e[2]))).toString(16).toUpperCase();return "000000".substring(t.length)+t},nf.hex.rgb=function(e){const t=e.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!t)return [0,0,0];let i=t[0];3===t[0].length&&(i=i.split("").map((e=>e+e)).join(""));const n=parseInt(i,16);return [n>>16&255,n>>8&255,255&n]},nf.rgb.hcg=function(e){const t=e[0]/255,i=e[1]/255,n=e[2]/255,s=Math.max(Math.max(t,i),n),o=Math.min(Math.min(t,i),n),r=s-o;let a,l;return a=r<1?o/(1-r):0,l=r<=0?0:s===t?(i-n)/r%6:s===i?2+(n-t)/r:4+(t-i)/r,l/=6,l%=1,[360*l,100*r,100*a]},nf.hsl.hcg=function(e){const t=e[1]/100,i=e[2]/100,n=i<.5?2*t*i:2*t*(1-i);let s=0;return n<1&&(s=(i-.5*n)/(1-n)),[e[0],100*n,100*s]},nf.hsv.hcg=function(e){const t=e[1]/100,i=e[2]/100,n=t*i;let s=0;return n<1&&(s=(i-n)/(1-n)),[e[0],100*n,100*s]},nf.hcg.rgb=function(e){const t=e[0]/360,i=e[1]/100,n=e[2]/100;if(0===i)return [255*n,255*n,255*n];const s=[0,0,0],o=t%1*6,r=o%1,a=1-r;let l=0;switch(Math.floor(o)){case 0:s[0]=1,s[1]=r,s[2]=0;break;case 1:s[0]=a,s[1]=1,s[2]=0;break;case 2:s[0]=0,s[1]=1,s[2]=r;break;case 3:s[0]=0,s[1]=a,s[2]=1;break;case 4:s[0]=r,s[1]=0,s[2]=1;break;default:s[0]=1,s[1]=0,s[2]=a;}return l=(1-i)*n,[255*(i*s[0]+l),255*(i*s[1]+l),255*(i*s[2]+l)]},nf.hcg.hsv=function(e){const t=e[1]/100,i=t+e[2]/100*(1-t);let n=0;return i>0&&(n=t/i),[e[0],100*n,100*i]},nf.hcg.hsl=function(e){const t=e[1]/100,i=e[2]/100*(1-t)+.5*t;let n=0;return i>0&&i<.5?n=t/(2*i):i>=.5&&i<1&&(n=t/(2*(1-i))),[e[0],100*n,100*i]},nf.hcg.hwb=function(e){const t=e[1]/100,i=t+e[2]/100*(1-t);return [e[0],100*(i-t),100*(1-i)]},nf.hwb.hcg=function(e){const t=e[1]/100,i=1-e[2]/100,n=i-t;let s=0;return n<1&&(s=(i-n)/(1-n)),[e[0],100*n,100*s]},nf.apple.rgb=function(e){return [e[0]/65535*255,e[1]/65535*255,e[2]/65535*255]},nf.rgb.apple=function(e){return [e[0]/255*65535,e[1]/255*65535,e[2]/255*65535]},nf.gray.rgb=function(e){return [e[0]/100*255,e[0]/100*255,e[0]/100*255]},nf.gray.hsl=function(e){return [0,0,e[0]]},nf.gray.hsv=nf.gray.hsl,nf.gray.hwb=function(e){return [0,100,e[0]]},nf.gray.cmyk=function(e){return [0,0,0,e[0]]},nf.gray.lab=function(e){return [e[0],0,0]},nf.gray.hex=function(e){const t=255&Math.round(e[0]/100*255),i=((t<<16)+(t<<8)+t).toString(16).toUpperCase();return "000000".substring(i.length)+i},nf.rgb.gray=function(e){return [(e[0]+e[1]+e[2])/3/255*100]};const rf=sf;function af(e){const t=function(){const e={},t=Object.keys(rf);for(let i=t.length,n=0;n{hf[e]={},Object.defineProperty(hf[e],"channels",{value:df[e].channels}),Object.defineProperty(hf[e],"labels",{value:df[e].labels});const t=uf(e);Object.keys(t).forEach((i=>{const n=t[i];hf[e][i]=function(e){const t=function(...t){const i=t[0];if(null==i)return i;i.length>1&&(t=i);const n=e(t);if("object"==typeof n)for(let e=n.length,t=0;t1&&(t=i),e(t))};return "conversion"in e&&(t.conversion=e.conversion),t}(n);}));}));var mf=e({__proto__:null,default:hf},[hf]);function gf(e,t){if(!e)return "";const i=ff(e);if(!i)return "";if(i.space===t)return e;if(n=i,!Object.keys(mf).includes(n.space))return "";var n;const s=mf[i.space][t];if(!s)return "";return function(e,t){switch(t){case"hex":return `#${e}`;case"rgb":return `rgb( ${e[0]}, ${e[1]}, ${e[2]} )`;case"hsl":return `hsl( ${e[0]}, ${e[1]}%, ${e[2]}% )`;case"hwb":return `hwb( ${e[0]}, ${e[1]}, ${e[2]} )`;case"lab":return `lab( ${e[0]}% ${e[1]} ${e[2]} )`;case"lch":return `lch( ${e[0]}% ${e[1]} ${e[2]} )`;default:return ""}}(s("hex"===i.space?i.hexValue:i.values),t)}function ff(e){if(e.startsWith("#")){const t=Xg(e);return {space:"hex",values:t.values,hexValue:e,alpha:t.alpha}}const t=Xg(e);return t.space?t:null}class pf extends lg{fieldView;labelView;statusView;fieldWrapperChildren;constructor(e,t){super(e);const i=`ck-labeled-field-view-${k()}`,n=`ck-labeled-field-view-status-${k()}`;this.fieldView=t(this,i,n),this.set("label",void 0),this.set("isEnabled",!0),this.set("isEmpty",!0),this.set("isFocused",!1),this.set("errorText",null),this.set("infoText",null),this.set("class",void 0),this.set("placeholder",void 0),this.labelView=this._createLabelView(i),this.statusView=this._createStatusView(n),this.fieldWrapperChildren=this.createCollection([this.fieldView,this.labelView]),this.bind("_statusText").to(this,"errorText",this,"infoText",((e,t)=>e||t));const s=this.bindTemplate;this.setTemplate({tag:"div",attributes:{class:["ck","ck-labeled-field-view",s.to("class"),s.if("isEnabled","ck-disabled",(e=>!e)),s.if("isEmpty","ck-labeled-field-view_empty"),s.if("isFocused","ck-labeled-field-view_focused"),s.if("placeholder","ck-labeled-field-view_placeholder"),s.if("errorText","ck-error")]},children:[{tag:"div",attributes:{class:["ck","ck-labeled-field-view__input-wrapper"]},children:this.fieldWrapperChildren},this.statusView]});}_createLabelView(e){const t=new Og(this.locale);return t.for=e,t.bind("text").to(this,"label"),t}_createStatusView(e){const t=new lg(this.locale),i=this.bindTemplate;return t.setTemplate({tag:"div",attributes:{class:["ck","ck-labeled-field-view__status",i.if("errorText","ck-labeled-field-view__status_error"),i.if("_statusText","ck-hidden",(e=>!e))],id:e,role:i.if("errorText","alert")},children:[{text:i.to("_statusText")}]}),t}focus(e){this.fieldView.focus(e);}}class bf extends lg{focusTracker;constructor(e){super(e),this.set("value",void 0),this.set("id",void 0),this.set("placeholder",void 0),this.set("tabIndex",void 0),this.set("isReadOnly",!1),this.set("hasError",!1),this.set("ariaDescribedById",void 0),this.set("ariaLabel",void 0),this.focusTracker=new _r,this.bind("isFocused").to(this.focusTracker),this.set("isEmpty",!0);const t=this.bindTemplate;this.setTemplate({tag:"input",attributes:{class:["ck","ck-input",t.if("isFocused","ck-input_focused"),t.if("isEmpty","ck-input-text_empty"),t.if("hasError","ck-error")],id:t.to("id"),placeholder:t.to("placeholder"),tabindex:t.to("tabIndex"),readonly:t.to("isReadOnly"),"aria-invalid":t.if("hasError",!0),"aria-describedby":t.to("ariaDescribedById"),"aria-label":t.to("ariaLabel")},on:{input:t.to(((...e)=>{this.fire("input",...e),this._updateIsEmpty();})),change:t.to(this._updateIsEmpty.bind(this))}});}render(){super.render(),this.focusTracker.add(this.element),this._setDomElementValue(this.value),this._updateIsEmpty(),this.on("change:value",((e,t,i)=>{this._setDomElementValue(i),this._updateIsEmpty();}));}destroy(){super.destroy(),this.focusTracker.destroy();}select(){this.element.select();}focus(){this.element.focus();}reset(){this.value=this.element.value="",this._updateIsEmpty();}_updateIsEmpty(){this.isEmpty=!this.element.value;}_setDomElementValue(e){this.element.value=e||0===e?e:"";}}class wf extends bf{constructor(e){super(e),this.set("inputMode","text");const t=this.bindTemplate;this.extendTemplate({attributes:{inputmode:t.to("inputMode")}});}}class _f extends wf{constructor(e){super(e),this.extendTemplate({attributes:{type:"text",class:["ck-input-text"]}});}}class vf extends wf{constructor(e,{min:t,max:i,step:n}={}){super(e);const s=this.bindTemplate;this.set("min",t),this.set("max",i),this.set("step",n),this.extendTemplate({attributes:{type:"number",class:["ck-input-number"],min:s.to("min"),max:s.to("max"),step:s.to("step")}});}}class yf extends bf{_resizeObserver;_isUpdateAutoGrowHeightPending=!1;constructor(e){super(e);const t=Oo("px");this.set("minRows",2),this.set("maxRows",5),this.set("_height",null),this.set("resize","none"),this._resizeObserver=null,this.on("change:minRows",this._validateMinMaxRows.bind(this)),this.on("change:maxRows",this._validateMinMaxRows.bind(this));const i=this.bindTemplate;this.template.tag="textarea",this.extendTemplate({attributes:{class:["ck-textarea"],style:{height:i.to("_height",(e=>e?t(e):null)),resize:i.to("resize")},rows:i.to("minRows")}});}render(){super.render();let e=!1;this.on("input",(()=>{this._updateAutoGrowHeight(!0),this.fire("update");})),this.on("change:value",(()=>{i.window.requestAnimationFrame((()=>{No(this.element)?(this._updateAutoGrowHeight(),this.fire("update")):this._isUpdateAutoGrowHeightPending=!0;}));})),this._resizeObserver=new Vo(this.element,(t=>{const n=!!t.contentRect.width&&!!t.contentRect.height;!e&&n&&this._isUpdateAutoGrowHeightPending&&i.window.requestAnimationFrame((()=>{this._updateAutoGrowHeight(),this.fire("update");})),e=n;}));}destroy(){this._resizeObserver&&this._resizeObserver.destroy();}reset(){super.reset(),this._updateAutoGrowHeight(),this.fire("update");}_updateAutoGrowHeight(e){const t=this.element;if(!t.offsetParent)return void(this._isUpdateAutoGrowHeightPending=!0);this._isUpdateAutoGrowHeightPending=!1;const i=kf(t,"1"),n=kf(t,t.value),s=i.ownerDocument.defaultView.getComputedStyle(i),o=parseFloat(s.paddingTop)+parseFloat(s.paddingBottom),r=vo(i),a=parseFloat(s.lineHeight),l=r.top+r.bottom,c=new Eo(i).height,d=Math.round((n.scrollHeight-o)/a),u=this.maxRows*a+o+l,h=1===d?c:this.minRows*a+o+l;this._height=Math.min(Math.max(Math.max(d,this.minRows)*a+o+l,h),u),e&&(t.scrollTop=t.scrollHeight),i.remove(),n.remove();}_validateMinMaxRows(){if(this.minRows>this.maxRows)throw new A("ui-textarea-view-min-rows-greater-than-max-rows",{textareaView:this,minRows:this.minRows,maxRows:this.maxRows})}}function kf(e,t){const i=e.cloneNode();return i.style.position="absolute",i.style.top="-99999px",i.style.left="-99999px",i.style.height="auto",i.style.overflow="hidden",i.style.width=e.ownerDocument.defaultView.getComputedStyle(e).width,i.tabIndex=-1,i.rows=1,i.value=t,e.parentNode.insertBefore(i,e),i}class Cf extends lg{children;constructor(e){super(e);const t=this.bindTemplate;this.set("isVisible",!1),this.set("position","se"),this.children=this.createCollection(),this.setTemplate({tag:"div",attributes:{class:["ck","ck-reset","ck-dropdown__panel",t.to("position",(e=>`ck-dropdown__panel_${e}`)),t.if("isVisible","ck-dropdown__panel-visible")],tabindex:"-1"},children:this.children,on:{selectstart:t.to((e=>{"input"!==e.target.tagName.toLocaleLowerCase()&&e.preventDefault();}))}});}focus(){if(this.children.length){const e=this.children.first;"function"==typeof e.focus?e.focus():E("ui-dropdown-panel-focus-child-missing-focus",{childView:this.children.first,dropdownPanel:this});}}focusLast(){if(this.children.length){const e=this.children.last;"function"==typeof e.focusLast?e.focusLast():e.focus();}}}class xf extends lg{buttonView;panelView;focusTracker;keystrokes;listView;toolbarView;menuView;constructor(e,t,i){super(e);const n=this.bindTemplate;this.buttonView=t,this.panelView=i,this.set("isOpen",!1),this.set("isEnabled",!0),this.set("class",void 0),this.set("id",void 0),this.set("panelPosition","auto"),this.panelView.bind("isVisible").to(this,"isOpen"),this.keystrokes=new Cr,this.focusTracker=new _r,this.setTemplate({tag:"div",attributes:{class:["ck","ck-dropdown",n.to("class"),n.if("isEnabled","ck-disabled",(e=>!e))],id:n.to("id"),"aria-describedby":n.to("ariaDescribedById")},children:[t,i]}),t.extendTemplate({attributes:{class:["ck-dropdown__button"],"data-cke-tooltip-disabled":n.to("isOpen")}});}render(){super.render(),this.focusTracker.add(this.buttonView.element),this.focusTracker.add(this.panelView.element),this.listenTo(this.buttonView,"open",(()=>{this.isOpen=!this.isOpen;})),this.on("change:isOpen",((e,t,i)=>{if(i)if("auto"===this.panelPosition){const e=xf._getOptimalPosition({element:this.panelView.element,target:this.buttonView.element,fitInViewport:!0,positions:this._panelPositions});this.panelView.position=e?e.name:this._panelPositions[0].name;}else this.panelView.position=this.panelPosition;})),this.keystrokes.listenTo(this.element);const e=(e,t)=>{this.isOpen&&(this.isOpen=!1,t());};this.keystrokes.set("arrowdown",((e,t)=>{this.buttonView.isEnabled&&!this.isOpen&&(this.isOpen=!0,t());})),this.keystrokes.set("arrowright",((e,t)=>{this.isOpen&&t();})),this.keystrokes.set("arrowleft",e),this.keystrokes.set("esc",e);}focus(){this.buttonView.focus();}get _panelPositions(){const{south:e,north:t,southEast:i,southWest:n,northEast:s,northWest:o,southMiddleEast:r,southMiddleWest:a,northMiddleEast:l,northMiddleWest:c}=xf.defaultPanelPositions;return "rtl"!==this.locale.uiLanguageDirection?[i,n,r,a,e,s,o,l,c,t]:[n,i,a,r,e,o,s,c,l,t]}static defaultPanelPositions={south:(e,t)=>({top:e.bottom,left:e.left-(t.width-e.width)/2,name:"s"}),southEast:e=>({top:e.bottom,left:e.left,name:"se"}),southWest:(e,t)=>({top:e.bottom,left:e.left-t.width+e.width,name:"sw"}),southMiddleEast:(e,t)=>({top:e.bottom,left:e.left-(t.width-e.width)/4,name:"sme"}),southMiddleWest:(e,t)=>({top:e.bottom,left:e.left-3*(t.width-e.width)/4,name:"smw"}),north:(e,t)=>({top:e.top-t.height,left:e.left-(t.width-e.width)/2,name:"n"}),northEast:(e,t)=>({top:e.top-t.height,left:e.left,name:"ne"}),northWest:(e,t)=>({top:e.top-t.height,left:e.left-t.width+e.width,name:"nw"}),northMiddleEast:(e,t)=>({top:e.top-t.height,left:e.left-(t.width-e.width)/4,name:"nme"}),northMiddleWest:(e,t)=>({top:e.top-t.height,left:e.left-3*(t.width-e.width)/4,name:"nmw"})};static _getOptimalPosition=Do}class Af extends pg{arrowView;constructor(e){super(e),this.arrowView=this._createArrowView(),this.extendTemplate({attributes:{"aria-haspopup":!0,"aria-expanded":this.bindTemplate.to("isOn",(e=>String(e)))}}),this.delegate("execute").to(this,"open");}render(){super.render(),this.children.add(this.arrowView);}_createArrowView(){const e=new gg;return e.content=Wg,e.extendTemplate({attributes:{class:"ck-dropdown__arrow"}}),e}}class Ef extends pg{id;constructor(e,t,i){super(e),this.id=t,this.set({withText:!0,withKeystroke:!0,tooltip:!1,role:"menuitem",label:i}),this.extendTemplate({attributes:{class:["ck-dropdown-menu-list__nested-menu__item__button"]}});}}class Tf extends Ig{arrowView;constructor(e){super(e);const t=this.bindTemplate;this.set({withText:!0,role:"menuitem"}),this.arrowView=this._createArrowView(),this.extendTemplate({attributes:{class:["ck-dropdown-menu-list__nested-menu__button"],"aria-haspopup":!0,"aria-expanded":this.bindTemplate.to("isOn",(e=>String(e))),"data-cke-tooltip-disabled":t.to("isOn")},on:{mouseenter:t.to("mouseenter")}});}render(){super.render(),this.children.add(this.arrowView);}_createArrowView(){const e=new gg;return e.content=Wg,e.extendTemplate({attributes:{class:"ck-dropdown-menu-list__nested-menu__button__arrow"}}),e}}class Pf extends lg{children;constructor(e){super(e);const t=this.bindTemplate;this.set("isVisible",!0),this.children=this.createCollection(),this.setTemplate({tag:"li",attributes:{class:["ck","ck-list__item",t.if("isVisible","ck-hidden",(e=>!e))],role:"presentation"},children:this.children});}focus(){this.children.first&&this.children.first.focus();}}class Sf extends lg{constructor(e){super(e),this.setTemplate({tag:"li",attributes:{class:["ck","ck-list__separator"]}});}}class If extends lg{labelView;items;children;constructor(e,t=new Og){super(e);const i=this.bindTemplate,n=new Vf(e);this.set({label:"",isVisible:!0}),this.labelView=t,this.labelView.bind("text").to(this,"label"),this.children=this.createCollection(),this.children.addMany([this.labelView,n]),n.set({role:"group",ariaLabelledBy:t.id}),n.focusTracker.destroy(),n.keystrokes.destroy(),this.items=n.items,this.setTemplate({tag:"li",attributes:{role:"presentation",class:["ck","ck-list__group",i.if("isVisible","ck-hidden",(e=>!e))]},children:this.children});}focus(){if(this.items){const e=this.items.find((e=>!(e instanceof Sf)));e&&e.focus();}}}class Vf extends lg{focusables;items;focusTracker;keystrokes;_focusCycler;_listItemGroupToChangeListeners=new WeakMap;constructor(e){super(e);const t=this.bindTemplate;this.focusables=new zm,this.items=this.createCollection(),this.focusTracker=new _r,this.keystrokes=new Cr,this._focusCycler=new _g({focusables:this.focusables,focusTracker:this.focusTracker,keystrokeHandler:this.keystrokes,actions:{focusPrevious:"arrowup",focusNext:"arrowdown"}}),this.set("ariaLabel",void 0),this.set("ariaLabelledBy",void 0),this.set("role",void 0),this.setTemplate({tag:"ul",attributes:{class:["ck","ck-reset","ck-list"],role:t.to("role"),"aria-label":t.to("ariaLabel"),"aria-labelledby":t.to("ariaLabelledBy")},children:this.items});}render(){super.render();for(const e of this.items)e instanceof If?this._registerFocusableItemsGroup(e):e instanceof Pf&&this._registerFocusableListItem(e);this.items.on("change",((e,t)=>{for(const e of t.removed)e instanceof If?this._deregisterFocusableItemsGroup(e):e instanceof Pf&&this._deregisterFocusableListItem(e);for(const e of Array.from(t.added).reverse())e instanceof If?this._registerFocusableItemsGroup(e,t.index):this._registerFocusableListItem(e,t.index);})),this.keystrokes.listenTo(this.element);}destroy(){super.destroy(),this.focusTracker.destroy(),this.keystrokes.destroy();}focus(){this._focusCycler.focusFirst();}focusFirst(){this._focusCycler.focusFirst();}focusLast(){this._focusCycler.focusLast();}_registerFocusableListItem(e,t){this.focusTracker.add(e.element),this.focusables.add(e,t);}_deregisterFocusableListItem(e){this.focusTracker.remove(e.element),this.focusables.remove(e);}_getOnGroupItemsChangeCallback(e){return (t,i)=>{for(const e of i.removed)this._deregisterFocusableListItem(e);for(const t of Array.from(i.added).reverse())this._registerFocusableListItem(t,this.items.getIndex(e)+i.index);}}_registerFocusableItemsGroup(e,t){Array.from(e.items).forEach(((e,i)=>{const n=void 0!==t?t+i:void 0;this._registerFocusableListItem(e,n);}));const i=this._getOnGroupItemsChangeCallback(e);this._listItemGroupToChangeListeners.set(e,i),e.items.on("change",i);}_deregisterFocusableItemsGroup(e){for(const t of e.items)this._deregisterFocusableListItem(t);e.items.off("change",this._listItemGroupToChangeListeners.get(e)),this._listItemGroupToChangeListeners.delete(e);}}class Rf extends Vf{constructor(e){super(e);const t=this.bindTemplate;this.role="menu",this.set("isVisible",!0),this.extendTemplate({attributes:{class:["ck-dropdown-menu-list",t.if("isVisible","ck-hidden",(e=>!e))]}});}}const Of={eastSouth:e=>({top:e.top,left:e.right-5,name:"es"}),eastNorth:(e,t)=>({top:e.top-t.height+e.height,left:e.right-5,name:"en"}),westSouth:(e,t)=>({top:e.top,left:e.left-t.width+5,name:"ws"}),westNorth:(e,t)=>({top:e.top-t.height+e.height,left:e.left-t.width+5,name:"wn"})};class Bf extends Pf{childView;constructor(e,t,i){super(e);const n=this.bindTemplate;this.childView=i,this.children.add(i),this.extendTemplate({attributes:{class:["ck-dropdown-menu-list__nested-menu__item"]},on:{mouseenter:n.to("mouseenter")}}),t&&(this.delegate("mouseenter").to(t),i instanceof Ef&&i.delegate("execute").to(t));}}const Mf={toggleMenusAndFocusItemsOnHover(e){e.on("menu:mouseenter",(t=>{const[i]=t.path;t.source.focus();for(const n of e.menus){const e=i instanceof Bf&&i.childView===n;n.isOpen=(t.path.includes(n)||e)&&n.isEnabled;}}));},closeMenuWhenAnotherOnTheSameLevelOpens(e){e.on("menu:change:isOpen",((t,i,n)=>{if(!n)return;const s=t.source;for(const t of e.menus)s.parentMenuView===t.parentMenuView&&s!==t&&(t.isOpen=!1);}));}},Lf={openOnArrowRightKey(e){const t="rtl"===e.locale.uiLanguageDirection?"arrowleft":"arrowright";e.keystrokes.set(t,((t,i)=>{e.focusTracker.focusedElement===e.buttonView.element&&e.isEnabled&&(e.isOpen||(e.isOpen=!0),e.panelView.focus(),i());}));},openOnButtonClick(e){e.buttonView.on("execute",(()=>{e.isEnabled&&(e.isOpen=!0);}));},openAndFocusOnEnterKeyPress(e){e.keystrokes.set("enter",((t,i)=>{e.focusTracker.focusedElement===e.buttonView.element&&(e.isOpen=!0,e.panelView.focus(),i());}));},closeOnArrowLeftKey(e){const t="rtl"===e.locale.uiLanguageDirection?"arrowright":"arrowleft";e.keystrokes.set(t,((t,i)=>{e.isOpen&&(e.focus(),e.isOpen=!1,i());}));},closeOnEscKey(e){e.keystrokes.set("esc",((t,i)=>{e.isOpen&&(e.focus(),e.isOpen=!1,i());}));},closeOnParentClose(e,t){t.on("change:isOpen",((i,n,s)=>{s||i.source!==t||(e.isOpen=!1);}));}},Ff=Oo("px"),Nf={top:-99999,left:-99999,name:"arrowless",config:{withArrow:!1}};class Df extends lg{content;_pinWhenIsVisibleCallback;_resizeObserver;constructor(e){super(e);const t=this.bindTemplate;this.set("top",0),this.set("left",0),this.set("position","arrow_nw"),this.set("isVisible",!1),this.set("withArrow",!0),this.set("class",void 0),this._pinWhenIsVisibleCallback=null,this._resizeObserver=null,this.content=this.createCollection(),this.setTemplate({tag:"div",attributes:{class:["ck","ck-balloon-panel",t.to("position",(e=>`ck-balloon-panel_${e}`)),t.if("isVisible","ck-balloon-panel_visible"),t.if("withArrow","ck-balloon-panel_with-arrow"),t.to("class")],style:{top:t.to("top",Ff),left:t.to("left",Ff)}},children:this.content});}destroy(){this.hide(),super.destroy();}show(){this.isVisible=!0;}hide(){this.isVisible=!1;}attachTo(e){const t=zf(e.target);if(t&&!No(t))return !1;this.show();const n=Df.defaultPositions,s=Object.assign({},{element:this.element,positions:[n.southArrowNorth,n.southArrowNorthMiddleWest,n.southArrowNorthMiddleEast,n.southArrowNorthWest,n.southArrowNorthEast,n.northArrowSouth,n.northArrowSouthMiddleWest,n.northArrowSouthMiddleEast,n.northArrowSouthWest,n.northArrowSouthEast,n.viewportStickyNorth],limiter:i.document.body,fitInViewport:!0},e),o=Df._getOptimalPosition(s)||Nf,r=parseInt(o.left),a=parseInt(o.top),l=o.name,c=o.config||{},{withArrow:d=!0}=c;return this.top=a,this.left=r,this.position=l,this.withArrow=d,!0}pin(e){this.unpin(),this._startPinning(e)&&(this._pinWhenIsVisibleCallback=()=>{this.isVisible?this._startPinning(e):this._stopPinning();},this.listenTo(this,"change:isVisible",this._pinWhenIsVisibleCallback));}unpin(){this._pinWhenIsVisibleCallback&&(this._stopPinning(),this.stopListening(this,"change:isVisible",this._pinWhenIsVisibleCallback),this._pinWhenIsVisibleCallback=null,this.hide());}_startPinning(e){if(!this.attachTo(e))return !1;let t=zf(e.target);const n=e.limiter?zf(e.limiter):i.document.body;if(this.listenTo(i.document,"scroll",((i,s)=>{const o=s.target,r=t&&o.contains(t),a=n&&o.contains(n);!r&&!a&&t&&n||this.attachTo(e);}),{useCapture:!0}),this.listenTo(i.window,"resize",(()=>{this.attachTo(e);})),!this._resizeObserver&&(t&&ko(t)&&(t=t.parentElement),t)){const e=()=>{No(t)||this.unpin();};this._resizeObserver=new Vo(t,e);}return !0}_stopPinning(){this.stopListening(i.document,"scroll"),this.stopListening(i.window,"resize"),this._resizeObserver&&(this._resizeObserver.destroy(),this._resizeObserver=null);}static generatePositions(e={}){const{sideOffset:t=Df.arrowSideOffset,heightOffset:i=Df.arrowHeightOffset,stickyVerticalOffset:n=Df.stickyVerticalOffset,config:s}=e;return {northWestArrowSouthWest:(e,i)=>({top:o(e,i),left:e.left-t,name:"arrow_sw",...s&&{config:s}}),northWestArrowSouthMiddleWest:(e,i)=>({top:o(e,i),left:e.left-.25*i.width-t,name:"arrow_smw",...s&&{config:s}}),northWestArrowSouth:(e,t)=>({top:o(e,t),left:e.left-t.width/2,name:"arrow_s",...s&&{config:s}}),northWestArrowSouthMiddleEast:(e,i)=>({top:o(e,i),left:e.left-.75*i.width+t,name:"arrow_sme",...s&&{config:s}}),northWestArrowSouthEast:(e,i)=>({top:o(e,i),left:e.left-i.width+t,name:"arrow_se",...s&&{config:s}}),northArrowSouthWest:(e,i)=>({top:o(e,i),left:e.left+e.width/2-t,name:"arrow_sw",...s&&{config:s}}),northArrowSouthMiddleWest:(e,i)=>({top:o(e,i),left:e.left+e.width/2-.25*i.width-t,name:"arrow_smw",...s&&{config:s}}),northArrowSouth:(e,t)=>({top:o(e,t),left:e.left+e.width/2-t.width/2,name:"arrow_s",...s&&{config:s}}),northArrowSouthMiddleEast:(e,i)=>({top:o(e,i),left:e.left+e.width/2-.75*i.width+t,name:"arrow_sme",...s&&{config:s}}),northArrowSouthEast:(e,i)=>({top:o(e,i),left:e.left+e.width/2-i.width+t,name:"arrow_se",...s&&{config:s}}),northEastArrowSouthWest:(e,i)=>({top:o(e,i),left:e.right-t,name:"arrow_sw",...s&&{config:s}}),northEastArrowSouthMiddleWest:(e,i)=>({top:o(e,i),left:e.right-.25*i.width-t,name:"arrow_smw",...s&&{config:s}}),northEastArrowSouth:(e,t)=>({top:o(e,t),left:e.right-t.width/2,name:"arrow_s",...s&&{config:s}}),northEastArrowSouthMiddleEast:(e,i)=>({top:o(e,i),left:e.right-.75*i.width+t,name:"arrow_sme",...s&&{config:s}}),northEastArrowSouthEast:(e,i)=>({top:o(e,i),left:e.right-i.width+t,name:"arrow_se",...s&&{config:s}}),southWestArrowNorthWest:e=>({top:r(e),left:e.left-t,name:"arrow_nw",...s&&{config:s}}),southWestArrowNorthMiddleWest:(e,i)=>({top:r(e),left:e.left-.25*i.width-t,name:"arrow_nmw",...s&&{config:s}}),southWestArrowNorth:(e,t)=>({top:r(e),left:e.left-t.width/2,name:"arrow_n",...s&&{config:s}}),southWestArrowNorthMiddleEast:(e,i)=>({top:r(e),left:e.left-.75*i.width+t,name:"arrow_nme",...s&&{config:s}}),southWestArrowNorthEast:(e,i)=>({top:r(e),left:e.left-i.width+t,name:"arrow_ne",...s&&{config:s}}),southArrowNorthWest:e=>({top:r(e),left:e.left+e.width/2-t,name:"arrow_nw",...s&&{config:s}}),southArrowNorthMiddleWest:(e,i)=>({top:r(e),left:e.left+e.width/2-.25*i.width-t,name:"arrow_nmw",...s&&{config:s}}),southArrowNorth:(e,t)=>({top:r(e),left:e.left+e.width/2-t.width/2,name:"arrow_n",...s&&{config:s}}),southArrowNorthMiddleEast:(e,i)=>({top:r(e),left:e.left+e.width/2-.75*i.width+t,name:"arrow_nme",...s&&{config:s}}),southArrowNorthEast:(e,i)=>({top:r(e),left:e.left+e.width/2-i.width+t,name:"arrow_ne",...s&&{config:s}}),southEastArrowNorthWest:e=>({top:r(e),left:e.right-t,name:"arrow_nw",...s&&{config:s}}),southEastArrowNorthMiddleWest:(e,i)=>({top:r(e),left:e.right-.25*i.width-t,name:"arrow_nmw",...s&&{config:s}}),southEastArrowNorth:(e,t)=>({top:r(e),left:e.right-t.width/2,name:"arrow_n",...s&&{config:s}}),southEastArrowNorthMiddleEast:(e,i)=>({top:r(e),left:e.right-.75*i.width+t,name:"arrow_nme",...s&&{config:s}}),southEastArrowNorthEast:(e,i)=>({top:r(e),left:e.right-i.width+t,name:"arrow_ne",...s&&{config:s}}),westArrowEast:(e,t)=>({top:e.top+e.height/2-t.height/2,left:e.left-t.width-i,name:"arrow_e",...s&&{config:s}}),eastArrowWest:(e,t)=>({top:e.top+e.height/2-t.height/2,left:e.right+i,name:"arrow_w",...s&&{config:s}}),viewportStickyNorth:(e,t,i,o)=>{const r=o||i;return e.getIntersection(r)?r.height-e.height>n?null:{top:r.top+n,left:e.left+e.width/2-t.width/2,name:"arrowless",config:{withArrow:!1,...s}}:null}};function o(e,t){return e.top-t.height-i}function r(e){return e.bottom+i}}static arrowSideOffset=25;static arrowHeightOffset=10;static stickyVerticalOffset=20;static _getOptimalPosition=Do;static defaultPositions=Df.generatePositions()}function zf(e){return Ms(e)?e:Co(e)?e.commonAncestorContainer:"function"==typeof e?zf(e()):null}class Hf extends Df{constructor(e){super(e);const t=this.bindTemplate;this.set({isVisible:!1,position:"se",class:null,top:0,left:0}),this.extendTemplate({tag:"div",attributes:{class:["ck-reset","ck-dropdown-menu__nested-menu__panel"],tabindex:"-1"},on:{selectstart:t.to((e=>{"input"!==e.target.tagName.toLocaleLowerCase()&&e.preventDefault();}))}});}focus(e=1){const{content:t}=this;t.length&&(1===e?t.first.focus():t.last.focus());}}class $f extends lg{static DELEGATED_EVENTS=["mouseenter","execute","change:isOpen"];id;buttonView;panelView;listView;focusTracker;keystrokes;_bodyCollection;constructor(e,t,i,n,s){super(e),this._bodyCollection=t,this.id=i,this.set({isOpen:!1,isEnabled:!0,panelPosition:"w",class:void 0,parentMenuView:null}),this.keystrokes=new Cr,this.focusTracker=new _r,this.buttonView=new Tf(e),this.buttonView.delegate("mouseenter").to(this),this.buttonView.bind("isOn","isEnabled").to(this,"isOpen","isEnabled"),this.buttonView.label=n,this.panelView=new Hf(e),this.panelView.isVisible=!0,this.listView=new Rf(e),this.listView.bind("ariaLabel").to(this.buttonView,"label"),this.panelView.content.add(this.listView);const o=this.bindTemplate;this.setTemplate({tag:"div",attributes:{class:["ck","ck-dropdown-menu-list__nested-menu",o.to("class"),o.if("isEnabled","ck-disabled",(e=>!e))],role:"presentation"},children:[this.buttonView]}),this.parentMenuView=s,this.parentMenuView&&this._handleParentMenuView(),this._attachBehaviors();}get _panelPositions(){const{westSouth:e,eastSouth:t,westNorth:i,eastNorth:n}=Of;return "ltr"===this.locale.uiLanguageDirection?[t,n,e,i]:[e,i,t,n]}render(){super.render(),this.panelView.render(),this.focusTracker.add(this.buttonView.element),this.focusTracker.add(this.panelView.element),this.focusTracker.add(this.listView),this.keystrokes.listenTo(this.element),this._mountPanelOnOpen();}destroy(){this._removePanelFromBody(),this.panelView.destroy(),super.destroy();}focus(){this.buttonView.focus();}_handleParentMenuView(){this.delegate(...$f.DELEGATED_EVENTS).to(this.parentMenuView),Lf.closeOnParentClose(this,this.parentMenuView);}_attachBehaviors(){Lf.openOnButtonClick(this),Lf.openAndFocusOnEnterKeyPress(this),Lf.openOnArrowRightKey(this),Lf.closeOnEscKey(this),Lf.closeOnArrowLeftKey(this);}_mountPanelOnOpen(){const{panelView:e}=this;this.on("change:isOpen",((t,i,n)=>{t.source===this&&(n||!this._bodyCollection.has(e)?n&&!this._bodyCollection.has(e)&&this._addPanelToBody():this._removePanelFromBody());}));}_removePanelFromBody(){const{panelView:e,keystrokes:t}=this;this._bodyCollection.has(e)&&(this._bodyCollection.remove(e),t.stopListening(e.element));}_addPanelToBody(){const{panelView:e,buttonView:t,keystrokes:n}=this;this._bodyCollection.has(e)||(this._bodyCollection.add(e),n.listenTo(e.element),e.pin({positions:this._panelPositions,limiter:i.document.body,element:e.element,target:t.element,fitInViewport:!0}));}}class Uf extends Rf{_definition;_cachedMenus=[];_cachedButtons=[];_bodyCollection;constructor(e,t,i){super(e),this._bodyCollection=t,this._definition=i,this.set("menuPanelClass",void 0);}get menus(){return Array.from(this._cachedMenus.values())}get buttons(){return Array.from(this._cachedButtons.values())}render(){this._createStructure(this._definition,null),super.render(),Mf.toggleMenusAndFocusItemsOnHover(this),Mf.closeMenuWhenAnotherOnTheSameLevelOpens(this);}closeMenus(){this.menus.forEach((e=>{e.isOpen=!1;}));}_createStructure(e,t){const i=[];for(const n of e){let e;"menu"in n?(e=new $f(this.locale,this._bodyCollection,n.id,n.menu,t),e.panelView.bind("class").to(this,"menuPanelClass"),t||e.delegate(...$f.DELEGATED_EVENTS).to(this,(e=>`menu:${e}`)),this._cachedMenus.push(e),this._createStructure(n.children,e)):(e=new Ef(this.locale,n.id,n.label),t||e.delegate("execute").to(this,"menu:execute"),this._cachedButtons.push(e));const s=new Bf(this.locale,t,e);t||s.delegate("mouseenter").to(this,"menu:mouseenter"),i.push(s);}(t?t.listView:this).items.addMany(i);}}class Wf extends lg{constructor(e){super(e),this.setTemplate({tag:"span",attributes:{class:["ck","ck-toolbar__separator"]}});}}class jf extends lg{constructor(e){super(e),this.setTemplate({tag:"span",attributes:{class:["ck","ck-toolbar__line-break"]}});}}function qf(e){if(Array.isArray(e))return {items:e,removeItems:[]};const t={items:[],removeItems:[]};return e?{...t,...e}:t}const Gf=(()=>({alignLeft:vm.alignLeft,bold:vm.bold,importExport:vm.importExport,paragraph:vm.paragraph,plus:vm.plus,text:vm.text,threeVerticalDots:vm.threeVerticalDots,pilcrow:vm.pilcrow,dragIndicator:vm.dragIndicator}))();class Kf extends lg{options;items;focusTracker;keystrokes;itemsView;children;focusables;_focusCycler;_behavior;constructor(e,t){super(e);const i=this.bindTemplate,n=this.t;this.options=t||{},this.set("ariaLabel",n("Editor toolbar")),this.set("maxWidth","auto"),this.items=this.createCollection(),this.focusTracker=new _r,this.keystrokes=new Cr,this.set("class",void 0),this.set("isCompact",!1),this.itemsView=new Zf(e),this.children=this.createCollection(),this.children.add(this.itemsView),this.focusables=this.createCollection();const s="rtl"===e.uiLanguageDirection;this._focusCycler=new _g({focusables:this.focusables,focusTracker:this.focusTracker,keystrokeHandler:this.keystrokes,actions:{focusPrevious:[s?"arrowright":"arrowleft","arrowup"],focusNext:[s?"arrowleft":"arrowright","arrowdown"]}});const o=["ck","ck-toolbar",i.to("class"),i.if("isCompact","ck-toolbar_compact")];var r;this.options.shouldGroupWhenFull&&this.options.isFloating&&o.push("ck-toolbar_floating"),this.setTemplate({tag:"div",attributes:{class:o,role:"toolbar","aria-label":i.to("ariaLabel"),style:{maxWidth:i.to("maxWidth")},tabindex:-1},children:this.children,on:{mousedown:(r=this,r.bindTemplate.to((e=>{e.target===r.element&&e.preventDefault();})))}}),this._behavior=this.options.shouldGroupWhenFull?new Qf(this):new Jf(this);}render(){super.render(),this.focusTracker.add(this.element);for(const e of this.items)this.focusTracker.add(e);this.items.on("add",((e,t)=>{this.focusTracker.add(t);})),this.items.on("remove",((e,t)=>{this.focusTracker.remove(t);})),this.keystrokes.listenTo(this.element),this._behavior.render(this);}destroy(){return this._behavior.destroy(),this.focusTracker.destroy(),this.keystrokes.destroy(),super.destroy()}focus(){this._focusCycler.focusFirst();}focusLast(){this._focusCycler.focusLast();}fillFromConfig(e,t,i){this.items.addMany(this._buildItemsFromConfig(e,t,i));}_buildItemsFromConfig(e,t,i){const n=qf(e),s=i||n.removeItems;return this._cleanItemsConfiguration(n.items,t,s).map((e=>ue(e)?this._createNestedToolbarDropdown(e,t,s):"|"===e?new Wf:"-"===e?new jf:t.create(e))).filter((e=>!!e))}_cleanItemsConfiguration(e,t,i){const n=e.filter(((e,n,s)=>"|"===e||-1===i.indexOf(e)&&("-"===e?!this.options.shouldGroupWhenFull||(E("toolbarview-line-break-ignored-when-grouping-items",s),!1):!(!ue(e)&&!t.has(e))||(E("toolbarview-item-unavailable",{item:e}),!1))));return this._cleanSeparatorsAndLineBreaks(n)}_cleanSeparatorsAndLineBreaks(e){const t=e=>"-"!==e&&"|"!==e,i=e.length,n=e.findIndex(t);if(-1===n)return [];const s=i-e.slice().reverse().findIndex(t);return e.slice(n,s).filter(((e,i,n)=>{if(t(e))return !0;return !(i>0&&n[i-1]===e)}))}_createNestedToolbarDropdown(e,t,i){let{label:n,icon:s,items:o,tooltip:r=!0,withText:a=!1}=e;if(o=this._cleanItemsConfiguration(o,t,i),!o.length)return null;const l=Xf(this.locale);return n||E("toolbarview-nested-toolbar-dropdown-missing-label",e),l.class="ck-toolbar__nested-toolbar-dropdown",l.buttonView.set({label:n,tooltip:r,withText:!!a}),!1!==s?l.buttonView.icon=Gf[s]||s||vm.threeVerticalDots:l.buttonView.withText=!0,ip(l,(()=>l.toolbarView._buildItemsFromConfig(o,t,i))),l}}class Zf extends lg{children;constructor(e){super(e),this.children=this.createCollection(),this.setTemplate({tag:"div",attributes:{class:["ck","ck-toolbar__items"]},children:this.children});}}class Jf{constructor(e){const t=e.bindTemplate;e.set("isVertical",!1),e.itemsView.children.bindTo(e.items).using((e=>e)),e.focusables.bindTo(e.items).using((e=>yg(e)?e:null)),e.extendTemplate({attributes:{class:[t.if("isVertical","ck-toolbar_vertical")]}});}render(){}destroy(){}}class Qf{view;viewChildren;viewFocusables;viewItemsView;viewFocusTracker;viewLocale;ungroupedItems;groupedItems;groupedItemsDropdown;resizeObserver=null;cachedPadding=null;shouldUpdateGroupingOnNextResize=!1;viewElement;constructor(e){this.view=e,this.viewChildren=e.children,this.viewFocusables=e.focusables,this.viewItemsView=e.itemsView,this.viewFocusTracker=e.focusTracker,this.viewLocale=e.locale,this.ungroupedItems=e.createCollection(),this.groupedItems=e.createCollection(),this.groupedItemsDropdown=this._createGroupedItemsDropdown(),e.itemsView.children.bindTo(this.ungroupedItems).using((e=>e)),this.ungroupedItems.on("change",this._updateFocusCyclableItems.bind(this)),e.children.on("change",this._updateFocusCyclableItems.bind(this)),e.items.on("change",((e,t)=>{const i=t.index,n=Array.from(t.added);for(const e of t.removed)i>=this.ungroupedItems.length?this.groupedItems.remove(e):this.ungroupedItems.remove(e);for(let e=i;ethis.ungroupedItems.length?this.groupedItems.add(t,e-this.ungroupedItems.length):this.ungroupedItems.add(t,e);}this._updateGrouping();})),e.extendTemplate({attributes:{class:["ck-toolbar_grouping"]}});}render(e){this.viewElement=e.element,this._enableGroupingOnResize(),this._enableGroupingOnMaxWidthChange(e);}destroy(){this.groupedItemsDropdown.destroy(),this.resizeObserver.destroy();}_updateGrouping(){if(!this.viewElement.ownerDocument.body.contains(this.viewElement))return;if(!No(this.viewElement))return void(this.shouldUpdateGroupingOnNextResize=!0);const e=this.groupedItems.length;let t;for(;this._areItemsOverflowing;)this._groupLastItem(),t=!0;if(!t&&this.groupedItems.length){for(;this.groupedItems.length&&!this._areItemsOverflowing;)this._ungroupFirstItem();this._areItemsOverflowing&&this._groupLastItem();}this.groupedItems.length!==e&&this.view.fire("groupedItemsUpdate");}get _areItemsOverflowing(){if(!this.ungroupedItems.length)return !1;const e=this.viewElement,t=this.viewLocale.uiLanguageDirection,n=new Eo(e.lastChild),s=new Eo(e);if(!this.cachedPadding){const n=i.window.getComputedStyle(e),s="ltr"===t?"paddingRight":"paddingLeft";this.cachedPadding=Number.parseInt(n[s]);}return "ltr"===t?n.right>s.right-this.cachedPadding:n.left{e&&e===t.contentRect.width&&!this.shouldUpdateGroupingOnNextResize||(this.shouldUpdateGroupingOnNextResize=!1,this._updateGrouping(),e=t.contentRect.width);})),this._updateGrouping();}_enableGroupingOnMaxWidthChange(e){e.on("change:maxWidth",(()=>{this._updateGrouping();}));}_groupLastItem(){this.groupedItems.length||(this.viewChildren.add(new Wf),this.viewChildren.add(this.groupedItemsDropdown),this.viewFocusTracker.add(this.groupedItemsDropdown.element)),this.groupedItems.add(this.ungroupedItems.remove(this.ungroupedItems.last),0);}_ungroupFirstItem(){this.ungroupedItems.add(this.groupedItems.remove(this.groupedItems.first)),this.groupedItems.length||(this.viewChildren.remove(this.groupedItemsDropdown),this.viewChildren.remove(this.viewChildren.last),this.viewFocusTracker.remove(this.groupedItemsDropdown.element));}_createGroupedItemsDropdown(){const e=this.viewLocale,t=e.t,i=Xf(e);return i.class="ck-toolbar__grouped-dropdown",i.panelPosition="ltr"===e.uiLanguageDirection?"sw":"se",ip(i,this.groupedItems),i.buttonView.set({label:t("Show more items"),tooltip:!0,tooltipPosition:"rtl"===e.uiLanguageDirection?"se":"sw",icon:vm.threeVerticalDots}),i}_updateFocusCyclableItems(){this.viewFocusables.clear(),this.ungroupedItems.map((e=>{yg(e)&&this.viewFocusables.add(e);})),this.groupedItems.length&&this.viewFocusables.add(this.groupedItemsDropdown);}}class Yf extends lg{children;actionView;arrowView;keystrokes;focusTracker;constructor(e,t){super(e);const i=this.bindTemplate;this.set("class",void 0),this.set("labelStyle",void 0),this.set("icon",void 0),this.set("isEnabled",!0),this.set("isOn",!1),this.set("isToggleable",!1),this.set("isVisible",!0),this.set("keystroke",void 0),this.set("withKeystroke",!1),this.set("label",void 0),this.set("tabindex",-1),this.set("tooltip",!1),this.set("tooltipPosition","s"),this.set("type","button"),this.set("withText",!1),this.children=this.createCollection(),this.actionView=this._createActionView(t),this.arrowView=this._createArrowView(),this.keystrokes=new Cr,this.focusTracker=new _r,this.setTemplate({tag:"div",attributes:{class:["ck","ck-splitbutton",i.to("class"),i.if("isVisible","ck-hidden",(e=>!e)),this.arrowView.bindTemplate.if("isOn","ck-splitbutton_open")]},children:this.children});}render(){super.render(),this.children.add(this.actionView),this.children.add(this.arrowView),this.focusTracker.add(this.actionView.element),this.focusTracker.add(this.arrowView.element),this.keystrokes.listenTo(this.element),this.keystrokes.set("arrowright",((e,t)=>{this.focusTracker.focusedElement===this.actionView.element&&(this.arrowView.focus(),t());})),this.keystrokes.set("arrowleft",((e,t)=>{this.focusTracker.focusedElement===this.arrowView.element&&(this.actionView.focus(),t());}));}destroy(){super.destroy(),this.focusTracker.destroy(),this.keystrokes.destroy();}focus(){this.actionView.focus();}_createActionView(e){const t=e||new pg;return e||t.bind("icon","isEnabled","isOn","isToggleable","keystroke","label","tabindex","tooltip","tooltipPosition","type","withText").to(this),t.extendTemplate({attributes:{class:"ck-splitbutton__action"}}),t.delegate("execute").to(this),t}_createArrowView(){const e=new pg,t=e.bindTemplate;return e.icon=Wg,e.extendTemplate({attributes:{class:["ck-splitbutton__arrow"],"data-cke-tooltip-disabled":t.to("isOn"),"aria-haspopup":!0,"aria-expanded":t.to("isOn",(e=>String(e)))}}),e.bind("isEnabled").to(this),e.bind("label").to(this),e.bind("tooltip").to(this),e.delegate("execute").to(this,"open"),e}}function Xf(e,t=Af){const n="function"==typeof t?new t(e):t,s=new Cf(e),o=new xf(e,n,s);return n.bind("isEnabled").to(o),n instanceof Yf?n.arrowView.bind("isOn").to(o,"isOpen"):n.bind("isOn").to(o,"isOpen"),function(e){((function(e){cg({emitter:e,activator:()=>e.isRendered&&e.isOpen,callback:()=>{e.isOpen=!1;},contextElements:()=>[e.element,...ap(e.focusTracker).filter((t=>!e.element.contains(t)))]});}))(e),function(e){e.on("execute",(t=>{t.source instanceof Dg||(e.isOpen=!1);}));}(e),function(e){e.focusTracker.on("change:isFocused",((t,i,n)=>{!n&&e.isOpen&&(e.isOpen=!1);}));}(e),function(e){e.keystrokes.set("arrowdown",((t,i)=>{e.isOpen&&(e.panelView.focus(),i());})),e.keystrokes.set("arrowup",((t,i)=>{e.isOpen&&(e.panelView.focusLast(),i());}));}(e),function(e){e.on("change:isOpen",((t,n,s)=>{if(s)return;e.focusTracker.elements.some((e=>e.contains(i.document.activeElement)))&&e.buttonView.focus();}));}(e),function(e){e.on("change:isOpen",((t,i,n)=>{n&&e.panelView.focus();}),{priority:"low"});}(e);}(o),o}function ep(e,t,i,n={}){e.menuView=new Uf(e.locale,t,i),e.focusTracker.add(e.menuView),e.isOpen?tp(e,n):e.once("change:isOpen",(()=>{tp(e,n);}),{priority:"highest"});}function tp(e,t){const i=e.menuView,n=e.locale.t;i.delegate("menu:execute").to(e,"execute"),i.listenTo(e,"change:isOpen",((e,t,n)=>{n||i.closeMenus();}),{priority:"low"}),e.panelView.children.add(i);for(const t of i.menus)e.focusTracker.add(t);i.ariaLabel=t.ariaLabel||n("Dropdown menu");}function ip(e,t,i={}){e.extendTemplate({attributes:{class:["ck-toolbar-dropdown"]}}),e.isOpen?np(e,t,i):e.once("change:isOpen",(()=>np(e,t,i)),{priority:"highest"}),i.enableActiveItemFocusOnDropdownOpen&&rp(e,(()=>e.toolbarView.items.find((e=>e.isOn))));}function np(e,t,i){const n=e.locale,s=n.t,o=e.toolbarView=new Kf(n),r="function"==typeof t?t():t;o.ariaLabel=i.ariaLabel||s("Dropdown toolbar"),i.maxWidth&&(o.maxWidth=i.maxWidth),i.class&&(o.class=i.class),i.isCompact&&(o.isCompact=i.isCompact),i.isVertical&&(o.isVertical=!0),r instanceof zm?o.items.bindTo(r).using((e=>e)):o.items.addMany(r),e.panelView.children.add(o),e.focusTracker.add(o),o.items.delegate("execute").to(e);}function sp(e,t,i={}){e.isOpen?op(e,t,i):e.once("change:isOpen",(()=>op(e,t,i)),{priority:"highest"}),rp(e,(()=>e.listView.items.find((e=>e instanceof Pf&&e.children.first.isOn))));}function op(e,t,i){const n=e.locale,s=e.listView=new Vf(n),o="function"==typeof t?t():t;s.ariaLabel=i.ariaLabel,s.role=i.role,lp(e,s.items,o,n),e.panelView.children.add(s),s.items.delegate("execute").to(e);}function rp(e,t){e.on("change:isOpen",(()=>{if(!e.isOpen)return;const i=t();i&&("function"==typeof i.focus?i.focus():E("ui-dropdown-focus-child-on-open-child-missing-focus",{view:i}));}),{priority:C.low-10});}function ap(e){return [...e.elements,...e.externalViews.flatMap((e=>ap(e.focusTracker)))]}function lp(e,t,i,n){t.on("change",(()=>{const e=[...t].reduce(((e,t)=>(t instanceof Pf&&t.children.first instanceof Ig&&e.push(t.children.first),e)),[]),i=e.some((e=>e.isToggleable));e.forEach((e=>{e.hasCheckSpace=i;}));})),t.bindTo(i).using((t=>{if("separator"===t.type)return new Sf(n);if("group"===t.type){const i=new If(n);return i.set({label:t.label}),lp(e,i.items,t.items,n),i.items.delegate("execute").to(e),i}if("button"===t.type||"switchbutton"===t.type){const e="menuitemcheckbox"===t.model.role||"menuitemradio"===t.model.role,i=new Pf(n);let s;return "button"===t.type?(s=new Ig(n),s.set({isToggleable:e})):s=new Dg(n),s.bind(...Object.keys(t.model)).to(t.model),s.delegate("execute").to(i),i.children.add(s),i}return null}));}const cp=(e,t,i)=>{const n=new _f(e.locale);return n.set({id:t,ariaDescribedById:i}),n.bind("isReadOnly").to(e,"isEnabled",(e=>!e)),n.bind("hasError").to(e,"errorText",(e=>!!e)),n.on("input",(()=>{e.errorText=null;})),e.bind("isEmpty","isFocused","placeholder").to(n),n},dp=(e,t,i)=>{const n=new vf(e.locale);return n.set({id:t,ariaDescribedById:i,inputMode:"numeric"}),n.bind("isReadOnly").to(e,"isEnabled",(e=>!e)),n.bind("hasError").to(e,"errorText",(e=>!!e)),n.on("input",(()=>{e.errorText=null;})),e.bind("isEmpty","isFocused","placeholder").to(n),n},up=(e,t,i)=>{const n=new yf(e.locale);return n.set({id:t,ariaDescribedById:i}),n.bind("isReadOnly").to(e,"isEnabled",(e=>!e)),n.bind("hasError").to(e,"errorText",(e=>!!e)),n.on("input",(()=>{e.errorText=null;})),e.bind("isEmpty","isFocused","placeholder").to(n),n},hp=(e,t,i)=>{const n=Xf(e.locale);return n.set({id:t,ariaDescribedById:i}),n.bind("isEnabled").to(e),n},mp=(e,t=0,i=1)=>e>i?i:eMath.round(i*e)/i,fp=e=>("#"===e[0]&&(e=e.substring(1)),e.length<6?{r:parseInt(e[0]+e[0],16),g:parseInt(e[1]+e[1],16),b:parseInt(e[2]+e[2],16),a:4===e.length?gp(parseInt(e[3]+e[3],16)/255,2):1}:{r:parseInt(e.substring(0,2),16),g:parseInt(e.substring(2,4),16),b:parseInt(e.substring(4,6),16),a:8===e.length?gp(parseInt(e.substring(6,8),16)/255,2):1}),pp=e=>{const{h:t,s:i,l:n}=(({h:e,s:t,v:i,a:n})=>{const s=(200-t)*i/100;return {h:gp(e),s:gp(s>0&&s<200?t*i/100/(s<=100?s:200-s)*100:0),l:gp(s/2),a:gp(n,2)}})(e);return `hsl(${t}, ${i}%, ${n}%)`},bp=({h:e,s:t,v:i,a:n})=>{e=e/360*6,t/=100,i/=100;const s=Math.floor(e),o=i*(1-t),r=i*(1-(e-s)*t),a=i*(1-(1-e+s)*t),l=s%6;return {r:gp(255*[i,r,o,o,a,i][l]),g:gp(255*[a,i,i,r,o,o][l]),b:gp(255*[o,o,a,i,i,r][l]),a:gp(n,2)}},wp=e=>{const t=e.toString(16);return t.length<2?"0"+t:t},_p=({r:e,g:t,b:i,a:n})=>{const s=n<1?wp(gp(255*n)):"";return "#"+wp(e)+wp(t)+wp(i)+s},vp=({r:e,g:t,b:i,a:n})=>{const s=Math.max(e,t,i),o=s-Math.min(e,t,i),r=o?s===e?(t-i)/o:s===t?2+(i-e)/o:4+(e-t)/o:0;return {h:gp(60*(r<0?r+6:r)),s:gp(s?o/s*100:0),v:gp(s/255*100),a:n}},yp=(e,t)=>{if(e===t)return !0;for(const i in e)if(e[i]!==t[i])return !1;return !0},kp={},Cp=e=>{let t=kp[e];return t||(t=document.createElement("template"),t.innerHTML=e,kp[e]=t),t},xp=(e,t,i)=>{e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:i}));};let Ap=!1;const Ep=e=>"touches"in e,Tp=(e,t)=>{const i=Ep(t)?t.touches[0]:t,n=e.el.getBoundingClientRect();xp(e.el,"move",e.getMove({x:mp((i.pageX-(n.left+window.pageXOffset))/n.width),y:mp((i.pageY-(n.top+window.pageYOffset))/n.height)}));};class Pp{constructor(e,t,i,n){const s=Cp(`
`);e.appendChild(s.content.cloneNode(!0));const o=e.querySelector(`[part=${t}]`);o.addEventListener("mousedown",this),o.addEventListener("touchstart",this),o.addEventListener("keydown",this),this.el=o,this.xy=n,this.nodes=[o.firstChild,o];}set dragging(e){const t=e?document.addEventListener:document.removeEventListener;t(Ap?"touchmove":"mousemove",this),t(Ap?"touchend":"mouseup",this);}handleEvent(e){switch(e.type){case"mousedown":case"touchstart":if(e.preventDefault(),!(e=>!(Ap&&!Ep(e)||(Ap||(Ap=Ep(e)),0)))(e)||!Ap&&0!=e.button)return;this.el.focus(),Tp(this,e),this.dragging=!0;break;case"mousemove":case"touchmove":e.preventDefault(),Tp(this,e);break;case"mouseup":case"touchend":this.dragging=!1;break;case"keydown":((e,t)=>{const i=t.keyCode;i>40||e.xy&&i<37||i<33||(t.preventDefault(),xp(e.el,"move",e.getMove({x:39===i?.01:37===i?-.01:34===i?.05:33===i?-.05:35===i?1:36===i?-1:0,y:40===i?.01:38===i?-.01:0},!0)));})(this,e);}}style(e){e.forEach(((e,t)=>{for(const i in e)this.nodes[t].style.setProperty(i,e[i]);}));}}class Sp extends Pp{constructor(e){super(e,"hue",'aria-label="Hue" aria-valuemin="0" aria-valuemax="360"',!1);}update({h:e}){this.h=e,this.style([{left:e/360*100+"%",color:pp({h:e,s:100,v:100,a:1})}]),this.el.setAttribute("aria-valuenow",`${gp(e)}`);}getMove(e,t){return {h:t?mp(this.h+360*e.x,0,360):360*e.x}}}class Ip extends Pp{constructor(e){super(e,"saturation",'aria-label="Color"',!0);}update(e){this.hsva=e,this.style([{top:100-e.v+"%",left:`${e.s}%`,color:pp(e)},{"background-color":pp({h:e.h,s:100,v:100,a:1})}]),this.el.setAttribute("aria-valuetext",`Saturation ${gp(e.s)}%, Brightness ${gp(e.v)}%`);}getMove(e,t){return {s:t?mp(this.hsva.s+100*e.x,0,100):100*e.x,v:t?mp(this.hsva.v-100*e.y,0,100):Math.round(100-100*e.y)}}}const Vp=Symbol("same"),Rp=Symbol("color"),Op=Symbol("hsva"),Bp=Symbol("update"),Mp=Symbol("parts"),Lp=Symbol("css"),Fp=Symbol("sliders");class Np extends HTMLElement{static get observedAttributes(){return ["color"]}get[Lp](){return [':host{display:flex;flex-direction:column;position:relative;width:200px;height:200px;user-select:none;-webkit-user-select:none;cursor:default}:host([hidden]){display:none!important}[role=slider]{position:relative;touch-action:none;user-select:none;-webkit-user-select:none;outline:0}[role=slider]:last-child{border-radius:0 0 8px 8px}[part$=pointer]{position:absolute;z-index:1;box-sizing:border-box;width:28px;height:28px;display:flex;place-content:center center;transform:translate(-50%,-50%);background-color:#fff;border:2px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.2)}[part$=pointer]::after{content:"";width:100%;height:100%;border-radius:inherit;background-color:currentColor}[role=slider]:focus [part$=pointer]{transform:translate(-50%,-50%) scale(1.1)}',"[part=hue]{flex:0 0 24px;background:linear-gradient(to right,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%)}[part=hue-pointer]{top:50%;z-index:2}","[part=saturation]{flex-grow:1;border-color:transparent;border-bottom:12px solid #000;border-radius:8px 8px 0 0;background-image:linear-gradient(to top,#000,transparent),linear-gradient(to right,#fff,rgba(255,255,255,0));box-shadow:inset 0 0 0 1px rgba(0,0,0,.05)}[part=saturation-pointer]{z-index:3}"]}get[Fp](){return [Ip,Sp]}get color(){return this[Rp]}set color(e){if(!this[Vp](e)){const t=this.colorModel.toHsva(e);this[Bp](t),this[Rp]=e;}}constructor(){super();const e=Cp(``),t=this.attachShadow({mode:"open"});t.appendChild(e.content.cloneNode(!0)),t.addEventListener("move",this),this[Mp]=this[Fp].map((e=>new e(t)));}connectedCallback(){if(this.hasOwnProperty("color")){const e=this.color;delete this.color,this.color=e;}else this.color||(this.color=this.colorModel.defaultColor);}attributeChangedCallback(e,t,i){const n=this.colorModel.fromAttr(i);this[Vp](n)||(this.color=n);}handleEvent(e){const t=this[Op],i={...t,...e.detail};let n;this[Bp](i),yp(i,t)||this[Vp](n=this.colorModel.fromHsva(i))||(this[Rp]=n,xp(this,"color-changed",{value:n}));}[Vp](e){return this.color&&this.colorModel.equal(e,this.color)}[Bp](e){this[Op]=e,this[Mp].forEach((t=>t.update(e)));}}const Dp={defaultColor:"#000",toHsva:e=>vp(fp(e)),fromHsva:({h:e,s:t,v:i})=>_p(bp({h:e,s:t,v:i,a:1})),equal:(e,t)=>e.toLowerCase()===t.toLowerCase()||yp(fp(e),fp(t)),fromAttr:e=>e};class zp extends Np{get colorModel(){return Dp}}class Hp extends lg{hexInputRow;_debounceColorPickerEvent;_config;constructor(e,t={}){super(e),this.set({color:"",_hexColor:""}),this.hexInputRow=this._createInputRow();const i=this.createCollection();t.hideInput||i.add(this.hexInputRow),this.setTemplate({tag:"div",attributes:{class:["ck","ck-color-picker"],tabindex:-1},children:i}),this._config=t,this._debounceColorPickerEvent=vs((e=>{this.set("color",e),this.fire("colorSelected",{color:this.color});}),150,{leading:!0}),this.on("set:color",((e,t,i)=>{e.return=gf(i,this._config.format||"hsl");})),this.on("change:color",(()=>{this._hexColor=$p(this.color);})),this.on("change:_hexColor",(()=>{document.activeElement!==this.picker&&this.picker.setAttribute("color",this._hexColor),$p(this.color)!=$p(this._hexColor)&&(this.color=this._hexColor);}));}render(){var e,t;if(super.render(),e="hex-color-picker",t=zp,void 0===customElements.get(e)&&customElements.define(e,t),this.picker=i.document.createElement("hex-color-picker"),this.picker.setAttribute("class","hex-color-picker"),this.picker.setAttribute("tabindex","-1"),this._createSlidersView(),this.element){this.hexInputRow.element?this.element.insertBefore(this.picker,this.hexInputRow.element):this.element.appendChild(this.picker);const e=document.createElement("style");e.textContent='[role="slider"]:focus [part$="pointer"] {border: 1px solid #fff;outline: 1px solid var(--ck-color-focus-border);box-shadow: 0 0 0 2px #fff;}',this.picker.shadowRoot.appendChild(e);}this.picker.addEventListener("color-changed",(e=>{const t=e.detail.value;this._debounceColorPickerEvent(t);}));}focus(){if(!this._config.hideInput&&(o.isGecko||o.isiOS||o.isSafari)){this.hexInputRow.children.get(1).focus();}this.slidersView.first.focus();}_createSlidersView(){const e=[...this.picker.shadowRoot.children].filter((e=>"slider"===e.getAttribute("role"))).map((e=>new Up(e)));this.slidersView=this.createCollection(),e.forEach((e=>{this.slidersView.add(e);}));}_createInputRow(){const e=this._createColorInput();return new jp(this.locale,e)}_createColorInput(){const e=new pf(this.locale,cp),{t:t}=this.locale;return e.set({label:t("HEX"),class:"color-picker-hex-input"}),e.fieldView.bind("value").to(this,"_hexColor",(t=>e.isFocused?e.fieldView.value:t.startsWith("#")?t.substring(1):t)),e.fieldView.on("input",(()=>{const t=e.fieldView.element.value;if(t){const e=qp(t);e&&this._debounceColorPickerEvent(e);}})),e}isValid(){const{t:e}=this.locale;return !!this._config.hideInput||(this.resetValidationStatus(),!!this.hexInputRow.getParsedColor()||(this.hexInputRow.inputView.errorText=e('Please enter a valid color (e.g. "ff0000").'),!1))}resetValidationStatus(){this.hexInputRow.inputView.errorText=null;}}function $p(e){let t=function(e){if(!e)return "";const t=ff(e);return t?"hex"===t.space?t.hexValue:gf(e,"hex"):"#000"}(e);return t||(t="#000"),4===t.length&&(t="#"+[t[1],t[1],t[2],t[2],t[3],t[3]].join("")),t.toLowerCase()}class Up extends lg{constructor(e){super(),this.element=e;}focus(){this.element.focus();}}class Wp extends lg{constructor(e){super(e),this.setTemplate({tag:"div",attributes:{class:["ck","ck-color-picker__hash-view"]},children:"#"});}}class jp extends lg{children;inputView;constructor(e,t){super(e),this.inputView=t,this.children=this.createCollection([new Wp,this.inputView]),this.setTemplate({tag:"div",attributes:{class:["ck","ck-color-picker__row"]},children:this.children});}getParsedColor(){return qp(this.inputView.fieldView.element.value)}}function qp(e){if(!e)return null;const t=e.trim().replace(/^#/,"");return [3,4,6,8].includes(t.length)&&/^(([0-9a-fA-F]{2}){3,4}|([0-9a-fA-F]){3,4})$/.test(t)?`#${t}`:null}class Gp extends(Zs(br)){constructor(e){super(e),this.set("isEmpty",!0),this.on("change",(()=>{this.set("isEmpty",0===this.length);}));}add(e,t){return this.find((t=>t.color===e.color))?this:super.add(e,t)}hasColor(e){return !!this.find((t=>t.color===e))}}class Kp extends lg{items;colorDefinitions;focusTracker;columns;documentColors;documentColorsCount;staticColorsGrid;documentColorsGrid;colorPickerButtonView;removeColorButtonView;_focusables;_documentColorsLabel;_removeButtonLabel;_colorPickerLabel;constructor(e,{colors:t,columns:i,removeButtonLabel:n,documentColorsLabel:s,documentColorsCount:o,colorPickerLabel:r,focusTracker:a,focusables:l}){super(e);const c=this.bindTemplate;this.set("isVisible",!0),this.focusTracker=a,this.items=this.createCollection(),this.colorDefinitions=t,this.columns=i,this.documentColors=new Gp,this.documentColorsCount=o,this._focusables=l,this._removeButtonLabel=n,this._colorPickerLabel=r,this._documentColorsLabel=s,this.setTemplate({tag:"div",attributes:{class:["ck-color-grids-fragment",c.if("isVisible","ck-hidden",(e=>!e))]},children:this.items}),this.removeColorButtonView=this._createRemoveColorButton(),this.items.add(this.removeColorButtonView);}updateDocumentColors(e,t){const i=e.document,n=this.documentColorsCount;this.documentColors.clear();for(const s of i.getRoots()){const i=e.createRangeIn(s);for(const e of i.getItems())if(e.is("$textProxy")&&e.hasAttribute(t)&&(this._addColorToDocumentColors(e.getAttribute(t)),this.documentColors.length>=n))return}}updateSelectedColors(){const e=this.documentColorsGrid,t=this.staticColorsGrid,i=this.selectedColor;t.selectedColor=i,e&&(e.selectedColor=i);}render(){if(super.render(),this.staticColorsGrid=this._createStaticColorsGrid(),this.items.add(this.staticColorsGrid),this.documentColorsCount){const e=Hm.bind(this.documentColors,this.documentColors),t=new lg(this.locale);t.setTemplate({tag:"span",attributes:{class:["ck","ck-color-grid__label",e.if("isEmpty","ck-hidden")]},children:[{text:this._documentColorsLabel}]}),this.items.add(t),this.documentColorsGrid=this._createDocumentColorsGrid(),this.items.add(this.documentColorsGrid);}this._createColorPickerButton(),this._addColorSelectorElementsToFocusTracker();}focus(){this.removeColorButtonView.focus();}destroy(){super.destroy();}addColorPickerButton(){this.colorPickerButtonView&&(this.items.add(this.colorPickerButtonView),this.focusTracker.add(this.colorPickerButtonView.element),this._focusables.add(this.colorPickerButtonView));}_addColorSelectorElementsToFocusTracker(){this.focusTracker.add(this.removeColorButtonView.element),this._focusables.add(this.removeColorButtonView),this.staticColorsGrid&&(this.focusTracker.add(this.staticColorsGrid.element),this._focusables.add(this.staticColorsGrid)),this.documentColorsGrid&&(this.focusTracker.add(this.documentColorsGrid.element),this._focusables.add(this.documentColorsGrid));}_createColorPickerButton(){this.colorPickerButtonView=new pg,this.colorPickerButtonView.set({label:this._colorPickerLabel,withText:!0,icon:vm.colorPalette,class:"ck-color-selector__color-picker"}),this.colorPickerButtonView.on("execute",(()=>{this.fire("colorPicker:show");}));}_createRemoveColorButton(){const e=new pg;return e.set({withText:!0,icon:vm.eraser,label:this._removeButtonLabel}),e.class="ck-color-selector__remove-color",e.on("execute",(()=>{this.fire("execute",{value:null,source:"removeColorButton"});})),e.render(),e}_createStaticColorsGrid(){const e=new Jg(this.locale,{colorDefinitions:this.colorDefinitions,columns:this.columns});return e.on("execute",((e,t)=>{this.fire("execute",{value:t.value,source:"staticColorsGrid"});})),e}_createDocumentColorsGrid(){const e=Hm.bind(this.documentColors,this.documentColors),t=new Jg(this.locale,{columns:this.columns});return t.extendTemplate({attributes:{class:e.if("isEmpty","ck-hidden")}}),t.items.bindTo(this.documentColors).using((e=>{const t=new Zg;return t.set({color:e.color,hasBorder:e.options&&e.options.hasBorder}),e.label&&t.set({label:e.label,tooltip:!0}),t.on("execute",(()=>{this.fire("execute",{value:e.color,source:"documentColorsGrid"});})),t})),this.documentColors.on("change:isEmpty",((e,i,n)=>{n&&(t.selectedColor=null);})),t}_addColorToDocumentColors(e){const t=this.colorDefinitions.find((t=>t.color===e));t?this.documentColors.add(Object.assign({},t)):this.documentColors.add({color:e,label:e,options:{hasBorder:!1}});}}class Zp extends lg{items;colorPickerView;saveButtonView;cancelButtonView;actionBarView;focusTracker;keystrokes;_focusables;_colorPickerViewConfig;constructor(e,{focusTracker:t,focusables:i,keystrokes:n,colorPickerViewConfig:s}){super(e),this.items=this.createCollection(),this.focusTracker=t,this.keystrokes=n,this.set("isVisible",!1),this.set("selectedColor",void 0),this._focusables=i,this._colorPickerViewConfig=s;const o=this.bindTemplate,{saveButtonView:r,cancelButtonView:a}=this._createActionButtons();this.saveButtonView=r,this.cancelButtonView=a,this.actionBarView=this._createActionBarView({saveButtonView:r,cancelButtonView:a}),this.setTemplate({tag:"div",attributes:{class:["ck-color-picker-fragment",o.if("isVisible","ck-hidden",(e=>!e))]},children:this.items});}render(){super.render();const e=new Hp(this.locale,{...this._colorPickerViewConfig});this.colorPickerView=e,this.colorPickerView.render(),this.selectedColor&&(e.color=this.selectedColor),this.listenTo(this,"change:selectedColor",((t,i,n)=>{e.color=n;})),this.items.add(this.colorPickerView),this.items.add(this.actionBarView),this._addColorPickersElementsToFocusTracker(),this._stopPropagationOnArrowsKeys(),this._executeOnEnterPress(),this._executeUponColorChange();}destroy(){super.destroy();}focus(){this.colorPickerView.focus();}resetValidationStatus(){this.colorPickerView.resetValidationStatus();}_executeOnEnterPress(){this.keystrokes.set("enter",(e=>{this.isVisible&&this.focusTracker.focusedElement!==this.cancelButtonView.element&&this.colorPickerView.isValid()&&(this.fire("execute",{value:this.selectedColor}),e.stopPropagation(),e.preventDefault());}));}_stopPropagationOnArrowsKeys(){const e=e=>e.stopPropagation();this.keystrokes.set("arrowright",e),this.keystrokes.set("arrowleft",e),this.keystrokes.set("arrowup",e),this.keystrokes.set("arrowdown",e);}_addColorPickersElementsToFocusTracker(){for(const e of this.colorPickerView.slidersView)this.focusTracker.add(e.element),this._focusables.add(e);const e=this.colorPickerView.hexInputRow.children.get(1);e.element&&(this.focusTracker.add(e.element),this._focusables.add(e)),this.focusTracker.add(this.saveButtonView.element),this._focusables.add(this.saveButtonView),this.focusTracker.add(this.cancelButtonView.element),this._focusables.add(this.cancelButtonView);}_createActionBarView({saveButtonView:e,cancelButtonView:t}){const i=new lg,n=this.createCollection();return n.add(e),n.add(t),i.setTemplate({tag:"div",attributes:{class:["ck","ck-color-selector_action-bar"]},children:n}),i}_createActionButtons(){const e=this.locale,t=e.t,i=new pg(e),n=new pg(e);return i.set({icon:vm.check,class:"ck-button-save",type:"button",withText:!1,label:t("Accept")}),n.set({icon:vm.cancel,class:"ck-button-cancel",type:"button",withText:!1,label:t("Cancel")}),i.on("execute",(()=>{this.colorPickerView.isValid()&&this.fire("execute",{source:"colorPickerSaveButton",value:this.selectedColor});})),n.on("execute",(()=>{this.fire("colorPicker:cancel");})),{saveButtonView:i,cancelButtonView:n}}_executeUponColorChange(){this.colorPickerView.on("colorSelected",((e,t)=>{this.fire("execute",{value:t.color,source:"colorPicker"}),this.set("selectedColor",t.color);}));}}class Jp extends lg{focusTracker;keystrokes;items;colorGridsFragmentView;colorPickerFragmentView;_focusCycler;_focusables;_colorPickerViewConfig;constructor(e,{colors:t,columns:i,removeButtonLabel:n,documentColorsLabel:s,documentColorsCount:o,colorPickerLabel:r,colorPickerViewConfig:a}){super(e),this.items=this.createCollection(),this.focusTracker=new _r,this.keystrokes=new Cr,this._focusables=new zm,this._colorPickerViewConfig=a,this._focusCycler=new _g({focusables:this._focusables,focusTracker:this.focusTracker,keystrokeHandler:this.keystrokes,actions:{focusPrevious:"shift + tab",focusNext:"tab"}}),this.colorGridsFragmentView=new Kp(e,{colors:t,columns:i,removeButtonLabel:n,documentColorsLabel:s,documentColorsCount:o,colorPickerLabel:r,focusTracker:this.focusTracker,focusables:this._focusables}),this.colorPickerFragmentView=new Zp(e,{focusables:this._focusables,focusTracker:this.focusTracker,keystrokes:this.keystrokes,colorPickerViewConfig:a}),this.set("_isColorGridsFragmentVisible",!0),this.set("_isColorPickerFragmentVisible",!1),this.set("selectedColor",void 0),this.colorGridsFragmentView.bind("isVisible").to(this,"_isColorGridsFragmentVisible"),this.colorPickerFragmentView.bind("isVisible").to(this,"_isColorPickerFragmentVisible"),this.on("change:selectedColor",((e,t,i)=>{this.colorGridsFragmentView.set("selectedColor",i),this.colorPickerFragmentView.set("selectedColor",i);})),this.colorGridsFragmentView.on("change:selectedColor",((e,t,i)=>{this.set("selectedColor",i);})),this.colorPickerFragmentView.on("change:selectedColor",((e,t,i)=>{this.set("selectedColor",i);})),this.setTemplate({tag:"div",attributes:{class:["ck","ck-color-selector"]},children:this.items});}render(){super.render(),this.keystrokes.listenTo(this.element);}destroy(){super.destroy(),this.focusTracker.destroy(),this.keystrokes.destroy();}appendUI(){this._appendColorGridsFragment(),this._colorPickerViewConfig&&this._appendColorPickerFragment();}showColorPickerFragment(){this.colorPickerFragmentView.colorPickerView&&!this._isColorPickerFragmentVisible&&(this._isColorPickerFragmentVisible=!0,this.colorPickerFragmentView.focus(),this.colorPickerFragmentView.resetValidationStatus(),this._isColorGridsFragmentVisible=!1);}showColorGridsFragment(){this._isColorGridsFragmentVisible||(this._isColorGridsFragmentVisible=!0,this.colorGridsFragmentView.focus(),this._isColorPickerFragmentVisible=!1);}focus(){this._focusCycler.focusFirst();}focusLast(){this._focusCycler.focusLast();}updateDocumentColors(e,t){this.colorGridsFragmentView.updateDocumentColors(e,t);}updateSelectedColors(){this.colorGridsFragmentView.updateSelectedColors();}_appendColorGridsFragment(){this.items.length||(this.items.add(this.colorGridsFragmentView),this.colorGridsFragmentView.delegate("execute").to(this),this.colorGridsFragmentView.delegate("colorPicker:show").to(this));}_appendColorPickerFragment(){2!==this.items.length&&(this.items.add(this.colorPickerFragmentView),this.colorGridsFragmentView.colorPickerButtonView&&this.colorGridsFragmentView.colorPickerButtonView.on("execute",(()=>{this.showColorPickerFragment();})),this.colorGridsFragmentView.addColorPickerButton(),this.colorPickerFragmentView.delegate("execute").to(this),this.colorPickerFragmentView.delegate("colorPicker:cancel").to(this));}}class Qp{editor;_components=new Map;constructor(e){this.editor=e;}*names(){for(const e of this._components.values())yield e.originalName;}add(e,t){this._components.set(Yp(e),{callback:t,originalName:e});}create(e){if(!this.has(e))throw new A("componentfactory-item-missing",this,{name:e});return this._components.get(Yp(e)).callback(this.editor.locale)}has(e){return this._components.has(Yp(e))}}function Yp(e){return String(e).toLowerCase()}const Xp="ck-tooltip";class eb extends(go()){tooltipTextView;balloonPanelView;static defaultBalloonPositions=Df.generatePositions({heightOffset:5,sideOffset:13});_currentElementWithTooltip=null;_currentTooltipPosition=null;_mutationObserver=null;_pinTooltipDebounced;_unpinTooltipDebounced;_watchdogExcluded;static _editors=new Set;static _instance=null;constructor(e){if(super(),eb._editors.add(e),eb._instance)return eb._instance;eb._instance=this,this.tooltipTextView=new lg(e.locale),this.tooltipTextView.set("text",""),this.tooltipTextView.setTemplate({tag:"span",attributes:{class:["ck","ck-tooltip__text"]},children:[{text:this.tooltipTextView.bindTemplate.to("text")}]}),this.balloonPanelView=new Df(e.locale),this.balloonPanelView.class=Xp,this.balloonPanelView.content.add(this.tooltipTextView),this._mutationObserver=function(e){const t=new MutationObserver((()=>{e();}));return {attach(e){t.observe(e,{attributes:!0,attributeFilter:["data-cke-tooltip-text","data-cke-tooltip-position"]});},detach(){t.disconnect();}}}((()=>{this._updateTooltipPosition();})),this._pinTooltipDebounced=vs(this._pinTooltip,600),this._unpinTooltipDebounced=vs(this._unpinTooltip,400),this.listenTo(i.document,"keydown",this._onKeyDown.bind(this),{useCapture:!0}),this.listenTo(i.document,"mouseenter",this._onEnterOrFocus.bind(this),{useCapture:!0}),this.listenTo(i.document,"mouseleave",this._onLeaveOrBlur.bind(this),{useCapture:!0}),this.listenTo(i.document,"focus",this._onEnterOrFocus.bind(this),{useCapture:!0}),this.listenTo(i.document,"blur",this._onLeaveOrBlur.bind(this),{useCapture:!0}),this.listenTo(i.document,"scroll",this._onScroll.bind(this),{useCapture:!0}),this._watchdogExcluded=!0;}destroy(e){const t=e.ui.view&&e.ui.view.body;eb._editors.delete(e),this.stopListening(e.ui),t&&t.has(this.balloonPanelView)&&t.remove(this.balloonPanelView),eb._editors.size||(this._unpinTooltip(),this.balloonPanelView.destroy(),this.stopListening(),eb._instance=null);}static getPositioningFunctions(e){const t=eb.defaultBalloonPositions;return {s:[t.southArrowNorth,t.southArrowNorthEast,t.southArrowNorthWest],n:[t.northArrowSouth],e:[t.eastArrowWest],w:[t.westArrowEast],sw:[t.southArrowNorthEast],se:[t.southArrowNorthWest]}[e]}_onKeyDown(e,t){"Escape"===t.key&&this._currentElementWithTooltip&&(this._unpinTooltip(),t.stopPropagation());}_onEnterOrFocus(e,{target:t}){const i=tb(t);i?i!==this._currentElementWithTooltip&&(this._unpinTooltip(),"focus"!==e.name||i.matches(":hover")?this._pinTooltipDebounced(i,ib(i)):this._pinTooltip(i,ib(i))):"focus"===e.name&&this._unpinTooltip();}_onLeaveOrBlur(e,{target:t,relatedTarget:i}){if("mouseleave"===e.name){if(!Ms(t))return;const e=this.balloonPanelView.element,n=e&&(e===i||e.contains(i)),s=!n&&t===e;if(n)return void this._unpinTooltipDebounced.cancel();if(!s&&this._currentElementWithTooltip&&t!==this._currentElementWithTooltip)return;const o=tb(t),r=tb(i);(s||o&&o!==r)&&this._unpinTooltipDebounced();}else {if(this._currentElementWithTooltip&&t!==this._currentElementWithTooltip)return;this._unpinTooltipDebounced();}}_onScroll(e,{target:t}){this._currentElementWithTooltip&&(t.contains(this.balloonPanelView.element)&&t.contains(this._currentElementWithTooltip)||this._unpinTooltip());}_pinTooltip(e,{text:t,position:i,cssClass:n}){this._unpinTooltip();const s=wr(eb._editors.values()).ui.view.body;s.has(this.balloonPanelView)||s.add(this.balloonPanelView),this.tooltipTextView.text=t,this.balloonPanelView.class=[Xp,n].filter((e=>e)).join(" "),this.balloonPanelView.pin({target:e,positions:eb.getPositioningFunctions(i)}),this._mutationObserver.attach(e);for(const e of eb._editors)this.listenTo(e.ui,"update",this._updateTooltipPosition.bind(this),{priority:"low"});this._currentElementWithTooltip=e,this._currentTooltipPosition=i;}_unpinTooltip(){this._unpinTooltipDebounced.cancel(),this._pinTooltipDebounced.cancel(),this.balloonPanelView.unpin();for(const e of eb._editors)this.stopListening(e.ui,"update");this._currentElementWithTooltip=null,this._currentTooltipPosition=null,this.tooltipTextView.text="",this._mutationObserver.detach();}_updateTooltipPosition(){if(!this._currentElementWithTooltip)return;const e=ib(this._currentElementWithTooltip);No(this._currentElementWithTooltip)&&e.text?this.balloonPanelView.pin({target:this._currentElementWithTooltip,positions:eb.getPositioningFunctions(e.position)}):this._unpinTooltip();}}function tb(e){return Ms(e)?e.closest("[data-cke-tooltip-text]:not([data-cke-tooltip-disabled])"):null}function ib(e){return {text:e.dataset.ckeTooltipText,position:e.dataset.ckeTooltipPosition||"s",cssClass:e.dataset.ckeTooltipClass||""}}class nb extends(go()){editor;_balloonView;_showBalloonThrottled;_lastFocusedEditableElement;constructor(e){super(),this.editor=e,this._balloonView=null,this._lastFocusedEditableElement=null,this._showBalloonThrottled=$s(this._showBalloon.bind(this),50,{leading:!0}),e.on("ready",this._handleEditorReady.bind(this));}destroy(){const e=this._balloonView;e&&(e.unpin(),this._balloonView=null),this._showBalloonThrottled.cancel(),this.stopListening();}_handleEditorReady(){const e=this.editor;(!!e.config.get("ui.poweredBy.forceVisible")||"VALID"!==Ir(e.config.get("licenseKey")))&&e.ui.view&&(e.ui.focusTracker.on("change:isFocused",((e,t,i)=>{this._updateLastFocusedEditableElement(),i?this._showBalloon():this._hideBalloon();})),e.ui.focusTracker.on("change:focusedElement",((e,t,i)=>{this._updateLastFocusedEditableElement(),i&&this._showBalloon();})),e.ui.on("update",(()=>{this._showBalloonThrottled();})));}_createBalloonView(){const e=this.editor,t=this._balloonView=new Df,i=rb(e),n=new sb(e.locale,i.label);t.content.add(n),t.set({class:"ck-powered-by-balloon"}),e.ui.view.body.add(t),this._balloonView=t;}_showBalloon(){if(!this._lastFocusedEditableElement)return;const e=function(e,t){const i=rb(e),n="right"===i.side?function(e,t){return ob(e,t,((e,i)=>e.left+e.width-i.width-t.horizontalOffset))}(t,i):function(e,t){return ob(e,t,(e=>e.left+t.horizontalOffset))}(t,i);return {target:t,positions:[n]}}(this.editor,this._lastFocusedEditableElement);e&&(this._balloonView||this._createBalloonView(),this._balloonView.pin(e));}_hideBalloon(){this._balloonView&&this._balloonView.unpin();}_updateLastFocusedEditableElement(){const e=this.editor,t=e.ui.focusTracker.isFocused,i=e.ui.focusTracker.focusedElement;if(!t||!i)return void(this._lastFocusedEditableElement=null);const n=Array.from(e.ui.getEditableElementsNames()).map((t=>e.ui.getEditableElement(t)));n.includes(i)?this._lastFocusedEditableElement=i:this._lastFocusedEditableElement=n[0];}}class sb extends lg{constructor(e,t){super(e);const i=new gg,n=this.bindTemplate;i.set({content:'\n',isColorInherited:!1}),i.extendTemplate({attributes:{style:{width:"53px",height:"10px"}}}),this.setTemplate({tag:"div",attributes:{class:["ck","ck-powered-by"],"aria-hidden":!0},children:[{tag:"a",attributes:{href:"https://ckeditor.com/powered-by-ckeditor/?utm_source=ckeditor&utm_medium=referral&utm_campaign=701Dn000000hVgmIAE_powered_by_ckeditor_logo",target:"_blank",tabindex:"-1"},children:[...t?[{tag:"span",attributes:{class:["ck","ck-powered-by__label"]},children:[t]}]:[],i],on:{dragstart:n.to((e=>e.preventDefault()))}}]});}}function ob(e,t,i){return (n,s)=>{const o=new Eo(e);if(o.width<350||o.height<50)return null;let r;r="inside"===t.position?o.bottom-s.height:o.bottom-s.height/2,r-=t.verticalOffset;const a=i(o,s),l=n.clone().moveTo(a,r).getIntersection(s.clone().moveTo(a,r)).getVisible();return !l||l.getArea(){for(const e of Object.values(ab))this.announce("",e);}));}announce(e,t=ab.POLITE){const i=this.editor;if(!i.ui.view)return;this.view||(this.view=new cb(i.locale),i.ui.view.body.add(this.view));const{politeness:n,isUnsafeHTML:s}="string"==typeof t?{politeness:t}:t;let o=this.view.regionViews.find((e=>e.politeness===n));o||(o=new db(i,n),this.view.regionViews.add(o)),o.announce({announcement:e,isUnsafeHTML:s});}}class cb extends lg{regionViews;constructor(e){super(e),this.regionViews=this.createCollection(),this.setTemplate({tag:"div",attributes:{class:["ck","ck-aria-live-announcer"]},children:this.regionViews});}}class db extends lg{politeness;_domConverter;_pruneAnnouncementsInterval;constructor(e,t){super(e.locale),this.setTemplate({tag:"div",attributes:{"aria-live":t,"aria-relevant":"additions"},children:[{tag:"ul",attributes:{class:["ck","ck-aria-live-region-list"]}}]}),e.on("destroy",(()=>{null!==this._pruneAnnouncementsInterval&&(clearInterval(this._pruneAnnouncementsInterval),this._pruneAnnouncementsInterval=null);})),this.politeness=t,this._domConverter=e.data.htmlProcessor.domConverter,this._pruneAnnouncementsInterval=setInterval((()=>{this.element&&this._listElement.firstChild&&this._listElement.firstChild.remove();}),5e3);}announce({announcement:e,isUnsafeHTML:t}){if(!e.trim().length)return;const i=document.createElement("li");t?this._domConverter.setContentOf(i,e):i.innerText=e,this._listElement.appendChild(i);}get _listElement(){return this.element.querySelector("ul")}}class ub extends Pf{constructor(e,t){super(e);const i=this.bindTemplate;this.extendTemplate({attributes:{class:["ck-menu-bar__menu__item"]},on:{mouseenter:i.to("mouseenter")}}),this.delegate("mouseenter").to(t);}}const hb={toggleMenusAndFocusItemsOnHover(e){e.on("menu:mouseenter",(t=>{if(e.isFocusBorderEnabled||e.isOpen){if(e.isOpen)for(const i of e.menus){const e=t.path[0],n=e instanceof ub&&e.children.first===i;i.isOpen=(t.path.includes(i)||n)&&i.isEnabled;}t.source.focus();}}));},focusCycleMenusOnArrows(e){const t="rtl"===e.locale.uiLanguageDirection;function i(t,i){const n=e.children.getIndex(t),s=t.isOpen,o=e.children.length,r=e.children.get((n+o+i)%o);t.isOpen=!1,s&&(r.isOpen=!0),r.buttonView.focus();}e.on("menu:arrowright",(e=>{i(e.source,t?-1:1);})),e.on("menu:arrowleft",(e=>{i(e.source,t?1:-1);}));},closeMenusWhenTheBarCloses(e){e.on("change:isOpen",(()=>{e.isOpen||e.menus.forEach((e=>{e.isOpen=!1;}));}));},closeMenuWhenAnotherOnTheSameLevelOpens(e){e.on("menu:change:isOpen",((t,i,n)=>{n&&e.menus.filter((e=>t.source.parentMenuView===e.parentMenuView&&t.source!==e&&e.isOpen)).forEach((e=>{e.isOpen=!1;}));}));},closeOnClickOutside(e){cg({emitter:e,activator:()=>e.isOpen,callback:()=>e.close(),contextElements:()=>e.children.map((e=>e.element))});},enableFocusHighlightOnInteraction(e){let t=!1;e.on("change:isOpen",((i,n,s)=>{s||(t||(e.isFocusBorderEnabled=!1),t=!1);})),e.listenTo(e.element,"keydown",(()=>{t=!0;}),{useCapture:!0}),e.listenTo(e.element,"keyup",(()=>{t=!1;}),{useCapture:!0}),e.listenTo(e.element,"focus",(()=>{t&&(e.isFocusBorderEnabled=!0);}),{useCapture:!0});}},mb={openAndFocusPanelOnArrowDownKey(e){e.keystrokes.set("arrowdown",((t,i)=>{e.focusTracker.focusedElement===e.buttonView.element&&(e.isOpen||(e.isOpen=!0),e.panelView.focus(),i());}));},openOnArrowRightKey(e){const t="rtl"===e.locale.uiLanguageDirection?"arrowleft":"arrowright";e.keystrokes.set(t,((t,i)=>{e.focusTracker.focusedElement===e.buttonView.element&&e.isEnabled&&(e.isOpen||(e.isOpen=!0),e.panelView.focus(),i());}));},openOnButtonClick(e){e.buttonView.on("execute",(()=>{e.isOpen=!0;}));},toggleOnButtonClick(e){e.buttonView.on("execute",(()=>{e.isOpen=!e.isOpen;}));},openAndFocusOnEnterKeyPress(e){e.keystrokes.set("enter",((t,i)=>{e.focusTracker.focusedElement===e.buttonView.element&&(e.isOpen=!0,e.panelView.focus(),i());}));},closeOnArrowLeftKey(e){const t="rtl"===e.locale.uiLanguageDirection?"arrowright":"arrowleft";e.keystrokes.set(t,((t,i)=>{e.isOpen&&(e.isOpen=!1,e.focus(),i());}));},closeOnEscKey(e){e.keystrokes.set("esc",((t,i)=>{e.isOpen&&(e.isOpen=!1,e.focus(),i());}));},closeOnParentClose(e){e.parentMenuView.on("change:isOpen",((t,i,n)=>{n||t.source!==e.parentMenuView||(e.isOpen=!1);}));}},gb={southEast:e=>({top:e.bottom,left:e.left,name:"se"}),southWest:(e,t)=>({top:e.bottom,left:e.left-t.width+e.width,name:"sw"}),northEast:(e,t)=>({top:e.top-t.height,left:e.left,name:"ne"}),northWest:(e,t)=>({top:e.top-t.height,left:e.left-t.width+e.width,name:"nw"}),eastSouth:e=>({top:e.top,left:e.right-5,name:"es"}),eastNorth:(e,t)=>({top:e.top-t.height,left:e.right-5,name:"en"}),westSouth:(e,t)=>({top:e.top,left:e.left-t.width+5,name:"ws"}),westNorth:(e,t)=>({top:e.top-t.height,left:e.left-t.width+5,name:"wn"})},fb=[{menuId:"file",label:"File",groups:[{groupId:"export",items:["menuBar:exportPdf","menuBar:exportWord"]},{groupId:"import",items:["menuBar:importWord"]},{groupId:"revisionHistory",items:["menuBar:revisionHistory"]}]},{menuId:"edit",label:"Edit",groups:[{groupId:"undo",items:["menuBar:undo","menuBar:redo"]},{groupId:"selectAll",items:["menuBar:selectAll"]},{groupId:"findAndReplace",items:["menuBar:findAndReplace"]}]},{menuId:"view",label:"View",groups:[{groupId:"sourceEditing",items:["menuBar:sourceEditing"]},{groupId:"showBlocks",items:["menuBar:showBlocks"]},{groupId:"previewMergeFields",items:["menuBar:previewMergeFields"]},{groupId:"restrictedEditing",items:["menuBar:restrictedEditing"]}]},{menuId:"insert",label:"Insert",groups:[{groupId:"insertMainWidgets",items:["menuBar:insertImage","menuBar:ckbox","menuBar:ckfinder","menuBar:insertTable"]},{groupId:"insertInline",items:["menuBar:link","menuBar:comment","menuBar:insertMergeField"]},{groupId:"insertMinorWidgets",items:["menuBar:mediaEmbed","menuBar:insertTemplate","menuBar:specialCharacters","menuBar:blockQuote","menuBar:codeBlock","menuBar:htmlEmbed"]},{groupId:"insertStructureWidgets",items:["menuBar:horizontalLine","menuBar:pageBreak","menuBar:tableOfContents"]},{groupId:"restrictedEditingException",items:["menuBar:restrictedEditingException"]}]},{menuId:"format",label:"Format",groups:[{groupId:"textAndFont",items:[{menuId:"text",label:"Text",groups:[{groupId:"basicStyles",items:["menuBar:bold","menuBar:italic","menuBar:underline","menuBar:strikethrough","menuBar:superscript","menuBar:subscript","menuBar:code"]},{groupId:"textPartLanguage",items:["menuBar:textPartLanguage"]}]},{menuId:"font",label:"Font",groups:[{groupId:"fontProperties",items:["menuBar:fontSize","menuBar:fontFamily"]},{groupId:"fontColors",items:["menuBar:fontColor","menuBar:fontBackgroundColor"]},{groupId:"highlight",items:["menuBar:highlight"]}]},"menuBar:heading"]},{groupId:"list",items:["menuBar:bulletedList","menuBar:numberedList","menuBar:multiLevelList","menuBar:todoList"]},{groupId:"indent",items:["menuBar:alignment","menuBar:indent","menuBar:outdent"]},{groupId:"caseChange",items:["menuBar:caseChange"]},{groupId:"removeFormat",items:["menuBar:removeFormat"]}]},{menuId:"tools",label:"Tools",groups:[{groupId:"aiTools",items:["menuBar:aiAssistant","menuBar:aiCommands"]},{groupId:"tools",items:["menuBar:trackChanges","menuBar:commentsArchive"]}]},{menuId:"help",label:"Help",groups:[{groupId:"help",items:["menuBar:accessibilityHelp"]}]}];function pb(e){let t;return t="items"in e&&e.items?{items:e.items,removeItems:[],addItems:[],isVisible:!0,isUsingDefaultConfig:!1,...e}:{items:Un(fb),addItems:[],removeItems:[],isVisible:!0,isUsingDefaultConfig:!0,...e},t}function bb({normalizedConfig:e,locale:t,componentFactory:i,extraItems:n}){const s=Un(e);return wb(e,s,n),function(e,t){const i=t.removeItems,n=[];t.items=t.items.filter((({menuId:e})=>!i.includes(e)||(n.push(e),!1))),kb(t.items,(e=>{e.groups=e.groups.filter((({groupId:e})=>!i.includes(e)||(n.push(e),!1)));for(const t of e.groups)t.items=t.items.filter((e=>{const t=Eb(e);return !i.includes(t)||(n.push(t),!1)}));}));for(const t of i)n.includes(t)||E("menu-bar-item-could-not-be-removed",{menuBarConfig:e,itemName:t});}(e,s),wb(e,s,s.addItems),function(e,t,i){kb(t.items,(n=>{for(const s of n.groups)s.items=s.items.filter((s=>{const o="string"==typeof s&&!i.has(s);return o&&!t.isUsingDefaultConfig&&E("menu-bar-item-unavailable",{menuBarConfig:e,parentMenuConfig:Un(n),componentName:s}),!o}));}));}(e,s,i),vb(e,s),function(e,t){const i=t.t,n={File:i({string:"File",id:"MENU_BAR_MENU_FILE"}),Edit:i({string:"Edit",id:"MENU_BAR_MENU_EDIT"}),View:i({string:"View",id:"MENU_BAR_MENU_VIEW"}),Insert:i({string:"Insert",id:"MENU_BAR_MENU_INSERT"}),Format:i({string:"Format",id:"MENU_BAR_MENU_FORMAT"}),Tools:i({string:"Tools",id:"MENU_BAR_MENU_TOOLS"}),Help:i({string:"Help",id:"MENU_BAR_MENU_HELP"}),Text:i({string:"Text",id:"MENU_BAR_MENU_TEXT"}),Font:i({string:"Font",id:"MENU_BAR_MENU_FONT"})};kb(e.items,(e=>{e.label in n&&(e.label=n[e.label]);}));}(s,t),s}function wb(e,t,i){const n=[];if(0!=i.length){for(const e of i){const i=xb(e.position),o=Ab(e.position);if("object"==typeof(s=e)&&"menu"in s)if(o){const s=t.items.findIndex((e=>e.menuId===o));if(-1!=s)"before"===i?(t.items.splice(s,0,e.menu),n.push(e)):"after"===i&&(t.items.splice(s+1,0,e.menu),n.push(e));else {_b(t,e.menu,o,i)&&n.push(e);}}else "start"===i?(t.items.unshift(e.menu),n.push(e)):"end"===i&&(t.items.push(e.menu),n.push(e));else if(Cb(e))kb(t.items,(t=>{if(t.menuId===o)"start"===i?(t.groups.unshift(e.group),n.push(e)):"end"===i&&(t.groups.push(e.group),n.push(e));else {const s=t.groups.findIndex((e=>e.groupId===o));-1!==s&&("before"===i?(t.groups.splice(s,0,e.group),n.push(e)):"after"===i&&(t.groups.splice(s+1,0,e.group),n.push(e)));}}));else {_b(t,e.item,o,i)&&n.push(e);}}var s;for(const t of i)n.includes(t)||E("menu-bar-item-could-not-be-added",{menuBarConfig:e,addedItemConfig:t});}}function _b(e,t,i,n){let s=!1;return kb(e.items,(e=>{for(const{groupId:o,items:r}of e.groups){if(s)return;if(o===i)"start"===n?(r.unshift(t),s=!0):"end"===n&&(r.push(t),s=!0);else {const e=r.findIndex((e=>Eb(e)===i));-1!==e&&("before"===n?(r.splice(e,0,t),s=!0):"after"===n&&(r.splice(e+1,0,t),s=!0));}}})),s}function vb(e,t){const i=t.isUsingDefaultConfig;let n=!1;t.items=t.items.filter((t=>!!t.groups.length||(yb(e,t,i),!1))),t.items.length?(kb(t.items,(t=>{t.groups=t.groups.filter((e=>!!e.items.length||(n=!0,!1)));for(const s of t.groups)s.items=s.items.filter((t=>!(Tb(t)&&!t.groups.length)||(yb(e,t,i),n=!0,!1)));})),n&&vb(e,t)):yb(e,e,i);}function yb(e,t,i){i||E("menu-bar-menu-empty",{menuBarConfig:e,emptyMenuConfig:t});}function kb(e,t){if(Array.isArray(e))for(const t of e)i(t);function i(e){t(e);for(const t of e.groups)for(const e of t.items)Tb(e)&&i(e);}}function Cb(e){return "object"==typeof e&&"group"in e}function xb(e){return e.startsWith("start")?"start":e.startsWith("end")?"end":e.startsWith("after")?"after":"before"}function Ab(e){const t=e.match(/^[^:]+:(.+)/);return t?t[1]:null}function Eb(e){return "string"==typeof e?e:e.menuId}function Tb(e){return "object"==typeof e&&"menuId"in e}class Pb extends(Zs()){editor;componentFactory;focusTracker;tooltipManager;poweredBy;ariaLiveAnnouncer;isReady=!1;_editableElementsMap=new Map;_focusableToolbarDefinitions=[];_extraMenuBarElements=[];_lastFocusedForeignElement=null;constructor(e){super();const t=e.editing.view;this.editor=e,this.componentFactory=new Qp(e),this.focusTracker=new _r,this.tooltipManager=new eb(e),this.poweredBy=new nb(e),this.ariaLiveAnnouncer=new lb(e),this.set("viewportOffset",this._readViewportOffsetFromConfig()),this.once("ready",(()=>{this._bindBodyCollectionWithFocusTracker(),this.isReady=!0;})),this.listenTo(t.document,"layoutChanged",this.update.bind(this)),this.listenTo(t,"scrollToTheSelection",this._handleScrollToTheSelection.bind(this)),this._initFocusTracking();}get element(){return null}update(){this.fire("update");}destroy(){this.stopListening(),this.focusTracker.destroy(),this.tooltipManager.destroy(this.editor),this.poweredBy.destroy();for(const e of this._editableElementsMap.values())e.ckeditorInstance=null,this.editor.keystrokes.stopListening(e);this._editableElementsMap=new Map,this._focusableToolbarDefinitions=[];}setEditableElement(e,t){this._editableElementsMap.set(e,t),t.ckeditorInstance||(t.ckeditorInstance=this.editor),this.focusTracker.add(t);const i=()=>{this.editor.editing.view.getDomRoot(e)||this.editor.keystrokes.listenTo(t);};this.isReady?i():this.once("ready",i);}removeEditableElement(e){const t=this._editableElementsMap.get(e);t&&(this._editableElementsMap.delete(e),this.editor.keystrokes.stopListening(t),this.focusTracker.remove(t),t.ckeditorInstance=null);}getEditableElement(e="main"){return this._editableElementsMap.get(e)}getEditableElementsNames(){return this._editableElementsMap.keys()}addToolbar(e,t={}){e.isRendered?(this.focusTracker.add(e),this.editor.keystrokes.listenTo(e.element)):e.once("render",(()=>{this.focusTracker.add(e),this.editor.keystrokes.listenTo(e.element);})),this._focusableToolbarDefinitions.push({toolbarView:e,options:t});}extendMenuBar(e){this._extraMenuBarElements.push(e);}get _editableElements(){return console.warn("editor-ui-deprecated-editable-elements: The EditorUI#_editableElements property has been deprecated and will be removed in the near future.",{editorUI:this}),this._editableElementsMap}_initMenuBar(e){const t=e.element;this.focusTracker.add(t),this.editor.keystrokes.listenTo(t);const i=pb(this.editor.config.get("menuBar")||{});e.fillFromConfig(i,this.componentFactory,this._extraMenuBarElements),this.editor.keystrokes.set("Esc",((e,i)=>{t.contains(this.editor.ui.focusTracker.focusedElement)&&(this._lastFocusedForeignElement?(this._lastFocusedForeignElement.focus(),this._lastFocusedForeignElement=null):this.editor.editing.view.focus(),i());})),this.editor.keystrokes.set("Alt+F9",((i,n)=>{t.contains(this.editor.ui.focusTracker.focusedElement)||(this._saveLastFocusedForeignElement(),e.isFocusBorderEnabled=!0,e.focus(),n());}));}_readViewportOffsetFromConfig(){const e=this.editor,t=e.config.get("ui.viewportOffset");if(t)return t;const i=e.config.get("toolbar.viewportTopOffset");return i?(console.warn("editor-ui-deprecated-viewport-offset-config: The `toolbar.vieportTopOffset` configuration option is deprecated. It will be removed from future CKEditor versions. Use `ui.viewportOffset.top` instead."),{top:i}):{top:0}}_initFocusTracking(){const e=this.editor;let t;e.keystrokes.set("Alt+F10",((e,i)=>{this._saveLastFocusedForeignElement();const n=this._getCurrentFocusedToolbarDefinition();n&&t||(t=this._getFocusableCandidateToolbarDefinitions());for(let e=0;e{const n=this._getCurrentFocusedToolbarDefinition();n&&(this._lastFocusedForeignElement?(this._lastFocusedForeignElement.focus(),this._lastFocusedForeignElement=null):e.editing.view.focus(),n.options.afterBlur&&n.options.afterBlur(),i());}));}_saveLastFocusedForeignElement(){const e=this.focusTracker.focusedElement;Array.from(this._editableElementsMap.values()).includes(e)&&!Array.from(this.editor.editing.view.domRoots.values()).includes(e)&&(this._lastFocusedForeignElement=e);}_getFocusableCandidateToolbarDefinitions(){const e=[];for(const t of this._focusableToolbarDefinitions){const{toolbarView:i,options:n}=t;(No(i.element)||n.beforeFocus)&&e.push(t);}return e.sort(((e,t)=>Sb(e)-Sb(t))),e}_getCurrentFocusedToolbarDefinition(){for(const e of this._focusableToolbarDefinitions)if(e.toolbarView.element&&e.toolbarView.element.contains(this.focusTracker.focusedElement))return e;return null}_focusFocusableCandidateToolbar(e){const{toolbarView:t,options:{beforeFocus:i}}=e;return i&&i(),!!No(t.element)&&(t.focus(),!0)}_handleScrollToTheSelection(e,t){const i={top:0,bottom:0,left:0,right:0,...this.viewportOffset};t.viewportOffset.top+=i.top,t.viewportOffset.bottom+=i.bottom,t.viewportOffset.left+=i.left,t.viewportOffset.right+=i.right;}_bindBodyCollectionWithFocusTracker(){const e=this.view.body;for(const t of e)this.focusTracker.add(t.element);e.on("add",((e,t)=>{this.focusTracker.add(t.element);})),e.on("remove",((e,t)=>{this.focusTracker.remove(t.element);}));}}function Sb(e){const{toolbarView:t,options:i}=e;let n=10;return No(t.element)&&n--,i.isContextual&&n--,n}class Ib extends lg{body;menuBarView;constructor(e){super(e),this.body=new Ng(e);}render(){super.render(),this.body.attachToDom();}destroy(){return this.body.detachFromDom(),super.destroy()}}class Vb extends Ib{top;main;_voiceLabelView;constructor(e){super(e),this.top=this.createCollection(),this.main=this.createCollection(),this._voiceLabelView=this._createVoiceLabel(),this.setTemplate({tag:"div",attributes:{class:["ck","ck-reset","ck-editor","ck-rounded-corners"],role:"application",dir:e.uiLanguageDirection,lang:e.uiLanguage,"aria-labelledby":this._voiceLabelView.id},children:[this._voiceLabelView,{tag:"div",attributes:{class:["ck","ck-editor__top","ck-reset_all"],role:"presentation"},children:this.top},{tag:"div",attributes:{class:["ck","ck-editor__main"],role:"presentation"},children:this.main}]});}_createVoiceLabel(){const e=this.t,t=new Og;return t.text=e("Rich Text Editor"),t.extendTemplate({attributes:{class:"ck-voice-label"}}),t}}class Rb extends lg{name=null;_editingView;_editableElement;_hasExternalElement;constructor(e,t,i){super(e),this.setTemplate({tag:"div",attributes:{class:["ck","ck-content","ck-editor__editable","ck-rounded-corners"],lang:e.contentLanguage,dir:e.contentLanguageDirection}}),this.set("isFocused",!1),this._editableElement=i,this._hasExternalElement=!!this._editableElement,this._editingView=t;}render(){super.render(),this._hasExternalElement?this.template.apply(this.element=this._editableElement):this._editableElement=this.element,this.on("change:isFocused",(()=>this._updateIsFocusedClasses())),this._updateIsFocusedClasses();}destroy(){this._hasExternalElement&&this.template.revert(this._editableElement),super.destroy();}get hasExternalElement(){return this._hasExternalElement}_updateIsFocusedClasses(){const e=this._editingView;function t(t){e.change((i=>{const n=e.document.getRoot(t.name);i.addClass(t.isFocused?"ck-focused":"ck-blurred",n),i.removeClass(t.isFocused?"ck-blurred":"ck-focused",n);}));}e.isRenderingInProgress?function i(n){e.once("change:isRenderingInProgress",((e,s,o)=>{o?i(n):t(n);}));}(this):t(this);}}class Ob extends Rb{_options;constructor(e,t,i,n={}){super(e,t,i),this._options=n,this.extendTemplate({attributes:{role:"textbox",class:"ck-editor__editable_inline"}});}render(){super.render();const e=this._editingView;e.change((t=>{const i=e.document.getRoot(this.name);t.setAttribute("aria-label",this.getEditableAriaLabel(),i);}));}getEditableAriaLabel(){const e=this.locale.t,t=this._options.label,i=this._editableElement,n=this.name;if("string"==typeof t)return t;if("object"==typeof t)return t[n];if("function"==typeof t)return t(this);if(i){const e=i.getAttribute("aria-label");if(e)return e}return e("Rich Text Editor. Editing area: %0",n)}}class Bb extends lg{constructor(e){super(e);const t=this.bindTemplate;this.setTemplate({tag:"iframe",attributes:{class:["ck","ck-reset_all"],sandbox:"allow-same-origin allow-scripts"},on:{load:t.to("loaded")}});}render(){return new Promise((e=>(this.on("loaded",e),super.render())))}}function Mb(e,t){let i=0,n=0;for(const s of t){const t=s,o=t.items,r=e&&!!t.label.match(e);t.labelView.highlightText(r?e:null);for(const t of o){const i=t.children.first,n=i.labelView;if(e){const s=!!i.label.match(e);n.highlightText(s?e:null),t.isVisible=r||s;}else t.isVisible=!0,n.highlightText(null);}const a=o.filter((e=>e.isVisible)).length;i+=t.items.length,n+=r?t.items.length:a,t.isVisible=r||!!a;}return {resultsCount:n,totalItemsCount:i}}class Lb extends qr{static get pluginName(){return "Notification"}static get isOfficialPlugin(){return !0}init(){this.on("show:warning",((e,t)=>{window.alert(t.message);}),{priority:"lowest"});}showSuccess(e,t={}){this._showNotification({message:e,type:"success",namespace:t.namespace,title:t.title});}showInfo(e,t={}){this._showNotification({message:e,type:"info",namespace:t.namespace,title:t.title});}showWarning(e,t={}){this._showNotification({message:e,type:"warning",namespace:t.namespace,title:t.title});}_showNotification(e){const t=e.namespace?`show:${e.type}:${e.namespace}`:`show:${e.type}`;this.fire(t,{message:e.message,type:e.type,title:e.title||""});}}class Fb extends(Zs()){constructor(e,t){super(),t&&xt(this,t),e&&this.set(e);}}const Nb=Oo("px");class Db extends Dr{positionLimiter;visibleStack;_viewToStack=new Map;_idToStack=new Map;_view=null;_rotatorView=null;_fakePanelsView=null;static get pluginName(){return "ContextualBalloon"}static get isOfficialPlugin(){return !0}constructor(e){super(e),this.positionLimiter=()=>{const e=this.editor.editing.view,t=e.document.selection.editableElement;return t?e.domConverter.mapViewToDom(t.root):null},this.decorate("getPositionOptions"),this.set("visibleView",null),this.set("_numberOfStacks",0),this.set("_singleViewMode",!1);}destroy(){super.destroy(),this._view&&this._view.destroy(),this._rotatorView&&this._rotatorView.destroy(),this._fakePanelsView&&this._fakePanelsView.destroy();}get view(){return this._view||this._createPanelView(),this._view}hasView(e){return Array.from(this._viewToStack.keys()).includes(e)}add(e){if(this._view||this._createPanelView(),this.hasView(e.view))throw new A("contextualballoon-add-view-exist",[this,e]);const t=e.stackId||"main";if(!this._idToStack.has(t))return this._idToStack.set(t,new Map([[e.view,e]])),this._viewToStack.set(e.view,this._idToStack.get(t)),this._numberOfStacks=this._idToStack.size,void(this._visibleStack&&!e.singleViewMode||this.showStack(t));const i=this._idToStack.get(t);e.singleViewMode&&this.showStack(t),i.set(e.view,e),this._viewToStack.set(e.view,i),i===this._visibleStack&&this._showView(e);}remove(e){if(!this.hasView(e))throw new A("contextualballoon-remove-view-not-exist",[this,e]);const t=this._viewToStack.get(e);this._singleViewMode&&this.visibleView===e&&(this._singleViewMode=!1),this.visibleView===e&&(1===t.size?this._idToStack.size>1?this._showNextStack():(this.view.hide(),this.visibleView=null,this._rotatorView.hideView()):this._showView(Array.from(t.values())[t.size-2])),1===t.size?(this._idToStack.delete(this._getStackId(t)),this._numberOfStacks=this._idToStack.size):t.delete(e),this._viewToStack.delete(e);}updatePosition(e){e&&(this._visibleStack.get(this.visibleView).position=e),this.view.pin(this.getPositionOptions()),this._fakePanelsView.updatePosition();}getPositionOptions(){let e=Array.from(this._visibleStack.values()).pop().position;return e&&(e.limiter||(e=Object.assign({},e,{limiter:this.positionLimiter})),e=Object.assign({},e,{viewportOffsetConfig:this.editor.ui.viewportOffset})),e}showStack(e){this.visibleStack=e;const t=this._idToStack.get(e);if(!t)throw new A("contextualballoon-showstack-stack-not-exist",this);this._visibleStack!==t&&this._showView(Array.from(t.values()).pop());}_createPanelView(){this._view=new Df(this.editor.locale),this.editor.ui.view.body.add(this._view),this._rotatorView=this._createRotatorView(),this._fakePanelsView=this._createFakePanelsView();}get _visibleStack(){return this._viewToStack.get(this.visibleView)}_getStackId(e){return Array.from(this._idToStack.entries()).find((t=>t[1]===e))[0]}_showNextStack(){const e=Array.from(this._idToStack.values());let t=e.indexOf(this._visibleStack)+1;e[t]||(t=0),this.showStack(this._getStackId(e[t]));}_showPrevStack(){const e=Array.from(this._idToStack.values());let t=e.indexOf(this._visibleStack)-1;e[t]||(t=e.length-1),this.showStack(this._getStackId(e[t]));}_createRotatorView(){const e=new zb(this.editor.locale),t=this.editor.locale.t;return this.view.content.add(e),e.bind("isNavigationVisible").to(this,"_numberOfStacks",this,"_singleViewMode",((e,t)=>!t&&e>1)),e.on("change:isNavigationVisible",(()=>this.updatePosition()),{priority:"low"}),e.bind("counter").to(this,"visibleView",this,"_numberOfStacks",((e,i)=>{if(i<2)return "";const n=Array.from(this._idToStack.values()).indexOf(this._visibleStack)+1;return t("%0 of %1",[n,i])})),e.buttonNextView.on("execute",(()=>{e.focusTracker.isFocused&&this.editor.editing.view.focus(),this._showNextStack();})),e.buttonPrevView.on("execute",(()=>{e.focusTracker.isFocused&&this.editor.editing.view.focus(),this._showPrevStack();})),e}_createFakePanelsView(){const e=new Hb(this.editor.locale,this.view);return e.bind("numberOfPanels").to(this,"_numberOfStacks",this,"_singleViewMode",((e,t)=>!t&&e>=2?Math.min(e-1,2):0)),e.listenTo(this.view,"change:top",(()=>e.updatePosition())),e.listenTo(this.view,"change:left",(()=>e.updatePosition())),this.editor.ui.view.body.add(e),e}_showView({view:e,balloonClassName:t="",withArrow:i=!0,singleViewMode:n=!1}){this.view.class=t,this.view.withArrow=i,this._rotatorView.showView(e),this.visibleView=e,this.view.pin(this.getPositionOptions()),this._fakePanelsView.updatePosition(),n&&(this._singleViewMode=!0);}}class zb extends lg{focusTracker;buttonPrevView;buttonNextView;content;constructor(e){super(e);const t=e.t,i=this.bindTemplate;this.set("isNavigationVisible",!0),this.focusTracker=new _r,this.buttonPrevView=this._createButtonView(t("Previous"),vm.previousArrow),this.buttonNextView=this._createButtonView(t("Next"),vm.nextArrow),this.content=this.createCollection(),this.setTemplate({tag:"div",attributes:{class:["ck","ck-balloon-rotator"],"z-index":"-1"},children:[{tag:"div",attributes:{class:["ck-balloon-rotator__navigation",i.to("isNavigationVisible",(e=>e?"":"ck-hidden"))]},children:[this.buttonPrevView,{tag:"span",attributes:{class:["ck-balloon-rotator__counter"]},children:[{text:i.to("counter")}]},this.buttonNextView]},{tag:"div",attributes:{class:"ck-balloon-rotator__content"},children:this.content}]});}render(){super.render(),this.focusTracker.add(this.element);}destroy(){super.destroy(),this.focusTracker.destroy();}showView(e){this.hideView(),this.content.add(e);}hideView(){this.content.clear();}_createButtonView(e,t){const i=new pg(this.locale);return i.set({label:e,icon:t,tooltip:!0}),i}}class Hb extends lg{content;_balloonPanelView;constructor(e,t){super(e);const i=this.bindTemplate;this.set("top",0),this.set("left",0),this.set("height",0),this.set("width",0),this.set("numberOfPanels",0),this.content=this.createCollection(),this._balloonPanelView=t,this.setTemplate({tag:"div",attributes:{class:["ck-fake-panel",i.to("numberOfPanels",(e=>e?"":"ck-hidden"))],style:{top:i.to("top",Nb),left:i.to("left",Nb),width:i.to("width",Nb),height:i.to("height",Nb)}},children:this.content}),this.on("change:numberOfPanels",((e,t,i,n)=>{i>n?this._addPanels(i-n):this._removePanels(n-i),this.updatePosition();}));}_addPanels(e){for(;e--;){const e=new lg;e.setTemplate({tag:"div"}),this.content.add(e),this.registerChild(e);}}_removePanels(e){for(;e--;){const e=this.content.last;this.content.remove(e),this.deregisterChild(e),e.destroy();}}updatePosition(){if(this.numberOfPanels){const{top:e,left:t}=this._balloonPanelView,{width:i,height:n}=new Eo(this._balloonPanelView.element);Object.assign(this,{top:e,left:t,width:i,height:n});}}}const $b=Oo("px");class Ub extends lg{content;contentPanelElement;_contentPanelPlaceholder;constructor(e){super(e);const t=this.bindTemplate;this.set("isActive",!1),this.set("isSticky",!1),this.set("limiterElement",null),this.set("limiterBottomOffset",50),this.set("viewportTopOffset",0),this.set("_marginLeft",null),this.set("_isStickyToTheBottomOfLimiter",!1),this.set("_stickyTopOffset",null),this.set("_stickyBottomOffset",null),this.content=this.createCollection(),this._contentPanelPlaceholder=new Hm({tag:"div",attributes:{class:["ck","ck-sticky-panel__placeholder"],style:{display:t.to("isSticky",(e=>e?"block":"none")),height:t.to("isSticky",(e=>e?$b(this._contentPanelRect.height):null))}}}).render(),this.contentPanelElement=new Hm({tag:"div",attributes:{class:["ck","ck-sticky-panel__content",t.if("isSticky","ck-sticky-panel__content_sticky"),t.if("_isStickyToTheBottomOfLimiter","ck-sticky-panel__content_sticky_bottom-limit")],style:{width:t.to("isSticky",(e=>e?$b(this._contentPanelPlaceholder.getBoundingClientRect().width):null)),top:t.to("_stickyTopOffset",(e=>e?$b(e):e)),bottom:t.to("_stickyBottomOffset",(e=>e?$b(e):e)),marginLeft:t.to("_marginLeft")}},children:this.content}).render(),this.setTemplate({tag:"div",attributes:{class:["ck","ck-sticky-panel"]},children:[this._contentPanelPlaceholder,this.contentPanelElement]});}render(){super.render(),this.checkIfShouldBeSticky(),this.listenTo(i.document,"scroll",(()=>{this.checkIfShouldBeSticky();}),{useCapture:!0}),this.listenTo(this,"change:isActive",(()=>{this.checkIfShouldBeSticky();}));}checkIfShouldBeSticky(){if(!this.limiterElement||!this.isActive)return void this._unstick();const e=new Eo(this.limiterElement);let t=e.getVisible();if(t){const e=new Eo(i.window);e.top+=this.viewportTopOffset,e.height-=this.viewportTopOffset,t=t.getIntersection(e);}if(t&&e.topt.bottom){const i=Math.max(e.bottom-t.bottom,0)+this.limiterBottomOffset;e.bottom-i>e.top+this._contentPanelRect.height?this._stickToBottomOfLimiter(i):this._unstick();}else this._contentPanelRect.height+this.limiterBottomOffset{this.reset(),this.focus(),this.fire("reset");})),this.resetButtonView.bind("isVisible").to(this.fieldView,"isEmpty",(e=>!e)),this.fieldWrapperChildren.add(this.resetButtonView),this.extendTemplate({attributes:{class:"ck-search__query_with-reset"}}));}reset(){this.fieldView.reset(),this._viewConfig.showResetButton&&(this.resetButtonView.isVisible=!1);}}class jb extends lg{constructor(){super();const e=this.bindTemplate;this.set({isVisible:!1,primaryText:"",secondaryText:""}),this.setTemplate({tag:"div",attributes:{class:["ck","ck-search__info",e.if("isVisible","ck-hidden",(e=>!e))],tabindex:-1},children:[{tag:"span",children:[{text:[e.to("primaryText")]}]},{tag:"span",children:[{text:[e.to("secondaryText")]}]}]});}focus(){this.element.focus();}}class qb extends lg{focusTracker;children;_focusCycler;constructor(e){super(e),this.children=this.createCollection(),this.focusTracker=new _r,this.setTemplate({tag:"div",attributes:{class:["ck","ck-search__results"],tabindex:-1},children:this.children}),this._focusCycler=new _g({focusables:this.children,focusTracker:this.focusTracker});}render(){super.render();for(const e of this.children)this.focusTracker.add(e.element);}focus(){this._focusCycler.focusFirst();}focusFirst(){this._focusCycler.focusFirst();}focusLast(){this._focusCycler.focusLast();}}class Gb extends lg{focusTracker;keystrokes;resultsView;filteredView;infoView;queryView;focusCycler;_config;constructor(e,t){super(e),this._config=t,this.filteredView=t.filteredView,this.queryView=this._createSearchTextQueryView(),this.focusTracker=new _r,this.keystrokes=new Cr,this.resultsView=new qb(e),this.children=this.createCollection(),this.focusableChildren=this.createCollection([this.queryView,this.resultsView]),this.set("isEnabled",!0),this.set("resultsCount",0),this.set("totalItemsCount",0),t.infoView&&t.infoView.instance?this.infoView=t.infoView.instance:(this.infoView=new jb,this._enableDefaultInfoViewBehavior(),this.on("render",(()=>{this.search("");}))),this.resultsView.children.addMany([this.infoView,this.filteredView]),this.focusCycler=new _g({focusables:this.focusableChildren,focusTracker:this.focusTracker,keystrokeHandler:this.keystrokes,actions:{focusPrevious:"shift + tab",focusNext:"tab"}}),this.on("search",((e,{resultsCount:t,totalItemsCount:i})=>{this.resultsCount=t,this.totalItemsCount=i;})),this.setTemplate({tag:"div",attributes:{class:["ck","ck-search",t.class||null],tabindex:"-1"},children:this.children});}render(){super.render(),this.children.addMany([this.queryView,this.resultsView]);const e=e=>e.stopPropagation();for(const e of this.focusableChildren)this.focusTracker.add(e.element);this.keystrokes.listenTo(this.element),this.keystrokes.set("arrowright",e),this.keystrokes.set("arrowleft",e),this.keystrokes.set("arrowup",e),this.keystrokes.set("arrowdown",e);}focus(){this.queryView.focus();}reset(){this.queryView.reset(),this.search(""),this.filteredView.element.scrollTo(0,0);}search(e){const t=e?new RegExp(Rs(e),"ig"):null,i=this.filteredView.filter(t);this.fire("search",{query:e,...i});}_createSearchTextQueryView(){const e=new Wb(this.locale,this._config.queryView);return this.listenTo(e.fieldView,"input",(()=>{this.search(e.fieldView.element.value);})),e.on("reset",(()=>this.reset())),e.bind("isEnabled").to(this),e}_enableDefaultInfoViewBehavior(){const e=this.locale.t,t=this.infoView;function i(e,{query:t,resultsCount:i,totalItemsCount:n}){return "function"==typeof e?e(t,i,n):e}this.on("search",((n,s)=>{if(s.resultsCount)t.set({isVisible:!1});else {const n=this._config.infoView&&this._config.infoView.text;let o,r;s.totalItemsCount?n&&n.notFound?(o=n.notFound.primary,r=n.notFound.secondary):(o=e("No results found"),r=""):n&&n.noSearchableItems?(o=n.noSearchableItems.primary,r=n.noSearchableItems.secondary):(o=e("No searchable items"),r=""),t.set({primaryText:i(o,s),secondaryText:i(r,s),isVisible:!0});}}));}}class Kb extends Gb{_config;constructor(e,t){super(e,t),this._config=t;const n=Oo("px");this.extendTemplate({attributes:{class:["ck-autocomplete"]}});const s=this.resultsView.bindTemplate;this.resultsView.set("isVisible",!1),this.resultsView.set("_position","s"),this.resultsView.set("_width",0),this.resultsView.extendTemplate({attributes:{class:[s.if("isVisible","ck-hidden",(e=>!e)),s.to("_position",(e=>`ck-search__results_${e}`))],style:{width:s.to("_width",n)}}}),this.focusTracker.on("change:isFocused",((e,i,n)=>{this._updateResultsVisibility(),n?this.resultsView.element.scrollTop=0:t.resetOnBlur&&this.queryView.reset();})),this.on("search",(()=>{this._updateResultsVisibility(),this._updateResultsViewWidthAndPosition();})),this.keystrokes.set("esc",((e,t)=>{this.resultsView.isVisible&&(this.queryView.focus(),this.resultsView.isVisible=!1,t());})),this.listenTo(i.document,"scroll",(()=>{this._updateResultsViewWidthAndPosition();})),this.on("change:isEnabled",(()=>{this._updateResultsVisibility();})),this.filteredView.on("execute",((e,{value:t})=>{this.focus(),this.reset(),this.queryView.fieldView.value=this.queryView.fieldView.element.value=t,this.resultsView.isVisible=!1;})),this.resultsView.on("change:isVisible",(()=>{this._updateResultsViewWidthAndPosition();}));}_updateResultsViewWidthAndPosition(){if(!this.resultsView.isVisible)return;this.resultsView._width=new Eo(this.queryView.fieldView.element).width;const e=Kb._getOptimalPosition({element:this.resultsView.element,target:this.queryView.element,fitInViewport:!0,positions:Kb.defaultResultsPositions});this.resultsView._position=e?e.name:"s";}_updateResultsVisibility(){const e=void 0===this._config.queryMinChars?0:this._config.queryMinChars,t=this.queryView.fieldView.element.value.length;this.resultsView.isVisible=this.focusTracker.isFocused&&this.isEnabled&&t>=e;}static defaultResultsPositions=[e=>({top:e.bottom,left:e.left,name:"s"}),(e,t)=>({top:e.top-t.height,left:e.left,name:"n"})];static _getOptimalPosition=Do}class Zb extends lg{constructor(){super(),this.set("text",void 0),this.setTemplate({tag:"span",attributes:{class:["ck","ck-highlighted-text"]}}),this.on("render",(()=>{this.on("change:text",(()=>{this._updateInnerHTML(this.text);})),this._updateInnerHTML(this.text);}));}highlightText(e){this._updateInnerHTML(function(e,t){if(!t)return Ss(e);const i=[];let n=0,s=t.exec(e);for(;null!==s;){const o=s.index;o!==n&&i.push({text:e.substring(n,o),isMatch:!1}),i.push({text:s[0],isMatch:!0}),n=t.lastIndex,s=t.exec(e);}n!==e.length&&i.push({text:e.substring(n),isMatch:!1});return i.map((e=>(e.text=Ss(e.text),e))).map((e=>e.isMatch?`${e.text}`:e.text)).join("")}(this.text||"",e));}_updateInnerHTML(e){this.element.innerHTML=e||"";}}class Jb extends Zb{constructor(){super(),this.set({style:void 0,text:void 0,id:void 0});const e=this.bindTemplate;this.extendTemplate({attributes:{class:["ck-button__label"],style:e.to("style"),id:e.to("id")}});}}class Qb extends Zb{id;constructor(){super(),this.set("for",void 0);const e=this.bindTemplate;this.id=`ck-editor__label_${k()}`,this.extendTemplate({attributes:{class:["ck","ck-label"],id:this.id,for:e.to("for")}});}}class Yb extends lg{constructor(){super(),this.set("isVisible",!1);const e=this.bindTemplate;this.setTemplate({tag:"span",attributes:{class:["ck","ck-spinner-container",e.if("isVisible","ck-hidden",(e=>!e))]},children:[{tag:"span",attributes:{class:["ck","ck-spinner"]}}]});}}const Xb=Oo("px");class ew extends Dr{toolbarView;focusTracker;_balloonConfig;_resizeObserver=null;_balloon;_fireSelectionChangeDebounced;static get pluginName(){return "BalloonToolbar"}static get isOfficialPlugin(){return !0}static get requires(){return [Db]}constructor(e){super(e),this._balloonConfig=qf(e.config.get("balloonToolbar")),this.toolbarView=this._createToolbarView(),this.focusTracker=new _r,this._trackFocusableEditableElements(),this.focusTracker.add(this.toolbarView),e.ui.addToolbar(this.toolbarView,{beforeFocus:()=>this.show(!0),afterBlur:()=>this.hide(),isContextual:!0}),this._balloon=e.plugins.get(Db),this._fireSelectionChangeDebounced=vs((()=>this.fire("_selectionChangeDebounced")),200),this.decorate("show");}init(){const e=this.editor,t=e.model.document.selection;this.listenTo(this.focusTracker,"change:isFocused",((e,t,i)=>{const n=this._balloon.visibleView===this.toolbarView;!i&&n?this.hide():i&&this.show();})),this.listenTo(t,"change:range",((e,i)=>{(i.directChange||t.isCollapsed)&&this.hide(),this._fireSelectionChangeDebounced();})),this.listenTo(this,"_selectionChangeDebounced",(()=>{this.editor.editing.view.document.isFocused&&this.show();})),this._balloonConfig.shouldNotGroupWhenFull||this.listenTo(e,"ready",(()=>{const t=e.ui.view.editable.element;this._resizeObserver=new Vo(t,(e=>{this.toolbarView.maxWidth=Xb(.9*e.contentRect.width);}));})),this.listenTo(this.toolbarView,"groupedItemsUpdate",(()=>{this._updatePosition();})),e.ui.once("ready",(()=>{this.toolbarView.fillFromConfig(this._balloonConfig,this.editor.ui.componentFactory);}));}_createToolbarView(){const e=this.editor.locale.t,t=!this._balloonConfig.shouldNotGroupWhenFull,i=new Kf(this.editor.locale,{shouldGroupWhenFull:t,isFloating:!0});return i.ariaLabel=e("Editor contextual toolbar"),i.render(),i}show(e=!1){const t=this.editor,i=t.model.document.selection,n=t.model.schema;this._balloon.hasView(this.toolbarView)||i.isCollapsed&&!e||function(e,t){if(1===e.rangeCount)return !1;return [...e.getRanges()].every((e=>{const i=e.getContainedElement();return i&&t.isSelectable(i)}))}(i,n)||Array.from(this.toolbarView.items).every((e=>void 0!==e.isEnabled&&!e.isEnabled))||(this.listenTo(this.editor.ui,"update",(()=>{this._updatePosition();})),this._balloon.add({view:this.toolbarView,position:this._getBalloonPositionData(),balloonClassName:"ck-toolbar-container"}));}hide(){this._balloon.hasView(this.toolbarView)&&(this.stopListening(this.editor.ui,"update"),this._balloon.remove(this.toolbarView));}_trackFocusableEditableElements(){const{editor:e,focusTracker:t}=this,{editing:i}=e;i.view.addObserver(class extends Al{observe(e){t.add(e);}stopObserving(e){t.remove(e);}});}_getBalloonPositionData(){const e=this.editor.editing.view,t=e.document,i=t.selection,n=t.selection.isBackward;return {target:()=>{const t=n?i.getFirstRange():i.getLastRange(),s=Eo.getDomRangeRects(e.domConverter.viewRangeToDom(t));return n?s[0]:(s.length>1&&0===s[s.length-1].width&&s.pop(),s[s.length-1])},positions:this._getBalloonPositions(n)}}_updatePosition(){this._balloon.updatePosition(this._getBalloonPositionData());}destroy(){super.destroy(),this.stopListening(),this._fireSelectionChangeDebounced.cancel(),this.toolbarView.destroy(),this.focusTracker.destroy(),this._resizeObserver&&this._resizeObserver.destroy();}_getBalloonPositions(e){const t=o.isSafari&&o.isiOS?Df.generatePositions({heightOffset:Math.max(Df.arrowHeightOffset,Math.round(20/i.window.visualViewport.scale))}):Df.defaultPositions;return e?[t.northWestArrowSouth,t.northWestArrowSouthWest,t.northWestArrowSouthEast,t.northWestArrowSouthMiddleEast,t.northWestArrowSouthMiddleWest,t.southWestArrowNorth,t.southWestArrowNorthWest,t.southWestArrowNorthEast,t.southWestArrowNorthMiddleWest,t.southWestArrowNorthMiddleEast]:[t.southEastArrowNorth,t.southEastArrowNorthEast,t.southEastArrowNorthWest,t.southEastArrowNorthMiddleEast,t.southEastArrowNorthMiddleWest,t.northEastArrowSouth,t.northEastArrowSouthEast,t.northEastArrowSouthWest,t.northEastArrowSouthMiddleEast,t.northEastArrowSouthMiddleWest]}}const tw=Oo("px");class iw extends pg{constructor(e){super(e);const t=this.bindTemplate;this.isVisible=!1,this.isToggleable=!0,this.set("top",0),this.set("left",0),this.extendTemplate({attributes:{class:"ck-block-toolbar-button",style:{top:t.to("top",(e=>tw(e))),left:t.to("left",(e=>tw(e)))}}});}}const nw=Oo("px");class sw extends Dr{toolbarView;panelView;buttonView;_resizeObserver=null;_blockToolbarConfig;static get pluginName(){return "BlockToolbar"}static get isOfficialPlugin(){return !0}constructor(e){super(e),this._blockToolbarConfig=qf(this.editor.config.get("blockToolbar")),this.toolbarView=this._createToolbarView(),this.panelView=this._createPanelView(),this.buttonView=this._createButtonView(),cg({emitter:this.panelView,contextElements:[this.panelView.element,this.buttonView.element],activator:()=>this.panelView.isVisible,callback:()=>this._hidePanel()});}init(){const e=this.editor,t=e.t,i=t("Click to edit block"),n=t("Drag to move"),s=t("Edit block"),o=e.plugins.has("DragDropBlockToolbar"),r=o?`${i}\n${n}`:s;this.buttonView.label=r,o&&(this.buttonView.element.dataset.ckeTooltipClass="ck-tooltip_multi-line"),this.listenTo(e.model.document.selection,"change:range",((e,t)=>{t.directChange&&this._hidePanel();})),this.listenTo(e.ui,"update",(()=>this._updateButton())),this.listenTo(e,"change:isReadOnly",(()=>this._updateButton()),{priority:"low"}),this.listenTo(e.ui.focusTracker,"change:isFocused",(()=>this._updateButton())),this.listenTo(this.buttonView,"change:isVisible",((e,t,i)=>{i?this.buttonView.listenTo(window,"resize",(()=>this._updateButton())):(this.buttonView.stopListening(window,"resize"),this._hidePanel());})),this._repositionButtonOnScroll(),e.ui.addToolbar(this.toolbarView,{beforeFocus:()=>this._showPanel(),afterBlur:()=>this._hidePanel()}),e.ui.once("ready",(()=>{this.toolbarView.fillFromConfig(this._blockToolbarConfig,this.editor.ui.componentFactory);for(const e of this.toolbarView.items)e.on("execute",(()=>this._hidePanel(!0)),{priority:"high"});}));}destroy(){super.destroy(),this.panelView.destroy(),this.buttonView.destroy(),this.toolbarView.destroy(),this._resizeObserver&&this._resizeObserver.destroy();}_createToolbarView(){const e=this.editor.locale.t,t=!this._blockToolbarConfig.shouldNotGroupWhenFull,i=new Kf(this.editor.locale,{shouldGroupWhenFull:t,isFloating:!0});return i.ariaLabel=e("Editor block content toolbar"),i}_createPanelView(){const e=this.editor,t=new Df(e.locale);return t.content.add(this.toolbarView),t.class="ck-toolbar-container",e.ui.view.body.add(t),this.toolbarView.keystrokes.set("Esc",((e,t)=>{this._hidePanel(!0),t();})),t}_createButtonView(){const e=this.editor,t=e.t,i=new iw(e.locale),n=this._blockToolbarConfig.icon,s=Gf[n]||n||Gf.dragIndicator;return i.set({label:t("Edit block"),icon:s,withText:!1}),i.bind("isOn").to(this.panelView,"isVisible"),i.bind("tooltip").to(this.panelView,"isVisible",(e=>!e)),this.listenTo(i,"execute",(()=>{this.panelView.isVisible?this._hidePanel(!0):this._showPanel();})),this.listenTo(i,"change:isEnabled",((e,t,i)=>{!i&&this.panelView.isVisible&&this._hidePanel(!1);})),e.ui.view.body.add(i),i}_updateButton(){const e=this.editor,t=e.model,i=e.editing.view;if(!e.ui.focusTracker.isFocused)return void this._hideButton();if(!e.model.canEditAt(e.model.document.selection))return void this._hideButton();const n=Array.from(t.document.selection.getSelectedBlocks())[0];if(!n||Array.from(this.toolbarView.items).every((e=>!e.isEnabled)))return void this._hideButton();const s=i.domConverter.mapViewToDom(e.editing.mapper.toViewElement(n));this.buttonView.isVisible=!0,this._setupToolbarResize(),this._attachButtonToElement(s),this.panelView.isVisible&&this._showPanel();}_hideButton(){this.buttonView.isVisible=!1;}_showPanel(){if(!this.buttonView.isVisible)return;const e=this.panelView.isVisible;this.panelView.show();const t=this._getSelectedEditableElement();this.toolbarView.maxWidth=this._getToolbarMaxWidth(t),this.panelView.pin({target:this.buttonView.element,limiter:t}),e||this.toolbarView.items.get(0).focus();}_getSelectedEditableElement(){const e=this.editor.model.document.selection.getFirstRange().root.rootName;return this.editor.ui.getEditableElement(e)}_hidePanel(e){this.panelView.isVisible=!1,e&&this.editor.editing.view.focus();}_repositionButtonOnScroll(){const{buttonView:e}=this;let t=!1;const n=(e,n)=>{if(t)return;const s=this._getSelectedEditableElement();(n.target===i.document||wo(s).includes(n.target))&&(t=!0,i.window.requestAnimationFrame((()=>{this._updateButton(),t=!1;})));};e.on("change:isVisible",((t,s,o)=>{o?e.listenTo(i.document,"scroll",n,{useCapture:!0,usePassive:!0}):e.stopListening(i.document,"scroll",n);}));}_attachButtonToElement(e){const t=this.buttonView.element,i=this._getSelectedEditableElement(),n=window.getComputedStyle(e),s=new Eo(i),o=parseInt(n.paddingTop,10),r=parseInt(n.lineHeight,10)||1.2*parseInt(n.fontSize,10),a=new Eo(t),l=new Eo(e);let c;c="ltr"===this.editor.locale.uiLanguageDirection?s.left-a.width:s.right;const d=l.top+o+(r-a.height)/2;a.moveTo(c,d);const u=a.toAbsoluteRect();this.buttonView.top=u.top,this.buttonView.left=u.left,this._clipButtonToViewport(this.buttonView,i);}_clipButtonToViewport(e,t){const i=new Eo(e.element),n=new Eo(t).getVisible(),s=(...t)=>{e.element.style.clipPath=t.length?`polygon(${t.join(",")})`:"";},o=t=>{e.isEnabled=!t,e.element.style.pointerEvents=t?"none":"";};if(n&&n.bottom=i.height),s("0 0","100% 0",`100% calc(100% - ${nw(e)})`,`0 calc(100% - ${nw(e)}`);}else if(n&&n.top>i.top){const e=Math.min(i.height,n.top-i.top);o(e>=i.height),s(`0 ${nw(e)}`,`100% ${nw(e)}`,"100% 100%","0 100%");}else o(!1),s();}_setupToolbarResize(){const e=this._getSelectedEditableElement();this._blockToolbarConfig.shouldNotGroupWhenFull||(this._resizeObserver&&this._resizeObserver.element!==e&&(this._resizeObserver.destroy(),this._resizeObserver=null),this._resizeObserver||(this._resizeObserver=new Vo(e,(()=>{this.toolbarView.maxWidth=this._getToolbarMaxWidth(e);}))));}_getToolbarMaxWidth(e){const t=new Eo(e),i=new Eo(this.buttonView.element),n="rtl"===this.editor.locale.uiLanguageDirection?i.left-t.right+i.width:t.left-i.left;return nw(t.width+n)}}class ow extends Ig{arrowView;constructor(e){super(e);const t=this.bindTemplate;this.set({withText:!0,role:"menuitem"}),this.arrowView=this._createArrowView(),this.extendTemplate({attributes:{class:["ck-menu-bar__menu__button"],"aria-haspopup":!0,"aria-expanded":this.bindTemplate.to("isOn",(e=>String(e))),"data-cke-tooltip-disabled":t.to("isOn")},on:{mouseenter:t.to("mouseenter")}});}render(){super.render(),this.children.add(this.arrowView);}_createArrowView(){const e=new gg;return e.content=Wg,e.extendTemplate({attributes:{class:"ck-menu-bar__menu__button__arrow"}}),e}}class rw extends lg{children;constructor(e){super(e);const t=this.bindTemplate;this.set("isVisible",!1),this.set("position","se"),this.children=this.createCollection(),this.setTemplate({tag:"div",attributes:{class:["ck","ck-reset","ck-menu-bar__menu__panel",t.to("position",(e=>`ck-menu-bar__menu__panel_position_${e}`)),t.if("isVisible","ck-hidden",(e=>!e))],tabindex:"-1"},children:this.children,on:{selectstart:t.to((e=>{"input"!==e.target.tagName.toLocaleLowerCase()&&e.preventDefault();}))}});}focus(e=1){this.children.length&&(1===e?this.children.first.focus():this.children.last.focus());}}class aw extends lg{buttonView;panelView;focusTracker;keystrokes;constructor(e){super(e);const t=this.bindTemplate;this.buttonView=new ow(e),this.buttonView.delegate("mouseenter").to(this),this.buttonView.bind("isOn","isEnabled").to(this,"isOpen","isEnabled"),this.panelView=new rw(e),this.panelView.bind("isVisible").to(this,"isOpen"),this.keystrokes=new Cr,this.focusTracker=new _r,this.set("isOpen",!1),this.set("isEnabled",!0),this.set("panelPosition","w"),this.set("class",void 0),this.set("parentMenuView",null),this.setTemplate({tag:"div",attributes:{class:["ck","ck-menu-bar__menu",t.to("class"),t.if("isEnabled","ck-disabled",(e=>!e)),t.if("parentMenuView","ck-menu-bar__menu_top-level",(e=>!e))]},children:[this.buttonView,this.panelView]});}render(){super.render(),this.focusTracker.add(this.buttonView.element),this.focusTracker.add(this.panelView.element),this.keystrokes.listenTo(this.element),mb.closeOnEscKey(this),this._repositionPanelOnOpen();}_attachBehaviors(){this.parentMenuView?(mb.openOnButtonClick(this),mb.openOnArrowRightKey(this),mb.closeOnArrowLeftKey(this),mb.openAndFocusOnEnterKeyPress(this),mb.closeOnParentClose(this)):(this._propagateArrowKeystrokeEvents(),mb.openAndFocusPanelOnArrowDownKey(this),mb.toggleOnButtonClick(this));}_propagateArrowKeystrokeEvents(){this.keystrokes.set("arrowright",((e,t)=>{this.fire("arrowright"),t();})),this.keystrokes.set("arrowleft",((e,t)=>{this.fire("arrowleft"),t();}));}_repositionPanelOnOpen(){this.on("change:isOpen",((e,t,i)=>{if(!i)return;const n=aw._getOptimalPosition({element:this.panelView.element,target:this.buttonView.element,fitInViewport:!0,positions:this._panelPositions});this.panelView.position=n?n.name:this._panelPositions[0].name;}));}focus(){this.buttonView.focus();}get _panelPositions(){const{southEast:e,southWest:t,northEast:i,northWest:n,westSouth:s,eastSouth:o,westNorth:r,eastNorth:a}=gb;return "ltr"===this.locale.uiLanguageDirection?this.parentMenuView?[o,a,s,r]:[e,t,i,n]:this.parentMenuView?[s,r,o,a]:[t,e,n,i]}static _getOptimalPosition=Do}class lw extends Vf{constructor(e){super(e),this.role="menu",this.items.on("change",this._setItemsCheckSpace.bind(this));}_setItemsCheckSpace(){const e=Array.from(this.items).some((e=>{const t=cw(e);return t&&t.isToggleable}));this.items.forEach((t=>{const i=cw(t);i&&(i.hasCheckSpace=e);}));}}function cw(e){return e instanceof Pf?e.children.map((e=>function(e){return "object"==typeof e&&"buttonView"in e&&e.buttonView instanceof pg}(e)?e.buttonView:e)).find((e=>e instanceof Ig)):null}class dw extends Hg{constructor(e){super(e),this.set({withText:!0,withKeystroke:!0,tooltip:!1,role:"menuitem"}),this.extendTemplate({attributes:{class:["ck-menu-bar__menu__item__button"]}});}}const uw=["mouseenter","arrowleft","arrowright","change:isOpen"];class hw extends lg{children;menus=[];constructor(e){super(e);const t=e.t,i=this.bindTemplate;this.set({isOpen:!1,isFocusBorderEnabled:!1}),this._setupIsOpenUpdater(),this.children=this.createCollection(),this.setTemplate({tag:"div",attributes:{class:["ck","ck-menu-bar",i.if("isFocusBorderEnabled","ck-menu-bar_focus-border-enabled")],"aria-label":t("Editor menu bar"),role:"menubar"},children:this.children});}fillFromConfig(e,t,i=[]){const n=bb({normalizedConfig:e,locale:this.locale,componentFactory:t,extraItems:i}).items.map((e=>this._createMenu({componentFactory:t,menuDefinition:e})));this.children.addMany(n);}render(){super.render(),hb.toggleMenusAndFocusItemsOnHover(this),hb.closeMenusWhenTheBarCloses(this),hb.closeMenuWhenAnotherOnTheSameLevelOpens(this),hb.focusCycleMenusOnArrows(this),hb.closeOnClickOutside(this),hb.enableFocusHighlightOnInteraction(this);}focus(){this.children.first&&this.children.first.focus();}close(){for(const e of this.children)e.isOpen=!1;}registerMenu(e,t=null){t?(e.delegate(...uw).to(t),e.parentMenuView=t):e.delegate(...uw).to(this,(e=>"menu:"+e)),e._attachBehaviors(),this.menus.push(e);}_createMenu({componentFactory:e,menuDefinition:t,parentMenuView:i}){const n=this.locale,s=new aw(n);return this.registerMenu(s,i),s.buttonView.set({label:t.label}),s.once("change:isOpen",(()=>{const i=new lw(n);i.ariaLabel=t.label,s.panelView.children.add(i),i.items.addMany(this._createMenuItems({menuDefinition:t,parentMenuView:s,componentFactory:e}));})),s}_createMenuItems({menuDefinition:e,parentMenuView:t,componentFactory:i}){const n=this.locale,s=[];for(const o of e.groups){for(const e of o.items){const o=new ub(n,t);if(ue(e))o.children.add(this._createMenu({componentFactory:i,menuDefinition:e,parentMenuView:t}));else {const n=this._createMenuItemContentFromFactory({componentName:e,componentFactory:i,parentMenuView:t});if(!n)continue;o.children.add(n);}s.push(o);}o!==e.groups[e.groups.length-1]&&s.push(new Sf(n));}return s}_createMenuItemContentFromFactory({componentName:e,parentMenuView:t,componentFactory:i}){const n=i.create(e);return n instanceof aw||n instanceof Rg||n instanceof dw?(this._registerMenuTree(n,t),n.on("execute",(()=>{this.close();})),n):(E("menu-bar-component-unsupported",{componentName:e,componentView:n}),null)}_registerMenuTree(e,t){if(!(e instanceof aw))return void e.delegate("mouseenter").to(t);this.registerMenu(e,t);const i=e.panelView.children.filter((e=>e instanceof lw))[0];if(!i)return void e.delegate("mouseenter").to(t);const n=i.items.filter((e=>e instanceof Pf));for(const t of n)this._registerMenuTree(t.children.get(0),e);}_setupIsOpenUpdater(){let e;this.on("menu:change:isOpen",((t,i,n)=>{clearTimeout(e),n?this.isOpen=!0:e=setTimeout((()=>{this.isOpen=Array.from(this.children).some((e=>e.isOpen));}),0);}));}}const mw=(()=>new Map([["left",vm.alignLeft],["right",vm.alignRight],["center",vm.alignCenter],["justify",vm.alignJustify]]))();class gw extends Dr{get localizedOptionTitles(){const e=this.editor.t;return {left:e("Align left"),right:e("Align right"),center:e("Align center"),justify:e("Justify")}}static get pluginName(){return "AlignmentUI"}static get isOfficialPlugin(){return !0}init(){const e=Lm(this.editor.config.get("alignment.options"));e.map((e=>e.name)).filter(Bm).forEach((e=>this._addButton(e))),this._addToolbarDropdown(e),this._addMenuBarMenu(e);}_addButton(e){this.editor.ui.componentFactory.add(`alignment:${e}`,(t=>this._createButton(t,e)));}_createButton(e,t,i={}){const n=this.editor,s=n.commands.get("alignment"),o=new pg(e);return o.set({label:this.localizedOptionTitles[t],icon:mw.get(t),tooltip:!0,isToggleable:!0,...i}),o.bind("isEnabled").to(s),o.bind("isOn").to(s,"value",(e=>e===t)),this.listenTo(o,"execute",(()=>{n.execute("alignment",{value:t}),n.editing.view.focus();})),o}_addToolbarDropdown(e){const t=this.editor;t.ui.componentFactory.add("alignment",(i=>{const n=Xf(i),s="rtl"===i.uiLanguageDirection?"w":"e",o=i.t;ip(n,(()=>e.map((e=>this._createButton(i,e.name,{tooltipPosition:s})))),{enableActiveItemFocusOnDropdownOpen:!0,isVertical:!0,ariaLabel:o("Text alignment toolbar")}),n.buttonView.set({label:o("Text alignment"),tooltip:!0}),n.extendTemplate({attributes:{class:"ck-alignment-dropdown"}});const r="rtl"===i.contentLanguageDirection?mw.get("right"):mw.get("left"),a=t.commands.get("alignment");return n.buttonView.bind("icon").to(a,"value",(e=>mw.get(e)||r)),n.bind("isEnabled").to(a,"isEnabled"),this.listenTo(n,"execute",(()=>{t.editing.view.focus();})),n}));}_addMenuBarMenu(e){const t=this.editor;t.ui.componentFactory.add("menuBar:alignment",(i=>{const n=t.commands.get("alignment"),s=i.t,o=new aw(i),r=new lw(i);o.bind("isEnabled").to(n),r.set({ariaLabel:s("Text alignment"),role:"menu"}),o.buttonView.set({label:s("Text alignment")});for(const s of e){const e=new ub(i,o),a=new Rg(i);a.delegate("execute").to(o),a.set({label:this.localizedOptionTitles[s.name],icon:mw.get(s.name),role:"menuitemcheckbox",isToggleable:!0}),a.on("execute",(()=>{t.execute("alignment",{value:s.name}),t.editing.view.focus();})),a.bind("isOn").to(n,"value",(e=>e===s.name)),a.bind("isEnabled").to(n,"isEnabled"),e.children.add(a),r.items.add(e);}return o.panelView.children.add(r),o}));}}class fw extends Dr{static get requires(){return [Dm,gw]}static get pluginName(){return "Alignment"}static get isOfficialPlugin(){return !0}}class pw{model;limit;_isLocked;_size;_batch=null;_changeCallback;_selectionChangeCallback;constructor(e,t=20){this.model=e,this._size=0,this.limit=t,this._isLocked=!1,this._changeCallback=(e,t)=>{t.isLocal&&t.isUndoable&&t!==this._batch&&this._reset(!0);},this._selectionChangeCallback=()=>{this._reset();},this.model.document.on("change",this._changeCallback),this.model.document.selection.on("change:range",this._selectionChangeCallback),this.model.document.selection.on("change:attribute",this._selectionChangeCallback);}get batch(){return this._batch||(this._batch=this.model.createBatch({isTyping:!0})),this._batch}get size(){return this._size}input(e){this._size+=e,this._size>=this.limit&&this._reset(!0);}get isLocked(){return this._isLocked}lock(){this._isLocked=!0;}unlock(){this._isLocked=!1;}destroy(){this.model.document.off("change",this._changeCallback),this.model.document.selection.off("change:range",this._selectionChangeCallback),this.model.document.selection.off("change:attribute",this._selectionChangeCallback);}_reset(e=!1){this.isLocked&&!e||(this._batch=null,this._size=0);}}class bw extends Hr{_buffer;constructor(e,t){super(e),this._buffer=new pw(e.model,t),this._isEnabledBasedOnSelection=!1;}get buffer(){return this._buffer}destroy(){super.destroy(),this._buffer.destroy();}execute(e={}){const t=this.editor.model,i=t.document,n=e.text||"",s=n.length;let o=i.selection;if(e.selection?o=e.selection:e.range&&(o=t.createSelection(e.range)),!t.canEditAt(o))return;const r=e.resultRange;t.enqueueChange(this._buffer.batch,(e=>{this._buffer.lock();const a=Array.from(i.selection.getAttributes());t.deleteContent(o),n&&t.insertContent(e.createText(n,a),o),r?e.setSelection(r):o.is("documentSelection")||e.setSelection(o),this._buffer.unlock(),this._buffer.input(s);}));}}const ww=["insertText","insertReplacementText"],_w=[...ww,"insertCompositionText"];class vw extends Al{focusObserver;constructor(e){super(e),this.focusObserver=e.getObserver(Rl);const t=o.isAndroid?_w:ww,i=e.document;i.on("beforeinput",((n,s)=>{if(!this.isEnabled)return;const{data:o,targetRanges:r,inputType:a,domEvent:l}=s;if(!t.includes(a))return;this.focusObserver.flush();const c=new v(i,"insertText");i.fire(c,new El(e,l,{text:o,selection:e.createSelection(r)})),c.stop.called&&n.stop();})),o.isAndroid||i.on("compositionend",((t,{data:n,domEvent:s})=>{this.isEnabled&&n&&i.fire("insertText",new El(e,s,{text:n}));}),{priority:"lowest"});}observe(){}stopObserving(){}}class yw extends Dr{_compositionQueue;static get pluginName(){return "Input"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.model,i=e.editing.view,n=e.editing.mapper,s=t.document.selection;this._compositionQueue=new kw(e),i.addObserver(vw);const r=new bw(e,e.config.get("typing.undoStep")||20);e.commands.add("insertText",r),e.commands.add("input",r),this.listenTo(i.document,"insertText",((r,a)=>{i.document.isComposing||a.preventDefault(),o.isAndroid&&i.document.isComposing&&this._compositionQueue.flush("next beforeinput");const{text:l,selection:c}=a;let d;d=c?Array.from(c.getRanges()).map((e=>n.toModelRange(e))):Array.from(s.getRanges());let u=l;if(o.isAndroid){const e=Array.from(d[0].getItems()).reduce(((e,t)=>e+(t.is("$textProxy")?t.data:"")),"");if(e&&(e.length<=u.length?u.startsWith(e)&&(u=u.substring(e.length),d[0].start=d[0].start.getShiftedBy(e.length)):e.startsWith(u)&&(d[0].start=d[0].start.getShiftedBy(u.length),u="")),0==u.length&&d[0].isCollapsed)return}const h={text:u,selection:t.createSelection(d)};o.isAndroid&&i.document.isComposing?this._compositionQueue.push(h):(e.execute("insertText",h),i.scrollToTheSelection());})),o.isAndroid?this.listenTo(i.document,"keydown",((e,n)=>{!s.isCollapsed&&229==n.keyCode&&i.document.isComposing&&Cw(t,r);})):this.listenTo(i.document,"compositionstart",(()=>{s.isCollapsed||Cw(t,r);})),o.isAndroid?(this.listenTo(i.document,"mutations",((e,{mutations:t})=>{if(i.document.isComposing)for(const{node:e}of t){const t=xw(e,n),i=n.toModelElement(t);if(this._compositionQueue.isComposedElement(i))return void this._compositionQueue.flush("mutations")}})),this.listenTo(i.document,"compositionend",(()=>{this._compositionQueue.flush("composition end");})),this.listenTo(i.document,"compositionend",(()=>{const e=[];for(const t of this._compositionQueue.flushComposedElements()){const i=n.toViewElement(t);i&&e.push({type:"children",node:i});}e.length&&i.document.fire("mutations",{mutations:e});}),{priority:"lowest"})):this.listenTo(i.document,"compositionend",(()=>{i.document.fire("mutations",{mutations:[]});}),{priority:"lowest"});}destroy(){super.destroy(),this._compositionQueue.destroy();}}class kw{editor;flushDebounced=vs((()=>this.flush("timeout")),50);_queue=[];_compositionElements=new Set;constructor(e){this.editor=e;}destroy(){for(this.flushDebounced.cancel(),this._compositionElements.clear();this._queue.length;)this.shift();}get length(){return this._queue.length}push(e){const t={text:e.text};if(e.selection){t.selectionRanges=[];for(const i of e.selection.getRanges())t.selectionRanges.push(fc.fromRange(i)),this._compositionElements.add(i.start.parent);}this._queue.push(t),this.flushDebounced();}shift(){const e=this._queue.shift(),t={text:e.text};if(e.selectionRanges){const i=e.selectionRanges.map((e=>function(e){const t=e.toRange();if(e.detach(),"$graveyard"==t.root.rootName)return null;return t}(e))).filter((e=>!!e));i.length&&(t.selection=this.editor.model.createSelection(i));}return t}flush(e){const t=this.editor,i=t.model,n=t.editing.view;if(this.flushDebounced.cancel(),!this._queue.length)return;const s=t.commands.get("insertText").buffer;i.enqueueChange(s.batch,(()=>{for(s.lock();this._queue.length;){const e=this.shift();t.execute("insertText",e);}s.unlock();})),n.scrollToTheSelection();}isComposedElement(e){return this._compositionElements.has(e)}flushComposedElements(){const e=Array.from(this._compositionElements);return this._compositionElements.clear(),e}}function Cw(e,t){if(!t.isEnabled)return;const i=t.buffer;i.lock(),e.enqueueChange(i.batch,(()=>{e.deleteContent(e.document.selection);})),i.unlock();}function xw(e,t){let i=e.is("$text")?e.parent:e;for(;!t.toModelElement(i);)i=i.parent;return i}class Aw extends Hr{direction;_buffer;constructor(e,t){super(e),this.direction=t,this._buffer=new pw(e.model,e.config.get("typing.undoStep")),this._isEnabledBasedOnSelection=!1;}get buffer(){return this._buffer}execute(e={}){const t=this.editor.model,i=t.document;t.enqueueChange(this._buffer.batch,(n=>{this._buffer.lock();const s=n.createSelection(e.selection||i.selection);if(!t.canEditAt(s))return;const o=e.sequence||1,r=s.isCollapsed;if(s.isCollapsed&&t.modifySelection(s,{direction:this.direction,unit:e.unit,treatEmojiAsSingleUnit:!0}),this._shouldEntireContentBeReplacedWithParagraph(o))return void this._replaceEntireContentWithParagraph(n);if(this._shouldReplaceFirstBlockWithParagraph(s,o))return void this.editor.execute("paragraph",{selection:s});if(s.isCollapsed)return;let a=0;s.getFirstRange().getMinimalFlatRanges().forEach((e=>{a+=no(e.getWalker({singleCharacters:!0,ignoreElementEnd:!0,shallow:!0}));})),t.deleteContent(s,{doNotResetEntireContent:r,direction:this.direction}),this._buffer.input(a),n.setSelection(s),this._buffer.unlock();}));}_shouldEntireContentBeReplacedWithParagraph(e){if(e>1)return !1;const t=this.editor.model,i=t.document.selection,n=t.schema.getLimitElement(i);if(!(i.isCollapsed&&i.containsEntireContent(n)))return !1;if(!t.schema.checkChild(n,"paragraph"))return !1;const s=n.getChild(0);return !s||!s.is("element","paragraph")}_replaceEntireContentWithParagraph(e){const t=this.editor.model,i=t.document.selection,n=t.schema.getLimitElement(i),s=e.createElement("paragraph");e.remove(e.createRangeIn(n)),e.insert(s,n),e.setSelection(s,0);}_shouldReplaceFirstBlockWithParagraph(e,t){const i=this.editor.model;if(t>1||"backward"!=this.direction)return !1;if(!e.isCollapsed)return !1;const n=e.getFirstPosition(),s=i.schema.getLimitElement(n),o=s.getChild(0);return n.parent==o&&(!!e.containsEntireContent(o)&&(!!i.schema.checkChild(s,"paragraph")&&"paragraph"!=o.name))}}const Ew="word",Tw="selection",Pw="backward",Sw="forward",Iw={deleteContent:{unit:Tw,direction:Pw},deleteContentBackward:{unit:"codePoint",direction:Pw},deleteWordBackward:{unit:Ew,direction:Pw},deleteHardLineBackward:{unit:Tw,direction:Pw},deleteSoftLineBackward:{unit:Tw,direction:Pw},deleteContentForward:{unit:"character",direction:Sw},deleteWordForward:{unit:Ew,direction:Sw},deleteHardLineForward:{unit:Tw,direction:Sw},deleteSoftLineForward:{unit:Tw,direction:Sw}};class Vw extends Al{constructor(e){super(e);const t=e.document;let i=0;t.on("keydown",(()=>{i++;})),t.on("keyup",(()=>{i=0;})),t.on("beforeinput",((n,s)=>{if(!this.isEnabled)return;const{targetRanges:r,domEvent:a,inputType:l}=s,c=Iw[l];if(!c)return;const d={direction:c.direction,unit:c.unit,sequence:i};d.unit==Tw&&(d.selectionToRemove=e.createSelection(r[0])),"deleteContentBackward"===l&&(o.isAndroid&&(d.sequence=1),function(e){if(1!=e.length||e[0].isCollapsed)return !1;const t=e[0].getWalker({direction:"backward",singleCharacters:!0,ignoreElementEnd:!0});let i=0;for(const{nextPosition:e,item:n}of t){if(e.parent.is("$text")){const t=e.parent.data,n=e.offset;if(Br(t,n)||Mr(t,n)||Fr(t,n))continue;i++;}else (n.is("containerElement")||n.is("emptyElement"))&&i++;if(i>1)return !0}return !1}(r)&&(d.unit=Tw,d.selectionToRemove=e.createSelection(r)));const u=new Ta(t,"delete",r[0]);t.fire(u,new El(e,a,d)),u.stop.called&&n.stop();})),o.isBlink&&function(e){const t=e.view,i=t.document;let n=null,s=!1;function o(e){return e==nr.backspace||e==nr.delete}function r(e){return e==nr.backspace?Pw:Sw}i.on("keydown",((e,{keyCode:t})=>{n=t,s=!1;})),i.on("keyup",((a,{keyCode:l,domEvent:c})=>{const d=i.selection,u=e.isEnabled&&l==n&&o(l)&&!d.isCollapsed&&!s;if(n=null,u){const e=d.getFirstRange(),n=new Ta(i,"delete",e),s={unit:Tw,direction:r(l),selectionToRemove:d};i.fire(n,new El(t,c,s));}})),i.on("beforeinput",((e,{inputType:t})=>{const i=Iw[t];o(n)&&i&&i.direction==r(n)&&(s=!0);}),{priority:"high"}),i.on("beforeinput",((e,{inputType:t,data:i})=>{n==nr.delete&&"insertText"==t&&""==i&&e.stop();}),{priority:"high"});}(this);}observe(){}stopObserving(){}}class Rw extends Dr{_undoOnBackspace;static get pluginName(){return "Delete"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.editing.view,i=t.document,n=e.model.document;t.addObserver(Vw),this._undoOnBackspace=!1;const s=new Aw(e,"forward");e.commands.add("deleteForward",s),e.commands.add("forwardDelete",s),e.commands.add("delete",new Aw(e,"backward")),this.listenTo(i,"delete",((n,s)=>{i.isComposing||s.preventDefault();const{direction:o,sequence:r,selectionToRemove:a,unit:l}=s,c="forward"===o?"deleteForward":"delete",d={sequence:r};if("selection"==l){const t=Array.from(a.getRanges()).map((t=>e.editing.mapper.toModelRange(t)));d.selection=e.model.createSelection(t);}else d.unit=l;e.execute(c,d),t.scrollToTheSelection();}),{priority:"low"}),this.editor.plugins.has("UndoEditing")&&(this.listenTo(i,"delete",((t,i)=>{this._undoOnBackspace&&"backward"==i.direction&&1==i.sequence&&"codePoint"==i.unit&&(this._undoOnBackspace=!1,e.execute("undo"),i.preventDefault(),t.stop());}),{context:"$capture"}),this.listenTo(n,"change",(()=>{this._undoOnBackspace=!1;})));}requestUndoOnBackspace(){this.editor.plugins.has("UndoEditing")&&(this._undoOnBackspace=!0);}}class Ow extends Dr{static get requires(){return [yw,Rw]}static get pluginName(){return "Typing"}static get isOfficialPlugin(){return !0}}function Bw(e,t){let i=e.start;return {text:Array.from(e.getWalker({ignoreElementEnd:!1})).reduce(((e,{item:n})=>n.is("$text")||n.is("$textProxy")?e+n.data:(i=t.createPositionAfter(n),"")),""),range:t.createRange(i,e.end)}}class Mw extends(Zs()){model;testCallback;_hasMatch;constructor(e,t){super(),this.model=e,this.testCallback=t,this._hasMatch=!1,this.set("isEnabled",!0),this.on("change:isEnabled",(()=>{this.isEnabled?this._startListening():(this.stopListening(e.document.selection),this.stopListening(e.document));})),this._startListening();}get hasMatch(){return this._hasMatch}_startListening(){const e=this.model.document;this.listenTo(e.selection,"change:range",((t,{directChange:i})=>{i&&(e.selection.isCollapsed?this._evaluateTextBeforeSelection("selection"):this.hasMatch&&(this.fire("unmatched"),this._hasMatch=!1));})),this.listenTo(e,"change:data",((e,t)=>{!t.isUndo&&t.isLocal&&this._evaluateTextBeforeSelection("data",{batch:t});}));}_evaluateTextBeforeSelection(e,t={}){const i=this.model,n=i.document.selection,s=i.createRange(i.createPositionAt(n.focus.parent,0),n.focus),{text:o,range:r}=Bw(s,i),a=this.testCallback(o);if(!a&&this.hasMatch&&this.fire("unmatched"),this._hasMatch=!!a,a){const i=Object.assign(t,{text:o,range:r});"object"==typeof a&&Object.assign(i,a),this.fire(`matched:${e}`,i);}}}class Lw extends Dr{attributes;_overrideUid;_isNextGravityRestorationSkipped=!1;static get pluginName(){return "TwoStepCaretMovement"}static get isOfficialPlugin(){return !0}constructor(e){super(e),this.attributes=new Set,this._overrideUid=null;}init(){const e=this.editor,t=e.model,i=e.editing.view,n=e.locale,s=t.document.selection;this.listenTo(i.document,"arrowKey",((e,t)=>{if(!s.isCollapsed)return;if(t.shiftKey||t.altKey||t.ctrlKey)return;const i=t.keyCode==nr.arrowright,o=t.keyCode==nr.arrowleft;if(!i&&!o)return;const r=n.contentLanguageDirection;let a=!1;a="ltr"===r&&i||"rtl"===r&&o?this._handleForwardMovement(t):this._handleBackwardMovement(t),!0===a&&e.stop();}),{context:"$text",priority:"highest"}),this.listenTo(s,"change:range",((e,t)=>{this._isNextGravityRestorationSkipped?this._isNextGravityRestorationSkipped=!1:this._isGravityOverridden&&(!t.directChange&&$w(s.getFirstPosition(),this.attributes)||this._restoreGravity());})),this._enableClickingAfterNode(),this._enableInsertContentSelectionAttributesFixer(),this._handleDeleteContentAfterNode();}registerAttribute(e){this.attributes.add(e);}_handleForwardMovement(e){const t=this.attributes,i=this.editor.model,n=i.document.selection,s=n.getFirstPosition();return !this._isGravityOverridden&&((!s.isAtStart||!Fw(n,t))&&(!!$w(s,t)&&(zw(e),Fw(n,t)&&$w(s,t,!0)?Dw(i,t):this._overrideGravity(),!0)))}_handleBackwardMovement(e){const t=this.attributes,i=this.editor.model,n=i.document.selection,s=n.getFirstPosition();return this._isGravityOverridden?(zw(e),this._restoreGravity(),$w(s,t,!0)?Dw(i,t):Nw(i,t,s),!0):s.isAtStart?!!Fw(n,t)&&(zw(e),Nw(i,t,s),!0):!Fw(n,t)&&$w(s,t,!0)?(zw(e),Nw(i,t,s),!0):!!Hw(s,t)&&(s.isAtEnd&&!Fw(n,t)&&$w(s,t)?(zw(e),Nw(i,t,s),!0):(this._isNextGravityRestorationSkipped=!0,this._overrideGravity(),!1))}_enableClickingAfterNode(){const e=this.editor,t=e.model,i=t.document.selection,n=e.editing.view.document;e.editing.view.addObserver(Wu);let s=!1;this.listenTo(n,"mousedown",(()=>{s=!0;})),this.listenTo(n,"selectionChange",(()=>{const e=this.attributes;if(!s)return;if(s=!1,!i.isCollapsed)return;if(!Fw(i,e))return;const n=i.getFirstPosition();$w(n,e)&&(n.isAtStart||$w(n,e,!0)?Dw(t,e):this._isGravityOverridden||this._overrideGravity());}));}_enableInsertContentSelectionAttributesFixer(){const e=this.editor.model,t=e.document.selection,i=this.attributes;this.listenTo(e,"insertContent",(()=>{const n=t.getFirstPosition();Fw(t,i)&&$w(n,i)&&Dw(e,i);}),{priority:"low"});}_handleDeleteContentAfterNode(){const e=this.editor,t=e.model,i=t.document.selection,n=e.editing.view;let s=!1,o=!1;this.listenTo(n.document,"delete",((e,t)=>{s="backward"===t.direction;}),{priority:"high"}),this.listenTo(t,"deleteContent",(()=>{if(!s)return;const e=i.getFirstPosition();o=Fw(i,this.attributes)&&!Hw(e,this.attributes);}),{priority:"high"}),this.listenTo(t,"deleteContent",(()=>{s&&(s=!1,o||e.model.enqueueChange((()=>{const e=i.getFirstPosition();Fw(i,this.attributes)&&$w(e,this.attributes)&&(e.isAtStart||$w(e,this.attributes,!0)?Dw(t,this.attributes):this._isGravityOverridden||this._overrideGravity());})));}),{priority:"low"});}get _isGravityOverridden(){return !!this._overrideUid}_overrideGravity(){this._overrideUid=this.editor.model.change((e=>e.overrideSelectionGravity()));}_restoreGravity(){this.editor.model.change((e=>{e.restoreSelectionGravity(this._overrideUid),this._overrideUid=null;}));}}function Fw(e,t){for(const i of t)if(e.hasAttribute(i))return !0;return !1}function Nw(e,t,i){const n=i.nodeBefore;e.change((i=>{if(n){const t=[],s=e.schema.isObject(n)&&e.schema.isInline(n);for(const[i,o]of n.getAttributes())!e.schema.checkAttribute("$text",i)||s&&!1===e.schema.getAttributeProperties(i).copyFromObject||t.push([i,o]);i.setSelectionAttribute(t);}else i.removeSelectionAttribute(t);}));}function Dw(e,t){e.change((e=>{e.removeSelectionAttribute(t);}));}function zw(e){e.preventDefault();}function Hw(e,t){return $w(e.getShiftedBy(-1),t)}function $w(e,t,i=!1){const{nodeBefore:n,nodeAfter:s}=e;for(const e of t){const t=n?n.getAttribute(e):void 0,o=s?s.getAttribute(e):void 0;if((!i||void 0!==t&&void 0!==o)&&o!==t)return !0}return !1}const Uw={copyright:{from:"(c)",to:"©"},registeredTrademark:{from:"(r)",to:"®"},trademark:{from:"(tm)",to:"™"},oneHalf:{from:/(^|[^/a-z0-9])(1\/2)([^/a-z0-9])$/i,to:[null,"½",null]},oneThird:{from:/(^|[^/a-z0-9])(1\/3)([^/a-z0-9])$/i,to:[null,"⅓",null]},twoThirds:{from:/(^|[^/a-z0-9])(2\/3)([^/a-z0-9])$/i,to:[null,"⅔",null]},oneForth:{from:/(^|[^/a-z0-9])(1\/4)([^/a-z0-9])$/i,to:[null,"¼",null]},threeQuarters:{from:/(^|[^/a-z0-9])(3\/4)([^/a-z0-9])$/i,to:[null,"¾",null]},lessThanOrEqual:{from:"<=",to:"≤"},greaterThanOrEqual:{from:">=",to:"≥"},notEqual:{from:"!=",to:"≠"},arrowLeft:{from:"<-",to:"←"},arrowRight:{from:"->",to:"→"},horizontalEllipsis:{from:"...",to:"…"},enDash:{from:/(^| )(--)( )$/,to:[null,"–",null]},emDash:{from:/(^| )(---)( )$/,to:[null,"—",null]},quotesPrimary:{from:Jw('"'),to:[null,"“",null,"”"]},quotesSecondary:{from:Jw("'"),to:[null,"‘",null,"’"]},quotesPrimaryEnGb:{from:Jw("'"),to:[null,"‘",null,"’"]},quotesSecondaryEnGb:{from:Jw('"'),to:[null,"“",null,"”"]},quotesPrimaryPl:{from:Jw('"'),to:[null,"„",null,"”"]},quotesSecondaryPl:{from:Jw("'"),to:[null,"‚",null,"’"]}},Ww={symbols:["copyright","registeredTrademark","trademark"],mathematical:["oneHalf","oneThird","twoThirds","oneForth","threeQuarters","lessThanOrEqual","greaterThanOrEqual","notEqual","arrowLeft","arrowRight"],typography:["horizontalEllipsis","enDash","emDash"],quotes:["quotesPrimary","quotesSecondary"]},jw=["symbols","mathematical","typography","quotes"];class qw extends Dr{static get requires(){return ["Delete","Input"]}static get pluginName(){return "TextTransformation"}static get isOfficialPlugin(){return !0}constructor(e){super(e),e.config.define("typing",{transformations:{include:jw}});}init(){const e=this.editor.model.document.selection;e.on("change:range",(()=>{this.isEnabled=!e.anchor.parent.is("element","codeBlock");})),this._enableTransformationWatchers();}_enableTransformationWatchers(){const e=this.editor,t=e.model,i=e.plugins.get("Delete"),n=function(e){const t=e.extra||[],i=e.remove||[],n=e=>!i.includes(e);return function(e){const t=new Set;for(const i of e)if("string"==typeof i&&Ww[i])for(const e of Ww[i])t.add(e);else t.add(i);return Array.from(t)}(e.include.concat(t).filter(n)).filter(n).map((e=>"string"==typeof e&&Uw[e]?Uw[e]:e)).filter((e=>"object"==typeof e)).map((e=>({from:Gw(e.from),to:Kw(e.to)})))}(e.config.get("typing.transformations")),s=new Mw(e.model,(e=>{for(const t of n){if(t.from.test(e))return {normalizedTransformation:t}}}));s.on("matched:data",((e,n)=>{if(!n.batch.isTyping)return;const{from:s,to:o}=n.normalizedTransformation,r=s.exec(n.text),a=o(r.slice(1)),l=n.range;let c=r.index;t.enqueueChange((e=>{for(let i=1;i{i.requestUndoOnBackspace();}));}));})),s.bind("isEnabled").to(this);}}function Gw(e){return "string"==typeof e?new RegExp(`(${Rs(e)})$`):e}function Kw(e){return "string"==typeof e?()=>[e]:e instanceof Array?()=>e:e}function Zw(e){return (e.textNode?e.textNode:e.nodeAfter).getAttributes()}function Jw(e){return new RegExp(`(^|\\s)(${e})([^${e}]*)(${e})$`)}function Qw(e,t,i,n){return n.createRange(Yw(e,t,i,!0,n),Yw(e,t,i,!1,n))}function Yw(e,t,i,n,s){let o=e.textNode||(n?e.nodeBefore:e.nodeAfter),r=null;for(;o&&o.getAttribute(t)==i;)r=o,o=n?o.previousSibling:o.nextSibling;return r?s.createPositionAt(r,n?"before":"after"):e}function Xw(e,t,i,n){const s=e.editing.view,o=new Set;s.document.registerPostFixer((s=>{const r=e.model.document.selection;let a=!1;if(r.hasAttribute(t)){const l=Qw(r.getFirstPosition(),t,r.getAttribute(t),e.model),c=e.editing.mapper.toViewRange(l);for(const e of c.getItems())e.is("element",i)&&!e.hasClass(n)&&(s.addClass(n,e),o.add(e),a=!0);}return a})),e.conversion.for("editingDowncast").add((e=>{function t(){s.change((e=>{for(const t of o.values())e.removeClass(n,t),o.delete(t);}));}e.on("insert",t,{priority:"highest"}),e.on("remove",t,{priority:"highest"}),e.on("attribute",t,{priority:"highest"}),e.on("selection",t,{priority:"highest"});}));}function e_(e,t,i,n){let s,o=null;"function"==typeof n?s=n:(o=e.commands.get(n),s=()=>{e.execute(n);}),e.model.document.on("change:data",((r,a)=>{if(o&&!o.isEnabled||!t.isEnabled)return;const l=wr(e.model.document.selection.getRanges());if(!l.isCollapsed)return;if(a.isUndo||!a.isLocal)return;const c=Array.from(e.model.document.differ.getChanges()),d=c[0];if(1!=c.length||"insert"!==d.type||"$text"!=d.name||1!=d.length)return;const u=d.position.parent;if(u.is("element","codeBlock"))return;if(u.is("element","listItem")&&"function"!=typeof n&&!["numberedList","bulletedList","todoList"].includes(n))return;if(o&&!0===o.value)return;const h=u.getChild(0),m=e.model.createRangeOn(h);if(!m.containsRange(l)&&!l.end.isEqual(m.end))return;const g=i.exec(h.data.substr(0,l.end.offset));g&&e.model.enqueueChange((t=>{const i=t.createPositionAt(u,0),n=t.createPositionAt(u,g[0].length),o=new fc(i,n);if(!1!==s({match:g})){t.remove(o);const i=e.model.document.selection.getFirstRange(),n=t.createRangeIn(u);!u.isEmpty||n.isEqual(i)||n.containsRange(i,!0)||t.remove(u);}o.detach(),e.model.enqueueChange((()=>{e.plugins.get("Delete").requestUndoOnBackspace();}));}));}));}function t_(e,t,i,n){let s,o;i instanceof RegExp?s=i:o=i,o=o||(e=>{let t;const i=[],n=[];for(;null!==(t=s.exec(e))&&!(t&&t.length<4);){let{index:e,1:s,2:o,3:r}=t;const a=s+o+r;e+=t[0].length-a.length;const l=[e,e+s.length],c=[e+s.length+o.length,e+s.length+o.length+r.length];i.push(l),i.push(c),n.push([e+s.length,e+s.length+o.length]);}return {remove:i,format:n}}),e.model.document.on("change:data",((i,s)=>{if(s.isUndo||!s.isLocal||!t.isEnabled)return;const r=e.model,a=r.document.selection;if(!a.isCollapsed)return;const l=Array.from(r.document.differ.getChanges()),c=l[0];if(1!=l.length||"insert"!==c.type||"$text"!=c.name||1!=c.length)return;const d=a.focus,u=d.parent,{text:h,range:m}=function(e,t){let i=e.start;const n=Array.from(e.getItems()).reduce(((e,n)=>!n.is("$text")&&!n.is("$textProxy")||n.getAttribute("code")?(i=t.createPositionAfter(n),""):e+n.data),"");return {text:n,range:t.createRange(i,e.end)}}(r.createRange(r.createPositionAt(u,0),d),r),g=o(h),f=i_(m.start,g.format,r),p=i_(m.start,g.remove,r);f.length&&p.length&&r.enqueueChange((t=>{if(!1!==n(t,f)){for(const e of p.reverse())t.remove(e);r.enqueueChange((()=>{e.plugins.get("Delete").requestUndoOnBackspace();}));}}));}));}function i_(e,t,i){return t.filter((e=>void 0!==e[0]&&void 0!==e[1])).map((t=>i.createRange(e.getShiftedBy(t[0]),e.getShiftedBy(t[1]))))}class n_ extends Dr{static get requires(){return [Rw]}static get pluginName(){return "Autoformat"}static get isOfficialPlugin(){return !0}afterInit(){const e=this.editor,t=this.editor.t;this._addListAutoformats(),this._addBasicStylesAutoformats(),this._addHeadingAutoformats(),this._addBlockQuoteAutoformats(),this._addCodeBlockAutoformats(),this._addHorizontalLineAutoformats(),e.accessibility.addKeystrokeInfos({keystrokes:[{label:t("Revert autoformatting action"),keystroke:"Backspace"}]});}_addListAutoformats(){const e=this.editor.commands;e.get("bulletedList")&&e_(this.editor,this,/^[*-]\s$/,"bulletedList"),e.get("numberedList")&&e_(this.editor,this,/^1[.|)]\s$/,"numberedList"),e.get("todoList")&&e_(this.editor,this,/^\[\s?\]\s$/,"todoList"),e.get("checkTodoList")&&e_(this.editor,this,/^\[\s?x\s?\]\s$/,(()=>{this.editor.execute("todoList"),this.editor.execute("checkTodoList");}));}_addBasicStylesAutoformats(){const e=this.editor.commands;if(e.get("bold")){const e=s_(this.editor,"bold");t_(this.editor,this,/(?:^|\s)(\*\*)([^*]+)(\*\*)$/g,e),t_(this.editor,this,/(?:^|\s)(__)([^_]+)(__)$/g,e);}if(e.get("italic")){const e=s_(this.editor,"italic");t_(this.editor,this,/(?:^|\s)(\*)([^*_]+)(\*)$/g,e),t_(this.editor,this,/(?:^|\s)(_)([^_]+)(_)$/g,e);}if(e.get("code")){const e=s_(this.editor,"code");t_(this.editor,this,/(`)([^`]+)(`)$/g,e);}if(e.get("strikethrough")){const e=s_(this.editor,"strikethrough");t_(this.editor,this,/(~~)([^~]+)(~~)$/g,e);}}_addHeadingAutoformats(){const e=this.editor.commands.get("heading");e&&e.modelElements.filter((e=>e.match(/^heading[1-6]$/))).forEach((t=>{const i=t[7],n=new RegExp(`^(#{${i}})\\s$`);e_(this.editor,this,n,(()=>{if(!e.isEnabled||e.value===t)return !1;this.editor.execute("heading",{value:t});}));}));}_addBlockQuoteAutoformats(){this.editor.commands.get("blockQuote")&&e_(this.editor,this,/^>\s$/,"blockQuote");}_addCodeBlockAutoformats(){const e=this.editor,t=e.model.document.selection;e.commands.get("codeBlock")&&e_(e,this,/^```$/,(()=>{if(t.getFirstPosition().parent.is("element","listItem"))return !1;this.editor.execute("codeBlock",{usePreviousLanguageChoice:!0});}));}_addHorizontalLineAutoformats(){this.editor.commands.get("horizontalLine")&&e_(this.editor,this,/^---$/,"horizontalLine");}}function s_(e,t){return (i,n)=>{if(!e.commands.get(t).isEnabled)return !1;const s=e.model.schema.getValidRanges(n,t);for(const e of s)i.setAttribute(t,!0,e);i.removeSelectionAttribute(t);}}class o_ extends Dr{adapter;_debouncedSave;_lastDocumentVersion;_savePromise;_domEmitter;_config;_pendingActions;_makeImmediateSave;_action=null;static get pluginName(){return "Autosave"}static get isOfficialPlugin(){return !0}static get requires(){return [_m]}constructor(e){super(e);const t=e.config.get("autosave")||{},i=t.waitingTime||1e3;this.set("state","synchronized"),this._debouncedSave=vs(this._save.bind(this),i),this._lastDocumentVersion=e.model.document.version,this._savePromise=null,this._domEmitter=new(go()),this._config=t,this._pendingActions=e.plugins.get(_m),this._makeImmediateSave=!1;}init(){const e=this.editor,t=e.model.document;this.listenTo(e,"ready",(()=>{this.listenTo(t,"change:data",((e,t)=>{this._saveCallbacks.length&&t.isLocal&&("synchronized"===this.state&&(this.state="waiting",this._setPendingAction()),"waiting"===this.state&&this._debouncedSave());}));})),this.listenTo(e,"destroy",(()=>this._flush()),{priority:"highest"}),this._domEmitter.listenTo(window,"beforeunload",((e,t)=>{this._pendingActions.hasAny&&(t.returnValue=this._pendingActions.first.message);}));}destroy(){this._domEmitter.stopListening(),super.destroy();}save(){return this._debouncedSave.cancel(),this._save()}_flush(){this._debouncedSave.flush();}_save(){return this._savePromise?(this._makeImmediateSave=this.editor.model.document.version>this._lastDocumentVersion,this._savePromise):(this._setPendingAction(),this.state="saving",this._lastDocumentVersion=this.editor.model.document.version,this._savePromise=Promise.resolve().then((()=>Promise.all(this._saveCallbacks.map((e=>e(this.editor)))))).finally((()=>{this._savePromise=null;})).then((()=>{if(this._makeImmediateSave)return this._makeImmediateSave=!1,this._save();this.editor.model.document.version>this._lastDocumentVersion?(this.state="waiting",this._debouncedSave()):(this.state="synchronized",this._pendingActions.remove(this._action),this._action=null);})).catch((e=>{throw this.state="error",this.state="saving",this._debouncedSave(),e})),this._savePromise)}_setPendingAction(){const e=this.editor.t;this._action||(this._action=this._pendingActions.add(e("Saving changes")));}get _saveCallbacks(){const e=[];return this.adapter&&this.adapter.save&&e.push(this.adapter.save),this._config.save&&e.push(this._config.save),e}}class r_ extends Hr{attributeKey;constructor(e,t){super(e),this.attributeKey=t;}refresh(){const e=this.editor.model,t=e.document;this.value=this._getValueFromFirstAllowedNode(),this.isEnabled=e.schema.checkAttributeInSelection(t.selection,this.attributeKey);}execute(e={}){const t=this.editor.model,i=t.document.selection,n=void 0===e.forceValue?!this.value:e.forceValue;t.change((e=>{if(i.isCollapsed)n?e.setSelectionAttribute(this.attributeKey,!0):e.removeSelectionAttribute(this.attributeKey);else {const s=t.schema.getValidRanges(i.getRanges(),this.attributeKey);for(const t of s)n?e.setAttribute(this.attributeKey,n,t):e.removeAttribute(this.attributeKey,t);}}));}_getValueFromFirstAllowedNode(){const e=this.editor.model,t=e.schema,i=e.document.selection;if(i.isCollapsed)return i.hasAttribute(this.attributeKey);for(const e of i.getRanges())for(const i of e.getItems())if(t.checkAttribute(i,this.attributeKey))return i.hasAttribute(this.attributeKey);return !1}}const a_="bold";class l_ extends Dr{static get pluginName(){return "BoldEditing"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=this.editor.t;e.model.schema.extend("$text",{allowAttributes:a_}),e.model.schema.setAttributeProperties(a_,{isFormatting:!0,copyOnEnter:!0}),e.conversion.attributeToElement({model:a_,view:"strong",upcastAlso:["b",e=>{const t=e.getStyle("font-weight");return t&&("bold"==t||Number(t)>=600)?{name:!0,styles:["font-weight"]}:null}]}),e.commands.add(a_,new r_(e,a_)),e.keystrokes.set("CTRL+B",a_),e.accessibility.addKeystrokeInfos({keystrokes:[{label:t("Bold text"),keystroke:"CTRL+B"}]});}}function c_({editor:e,commandName:t,plugin:i,icon:n,label:s,keystroke:o}){return r=>{const a=e.commands.get(t),l=new r(e.locale);return l.set({label:s,icon:n,keystroke:o,isToggleable:!0}),l.bind("isEnabled").to(a,"isEnabled"),l.bind("isOn").to(a,"value"),l instanceof Rg?l.set({role:"menuitemcheckbox"}):l.set({tooltip:!0}),i.listenTo(l,"execute",(()=>{e.execute(t),e.editing.view.focus();})),l}}const d_="bold";class u_ extends Dr{static get pluginName(){return "BoldUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.locale.t,i=c_({editor:e,commandName:d_,plugin:this,icon:vm.bold,label:t("Bold"),keystroke:"CTRL+B"});e.ui.componentFactory.add(d_,(()=>i(pg))),e.ui.componentFactory.add("menuBar:"+d_,(()=>i(Rg)));}}class h_ extends Dr{static get requires(){return [l_,u_]}static get pluginName(){return "Bold"}static get isOfficialPlugin(){return !0}}const m_="code";class g_ extends Dr{static get pluginName(){return "CodeEditing"}static get isOfficialPlugin(){return !0}static get requires(){return [Lw]}init(){const e=this.editor,t=this.editor.t;e.model.schema.extend("$text",{allowAttributes:m_}),e.model.schema.setAttributeProperties(m_,{isFormatting:!0,copyOnEnter:!1}),e.conversion.attributeToElement({model:m_,view:"code",upcastAlso:{styles:{"word-wrap":"break-word"}}}),e.commands.add(m_,new r_(e,m_)),e.plugins.get(Lw).registerAttribute(m_),Xw(e,m_,"code","ck-code_selected"),e.accessibility.addKeystrokeInfos({keystrokes:[{label:t("Move out of an inline code style"),keystroke:[["arrowleft","arrowleft"],["arrowright","arrowright"]]}]});}}const f_="code";class p_ extends Dr{static get pluginName(){return "CodeUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.locale.t,i=c_({editor:e,commandName:f_,plugin:this,icon:'',label:t("Code")});e.ui.componentFactory.add(f_,(()=>i(pg))),e.ui.componentFactory.add("menuBar:"+f_,(()=>i(Rg)));}}class b_ extends Dr{static get requires(){return [g_,p_]}static get pluginName(){return "Code"}static get isOfficialPlugin(){return !0}}const w_="italic";class __ extends Dr{static get pluginName(){return "ItalicEditing"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=this.editor.t;e.model.schema.extend("$text",{allowAttributes:w_}),e.model.schema.setAttributeProperties(w_,{isFormatting:!0,copyOnEnter:!0}),e.conversion.attributeToElement({model:w_,view:"i",upcastAlso:["em",{styles:{"font-style":"italic"}}]}),e.commands.add(w_,new r_(e,w_)),e.keystrokes.set("CTRL+I",w_),e.accessibility.addKeystrokeInfos({keystrokes:[{label:t("Italic text"),keystroke:"CTRL+I"}]});}}const v_="italic";class y_ extends Dr{static get pluginName(){return "ItalicUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.locale.t,i=c_({editor:e,commandName:v_,plugin:this,icon:'',keystroke:"CTRL+I",label:t("Italic")});e.ui.componentFactory.add(v_,(()=>i(pg))),e.ui.componentFactory.add("menuBar:"+v_,(()=>i(Rg)));}}class k_ extends Dr{static get requires(){return [__,y_]}static get pluginName(){return "Italic"}static get isOfficialPlugin(){return !0}}const C_="strikethrough";class x_ extends Dr{static get pluginName(){return "StrikethroughEditing"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=this.editor.t;e.model.schema.extend("$text",{allowAttributes:C_}),e.model.schema.setAttributeProperties(C_,{isFormatting:!0,copyOnEnter:!0}),e.conversion.attributeToElement({model:C_,view:"s",upcastAlso:["del","strike",{styles:{"text-decoration":"line-through"}}]}),e.commands.add(C_,new r_(e,C_)),e.keystrokes.set("CTRL+SHIFT+X","strikethrough"),e.accessibility.addKeystrokeInfos({keystrokes:[{label:t("Strikethrough text"),keystroke:"CTRL+SHIFT+X"}]});}}const A_="strikethrough";class E_ extends Dr{static get pluginName(){return "StrikethroughUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.locale.t,i=c_({editor:e,commandName:A_,plugin:this,icon:'',keystroke:"CTRL+SHIFT+X",label:t("Strikethrough")});e.ui.componentFactory.add(A_,(()=>i(pg))),e.ui.componentFactory.add("menuBar:"+A_,(()=>i(Rg)));}}class T_ extends Dr{static get requires(){return [x_,E_]}static get pluginName(){return "Strikethrough"}static get isOfficialPlugin(){return !0}}const P_="subscript";class S_ extends Dr{static get pluginName(){return "SubscriptEditing"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;e.model.schema.extend("$text",{allowAttributes:P_}),e.model.schema.setAttributeProperties(P_,{isFormatting:!0,copyOnEnter:!0}),e.conversion.attributeToElement({model:P_,view:"sub",upcastAlso:[{styles:{"vertical-align":"sub"}}]}),e.commands.add(P_,new r_(e,P_));}}const I_="subscript";class V_ extends Dr{static get pluginName(){return "SubscriptUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.locale.t,i=c_({editor:e,commandName:I_,plugin:this,icon:'',label:t("Subscript")});e.ui.componentFactory.add(I_,(()=>i(pg))),e.ui.componentFactory.add("menuBar:"+I_,(()=>i(Rg)));}}class R_ extends Dr{static get requires(){return [S_,V_]}static get pluginName(){return "Subscript"}static get isOfficialPlugin(){return !0}}const O_="superscript";class B_ extends Dr{static get pluginName(){return "SuperscriptEditing"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;e.model.schema.extend("$text",{allowAttributes:O_}),e.model.schema.setAttributeProperties(O_,{isFormatting:!0,copyOnEnter:!0}),e.conversion.attributeToElement({model:O_,view:"sup",upcastAlso:[{styles:{"vertical-align":"super"}}]}),e.commands.add(O_,new r_(e,O_));}}const M_="superscript";class L_ extends Dr{static get pluginName(){return "SuperscriptUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.locale.t,i=c_({editor:e,commandName:M_,plugin:this,icon:'',label:t("Superscript")});e.ui.componentFactory.add(M_,(()=>i(pg))),e.ui.componentFactory.add("menuBar:"+M_,(()=>i(Rg)));}}class F_ extends Dr{static get requires(){return [B_,L_]}static get pluginName(){return "Superscript"}static get isOfficialPlugin(){return !0}}const N_="underline";class D_ extends Dr{static get pluginName(){return "UnderlineEditing"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=this.editor.t;e.model.schema.extend("$text",{allowAttributes:N_}),e.model.schema.setAttributeProperties(N_,{isFormatting:!0,copyOnEnter:!0}),e.conversion.attributeToElement({model:N_,view:"u",upcastAlso:{styles:{"text-decoration":"underline"}}}),e.commands.add(N_,new r_(e,N_)),e.keystrokes.set("CTRL+U","underline"),e.accessibility.addKeystrokeInfos({keystrokes:[{label:t("Underline text"),keystroke:"CTRL+U"}]});}}const z_="underline";class H_ extends Dr{static get pluginName(){return "UnderlineUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.locale.t,i=c_({editor:e,commandName:z_,plugin:this,icon:'',label:t("Underline"),keystroke:"CTRL+U"});e.ui.componentFactory.add(z_,(()=>i(pg))),e.ui.componentFactory.add("menuBar:"+z_,(()=>i(Rg)));}}class $_ extends Dr{static get requires(){return [D_,H_]}static get pluginName(){return "Underline"}static get isOfficialPlugin(){return !0}}function*U_(e,t){for(const i of t)i&&e.getAttributeProperties(i[0]).copyOnEnter&&(yield i);}class W_ extends Hr{execute(){this.editor.model.change((e=>{this.enterBlock(e),this.fire("afterExecute",{writer:e});}));}enterBlock(e){const t=this.editor.model,i=t.document.selection,n=t.schema,s=i.isCollapsed,o=i.getFirstRange(),r=o.start.parent,a=o.end.parent;if(n.isLimit(r)||n.isLimit(a))return s||r!=a||t.deleteContent(i),!1;if(s){const t=U_(e.model.schema,i.getAttributes());return j_(e,o.start),e.setSelectionAttribute(t),!0}{const n=!(o.start.isAtStart&&o.end.isAtEnd),s=r==a;if(t.deleteContent(i,{leaveUnmerged:n}),n){if(s)return j_(e,i.focus),!0;e.setSelection(a,0);}}return !1}}function j_(e,t){e.split(t),e.setSelection(t.parent.nextSibling,0);}const q_={insertParagraph:{isSoft:!1},insertLineBreak:{isSoft:!0}};class G_ extends Al{constructor(e){super(e);const t=this.document;let i=!1;t.on("keydown",((e,t)=>{i=t.shiftKey;})),t.on("beforeinput",((n,s)=>{if(!this.isEnabled)return;let r=s.inputType;o.isSafari&&i&&"insertParagraph"==r&&(r="insertLineBreak");const a=s.domEvent,l=q_[r];if(!l)return;const c=new Ta(t,"enter",s.targetRanges[0]);t.fire(c,new El(e,a,{isSoft:l.isSoft})),c.stop.called&&n.stop();}));}observe(){}stopObserving(){}}class K_ extends Dr{static get pluginName(){return "Enter"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.editing.view,i=t.document,n=this.editor.t;t.addObserver(G_),e.commands.add("enter",new W_(e)),this.listenTo(i,"enter",((n,s)=>{i.isComposing||s.preventDefault(),s.isSoft||(e.execute("enter"),t.scrollToTheSelection());}),{priority:"low"}),e.accessibility.addKeystrokeInfos({keystrokes:[{label:n("Insert a hard break (a new paragraph)"),keystroke:"Enter"}]});}}class Z_ extends Hr{execute(){const e=this.editor.model,t=e.document;e.change((i=>{!function(e,t,i){const n=i.isCollapsed,s=i.getFirstRange(),o=s.start.parent,r=s.end.parent,a=o==r;if(n){const n=U_(e.schema,i.getAttributes());J_(e,t,s.end),t.removeSelectionAttribute(i.getAttributeKeys()),t.setSelectionAttribute(n);}else {const n=!(s.start.isAtStart&&s.end.isAtEnd);e.deleteContent(i,{leaveUnmerged:n}),a?J_(e,t,i.focus):n&&t.setSelection(r,0);}}(e,i,t.selection),this.fire("afterExecute",{writer:i});}));}refresh(){const e=this.editor.model,t=e.document;this.isEnabled=function(e,t){if(t.rangeCount>1)return !1;const i=t.anchor;if(!i||!e.checkChild(i,"softBreak"))return !1;const n=t.getFirstRange(),s=n.start.parent,o=n.end.parent;if((Q_(s,e)||Q_(o,e))&&s!==o)return !1;return !0}(e.schema,t.selection);}}function J_(e,t,i){const n=t.createElement("softBreak");e.insertContent(n,i),t.setSelection(n,"after");}function Q_(e,t){return !e.is("rootElement")&&(t.isLimit(e)||Q_(e.parent,t))}class Y_ extends Dr{static get pluginName(){return "ShiftEnter"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.model.schema,i=e.conversion,n=e.editing.view,s=n.document,o=this.editor.t;t.register("softBreak",{allowWhere:"$text",isInline:!0}),i.for("upcast").elementToElement({model:"softBreak",view:"br"}),i.for("downcast").elementToElement({model:"softBreak",view:(e,{writer:t})=>t.createEmptyElement("br")}),n.addObserver(G_),e.commands.add("shiftEnter",new Z_(e)),this.listenTo(s,"enter",((t,i)=>{s.isComposing||i.preventDefault(),i.isSoft&&(e.execute("shiftEnter"),n.scrollToTheSelection());}),{priority:"low"}),e.accessibility.addKeystrokeInfos({keystrokes:[{label:o("Insert a soft break (a <br> element)"),keystroke:"Shift+Enter"}]});}}class X_ extends Hr{refresh(){this.value=this._getValue(),this.isEnabled=this._checkEnabled();}execute(e={}){const t=this.editor.model,i=t.schema,n=t.document.selection,s=Array.from(n.getSelectedBlocks()),o=void 0===e.forceValue?!this.value:e.forceValue;t.change((e=>{if(o){const t=s.filter((e=>ev(e)||iv(i,e)));this._applyQuote(e,t);}else this._removeQuote(e,s.filter(ev));}));}_getValue(){const e=wr(this.editor.model.document.selection.getSelectedBlocks());return !(!e||!ev(e))}_checkEnabled(){if(this.value)return !0;const e=this.editor.model.document.selection,t=this.editor.model.schema,i=wr(e.getSelectedBlocks());return !!i&&iv(t,i)}_removeQuote(e,t){tv(e,t).reverse().forEach((t=>{if(t.start.isAtStart&&t.end.isAtEnd)return void e.unwrap(t.start.parent);if(t.start.isAtStart){const i=e.createPositionBefore(t.start.parent);return void e.move(t,i)}t.end.isAtEnd||e.split(t.end);const i=e.createPositionAfter(t.end.parent);e.move(t,i);}));}_applyQuote(e,t){const i=[];tv(e,t).reverse().forEach((t=>{let n=ev(t.start);n||(n=e.createElement("blockQuote"),e.wrap(t,n)),i.push(n);})),i.reverse().reduce(((t,i)=>t.nextSibling==i?(e.merge(e.createPositionAfter(t)),t):i));}}function ev(e){return "blockQuote"==e.parent.name?e.parent:null}function tv(e,t){let i,n=0;const s=[];for(;n{const n=e.model.document.differ.getChanges();for(const e of n)if("insert"==e.type){const n=e.position.nodeAfter;if(!n)continue;if(n.is("element","blockQuote")&&n.isEmpty)return i.remove(n),!0;if(n.is("element","blockQuote")&&!t.checkChild(e.position,n))return i.unwrap(n),!0;if(n.is("element")){const e=i.createRangeIn(n);for(const n of e.getItems())if(n.is("element","blockQuote")&&!t.checkChild(i.createPositionBefore(n),n))return i.unwrap(n),!0}}else if("remove"==e.type){const t=e.position.parent;if(t.is("element","blockQuote")&&t.isEmpty)return i.remove(t),!0}return !1}));const i=this.editor.editing.view.document,n=e.model.document.selection,s=e.commands.get("blockQuote");this.listenTo(i,"enter",((t,i)=>{if(!n.isCollapsed||!s.value)return;n.getLastPosition().parent.isEmpty&&(e.execute("blockQuote"),e.editing.view.scrollToTheSelection(),i.preventDefault(),t.stop());}),{context:"blockquote"}),this.listenTo(i,"delete",((t,i)=>{if("backward"!=i.direction||!n.isCollapsed||!s.value)return;const o=n.getLastPosition().parent;o.isEmpty&&!o.previousSibling&&(e.execute("blockQuote"),e.editing.view.scrollToTheSelection(),i.preventDefault(),t.stop());}),{context:"blockquote"});}}class sv extends Dr{static get pluginName(){return "BlockQuoteUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;e.ui.componentFactory.add("blockQuote",(()=>{const e=this._createButton(pg);return e.set({tooltip:!0}),e})),e.ui.componentFactory.add("menuBar:blockQuote",(()=>{const e=this._createButton(Rg);return e.set({role:"menuitemcheckbox"}),e}));}_createButton(e){const t=this.editor,i=t.locale,n=t.commands.get("blockQuote"),s=new e(t.locale),o=i.t;return s.set({label:o("Block quote"),icon:vm.quote,isToggleable:!0}),s.bind("isEnabled").to(n,"isEnabled"),s.bind("isOn").to(n,"value"),this.listenTo(s,"execute",(()=>{t.execute("blockQuote"),t.editing.view.focus();})),s}}class ov extends Dr{static get requires(){return [nv,sv]}static get pluginName(){return "BlockQuote"}static get isOfficialPlugin(){return !0}}class rv extends Dr{static get pluginName(){return "CKBoxUI"}static get isOfficialPlugin(){return !0}afterInit(){const e=this.editor;e.commands.get("ckbox")&&(e.ui.componentFactory.add("ckbox",(()=>this._createFileToolbarButton())),e.ui.componentFactory.add("menuBar:ckbox",(()=>this._createFileMenuBarButton())),e.plugins.has("ImageInsertUI")&&e.plugins.get("ImageInsertUI").registerIntegration({name:"assetManager",observable:()=>e.commands.get("ckbox"),buttonViewCreator:()=>this._createImageToolbarButton(),formViewCreator:()=>this._createImageDropdownButton(),menuBarButtonViewCreator:e=>this._createImageMenuBarButton(e?"insertOnly":"insertNested")}));}_createButton(e){const t=this.editor,i=new e(t.locale),n=t.commands.get("ckbox");return i.bind("isOn","isEnabled").to(n,"value","isEnabled"),i.on("execute",(()=>{t.execute("ckbox");})),i}_createFileToolbarButton(){const e=this.editor.locale.t,t=this._createButton(pg);return t.icon=vm.browseFiles,t.label=e("Open file manager"),t.tooltip=!0,t}_createImageToolbarButton(){const e=this.editor.locale.t,t=this.editor.plugins.get("ImageInsertUI"),i=this._createButton(pg);return i.icon=vm.imageAssetManager,i.bind("label").to(t,"isImageSelected",(t=>e(t?"Replace image with file manager":"Insert image with file manager"))),i.tooltip=!0,i}_createImageDropdownButton(){const e=this.editor.locale.t,t=this.editor.plugins.get("ImageInsertUI"),i=this._createButton(pg);return i.icon=vm.imageAssetManager,i.withText=!0,i.bind("label").to(t,"isImageSelected",(t=>e(t?"Replace with file manager":"Insert with file manager"))),i.on("execute",(()=>{t.dropdownView.isOpen=!1;})),i}_createFileMenuBarButton(){const e=this.editor.locale.t,t=this._createButton(Rg);return t.icon=vm.browseFiles,t.withText=!0,t.label=e("File"),t}_createImageMenuBarButton(e){const t=this.editor.locale.t,i=this.editor.locale.t,n=this._createButton(Rg);switch(n.icon=vm.imageAssetManager,n.withText=!0,e){case"insertOnly":n.label=t("Image");break;case"insertNested":n.label=i("With file manager");}return n}}var av=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","#","$","%","*","+",",","-",".",":",";","=","?","@","[","]","^","_","{","|","}","~"],lv=e=>{let t=0;for(let i=0;i{let t=e/255;return t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)},dv=e=>{let t=Math.max(0,Math.min(1,e));return t<=.0031308?Math.trunc(12.92*t*255+.5):Math.trunc(255*(1.055*Math.pow(t,.4166666666666667)-.055)+.5)},uv=(e,t)=>(e=>e<0?-1:1)(e)*Math.pow(Math.abs(e),t),hv=class extends Error{constructor(e){super(e),this.name="ValidationError",this.message=e;}},mv=e=>{let t=e>>8&255,i=255&e;return [cv(e>>16),cv(t),cv(i)]},gv=(e,t)=>{let i=Math.floor(e/361),n=Math.floor(e/19)%19,s=e%19;return [uv((i-9)/9,2)*t,uv((n-9)/9,2)*t,uv((s-9)/9,2)*t]},fv=(e,t,i,n)=>{(e=>{if(!e||e.length<6)throw new hv("The blurhash string must be at least 6 characters");let t=lv(e[0]),i=Math.floor(t/9)+1,n=t%9+1;if(e.length!==4+2*n*i)throw new hv(`blurhash length mismatch: length is ${e.length} but it should be ${4+2*n*i}`)})(e),n|=1;let s=lv(e[0]),o=Math.floor(s/9)+1,r=s%9+1,a=(lv(e[1])+1)/166,l=new Array(r*o);for(let t=0;ti&&(i=s),t.push(`${e[n]} ${n}w`));}const n=[{srcset:t.join(","),sizes:`(max-width: ${i}px) 100vw, ${i}px`,type:"image/webp"}];return {imageFallbackUrl:e.default,imageSources:n}}function bv({url:e,method:t="GET",data:i,onUploadProgress:n,signal:s,authorization:o}){const r=new XMLHttpRequest;r.open(t,e.toString()),r.setRequestHeader("Authorization",o),r.setRequestHeader("CKBox-Version","CKEditor 5"),r.responseType="json";const a=()=>{r.abort();};return new Promise(((e,t)=>{s.throwIfAborted(),s.addEventListener("abort",a),r.addEventListener("loadstart",(()=>{s.addEventListener("abort",a);})),r.addEventListener("loadend",(()=>{s.removeEventListener("abort",a);})),r.addEventListener("error",(()=>{t();})),r.addEventListener("abort",(()=>{t();})),r.addEventListener("load",(()=>{const i=r.response;if(!i||i.statusCode>=400)return t(i&&i.message);e(i);})),n&&r.upload.addEventListener("progress",(e=>{n(e);})),r.send(i);}))}const wv={"image/gif":"gif","image/jpeg":"jpg","image/png":"png","image/webp":"webp","image/bmp":"bmp","image/tiff":"tiff"};class _v extends Hr{_chosenAssets=new Set;_wrapper=null;constructor(e){super(e),this._initListeners();}refresh(){this.value=this._getValue(),this.isEnabled=this._checkEnabled();}execute(){this.fire("ckbox:open");}_getValue(){return null!==this._wrapper}_checkEnabled(){const e=this.editor.commands.get("insertImage"),t=this.editor.commands.get("link");return !(!e.isEnabled&&!t.isEnabled)}_prepareOptions(){const e=this.editor.config.get("ckbox"),t=e.dialog,i=e.categories,n=e.view,s=e.upload;return {theme:e.theme,language:e.language,tokenUrl:e.tokenUrl,serviceOrigin:e.serviceOrigin,forceDemoLabel:e.forceDemoLabel,choosableFileExtensions:e.choosableFileExtensions,assets:{onChoose:e=>this.fire("ckbox:choose",e)},dialog:{onClose:()=>this.fire("ckbox:close"),width:t&&t.width,height:t&&t.height},categories:i&&{icons:i.icons},view:n&&{openLastView:n.openLastView,startupFolderId:n.startupFolderId,startupCategoryId:n.startupCategoryId,hideMaximizeButton:n.hideMaximizeButton},upload:s&&{componentsHideTimeout:s.componentsHideTimeout,dialogMinimizeTimeout:s.dialogMinimizeTimeout}}}_initListeners(){const e=this.editor,t=e.model,i=!e.config.get("ckbox.ignoreDataId");this.on("ckbox",(()=>{this.refresh();}),{priority:"low"}),this.on("ckbox:open",(()=>{this.isEnabled&&!this.value&&(this._wrapper=ro(document,"div",{class:"ck ckbox-wrapper"}),document.body.appendChild(this._wrapper),window.CKBox.mount(this._wrapper,this._prepareOptions()));})),this.on("ckbox:close",(()=>{this.value&&(this._wrapper.remove(),this._wrapper=null,e.editing.view.focus());})),this.on("ckbox:choose",((n,s)=>{if(!this.isEnabled)return;const o=e.commands.get("insertImage"),r=e.commands.get("link"),a=function({assets:e,isImageAllowed:t,isLinkAllowed:i}){return e.map((e=>function(e){const t=e.data.metadata;if(!t)return !1;return t.width&&t.height}(e)?{id:e.data.id,type:"image",attributes:vv(e)}:{id:e.data.id,type:"link",attributes:yv(e)})).filter((e=>"image"===e.type?t:i))}({assets:s,isImageAllowed:o.isEnabled,isLinkAllowed:r.isEnabled}),l=a.length;0!==l&&(t.change((e=>{for(const t of a){const n=t===a[l-1],s=1===l;this._insertAsset(t,n,e,s),i&&(setTimeout((()=>this._chosenAssets.delete(t)),1e3),this._chosenAssets.add(t));}})),e.editing.view.focus());})),this.listenTo(e,"destroy",(()=>{this.fire("ckbox:close"),this._chosenAssets.clear();}));}_insertAsset(e,t,i,n){const s=this.editor.model.document.selection;i.removeSelectionAttribute("linkHref"),"image"===e.type?this._insertImage(e):this._insertLink(e,i,n),t||i.setSelection(s.getLastPosition());}_insertImage(e){const t=this.editor,{imageFallbackUrl:i,imageSources:n,imageTextAlternative:s,imageWidth:o,imageHeight:r,imagePlaceholder:a}=e.attributes;t.execute("insertImage",{source:{src:i,sources:n,alt:s,width:o,height:r,...a?{placeholder:a}:null}});}_insertLink(e,t,i){const n=this.editor,s=n.model,o=s.document.selection,{linkName:r,linkHref:a}=e.attributes;if(o.isCollapsed){const e=xr(o.getAttributes()),l=t.createText(r,e);if(!i){const e=o.getLastPosition(),i=e.parent;"paragraph"===i.name&&i.isEmpty||n.execute("insertParagraph",{position:e});const r=s.insertContent(l);return t.setSelection(r),void n.execute("link",a)}const c=s.insertContent(l);t.setSelection(c);}n.execute("link",a);}}function vv(e){const{imageFallbackUrl:t,imageSources:i}=pv(e.data.imageUrls),{description:n,width:s,height:o,blurHash:r}=e.data.metadata,a=function(e){if(e)try{const t="32px",i=document.createElement("canvas");i.setAttribute("width",t),i.setAttribute("height",t);const n=i.getContext("2d");if(!n)return;const s=n.createImageData(32,32),o=fv(e,32,32);return s.data.set(o),n.putImageData(s,0,0),i.toDataURL()}catch(e){return}}(r);return {imageFallbackUrl:t,imageSources:i,imageTextAlternative:n||"",imageWidth:s,imageHeight:o,...a?{imagePlaceholder:a}:null}}function yv(e){return {linkName:e.data.name,linkHref:kv(e)}}function kv(e){const t=new URL(e.data.url);return t.searchParams.set("download","true"),t.toString()}class Cv extends Dr{_token;static get pluginName(){return "CKBoxUtils"}static get isOfficialPlugin(){return !0}static get requires(){return ["CloudServices"]}init(){const e=this.editor,t=!!e.config.get("ckbox"),i=!!window.CKBox;if(!t&&!i)return;e.config.define("ckbox",{serviceOrigin:"https://api.ckbox.io",defaultUploadCategories:null,ignoreDataId:!1,language:e.locale.uiLanguage,theme:"lark",tokenUrl:e.config.get("cloudServices.tokenUrl")});const n=e.plugins.get("CloudServices"),s=e.config.get("cloudServices.tokenUrl"),o=e.config.get("ckbox.tokenUrl");if(!o)throw new A("ckbox-plugin-missing-token-url",this);this._token=o==s?Promise.resolve(n.token):n.registerTokenUrl(o);}getToken(){return this._token}async getWorkspaceId(){const e=(0, this.editor.t)("Cannot access default workspace."),t=this.editor.config.get("ckbox.defaultUploadWorkspaceId"),i=function(e,t){const[,i]=e.value.split("."),n=JSON.parse(atob(i)),s=n.auth&&n.auth.ckbox&&n.auth.ckbox.workspaces||[n.aud];return t?"superadmin"==(n.auth&&n.auth.ckbox&&n.auth.ckbox.role)||s.includes(t)?t:null:s[0]}(await this._token,t);if(null==i)throw T("ckbox-access-default-workspace-error"),e;return i}async getCategoryIdForFile(e,t){const i=(0, this.editor.t)("Cannot determine a category for the uploaded file."),n=this.editor.config.get("ckbox.defaultUploadCategories"),s=this._getAvailableCategories(t),o="string"==typeof e?(r=await async function(e,t){try{const i=await fetch(e,{method:"HEAD",cache:"force-cache",...t});return i.ok&&i.headers.get("content-type")||""}catch{return ""}}(e,t),wv[r]):e.name.match(/\.(?[^.]+)$/).groups.ext.toLowerCase();var r;const a=await s;if(!a)throw i;if(n){const e=Object.keys(n).find((e=>n[e].find((e=>e.toLowerCase()==o))));if(e){const t=a.find((t=>t.id===e||t.name===e));if(!t)throw i;return t.id}}const l=a.find((e=>e.extensions.find((e=>e.toLowerCase()==o))));if(!l)throw i;return l.id}async _getAvailableCategories(e){const t=this.editor,i=this._token,{signal:n}=e,s=t.config.get("ckbox.serviceOrigin"),o=await this.getWorkspaceId();try{const e=[];let t,i=0;do{const n=await r(i);e.push(...n.items),t=n.totalCount-(i+50),i+=50;}while(t>0);return e}catch{return n.throwIfAborted(),void T("ckbox-fetch-category-http-error")}async function r(e){const t=new URL("categories",s);return t.searchParams.set("limit",String(50)),t.searchParams.set("offset",String(e)),t.searchParams.set("workspaceId",o),bv({url:t,signal:n,authorization:(await i).value})}}}class xv extends Dr{static get requires(){return ["ImageUploadEditing","ImageUploadProgress",km,Tv]}static get pluginName(){return "CKBoxUploadAdapter"}static get isOfficialPlugin(){return !0}async afterInit(){const e=this.editor,t=!!e.config.get("ckbox"),i=!!window.CKBox;if(!t&&!i)return;const n=e.plugins.get(km),s=e.plugins.get(Cv);n.createUploadAdapter=t=>new Av(t,e,s);const o=!e.config.get("ckbox.ignoreDataId"),r=e.plugins.get("ImageUploadEditing");o&&r.on("uploadComplete",((t,{imageElement:i,data:n})=>{e.model.change((e=>{e.setAttribute("ckboxImageId",n.ckboxImageId,i);}));}));}}let Av=class{loader;token;editor;controller;serviceOrigin;ckboxUtils;constructor(e,t,i){this.loader=e,this.token=i.getToken(),this.ckboxUtils=i,this.editor=t,this.controller=new AbortController,this.serviceOrigin=t.config.get("ckbox.serviceOrigin");}async upload(){const e=this.ckboxUtils,t=this.editor.t,i=await this.loader.file,n=await e.getCategoryIdForFile(i,{signal:this.controller.signal}),s=new URL("assets",this.serviceOrigin),o=new FormData;s.searchParams.set("workspaceId",await e.getWorkspaceId()),o.append("categoryId",n),o.append("file",i);return bv({method:"POST",url:s,data:o,onUploadProgress:e=>{e.lengthComputable&&(this.loader.uploadTotal=e.total,this.loader.uploaded=e.loaded);},signal:this.controller.signal,authorization:(await this.token).value}).then((async e=>{const t=pv(e.imageUrls);return {ckboxImageId:e.id,default:t.imageFallbackUrl,sources:t.imageSources}})).catch((()=>{const e=t("Cannot upload file:")+` ${i.name}.`;return Promise.reject(e)}))}abort(){this.controller.abort();}};const Ev="NoPermission";class Tv extends Dr{static get pluginName(){return "CKBoxEditing"}static get isOfficialPlugin(){return !0}static get requires(){return ["LinkEditing","PictureEditing",xv,Cv]}init(){const e=this.editor;this._shouldBeInitialised()&&(this._checkImagePlugins(),Vv()&&e.commands.add("ckbox",new _v(e)),async function(e){const t=e.plugins.get(Cv),i=e.config.get("ckbox.serviceOrigin"),n=new URL("permissions",i),{value:s}=await t.getToken(),o=await bv({url:n,authorization:s,signal:(new AbortController).signal});return Object.values(o).some((e=>e["asset:create"]))}(e).then((e=>{e||this._blockImageCommands();})));}afterInit(){const e=this.editor;this._shouldBeInitialised()&&(e.config.get("ckbox.ignoreDataId")||(this._initSchema(),this._initConversion(),this._initFixers()));}_shouldBeInitialised(){return !!this.editor.config.get("ckbox")||Vv()}_blockImageCommands(){const e=this.editor,t=e.commands.get("uploadImage"),i=e.commands.get("ckboxImageEdit");t&&(t.isAccessAllowed=!1,t.forceDisabled(Ev)),i&&i.forceDisabled(Ev);}_checkImagePlugins(){const e=this.editor;e.plugins.has("ImageBlockEditing")||e.plugins.has("ImageInlineEditing")||T("ckbox-plugin-image-feature-missing",e);}_initSchema(){const e=this.editor.model.schema;e.extend("$text",{allowAttributes:"ckboxLinkId"}),e.isRegistered("imageBlock")&&e.extend("imageBlock",{allowAttributes:["ckboxImageId","ckboxLinkId"]}),e.isRegistered("imageInline")&&e.extend("imageInline",{allowAttributes:["ckboxImageId","ckboxLinkId"]}),e.addAttributeCheck((e=>{if(!e.last.getAttribute("linkHref"))return !1}),"ckboxLinkId");}_initConversion(){const e=this.editor;e.conversion.for("downcast").add((e=>{e.on("attribute:ckboxLinkId:imageBlock",((e,t,i)=>{const{writer:n,mapper:s,consumable:o}=i;if(!o.consume(t.item,e.name))return;const r=[...s.toViewElement(t.item).getChildren()].find((e=>"a"===e.name));r&&(t.item.hasAttribute("ckboxLinkId")?n.setAttribute("data-ckbox-resource-id",t.item.getAttribute("ckboxLinkId"),r):n.removeAttribute("data-ckbox-resource-id",r));}),{priority:"low"}),e.on("attribute:ckboxLinkId",((e,t,i)=>{const{writer:n,mapper:s,consumable:o}=i;if(o.consume(t.item,e.name)){if(t.attributeOldValue){const e=Sv(n,t.attributeOldValue);n.unwrap(s.toViewRange(t.range),e);}if(t.attributeNewValue){const e=Sv(n,t.attributeNewValue);if(t.item.is("selection")){const t=n.document.selection;n.wrap(t.getFirstRange(),e);}else n.wrap(s.toViewRange(t.range),e);}}}),{priority:"low"});})),e.conversion.for("upcast").add((e=>{e.on("element:a",((e,t,i)=>{const{writer:n,consumable:s}=i;if(!t.viewItem.getAttribute("href"))return;if(!s.consume(t.viewItem,{attributes:["data-ckbox-resource-id"]}))return;const o=t.viewItem.getAttribute("data-ckbox-resource-id");if(o)if(t.modelRange)for(let e of t.modelRange.getItems())e.is("$textProxy")&&(e=e.textNode),Iv(e)&&n.setAttribute("ckboxLinkId",o,e);else {const e=t.modelCursor.nodeBefore||t.modelCursor.parent;n.setAttribute("ckboxLinkId",o,e);}}),{priority:"low"});})),e.conversion.for("downcast").attributeToAttribute({model:"ckboxImageId",view:"data-ckbox-resource-id"}),e.conversion.for("upcast").elementToAttribute({model:{key:"ckboxImageId",value:e=>e.getAttribute("data-ckbox-resource-id")},view:{attributes:{"data-ckbox-resource-id":/[\s\S]+/}}});const t=e.commands.get("replaceImageSource");t&&this.listenTo(t,"cleanupImage",((e,[t,i])=>{t.removeAttribute("ckboxImageId",i);}));}_initFixers(){const e=this.editor,t=e.model,i=t.document.selection;t.document.registerPostFixer(function(e){return t=>{let i=!1;const n=e.model,s=e.commands.get("ckbox");if(!s)return i;for(const e of n.document.differ.getChanges()){if("insert"!==e.type&&"attribute"!==e.type)continue;const n="insert"===e.type?new tc(e.position,e.position.getShiftedBy(e.length)):e.range,o="attribute"===e.type&&"linkHref"===e.attributeKey&&null===e.attributeNewValue;for(const e of n.getItems()){if(o&&e.hasAttribute("ckboxLinkId")){t.removeAttribute("ckboxLinkId",e),i=!0;continue}const n=Pv(e,s._chosenAssets);for(const s of n){const n="image"===s.type?"ckboxImageId":"ckboxLinkId";s.id!==e.getAttribute(n)&&(t.setAttribute(n,s.id,e),i=!0);}}}return i}}(e)),t.document.registerPostFixer(function(e){return t=>!(e.hasAttribute("linkHref")||!e.hasAttribute("ckboxLinkId"))&&(t.removeSelectionAttribute("ckboxLinkId"),!0)}(i));}}function Pv(e,t){const i=e.is("element","imageInline")||e.is("element","imageBlock"),n=e.hasAttribute("linkHref");return [...t].filter((t=>"image"===t.type&&i?t.attributes.imageFallbackUrl===e.getAttribute("src"):"link"===t.type&&n?t.attributes.linkHref===e.getAttribute("linkHref"):void 0))}function Sv(e,t){const i=e.createAttributeElement("a",{"data-ckbox-resource-id":t},{priority:5});return e.setCustomProperty("link",!0,i),i}function Iv(e){return !!e.is("$text")||!(!e.is("element","imageInline")&&!e.is("element","imageBlock"))}function Vv(){return !!window.CKBox}class Rv extends Dr{static get pluginName(){return "CKBox"}static get isOfficialPlugin(){return !0}static get requires(){return [Tv,rv]}}function Ov(e){if(Array.isArray(e)){const t=e.map(Ov);return e=>t.some((t=>t(e)))}if("origin"==e){const e=i.window.location.origin;return t=>new URL(t,i.document.baseURI).origin==e}return "function"==typeof e?e:e instanceof RegExp?t=>!(!t.match(e)&&!t.replace(/^https?:\/\//,"").match(e)):()=>!1}class Bv extends Hr{_wrapper=null;_processInProgress=new Set;_canEdit;_prepareOptions;_updateUiDelayed=Sr((()=>this.editor.ui.update()),0);constructor(e){super(e),this.value=!1,this._canEdit=function(e){const t=Ov(e);return e=>!(!e.is("element","imageInline")&&!e.is("element","imageBlock"))&&(!!e.hasAttribute("ckboxImageId")||!!e.hasAttribute("src")&&t(e.getAttribute("src")))}(e.config.get("ckbox.allowExternalImagesEditing")),this._prepareOptions=io(((e,t)=>this._prepareOptionsAbortable(e,t))),this._prepareListeners();}refresh(){const e=this.editor;this.value=this._getValue();const t=e.model.document.selection.getSelectedElement();this.isEnabled=!!t&&this._canEdit(t)&&!this._checkIfElementIsBeingProcessed(t);}execute(){if(this._getValue())return;const e=ro(document,"div",{class:"ck ckbox-wrapper"});this._wrapper=e,this.value=!0,document.body.appendChild(this._wrapper);const t={element:this.editor.model.document.selection.getSelectedElement(),controller:new AbortController};this._prepareOptions(t).then((t=>window.CKBox.mountImageEditor(e,t)),(e=>{const t=this.editor,i=t.t;t.plugins.get(Lb).showWarning(i("Failed to determine category of edited image."),{namespace:"ckbox"}),console.error(e),this._handleImageEditorClose();}));}destroy(){this._handleImageEditorClose(),this._prepareOptions.abort(),this._updateUiDelayed.cancel();for(const e of this._processInProgress.values())e.controller.abort();super.destroy();}_getValue(){return null!==this._wrapper}async _prepareOptionsAbortable(e,t){const i=this.editor,n=i.config.get("ckbox"),s=i.plugins.get(Cv),{element:o}=t;let r;const a=o.getAttribute("ckboxImageId");if(a)r={assetId:a};else {const t=new URL(o.getAttribute("src"),document.baseURI).href;r={imageUrl:t,uploadCategoryId:await s.getCategoryIdForFile(t,{signal:e})};}return {...r,imageEditing:{allowOverwrite:!1},tokenUrl:n.tokenUrl,...n.serviceOrigin&&{serviceOrigin:n.serviceOrigin},onClose:()=>this._handleImageEditorClose(),onSave:e=>this._handleImageEditorSave(t,e)}}_prepareListeners(){this.listenTo(this.editor.model.document,"change:data",(()=>{this._getProcessingStatesOfDeletedImages().forEach((e=>{e.controller.abort();}));}));}_getProcessingStatesOfDeletedImages(){const e=[];for(const t of this._processInProgress.values())"$graveyard"==t.element.root.rootName&&e.push(t);return e}_checkIfElementIsBeingProcessed(e){for(const{element:t}of this._processInProgress)if(Ls(t,e))return !0;return !1}_handleImageEditorClose(){this._wrapper&&(this._wrapper.remove(),this._wrapper=null,this.editor.editing.view.focus(),this._updateUiDelayed(),this.refresh());}_handleImageEditorSave(e,t){const i=this.editor.locale.t,n=this.editor.plugins.get(Lb),s=this.editor.plugins.get(_m),o=s.add(i("Processing the edited image."));this._processInProgress.add(e),this._showImageProcessingIndicator(e.element,t),this.refresh(),this._waitForAssetProcessed(t.data.id,e.controller.signal).then((t=>{this._replaceImage(e.element,t);}),(t=>{this.editor.editing.reconvertItem(e.element),e.controller.signal.aborted||(!t||t instanceof A?n.showWarning(i("Server failed to process the image."),{namespace:"ckbox"}):console.error(t));})).finally((()=>{this._processInProgress.delete(e),s.remove(o),this.refresh();}));}async _getAssetStatusFromServer(e,t){const i=this.editor.plugins.get(Cv),n=new URL("assets/"+e,this.editor.config.get("ckbox.serviceOrigin")),s=await bv({url:n,signal:t,authorization:(await i.getToken()).value}),o=s.metadata.metadataProcessingStatus;if(!o||"queued"==o)throw new A("ckbox-image-not-processed");return {data:{...s}}}async _waitForAssetProcessed(e,t){const i=await Er((()=>this._getAssetStatusFromServer(e,t)),{signal:t,maxAttempts:5});if("success"!=i.data.metadata.metadataProcessingStatus)throw new A("ckbox-image-processing-failed");return i}_showImageProcessingIndicator(e,t){const i=this.editor;i.editing.view.change((n=>{const s=i.editing.mapper.toViewElement(e),o=this.editor.plugins.get("ImageUtils").findViewImgElement(s);n.removeStyle("aspect-ratio",o),n.setAttribute("width",t.data.metadata.width,o),n.setAttribute("height",t.data.metadata.height,o),n.setStyle("width",`${t.data.metadata.width}px`,o),n.setStyle("height",`${t.data.metadata.height}px`,o),n.addClass("image-processing",s);}));}_replaceImage(e,t){const i=this.editor,{imageFallbackUrl:n,imageSources:s,imageWidth:o,imageHeight:r,imagePlaceholder:a}=vv(t),l=Array.from(i.model.document.selection.getRanges());i.model.change((c=>{c.setSelection(e,"on"),i.execute("insertImage",{imageType:e.is("element","imageInline")?"imageInline":null,source:{src:n,sources:s,width:o,height:r,...a?{placeholder:a}:null,...e.hasAttribute("alt")?{alt:e.getAttribute("alt")}:null}});const d=e.getChildren();e=i.model.document.selection.getSelectedElement();for(const t of d)c.append(c.cloneElement(t),e);c.setAttribute("ckboxImageId",t.data.id,e),c.setSelection(l);}));}}class Mv extends Dr{static get pluginName(){return "CKBoxImageEditEditing"}static get isOfficialPlugin(){return !0}static get requires(){return [Tv,Cv,_m,Lb,"ImageUtils","ImageEditing"]}init(){const{editor:e}=this;e.commands.add("ckboxImageEdit",new Bv(e));}}class Lv extends Dr{static get pluginName(){return "CKBoxImageEditUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;e.ui.componentFactory.add("ckboxImageEdit",(t=>{const i=e.commands.get("ckboxImageEdit"),n=e.commands.get("uploadImage"),s=new pg(t),o=t.t;return s.set({icon:'',tooltip:!0}),s.bind("label").to(n,"isAccessAllowed",(e=>o(e?"Edit image":"You have no image editing permissions."))),s.bind("isOn").to(i,"value",i,"isEnabled",((e,t)=>e&&t)),s.bind("isEnabled").to(i),this.listenTo(s,"execute",(()=>{e.execute("ckboxImageEdit"),e.editing.view.focus();})),s}));}}class Fv extends Dr{static get pluginName(){return "CKBoxImageEdit"}static get isOfficialPlugin(){return !0}static get requires(){return [Mv,Lv]}}class Nv extends Dr{static get pluginName(){return "CKFinderUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;e.ui.componentFactory.add("ckfinder",(()=>this._createFileToolbarButton())),e.ui.componentFactory.add("menuBar:ckfinder",(()=>this._createFileMenuBarButton())),e.plugins.has("ImageInsertUI")&&e.plugins.get("ImageInsertUI").registerIntegration({name:"assetManager",observable:()=>e.commands.get("ckfinder"),buttonViewCreator:()=>this._createImageToolbarButton(),formViewCreator:()=>this._createImageDropdownButton(),menuBarButtonViewCreator:e=>this._createImageMenuBarButton(e?"insertOnly":"insertNested")});}_createButton(e){const t=this.editor,i=new e(t.locale),n=t.commands.get("ckfinder");return i.bind("isEnabled").to(n),i.on("execute",(()=>{t.execute("ckfinder"),t.editing.view.focus();})),i}_createFileToolbarButton(){const e=this.editor.locale.t,t=this._createButton(pg);return t.icon=vm.browseFiles,t.label=e("Insert image or file"),t.tooltip=!0,t}_createImageToolbarButton(){const e=this.editor.locale.t,t=this.editor.plugins.get("ImageInsertUI"),i=this._createButton(pg);return i.icon=vm.imageAssetManager,i.bind("label").to(t,"isImageSelected",(t=>e(t?"Replace image with file manager":"Insert image with file manager"))),i.tooltip=!0,i}_createImageDropdownButton(){const e=this.editor.locale.t,t=this.editor.plugins.get("ImageInsertUI"),i=this._createButton(pg);return i.icon=vm.imageAssetManager,i.withText=!0,i.bind("label").to(t,"isImageSelected",(t=>e(t?"Replace with file manager":"Insert with file manager"))),i.on("execute",(()=>{t.dropdownView.isOpen=!1;})),i}_createFileMenuBarButton(){const e=this.editor.locale.t,t=this._createButton(Rg);return t.icon=vm.browseFiles,t.withText=!0,t.label=e("File"),t}_createImageMenuBarButton(e){const t=this.editor.locale.t,i=this.editor.locale.t,n=this._createButton(Rg);switch(n.icon=vm.imageAssetManager,n.withText=!0,e){case"insertOnly":n.label=t("Image");break;case"insertNested":n.label=i("With file manager");}return n}}class Dv extends Hr{constructor(e){super(e),this.affectsData=!1,this.stopListening(this.editor.model.document,"change"),this.listenTo(this.editor.model.document,"change",(()=>this.refresh()),{priority:"low"});}refresh(){const e=this.editor.commands.get("insertImage"),t=this.editor.commands.get("link");this.isEnabled=e.isEnabled||t.isEnabled;}execute(){const e=this.editor,t=this.editor.config.get("ckfinder.openerMethod")||"modal";if("popup"!=t&&"modal"!=t)throw new A("ckfinder-unknown-openermethod",e);const i=this.editor.config.get("ckfinder.options")||{};i.chooseFiles=!0;const n=i.onInit;i.language||(i.language=e.locale.uiLanguage),i.onInit=t=>{n&&n(t),t.on("files:choose",(i=>{const n=i.data.files.toArray(),s=n.filter((e=>!e.isImage())),o=n.filter((e=>e.isImage()));for(const t of s)e.execute("link",t.getUrl());const r=[];for(const e of o){const i=e.getUrl();r.push(i||t.request("file:getProxyUrl",{file:e}));}r.length&&zv(e,r);})),t.on("file:choose:resizedImage",(t=>{const i=t.data.resizedUrl;if(i)zv(e,[i]);else {const t=e.plugins.get("Notification"),i=e.locale.t;t.showWarning(i("Could not obtain resized image URL."),{title:i("Selecting resized image failed"),namespace:"ckfinder"});}}));},window.CKFinder[t](i);}}function zv(e,t){if(e.commands.get("insertImage").isEnabled)e.execute("insertImage",{source:t});else {const t=e.plugins.get("Notification"),i=e.locale.t;t.showWarning(i("Could not insert image at the current position."),{title:i("Inserting image failed"),namespace:"ckfinder"});}}class Hv extends Dr{static get pluginName(){return "CKFinderEditing"}static get isOfficialPlugin(){return !0}static get requires(){return [Lb,"LinkEditing"]}init(){const e=this.editor;if(!e.plugins.has("ImageBlockEditing")&&!e.plugins.has("ImageInlineEditing"))throw new A("ckfinder-missing-image-plugin",e);e.commands.add("ckfinder",new Dv(e));}}class $v extends Dr{static get pluginName(){return "CKFinder"}static get isOfficialPlugin(){return !0}static get requires(){return ["Link","CKFinderUploadAdapter",Hv,Nv]}}class Uv extends Tl{domEventType=["paste","copy","cut","drop","dragover","dragstart","dragend","dragenter","dragleave"];constructor(e){super(e);const t=this.document;function i(e){return (i,n)=>{n.preventDefault();const s=n.dropRange?[n.dropRange]:null,o=new v(t,e);t.fire(o,{dataTransfer:n.dataTransfer,method:i.name,targetRanges:s,target:n.target,domEvent:n.domEvent}),o.stop.called&&n.stopPropagation();}}this.listenTo(t,"paste",i("clipboardInput"),{priority:"low"}),this.listenTo(t,"drop",i("clipboardInput"),{priority:"low"}),this.listenTo(t,"dragover",i("dragging"),{priority:"low"});}onDomEvent(e){const t="clipboardData"in e?e.clipboardData:e.dataTransfer,i="drop"==e.type||"paste"==e.type,n={dataTransfer:new Ml(t,{cacheFiles:i})};if("drop"==e.type||"dragover"==e.type){const t=yo(e);n.dropRange=t&&this.view.domConverter.domRangeToView(t);}this.fire(e.type,e,n);}}function Wv(e){return ((e=e.replace(/&/g,"&").replace(//g,">").replace(/\r?\n\r?\n/g,"

").replace(/\r?\n/g,"
").replace(/\t/g,"    ").replace(/^\s/," ").replace(/\s$/," ").replace(/\s\s/g,"  ")).includes("

")||e.includes("
"))&&(e=`

${e}

`),e}const jv=["figcaption","li"],qv=["ol","ul"];function Gv(e){if(e.is("$text")||e.is("$textProxy"))return e.data;if(e.is("element","img")&&e.hasAttribute("alt"))return e.getAttribute("alt");if(e.is("element","br"))return "\n";let t="",i=null;for(const n of e.getChildren())t+=Kv(n,i)+Gv(n),i=n;return t}function Kv(e,t){return t?e.is("element","li")&&!e.isEmpty&&e.getChild(0).is("containerElement")||qv.includes(e.name)&&qv.includes(t.name)?"\n\n":e.is("containerElement")||t.is("containerElement")?jv.includes(e.name)||jv.includes(t.name)?"\n":e.is("element")&&e.getCustomProperty("dataPipeline:transparentRendering")||t.is("element")&&t.getCustomProperty("dataPipeline:transparentRendering")?"":"\n\n":"":""}class Zv extends Dr{_markersToCopy=new Map;static get pluginName(){return "ClipboardMarkersUtils"}static get isOfficialPlugin(){return !0}_registerMarkerToCopy(e,t){this._markersToCopy.set(e,t);}_copySelectedFragmentWithMarkers(e,t,i=e=>e.model.getSelectedContent(e.model.document.selection)){return this.editor.model.change((n=>{const s=n.model.document.selection;n.setSelection(t);const o=this._insertFakeMarkersIntoSelection(n,n.model.document.selection,e),r=i(n),a=this._removeFakeMarkersInsideElement(n,r);for(const[e,t]of Object.entries(o)){a[e]||=n.createRangeIn(r);for(const e of t)n.remove(e);}r.markers.clear();for(const[e,t]of Object.entries(a))r.markers.set(e,t);return n.setSelection(s),r}))}_pasteMarkersIntoTransformedElement(e,t){const i=this._getPasteMarkersFromRangeMap(e);return this.editor.model.change((e=>{const n=this._insertFakeMarkersElements(e,i),s=t(e),o=this._removeFakeMarkersInsideElement(e,s);for(const t of Object.values(n).flat())e.remove(t);for(const[t,i]of Object.entries(o))e.model.markers.has(t)||e.addMarker(t,{usingOperation:!0,affectsData:!0,range:i});return s}))}_pasteFragmentWithMarkers(e){const t=this._getPasteMarkersFromRangeMap(e.markers);e.markers.clear();for(const i of t)e.markers.set(i.name,i.range);return this.editor.model.insertContent(e)}_forceMarkersCopy(e,t,i={allowedActions:"all",copyPartiallySelected:!0,duplicateOnPaste:!0}){const n=this._markersToCopy.get(e);this._markersToCopy.set(e,i),t(),n?this._markersToCopy.set(e,n):this._markersToCopy.delete(e);}_isMarkerCopyable(e,t){const i=this._getMarkerClipboardConfig(e);if(!i)return !1;if(!t)return !0;const{allowedActions:n}=i;return "all"===n||n.includes(t)}_hasMarkerConfiguration(e){return !!this._getMarkerClipboardConfig(e)}_getMarkerClipboardConfig(e){const[t]=e.split(":");return this._markersToCopy.get(t)||null}_insertFakeMarkersIntoSelection(e,t,i){const n=this._getCopyableMarkersFromSelection(e,t,i);return this._insertFakeMarkersElements(e,n)}_getCopyableMarkersFromSelection(e,t,i){const n=Array.from(t.getRanges()),s=new Set(n.flatMap((t=>Array.from(e.model.markers.getMarkersIntersectingRange(t)))));return Array.from(s).filter((e=>{if(!this._isMarkerCopyable(e.name,i))return !1;const{copyPartiallySelected:t}=this._getMarkerClipboardConfig(e.name);if(!t){const t=e.getRange();return n.some((e=>e.containsRange(t,!0)))}return !0})).map((e=>({name:"dragstart"===i?this._getUniqueMarkerName(e.name):e.name,range:e.getRange()})))}_getPasteMarkersFromRangeMap(e,t=null){const{model:i}=this.editor;return (e instanceof Map?Array.from(e.entries()):Object.entries(e)).flatMap((([e,n])=>{if(!this._hasMarkerConfiguration(e))return [{name:e,range:n}];if(this._isMarkerCopyable(e,t)){const t=this._getMarkerClipboardConfig(e),s=i.markers.has(e)&&"$graveyard"===i.markers.get(e).getRange().root.rootName;return (t.duplicateOnPaste||s)&&(e=this._getUniqueMarkerName(e)),[{name:e,range:n}]}return []}))}_insertFakeMarkersElements(e,t){const i={},n=t.flatMap((e=>{const{start:t,end:i}=e.range;return [{position:t,marker:e,type:"start"},{position:i,marker:e,type:"end"}]})).sort((({position:e},{position:t})=>e.isBefore(t)?1:-1));for(const{position:t,marker:s,type:o}of n){const n=e.createElement("$marker",{"data-name":s.name,"data-type":o});i[s.name]||(i[s.name]=[]),i[s.name].push(n),e.insert(n,t);}return i}_removeFakeMarkersInsideElement(e,t){const i=this._getAllFakeMarkersFromElement(e,t).reduce(((t,i)=>{const n=i.markerElement&&e.createPositionBefore(i.markerElement);let s=t[i.name],o=!1;if(s&&s.start&&s.end){this._getMarkerClipboardConfig(i.name).duplicateOnPaste?t[this._getUniqueMarkerName(i.name)]=t[i.name]:o=!0,s=null;}return o||(t[i.name]={...s,[i.type]:n}),i.markerElement&&e.remove(i.markerElement),t}),{});return n=i,o={},s=hs(s=i=>new tc(i.start||e.createPositionFromPath(t,[0]),i.end||e.createPositionAt(t,"end"))),gs(n,(function(e,t,i){ze(o,t,s(e,t,i));})),o;var n,s,o;}_getAllFakeMarkersFromElement(e,t){const i=Array.from(e.createRangeIn(t)).flatMap((({item:e})=>{if(!e.is("element","$marker"))return [];const t=e.getAttribute("data-name"),i=e.getAttribute("data-type");return [{markerElement:e,name:t,type:i}]})),n=[],s=[];for(const e of i){if("end"===e.type){i.some((t=>t.name===e.name&&"start"===t.type))||n.push({markerElement:null,name:e.name,type:"start"});}if("start"===e.type){i.some((t=>t.name===e.name&&"end"===t.type))||s.unshift({markerElement:null,name:e.name,type:"end"});}}return [...n,...i,...s]}_getUniqueMarkerName(e){const t=e.split(":"),i=k().substring(1,6);return 3===t.length?`${t.slice(0,2).join(":")}:${i}`:`${t.join(":")}:${i}`}}class Jv extends Dr{static get pluginName(){return "ClipboardPipeline"}static get isOfficialPlugin(){return !0}static get requires(){return [Zv]}init(){this.editor.editing.view.addObserver(Uv),this._setupPasteDrop(),this._setupCopyCut();}_fireOutputTransformationEvent(e,t,i){const n=this.editor.plugins.get("ClipboardMarkersUtils");this.editor.model.enqueueChange({isUndoable:"cut"===i},(()=>{const s=n._copySelectedFragmentWithMarkers(i,t);this.fire("outputTransformation",{dataTransfer:e,content:s,method:i});}));}_setupPasteDrop(){const e=this.editor,t=e.model,i=e.editing.view,n=i.document,s=this.editor.plugins.get("ClipboardMarkersUtils");this.listenTo(n,"clipboardInput",((t,i)=>{"paste"!=i.method||e.model.canEditAt(e.model.document.selection)||t.stop();}),{priority:"highest"}),this.listenTo(n,"clipboardInput",((e,t)=>{const n=t.dataTransfer;let s;if(t.content)s=t.content;else {let e="";n.getData("text/html")?e=function(e){return e.replace(/(\s+)<\/span>/g,((e,t)=>1==t.length?" ":t)).replace(//g,"")}(n.getData("text/html")):n.getData("text/plain")&&(e=Wv(n.getData("text/plain"))),s=this.editor.data.htmlProcessor.toView(e);}const o=new v(this,"inputTransformation");this.fire(o,{content:s,dataTransfer:n,targetRanges:t.targetRanges,method:t.method}),o.stop.called&&e.stop(),i.scrollToTheSelection();}),{priority:"low"}),this.listenTo(this,"inputTransformation",((e,i)=>{if(i.content.isEmpty)return;const n=this.editor.data.toModel(i.content,"$clipboardHolder");0!=n.childCount&&(e.stop(),t.change((()=>{this.fire("contentInsertion",{content:n,method:i.method,dataTransfer:i.dataTransfer,targetRanges:i.targetRanges});})));}),{priority:"low"}),this.listenTo(this,"contentInsertion",((e,t)=>{t.resultRange=s._pasteFragmentWithMarkers(t.content);}),{priority:"low"});}_setupCopyCut(){const e=this.editor,t=e.model.document,i=e.editing.view.document,n=(e,i)=>{const n=i.dataTransfer;i.preventDefault(),this._fireOutputTransformationEvent(n,t.selection,e.name);};this.listenTo(i,"copy",n,{priority:"low"}),this.listenTo(i,"cut",((t,i)=>{e.model.canEditAt(e.model.document.selection)?n(t,i):i.preventDefault();}),{priority:"low"}),this.listenTo(this,"outputTransformation",((t,n)=>{const s=e.data.toView(n.content);i.fire("clipboardOutput",{dataTransfer:n.dataTransfer,content:s,method:n.method});}),{priority:"low"}),this.listenTo(i,"clipboardOutput",((i,n)=>{n.content.isEmpty||(n.dataTransfer.setData("text/html",this.editor.data.htmlProcessor.toData(n.content)),n.dataTransfer.setData("text/plain",Gv(n.content))),"cut"==n.method&&e.model.deleteContent(t.selection);}),{priority:"low"});}}class Qv extends(L()){_stack=[];add(e,t){const i=this._stack,n=i[0];this._insertDescriptor(e);const s=i[0];n===s||Yv(n,s)||this.fire("change:top",{oldDescriptor:n,newDescriptor:s,writer:t});}remove(e,t){const i=this._stack,n=i[0];this._removeDescriptor(e);const s=i[0];n===s||Yv(n,s)||this.fire("change:top",{oldDescriptor:n,newDescriptor:s,writer:t});}_insertDescriptor(e){const t=this._stack,i=t.findIndex((t=>t.id===e.id));if(Yv(e,t[i]))return;i>-1&&t.splice(i,1);let n=0;for(;t[n]&&Xv(t[n],e);)n++;t.splice(n,0,e);}_removeDescriptor(e){const t=this._stack,i=t.findIndex((t=>t.id===e));i>-1&&t.splice(i,1);}}function Yv(e,t){return e&&t&&e.priority==t.priority&&ey(e.classes)==ey(t.classes)}function Xv(e,t){return e.priority>t.priority||!(e.priorityey(t.classes)}function ey(e){return Array.isArray(e)?e.sort().join(","):e}var ty='';const iy="ck-widget",ny="ck-widget_selected";function sy(e){return !!e.is("element")&&!!e.getCustomProperty("widget")}function oy(e,t,i={}){if(!e.is("containerElement"))throw new A("widget-to-widget-wrong-element-type",null,{element:e});return t.setAttribute("contenteditable","false",e),t.addClass(iy,e),t.setCustomProperty("widget",!0,e),e.getFillerOffset=gy,t.setCustomProperty("widgetLabel",[],e),i.label&&cy(e,i.label),i.hasSelectionHandle&&function(e,t){const i=t.createUIElement("div",{class:"ck ck-widget__selection-handle"},(function(e){const t=this.toDomElement(e),i=new gg;return i.set("content",ty),i.render(),t.appendChild(i.element),t}));t.insert(t.createPositionAt(e,0),i),t.addClass(["ck-widget_with-selection-handle"],e);}(e,t),ly(e,t),e}function ry(e,t,i){if(t.classes&&i.addClass(gr(t.classes),e),t.attributes)for(const n in t.attributes)i.setAttribute(n,t.attributes[n],e);}function ay(e,t,i){if(t.classes&&i.removeClass(gr(t.classes),e),t.attributes)for(const n in t.attributes)i.removeAttribute(n,e);}function ly(e,t,i=ry,n=ay){const s=new Qv;s.on("change:top",((t,s)=>{s.oldDescriptor&&n(e,s.oldDescriptor,s.writer),s.newDescriptor&&i(e,s.newDescriptor,s.writer);}));t.setCustomProperty("addHighlight",((e,t,i)=>s.add(t,i)),e),t.setCustomProperty("removeHighlight",((e,t,i)=>s.remove(t,i)),e);}function cy(e,t){e.getCustomProperty("widgetLabel").push(t);}function dy(e){return e.getCustomProperty("widgetLabel").reduce(((e,t)=>"function"==typeof t?e?e+". "+t():t():e?e+". "+t:t),"")}function uy(e,t,i={}){return t.addClass(["ck-editor__editable","ck-editor__nested-editable"],e),t.setAttribute("role","textbox",e),t.setAttribute("tabindex","-1",e),i.label&&t.setAttribute("aria-label",i.label,e),t.setAttribute("contenteditable",e.isReadOnly?"false":"true",e),e.on("change:isReadOnly",((i,n,s)=>{t.setAttribute("contenteditable",s?"false":"true",e);})),e.on("change:isFocused",((i,n,s)=>{s?t.addClass("ck-editor__nested-editable_focused",e):t.removeClass("ck-editor__nested-editable_focused",e);})),ly(e,t),e}function hy(e,t){const i=e.getSelectedElement();if(i){const n=_y(e);if(n)return t.createRange(t.createPositionAt(i,n))}return t.schema.findOptimalInsertionRange(e)}function my(e,t){return (i,n)=>{const{mapper:s,viewPosition:o}=n,r=s.findMappedViewAncestor(o);if(!t(r))return;const a=s.toModelElement(r);n.modelPosition=e.createPositionAt(a,o.isAtStart?"before":"after");}}function gy(){return null}function fy(e){const t=e=>{const{width:t,paddingLeft:i,paddingRight:n}=e.ownerDocument.defaultView.getComputedStyle(e);return parseFloat(t)-(parseFloat(i)||0)-(parseFloat(n)||0)},i=e.parentElement;if(!i)return 0;let n=t(i);let s=0,o=i;for(;isNaN(n);){if(o=o.parentElement,++s>5)return 0;n=t(o);}return n}function py(e,t=new Eo(e)){const i=fy(e);return i?t.width/i*100:0}const by="widget-type-around";function wy(e,t,i){return !!e&&sy(e)&&!i.isInline(t)}function _y(e){return e.getAttribute(by)}const vy=["before","after"],yy=(new DOMParser).parseFromString('',"image/svg+xml").firstChild,ky="ck-widget__type-around_disabled";class Cy extends Dr{_currentFakeCaretModelElement=null;static get pluginName(){return "WidgetTypeAround"}static get isOfficialPlugin(){return !0}static get requires(){return [K_,Rw]}init(){const e=this.editor,t=e.editing.view;this.on("change:isEnabled",((i,n,s)=>{t.change((e=>{for(const i of t.document.roots)s?e.removeClass(ky,i):e.addClass(ky,i);})),s||e.model.change((e=>{e.removeSelectionAttribute(by);}));})),this._enableTypeAroundUIInjection(),this._enableInsertingParagraphsOnButtonClick(),this._enableInsertingParagraphsOnEnterKeypress(),this._enableInsertingParagraphsOnTypingKeystroke(),this._enableTypeAroundFakeCaretActivationUsingKeyboardArrows(),this._enableDeleteIntegration(),this._enableInsertContentIntegration(),this._enableInsertObjectIntegration(),this._enableDeleteContentIntegration();}destroy(){super.destroy(),this._currentFakeCaretModelElement=null;}_insertParagraph(e,t){const i=this.editor,n=i.editing.view,s=i.model.schema.getAttributesWithProperty(e,"copyOnReplace",!0);i.execute("insertParagraph",{position:i.model.createPositionAt(e,t),attributes:s}),n.focus(),n.scrollToTheSelection();}_listenToIfEnabled(e,t,i,n){this.listenTo(e,t,((...e)=>{this.isEnabled&&i(...e);}),n);}_insertParagraphAccordingToFakeCaretPosition(){const e=this.editor.model.document.selection,t=_y(e);if(!t)return !1;const i=e.getSelectedElement();return this._insertParagraph(i,t),!0}_enableTypeAroundUIInjection(){const e=this.editor,t=e.model.schema,i=e.locale.t,n={before:i("Insert paragraph before block"),after:i("Insert paragraph after block")};e.editing.downcastDispatcher.on("insert",((e,s,o)=>{const r=o.mapper.toViewElement(s.item);if(r&&wy(r,s.item,t)){!function(e,t,i){const n=e.createUIElement("div",{class:"ck ck-reset_all ck-widget__type-around"},(function(e){const i=this.toDomElement(e);return function(e,t){for(const i of vy){const n=new Hm({tag:"div",attributes:{class:["ck","ck-widget__type-around__button",`ck-widget__type-around__button_${i}`],title:t[i],"aria-hidden":"true"},children:[e.ownerDocument.importNode(yy,!0)]});e.appendChild(n.render());}}(i,t),function(e){const t=new Hm({tag:"div",attributes:{class:["ck","ck-widget__type-around__fake-caret"]}});e.appendChild(t.render());}(i),i}));e.insert(e.createPositionAt(i,"end"),n);}(o.writer,n,r);r.getCustomProperty("widgetLabel").push((()=>this.isEnabled?i("Press Enter to type after or press Shift + Enter to type before the widget"):""));}}),{priority:"low"});}_enableTypeAroundFakeCaretActivationUsingKeyboardArrows(){const e=this.editor,t=e.model,i=t.document.selection,n=t.schema,s=e.editing.view;function o(e){return `ck-widget_type-around_show-fake-caret_${e}`}this._listenToIfEnabled(s.document,"arrowKey",((e,t)=>{this._handleArrowKeyPress(e,t);}),{context:[sy,"$text"],priority:"high"}),this._listenToIfEnabled(i,"change:range",((t,i)=>{i.directChange&&e.model.change((e=>{e.removeSelectionAttribute(by);}));})),this._listenToIfEnabled(t.document,"change:data",(()=>{const t=i.getSelectedElement();if(t){if(wy(e.editing.mapper.toViewElement(t),t,n))return}e.model.change((e=>{e.removeSelectionAttribute(by);}));})),this._listenToIfEnabled(e.editing.downcastDispatcher,"selection",((e,t,i)=>{const s=i.writer;if(this._currentFakeCaretModelElement){const e=i.mapper.toViewElement(this._currentFakeCaretModelElement);e&&(s.removeClass(vy.map(o),e),this._currentFakeCaretModelElement=null);}const r=t.selection.getSelectedElement();if(!r)return;const a=i.mapper.toViewElement(r);if(!wy(a,r,n))return;const l=_y(t.selection);l&&(s.addClass(o(l),a),this._currentFakeCaretModelElement=r);})),this._listenToIfEnabled(e.ui.focusTracker,"change:isFocused",((t,i,n)=>{n||e.model.change((e=>{e.removeSelectionAttribute(by);}));}));}_handleArrowKeyPress(e,t){const i=this.editor,n=i.model,s=n.document.selection,o=n.schema,r=i.editing.view,a=dr(t.keyCode,i.locale.contentLanguageDirection),l=r.document.selection.getSelectedElement();let c;wy(l,i.editing.mapper.toModelElement(l),o)?c=this._handleArrowKeyPressOnSelectedWidget(a):s.isCollapsed?c=this._handleArrowKeyPressWhenSelectionNextToAWidget(a):t.shiftKey||(c=this._handleArrowKeyPressWhenNonCollapsedSelection(a)),c&&(t.preventDefault(),e.stop());}_handleArrowKeyPressOnSelectedWidget(e){const t=this.editor.model,i=_y(t.document.selection);return t.change((t=>{if(!i)return t.setSelectionAttribute(by,e?"after":"before"),!0;if(!(i===(e?"after":"before")))return t.removeSelectionAttribute(by),!0;return !1}))}_handleArrowKeyPressWhenSelectionNextToAWidget(e){const t=this.editor,i=t.model,n=i.schema,s=t.plugins.get("Widget"),o=s._getObjectElementNextToSelection(e);return !!wy(t.editing.mapper.toViewElement(o),o,n)&&(i.change((t=>{s._setSelectionOverElement(o),t.setSelectionAttribute(by,e?"before":"after");})),!0)}_handleArrowKeyPressWhenNonCollapsedSelection(e){const t=this.editor,i=t.model,n=i.schema,s=t.editing.mapper,o=i.document.selection,r=e?o.getLastPosition().nodeBefore:o.getFirstPosition().nodeAfter;return !!wy(s.toViewElement(r),r,n)&&(i.change((t=>{t.setSelection(r,"on"),t.setSelectionAttribute(by,e?"after":"before");})),!0)}_enableInsertingParagraphsOnButtonClick(){const e=this.editor,t=e.editing.view;this._listenToIfEnabled(t.document,"mousedown",((i,n)=>{const s=n.domTarget.closest(".ck-widget__type-around__button");if(!s)return;const o=function(e){return e.classList.contains("ck-widget__type-around__button_before")?"before":"after"}(s),r=function(e,t){const i=e.closest(".ck-widget");return t.mapDomToView(i)}(s,t.domConverter),a=e.editing.mapper.toModelElement(r);this._insertParagraph(a,o),n.preventDefault(),i.stop();}));}_enableInsertingParagraphsOnEnterKeypress(){const e=this.editor,t=e.model.document.selection,i=e.editing.view;this._listenToIfEnabled(i.document,"enter",((i,n)=>{if("atTarget"!=i.eventPhase)return;const s=t.getSelectedElement(),o=e.editing.mapper.toViewElement(s),r=e.model.schema;let a;this._insertParagraphAccordingToFakeCaretPosition()?a=!0:wy(o,s,r)&&(this._insertParagraph(s,n.isSoft?"before":"after"),a=!0),a&&(n.preventDefault(),i.stop());}),{context:sy});}_enableInsertingParagraphsOnTypingKeystroke(){const e=this.editor.editing.view.document;this._listenToIfEnabled(e,"insertText",((t,i)=>{this._insertParagraphAccordingToFakeCaretPosition()&&(i.selection=e.selection);}),{priority:"high"}),o.isAndroid?this._listenToIfEnabled(e,"keydown",((e,t)=>{229==t.keyCode&&this._insertParagraphAccordingToFakeCaretPosition();})):this._listenToIfEnabled(e,"compositionstart",(()=>{this._insertParagraphAccordingToFakeCaretPosition();}),{priority:"high"});}_enableDeleteIntegration(){const e=this.editor,t=e.editing.view,i=e.model,n=i.schema;this._listenToIfEnabled(t.document,"delete",((t,s)=>{if("atTarget"!=t.eventPhase)return;const o=_y(i.document.selection);if(!o)return;const r=s.direction,a=i.document.selection.getSelectedElement(),l="forward"==r;if("before"===o===l)e.execute("delete",{selection:i.createSelection(a,"on")});else {const t=n.getNearestSelectionRange(i.createPositionAt(a,o),r);if(t)if(t.isCollapsed){const s=i.createSelection(t.start);if(i.modifySelection(s,{direction:r}),s.focus.isEqual(t.start)){const e=function(e,t){let i=t;for(const n of t.getAncestors({parentFirst:!0})){if(n.childCount>1||e.isLimit(n))break;i=n;}return i}(n,t.start.parent);i.deleteContent(i.createSelection(e,"on"),{doNotAutoparagraph:!0});}else i.change((i=>{i.setSelection(t),e.execute(l?"deleteForward":"delete");}));}else i.change((i=>{i.setSelection(t),e.execute(l?"deleteForward":"delete");}));}s.preventDefault(),t.stop();}),{context:sy});}_enableInsertContentIntegration(){const e=this.editor,t=this.editor.model,i=t.document.selection;this._listenToIfEnabled(e.model,"insertContent",((e,[n,s])=>{if(s&&!s.is("documentSelection"))return;const o=_y(i);return o?(e.stop(),t.change((e=>{const s=i.getSelectedElement(),r=t.createPositionAt(s,o),a=e.createSelection(r),l=t.insertContent(n,a);return e.setSelection(a),l}))):void 0}),{priority:"high"});}_enableInsertObjectIntegration(){const e=this.editor,t=this.editor.model.document.selection;this._listenToIfEnabled(e.model,"insertObject",((e,i)=>{const[,n,s={}]=i;if(n&&!n.is("documentSelection"))return;const o=_y(t);o&&(s.findOptimalPosition=o,i[3]=s);}),{priority:"high"});}_enableDeleteContentIntegration(){const e=this.editor,t=this.editor.model.document.selection;this._listenToIfEnabled(e.model,"deleteContent",((e,[i])=>{if(i&&!i.is("documentSelection"))return;_y(t)&&e.stop();}),{priority:"high"});}}function xy(e){const t=e.model;return (i,n)=>{const s=n.keyCode==nr.arrowup,o=n.keyCode==nr.arrowdown,r=n.shiftKey,a=t.document.selection;if(!s&&!o)return;const l=o;if(r&&function(e,t){return !e.isCollapsed&&e.isBackward==t}(a,l))return;const c=function(e,t,i){const n=e.model;if(i){const e=t.isCollapsed?t.focus:t.getLastPosition(),i=Ay(n,e,"forward");if(!i)return null;const s=n.createRange(e,i),o=Ey(n.schema,s,"backward");return o?n.createRange(e,o):null}{const e=t.isCollapsed?t.focus:t.getFirstPosition(),i=Ay(n,e,"backward");if(!i)return null;const s=n.createRange(i,e),o=Ey(n.schema,s,"forward");return o?n.createRange(o,e):null}}(e,a,l);if(c){if(c.isCollapsed){if(a.isCollapsed)return;if(r)return}(c.isCollapsed||function(e,t,i){const n=e.model,s=e.view.domConverter;if(i){const e=n.createSelection(t.start);n.modifySelection(e),e.focus.isAtEnd||t.start.isEqual(e.focus)||(t=n.createRange(e.focus,t.end));}const o=e.mapper.toViewRange(t),r=s.viewRangeToDom(o),a=Eo.getDomRangeRects(r);let l;for(const e of a)if(void 0!==l){if(Math.round(e.top)>=l)return !1;l=Math.max(l,Math.round(e.bottom));}else l=Math.round(e.bottom);return !0}(e,c,l))&&(t.change((e=>{const i=l?c.end:c.start;if(r){const n=t.createSelection(a.anchor);n.setFocus(i),e.setSelection(n);}else e.setSelection(i);})),i.stop(),n.preventDefault(),n.stopPropagation());}}}function Ay(e,t,i){const n=e.schema,s=e.createRangeIn(t.root),o="forward"==i?"elementStart":"elementEnd";for(const{previousPosition:e,item:r,type:a}of s.getWalker({startPosition:t,direction:i})){if(n.isLimit(r)&&!n.isInline(r))return e;if(a==o&&n.isBlock(r))return null}return null}function Ey(e,t,i){const n="backward"==i?t.end:t.start;if(e.checkChild(n,"$text"))return n;for(const{nextPosition:n}of t.getWalker({direction:i}))if(e.checkChild(n,"$text"))return n;return null}class Ty extends Dr{_previouslySelected=new Set;static get pluginName(){return "Widget"}static get isOfficialPlugin(){return !0}static get requires(){return [Cy,Rw]}init(){const e=this.editor,t=e.editing.view,i=t.document,n=e.t;this.editor.editing.downcastDispatcher.on("selection",((t,i,n)=>{const s=n.writer,o=i.selection;if(o.isCollapsed)return;const r=o.getSelectedElement();if(!r)return;const a=e.editing.mapper.toViewElement(r);sy(a)&&n.consumable.consume(o,"selection")&&s.setSelection(s.createRangeOn(a),{fake:!0,label:dy(a)});})),this.editor.editing.downcastDispatcher.on("selection",((e,t,i)=>{this._clearPreviouslySelectedWidgets(i.writer);const n=i.writer,s=n.document.selection;let o=null;for(const e of s.getRanges())for(const t of e){const e=t.item;sy(e)&&!Py(e,o)&&(n.addClass(ny,e),this._previouslySelected.add(e),o=e);}}),{priority:"low"}),t.addObserver(Wu),this.listenTo(i,"mousedown",((...e)=>this._onMousedown(...e))),this.listenTo(i,"arrowKey",((...e)=>{this._handleSelectionChangeOnArrowKeyPress(...e);}),{context:[sy,"$text"]}),this.listenTo(i,"arrowKey",((...e)=>{this._preventDefaultOnArrowKeyPress(...e);}),{context:"$root"}),this.listenTo(i,"arrowKey",xy(this.editor.editing),{context:"$text"}),this.listenTo(i,"delete",((e,t)=>{this._handleDelete("forward"==t.direction)&&(t.preventDefault(),e.stop());}),{context:"$root"}),this.listenTo(i,"tab",((e,t)=>{"atTarget"==e.eventPhase&&(t.shiftKey||this._selectFirstNestedEditable()&&(t.preventDefault(),e.stop()));}),{context:sy,priority:"low"}),this.listenTo(i,"tab",((e,t)=>{t.shiftKey&&this._selectAncestorWidget()&&(t.preventDefault(),e.stop());}),{priority:"low"}),this.listenTo(i,"keydown",((e,t)=>{t.keystroke==nr.esc&&this._selectAncestorWidget()&&(t.preventDefault(),e.stop());}),{priority:"low"}),e.accessibility.addKeystrokeInfoGroup({id:"widget",label:n("Keystrokes that can be used when a widget is selected (for example: image, table, etc.)"),keystrokes:[{label:n("Move focus from an editable area back to the parent widget"),keystroke:"Esc"},{label:n("Insert a new paragraph directly after a widget"),keystroke:"Enter"},{label:n("Insert a new paragraph directly before a widget"),keystroke:"Shift+Enter"},{label:n("Move the caret to allow typing directly before a widget"),keystroke:[["arrowup"],["arrowleft"]]},{label:n("Move the caret to allow typing directly after a widget"),keystroke:[["arrowdown"],["arrowright"]]}]});}_onMousedown(e,t){const i=this.editor,n=i.editing.view,s=n.document;let r=t.target;if(!r)return;if(t.domEvent.detail>=3)return void(this._selectBlockContent(r)&&t.preventDefault());if(!sy(r)){const e=function(e){let t=e;for(;t;){if(t.is("editableElement")||sy(t))return t;t=t.parent;}return null}(r);if(!e)return;if(sy(e))r=e;else {const e=function(e,t){const i=yo(t.domEvent);let n=null;n=i?e.domConverter.domRangeToView(i):e.createRange(e.createPositionAt(t.target,0));if(!n)return null;const s=n.start;if(!s.parent)return null;let o=s.parent;s.parent.is("editableElement")&&(s.isAtEnd&&s.nodeBefore?o=s.nodeBefore:s.isAtStart&&s.nodeAfter&&(o=s.nodeAfter));if(o.is("$text"))return o.parent;return o}(n,t);if(!e||!sy(e))return;r=e;}}o.isAndroid&&t.preventDefault(),s.isFocused||n.focus();const a=i.editing.mapper.toModelElement(r);this._setSelectionOverElement(a);}_selectBlockContent(e){const t=this.editor,i=t.model,n=t.editing.mapper,s=i.schema,o=n.findMappedViewAncestor(this.editor.editing.view.createPositionAt(e,0)),r=function(e,t){for(const i of e.getAncestors({includeSelf:!0,parentFirst:!0})){if(t.checkChild(i,"$text"))return i;if(t.isLimit(i)&&!t.isObject(i))break}return null}(n.toModelElement(o),i.schema);return !!r&&(i.change((e=>{const t=s.isLimit(r)?null:function(e,t){const i=new Gl({startPosition:e});for(const{item:e}of i){if(t.isLimit(e)||!e.is("element"))return null;if(t.checkChild(e,"$text"))return e}return null}(e.createPositionAfter(r),s),i=e.createPositionAt(r,0),n=t?e.createPositionAt(t,0):e.createPositionAt(r,"end");e.setSelection(e.createRange(i,n));})),!0)}_handleSelectionChangeOnArrowKeyPress(e,t){const i=t.keyCode,n=this.editor.model,s=n.schema,o=n.document.selection,r=o.getSelectedElement(),a=cr(i,this.editor.locale.contentLanguageDirection),l="down"==a||"right"==a,c="up"==a||"down"==a;if(r&&s.isObject(r)){const i=l?o.getLastPosition():o.getFirstPosition(),r=s.getNearestSelectionRange(i,l?"forward":"backward");return void(r&&(n.change((e=>{e.setSelection(r);})),t.preventDefault(),e.stop()))}if(!o.isCollapsed&&!t.shiftKey){const i=o.getFirstPosition(),r=o.getLastPosition(),a=i.nodeAfter,c=r.nodeBefore;return void((a&&s.isObject(a)||c&&s.isObject(c))&&(n.change((e=>{e.setSelection(l?r:i);})),t.preventDefault(),e.stop()))}if(!o.isCollapsed)return;const d=this._getObjectElementNextToSelection(l);if(d&&s.isObject(d)){if(s.isInline(d)&&c)return;this._setSelectionOverElement(d),t.preventDefault(),e.stop();}}_preventDefaultOnArrowKeyPress(e,t){const i=this.editor.model,n=i.schema,s=i.document.selection.getSelectedElement();s&&n.isObject(s)&&(t.preventDefault(),e.stop());}_handleDelete(e){const t=this.editor.model.document.selection;if(!this.editor.model.canEditAt(t))return;if(!t.isCollapsed)return;const i=this._getObjectElementNextToSelection(e);return i?(this.editor.model.change((e=>{let n=t.anchor.parent;for(;n.isEmpty;){const t=n;n=t.parent,e.remove(t);}this._setSelectionOverElement(i);})),!0):void 0}_setSelectionOverElement(e){this.editor.model.change((t=>{t.setSelection(t.createRangeOn(e));}));}_getObjectElementNextToSelection(e){const t=this.editor.model,i=t.schema,n=t.document.selection,s=t.createSelection(n);if(t.modifySelection(s,{direction:e?"forward":"backward"}),s.isEqual(n))return null;const o=e?s.focus.nodeBefore:s.focus.nodeAfter;return o&&i.isObject(o)?o:null}_clearPreviouslySelectedWidgets(e){for(const t of this._previouslySelected)e.removeClass(ny,t);this._previouslySelected.clear();}_selectFirstNestedEditable(){const e=this.editor,t=this.editor.editing.view.document;for(const i of t.selection.getFirstRange().getItems())if(i.is("editableElement")){const t=e.editing.mapper.toModelElement(i);if(!t)continue;const n=e.model.createPositionAt(t,0),s=e.model.schema.getNearestSelectionRange(n,"forward");return e.model.change((e=>{e.setSelection(s);})),!0}return !1}_selectAncestorWidget(){const e=this.editor,t=e.editing.mapper,i=e.editing.view.document.selection.getFirstPosition().parent,n=(i.is("$text")?i.parent:i).findAncestor(sy);if(!n)return !1;const s=t.toModelElement(n);return !!s&&(e.model.change((e=>{e.setSelection(s,"on");})),!0)}}function Py(e,t){return !!t&&Array.from(e.getAncestors()).includes(t)}class Sy extends Dr{_toolbarDefinitions=new Map;_balloon;static get requires(){return [Db]}static get pluginName(){return "WidgetToolbarRepository"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;if(e.plugins.has("BalloonToolbar")){const t=e.plugins.get("BalloonToolbar");this.listenTo(t,"show",(t=>{(function(e){const t=e.getSelectedElement();return !(!t||!sy(t))})(e.editing.view.document.selection)&&t.stop();}),{priority:"high"});}this._balloon=this.editor.plugins.get("ContextualBalloon"),this.on("change:isEnabled",(()=>{this._updateToolbarsVisibility();})),this.listenTo(e.ui,"update",(()=>{this._updateToolbarsVisibility();})),this.listenTo(e.ui.focusTracker,"change:isFocused",(()=>{this._updateToolbarsVisibility();}),{priority:"low"});}destroy(){super.destroy();for(const e of this._toolbarDefinitions.values())e.view.destroy();}register(e,{ariaLabel:t,items:i,getRelatedElement:n,balloonClassName:s="ck-toolbar-container"}){if(!i.length)return void E("widget-toolbar-no-items",{toolbarId:e});const o=this.editor,r=o.t,a=new Kf(o.locale);if(a.ariaLabel=t||r("Widget toolbar"),this._toolbarDefinitions.has(e))throw new A("widget-toolbar-duplicated",this,{toolbarId:e});const l={view:a,getRelatedElement:n,balloonClassName:s,itemsConfig:i,initialized:!1};o.ui.addToolbar(a,{isContextual:!0,beforeFocus:()=>{const e=n(o.editing.view.document.selection);e&&this._showToolbar(l,e);},afterBlur:()=>{this._hideToolbar(l);}}),this._toolbarDefinitions.set(e,l);}_updateToolbarsVisibility(){let e=0,t=null,i=null;for(const n of this._toolbarDefinitions.values()){const s=n.getRelatedElement(this.editor.editing.view.document.selection);if(this.isEnabled&&s)if(this.editor.ui.focusTracker.isFocused){const o=s.getAncestors().length;o>e&&(e=o,t=s,i=n);}else this._isToolbarVisible(n)&&this._hideToolbar(n);else this._isToolbarInBalloon(n)&&this._hideToolbar(n);}i&&this._showToolbar(i,t);}_hideToolbar(e){this._balloon.remove(e.view),this.stopListening(this._balloon,"change:visibleView");}_showToolbar(e,t){this._isToolbarVisible(e)?Iy(this.editor,t):this._isToolbarInBalloon(e)||(e.initialized||(e.initialized=!0,e.view.fillFromConfig(e.itemsConfig,this.editor.ui.componentFactory)),this._balloon.add({view:e.view,position:Vy(this.editor,t),balloonClassName:e.balloonClassName}),this.listenTo(this._balloon,"change:visibleView",(()=>{for(const e of this._toolbarDefinitions.values())if(this._isToolbarVisible(e)){const t=e.getRelatedElement(this.editor.editing.view.document.selection);Iy(this.editor,t);}})));}_isToolbarVisible(e){return this._balloon.visibleView===e.view}_isToolbarInBalloon(e){return this._balloon.hasView(e.view)}}function Iy(e,t){const i=e.plugins.get("ContextualBalloon"),n=Vy(e,t);i.updatePosition(n);}function Vy(e,t){const i=e.editing.view,n=Df.defaultPositions;return {target:i.domConverter.mapViewToDom(t),positions:[n.northArrowSouth,n.northArrowSouthWest,n.northArrowSouthEast,n.southArrowNorth,n.southArrowNorthWest,n.southArrowNorthEast,n.viewportStickyNorth]}}class Ry extends(Zs()){_referenceCoordinates;_options;_originalWidth;_originalHeight;_originalWidthPercents;_aspectRatio;constructor(e){super(),this.set("activeHandlePosition",null),this.set("proposedWidthPercents",null),this.set("proposedWidth",null),this.set("proposedHeight",null),this.set("proposedHandleHostWidth",null),this.set("proposedHandleHostHeight",null),this._options=e,this._referenceCoordinates=null;}get originalWidth(){return this._originalWidth}get originalHeight(){return this._originalHeight}get originalWidthPercents(){return this._originalWidthPercents}get aspectRatio(){return this._aspectRatio}begin(e,t,i){const n=new Eo(t);this.activeHandlePosition=function(e){const t=["top-left","top-right","bottom-right","bottom-left"];for(const i of t)if(e.classList.contains(Oy(i)))return i}(e),this._referenceCoordinates=function(e,t){const i=new Eo(e),n=t.split("-"),s={x:"right"==n[1]?i.right:i.left,y:"bottom"==n[0]?i.bottom:i.top};return s.x+=e.ownerDocument.defaultView.scrollX,s.y+=e.ownerDocument.defaultView.scrollY,s}(t,function(e){const t=e.split("-"),i={top:"bottom",bottom:"top",left:"right",right:"left"};return `${i[t[0]]}-${i[t[1]]}`}(this.activeHandlePosition)),this._originalWidth=n.width,this._originalHeight=n.height,this._aspectRatio=n.width/n.height;const s=i.style.width;s&&s.match(/^\d+(\.\d*)?%$/)?this._originalWidthPercents=parseFloat(s):this._originalWidthPercents=py(i,n);}update(e){this.proposedWidth=e.width,this.proposedHeight=e.height,this.proposedWidthPercents=e.widthPercents,this.proposedHandleHostWidth=e.handleHostWidth,this.proposedHandleHostHeight=e.handleHostHeight;}}function Oy(e){return `ck-widget__resizer__handle-${e}`}class By extends lg{constructor(){super();const e=this.bindTemplate;this.setTemplate({tag:"div",attributes:{class:["ck","ck-size-view",e.to("_viewPosition",(e=>e?`ck-orientation-${e}`:""))],style:{display:e.if("_isVisible","none",(e=>!e))}},children:[{text:e.to("_label")}]});}_bindToState(e,t){this.bind("_isVisible").to(t,"proposedWidth",t,"proposedHeight",((e,t)=>null!==e&&null!==t)),this.bind("_label").to(t,"proposedHandleHostWidth",t,"proposedHandleHostHeight",t,"proposedWidthPercents",((t,i,n)=>"px"===e.unit?`${t}×${i}`:`${n}%`)),this.bind("_viewPosition").to(t,"activeHandlePosition",t,"proposedHandleHostWidth",t,"proposedHandleHostHeight",((e,t,i)=>t<50||i<50?"above-center":e));}_dismiss(){this.unbind(),this._isVisible=!1;}}class My extends(Zs()){_state;_sizeView;_options;_viewResizerWrapper=null;_initialViewWidth;constructor(e){super(),this._options=e,this.set("isEnabled",!0),this.set("isSelected",!1),this.bind("isVisible").to(this,"isEnabled",this,"isSelected",((e,t)=>e&&t)),this.decorate("begin"),this.decorate("cancel"),this.decorate("commit"),this.decorate("updateSize"),this.on("commit",(e=>{this.state.proposedWidth||this.state.proposedWidthPercents||(this._cleanup(),e.stop());}),{priority:"high"});}get state(){return this._state}show(){this._options.editor.editing.view.change((e=>{e.removeClass("ck-hidden",this._viewResizerWrapper);}));}hide(){this._options.editor.editing.view.change((e=>{e.addClass("ck-hidden",this._viewResizerWrapper);}));}attach(){const e=this,t=this._options.viewElement;this._options.editor.editing.view.change((i=>{const n=i.createUIElement("div",{class:"ck ck-reset_all ck-widget__resizer"},(function(t){const i=this.toDomElement(t);return e._appendHandles(i),e._appendSizeUI(i),i}));i.insert(i.createPositionAt(t,"end"),n),i.addClass("ck-widget_with-resizer",t),this._viewResizerWrapper=n,this.isVisible||this.hide();})),this.on("change:isVisible",(()=>{this.isVisible?(this.show(),this.redraw()):this.hide();}));}begin(e){this._state=new Ry(this._options),this._sizeView._bindToState(this._options,this.state),this._initialViewWidth=this._options.viewElement.getStyle("width"),this.state.begin(e,this._getHandleHost(),this._getResizeHost());}updateSize(e){const t=this._proposeNewSize(e);this._options.editor.editing.view.change((e=>{const i=this._options.unit||"%",n=("%"===i?t.widthPercents:t.width)+i;e.setStyle("width",n,this._options.viewElement);}));const i=this._getHandleHost(),n=new Eo(i),s=Math.round(n.width),o=Math.round(n.height),r=new Eo(i);t.width=Math.round(r.width),t.height=Math.round(r.height),this.redraw(n),this.state.update({...t,handleHostWidth:s,handleHostHeight:o});}commit(){const e=this._options.unit||"%",t=("%"===e?this.state.proposedWidthPercents:this.state.proposedWidth)+e;this._options.editor.editing.view.change((()=>{this._cleanup(),this._options.onCommit(t);}));}cancel(){this._cleanup();}destroy(){this.cancel();}redraw(e){const t=this._domResizerWrapper;if(!((i=t)&&i.ownerDocument&&i.ownerDocument.contains(i)))return;var i;const n=t.parentElement,s=this._getHandleHost(),o=this._viewResizerWrapper,r=[o.getStyle("width"),o.getStyle("height"),o.getStyle("left"),o.getStyle("top")];let a;if(n.isSameNode(s)){const t=e||new Eo(s);a=[t.width+"px",t.height+"px",void 0,void 0];}else a=[s.offsetWidth+"px",s.offsetHeight+"px",s.offsetLeft+"px",s.offsetTop+"px"];"same"!==so(r,a)&&this._options.editor.editing.view.change((e=>{e.setStyle({width:a[0],height:a[1],left:a[2],top:a[3]},o);}));}containsHandle(e){return this._domResizerWrapper.contains(e)}static isResizeHandle(e){return e.classList.contains("ck-widget__resizer__handle")}_cleanup(){this._sizeView._dismiss();this._options.editor.editing.view.change((e=>{e.setStyle("width",this._initialViewWidth,this._options.viewElement);}));}_proposeNewSize(e){const t=this.state,i={x:(n=e).pageX,y:n.pageY};var n;const s=!this._options.isCentered||this._options.isCentered(this),o={x:t._referenceCoordinates.x-(i.x+t.originalWidth),y:i.y-t.originalHeight-t._referenceCoordinates.y};s&&t.activeHandlePosition.endsWith("-right")&&(o.x=i.x-(t._referenceCoordinates.x+t.originalWidth)),s&&(o.x*=2);let r=Math.abs(t.originalWidth+o.x),a=Math.abs(t.originalHeight+o.y);return "width"==(r/t.aspectRatio>a?"width":"height")?a=r/t.aspectRatio:r=a*t.aspectRatio,{width:Math.round(r),height:Math.round(a),widthPercents:Math.min(Math.round(t.originalWidthPercents/t.originalWidth*r*100)/100,100)}}_getResizeHost(){const e=this._domResizerWrapper.parentElement;return this._options.getResizeHost(e)}_getHandleHost(){const e=this._domResizerWrapper.parentElement;return this._options.getHandleHost(e)}get _domResizerWrapper(){return this._options.editor.editing.view.domConverter.mapViewToDom(this._viewResizerWrapper)}_appendHandles(e){const t=["top-left","top-right","bottom-right","bottom-left"];for(const n of t)e.appendChild(new Hm({tag:"div",attributes:{class:"ck-widget__resizer__handle "+(i=n,`ck-widget__resizer__handle-${i}`)}}).render());var i;}_appendSizeUI(e){this._sizeView=new By,this._sizeView.render(),e.appendChild(this._sizeView.element);}}class Ly extends Dr{_resizers=new Map;_observer;_redrawSelectedResizerThrottled;static get pluginName(){return "WidgetResize"}static get isOfficialPlugin(){return !0}init(){const e=this.editor.editing,t=i.window.document;this.set("selectedResizer",null),this.set("_activeResizer",null),e.view.addObserver(Wu),this._observer=new(go()),this.listenTo(e.view.document,"mousedown",this._mouseDownListener.bind(this),{priority:"high"}),this._observer.listenTo(t,"mousemove",this._mouseMoveListener.bind(this)),this._observer.listenTo(t,"mouseup",this._mouseUpListener.bind(this)),this._redrawSelectedResizerThrottled=$s((()=>this.redrawSelectedResizer()),200),this.editor.ui.on("update",this._redrawSelectedResizerThrottled),this.editor.model.document.on("change",(()=>{for(const[e,t]of this._resizers)e.isAttached()||(this._resizers.delete(e),t.destroy());}),{priority:"lowest"}),this._observer.listenTo(i.window,"resize",this._redrawSelectedResizerThrottled);const n=this.editor.editing.view.document.selection;n.on("change",(()=>{const e=n.getSelectedElement(),t=this.getResizerByViewElement(e)||null;t?this.select(t):this.deselect();}));}redrawSelectedResizer(){this.selectedResizer&&this.selectedResizer.isVisible&&this.selectedResizer.redraw();}destroy(){super.destroy(),this._observer.stopListening();for(const e of this._resizers.values())e.destroy();this._redrawSelectedResizerThrottled.cancel();}select(e){this.deselect(),this.selectedResizer=e,this.selectedResizer.isSelected=!0;}deselect(){this.selectedResizer&&(this.selectedResizer.isSelected=!1),this.selectedResizer=null;}attachTo(e){const t=new My(e),i=this.editor.plugins;if(t.attach(),i.has("WidgetToolbarRepository")){const e=i.get("WidgetToolbarRepository");t.on("begin",(()=>{e.forceDisabled("resize");}),{priority:"lowest"}),t.on("cancel",(()=>{e.clearForceDisabled("resize");}),{priority:"highest"}),t.on("commit",(()=>{e.clearForceDisabled("resize");}),{priority:"highest"});}this._resizers.set(e.viewElement,t);const n=this.editor.editing.view.document.selection.getSelectedElement();return this.getResizerByViewElement(n)==t&&this.select(t),t}getResizerByViewElement(e){return this._resizers.get(e)}_getResizerByHandle(e){for(const t of this._resizers.values())if(t.containsHandle(e))return t}_mouseDownListener(e,t){const i=t.domTarget;My.isResizeHandle(i)&&(this._activeResizer=this._getResizerByHandle(i)||null,this._activeResizer&&(this._activeResizer.begin(i),e.stop(),t.preventDefault()));}_mouseMoveListener(e,t){this._activeResizer&&this._activeResizer.updateSize(t);}_mouseUpListener(){this._activeResizer&&(this._activeResizer.commit(),this._activeResizer=null);}}const Fy=Oo("px");class Ny extends lg{constructor(){super();const e=this.bindTemplate;this.set({isVisible:!1,left:null,top:null,width:null}),this.setTemplate({tag:"div",attributes:{class:["ck","ck-clipboard-drop-target-line",e.if("isVisible","ck-hidden",(e=>!e))],style:{left:e.to("left",(e=>Fy(e))),top:e.to("top",(e=>Fy(e))),width:e.to("width",(e=>Fy(e)))}}});}}class Dy extends Dr{removeDropMarkerDelayed=Sr((()=>this.removeDropMarker()),40);_updateDropMarkerThrottled=$s((e=>this._updateDropMarker(e)),40);_reconvertMarkerThrottled=$s((()=>{this.editor.model.markers.has("drop-target")&&this.editor.editing.reconvertMarker("drop-target");}),0);_dropTargetLineView=new Ny;_domEmitter=new(go());_scrollables=new Map;static get pluginName(){return "DragDropTarget"}static get isOfficialPlugin(){return !0}init(){this._setupDropMarker();}destroy(){this._domEmitter.stopListening();for(const{resizeObserver:e}of this._scrollables.values())e.destroy();return this._updateDropMarkerThrottled.cancel(),this.removeDropMarkerDelayed.cancel(),this._reconvertMarkerThrottled.cancel(),super.destroy()}updateDropMarker(e,t,i,n,s,o){this.removeDropMarkerDelayed.cancel();const r=zy(this.editor,e,t,i,n,s,o);if(r)return o&&o.containsRange(r)?this.removeDropMarker():void this._updateDropMarkerThrottled(r)}getFinalDropRange(e,t,i,n,s,o){const r=zy(this.editor,e,t,i,n,s,o);return this.removeDropMarker(),r}removeDropMarker(){const e=this.editor.model;this.removeDropMarkerDelayed.cancel(),this._updateDropMarkerThrottled.cancel(),this._dropTargetLineView.isVisible=!1,e.markers.has("drop-target")&&e.change((e=>{e.removeMarker("drop-target");}));}_setupDropMarker(){const e=this.editor;e.ui.view.body.add(this._dropTargetLineView),e.conversion.for("editingDowncast").markerToHighlight({model:"drop-target",view:{classes:["ck-clipboard-drop-target-range"]}}),e.conversion.for("editingDowncast").markerToElement({model:"drop-target",view:(t,{writer:i})=>{if(e.model.schema.checkChild(t.markerRange.start,"$text"))return this._dropTargetLineView.isVisible=!1,this._createDropTargetPosition(i);t.markerRange.isCollapsed?this._updateDropTargetLine(t.markerRange):this._dropTargetLineView.isVisible=!1;}});}_updateDropMarker(e){const t=this.editor,i=t.model.markers;t.model.change((t=>{i.has("drop-target")?i.get("drop-target").getRange().isEqual(e)||t.updateMarker("drop-target",{range:e}):t.addMarker("drop-target",{range:e,usingOperation:!1,affectsData:!1});}));}_createDropTargetPosition(e){return e.createUIElement("span",{class:"ck ck-clipboard-drop-target-position"},(function(e){const t=this.toDomElement(e);return t.append("⁠",e.createElement("span"),"⁠"),t}))}_updateDropTargetLine(e){const t=this.editor.editing,n=e.start.nodeBefore,s=e.start.nodeAfter,o=e.start.parent,r=n?t.mapper.toViewElement(n):null,a=r?t.view.domConverter.mapViewToDom(r):null,l=s?t.mapper.toViewElement(s):null,c=l?t.view.domConverter.mapViewToDom(l):null,d=t.mapper.toViewElement(o);if(!d)return;const u=t.view.domConverter.mapViewToDom(d),h=this._getScrollableRect(d),{scrollX:m,scrollY:g}=i.window,f=a?new Eo(a):null,p=c?new Eo(c):null,b=new Eo(u).excludeScrollbarsAndBorders(),w=f?f.bottom:b.top,_=p?p.top:b.bottom,v=i.window.getComputedStyle(u),y=w<=_?(w+_)/2:_;if(h.topa.schema.checkChild(o,e)))){if(a.schema.checkChild(o,"$text"))return a.createRange(o);if(t)return $y(e,Wy(e,t.parent),n,s)}}}else if(a.schema.isInline(c))return $y(e,c,n,s);if(a.schema.isBlock(c))return $y(e,c,n,s);if(a.schema.checkChild(c,"$block")){const t=Array.from(c.getChildren()).filter((t=>t.is("element")&&!Hy(e,t)));let i=0,o=t.length;if(0==o)return a.createRange(a.createPositionAt(c,"end"));for(;i{i?(this.forceDisabled("readOnlyMode"),this._isBlockDragging=!1):this.clearForceDisabled("readOnlyMode");})),o.isAndroid&&this.forceDisabled("noAndroidSupport"),e.plugins.has("BlockToolbar")){const t=e.plugins.get("BlockToolbar").buttonView.element;this._domEmitter.listenTo(t,"dragstart",((e,t)=>this._handleBlockDragStart(t))),this._domEmitter.listenTo(i.document,"dragover",((e,t)=>this._handleBlockDragging(t))),this._domEmitter.listenTo(i.document,"drop",((e,t)=>this._handleBlockDragging(t))),this._domEmitter.listenTo(i.document,"dragend",(()=>this._handleBlockDragEnd()),{useCapture:!0}),this.isEnabled&&t.setAttribute("draggable","true"),this.on("change:isEnabled",((e,i,n)=>{t.setAttribute("draggable",n?"true":"false");}));}}destroy(){return this._domEmitter.stopListening(),super.destroy()}_handleBlockDragStart(e){if(!this.isEnabled)return;const t=this.editor.model,i=t.document.selection,n=this.editor.editing.view,s=Array.from(i.getSelectedBlocks()),o=t.createRange(t.createPositionBefore(s[0]),t.createPositionAfter(s[s.length-1]));t.change((e=>e.setSelection(o))),this._isBlockDragging=!0,n.focus(),n.getObserver(Uv).onDomEvent(e);}_handleBlockDragging(e){if(!this.isEnabled||!this._isBlockDragging)return;const t=e.clientX+("ltr"==this.editor.locale.contentLanguageDirection?100:-100),i=e.clientY,n=document.elementFromPoint(t,i),s=this.editor.editing.view;n&&n.closest(".ck-editor__editable")&&s.getObserver(Uv).onDomEvent({...e,type:e.type,dataTransfer:e.dataTransfer,target:n,clientX:t,clientY:i,preventDefault:()=>e.preventDefault(),stopPropagation:()=>e.stopPropagation()});}_handleBlockDragEnd(){this._isBlockDragging=!1;}}class qy extends Dr{_draggedRange;_draggingUid;_draggableElement;_clearDraggableAttributesDelayed=Sr((()=>this._clearDraggableAttributes()),40);_blockMode=!1;_domEmitter=new(go());_previewContainer;static get pluginName(){return "DragDrop"}static get isOfficialPlugin(){return !0}static get requires(){return [Jv,Ty,Dy,jy]}init(){const e=this.editor,t=e.editing.view;this._draggedRange=null,this._draggingUid="",this._draggableElement=null,t.addObserver(Uv),t.addObserver(Wu),this._setupDragging(),this._setupContentInsertionIntegration(),this._setupClipboardInputIntegration(),this._setupDraggableAttributeHandling(),this.listenTo(e,"change:isReadOnly",((e,t,i)=>{i?this.forceDisabled("readOnlyMode"):this.clearForceDisabled("readOnlyMode");})),this.on("change:isEnabled",((e,t,i)=>{i||this._finalizeDragging(!1);})),o.isAndroid&&this.forceDisabled("noAndroidSupport");}destroy(){return this._draggedRange&&(this._draggedRange.detach(),this._draggedRange=null),this._previewContainer&&this._previewContainer.remove(),this._domEmitter.stopListening(),this._clearDraggableAttributesDelayed.cancel(),super.destroy()}_setupDragging(){const e=this.editor,t=e.model,n=e.editing.view,s=n.document,r=e.plugins.get(Dy);this.listenTo(s,"dragstart",((e,i)=>{if(i.target&&i.target.is("editableElement"))return void i.preventDefault();if(this._prepareDraggedRange(i.target),!this._draggedRange)return void i.preventDefault();this._draggingUid=k(),i.dataTransfer.effectAllowed=this.isEnabled?"copyMove":"copy",i.dataTransfer.setData("application/ckeditor5-dragging-uid",this._draggingUid);const n=t.createSelection(this._draggedRange.toRange());this.editor.plugins.get("ClipboardPipeline")._fireOutputTransformationEvent(i.dataTransfer,n,"dragstart");const{dataTransfer:s,domTarget:o,domEvent:r}=i,{clientX:a}=r;this._updatePreview({dataTransfer:s,domTarget:o,clientX:a}),i.stopPropagation(),this.isEnabled||(this._draggedRange.detach(),this._draggedRange=null,this._draggingUid="");}),{priority:"low"}),this.listenTo(s,"dragend",((e,t)=>{this._finalizeDragging(!t.dataTransfer.isCanceled&&"move"==t.dataTransfer.dropEffect);}),{priority:"low"}),this._domEmitter.listenTo(i.document,"dragend",(()=>{this._blockMode=!1;}),{useCapture:!0}),this.listenTo(s,"dragenter",(()=>{this.isEnabled&&n.focus();})),this.listenTo(s,"dragleave",(()=>{r.removeDropMarkerDelayed();})),this.listenTo(s,"dragging",((e,t)=>{if(!this.isEnabled)return void(t.dataTransfer.dropEffect="none");const{clientX:i,clientY:n}=t.domEvent;r.updateDropMarker(t.target,t.targetRanges,i,n,this._blockMode,this._draggedRange),this._draggedRange||(t.dataTransfer.dropEffect="copy"),o.isGecko||("copy"==t.dataTransfer.effectAllowed?t.dataTransfer.dropEffect="copy":["all","copyMove"].includes(t.dataTransfer.effectAllowed)&&(t.dataTransfer.dropEffect="move")),e.stop();}),{priority:"low"});}_setupClipboardInputIntegration(){const e=this.editor,t=e.editing.view.document,i=e.plugins.get(Dy);this.listenTo(t,"clipboardInput",((t,n)=>{if("drop"!=n.method)return;const{clientX:s,clientY:o}=n.domEvent,r=i.getFinalDropRange(n.target,n.targetRanges,s,o,this._blockMode,this._draggedRange);if(!r)return this._finalizeDragging(!1),void t.stop();this._draggedRange&&this._draggingUid!=n.dataTransfer.getData("application/ckeditor5-dragging-uid")&&(this._draggedRange.detach(),this._draggedRange=null,this._draggingUid="");if("move"==Gy(n.dataTransfer)&&this._draggedRange&&this._draggedRange.containsRange(r,!0))return this._finalizeDragging(!1),void t.stop();n.targetRanges=[e.editing.mapper.toViewRange(r)];}),{priority:"high"});}_setupContentInsertionIntegration(){const e=this.editor.plugins.get(Jv);e.on("contentInsertion",((e,t)=>{if(!this.isEnabled||"drop"!==t.method)return;const i=t.targetRanges.map((e=>this.editor.editing.mapper.toModelRange(e)));this.editor.model.change((e=>e.setSelection(i)));}),{priority:"high"}),e.on("contentInsertion",((e,t)=>{if(!this.isEnabled||"drop"!==t.method)return;const i="move"==Gy(t.dataTransfer),n=!t.resultRange||!t.resultRange.isCollapsed;this._finalizeDragging(n&&i);}),{priority:"lowest"});}_setupDraggableAttributeHandling(){const e=this.editor,t=e.editing.view,i=t.document;this.listenTo(i,"mousedown",((n,s)=>{if(o.isAndroid||!s)return;this._clearDraggableAttributesDelayed.cancel();let r=Ky(s.target);if(o.isBlink&&!e.isReadOnly&&!r&&!i.selection.isCollapsed){const e=i.selection.getSelectedElement();e&&sy(e)||(r=i.selection.editableElement);}r&&(t.change((e=>{e.setAttribute("draggable","true",r);})),this._draggableElement=e.editing.mapper.toModelElement(r));})),this.listenTo(i,"mouseup",(()=>{o.isAndroid||this._clearDraggableAttributesDelayed();}));}_clearDraggableAttributes(){const e=this.editor.editing;e.view.change((t=>{this._draggableElement&&"$graveyard"!=this._draggableElement.root.rootName&&t.removeAttribute("draggable",e.mapper.toViewElement(this._draggableElement)),this._draggableElement=null;}));}_finalizeDragging(e){const t=this.editor,i=t.model;if(t.plugins.get(Dy).removeDropMarker(),this._clearDraggableAttributes(),t.plugins.has("WidgetToolbarRepository")){t.plugins.get("WidgetToolbarRepository").clearForceDisabled("dragDrop");}this._draggingUid="",this._previewContainer&&(this._previewContainer.remove(),this._previewContainer=void 0),this._draggedRange&&(e&&this.isEnabled&&i.change((e=>{const t=i.createSelection(this._draggedRange);i.deleteContent(t,{doNotAutoparagraph:!0});const n=t.getFirstPosition().parent;n.isEmpty&&!i.schema.checkChild(n,"$text")&&i.schema.checkChild(n,"paragraph")&&e.insertElement("paragraph",n,0);})),this._draggedRange.detach(),this._draggedRange=null);}_prepareDraggedRange(e){const t=this.editor,i=t.model,n=i.document.selection,s=e?Ky(e):null;if(s){const e=t.editing.mapper.toModelElement(s);if(this._draggedRange=fc.fromRange(i.createRangeOn(e)),this._blockMode=i.schema.isBlock(e),t.plugins.has("WidgetToolbarRepository")){t.plugins.get("WidgetToolbarRepository").forceDisabled("dragDrop");}return}if(n.isCollapsed&&!n.getFirstPosition().parent.isEmpty)return;const o=Array.from(n.getSelectedBlocks()),r=n.getFirstRange();if(0==o.length)return void(this._draggedRange=fc.fromRange(r));const a=Zy(i,o);if(o.length>1)this._draggedRange=fc.fromRange(a),this._blockMode=!0;else if(1==o.length){const e=r.start.isTouching(a.start)&&r.end.isTouching(a.end);this._draggedRange=fc.fromRange(e?a:r),this._blockMode=e;}i.change((e=>e.setSelection(this._draggedRange.toRange())));}_updatePreview({dataTransfer:e,domTarget:t,clientX:n}){const s=this.editor.editing.view,r=s.document.selection.editableElement,a=s.domConverter.mapViewToDom(r),l=i.window.getComputedStyle(a);this._previewContainer?this._previewContainer.firstElementChild&&this._previewContainer.removeChild(this._previewContainer.firstElementChild):(this._previewContainer=ro(i.document,"div",{style:"position: fixed; left: -999999px;"}),i.document.body.appendChild(this._previewContainer));const c=new Eo(a);if(a.contains(t))return;const d=parseFloat(l.paddingLeft),u=ro(i.document,"div");u.className="ck ck-content",u.style.width=l.width,u.style.paddingLeft=`${c.left-n+d}px`,o.isiOS&&(u.style.backgroundColor="white"),s.domConverter.setContentOf(u,e.getData("text/html")),e.setDragImage(u,0,0),this._previewContainer.appendChild(u);}}function Gy(e){return o.isGecko?e.dropEffect:["all","copyMove"].includes(e.effectAllowed)?"move":"copy"}function Ky(e){if(e.is("editableElement"))return null;if(e.hasClass("ck-widget__selection-handle"))return e.findAncestor(sy);if(sy(e))return e;const t=e.findAncestor((e=>sy(e)||e.is("editableElement")));return sy(t)?t:null}function Zy(e,t){const i=t[0],n=t[t.length-1],s=i.getCommonAncestor(n),o=e.createPositionBefore(i),r=e.createPositionAfter(n);if(s&&s.is("element")&&!e.schema.isLimit(s)){const t=e.createRangeOn(s),i=o.isTouching(t.start),n=r.isTouching(t.end);if(i&&n)return Zy(e,[s])}return e.createRange(o,r)}class Jy extends Dr{static get pluginName(){return "PastePlainText"}static get isOfficialPlugin(){return !0}static get requires(){return [Jv]}init(){const e=this.editor,t=e.model,i=e.editing.view,n=t.document.selection;i.addObserver(Uv),e.plugins.get(Jv).on("contentInsertion",((e,i)=>{(function(e,t){let i=t.createRangeIn(e);if(1==e.childCount){const n=e.getChild(0);n.is("element")&&t.schema.isBlock(n)&&!t.schema.isObject(n)&&!t.schema.isLimit(n)&&(i=t.createRangeIn(n));}for(const e of i.getItems()){if(!t.schema.isInline(e))return !1;if(Array.from(e.getAttributeKeys()).find((e=>t.schema.getAttributeProperties(e).isFormatting)))return !1}return !0})(i.content,t)&&t.change((e=>{const s=Array.from(n.getAttributes()).filter((([e])=>t.schema.getAttributeProperties(e).isFormatting));n.isCollapsed||t.deleteContent(n,{doNotAutoparagraph:!0}),s.push(...n.getAttributes());const o=e.createRangeIn(i.content);for(const i of o.getItems())for(const n of s)t.schema.checkAttribute(i,n[0])&&e.setAttribute(n[0],n[1],i);}));}));}}class Qy extends Dr{static get pluginName(){return "Clipboard"}static get isOfficialPlugin(){return !0}static get requires(){return [Zv,Jv,qy,Jy]}init(){const e=this.editor,t=this.editor.t;e.accessibility.addKeystrokeInfos({keystrokes:[{label:t("Copy selected content"),keystroke:"CTRL+C"},{label:t("Paste content"),keystroke:"CTRL+V"},{label:t("Paste content as plain text"),keystroke:"CTRL+SHIFT+V"}]});}}const Yy={autoRefresh:!0},Xy=36e5;class ek extends(Zs()){_refresh;_options;_tokenRefreshTimeout;constructor(e,t={}){if(super(),!e)throw new A("token-missing-token-url",this);t.initValue&&this._validateTokenValue(t.initValue),this.set("value",t.initValue),this._refresh="function"==typeof e?e:()=>{return t=e,new Promise(((e,i)=>{const n=new XMLHttpRequest;n.open("GET",t),n.addEventListener("load",(()=>{const t=n.status,s=n.response;return t<200||t>299?i(new A("token-cannot-download-new-token",null)):e(s)})),n.addEventListener("error",(()=>i(new Error("Network Error")))),n.addEventListener("abort",(()=>i(new Error("Abort")))),n.send();}));var t;},this._options={...Yy,...t};}init(){return new Promise(((e,t)=>{this.value?(this._options.autoRefresh&&this._registerRefreshTokenTimeout(),e(this)):this.refreshToken().then(e).catch(t);}))}refreshToken(){const e=this._options.autoRefresh;return this._refresh().then((t=>(this._validateTokenValue(t),this.set("value",t),e&&this._registerRefreshTokenTimeout(),this))).catch((t=>{throw E("token-refresh-failed",{autoRefresh:e}),e&&this._registerRefreshTokenTimeout(5e3),t}))}destroy(){clearTimeout(this._tokenRefreshTimeout);}_validateTokenValue(e){const t="string"==typeof e,i=!/^".*"$/.test(e),n=t&&3===e.split(".").length;if(!i||!n)throw new A("token-not-in-jwt-format",this)}_registerRefreshTokenTimeout(e){const t=e||this._getTokenRefreshTimeoutTime();clearTimeout(this._tokenRefreshTimeout),this._tokenRefreshTimeout=setTimeout((()=>{this.refreshToken();}),t);}_getTokenRefreshTimeoutTime(){try{const[,e]=this.value.split("."),{exp:t}=JSON.parse(atob(e));if(!t)return Xy;return Math.floor((1e3*t-Date.now())/2)}catch(e){return Xy}}static create(e,t={}){return new ek(e,t).init()}}const tk=/^data:(\S*?);base64,/;class ik extends(L()){file;xhr;_token;_apiAddress;constructor(e,t,i){if(super(),!e)throw new A("fileuploader-missing-file",null);if(!t)throw new A("fileuploader-missing-token",null);if(!i)throw new A("fileuploader-missing-api-address",null);this.file=function(e){if("string"!=typeof e)return !1;const t=e.match(tk);return !(!t||!t.length)}(e)?function(e,t=512){try{const i=e.match(tk)[1],n=atob(e.replace(tk,"")),s=[];for(let e=0;ee(i))),this}onError(e){return this.once("error",((t,i)=>e(i))),this}abort(){this.xhr.abort();}send(){return this._prepareRequest(),this._attachXHRListeners(),this._sendRequest()}_prepareRequest(){const e=new XMLHttpRequest;e.open("POST",this._apiAddress),e.setRequestHeader("Authorization",this._token.value),e.responseType="json",this.xhr=e;}_attachXHRListeners(){const e=this.xhr,t=e=>()=>this.fire("error",e);e.addEventListener("error",t("Network Error")),e.addEventListener("abort",t("Abort")),e.upload&&e.upload.addEventListener("progress",(e=>{e.lengthComputable&&this.fire("progress",{total:e.total,uploaded:e.loaded});})),e.addEventListener("load",(()=>{const t=e.status,i=e.response;if(t<200||t>299)return this.fire("error",i.message||i.error)}));}_sendRequest(){const e=new FormData,t=this.xhr;return e.append("file",this.file),new Promise(((i,n)=>{t.addEventListener("load",(()=>{const e=t.status,s=t.response;return e<200||e>299?s.message?n(new A("fileuploader-uploading-data-failed",this,{message:s.message})):n(s.error):i(s)})),t.addEventListener("error",(()=>n(new Error("Network Error")))),t.addEventListener("abort",(()=>n(new Error("Abort")))),t.send(e);}))}}class nk{_token;_apiAddress;constructor(e,t){if(!e)throw new A("uploadgateway-missing-token",null);if(!t)throw new A("uploadgateway-missing-api-address",null);this._token=e,this._apiAddress=t;}upload(e){return new ik(e,this._token,this._apiAddress)}}class sk extends qr{static get pluginName(){return "CloudServicesCore"}static get isOfficialPlugin(){return !0}createToken(e,t){return new ek(e,t)}createUploadGateway(e,t){return new nk(e,t)}}class ok extends qr{tokenUrl;uploadUrl;webSocketUrl;bundleVersion;token=null;_tokens=new Map;static get pluginName(){return "CloudServices"}static get isOfficialPlugin(){return !0}static get requires(){return [sk]}async init(){const e=this.context.config.get("cloudServices")||{};for(const[t,i]of Object.entries(e))this[t]=i;if(!this.tokenUrl)return void(this.token=null);const t=this.context.plugins.get("CloudServicesCore");this.token=await t.createToken(this.tokenUrl).init(),this._tokens.set(this.tokenUrl,this.token);}async registerTokenUrl(e){if(this._tokens.has(e))return this.getTokenFor(e);const t=this.context.plugins.get("CloudServicesCore"),i=await t.createToken(e).init();return this._tokens.set(e,i),i}getTokenFor(e){const t=this._tokens.get(e);if(!t)throw new A("cloudservices-token-not-registered",this);return t}destroy(){super.destroy();for(const e of this._tokens.values())e.destroy();}}function rk(e){const t=e.t,i=e.config.get("codeBlock.languages");for(const e of i)"Plain text"===e.label&&(e.label=t("Plain text")),void 0===e.class&&(e.class=`language-${e.language}`);return i}function ak(e,t,i){const n={};for(const s of e)if("class"===t){n[s[t].split(" ").shift()]=s[i];}else n[s[t]]=s[i];return n}function lk(e){return e.data.match(/^(\s*)/)[0]}function ck(e){const t=e.document.selection,i=[];if(t.isCollapsed)return [t.anchor];const n=t.getFirstRange().getWalker({ignoreElementEnd:!0,direction:"backward"});for(const{item:t}of n){let n=t.is("$textProxy")?t.textNode:t;const s=n.parent;if(!s.is("element","codeBlock")||n.is("element","softBreak"))continue;for(;n.previousSibling&&!n.previousSibling.is("element","softBreak");)n=n.previousSibling;const o=n.is("$text")?n.startOffset+lk(n).length:n.startOffset,r=e.createPositionAt(s,o);i.every((e=>!e.isEqual(r)))&&i.push(r);}return i}function dk(e){const t=wr(e.getSelectedBlocks());return !!t&&t.is("element","codeBlock")}function uk(e,t){return !t.is("rootElement")&&!e.isLimit(t)&&e.checkChild(t.parent,"codeBlock")}function hk(e,t,i,n){const s=ak(t,"language","label"),o=i.getAttribute("language");if(o in s){const t=s[o];return e("enter"===n?"Entering %0 code snippet":"Leaving %0 code snippet",t)}return e("enter"===n?"Entering code snippet":"Leaving code snippet")}function mk(e,t){for(e.textNode&&(e=t.createPositionBefore(e.textNode));e.nodeBefore&&!e.nodeBefore.is("element","softBreak");)e=t.createPositionBefore(e.nodeBefore);const i=e.nodeAfter;return i&&i.is("$text")?i:null}class gk extends Hr{_lastLanguage;constructor(e){super(e),this._lastLanguage=null;}refresh(){this.value=this._getValue(),this.isEnabled=this._checkEnabled();}execute(e={}){const t=this.editor,i=t.model,n=i.document.selection,s=rk(t)[0],o=Array.from(n.getSelectedBlocks()),r=null==e.forceValue?!this.value:e.forceValue,a=function(e,t,i){if(e.language)return e.language;if(e.usePreviousLanguageChoice&&t)return t;return i}(e,this._lastLanguage,s.language);i.change((e=>{r?this._applyCodeBlock(e,o,a):this._removeCodeBlock(e,o);}));}_getValue(){const e=wr(this.editor.model.document.selection.getSelectedBlocks());return !!!(!e||!e.is("element","codeBlock"))&&e.getAttribute("language")}_checkEnabled(){if(this.value)return !0;const e=this.editor.model.document.selection,t=this.editor.model.schema,i=wr(e.getSelectedBlocks());return !!i&&uk(t,i)}_applyCodeBlock(e,t,i){this._lastLanguage=i;const n=this.editor.model.schema,s=t.filter((e=>uk(n,e)));for(const t of s)e.rename(t,"codeBlock"),e.setAttribute("language",i,t),n.removeDisallowedAttributes([t],e),Array.from(t.getChildren()).filter((e=>!n.checkChild(t,e))).forEach((t=>e.remove(t)));s.reverse().forEach(((t,i)=>{const n=s[i+1];t.previousSibling===n&&(e.appendElement("softBreak",n),e.merge(e.createPositionBefore(t)));}));}_removeCodeBlock(e,t){const i=t.filter((e=>e.is("element","codeBlock")));for(const t of i){const i=e.createRangeOn(t);for(const t of Array.from(i.getItems()).reverse())if(t.is("element","softBreak")&&t.parent.is("element","codeBlock")){const{position:i}=e.split(e.createPositionBefore(t)),n=i.nodeAfter;e.rename(n,"paragraph"),e.removeAttribute("language",n),e.remove(t);}e.rename(t,"paragraph"),e.removeAttribute("language",t);}}}class fk extends Hr{_indentSequence;constructor(e){super(e),this._indentSequence=e.config.get("codeBlock.indentSequence");}refresh(){this.isEnabled=this._checkEnabled();}execute(){const e=this.editor.model;e.change((t=>{const i=ck(e);for(const n of i){const i=t.createText(this._indentSequence);e.insertContent(i,n);}}));}_checkEnabled(){return !!this._indentSequence&&dk(this.editor.model.document.selection)}}class pk extends Hr{_indentSequence;constructor(e){super(e),this._indentSequence=e.config.get("codeBlock.indentSequence");}refresh(){this.isEnabled=this._checkEnabled();}execute(){const e=this.editor.model;e.change((()=>{const t=ck(e);for(const i of t){const t=bk(e,i,this._indentSequence);t&&e.deleteContent(e.createSelection(t));}}));}_checkEnabled(){if(!this._indentSequence)return !1;const e=this.editor.model;return !!dk(e.document.selection)&&ck(e).some((t=>bk(e,t,this._indentSequence)))}}function bk(e,t,i){const n=mk(t,e);if(!n)return null;const s=lk(n),o=s.lastIndexOf(i);if(o+i.length!==s.length)return null;if(-1===o)return null;const{parent:r,startOffset:a}=n;return e.createRange(e.createPositionAt(r,a+o),e.createPositionAt(r,a+o+i.length))}function wk(e,t,i=!1){const n=ak(t,"language","class"),s=ak(t,"language","label");return (t,o,r)=>{const{writer:a,mapper:l,consumable:c}=r;if(!c.consume(o.item,"insert"))return;const d=o.item.getAttribute("language"),u=l.toViewPosition(e.createPositionBefore(o.item)),h={};i&&(h["data-language"]=s[d],h.spellcheck="false");const m=n[d]?{class:n[d]}:void 0,g=a.createContainerElement("code",m),f=a.createContainerElement("pre",h,g);a.insert(u,f),l.bindElements(o.item,g);}}const _k="paragraph";class vk extends Dr{static get pluginName(){return "CodeBlockEditing"}static get isOfficialPlugin(){return !0}static get requires(){return [Y_]}constructor(e){super(e),e.config.define("codeBlock",{languages:[{language:"plaintext",label:"Plain text"},{language:"c",label:"C"},{language:"cs",label:"C#"},{language:"cpp",label:"C++"},{language:"css",label:"CSS"},{language:"diff",label:"Diff"},{language:"html",label:"HTML"},{language:"java",label:"Java"},{language:"javascript",label:"JavaScript"},{language:"php",label:"PHP"},{language:"python",label:"Python"},{language:"ruby",label:"Ruby"},{language:"typescript",label:"TypeScript"},{language:"xml",label:"XML"}],indentSequence:"\t"});}init(){const e=this.editor,t=e.model.schema,i=e.model,n=e.editing.view,s=rk(e);e.commands.add("codeBlock",new gk(e)),e.commands.add("indentCodeBlock",new fk(e)),e.commands.add("outdentCodeBlock",new pk(e)),this.listenTo(n.document,"tab",((t,i)=>{const n=i.shiftKey?"outdentCodeBlock":"indentCodeBlock";e.commands.get(n).isEnabled&&(e.execute(n),i.stopPropagation(),i.preventDefault(),t.stop());}),{context:"pre"}),t.register("codeBlock",{allowWhere:"$block",allowChildren:"$text",disallowChildren:"$inlineObject",allowAttributes:["language"],allowAttributesOf:"$listItem",isBlock:!0}),t.addAttributeCheck(((e,i)=>{const n=e.getItem(e.length-2);if(t.getAttributeProperties(i).isFormatting&&n&&"codeBlock"==n.name)return !1})),e.editing.downcastDispatcher.on("insert:codeBlock",wk(i,s,!0)),e.data.downcastDispatcher.on("insert:codeBlock",wk(i,s)),e.data.downcastDispatcher.on("insert:softBreak",function(e){return (t,i,n)=>{if("codeBlock"!==i.item.parent.name)return;const{writer:s,mapper:o,consumable:r}=n;if(!r.consume(i.item,"insert"))return;const a=o.toViewPosition(e.createPositionBefore(i.item));s.insert(a,s.createText("\n"));}}(i),{priority:"high"}),e.data.upcastDispatcher.on("element:code",function(e,t){const i=ak(t,"class","language"),n=t[0].language;return (e,t,s)=>{const o=t.viewItem,r=o.parent;if(!r||!r.is("element","pre"))return;if(t.modelCursor.findAncestor("codeBlock"))return;const{consumable:a,writer:l}=s;if(!a.test(o,{name:!0}))return;const c=l.createElement("codeBlock"),d=[...o.getClassNames()];d.length||d.push("");for(const e of d){const t=i[e];if(t){l.setAttribute("language",t,c);break}}c.hasAttribute("language")||l.setAttribute("language",n,c),s.convertChildren(o,c),s.safeInsert(c,t.modelCursor)&&(a.consume(o,{name:!0}),s.updateConversionResult(c,t));}}(0,s)),e.data.upcastDispatcher.on("text",((e,t,{consumable:i,writer:n})=>{let s=t.modelCursor;if(!i.test(t.viewItem))return;if(!s.findAncestor("codeBlock"))return;i.consume(t.viewItem);const o=t.viewItem.data.split("\n").map((e=>n.createText(e))),r=o[o.length-1];for(const e of o)if(n.insert(e,s),s=s.getShiftedBy(e.offsetSize),e!==r){const e=n.createElement("softBreak");n.insert(e,s),s=n.createPositionAfter(e);}t.modelRange=n.createRange(t.modelCursor,s),t.modelCursor=s;})),e.data.upcastDispatcher.on("element:pre",((e,t,{consumable:i})=>{const n=t.viewItem;if(n.findAncestor("pre"))return;const s=Array.from(n.getChildren()),o=s.find((e=>e.is("element","code")));if(o)for(const e of s)e!==o&&e.is("$text")&&i.consume(e,{name:!0});}),{priority:"high"}),this.listenTo(e.editing.view.document,"clipboardInput",((t,n)=>{let s=i.createRange(i.document.selection.anchor);if(n.targetRanges&&(s=e.editing.mapper.toModelRange(n.targetRanges[0])),!s.start.parent.is("element","codeBlock"))return;const o=n.dataTransfer.getData("text/plain"),r=new ju(e.editing.view.document);n.content=function(e,t){const i=e.createDocumentFragment(),n=t.split("\n"),s=n.reduce(((t,i,s)=>(t.push(i),s{const s=e.model,o=s.document.selection;o.anchor.parent.is("element","codeBlock")&&s.change((e=>{const i=e.createRangeIn(n.content);for(const n of [...i.getItems()])n.is("node")&&!t.checkChild(o.anchor,n)&&e.remove(n);}));})),this.listenTo(i,"getSelectedContent",((e,[n])=>{const s=n.anchor;!n.isCollapsed&&s.parent.is("element","codeBlock")&&s.hasSameParentAs(n.focus)&&i.change((i=>{const o=e.return;if(s.parent.is("element")&&(o.childCount>1||n.containsEntireContent(s.parent))){const t=i.createElement("codeBlock",s.parent.getAttributes());i.append(o,t);const n=i.createDocumentFragment();return i.append(t,n),void(e.return=n)}const r=o.getChild(0);t.checkAttribute(r,"code")&&i.setAttribute("code",!0,r);}));}));}afterInit(){const e=this.editor,t=e.commands,i=t.get("indent"),n=t.get("outdent");i&&i.registerChildCommand(t.get("indentCodeBlock"),{priority:"highest"}),n&&n.registerChildCommand(t.get("outdentCodeBlock")),this.listenTo(e.editing.view.document,"enter",((t,i)=>{e.model.document.selection.getLastPosition().parent.is("element","codeBlock")&&(function(e,t){const i=e.model,n=i.document,s=e.editing.view,o=n.selection.getLastPosition(),r=o.nodeAfter;if(t||!n.selection.isCollapsed||!o.isAtStart)return !1;if(!kk(r))return !1;return e.model.change((t=>{e.execute("enter");const i=n.selection.anchor.parent.previousSibling;t.rename(i,_k),t.setSelection(i,"in"),e.model.schema.removeDisallowedAttributes([i],t),t.remove(r);})),s.scrollToTheSelection(),!0}(e,i.isSoft)||function(e,t){const i=e.model,n=i.document,s=e.editing.view,o=n.selection.getLastPosition(),r=o.nodeBefore;let a;if(t||!n.selection.isCollapsed||!o.isAtEnd||!r||!r.previousSibling)return !1;if(kk(r)&&kk(r.previousSibling))a=i.createRange(i.createPositionBefore(r.previousSibling),i.createPositionAfter(r));else if(yk(r)&&kk(r.previousSibling)&&kk(r.previousSibling.previousSibling))a=i.createRange(i.createPositionBefore(r.previousSibling.previousSibling),i.createPositionAfter(r));else {if(!(yk(r)&&kk(r.previousSibling)&&yk(r.previousSibling.previousSibling)&&r.previousSibling.previousSibling&&kk(r.previousSibling.previousSibling.previousSibling)))return !1;a=i.createRange(i.createPositionBefore(r.previousSibling.previousSibling.previousSibling),i.createPositionAfter(r));}return e.model.change((t=>{t.remove(a),e.execute("enter");const i=n.selection.anchor.parent;t.rename(i,_k),e.model.schema.removeDisallowedAttributes([i],t);})),s.scrollToTheSelection(),!0}(e,i.isSoft)||function(e){const t=e.model,i=t.document;let n;const s=mk(i.selection.getLastPosition(),t);s&&s.is("$text")&&(n=lk(s));e.model.change((t=>{e.execute("shiftEnter"),n&&t.insertText(n,i.selection.anchor);}));}(e),i.preventDefault(),t.stop());}),{context:"pre"}),this._initAriaAnnouncements();}_initAriaAnnouncements(){const{model:e,ui:t,t:i}=this.editor,n=rk(this.editor);let s=null;e.document.selection.on("change:range",(()=>{const o=e.document.selection.focus.parent;t&&s!==o&&o.is("element")&&(s&&s.is("element","codeBlock")&&t.ariaLiveAnnouncer.announce(hk(i,n,s,"leave")),o.is("element","codeBlock")&&t.ariaLiveAnnouncer.announce(hk(i,n,o,"enter")),s=o);}));}}function yk(e){return e&&e.is("$text")&&!e.data.match(/\S/)}function kk(e){return e&&e.is("element","softBreak")}class Ck extends Dr{static get pluginName(){return "CodeBlockUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.t,i=e.ui.componentFactory,n=rk(e),s=this._getLanguageListItemDefinitions(n),o=e.commands.get("codeBlock");i.add("codeBlock",(i=>{const n=Xf(i,Yf),r=n.buttonView,a=t("Insert code block");return r.set({label:a,tooltip:!0,icon:vm.codeBlock,isToggleable:!0}),r.bind("isOn").to(o,"value",(e=>!!e)),r.on("execute",(()=>{e.execute("codeBlock",{usePreviousLanguageChoice:!0}),e.editing.view.focus();})),n.on("execute",(t=>{e.execute("codeBlock",{language:t.source._codeBlockLanguage,forceValue:!0}),e.editing.view.focus();})),n.class="ck-code-block-dropdown",n.bind("isEnabled").to(o),sp(n,s,{role:"menu",ariaLabel:a}),n})),i.add("menuBar:codeBlock",(i=>{const n=new aw(i);n.buttonView.set({role:"menuitem",label:t("Code block"),icon:vm.codeBlock}),n.bind("isEnabled").to(o);const r=new lw(i);r.set({ariaLabel:t("Insert code block")});for(const t of s){const s=new ub(i,n),a=new Rg(i);a.bind(...Object.keys(t.model)).to(t.model),a.set({isToggleable:!0,role:"menuitemcheckbox"}),a.delegate("execute").to(n),a.on("execute",(()=>{e.execute("codeBlock",{language:t.model._codeBlockLanguage,forceValue:o.value!=t.model._codeBlockLanguage}),e.editing.view.focus();})),s.children.add(a),r.items.add(s);}return n.panelView.children.add(r),n}));}_getLanguageListItemDefinitions(e){const t=this.editor.commands.get("codeBlock"),i=new br;for(const n of e){const e={type:"button",model:new Fb({_codeBlockLanguage:n.language,label:n.label,role:"menuitemradio",withText:!0})};e.model.bind("isOn").to(t,"value",(t=>t===e.model._codeBlockLanguage)),i.add(e);}return i}}class xk extends Dr{static get requires(){return [vk,Ck]}static get pluginName(){return "CodeBlock"}static get isOfficialPlugin(){return !0}}class Ak extends Dr{_uploadGateway;static get pluginName(){return "CloudServicesUploadAdapter"}static get isOfficialPlugin(){return !0}static get requires(){return ["CloudServices",km]}init(){const e=this.editor,t=e.plugins.get("CloudServices"),i=t.token,n=t.uploadUrl;if(!i)return;const s=e.plugins.get("CloudServicesCore");this._uploadGateway=s.createUploadGateway(i,n),e.plugins.get(km).createUploadAdapter=e=>new Ek(this._uploadGateway,e);}}class Ek{uploadGateway;loader;fileUploader;constructor(e,t){this.uploadGateway=e,this.loader=t;}upload(){return this.loader.file.then((e=>(this.fileUploader=this.uploadGateway.upload(e),this.fileUploader.on("progress",((e,t)=>{this.loader.uploadTotal=t.total,this.loader.uploaded=t.uploaded;})),this.fileUploader.send())))}abort(){this.fileUploader.abort();}}class Tk extends Dr{static get pluginName(){return "EasyImage"}static get isOfficialPlugin(){return !0}static get requires(){return [Ak,"ImageUpload"]}init(){const e=this.editor;e.plugins.has("ImageBlockEditing")||e.plugins.has("ImageInlineEditing")||E("easy-image-image-feature-missing",e);}}class Pk extends Pb{view;constructor(e,t){super(e),this.view=t;}get element(){return this.view.editable.element}init(){const e=this.editor,t=this.view,i=e.editing.view,n=t.editable,s=i.document.getRoot();n.name=s.rootName,t.render();const o=n.element;this.setEditableElement(n.name,o),n.bind("isFocused").to(this.focusTracker),i.attachDomRoot(o),this._initPlaceholder(),this._initMenuBar(this.view.menuBarView),this.fire("ready");}destroy(){super.destroy();const e=this.view,t=this.editor.editing.view;t.getDomRoot(e.editable.name)&&t.detachDomRoot(e.editable.name),e.destroy();}_initPlaceholder(){const e=this.editor,t=e.editing.view,i=t.document.getRoot(),n=e.config.get("placeholder");if(n){const e="string"==typeof n?n:n[i.rootName];e&&(i.placeholder=e);}Zr({view:t,element:i,isDirectHost:!1,keepOnFocus:!0});}}class Sk extends Ib{editable;menuBarView;constructor(e,t,i,n){super(e),this.editable=new Ob(e,t,i,{label:n}),this.menuBarView=new hw(e),this.menuBarView.extendTemplate({attributes:{class:["ck-reset_all","ck-rounded-corners"],dir:e.uiLanguageDirection}});}render(){super.render(),this.registerChild(this.editable),this.registerChild(this.menuBarView);}}class Ik extends(bm(gm)){ui;constructor(e,t={}){if(!Vk(e)&&void 0!==t.initialData)throw new A("editor-create-initial-data",null);super(t),void 0===this.config.get("initialData")&&this.config.set("initialData",function(e){return Vk(e)?_o(e):e}(e)),Vk(e)&&(this.sourceElement=e,wm(this,e));const i=this.config.get("plugins");i.push(ew),this.config.set("plugins",i),this.config.define("balloonToolbar",this.config.get("toolbar")),this.model.document.createRoot();const n=new Sk(this.locale,this.editing.view,this.sourceElement,this.config.get("label"));this.ui=new Pk(this,n),fm(this);}destroy(){const e=this.getData();return this.ui.destroy(),super.destroy().then((()=>{this.sourceElement&&this.updateSourceElement(e);}))}static create(e,t={}){return new Promise((i=>{if(Vk(e)&&"TEXTAREA"===e.tagName)throw new A("editor-wrong-element",null);const n=new this(e,t);i(n.initPlugins().then((()=>n.ui.init())).then((()=>n.data.init(n.config.get("initialData")))).then((()=>n.fire("ready"))).then((()=>n)));}))}}function Vk(e){return Ms(e)}class Rk extends Pb{view;_toolbarConfig;_elementReplacer;constructor(e,t){super(e),this.view=t,this._toolbarConfig=qf(e.config.get("toolbar")),this._elementReplacer=new to,this.listenTo(e.editing.view,"scrollToTheSelection",this._handleScrollToTheSelectionWithStickyPanel.bind(this));}get element(){return this.view.element}init(e){const t=this.editor,i=this.view,n=t.editing.view,s=i.editable,o=n.document.getRoot();s.name=o.rootName,i.render();const r=s.element;this.setEditableElement(s.name,r),i.editable.bind("isFocused").to(this.focusTracker),n.attachDomRoot(r),e&&this._elementReplacer.replace(e,this.element),this._initPlaceholder(),this._initToolbar(),i.menuBarView&&this._initMenuBar(i.menuBarView),this._initDialogPluginIntegration(),this._initContextualBalloonIntegration(),this.fire("ready");}destroy(){super.destroy();const e=this.view,t=this.editor.editing.view;this._elementReplacer.restore(),t.getDomRoot(e.editable.name)&&t.detachDomRoot(e.editable.name),e.destroy();}_initToolbar(){const e=this.view;e.stickyPanel.bind("isActive").to(this.focusTracker,"isFocused"),e.stickyPanel.limiterElement=e.element,e.stickyPanel.bind("viewportTopOffset").to(this,"viewportOffset",(({top:e})=>e||0)),e.toolbar.fillFromConfig(this._toolbarConfig,this.componentFactory),this.addToolbar(e.toolbar);}_initPlaceholder(){const e=this.editor,t=e.editing.view,i=t.document.getRoot(),n=e.sourceElement;let s;const o=e.config.get("placeholder");o&&(s="string"==typeof o?o:o[this.view.editable.name]),!s&&n&&"textarea"===n.tagName.toLowerCase()&&(s=n.getAttribute("placeholder")),s&&(i.placeholder=s),Zr({view:t,element:i,isDirectHost:!1,keepOnFocus:!0});}_initContextualBalloonIntegration(){if(!this.editor.plugins.has("ContextualBalloon"))return;const{stickyPanel:e}=this.view,t=this.editor.plugins.get("ContextualBalloon");t.on("getPositionOptions",(t=>{const i=t.return;if(!i||!e.isSticky||!e.element)return;const n=new Eo(e.element).height,s="function"==typeof i.target?i.target():i.target,o="function"==typeof i.limiter?i.limiter():i.limiter;if(s&&o&&new Eo(s).height>=new Eo(o).height-n)return;const r={...i.viewportOffsetConfig},a=(r.top||0)+n;t.return={...i,viewportOffsetConfig:{...r,top:a}};}),{priority:"low"});const i=()=>{t.visibleView&&t.updatePosition();};this.listenTo(e,"change:isSticky",i),this.listenTo(this.editor.ui,"change:viewportOffset",i);}_handleScrollToTheSelectionWithStickyPanel(e,t,i){const n=this.view.stickyPanel;if(n.isSticky){const e=new Eo(n.element).height;t.viewportOffset.top+=e;}else {const e=()=>{this.editor.editing.view.scrollToTheSelection(i);};this.listenTo(n,"change:isSticky",e),setTimeout((()=>{this.stopListening(n,"change:isSticky",e);}),20);}}_initDialogPluginIntegration(){if(!this.editor.plugins.has("Dialog"))return;const e=this.view.stickyPanel,t=this.editor.plugins.get("Dialog");t.on("show",(()=>{const i=t.view;i.on("moveTo",((t,n)=>{if(!e.isSticky||i.wasMoved)return;const s=new Eo(e.contentPanelElement);n[1]{const n=new this(e,t);i(n.initPlugins().then((()=>n.ui.init(Mk(e)?e:null))).then((()=>n.data.init(n.config.get("initialData")))).then((()=>n.fire("ready"))).then((()=>n)));}))}}function Mk(e){return Ms(e)}class Lk extends Pb{view;constructor(e,t){super(e),this.view=t;}init(){const e=this.editor,t=this.view,i=e.editing.view,n=t.editable,s=i.document.getRoot();n.name=s.rootName,t.render();const o=n.element;this.setEditableElement(n.name,o),t.editable.bind("isFocused").to(this.focusTracker),i.attachDomRoot(o),this._initPlaceholder(),this._initToolbar(),this._initMenuBar(this.view.menuBarView),this.fire("ready");}destroy(){super.destroy();const e=this.view,t=this.editor.editing.view;t.getDomRoot(e.editable.name)&&t.detachDomRoot(e.editable.name),e.destroy();}_initToolbar(){const e=this.editor,t=this.view;t.toolbar.fillFromConfig(e.config.get("toolbar"),this.componentFactory),this.addToolbar(t.toolbar);}_initPlaceholder(){const e=this.editor,t=e.editing.view,i=t.document.getRoot(),n=e.config.get("placeholder");if(n){const e="string"==typeof n?n:n[i.rootName];e&&(i.placeholder=e);}Zr({view:t,element:i,isDirectHost:!1,keepOnFocus:!0});}}class Fk extends Ib{toolbar;editable;menuBarView;constructor(e,t,i={}){super(e),this.toolbar=new Kf(e,{shouldGroupWhenFull:i.shouldToolbarGroupWhenFull}),this.menuBarView=new hw(e),this.editable=new Ob(e,t,i.editableElement,{label:i.label}),this.toolbar.extendTemplate({attributes:{class:["ck-reset_all","ck-rounded-corners"],dir:e.uiLanguageDirection}}),this.menuBarView.extendTemplate({attributes:{class:["ck-reset_all","ck-rounded-corners"],dir:e.uiLanguageDirection}});}render(){super.render(),this.registerChild([this.menuBarView,this.toolbar,this.editable]);}}class Nk extends(bm(gm)){ui;constructor(e,t={}){if(!Dk(e)&&void 0!==t.initialData)throw new A("editor-create-initial-data",null);super(t),void 0===this.config.get("initialData")&&this.config.set("initialData",function(e){return Dk(e)?_o(e):e}(e)),Dk(e)&&(this.sourceElement=e,wm(this,e)),this.model.document.createRoot();const i=!this.config.get("toolbar.shouldNotGroupWhenFull"),n=new Fk(this.locale,this.editing.view,{editableElement:this.sourceElement,shouldToolbarGroupWhenFull:i,label:this.config.get("label")});this.ui=new Lk(this,n);}destroy(){const e=this.getData();return this.ui.destroy(),super.destroy().then((()=>{this.sourceElement&&this.updateSourceElement(e);}))}static create(e,t={}){return new Promise((i=>{if(Dk(e)&&"TEXTAREA"===e.tagName)throw new A("editor-wrong-element",null);const n=new this(e,t);i(n.initPlugins().then((()=>n.ui.init())).then((()=>n.data.init(n.config.get("initialData")))).then((()=>n.fire("ready"))).then((()=>n)));}))}}function Dk(e){return Ms(e)}class zk extends Pb{view;_toolbarConfig;constructor(e,t){super(e),this.view=t,this._toolbarConfig=qf(e.config.get("toolbar"));}get element(){return this.view.editable.element}init(){const e=this.editor,t=this.view,i=e.editing.view,n=t.editable,s=i.document.getRoot();n.name=s.rootName,t.render();const o=n.element;this.setEditableElement(n.name,o),n.bind("isFocused").to(this.focusTracker),i.attachDomRoot(o),this._initPlaceholder(),this._initToolbar(),t.menuBarView&&this._initMenuBar(t.menuBarView),this.fire("ready");}destroy(){super.destroy();const e=this.view;this.editor.editing.view.detachDomRoot(e.editable.name),e.destroy();}_initToolbar(){const e=this.editor,t=this.view,i=t.editable.element,n=t.toolbar;t.panel.bind("isVisible").to(this.focusTracker,"isFocused"),t.bind("viewportTopOffset").to(this,"viewportOffset",(({top:e})=>e||0)),t.listenTo(e.ui,"update",(()=>{t.panel.isVisible&&t.panel.pin({target:i,positions:t.panelPositions});})),n.fillFromConfig(this._toolbarConfig,this.componentFactory),this.addToolbar(n);}_initPlaceholder(){const e=this.editor,t=e.editing.view,i=t.document.getRoot(),n=e.config.get("placeholder");if(n){const e="string"==typeof n?n:n[i.rootName];e&&(i.placeholder=e);}Zr({view:t,element:i,isDirectHost:!1,keepOnFocus:!0});}}const Hk=Oo("px");class $k extends Ib{toolbar;panel;panelPositions;editable;_resizeObserver;constructor(e,t,i,n={}){super(e),this.toolbar=new Kf(e,{shouldGroupWhenFull:n.shouldToolbarGroupWhenFull,isFloating:!0}),n.useMenuBar&&(this.menuBarView=new hw(e)),this.set("viewportTopOffset",0),this.panel=new Df(e),this.panelPositions=this._getPanelPositions(),this.panel.extendTemplate({attributes:{class:"ck-toolbar-container"}}),this.editable=new Ob(e,t,i,{label:n.label}),this._resizeObserver=null;}render(){super.render(),this.body.add(this.panel),this.registerChild(this.editable),this.menuBarView?this.panel.content.addMany([this.menuBarView,this.toolbar]):this.panel.content.add(this.toolbar);if(this.toolbar.options.shouldGroupWhenFull){const e=this.editable.element;this._resizeObserver=new Vo(e,(()=>{this.toolbar.maxWidth=Hk(new Eo(e).width);}));}}destroy(){super.destroy(),this._resizeObserver&&this._resizeObserver.destroy();}_getPanelPositionTop(e,t){let i;return i=e.top>t.height+this.viewportTopOffset?e.top-t.height:e.bottom>t.height+this.viewportTopOffset+50?this.viewportTopOffset:e.bottom,i}_getPanelPositions(){const e=[(e,t)=>({top:this._getPanelPositionTop(e,t),left:e.left,name:"toolbar_west",config:{withArrow:!1}}),(e,t)=>({top:this._getPanelPositionTop(e,t),left:e.left+e.width-t.width,name:"toolbar_east",config:{withArrow:!1}})];return "ltr"===this.locale.uiLanguageDirection?e:e.reverse()}}class Uk extends(bm(gm)){ui;constructor(e,t={}){if(!Wk(e)&&void 0!==t.initialData)throw new A("editor-create-initial-data",null);super(t),this.config.define("menuBar.isVisible",!1),void 0===this.config.get("initialData")&&this.config.set("initialData",function(e){return Wk(e)?_o(e):e}(e)),this.model.document.createRoot(),Wk(e)&&(this.sourceElement=e,wm(this,e));const i=!this.config.get("toolbar.shouldNotGroupWhenFull"),n=this.config.get("menuBar"),s=new $k(this.locale,this.editing.view,this.sourceElement,{shouldToolbarGroupWhenFull:i,useMenuBar:n.isVisible,label:this.config.get("label")});this.ui=new zk(this,s),fm(this);}destroy(){const e=this.getData();return this.ui.destroy(),super.destroy().then((()=>{this.sourceElement&&this.updateSourceElement(e);}))}static create(e,t={}){return new Promise((i=>{if(Wk(e)&&"TEXTAREA"===e.tagName)throw new A("editor-wrong-element",null);const n=new this(e,t);i(n.initPlugins().then((()=>n.ui.init())).then((()=>n.data.init(n.config.get("initialData")))).then((()=>n.fire("ready"))).then((()=>n)));}))}}function Wk(e){return Ms(e)}class jk extends Pb{view;_lastFocusedEditableElement;constructor(e,t){super(e),this.view=t,this._lastFocusedEditableElement=null;}init(){this.view.render(),this.focusTracker.on("change:focusedElement",((e,t,i)=>{for(const e of Object.values(this.view.editables))i===e.element&&(this._lastFocusedEditableElement=e.element);})),this.focusTracker.on("change:isFocused",((e,t,i)=>{i||(this._lastFocusedEditableElement=null);}));for(const e of Object.values(this.view.editables))this.addEditable(e);this._initToolbar(),this._initMenuBar(this.view.menuBarView),this.fire("ready");}addEditable(e,t){const i=e.element;this.editor.editing.view.attachDomRoot(i,e.name),this.setEditableElement(e.name,i),e.bind("isFocused").to(this.focusTracker,"isFocused",this.focusTracker,"focusedElement",((e,t)=>!!e&&(t===i||this._lastFocusedEditableElement===i))),this._initPlaceholder(e,t);}removeEditable(e){this.editor.editing.view.detachDomRoot(e.name),e.unbind("isFocused"),this.removeEditableElement(e.name);}destroy(){super.destroy();for(const e of Object.values(this.view.editables))this.removeEditable(e);this.view.destroy();}_initToolbar(){const e=this.editor,t=this.view;t.toolbar.fillFromConfig(e.config.get("toolbar"),this.componentFactory),this.addToolbar(t.toolbar);}_initPlaceholder(e,t){if(!t){const i=this.editor.config.get("placeholder");i&&(t="string"==typeof i?i:i[e.name]);}const i=this.editor.editing.view,n=i.document.getRoot(e.name);t&&(n.placeholder=t),Zr({view:i,element:n,isDirectHost:!1,keepOnFocus:!0});}}class qk extends Ib{toolbar;editables;editable;menuBarView;_editingView;constructor(e,t,i,n={}){super(e),this._editingView=t,this.toolbar=new Kf(e,{shouldGroupWhenFull:n.shouldToolbarGroupWhenFull}),this.menuBarView=new hw(e),this.editables={};for(const e of i){const t=n.editableElements?n.editableElements[e]:void 0;let{label:i}=n;"object"==typeof i&&(i=i[e]),this.createEditable(e,t,i);}this.editable=Object.values(this.editables)[0],this.toolbar.extendTemplate({attributes:{class:["ck-reset_all","ck-rounded-corners"],dir:e.uiLanguageDirection}}),this.menuBarView.extendTemplate({attributes:{class:["ck-reset_all","ck-rounded-corners"],dir:e.uiLanguageDirection}});}createEditable(e,t,i){const n=new Ob(this.locale,this._editingView,t,{label:i});return this.editables[e]=n,n.name=e,this.isRendered&&this.registerChild(n),n}removeEditable(e){const t=this.editables[e];this.isRendered&&this.deregisterChild(t),delete this.editables[e],t.destroy();}render(){super.render(),this.registerChild(Object.values(this.editables)),this.registerChild(this.toolbar),this.registerChild(this.menuBarView);}}class Gk extends gm{ui;sourceElements;_registeredRootsAttributesKeys=new Set;_readOnlyRootLocks=new Map;constructor(e,t={}){const i=Object.keys(e),n=0===i.length||"string"==typeof e[i[0]];if(n&&void 0!==t.initialData&&Object.keys(t.initialData).length>0)throw new A("editor-create-initial-data",null);if(super(t),this.sourceElements=n?{}:e,void 0===this.config.get("initialData")){const t={};for(const n of i)t[n]=Kk(s=e[n])?_o(s):s;this.config.set("initialData",t);}var s;if(!n)for(const t of i)wm(this,e[t]);this.editing.view.document.roots.on("add",((e,t)=>{t.unbind("isReadOnly"),t.bind("isReadOnly").to(this.editing.view.document,"isReadOnly",(e=>e||this._readOnlyRootLocks.has(t.rootName))),t.on("change:isReadOnly",((e,i,n)=>{const s=this.editing.view.createRangeIn(t);for(const e of s.getItems())e.is("editableElement")&&(e.unbind("isReadOnly"),e.isReadOnly=n);}));}));for(const e of i)this.model.document.createRoot("$root",e);if(this.config.get("lazyRoots"))for(const e of this.config.get("lazyRoots")){this.model.document.createRoot("$root",e)._isLoaded=!1;}if(this.config.get("rootsAttributes")){const e=this.config.get("rootsAttributes");for(const[t,i]of Object.entries(e)){if(!this.model.document.getRoot(t))throw new A("multi-root-editor-root-attributes-no-root",null);for(const e of Object.keys(i))this.registerRootAttribute(e);}this.data.on("init",(()=>{this.model.enqueueChange({isUndoable:!1},(t=>{for(const[i,n]of Object.entries(e)){const e=this.model.document.getRoot(i);for(const[i,s]of Object.entries(n))null!==s&&t.setAttribute(i,s,e);}}));}));}const o={shouldToolbarGroupWhenFull:!this.config.get("toolbar.shouldNotGroupWhenFull"),editableElements:n?void 0:e,label:this.config.get("label")},r=new qk(this.locale,this.editing.view,i,o);this.ui=new jk(this,r),this.model.document.on("change:data",(()=>{const e=this.model.document.differ.getChangedRoots();for(const t of e){const e=this.model.document.getRoot(t.name);"detached"==t.state&&this.fire("detachRoot",e);}for(const t of e){const e=this.model.document.getRoot(t.name);"attached"==t.state&&this.fire("addRoot",e);}})),this.listenTo(this.model,"canEditAt",((e,[t])=>{if(!t)return;let i=!1;for(const e of t.getRanges()){const t=e.root;if(this._readOnlyRootLocks.has(t.rootName)){i=!0;break}}i&&(e.return=!1,e.stop());}),{priority:"high"}),this.decorate("loadRoot"),this.on("loadRoot",((e,[t])=>{const i=this.model.document.getRoot(t);if(!i)throw new A("multi-root-editor-load-root-no-root",this,{rootName:t});i._isLoaded&&(E("multi-root-editor-load-root-already-loaded"),e.stop());}),{priority:"highest"});}destroy(){const e=this.config.get("updateSourceElementOnDestroy"),t={};for(const i of Object.keys(this.sourceElements))t[i]=e?this.getData({rootName:i}):"";return this.ui.destroy(),super.destroy().then((()=>{for(const e of Object.keys(this.sourceElements))Ro(this.sourceElements[e],t[e]);}))}addRoot(e,{data:t="",attributes:i={},elementName:n="$root",isUndoable:s=!1}={}){const o=s=>{const o=s.addRoot(e,n);t&&s.insert(this.data.parse(t,o),o,0);for(const e of Object.keys(i))this.registerRootAttribute(e),s.setAttribute(e,i[e],o);};s?this.model.change(o):this.model.enqueueChange({isUndoable:!1},o);}detachRoot(e,t=!1){t?this.model.change((t=>t.detachRoot(e))):this.model.enqueueChange({isUndoable:!1},(t=>t.detachRoot(e)));}createEditable(e,t,i){const n=this.ui.view.createEditable(e.rootName,void 0,i);return this.ui.addEditable(n,t),this.editing.view.forceRender(),n.element}detachEditable(e){const t=e.rootName,i=this.ui.view.editables[t];return this.ui.removeEditable(i),this.ui.view.removeEditable(t),i.element}loadRoot(e,{data:t="",attributes:i={}}={}){const n=this.model.document.getRoot(e);this.model.enqueueChange({isUndoable:!1},(e=>{t&&e.insert(this.data.parse(t,n),n,0);for(const t of Object.keys(i))this.registerRootAttribute(t),e.setAttribute(t,i[t],n);n._isLoaded=!0,this.model.document.differ._bufferRootLoad(n);}));}getFullData(e){const t={};for(const i of this.model.document.getRootNames())t[i]=this.data.get({...e,rootName:i});return t}getRootsAttributes(){const e={};for(const t of this.model.document.getRootNames())e[t]=this.getRootAttributes(t);return e}getRootAttributes(e){const t={},i=this.model.document.getRoot(e);for(const e of this._registeredRootsAttributesKeys)t[e]=i.hasAttribute(e)?i.getAttribute(e):null;return t}registerRootAttribute(e){this._registeredRootsAttributesKeys.has(e)||(this._registeredRootsAttributesKeys.add(e),this.editing.model.schema.extend("$root",{allowAttributes:e}));}disableRoot(e,t){if("$graveyard"==e)throw new A("multi-root-editor-cannot-disable-graveyard-root",this);const i=this._readOnlyRootLocks.get(e);if(i)i.add(t);else {this._readOnlyRootLocks.set(e,new Set([t]));this.editing.view.document.getRoot(e).isReadOnly=!0,Array.from(this.commands.commands()).forEach((e=>e.affectsData&&e.refresh()));}}enableRoot(e,t){const i=this._readOnlyRootLocks.get(e);if(i&&i.has(t))if(1===i.size){this._readOnlyRootLocks.delete(e);this.editing.view.document.getRoot(e).isReadOnly=this.isReadOnly,Array.from(this.commands.commands()).forEach((e=>e.affectsData&&e.refresh()));}else i.delete(t);}static create(e,t={}){return new Promise((i=>{for(const t of Object.values(e))if(Kk(t)&&"TEXTAREA"===t.tagName)throw new A("editor-wrong-element",null);const n=new this(e,t);i(n.initPlugins().then((()=>n.ui.init())).then((()=>(n._verifyRootsWithInitialData(),n.data.init(n.config.get("initialData"))))).then((()=>n.fire("ready"))).then((()=>n)));}))}_verifyRootsWithInitialData(){const e=this.config.get("initialData");for(const t of this.model.document.getRootNames())if(!(t in e))throw new A("multi-root-editor-root-initial-data-mismatch",null);for(const t of Object.keys(e)){const e=this.model.document.getRoot(t);if(!e||!e.isAttached())throw new A("multi-root-editor-root-initial-data-mismatch",null)}}}function Kk(e){return Ms(e)}class Zk extends Hr{constructor(e){super(e),this.affectsData=!1;}execute(){const e=this.editor.model,t=e.document.selection;let i=e.schema.getLimitElement(t);if(t.containsEntireContent(i)||!Jk(e.schema,i))do{if(i=i.parent,!i)return}while(!Jk(e.schema,i));e.change((e=>{e.setSelection(i,"in");}));}}function Jk(e,t){return e.isLimit(t)&&(e.checkChild(t,"$text")||e.checkChild(t,"paragraph"))}const Qk=rr("Ctrl+A");class Yk extends Dr{static get pluginName(){return "SelectAllEditing"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.t,i=e.editing.view.document;e.commands.add("selectAll",new Zk(e)),this.listenTo(i,"keydown",((t,i)=>{or(i)===Qk&&(e.execute("selectAll"),i.preventDefault());})),e.accessibility.addKeystrokeInfos({keystrokes:[{label:t("Select all"),keystroke:"CTRL+A"}]});}}class Xk extends Dr{static get pluginName(){return "SelectAllUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;e.ui.componentFactory.add("selectAll",(()=>{const e=this._createButton(pg);return e.set({tooltip:!0}),e})),e.ui.componentFactory.add("menuBar:selectAll",(()=>this._createButton(Rg)));}_createButton(e){const t=this.editor,i=t.locale,n=t.commands.get("selectAll"),s=new e(t.locale),o=i.t;return s.set({label:o("Select all"),icon:'',keystroke:"Ctrl+A"}),s.bind("isEnabled").to(n,"isEnabled"),this.listenTo(s,"execute",(()=>{t.execute("selectAll"),t.editing.view.focus();})),s}}class eC extends Dr{static get requires(){return [Yk,Xk]}static get pluginName(){return "SelectAll"}static get isOfficialPlugin(){return !0}}class tC extends Hr{_stack=[];_createdBatches=new WeakSet;constructor(e){super(e),this.refresh(),this._isEnabledBasedOnSelection=!1,this.listenTo(e.data,"set",((e,t)=>{t[1]={...t[1]};const i=t[1];i.batchType||(i.batchType={isUndoable:!1});}),{priority:"high"}),this.listenTo(e.data,"set",((e,t)=>{t[1].batchType.isUndoable||this.clearStack();}));}refresh(){this.isEnabled=this._stack.length>0;}get createdBatches(){return this._createdBatches}addBatch(e){const t=this.editor.model.document.selection,i={ranges:t.hasOwnRange?Array.from(t.getRanges()):[],isBackward:t.isBackward};this._stack.push({batch:e,selection:i}),this.refresh();}clearStack(){this._stack=[],this.refresh();}_restoreSelection(e,t,i){const n=this.editor.model,s=n.document,o=[],r=e.map((e=>e.getTransformedByOperations(i))),a=r.flat();for(const e of r){const t=e.filter((e=>e.root!=s.graveyard)).filter((e=>!nC(e,a)));t.length&&(iC(t),o.push(t[0]));}o.length&&n.change((e=>{e.setSelection(o,{backward:t});}));}_undo(e,t){const i=this.editor.model,n=i.document;this._createdBatches.add(t);const s=e.operations.slice().filter((e=>e.isDocumentOperation));s.reverse();for(const e of s){const s=e.baseVersion+1,o=Array.from(n.history.getOperations(s)),r=Jd([e.getReversed()],o,{useRelations:!0,document:this.editor.model.document,padWithNoOps:!1,forceWeakRemove:!0}).operationsA;for(let s of r){const o=s.affectedSelectable;o&&!i.canEditAt(o)&&(s=new zd(s.baseVersion)),t.addOperation(s),i.applyOperation(s),n.history.setOperationAsUndone(e,s);}}}}function iC(e){e.sort(((e,t)=>e.start.isBefore(t.start)?-1:1));for(let t=1;tt!==e&&t.containsRange(e,!0)))}class sC extends tC{execute(e=null){const t=e?this._stack.findIndex((t=>t.batch==e)):this._stack.length-1,i=this._stack.splice(t,1)[0],n=this.editor.model.createBatch({isUndo:!0});this.editor.model.enqueueChange(n,(()=>{this._undo(i.batch,n);const e=this.editor.model.document.history.getOperations(i.batch.baseVersion);this._restoreSelection(i.selection.ranges,i.selection.isBackward,e);})),this.fire("revert",i.batch,n),this.refresh();}}class oC extends tC{execute(){const e=this._stack.pop(),t=this.editor.model.createBatch({isUndo:!0});this.editor.model.enqueueChange(t,(()=>{const i=e.batch.operations[e.batch.operations.length-1].baseVersion+1,n=this.editor.model.document.history.getOperations(i);this._restoreSelection(e.selection.ranges,e.selection.isBackward,n),this._undo(e.batch,t);})),this.refresh();}}class rC extends Dr{_undoCommand;_redoCommand;_batchRegistry=new WeakSet;static get pluginName(){return "UndoEditing"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.t;this._undoCommand=new sC(e),this._redoCommand=new oC(e),e.commands.add("undo",this._undoCommand),e.commands.add("redo",this._redoCommand),this.listenTo(e.model,"applyOperation",((e,t)=>{const i=t[0];if(!i.isDocumentOperation)return;const n=i.batch,s=this._redoCommand.createdBatches.has(n),o=this._undoCommand.createdBatches.has(n);this._batchRegistry.has(n)||(this._batchRegistry.add(n),n.isUndoable&&(s?this._undoCommand.addBatch(n):o||(this._undoCommand.addBatch(n),this._redoCommand.clearStack())));}),{priority:"highest"}),this.listenTo(this._undoCommand,"revert",((e,t,i)=>{this._redoCommand.addBatch(i);})),e.keystrokes.set("CTRL+Z","undo"),e.keystrokes.set("CTRL+Y","redo"),e.keystrokes.set("CTRL+SHIFT+Z","redo"),e.accessibility.addKeystrokeInfos({keystrokes:[{label:t("Undo"),keystroke:"CTRL+Z"},{label:t("Redo"),keystroke:[["CTRL+Y"],["CTRL+SHIFT+Z"]]}]});}}class aC extends Dr{static get pluginName(){return "UndoUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.locale,i=e.t,n="ltr"==t.uiLanguageDirection?vm.undo:vm.redo,s="ltr"==t.uiLanguageDirection?vm.redo:vm.undo;this._addButtonsToFactory("undo",i("Undo"),"CTRL+Z",n),this._addButtonsToFactory("redo",i("Redo"),"CTRL+Y",s);}_addButtonsToFactory(e,t,i,n){const s=this.editor;s.ui.componentFactory.add(e,(()=>{const s=this._createButton(pg,e,t,i,n);return s.set({tooltip:!0}),s})),s.ui.componentFactory.add("menuBar:"+e,(()=>this._createButton(Rg,e,t,i,n)));}_createButton(e,t,i,n,s){const o=this.editor,r=o.locale,a=o.commands.get(t),l=new e(r);return l.set({label:i,icon:s,keystroke:n}),l.bind("isEnabled").to(a,"isEnabled"),this.listenTo(l,"execute",(()=>{o.execute(t),o.editing.view.focus();})),l}}class lC extends Dr{static get requires(){return [rC,aC]}static get pluginName(){return "Undo"}static get isOfficialPlugin(){return !0}}class cC extends Dr{static get requires(){return [Fg,Qy,K_,eC,Y_,Ow,lC]}static get pluginName(){return "Essentials"}static get isOfficialPlugin(){return !0}}class dC extends lg{children;_findInputView;_replaceInputView;_findButtonView;_findPrevButtonView;_findNextButtonView;_advancedOptionsCollapsibleView;_matchCaseSwitchView;_wholeWordsOnlySwitchView;_replaceButtonView;_replaceAllButtonView;_inputsDivView;_actionButtonsDivView;_focusTracker;_keystrokes;_focusables;focusCycler;constructor(e){super(e);const t=e.t;this.children=this.createCollection(),this.set("matchCount",0),this.set("highlightOffset",0),this.set("isDirty",!1),this.set("_areCommandsEnabled",{}),this.set("_resultsCounterText",""),this.set("_matchCase",!1),this.set("_wholeWordsOnly",!1),this.bind("_searchResultsFound").to(this,"matchCount",this,"isDirty",((e,t)=>e>0&&!t)),this._findInputView=this._createInputField(t("Find in text…")),this._findPrevButtonView=this._createButton({label:t("Previous result"),class:"ck-button-prev",icon:vm.previousArrow,keystroke:"Shift+F3",tooltip:!0}),this._findNextButtonView=this._createButton({label:t("Next result"),class:"ck-button-next",icon:vm.previousArrow,keystroke:"F3",tooltip:!0}),this._replaceInputView=this._createInputField(t("Replace with…"),"ck-labeled-field-replace"),this._inputsDivView=this._createInputsDiv(),this._matchCaseSwitchView=this._createMatchCaseSwitch(),this._wholeWordsOnlySwitchView=this._createWholeWordsOnlySwitch(),this._advancedOptionsCollapsibleView=this._createAdvancedOptionsCollapsible(),this._replaceAllButtonView=this._createButton({label:t("Replace all"),class:"ck-button-replaceall",withText:!0}),this._replaceButtonView=this._createButton({label:t("Replace"),class:"ck-button-replace",withText:!0}),this._findButtonView=this._createButton({label:t("Find"),class:"ck-button-find ck-button-action",withText:!0}),this._actionButtonsDivView=this._createActionButtonsDiv(),this._focusTracker=new _r,this._keystrokes=new Cr,this._focusables=new zm,this.focusCycler=new _g({focusables:this._focusables,focusTracker:this._focusTracker,keystrokeHandler:this._keystrokes,actions:{focusPrevious:"shift + tab",focusNext:"tab"}}),this.children.addMany([this._inputsDivView,this._advancedOptionsCollapsibleView,this._actionButtonsDivView]),this.setTemplate({tag:"form",attributes:{class:["ck","ck-find-and-replace-form"],tabindex:"-1"},children:this.children});}render(){super.render(),hg({view:this}),this._initFocusCycling(),this._initKeystrokeHandling();}destroy(){super.destroy(),this._focusTracker.destroy(),this._keystrokes.destroy();}focus(e){-1===e?this.focusCycler.focusLast():this.focusCycler.focusFirst();}reset(){this._findInputView.errorText=null,this.isDirty=!0;}get _textToFind(){return this._findInputView.fieldView.element.value}get _textToReplace(){return this._replaceInputView.fieldView.element.value}_createInputsDiv(){const e=this.locale,t=e.t,i=new lg(e);return this._findInputView.fieldView.on("input",(()=>{this.isDirty=!0;})),this._findPrevButtonView.delegate("execute").to(this,"findPrevious"),this._findNextButtonView.delegate("execute").to(this,"findNext"),this._findPrevButtonView.bind("isEnabled").to(this,"_areCommandsEnabled",(({findPrevious:e})=>e)),this._findNextButtonView.bind("isEnabled").to(this,"_areCommandsEnabled",(({findNext:e})=>e)),this._injectFindResultsCounter(),this._replaceInputView.bind("isEnabled").to(this,"_areCommandsEnabled",this,"_searchResultsFound",(({replace:e},t)=>e&&t)),this._replaceInputView.bind("infoText").to(this._replaceInputView,"isEnabled",this._replaceInputView,"isFocused",((e,i)=>e||!i?"":t("Tip: Find some text first in order to replace it."))),i.setTemplate({tag:"div",attributes:{class:["ck","ck-find-and-replace-form__inputs"]},children:[this._findInputView,this._findPrevButtonView,this._findNextButtonView,this._replaceInputView]}),i}_onFindButtonExecute(){if(this._textToFind)this.isDirty=!1,this.fire("findNext",{searchText:this._textToFind,matchCase:this._matchCase,wholeWords:this._wholeWordsOnly});else {const e=this.t;this._findInputView.errorText=e("Text to find must not be empty.");}}_injectFindResultsCounter(){const e=this.locale,t=e.t,i=this.bindTemplate,n=new lg(this.locale);this.bind("_resultsCounterText").to(this,"highlightOffset",this,"matchCount",((e,i)=>t("%0 of %1",[e,i]))),n.setTemplate({tag:"span",attributes:{class:["ck","ck-results-counter",i.if("isDirty","ck-hidden")]},children:[{text:i.to("_resultsCounterText")}]});const s=()=>{const t=this._findInputView.fieldView.element;if(!t||!No(t))return;const i=new Eo(n.element).width,s="ltr"===e.uiLanguageDirection?"paddingRight":"paddingLeft";t.style[s]=i?`calc( 2 * var(--ck-spacing-standard) + ${i}px )`:"";};this.on("change:_resultsCounterText",s,{priority:"low"}),this.on("change:isDirty",s,{priority:"low"}),this._findInputView.template.children[0].children.push(n);}_createAdvancedOptionsCollapsible(){const e=this.locale.t,t=new jg(this.locale,[this._matchCaseSwitchView,this._wholeWordsOnlySwitchView]);return t.set({label:e("Advanced options"),isCollapsed:!0}),t}_createActionButtonsDiv(){const e=new lg(this.locale);return this._replaceButtonView.bind("isEnabled").to(this,"_areCommandsEnabled",this,"_searchResultsFound",(({replace:e},t)=>e&&t)),this._replaceAllButtonView.bind("isEnabled").to(this,"_areCommandsEnabled",this,"_searchResultsFound",(({replaceAll:e},t)=>e&&t)),this._replaceButtonView.on("execute",(()=>{this.fire("replace",{searchText:this._textToFind,replaceText:this._textToReplace});})),this._replaceAllButtonView.on("execute",(()=>{this.fire("replaceAll",{searchText:this._textToFind,replaceText:this._textToReplace}),this.focus();})),this._findButtonView.on("execute",this._onFindButtonExecute.bind(this)),e.setTemplate({tag:"div",attributes:{class:["ck","ck-find-and-replace-form__actions"]},children:[this._replaceAllButtonView,this._replaceButtonView,this._findButtonView]}),e}_createMatchCaseSwitch(){const e=this.locale.t,t=new Dg(this.locale);return t.set({label:e("Match case"),withText:!0}),t.bind("isOn").to(this,"_matchCase"),t.on("execute",(()=>{this._matchCase=!this._matchCase,this.isDirty=!0;})),t}_createWholeWordsOnlySwitch(){const e=this.locale.t,t=new Dg(this.locale);return t.set({label:e("Whole words only"),withText:!0}),t.bind("isOn").to(this,"_wholeWordsOnly"),t.on("execute",(()=>{this._wholeWordsOnly=!this._wholeWordsOnly,this.isDirty=!0;})),t}_initFocusCycling(){[this._findInputView,this._findPrevButtonView,this._findNextButtonView,this._replaceInputView,this._advancedOptionsCollapsibleView.buttonView,this._matchCaseSwitchView,this._wholeWordsOnlySwitchView,this._replaceAllButtonView,this._replaceButtonView,this._findButtonView].forEach((e=>{this._focusables.add(e),this._focusTracker.add(e.element);}));}_initKeystrokeHandling(){const e=e=>e.stopPropagation(),t=e=>{e.stopPropagation(),e.preventDefault();};this._keystrokes.listenTo(this.element),this._keystrokes.set("f3",(e=>{t(e),this._findNextButtonView.fire("execute");})),this._keystrokes.set("shift+f3",(e=>{t(e),this._findPrevButtonView.fire("execute");})),this._keystrokes.set("enter",(e=>{const i=e.target;i===this._findInputView.fieldView.element?(this._areCommandsEnabled.findNext?this._findNextButtonView.fire("execute"):this._findButtonView.fire("execute"),t(e)):i!==this._replaceInputView.fieldView.element||this.isDirty||(this._replaceButtonView.fire("execute"),t(e));})),this._keystrokes.set("shift+enter",(e=>{e.target===this._findInputView.fieldView.element&&(this._areCommandsEnabled.findPrevious?this._findPrevButtonView.fire("execute"):this._findButtonView.fire("execute"),t(e));})),this._keystrokes.set("arrowright",e),this._keystrokes.set("arrowleft",e),this._keystrokes.set("arrowup",e),this._keystrokes.set("arrowdown",e);}_createButton(e){const t=new pg(this.locale);return t.set(e),t}_createInputField(e,t){const i=new pf(this.locale,cp);return i.label=e,i.class=t,i}}var uC='';class hC extends Dr{static get requires(){return [Sg]}static get pluginName(){return "FindAndReplaceUI"}static get isOfficialPlugin(){return !0}formView;constructor(e){super(e),e.config.define("findAndReplace.uiType","dialog"),this.formView=null;}init(){const e=this.editor,t="dropdown"===e.config.get("findAndReplace.uiType"),i=e.commands.get("find"),n=this.editor.t;e.ui.componentFactory.add("findAndReplace",(()=>{let n;return t?(n=this._createDropdown(),n.bind("isEnabled").to(i)):n=this._createDialogButtonForToolbar(),e.keystrokes.set("Ctrl+F",((t,s)=>{if(i.isEnabled){if(n instanceof xf){const e=n.buttonView;e.isOn||e.fire("execute");}else n.isOn?e.plugins.get("Dialog").view.focus():n.fire("execute");s();}})),n})),t||e.ui.componentFactory.add("menuBar:findAndReplace",(()=>this._createDialogButtonForMenuBar())),e.accessibility.addKeystrokeInfos({keystrokes:[{label:n("Find in the document"),keystroke:"CTRL+F"}]});}_createDropdown(){const e=this.editor,t=e.locale.t,i=Xf(e.locale);return i.once("change:isOpen",(()=>{this.formView=this._createFormView(),this.formView.children.add(new wg(e.locale,{label:t("Find and replace")}),0),i.panelView.children.add(this.formView);})),i.on("change:isOpen",((e,t,i)=>{i?this._setupFormView():this.fire("searchReseted");}),{priority:"low"}),i.buttonView.set({icon:uC,label:t("Find and replace"),keystroke:"CTRL+F",tooltip:!0}),i}_createDialogButtonForToolbar(){const e=this.editor,t=this._createButton(pg),i=e.plugins.get("Dialog");return t.set({tooltip:!0}),t.bind("isOn").to(i,"id",(e=>"findAndReplace"===e)),t.on("execute",(()=>{t.isOn?i.hide():this._showDialog();})),t}_createDialogButtonForMenuBar(){const e=this._createButton(Rg),t=this.editor.plugins.get("Dialog"),i=this.editor.plugins.get("Dialog");return e.set({role:"menuitemcheckbox",isToggleable:!0}),e.bind("isOn").to(i,"id",(e=>"findAndReplace"===e)),e.on("execute",(()=>{"findAndReplace"!==t.id?this._showDialog():t.hide();})),e}_createButton(e){const t=this.editor,i=t.commands.get("find"),n=new e(t.locale),s=t.locale.t;return n.bind("isEnabled").to(i),n.set({icon:uC,label:s("Find and replace"),keystroke:"CTRL+F"}),n}_showDialog(){const e=this.editor,t=e.plugins.get("Dialog"),i=e.locale.t;this.formView||(this.formView=this._createFormView()),t.show({id:"findAndReplace",title:i("Find and replace"),content:this.formView,position:Eg.EDITOR_TOP_SIDE,onShow:()=>{this._setupFormView();},onHide:()=>{this.fire("searchReseted");}});}_createFormView(){const e=this.editor,t=new(ug(dC))(e.locale),i=e.commands,n=this.editor.plugins.get("FindAndReplaceEditing").state;t.bind("highlightOffset").to(n,"highlightedOffset"),t.listenTo(n.results,"change",(()=>{t.matchCount=n.results.length;}));const s=i.get("findNext"),o=i.get("findPrevious"),r=i.get("replace"),a=i.get("replaceAll");return t.bind("_areCommandsEnabled").to(s,"isEnabled",o,"isEnabled",r,"isEnabled",a,"isEnabled",((e,t,i,n)=>({findNext:e,findPrevious:t,replace:i,replaceAll:n}))),t.delegate("findNext","findPrevious","replace","replaceAll").to(this),t.on("change:isDirty",((e,t,i)=>{i&&this.fire("searchReseted");})),t}_setupFormView(){this.formView.disableCssTransitions(),this.formView.reset(),this.formView._findInputView.fieldView.select(),this.formView.enableCssTransitions();}}class mC extends Hr{_state;constructor(e,t){super(e),this.isEnabled=!0,this.affectsData=!1,this._state=t;}execute(e,{matchCase:t,wholeWords:i}={}){const{editor:n}=this,{model:s}=n,o=n.plugins.get("FindAndReplaceUtils");let r,a="";r="string"==typeof e?(...n)=>({results:o.findByTextCallback(e,{matchCase:t,wholeWords:i})(...n),searchText:e}):e;const l=r;r=(...e)=>{const t=l(...e);return t&&"searchText"in t&&(a=t.searchText),t};const c=s.document.getRootNames().reduce(((e,t)=>o.updateFindResultFromRange(s.createRangeIn(s.document.getRoot(t)),s,r,e)),null);return this._state.clear(s),this._state.results.addMany(c),this._state.highlightedResult=c.get(0),this._state.searchText=a,r&&(this._state.lastSearchCallback=r),this._state.matchCase=!!t,this._state.matchWholeWords=!!i,{results:c,findCallback:r}}}class gC extends Hr{_state;constructor(e,t){super(e),this.isEnabled=!0,this._state=t,this._isEnabledBasedOnSelection=!1;}_replace(e,t){const{model:i}=this.editor,n=t.marker.getRange();i.canEditAt(n)&&i.change((s=>{if("$graveyard"===n.root.rootName)return void this._state.results.remove(t);let o={};for(const e of n.getItems())if(e.is("$text")||e.is("$textProxy")){o=e.getAttributes();break}i.insertContent(s.createText(e,o),n),this._state.results.has(t)&&this._state.results.remove(t);}));}}class fC extends gC{execute(e,t){this._replace(e,t);}}class pC extends gC{execute(e,t){const{editor:i}=this,{model:n}=i,s=i.plugins.get("FindAndReplaceUtils"),o=t instanceof br?t:n.document.getRootNames().reduce(((e,i)=>s.updateFindResultFromRange(n.createRangeIn(n.document.getRoot(i)),n,s.findByTextCallback(t,this._state),e)),null);o.length&&n.change((()=>{[...o].forEach((t=>{this._replace(e,t);}));}));}}class bC extends Hr{_state;constructor(e,t){super(e),this.affectsData=!1,this._state=t,this.isEnabled=!1,this.listenTo(this._state.results,"change",(()=>{this.isEnabled=this._state.results.length>1;}));}refresh(){this.isEnabled=this._state.results.length>1;}execute(){const e=this._state.results,t=e.getIndex(this._state.highlightedResult),i=t+1>=e.length?0:t+1;this._state.highlightedResult=this._state.results.get(i);}}class wC extends bC{execute(){const e=this._state.results.getIndex(this._state.highlightedResult),t=e-1<0?this._state.results.length-1:e-1;this._state.highlightedResult=this._state.results.get(t);}}class _C extends(Zs()){constructor(e){super(),this.set("results",new br),this.set("highlightedResult",null),this.set("highlightedOffset",0),this.set("searchText",""),this.set("replaceText",""),this.set("lastSearchCallback",null),this.set("matchCase",!1),this.set("matchWholeWords",!1),this.results.on("change",((t,{removed:i,index:n})=>{if(Array.from(i).length){let t=!1;if(e.change((n=>{for(const s of i)this.highlightedResult===s&&(t=!0),e.markers.has(s.marker.name)&&n.removeMarker(s.marker);})),t){const e=n>=this.results.length?0:n;this.highlightedResult=this.results.get(e);}}})),this.on("change:highlightedResult",(()=>{this.refreshHighlightOffset();}));}clear(e){this.searchText="",e.change((t=>{if(this.highlightedResult){const i=this.highlightedResult.marker.name.split(":")[1],n=e.markers.get(`findResultHighlighted:${i}`);n&&t.removeMarker(n);}[...this.results].forEach((({marker:e})=>{t.removeMarker(e);}));})),this.results.clear();}refreshHighlightOffset(){const{highlightedResult:e,results:t}=this,i={before:-1,same:0,after:1,different:1};this.highlightedOffset=e?Array.from(t).sort(((e,t)=>i[e.marker.getStart().compareWith(t.marker.getStart())])).indexOf(e)+1:0;}}class vC extends Dr{static get pluginName(){return "FindAndReplaceUtils"}static get isOfficialPlugin(){return !0}updateFindResultFromRange(e,t,i,n){const s=n||new br;return t.change((n=>{[...e].forEach((({type:e,item:o})=>{if("elementStart"===e&&t.schema.checkChild(o,"$text")){let e=i({item:o,text:this.rangeToText(t.createRangeIn(o))});if(!e)return;"results"in e&&(e=e.results),e.forEach((e=>{const t=`findResult:${k()}`,i=n.addMarker(t,{usingOperation:!1,affectsData:!1,range:n.createRange(n.createPositionAt(o,e.start),n.createPositionAt(o,e.end))}),r=function(e,t){const i=e.find((({marker:e})=>t.getStart().isBefore(e.getStart())));return i?e.getIndex(i):e.length}(s,i);(e=>s.find((t=>{const{marker:i}=t,n=i.getRange(),s=e.getRange();return n.isEqual(s)})))(i)||s.add({id:t,label:e.label,marker:i},r);}));}}));})),s}rangeToText(e){return Array.from(e.getItems()).reduce(((e,t)=>t.is("$text")||t.is("$textProxy")?e+t.data:`${e}\n`),"")}findByTextCallback(e,t){let i="gu";t.matchCase||(i+="i");let n=`(${Rs(e)})`;if(t.wholeWords){const t="[^a-zA-ZÀ-ɏḀ-ỿ]";new RegExp("^"+t).test(e)||(n=`(^|${t}|_)${n}`),new RegExp(t+"$").test(e)||(n=`${n}(?=_|${t}|$)`);}const s=new RegExp(n,i);return function({text:e}){return [...e.matchAll(s)].map(yC)}}}function yC(e){const t=e.length-1;let i=e.index;return 3===e.length&&(i+=e[1].length),{label:e[t],start:i,end:i+e[t].length}}class kC extends Dr{static get requires(){return [vC]}static get pluginName(){return "FindAndReplaceEditing"}static get isOfficialPlugin(){return !0}state;init(){this.state=new _C(this.editor.model),this.set("_isSearchActive",!1),this._defineConverters(),this._defineCommands(),this.listenTo(this.state,"change:highlightedResult",((e,t,i,n)=>{const{model:s}=this.editor;s.change((e=>{if(n){const t=n.marker.name.split(":")[1],i=s.markers.get(`findResultHighlighted:${t}`);i&&e.removeMarker(i);}if(i){const t=i.marker.name.split(":")[1];e.addMarker(`findResultHighlighted:${t}`,{usingOperation:!1,affectsData:!1,range:i.marker.getRange()});}}));}));const e=vs(((e,t,i)=>{if(i){const e=this.editor.editing.view.domConverter,t=this.editor.editing.mapper.toViewRange(i.marker.getRange());Uo({target:e.viewRangeToDom(t),viewportOffset:40});}}).bind(this),32);this.listenTo(this.state,"change:highlightedResult",e,{priority:"low"}),this.listenTo(this.editor,"destroy",e.cancel),this.on("change:_isSearchActive",((e,t,i)=>{i?this.listenTo(this.editor.model.document,"change:data",this._onDocumentChange):this.stopListening(this.editor.model.document,"change:data",this._onDocumentChange);}));}find(e,t){return this._isSearchActive=!0,this.editor.execute("find",e,t),this.state.results}stop(){this.state.clear(this.editor.model),this._isSearchActive=!1;}_defineCommands(){this.editor.commands.add("find",new mC(this.editor,this.state)),this.editor.commands.add("findNext",new bC(this.editor,this.state)),this.editor.commands.add("findPrevious",new wC(this.editor,this.state)),this.editor.commands.add("replace",new fC(this.editor,this.state)),this.editor.commands.add("replaceAll",new pC(this.editor,this.state));}_defineConverters(){const{editor:e}=this;e.conversion.for("editingDowncast").markerToHighlight({model:"findResult",view:({markerName:e})=>{const[,t]=e.split(":");return {name:"span",classes:["ck-find-result"],attributes:{"data-find-result":t}}}}),e.conversion.for("editingDowncast").markerToHighlight({model:"findResultHighlighted",view:({markerName:e})=>{const[,t]=e.split(":");return {name:"span",classes:["ck-find-result_selected"],attributes:{"data-find-result":t}}}});}_onDocumentChange=()=>{const e=new Set,t=new Set,i=this.editor.model,{results:n}=this.state,s=i.document.differ.getChanges(),o=i.document.differ.getChangedMarkers();s.forEach((n=>{n.position&&("$text"===n.name||n.position.nodeAfter&&i.schema.isInline(n.position.nodeAfter)?(e.add(n.position.parent),[...i.markers.getMarkersAtPosition(n.position)].forEach((e=>{t.add(e.name);}))):"insert"===n.type&&n.position.nodeAfter&&e.add(n.position.nodeAfter));})),o.forEach((({name:e,data:{newRange:i}})=>{i&&"$graveyard"===i.start.root.rootName&&t.add(e);})),e.forEach((e=>{[...i.markers.getMarkersIntersectingRange(i.createRangeIn(e))].forEach((e=>t.add(e.name)));})),t.forEach((e=>{n.has(e)&&(n.get(e)===this.state.highlightedResult&&(this.state.highlightedResult=null),n.remove(e));}));const r=[],a=this.editor.plugins.get("FindAndReplaceUtils");e.forEach((e=>{const t=a.updateFindResultFromRange(i.createRangeOn(e),i,this.state.lastSearchCallback,n);r.push(...t);})),o.forEach((e=>{if(e.data.newRange){const t=a.updateFindResultFromRange(e.data.newRange,i,this.state.lastSearchCallback,n);r.push(...t);}})),!this.state.highlightedResult&&r.length?this.state.highlightedResult=r[0]:this.state.refreshHighlightOffset();}}class CC extends Dr{static get requires(){return [kC,hC]}static get pluginName(){return "FindAndReplace"}static get isOfficialPlugin(){return !0}init(){const e=this.editor.plugins.get("FindAndReplaceUI"),t=this.editor.plugins.get("FindAndReplaceEditing"),i=t.state;e.on("findNext",((e,n)=>{n?(i.searchText=n.searchText,t.find(n.searchText,n)):this.editor.execute("findNext");})),e.on("findPrevious",((e,n)=>{n&&i.searchText!==n.searchText?t.find(n.searchText):this.editor.execute("findPrevious");})),e.on("replace",((e,n)=>{i.searchText!==n.searchText&&t.find(n.searchText);const s=i.highlightedResult;s&&this.editor.execute("replace",n.replaceText,s);})),e.on("replaceAll",((e,n)=>{i.searchText!==n.searchText&&t.find(n.searchText),this.editor.execute("replaceAll",n.replaceText,i.results);})),e.on("searchReseted",(()=>{i.clear(this.editor.model),t.stop();}));}}class xC extends Hr{attributeKey;constructor(e,t){super(e),this.attributeKey=t;}refresh(){const e=this.editor.model,t=e.document;this.value=t.selection.getAttribute(this.attributeKey),this.isEnabled=e.schema.checkAttributeInSelection(t.selection,this.attributeKey);}execute(e={}){const t=this.editor.model,i=t.document.selection,n=e.value,s=e.batch,o=e=>{if(i.isCollapsed)n?e.setSelectionAttribute(this.attributeKey,n):e.removeSelectionAttribute(this.attributeKey);else {const s=t.schema.getValidRanges(i.getRanges(),this.attributeKey);for(const t of s)n?e.setAttribute(this.attributeKey,n,t):e.removeAttribute(this.attributeKey,t);}};s?t.enqueueChange(s,(e=>{o(e);})):t.change((e=>{o(e);}));}}const AC="fontSize",EC="fontFamily",TC="fontColor",PC="fontBackgroundColor";function SC(e,t){const i={model:{key:e,values:[]},view:{},upcastAlso:{}};for(const e of t)i.model.values.push(e.model),i.view[e.model]=e.view,e.upcastAlso&&(i.upcastAlso[e.model]=e.upcastAlso);return i}function IC(e){return t=>t.getStyle(e).replace(/\s/g,"")}function VC(e){return (t,{writer:i})=>i.createAttributeElement("span",{style:`${e}:${t}`},{priority:7})}class RC extends xC{constructor(e){super(e,EC);}}function OC(e){return e.map(BC).filter((e=>void 0!==e))}function BC(e){return "object"==typeof e?e:"default"===e?{title:"Default",model:void 0}:"string"==typeof e?function(e){const t=e.replace(/"|'/g,"").split(","),i=t[0],n=t.map(MC).join(", ");return {title:i,model:n,view:{name:"span",styles:{"font-family":n},priority:7}}}(e):void 0}function MC(e){return (e=e.trim()).indexOf(" ")>0&&(e=`'${e}'`),e}class LC extends Dr{static get pluginName(){return "FontFamilyEditing"}static get isOfficialPlugin(){return !0}constructor(e){super(e),e.config.define(EC,{options:["default","Arial, Helvetica, sans-serif","Courier New, Courier, monospace","Georgia, serif","Lucida Sans Unicode, Lucida Grande, sans-serif","Tahoma, Geneva, sans-serif","Times New Roman, Times, serif","Trebuchet MS, Helvetica, sans-serif","Verdana, Geneva, sans-serif"],supportAllValues:!1});}init(){const e=this.editor;e.model.schema.extend("$text",{allowAttributes:EC}),e.model.schema.setAttributeProperties(EC,{isFormatting:!0,copyOnEnter:!0});const t=OC(e.config.get("fontFamily.options")).filter((e=>e.model)),i=SC(EC,t);e.config.get("fontFamily.supportAllValues")?(this._prepareAnyValueConverters(),this._prepareCompatibilityConverter()):e.conversion.attributeToElement(i),e.commands.add(EC,new RC(e));}_prepareAnyValueConverters(){const e=this.editor;e.conversion.for("downcast").attributeToElement({model:EC,view:(e,{writer:t})=>t.createAttributeElement("span",{style:"font-family:"+e},{priority:7})}),e.conversion.for("upcast").elementToAttribute({model:{key:EC,value:e=>e.getStyle("font-family")},view:{name:"span",styles:{"font-family":/.*/}}});}_prepareCompatibilityConverter(){this.editor.conversion.for("upcast").elementToAttribute({view:{name:"font",attributes:{face:/.*/}},model:{key:EC,value:e=>e.getAttribute("face")}});}}var FC='';class NC extends Dr{static get pluginName(){return "FontFamilyUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.t,i=this._getLocalizedOptions(),n=e.commands.get(EC),s=t("Font Family"),o=function(e,t){const i=new br;for(const n of e){const e={type:"button",model:new Fb({commandName:EC,commandParam:n.model,label:n.title,role:"menuitemradio",withText:!0})};e.model.bind("isOn").to(t,"value",(e=>e===n.model||!(!e||!n.model)&&e.split(",")[0].replace(/'/g,"").toLowerCase()===n.model.toLowerCase())),n.view&&"string"!=typeof n.view&&n.view.styles&&e.model.set("labelStyle",`font-family: ${n.view.styles["font-family"]}`),i.add(e);}return i}(i,n);e.ui.componentFactory.add(EC,(t=>{const i=Xf(t);return sp(i,o,{role:"menu",ariaLabel:s}),i.buttonView.set({label:s,icon:FC,tooltip:!0}),i.extendTemplate({attributes:{class:"ck-font-family-dropdown"}}),i.bind("isEnabled").to(n),this.listenTo(i,"execute",(t=>{e.execute(t.source.commandName,{value:t.source.commandParam}),e.editing.view.focus();})),i})),e.ui.componentFactory.add(`menuBar:${EC}`,(t=>{const i=new aw(t);i.buttonView.set({label:s,icon:FC}),i.bind("isEnabled").to(n);const r=new lw(t);for(const n of o){const s=new ub(t,i),o=new Rg(t);o.set({role:"menuitemradio",isToggleable:!0}),o.bind(...Object.keys(n.model)).to(n.model),o.delegate("execute").to(i),o.on("execute",(()=>{e.execute(n.model.commandName,{value:n.model.commandParam}),e.editing.view.focus();})),s.children.add(o),r.items.add(s);}return i.panelView.children.add(r),i}));}_getLocalizedOptions(){const e=this.editor,t=e.t;return OC(e.config.get(EC).options).map((e=>("Default"===e.title&&(e.title=t("Default")),e)))}}class DC extends Dr{static get requires(){return [LC,NC]}static get pluginName(){return "FontFamily"}static get isOfficialPlugin(){return !0}}class zC extends xC{constructor(e){super(e,AC);}}function HC(e){return e.map((e=>function(e){"number"==typeof e&&(e=String(e));if("object"==typeof e&&(t=e,t.title&&t.model&&t.view))return UC(e);var t;const i=function(e){return "string"==typeof e?$C[e]:$C[e.model]}(e);if(i)return UC(i);if("default"===e)return {model:void 0,title:"Default"};if(function(e){let t;if("object"==typeof e){if(!e.model)throw new A("font-size-invalid-definition",null,e);t=parseFloat(e.model);}else t=parseFloat(e);return isNaN(t)}(e))return;return function(e){"string"==typeof e&&(e={title:e,model:`${parseFloat(e)}px`});return e.view={name:"span",styles:{"font-size":e.model}},UC(e)}(e)}(e))).filter((e=>void 0!==e))}const $C={get tiny(){return {title:"Tiny",model:"tiny",view:{name:"span",classes:"text-tiny",priority:7}}},get small(){return {title:"Small",model:"small",view:{name:"span",classes:"text-small",priority:7}}},get big(){return {title:"Big",model:"big",view:{name:"span",classes:"text-big",priority:7}}},get huge(){return {title:"Huge",model:"huge",view:{name:"span",classes:"text-huge",priority:7}}}};function UC(e){return e.view&&"string"!=typeof e.view&&!e.view.priority&&(e.view.priority=7),e}const WC=["x-small","x-small","small","medium","large","x-large","xx-large","xxx-large"];class jC extends Dr{static get pluginName(){return "FontSizeEditing"}static get isOfficialPlugin(){return !0}constructor(e){super(e),e.config.define(AC,{options:["tiny","small","default","big","huge"],supportAllValues:!1});}init(){const e=this.editor;e.model.schema.extend("$text",{allowAttributes:AC}),e.model.schema.setAttributeProperties(AC,{isFormatting:!0,copyOnEnter:!0});const t=e.config.get("fontSize.supportAllValues"),i=HC(this.editor.config.get("fontSize.options")).filter((e=>e.model)),n=SC(AC,i);t?(this._prepareAnyValueConverters(n),this._prepareCompatibilityConverter()):e.conversion.attributeToElement(n),e.commands.add(AC,new zC(e));}_prepareAnyValueConverters(e){const t=this.editor,i=e.model.values.filter((e=>!nh(String(e))&&!oh(String(e))));if(i.length)throw new A("font-size-invalid-use-of-named-presets",null,{presets:i});t.conversion.for("downcast").attributeToElement({model:AC,view:(e,{writer:t})=>{if(e)return t.createAttributeElement("span",{style:"font-size:"+e},{priority:7})}}),t.conversion.for("upcast").elementToAttribute({model:{key:AC,value:e=>e.getStyle("font-size")},view:{name:"span",styles:{"font-size":/.*/}}});}_prepareCompatibilityConverter(){this.editor.conversion.for("upcast").elementToAttribute({view:{name:"font",attributes:{size:/^[+-]?\d{1,3}$/}},model:{key:AC,value:e=>{const t=e.getAttribute("size"),i="-"===t[0]||"+"===t[0];let n=parseInt(t,10);i&&(n=3+n);const s=WC.length-1,o=Math.min(Math.max(n,0),s);return WC[o]}}});}}var qC='';class GC extends Dr{static get pluginName(){return "FontSizeUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.t,i=this._getLocalizedOptions(),n=e.commands.get(AC),s=t("Font Size"),o=function(e,t){const i=new br;for(const n of e){const e={type:"button",model:new Fb({commandName:AC,commandParam:n.model,label:n.title,class:"ck-fontsize-option",role:"menuitemradio",withText:!0})};n.view&&"string"!=typeof n.view&&(n.view.styles&&e.model.set("labelStyle",`font-size:${n.view.styles["font-size"]}`),n.view.classes&&e.model.set("class",`${e.model.class} ${n.view.classes}`)),e.model.bind("isOn").to(t,"value",(e=>e===n.model)),i.add(e);}return i}(i,n);e.ui.componentFactory.add(AC,(t=>{const i=Xf(t);return sp(i,o,{role:"menu",ariaLabel:s}),i.buttonView.set({label:s,icon:qC,tooltip:!0}),i.extendTemplate({attributes:{class:["ck-font-size-dropdown"]}}),i.bind("isEnabled").to(n),this.listenTo(i,"execute",(t=>{e.execute(t.source.commandName,{value:t.source.commandParam}),e.editing.view.focus();})),i})),e.ui.componentFactory.add(`menuBar:${AC}`,(t=>{const i=new aw(t);i.buttonView.set({label:s,icon:qC}),i.bind("isEnabled").to(n);const r=new lw(t);for(const n of o){const s=new ub(t,i),o=new Rg(t);o.set({role:"menuitemradio",isToggleable:!0}),o.bind(...Object.keys(n.model)).to(n.model),o.delegate("execute").to(i),o.on("execute",(()=>{e.execute(n.model.commandName,{value:n.model.commandParam}),e.editing.view.focus();})),s.children.add(o),r.items.add(s);}return i.panelView.children.add(r),i}));}_getLocalizedOptions(){const e=this.editor,t=e.t,i={Default:t("Default"),Tiny:t("Tiny"),Small:t("Small"),Big:t("Big"),Huge:t("Huge")};return HC(e.config.get(AC).options).map((e=>{const t=i[e.title];return t&&t!=e.title&&(e=Object.assign({},e,{title:t})),e}))}}class KC extends Dr{static get requires(){return [jC,GC]}static get pluginName(){return "FontSize"}static get isOfficialPlugin(){return !0}normalizeSizeOptions(e){return HC(e)}}class ZC extends xC{constructor(e){super(e,TC);}}class JC extends Dr{static get pluginName(){return "FontColorEditing"}static get isOfficialPlugin(){return !0}constructor(e){super(e),e.config.define(TC,{colors:[{color:"hsl(0, 0%, 0%)",label:"Black"},{color:"hsl(0, 0%, 30%)",label:"Dim grey"},{color:"hsl(0, 0%, 60%)",label:"Grey"},{color:"hsl(0, 0%, 90%)",label:"Light grey"},{color:"hsl(0, 0%, 100%)",label:"White",hasBorder:!0},{color:"hsl(0, 75%, 60%)",label:"Red"},{color:"hsl(30, 75%, 60%)",label:"Orange"},{color:"hsl(60, 75%, 60%)",label:"Yellow"},{color:"hsl(90, 75%, 60%)",label:"Light green"},{color:"hsl(120, 75%, 60%)",label:"Green"},{color:"hsl(150, 75%, 60%)",label:"Aquamarine"},{color:"hsl(180, 75%, 60%)",label:"Turquoise"},{color:"hsl(210, 75%, 60%)",label:"Light blue"},{color:"hsl(240, 75%, 60%)",label:"Blue"},{color:"hsl(270, 75%, 60%)",label:"Purple"}],columns:5}),e.conversion.for("upcast").elementToAttribute({view:{name:"span",styles:{color:/[\s\S]+/}},model:{key:TC,value:IC("color")}}),e.conversion.for("upcast").elementToAttribute({view:{name:"font",attributes:{color:/^#?\w+$/}},model:{key:TC,value:e=>e.getAttribute("color")}}),e.conversion.for("downcast").attributeToElement({model:TC,view:VC("color")}),e.commands.add(TC,new ZC(e)),e.model.schema.extend("$text",{allowAttributes:TC}),e.model.schema.setAttributeProperties(TC,{isFormatting:!0,copyOnEnter:!0});}}class QC extends Dr{commandName;componentName;icon;dropdownLabel;columns;constructor(e,{commandName:t,componentName:i,icon:n,dropdownLabel:s}){super(e),this.commandName=t,this.componentName=i,this.icon=n,this.dropdownLabel=s,this.columns=e.config.get(`${this.componentName}.columns`);}init(){const e=this.editor,t=e.locale,i=t.t,n=e.commands.get(this.commandName),s=e.config.get(this.componentName),o=qg(t,Gg(s.colors)),r=s.documentColors,a=!1!==s.colorPicker;e.ui.componentFactory.add(this.componentName,(t=>{const l=Xf(t);let c=!1;const d=function({dropdownView:e,colors:t,columns:i,removeButtonLabel:n,colorPickerLabel:s,documentColorsLabel:o,documentColorsCount:r,colorPickerViewConfig:a}){const l=e.locale,c=new Jp(l,{colors:t,columns:i,removeButtonLabel:n,colorPickerLabel:s,documentColorsLabel:o,documentColorsCount:r,colorPickerViewConfig:a});return e.colorSelectorView=c,e.panelView.children.add(c),c}({dropdownView:l,colors:o.map((e=>({label:e.label,color:e.model,options:{hasBorder:e.hasBorder}}))),columns:this.columns,removeButtonLabel:i("Remove color"),colorPickerLabel:i("Color picker"),documentColorsLabel:0!==r?i("Document colors"):"",documentColorsCount:void 0===r?this.columns:r,colorPickerViewConfig:!!a&&(s.colorPicker||{})});return d.bind("selectedColor").to(n,"value"),l.buttonView.set({label:this.dropdownLabel,icon:this.icon,tooltip:!0}),l.extendTemplate({attributes:{class:"ck-color-ui-dropdown"}}),l.bind("isEnabled").to(n),d.on("execute",((t,i)=>{l.isOpen&&e.execute(this.commandName,{value:i.value,batch:this._undoStepBatch}),"colorPicker"!==i.source&&e.editing.view.focus(),"colorPickerSaveButton"===i.source&&(l.isOpen=!1);})),d.on("colorPicker:show",(()=>{this._undoStepBatch=e.model.createBatch();})),d.on("colorPicker:cancel",(()=>{this._undoStepBatch.operations.length&&(l.isOpen=!1,e.execute("undo",this._undoStepBatch)),e.editing.view.focus();})),l.on("change:isOpen",((t,i,n)=>{c||(c=!0,l.colorSelectorView.appendUI()),n&&(0!==r&&d.updateDocumentColors(e.model,this.componentName),d.updateSelectedColors(),d.showColorGridsFragment());})),rp(l,(()=>l.colorSelectorView.colorGridsFragmentView.staticColorsGrid.items.find((e=>e.isOn)))),l})),e.ui.componentFactory.add(`menuBar:${this.componentName}`,(t=>{const s=new aw(t);s.buttonView.set({label:this.dropdownLabel,icon:this.icon}),s.bind("isEnabled").to(n);let a=!1;const l=new Jp(t,{colors:o.map((e=>({label:e.label,color:e.model,options:{hasBorder:e.hasBorder}}))),columns:this.columns,removeButtonLabel:i("Remove color"),colorPickerLabel:i("Color picker"),documentColorsLabel:0!==r?i("Document colors"):"",documentColorsCount:void 0===r?this.columns:r,colorPickerViewConfig:!1});return l.bind("selectedColor").to(n,"value"),l.delegate("execute").to(s),l.on("execute",((t,i)=>{e.execute(this.commandName,{value:i.value,batch:this._undoStepBatch}),e.editing.view.focus();})),s.on("change:isOpen",((t,i,n)=>{a||(a=!0,l.appendUI()),n&&(0!==r&&l.updateDocumentColors(e.model,this.componentName),l.updateSelectedColors(),l.showColorGridsFragment());})),s.panelView.children.add(l),s}));}}class YC extends QC{constructor(e){const t=e.locale.t;super(e,{commandName:TC,componentName:TC,icon:'',dropdownLabel:t("Font Color")});}static get pluginName(){return "FontColorUI"}}class XC extends Dr{static get requires(){return [JC,YC]}static get pluginName(){return "FontColor"}static get isOfficialPlugin(){return !0}}class ex extends xC{constructor(e){super(e,PC);}}class tx extends Dr{static get pluginName(){return "FontBackgroundColorEditing"}static get isOfficialPlugin(){return !0}constructor(e){super(e),e.config.define(PC,{colors:[{color:"hsl(0, 0%, 0%)",label:"Black"},{color:"hsl(0, 0%, 30%)",label:"Dim grey"},{color:"hsl(0, 0%, 60%)",label:"Grey"},{color:"hsl(0, 0%, 90%)",label:"Light grey"},{color:"hsl(0, 0%, 100%)",label:"White",hasBorder:!0},{color:"hsl(0, 75%, 60%)",label:"Red"},{color:"hsl(30, 75%, 60%)",label:"Orange"},{color:"hsl(60, 75%, 60%)",label:"Yellow"},{color:"hsl(90, 75%, 60%)",label:"Light green"},{color:"hsl(120, 75%, 60%)",label:"Green"},{color:"hsl(150, 75%, 60%)",label:"Aquamarine"},{color:"hsl(180, 75%, 60%)",label:"Turquoise"},{color:"hsl(210, 75%, 60%)",label:"Light blue"},{color:"hsl(240, 75%, 60%)",label:"Blue"},{color:"hsl(270, 75%, 60%)",label:"Purple"}],columns:5}),e.data.addStyleProcessorRules(_h),e.conversion.for("upcast").elementToAttribute({view:{name:"span",styles:{"background-color":/[\s\S]+/}},model:{key:PC,value:IC("background-color")}}),e.conversion.for("downcast").attributeToElement({model:PC,view:VC("background-color")}),e.commands.add(PC,new ex(e)),e.model.schema.extend("$text",{allowAttributes:PC}),e.model.schema.setAttributeProperties(PC,{isFormatting:!0,copyOnEnter:!0});}}class ix extends QC{constructor(e){const t=e.locale.t;super(e,{commandName:PC,componentName:PC,icon:'',dropdownLabel:t("Font Background Color")});}static get pluginName(){return "FontBackgroundColorUI"}}class nx extends Dr{static get requires(){return [tx,ix]}static get pluginName(){return "FontBackgroundColor"}static get isOfficialPlugin(){return !0}}class sx extends Dr{static get requires(){return [DC,KC,XC,nx]}static get pluginName(){return "Font"}static get isOfficialPlugin(){return !0}}class ox extends Hr{constructor(e){super(e),this._isEnabledBasedOnSelection=!1;}refresh(){const e=this.editor.model,t=wr(e.document.selection.getSelectedBlocks());this.value=!!t&&t.is("element","paragraph"),this.isEnabled=!!t&&rx(t,e.schema);}execute(e={}){const t=this.editor.model,i=t.document,n=e.selection||i.selection;t.canEditAt(n)&&t.change((e=>{const i=n.getSelectedBlocks();for(const n of i)!n.is("element","paragraph")&&rx(n,t.schema)&&e.rename(n,"paragraph");}));}}function rx(e,t){return t.checkChild(e.parent,"paragraph")&&!t.isObject(e)}class ax extends Hr{constructor(e){super(e),this._isEnabledBasedOnSelection=!1;}execute(e){const t=this.editor.model,i=e.attributes;let n=e.position;t.canEditAt(n)&&t.change((e=>{if(n=this._findPositionToInsertParagraph(n,e),!n)return;const s=e.createElement("paragraph");i&&t.schema.setAllowedAttributes(s,i,e),t.insertContent(s,n),e.setSelection(s,"in");}));}_findPositionToInsertParagraph(e,t){const i=this.editor.model;if(i.schema.checkChild(e,"paragraph"))return e;const n=i.schema.findAllowedParent(e,"paragraph");if(!n)return null;const s=e.parent,o=i.schema.checkChild(s,"$text");return s.isEmpty||o&&e.isAtEnd?i.createPositionAfter(s):!s.isEmpty&&o&&e.isAtStart?i.createPositionBefore(s):t.split(e,n).position}}class lx extends Dr{static get pluginName(){return "Paragraph"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.model;e.commands.add("paragraph",new ox(e)),e.commands.add("insertParagraph",new ax(e)),t.schema.register("paragraph",{inheritAllFrom:"$block"}),e.conversion.elementToElement({model:"paragraph",view:"p"}),e.conversion.for("upcast").elementToElement({model:(e,{writer:t})=>lx.paragraphLikeElements.has(e.name)?e.isEmpty?null:t.createElement("paragraph"):null,view:/.+/,converterPriority:"low"});}static paragraphLikeElements=new Set(["blockquote","dd","div","dt","h1","h2","h3","h4","h5","h6","li","p","td","th"])}class cx extends Dr{static get requires(){return [lx]}init(){const e=this.editor,t=e.t;e.ui.componentFactory.add("paragraph",(i=>{const n=new pg(i),s=e.commands.get("paragraph");return n.label=t("Paragraph"),n.icon=vm.paragraph,n.tooltip=!0,n.isToggleable=!0,n.bind("isEnabled").to(s),n.bind("isOn").to(s,"value"),n.on("execute",(()=>{e.execute("paragraph");})),n}));}}class dx extends Hr{modelElements;constructor(e,t){super(e),this.modelElements=t;}refresh(){const e=wr(this.editor.model.document.selection.getSelectedBlocks());this.value=!!e&&this.modelElements.includes(e.name)&&e.name,this.isEnabled=!!e&&this.modelElements.some((t=>ux(e,t,this.editor.model.schema)));}execute(e){const t=this.editor.model,i=t.document,n=e.value;t.change((e=>{const s=Array.from(i.selection.getSelectedBlocks()).filter((e=>ux(e,n,t.schema)));for(const t of s)t.is("element",n)||e.rename(t,n);}));}}function ux(e,t,i){return i.checkChild(e.parent,t)&&!i.isObject(e)}const hx="paragraph";class mx extends Dr{static get pluginName(){return "HeadingEditing"}static get isOfficialPlugin(){return !0}constructor(e){super(e),e.config.define("heading",{options:[{model:"paragraph",title:"Paragraph",class:"ck-heading_paragraph"},{model:"heading1",view:"h2",title:"Heading 1",class:"ck-heading_heading1"},{model:"heading2",view:"h3",title:"Heading 2",class:"ck-heading_heading2"},{model:"heading3",view:"h4",title:"Heading 3",class:"ck-heading_heading3"}]});}static get requires(){return [lx]}init(){const e=this.editor,t=e.config.get("heading.options"),i=[];for(const n of t)"paragraph"!==n.model&&(e.model.schema.register(n.model,{inheritAllFrom:"$block"}),e.conversion.elementToElement(n),i.push(n.model));this._addDefaultH1Conversion(e),e.commands.add("heading",new dx(e,i));}afterInit(){const e=this.editor,t=e.commands.get("enter"),i=e.config.get("heading.options");t&&this.listenTo(t,"afterExecute",((t,n)=>{const s=e.model.document.selection.getFirstPosition().parent;i.some((e=>s.is("element",e.model)))&&!s.is("element",hx)&&0===s.childCount&&n.writer.rename(s,hx);}));}_addDefaultH1Conversion(e){e.conversion.for("upcast").elementToElement({model:"heading1",view:"h1",converterPriority:C.low+1});}}function gx(e){const t=e.t,i={Paragraph:t("Paragraph"),"Heading 1":t("Heading 1"),"Heading 2":t("Heading 2"),"Heading 3":t("Heading 3"),"Heading 4":t("Heading 4"),"Heading 5":t("Heading 5"),"Heading 6":t("Heading 6")};return e.config.get("heading.options").map((e=>{const t=i[e.title];return t&&t!=e.title&&(e.title=t),e}))}class fx extends Dr{static get pluginName(){return "HeadingUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.t,i=gx(e),n=t("Choose heading"),s=t("Heading");e.ui.componentFactory.add("heading",(t=>{const o={},r=new br,a=e.commands.get("heading"),l=e.commands.get("paragraph"),c=[a];for(const e of i){const t={type:"button",model:new Fb({label:e.title,class:e.class,role:"menuitemradio",withText:!0})};"paragraph"===e.model?(t.model.bind("isOn").to(l,"value"),t.model.set("commandName","paragraph"),c.push(l)):(t.model.bind("isOn").to(a,"value",(t=>t===e.model)),t.model.set({commandName:"heading",commandValue:e.model})),r.add(t),o[e.model]=e.title;}const d=Xf(t);return sp(d,r,{ariaLabel:s,role:"menu"}),d.buttonView.set({ariaLabel:s,ariaLabelledBy:void 0,isOn:!1,withText:!0,tooltip:s}),d.extendTemplate({attributes:{class:["ck-heading-dropdown"]}}),d.bind("isEnabled").toMany(c,"isEnabled",((...e)=>e.some((e=>e)))),d.buttonView.bind("label").to(a,"value",l,"value",((e,t)=>{const i=t?"paragraph":e;return "boolean"==typeof i?n:o[i]?o[i]:n})),d.buttonView.bind("ariaLabel").to(a,"value",l,"value",((e,t)=>{const i=t?"paragraph":e;return "boolean"==typeof i?s:o[i]?`${o[i]}, ${s}`:s})),this.listenTo(d,"execute",(t=>{const{commandName:i,commandValue:n}=t.source;e.execute(i,n?{value:n}:void 0),e.editing.view.focus();})),d})),e.ui.componentFactory.add("menuBar:heading",(n=>{const s=new aw(n),o=e.commands.get("heading"),r=e.commands.get("paragraph"),a=[o],l=new lw(n);s.set({class:"ck-heading-dropdown"}),l.set({ariaLabel:t("Heading"),role:"menu"}),s.buttonView.set({label:t("Heading")}),s.panelView.children.add(l);for(const t of i){const i=new ub(n,s),c=new Rg(n);i.children.add(c),l.items.add(i),c.set({isToggleable:!0,label:t.title,role:"menuitemradio",class:t.class}),c.delegate("execute").to(s),c.on("execute",(()=>{const i="paragraph"===t.model?"paragraph":"heading";e.execute(i,{value:t.model}),e.editing.view.focus();})),"paragraph"===t.model?(c.bind("isOn").to(r,"value"),a.push(r)):c.bind("isOn").to(o,"value",(e=>e===t.model));}return s.bind("isEnabled").toMany(a,"isEnabled",((...e)=>e.some((e=>e)))),s}));}}class px extends Dr{static get requires(){return [mx,fx]}static get pluginName(){return "Heading"}static get isOfficialPlugin(){return !0}}const bx=(()=>({heading1:vm.heading1,heading2:vm.heading2,heading3:vm.heading3,heading4:vm.heading4,heading5:vm.heading5,heading6:vm.heading6}))();class wx extends Dr{init(){gx(this.editor).filter((e=>"paragraph"!==e.model)).map((e=>this._createButton(e)));}_createButton(e){const t=this.editor;t.ui.componentFactory.add(e.model,(i=>{const n=new pg(i),s=t.commands.get("heading");return n.label=e.title,n.icon=e.icon||bx[e.model],n.tooltip=!0,n.isToggleable=!0,n.bind("isEnabled").to(s),n.bind("isOn").to(s,"value",(t=>t==e.model)),n.on("execute",(()=>{t.execute("heading",{value:e.model}),t.editing.view.focus();})),n}));}}const _x=new Set(["paragraph","heading1","heading2","heading3","heading4","heading5","heading6"]);class vx extends Dr{_bodyPlaceholder=new Map;static get pluginName(){return "Title"}static get isOfficialPlugin(){return !0}static get requires(){return ["Paragraph"]}init(){const e=this.editor,t=e.model;t.schema.register("title",{isBlock:!0,allowIn:"$root"}),t.schema.register("title-content",{isBlock:!0,allowIn:"title",allowAttributes:["alignment"]}),t.schema.extend("$text",{allowIn:"title-content"}),t.schema.addAttributeCheck((e=>{if(e.endsWith("title-content $text"))return !1})),e.editing.mapper.on("modelToViewPosition",kx(e.editing.view)),e.data.mapper.on("modelToViewPosition",kx(e.editing.view)),e.conversion.for("downcast").elementToElement({model:"title-content",view:"h1"}),e.conversion.for("downcast").add((e=>e.on("insert:title",((e,t,i)=>{i.consumable.consume(t.item,e.name);})))),e.data.upcastDispatcher.on("element:h1",yx,{priority:"high"}),e.data.upcastDispatcher.on("element:h2",yx,{priority:"high"}),e.data.upcastDispatcher.on("element:h3",yx,{priority:"high"}),t.document.registerPostFixer((e=>this._fixTitleContent(e))),t.document.registerPostFixer((e=>this._fixTitleElement(e))),t.document.registerPostFixer((e=>this._fixBodyElement(e))),t.document.registerPostFixer((e=>this._fixExtraParagraph(e))),this._attachPlaceholders(),this._attachTabPressHandling();}getTitle(e={}){const t=e.rootName?e.rootName:void 0,i=this._getTitleElement(t).getChild(0);return this.editor.data.stringify(i,e)}getBody(e={}){const t=this.editor,i=t.data,n=t.model,s=e.rootName?e.rootName:void 0,o=t.model.document.getRoot(s),r=t.editing.view,a=new qa(r.document),l=n.createRangeIn(o),c=a.createDocumentFragment(),d=n.createPositionAfter(o.getChild(0)),u=n.createRange(d,n.createPositionAt(o,"end")),h=new Map;for(const e of n.markers){const t=u.getIntersection(e.getRange());t&&h.set(e.name,t);}return i.mapper.clearBindings(),i.mapper.bindElements(o,c),i.downcastDispatcher.convert(l,h,a,e),a.remove(a.createRangeOn(c.getChild(0))),t.data.processor.toData(c)}_getTitleElement(e){const t=this.editor.model.document.getRoot(e);for(const e of t.getChildren())if(Cx(e))return e}_fixTitleContent(e){let t=!1;for(const i of this.editor.model.document.getRootNames()){const n=this._getTitleElement(i);if(!n||1===n.maxOffset)continue;const s=Array.from(n.getChildren());s.shift();for(const t of s)e.move(e.createRangeOn(t),n,"after"),e.rename(t,"paragraph");t=!0;}return t}_fixTitleElement(e){let t=!1;const i=this.editor.model;for(const n of this.editor.model.document.getRoots()){const s=Array.from(n.getChildren()).filter(Cx),o=s[0],r=n.getChild(0);if(r.is("element","title"))s.length>1&&(Ax(s,e,i),t=!0);else if(o||_x.has(r.name))_x.has(r.name)?xx(r,e,i):e.move(e.createRangeOn(o),n,0),Ax(s,e,i),t=!0;else {const i=e.createElement("title");e.insert(i,n),e.insertElement("title-content",i),t=!0;}}return t}_fixBodyElement(e){let t=!1;for(const i of this.editor.model.document.getRootNames()){const n=this.editor.model.document.getRoot(i);if(n.childCount<2){const s=e.createElement("paragraph");e.insert(s,n,1),this._bodyPlaceholder.set(i,s),t=!0;}}return t}_fixExtraParagraph(e){let t=!1;for(const i of this.editor.model.document.getRootNames()){const n=this.editor.model.document.getRoot(i),s=this._bodyPlaceholder.get(i);Tx(s,n)&&(this._bodyPlaceholder.delete(i),e.remove(s),t=!0);}return t}_attachPlaceholders(){const e=this.editor,t=e.t,i=e.editing.view,n=e.sourceElement,s=e.config.get("title.placeholder")||t("Type your title"),o=e.config.get("placeholder")||n&&"textarea"===n.tagName.toLowerCase()&&n.getAttribute("placeholder")||t("Type or paste your content here.");e.editing.downcastDispatcher.on("insert:title-content",((e,t,n)=>{const o=n.mapper.toViewElement(t.item);o.placeholder=s,Zr({view:i,element:o,keepOnFocus:!0});}));const r=new Map;i.document.registerPostFixer((e=>{let t=!1;for(const n of i.document.roots){if(n.isEmpty)continue;const i=n.getChild(1),s=r.get(n.rootName);i!==s&&(s&&(Yr(e,s),e.removeAttribute("data-placeholder",s)),e.setAttribute("data-placeholder",o,i),r.set(n.rootName,i),t=!0),t=Xr(i,!0)&&2===n.childCount&&"p"===i.name?!!Qr(e,i)||t:!!Yr(e,i)||t;}return t}));}_attachTabPressHandling(){const e=this.editor,t=e.model;e.keystrokes.set("TAB",((e,i)=>{t.change((e=>{const n=t.document.selection,s=Array.from(n.getSelectedBlocks());if(1===s.length&&s[0].is("element","title-content")){const t=n.getFirstPosition().root.getChild(1);e.setSelection(t,0),i();}}));})),e.keystrokes.set("SHIFT + TAB",((i,n)=>{t.change((i=>{const s=t.document.selection;if(!s.isCollapsed)return;const o=wr(s.getSelectedBlocks()),r=s.getFirstPosition(),a=e.model.document.getRoot(r.root.rootName),l=a.getChild(0);o===a.getChild(1)&&r.isAtStart&&(i.setSelection(l.getChild(0),0),n());}));}));}}function yx(e,t,i){const n=t.modelCursor,s=t.viewItem;if(!n.isAtStart||!n.parent.is("element","$root"))return;if(!i.consumable.consume(s,{name:!0}))return;const o=i.writer,r=o.createElement("title"),a=o.createElement("title-content");o.append(a,r),o.insert(r,n),i.convertChildren(s,a),i.updateConversionResult(r,t);}function kx(e){return (t,i)=>{const n=i.modelPosition.parent;if(!n.is("element","title"))return;const s=n.parent,o=i.mapper.toViewElement(s);i.viewPosition=e.createPositionAt(o,0),t.stop();}}function Cx(e){return e.is("element","title")}function xx(e,t,i){const n=t.createElement("title");t.insert(n,e,"before"),t.insert(e,n,0),t.rename(e,"title-content"),i.schema.removeDisallowedAttributes([e],t);}function Ax(e,t,i){let n=!1;for(const s of e)0!==s.index&&(Ex(s,t,i),n=!0);return n}function Ex(e,t,i){const n=e.getChild(0);n.isEmpty?t.remove(e):(t.move(t.createRangeOn(n),e,"before"),t.rename(n,"paragraph"),t.remove(e),i.schema.removeDisallowedAttributes([n],t));}function Tx(e,t){return !(!e||!e.is("element","paragraph")||e.childCount)&&!(t.childCount<=2||t.getChild(t.childCount-1)!==e)}class Px extends Hr{refresh(){const e=this.editor.model,t=e.document;this.value=t.selection.getAttribute("highlight"),this.isEnabled=e.schema.checkAttributeInSelection(t.selection,"highlight");}execute(e={}){const t=this.editor.model,i=t.document.selection,n=e.value;t.change((e=>{if(i.isCollapsed){const t=i.getFirstPosition();if(i.hasAttribute("highlight")){const i=e=>e.item.hasAttribute("highlight")&&e.item.getAttribute("highlight")===this.value,s=t.getLastMatchingPosition(i,{direction:"backward"}),o=t.getLastMatchingPosition(i),r=e.createRange(s,o);n&&this.value!==n?(t.isEqual(o)||e.setAttribute("highlight",n,r),e.setSelectionAttribute("highlight",n)):(t.isEqual(o)||e.removeAttribute("highlight",r),e.removeSelectionAttribute("highlight"));}else n&&e.setSelectionAttribute("highlight",n);}else {const s=t.schema.getValidRanges(i.getRanges(),"highlight");for(const t of s)n?e.setAttribute("highlight",n,t):e.removeAttribute("highlight",t);}}));}}class Sx extends Dr{static get pluginName(){return "HighlightEditing"}static get isOfficialPlugin(){return !0}constructor(e){super(e),e.config.define("highlight",{options:[{model:"yellowMarker",class:"marker-yellow",title:"Yellow marker",color:"var(--ck-highlight-marker-yellow)",type:"marker"},{model:"greenMarker",class:"marker-green",title:"Green marker",color:"var(--ck-highlight-marker-green)",type:"marker"},{model:"pinkMarker",class:"marker-pink",title:"Pink marker",color:"var(--ck-highlight-marker-pink)",type:"marker"},{model:"blueMarker",class:"marker-blue",title:"Blue marker",color:"var(--ck-highlight-marker-blue)",type:"marker"},{model:"redPen",class:"pen-red",title:"Red pen",color:"var(--ck-highlight-pen-red)",type:"pen"},{model:"greenPen",class:"pen-green",title:"Green pen",color:"var(--ck-highlight-pen-green)",type:"pen"}]});}init(){const e=this.editor;e.model.schema.extend("$text",{allowAttributes:"highlight"});const t=e.config.get("highlight.options");e.conversion.attributeToElement(function(e){const t={model:{key:"highlight",values:[]},view:{}};for(const i of e)t.model.values.push(i.model),t.view[i.model]={name:"mark",classes:i.class};return t}(t)),e.commands.add("highlight",new Px(e));}}class Ix extends Dr{get localizedOptionTitles(){const e=this.editor.t;return {"Yellow marker":e("Yellow marker"),"Green marker":e("Green marker"),"Pink marker":e("Pink marker"),"Blue marker":e("Blue marker"),"Red pen":e("Red pen"),"Green pen":e("Green pen")}}static get pluginName(){return "HighlightUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor.config.get("highlight.options");for(const t of e)this._addHighlighterButton(t);this._addRemoveHighlightButton(),this._addDropdown(e),this._addMenuBarButton(e);}_addRemoveHighlightButton(){const e=this.editor.t,t=this.editor.commands.get("highlight");this._addButton("removeHighlight",e("Remove highlight"),vm.eraser,null,(e=>{e.bind("isEnabled").to(t,"isEnabled");}));}_addHighlighterButton(e){const t=this.editor.commands.get("highlight");this._addButton("highlight:"+e.model,e.title,Vx(e.type),e.model,(function(i){i.bind("isEnabled").to(t,"isEnabled"),i.bind("isOn").to(t,"value",(t=>t===e.model)),i.iconView.fillColor=e.color,i.isToggleable=!0;}));}_addButton(e,t,i,n,s){const o=this.editor;o.ui.componentFactory.add(e,(e=>{const r=new pg(e),a=this.localizedOptionTitles[t]?this.localizedOptionTitles[t]:t;return r.set({label:a,icon:i,tooltip:!0}),r.on("execute",(()=>{o.execute("highlight",{value:n}),o.editing.view.focus();})),s(r),r}));}_addDropdown(e){const t=this.editor,i=t.t,n=t.ui.componentFactory,s=e[0],o=e.reduce(((e,t)=>(e[t.model]=t,e)),{});n.add("highlight",(r=>{const a=t.commands.get("highlight"),l=Xf(r,Yf),c=l.buttonView;c.set({label:i("Highlight"),tooltip:!0,lastExecuted:s.model,commandValue:s.model,isToggleable:!0}),c.bind("icon").to(a,"value",(e=>Vx(d(e,"type")))),c.bind("color").to(a,"value",(e=>d(e,"color"))),c.bind("commandValue").to(a,"value",(e=>d(e,"model"))),c.bind("isOn").to(a,"value",(e=>!!e)),c.delegate("execute").to(l);function d(e,t){const i=e&&e!==c.lastExecuted?e:c.lastExecuted;return o[i][t]}return l.bind("isEnabled").to(a,"isEnabled"),ip(l,(()=>{const t=e.map((e=>{const t=n.create("highlight:"+e.model);return this.listenTo(t,"execute",(()=>{l.buttonView.set({lastExecuted:e.model});})),t}));return t.push(new Wf),t.push(n.create("removeHighlight")),t}),{enableActiveItemFocusOnDropdownOpen:!0,ariaLabel:i("Text highlight toolbar")}),function(e){const t=e.buttonView.actionView;t.iconView.bind("fillColor").to(e.buttonView,"color");}(l),c.on("execute",(()=>{t.execute("highlight",{value:c.commandValue});})),this.listenTo(l,"execute",(()=>{t.editing.view.focus();})),l}));}_addMenuBarButton(e){const t=this.editor,i=t.t,n=t.commands.get("highlight");t.ui.componentFactory.add("menuBar:highlight",(s=>{const o=new aw(s);o.buttonView.set({label:i("Highlight"),icon:Vx("marker")}),o.bind("isEnabled").to(n),o.buttonView.iconView.fillColor="transparent";const r=new lw(s);for(const i of e){const e=new ub(s,o),a=new Rg(s);a.set({label:i.title,icon:Vx(i.type),role:"menuitemradio",isToggleable:!0}),a.iconView.fillColor=i.color,a.delegate("execute").to(o),a.bind("isOn").to(n,"value",(e=>e===i.model)),a.on("execute",(()=>{t.execute("highlight",{value:i.model}),t.editing.view.focus();})),e.children.add(a),r.items.add(e);}r.items.add(new Sf(s));const a=new ub(s,o),l=new Rg(s);return l.set({label:i("Remove highlight"),icon:vm.eraser}),l.delegate("execute").to(o),l.on("execute",(()=>{t.execute("highlight",{value:null}),t.editing.view.focus();})),a.children.add(l),r.items.add(a),o.panelView.children.add(r),o}));}}function Vx(e){return "marker"===e?'':''}class Rx extends Dr{static get requires(){return [Sx,Ix]}static get pluginName(){return "Highlight"}static get isOfficialPlugin(){return !0}}class Ox extends Hr{refresh(){const e=this.editor.model,t=e.schema,i=e.document.selection;this.isEnabled=function(e,t,i){const n=function(e,t){const i=hy(e,t),n=i.start.parent;if(n.isEmpty&&!n.is("element","$root"))return n.parent;return n}(e,i);return t.checkChild(n,"horizontalLine")}(i,t,e);}execute(){const e=this.editor.model;e.change((t=>{const i=t.createElement("horizontalLine");e.insertObject(i,null,null,{setSelection:"after"});}));}}class Bx extends Dr{static get pluginName(){return "HorizontalLineEditing"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.model.schema,i=e.t,n=e.conversion;t.register("horizontalLine",{inheritAllFrom:"$blockObject"}),n.for("dataDowncast").elementToElement({model:"horizontalLine",view:(e,{writer:t})=>t.createEmptyElement("hr")}),n.for("editingDowncast").elementToStructure({model:"horizontalLine",view:(e,{writer:t})=>{const n=i("Horizontal line"),s=t.createContainerElement("div",null,t.createEmptyElement("hr"));return t.addClass("ck-horizontal-line",s),t.setCustomProperty("hr",!0,s),function(e,t,i){return t.setCustomProperty("horizontalLine",!0,e),oy(e,t,{label:i})}(s,t,n)}}),n.for("upcast").elementToElement({view:"hr",model:"horizontalLine"}),e.commands.add("horizontalLine",new Ox(e));}}class Mx extends Dr{static get pluginName(){return "HorizontalLineUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;e.ui.componentFactory.add("horizontalLine",(()=>{const e=this._createButton(pg);return e.set({tooltip:!0}),e})),e.ui.componentFactory.add("menuBar:horizontalLine",(()=>this._createButton(Rg)));}_createButton(e){const t=this.editor,i=t.locale,n=t.commands.get("horizontalLine"),s=new e(t.locale),o=i.t;return s.set({label:o("Horizontal line"),icon:vm.horizontalLine}),s.bind("isEnabled").to(n,"isEnabled"),this.listenTo(s,"execute",(()=>{t.execute("horizontalLine"),t.editing.view.focus();})),s}}class Lx extends Dr{static get requires(){return [Bx,Mx,Ty]}static get pluginName(){return "HorizontalLine"}static get isOfficialPlugin(){return !0}}class Fx extends Hr{refresh(){const e=this.editor.model,t=e.schema,i=e.document.selection,n=Nx(i);this.isEnabled=function(e,t,i){const n=function(e,t){const i=hy(e,t),n=i.start.parent;if(n.isEmpty&&!n.is("rootElement"))return n.parent;return n}(e,i);return t.checkChild(n,"rawHtml")}(i,t,e),this.value=n?n.getAttribute("value")||"":null;}execute(e){const t=this.editor.model,i=t.document.selection;t.change((n=>{let s;null!==this.value?s=Nx(i):(s=n.createElement("rawHtml"),t.insertObject(s,null,null,{setSelection:"on"})),n.setAttribute("value",e,s);}));}}function Nx(e){const t=e.getSelectedElement();return t&&t.is("element","rawHtml")?t:null}class Dx extends Dr{_widgetButtonViewReferences=new Set;static get pluginName(){return "HtmlEmbedEditing"}static get isOfficialPlugin(){return !0}constructor(e){super(e),e.config.define("htmlEmbed",{showPreviews:!1,sanitizeHtml:e=>(E("html-embed-provide-sanitize-function"),{html:e,hasChanged:!1})});}init(){const e=this.editor;e.model.schema.register("rawHtml",{inheritAllFrom:"$blockObject",allowAttributes:["value"]}),e.commands.add("htmlEmbed",new Fx(e)),this._setupConversion();}_setupConversion(){const e=this.editor,t=e.t,i=e.editing.view,n=this._widgetButtonViewReferences,s=e.config.get("htmlEmbed");function o({editor:e,domElement:i,state:s,props:o}){i.textContent="";const a=i.ownerDocument;let l;if(s.isEditable){const e={isDisabled:!1,placeholder:o.textareaPlaceholder};l=r({domDocument:a,state:s,props:e}),i.append(l);}else if(s.showPreviews){const n={sanitizeHtml:o.sanitizeHtml};i.append(function({editor:e,domDocument:i,state:n,props:s}){const o=s.sanitizeHtml(n.getRawHtmlValue()),r=n.getRawHtmlValue().length>0?t("No preview available"):t("Empty snippet content"),a=ro(i,"div",{class:"ck ck-reset_all raw-html-embed__preview-placeholder"},r),l=ro(i,"div",{class:"raw-html-embed__preview-content",dir:e.locale.contentLanguageDirection}),c=i.createRange(),d=c.createContextualFragment(o.html);l.appendChild(d);const u=ro(i,"div",{class:"raw-html-embed__preview"},[a,l]);return u}({domDocument:a,state:s,props:n,editor:e}));}else {const e={isDisabled:!0,placeholder:o.textareaPlaceholder};i.append(r({domDocument:a,state:s,props:e}));}const c={onEditClick:o.onEditClick,onSaveClick:()=>{o.onSaveClick(l.value);},onCancelClick:o.onCancelClick};i.prepend(function({editor:e,domDocument:t,state:i,props:s}){const o=ro(t,"div",{class:"raw-html-embed__buttons-wrapper"});if(i.isEditable){const t=zx(e,"save",s.onSaveClick),i=zx(e,"cancel",s.onCancelClick);o.append(t.element,i.element),n.add(t).add(i);}else {const t=zx(e,"edit",s.onEditClick);o.append(t.element),n.add(t);}return o}({editor:e,domDocument:a,state:s,props:c}));}function r({domDocument:e,state:t,props:i}){const n=ro(e,"textarea",{placeholder:i.placeholder,class:"ck ck-reset ck-input ck-input-text raw-html-embed__source"});return n.disabled=i.isDisabled,n.value=t.getRawHtmlValue(),n}this.editor.editing.view.on("render",(()=>{for(const e of n){if(e.element&&e.element.isConnected)return;e.destroy(),n.delete(e);}}),{priority:"lowest"}),e.data.registerRawContentMatcher({name:"div",classes:"raw-html-embed"}),e.conversion.for("upcast").elementToElement({view:{name:"div",classes:"raw-html-embed"},model:(e,{writer:t})=>t.createElement("rawHtml",{value:e.getCustomProperty("$rawContent")})}),e.conversion.for("dataDowncast").elementToElement({model:"rawHtml",view:(e,{writer:t})=>t.createRawElement("div",{class:"raw-html-embed"},(function(t){t.innerHTML=e.getAttribute("value")||"";}))}),e.conversion.for("editingDowncast").elementToStructure({model:{name:"rawHtml",attributes:["value"]},view:(n,{writer:r})=>{let a,l,c;const d=r.createRawElement("div",{class:"raw-html-embed__content-wrapper"},(function(t){a=t,o({editor:e,domElement:t,state:l,props:c}),a.addEventListener("mousedown",(()=>{if(l.isEditable){const t=e.model;t.document.selection.getSelectedElement()!==n&&t.change((e=>e.setSelection(n,"on")));}}),!0);})),u={makeEditable(){l=Object.assign({},l,{isEditable:!0}),o({domElement:a,editor:e,state:l,props:c}),i.change((e=>{e.setAttribute("data-cke-ignore-events","true",d);})),a.querySelector("textarea").focus();},save(t){t!==l.getRawHtmlValue()?(e.execute("htmlEmbed",t),e.editing.view.focus()):this.cancel();},cancel(){l=Object.assign({},l,{isEditable:!1}),o({domElement:a,editor:e,state:l,props:c}),e.editing.view.focus(),i.change((e=>{e.removeAttribute("data-cke-ignore-events",d);}));}};l={showPreviews:s.showPreviews,isEditable:!1,getRawHtmlValue:()=>n.getAttribute("value")||""},c={sanitizeHtml:s.sanitizeHtml,textareaPlaceholder:t("Paste raw HTML here..."),onEditClick(){u.makeEditable();},onSaveClick(e){u.save(e);},onCancelClick(){u.cancel();}};const h=r.createContainerElement("div",{class:"raw-html-embed","data-html-embed-label":t("HTML snippet"),dir:e.locale.uiLanguageDirection},d);return r.setCustomProperty("rawHtmlApi",u,h),r.setCustomProperty("rawHtml",!0,h),oy(h,r,{label:t("HTML snippet"),hasSelectionHandle:!0})}});}}function zx(e,t,i){const{t:n}=e.locale,s=new pg(e.locale),o=e.commands.get("htmlEmbed");return s.set({class:`raw-html-embed__${t}-button`,icon:vm.pencil,tooltip:!0,tooltipPosition:"rtl"===e.locale.uiLanguageDirection?"e":"w"}),s.render(),"edit"===t?(s.set({icon:vm.pencil,label:n("Edit source")}),s.bind("isEnabled").to(o)):"save"===t?(s.set({icon:vm.check,label:n("Save changes")}),s.bind("isEnabled").to(o)):s.set({icon:vm.cancel,label:n("Cancel")}),s.on("execute",i),s}class Hx extends Dr{static get pluginName(){return "HtmlEmbedUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.locale.t;e.ui.componentFactory.add("htmlEmbed",(()=>{const e=this._createButton(pg);return e.set({tooltip:!0,label:t("Insert HTML")}),e})),e.ui.componentFactory.add("menuBar:htmlEmbed",(()=>{const e=this._createButton(Rg);return e.set({label:t("HTML snippet")}),e}));}_createButton(e){const t=this.editor,i=t.commands.get("htmlEmbed"),n=new e(t.locale);return n.set({icon:vm.html}),n.bind("isEnabled").to(i,"isEnabled"),this.listenTo(n,"execute",(()=>{t.execute("htmlEmbed"),t.editing.view.focus();t.editing.view.document.selection.getSelectedElement().getCustomProperty("rawHtmlApi").makeEditable();})),n}}class $x extends Dr{static get requires(){return [Dx,Hx,Ty]}static get pluginName(){return "HtmlEmbed"}static get isOfficialPlugin(){return !0}}function Ux(e,t,i,n){t&&function(e,t,i){if(t.attributes)for(const[n]of Object.entries(t.attributes))e.removeAttribute(n,i);if(t.styles)for(const n of Object.keys(t.styles))e.removeStyle(n,i);t.classes&&e.removeClass(t.classes,i);}(e,t,n),i&&Wx(e,i,n);}function Wx(e,t,i){if(t.attributes)for(const[n,s]of Object.entries(t.attributes))e.setAttribute(n,s,i);t.styles&&e.setStyle(t.styles,i),t.classes&&e.addClass(t.classes,i);}function jx(e,t,i,n,s){const o=t.getAttribute(i),r={};for(const e of ["attributes","styles","classes"]){if(e!=n){o&&o[e]&&(r[e]=o[e]);continue}if("classes"==n){const t=new Set(o&&o.classes||[]);s(t),t.size&&(r[e]=Array.from(t));continue}const t=new Map(Object.entries(o&&o[e]||{}));s(t),t.size&&(r[e]=Object.fromEntries(t));}Object.keys(r).length?t.is("documentSelection")?e.setSelectionAttribute(i,r):e.setAttribute(i,r,t):o&&(t.is("documentSelection")?e.removeSelectionAttribute(i):e.removeAttribute(i,t));}function qx(e){return `html${t=e,Hs(t).replace(/ /g,"")}Attributes`;var t;}function Gx({model:e}){return (t,i)=>i.writer.createElement(e,{htmlContent:t.getCustomProperty("$rawContent")})}function Kx(e,{view:t,isInline:i}){const n=e.t;return (e,{writer:s})=>{const o=n("HTML object"),r=Zx(t,e,s),a=e.getAttribute(qx(t));s.addClass("html-object-embed__content",r),a&&Wx(s,a,r);return oy(s.createContainerElement(i?"span":"div",{class:"html-object-embed","data-html-object-embed-label":o},r),s,{label:o})}}function Zx(e,t,i){return i.createRawElement(e,null,((e,i)=>{i.setContentOf(e,t.getAttribute("htmlContent"));}))}function Jx({view:e,model:t,allowEmpty:i},n){return t=>{t.on(`element:${e}`,((e,t,o)=>{let r=n.processViewAttributes(t.viewItem,o);if(r||o.consumable.test(t.viewItem,{name:!0})){if(r=r||{},o.consumable.consume(t.viewItem,{name:!0}),t.modelRange||(t=Object.assign(t,o.convertChildren(t.viewItem,t.modelCursor))),i&&t.modelRange.isCollapsed&&Object.keys(r).length){const e=o.writer.createElement("htmlEmptyElement");if(!o.safeInsert(e,t.modelCursor))return;const i=o.getSplitParts(e);return t.modelRange=o.writer.createRange(t.modelRange.start,o.writer.createPositionAfter(i[i.length-1])),o.updateConversionResult(e,t),void s(e,r,o)}for(const e of t.modelRange.getItems())s(e,r,o);}}),{priority:"low"});};function s(e,i,n){if(n.schema.checkAttribute(e,t)){const s=function(e,t){const i=Un(e);let n="attributes";for(n in t)i[n]="classes"==n?Array.from(new Set([...e[n]||[],...t[n]])):{...e[n],...t[n]};return i}(i,e.getAttribute(t)||{});n.writer.setAttribute(t,s,e);}}}function Qx({model:e,view:t},i){return (n,{writer:s,consumable:o})=>{if(!n.hasAttribute(e))return null;const r=s.createContainerElement(t),a=n.getAttribute(e);return o.consume(n,`attribute:${e}`),Wx(s,a,r),r.getFillerOffset=()=>null,i?oy(r,s):r}}function Yx({priority:e,view:t}){return (i,n)=>{if(!i)return;const{writer:s}=n,o=s.createAttributeElement(t,null,{priority:e});return Wx(s,i,o),o}}function Xx({view:e},t){return i=>{i.on(`element:${e}`,((e,i,n)=>{if(!i.modelRange||i.modelRange.isCollapsed)return;const s=t.processViewAttributes(i.viewItem,n);s&&n.writer.setAttribute(qx(i.viewItem.name),s,i.modelRange);}),{priority:"low"});}}function eA({view:e,model:t}){return i=>{i.on(`attribute:${qx(e)}:${t}`,((e,t,i)=>{if(!i.consumable.consume(t.item,e.name))return;const{attributeOldValue:n,attributeNewValue:s}=t;Ux(i.writer,n,s,i.mapper.toViewElement(t.item));}));}}var tA=[{model:"codeBlock",view:"pre"},{model:"paragraph",view:"p"},{model:"blockQuote",view:"blockquote"},{model:"listItem",view:"li"},{model:"pageBreak",view:"div"},{model:"rawHtml",view:"div"},{model:"table",view:"table"},{model:"tableRow",view:"tr"},{model:"tableCell",view:"td"},{model:"tableCell",view:"th"},{model:"tableColumnGroup",view:"colgroup"},{model:"tableColumn",view:"col"},{model:"caption",view:"caption"},{model:"caption",view:"figcaption"},{model:"imageBlock",view:"img"},{model:"imageInline",view:"img"},{model:"htmlP",view:"p",modelSchema:{inheritAllFrom:"$block"}},{model:"htmlBlockquote",view:"blockquote",modelSchema:{inheritAllFrom:"$container"}},{model:"htmlTable",view:"table",modelSchema:{allowWhere:"$block",isBlock:!0}},{model:"htmlTbody",view:"tbody",modelSchema:{allowIn:"htmlTable",isBlock:!1}},{model:"htmlThead",view:"thead",modelSchema:{allowIn:"htmlTable",isBlock:!1}},{model:"htmlTfoot",view:"tfoot",modelSchema:{allowIn:"htmlTable",isBlock:!1}},{model:"htmlCaption",view:"caption",modelSchema:{allowIn:"htmlTable",allowChildren:"$text",isBlock:!1}},{model:"htmlColgroup",view:"colgroup",modelSchema:{allowIn:"htmlTable",allowChildren:"col",isBlock:!1}},{model:"htmlCol",view:"col",modelSchema:{allowIn:"htmlColgroup",isBlock:!1}},{model:"htmlTr",view:"tr",modelSchema:{allowIn:["htmlTable","htmlThead","htmlTbody"],isLimit:!0}},{model:"htmlTd",view:"td",modelSchema:{allowIn:"htmlTr",allowContentOf:"$container",isLimit:!0,isBlock:!1}},{model:"htmlTh",view:"th",modelSchema:{allowIn:"htmlTr",allowContentOf:"$container",isLimit:!0,isBlock:!1}},{model:"htmlFigure",view:"figure",modelSchema:{inheritAllFrom:"$container",isBlock:!1}},{model:"htmlFigcaption",view:"figcaption",modelSchema:{allowIn:"htmlFigure",allowChildren:"$text",isBlock:!1}},{model:"htmlAddress",view:"address",modelSchema:{inheritAllFrom:"$container",isBlock:!1}},{model:"htmlAside",view:"aside",modelSchema:{inheritAllFrom:"$container",isBlock:!1}},{model:"htmlMain",view:"main",modelSchema:{inheritAllFrom:"$container",isBlock:!1}},{model:"htmlDetails",view:"details",modelSchema:{inheritAllFrom:"$container",isBlock:!1}},{model:"htmlSummary",view:"summary",modelSchema:{allowChildren:["htmlH1","htmlH2","htmlH3","htmlH4","htmlH5","htmlH6","$text"],allowIn:"htmlDetails",isBlock:!1}},{model:"htmlDiv",view:"div",paragraphLikeModel:"htmlDivParagraph",modelSchema:{inheritAllFrom:"$container"}},{model:"htmlFieldset",view:"fieldset",modelSchema:{inheritAllFrom:"$container",isBlock:!1}},{model:"htmlLegend",view:"legend",modelSchema:{allowIn:"htmlFieldset",allowChildren:"$text"}},{model:"htmlHeader",view:"header",modelSchema:{inheritAllFrom:"$container",isBlock:!1}},{model:"htmlFooter",view:"footer",modelSchema:{inheritAllFrom:"$container",isBlock:!1}},{model:"htmlForm",view:"form",modelSchema:{inheritAllFrom:"$container",isBlock:!0}},{model:"htmlHgroup",view:"hgroup",modelSchema:{allowIn:["$root","$container"],allowChildren:["paragraph","htmlP","htmlH1","htmlH2","htmlH3","htmlH4","htmlH5","htmlH6"],isBlock:!1}},{model:"htmlH1",view:"h1",modelSchema:{inheritAllFrom:"$block"}},{model:"htmlH2",view:"h2",modelSchema:{inheritAllFrom:"$block"}},{model:"htmlH3",view:"h3",modelSchema:{inheritAllFrom:"$block"}},{model:"htmlH4",view:"h4",modelSchema:{inheritAllFrom:"$block"}},{model:"htmlH5",view:"h5",modelSchema:{inheritAllFrom:"$block"}},{model:"htmlH6",view:"h6",modelSchema:{inheritAllFrom:"$block"}},{model:"$htmlList",modelSchema:{allowWhere:"$container",allowChildren:["$htmlList","htmlLi"],isBlock:!1}},{model:"htmlDir",view:"dir",modelSchema:{inheritAllFrom:"$htmlList"}},{model:"htmlMenu",view:"menu",modelSchema:{inheritAllFrom:"$htmlList"}},{model:"htmlUl",view:"ul",modelSchema:{inheritAllFrom:"$htmlList"}},{model:"htmlOl",view:"ol",modelSchema:{inheritAllFrom:"$htmlList"}},{model:"htmlLi",view:"li",modelSchema:{allowIn:"$htmlList",allowChildren:"$text",isBlock:!1}},{model:"htmlPre",view:"pre",modelSchema:{inheritAllFrom:"$block"}},{model:"htmlArticle",view:"article",modelSchema:{inheritAllFrom:"$container",isBlock:!1}},{model:"htmlSection",view:"section",modelSchema:{inheritAllFrom:"$container",isBlock:!1}},{model:"htmlNav",view:"nav",modelSchema:{inheritAllFrom:"$container",isBlock:!1}},{model:"htmlDivDl",view:"div",modelSchema:{allowChildren:["htmlDt","htmlDd"],allowIn:"htmlDl"}},{model:"htmlDl",view:"dl",modelSchema:{allowWhere:"$container",allowChildren:["htmlDt","htmlDd","htmlDivDl"],isBlock:!1}},{model:"htmlDt",view:"dt",modelSchema:{allowChildren:"$block",isBlock:!1}},{model:"htmlDd",view:"dd",modelSchema:{allowChildren:"$block",isBlock:!1}},{model:"htmlCenter",view:"center",modelSchema:{inheritAllFrom:"$container",isBlock:!1}}],iA=[{model:"htmlLiAttributes",view:"li",appliesToBlock:!0,coupledAttribute:"listItemId"},{model:"htmlOlAttributes",view:"ol",appliesToBlock:!0,coupledAttribute:"listItemId"},{model:"htmlUlAttributes",view:"ul",appliesToBlock:!0,coupledAttribute:"listItemId"},{model:"htmlFigureAttributes",view:"figure",appliesToBlock:"table"},{model:"htmlTheadAttributes",view:"thead",appliesToBlock:"table"},{model:"htmlTbodyAttributes",view:"tbody",appliesToBlock:"table"},{model:"htmlFigureAttributes",view:"figure",appliesToBlock:"imageBlock"},{model:"htmlAcronym",view:"acronym",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlTt",view:"tt",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlFont",view:"font",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlTime",view:"time",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlVar",view:"var",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlBig",view:"big",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlSmall",view:"small",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlSamp",view:"samp",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlQ",view:"q",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlOutput",view:"output",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlKbd",view:"kbd",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlBdi",view:"bdi",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlBdo",view:"bdo",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlAbbr",view:"abbr",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlA",view:"a",priority:5,coupledAttribute:"linkHref"},{model:"htmlStrong",view:"strong",coupledAttribute:"bold",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlB",view:"b",coupledAttribute:"bold",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlI",view:"i",coupledAttribute:"italic",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlEm",view:"em",coupledAttribute:"italic",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlS",view:"s",coupledAttribute:"strikethrough",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlDel",view:"del",coupledAttribute:"strikethrough",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlIns",view:"ins",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlU",view:"u",coupledAttribute:"underline",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlSub",view:"sub",coupledAttribute:"subscript",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlSup",view:"sup",coupledAttribute:"superscript",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlCode",view:"code",coupledAttribute:"code",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlMark",view:"mark",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlSpan",view:"span",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlCite",view:"cite",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlLabel",view:"label",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlDfn",view:"dfn",attributeProperties:{copyOnEnter:!0,isFormatting:!0}},{model:"htmlObject",view:"object",isObject:!0,modelSchema:{inheritAllFrom:"$inlineObject"}},{model:"htmlIframe",view:"iframe",isObject:!0,modelSchema:{inheritAllFrom:"$inlineObject"}},{model:"htmlInput",view:"input",isObject:!0,modelSchema:{inheritAllFrom:"$inlineObject"}},{model:"htmlButton",view:"button",isObject:!0,modelSchema:{inheritAllFrom:"$inlineObject"}},{model:"htmlTextarea",view:"textarea",isObject:!0,modelSchema:{inheritAllFrom:"$inlineObject"}},{model:"htmlSelect",view:"select",isObject:!0,modelSchema:{inheritAllFrom:"$inlineObject"}},{model:"htmlVideo",view:"video",isObject:!0,modelSchema:{inheritAllFrom:"$inlineObject"}},{model:"htmlEmbed",view:"embed",isObject:!0,modelSchema:{inheritAllFrom:"$inlineObject"}},{model:"htmlOembed",view:"oembed",isObject:!0,modelSchema:{inheritAllFrom:"$inlineObject"}},{model:"htmlAudio",view:"audio",isObject:!0,modelSchema:{inheritAllFrom:"$inlineObject"}},{model:"htmlImg",view:"img",isObject:!0,modelSchema:{inheritAllFrom:"$inlineObject"}},{model:"htmlCanvas",view:"canvas",isObject:!0,modelSchema:{inheritAllFrom:"$inlineObject"}},{model:"htmlMeter",view:"meter",isObject:!0,modelSchema:{inheritAllFrom:"$inlineObject"}},{model:"htmlProgress",view:"progress",isObject:!0,modelSchema:{inheritAllFrom:"$inlineObject"}},{model:"htmlScript",view:"script",modelSchema:{allowWhere:["$text","$block"],isInline:!0}},{model:"htmlStyle",view:"style",modelSchema:{allowWhere:["$text","$block"],isInline:!0}},{model:"htmlCustomElement",view:"$customElement",modelSchema:{allowWhere:["$text","$block"],allowAttributesOf:"$inlineObject",isInline:!0}}];class nA extends Dr{_definitions=[];static get pluginName(){return "DataSchema"}static get isOfficialPlugin(){return !0}init(){for(const e of tA)this.registerBlockElement(e);for(const e of iA)this.registerInlineElement(e);}registerBlockElement(e){this._definitions.push({...e,isBlock:!0});}registerInlineElement(e){this._definitions.push({...e,isInline:!0});}extendBlockElement(e){this._extendDefinition({...e,isBlock:!0});}extendInlineElement(e){this._extendDefinition({...e,isInline:!0});}getDefinitionsForView(e,t=!1){const i=new Set;for(const n of this._getMatchingViewDefinitions(e)){if(t)for(const e of this._getReferences(n.model))i.add(e);i.add(n);}return i}getDefinitionsForModel(e){return this._definitions.filter((t=>t.model==e))}_getMatchingViewDefinitions(e){return this._definitions.filter((t=>t.view&&function(e,t){if("string"==typeof e)return e===t;if(e instanceof RegExp)return e.test(t);return !1}(e,t.view)))}*_getReferences(e){const t=["inheritAllFrom","inheritTypesFrom","allowWhere","allowContentOf","allowAttributesOf"],i=this._definitions.filter((t=>t.model==e));for(const{modelSchema:n}of i)if(n)for(const i of t)for(const t of gr(n[i]||[])){const i=this._definitions.filter((e=>e.model==t));for(const n of i)t!==e&&(yield*this._getReferences(n.model),yield n);}}_extendDefinition(e){const t=Array.from(this._definitions.entries()).filter((([,t])=>t.model==e.model));if(0!=t.length)for(const[i,n]of t)this._definitions[i]=As({},n,e,((e,t)=>Array.isArray(e)?e.concat(t):void 0));else this._definitions.push(e);}}class sA extends Dr{_dataSchema;_allowedAttributes;_disallowedAttributes;_allowedElements;_disallowedElements;_dataInitialized;_coupledAttributes;constructor(e){super(e),this._dataSchema=e.plugins.get("DataSchema"),this._allowedAttributes=new aa,this._disallowedAttributes=new aa,this._allowedElements=new Set,this._disallowedElements=new Set,this._dataInitialized=!1,this._coupledAttributes=null,this._registerElementsAfterInit(),this._registerElementHandlers(),this._registerCoupledAttributesPostFixer(),this._registerAssociatedHtmlAttributesPostFixer();}static get pluginName(){return "DataFilter"}static get isOfficialPlugin(){return !0}static get requires(){return [nA,Ty]}loadAllowedConfig(e){for(const t of e){const e=t.name||/[\s\S]+/,i=cA(t);this.allowElement(e),i.forEach((e=>this.allowAttributes(e)));}}loadDisallowedConfig(e){for(const t of e){const e=t.name||/[\s\S]+/,i=cA(t);0==i.length?this.disallowElement(e):i.forEach((e=>this.disallowAttributes(e)));}}loadAllowedEmptyElementsConfig(e){for(const t of e)this.allowEmptyElement(t);}allowElement(e){for(const t of this._dataSchema.getDefinitionsForView(e,!0))this._addAllowedElement(t),this._coupledAttributes=null;}disallowElement(e){for(const t of this._dataSchema.getDefinitionsForView(e,!1))this._disallowedElements.add(t.view);}allowEmptyElement(e){for(const t of this._dataSchema.getDefinitionsForView(e,!0))t.isInline&&this._dataSchema.extendInlineElement({...t,allowEmpty:!0});}allowAttributes(e){this._allowedAttributes.add(e);}disallowAttributes(e){this._disallowedAttributes.add(e);}processViewAttributes(e,t){const{consumable:i}=t;return oA(e,this._disallowedAttributes,i),function(e,{attributes:t,classes:i,styles:n}){if(!t.length&&!i.length&&!n.length)return null;return {...t.length&&{attributes:rA(e,t)},...n.length&&{styles:aA(e,n)},...i.length&&{classes:i}}}(e,oA(e,this._allowedAttributes,i))}_addAllowedElement(e){if(!this._allowedElements.has(e)){if(this._allowedElements.add(e),"appliesToBlock"in e&&"string"==typeof e.appliesToBlock)for(const t of this._dataSchema.getDefinitionsForModel(e.appliesToBlock))t.isBlock&&this._addAllowedElement(t);this._dataInitialized&&this.editor.data.once("set",(()=>{this._fireRegisterEvent(e);}),{priority:C.highest+1});}}_registerElementsAfterInit(){this.editor.data.on("init",(()=>{this._dataInitialized=!0;for(const e of this._allowedElements)this._fireRegisterEvent(e);}),{priority:C.highest+1});}_registerElementHandlers(){this.on("register",((e,t)=>{const i=this.editor.model.schema;if(t.isObject&&!i.isRegistered(t.model))this._registerObjectElement(t);else if(t.isBlock)this._registerBlockElement(t);else {if(!t.isInline)throw new A("data-filter-invalid-definition",null,t);this._registerInlineElement(t);}e.stop();}),{priority:"lowest"});}_registerCoupledAttributesPostFixer(){const e=this.editor.model,t=e.document.selection;e.document.registerPostFixer((t=>{const i=e.document.differ.getChanges();let n=!1;const s=this._getCoupledAttributesMap();for(const e of i){if("attribute"!=e.type||null!==e.attributeNewValue)continue;const i=s.get(e.attributeKey);if(i)for(const{item:s}of e.range.getWalker())for(const e of i)s.hasAttribute(e)&&(t.removeAttribute(e,s),n=!0);}return n})),this.listenTo(t,"change:attribute",((i,{attributeKeys:n})=>{const s=new Set,o=this._getCoupledAttributesMap();for(const e of n){if(t.hasAttribute(e))continue;const i=o.get(e);if(i)for(const e of i)t.hasAttribute(e)&&s.add(e);}0!=s.size&&e.change((e=>{for(const t of s)e.removeSelectionAttribute(t);}));}));}_registerAssociatedHtmlAttributesPostFixer(){const e=this.editor.model;e.document.registerPostFixer((t=>{const i=e.document.differ.getChanges();let n=!1;for(const s of i)if("insert"===s.type&&"$text"!==s.name)for(const i of s.attributes.keys())i.startsWith("html")&&i.endsWith("Attributes")&&(e.schema.checkAttribute(s.name,i)||(t.removeAttribute(i,s.position.nodeAfter),n=!0));return n}));}_getCoupledAttributesMap(){if(this._coupledAttributes)return this._coupledAttributes;this._coupledAttributes=new Map;for(const e of this._allowedElements)if(e.coupledAttribute&&e.model){const t=this._coupledAttributes.get(e.coupledAttribute);t?t.push(e.model):this._coupledAttributes.set(e.coupledAttribute,[e.model]);}return this._coupledAttributes}_fireRegisterEvent(e){e.view&&this._disallowedElements.has(e.view)||this.fire(e.view?`register:${e.view}`:"register",e);}_registerObjectElement(e){const t=this.editor,i=t.model.schema,n=t.conversion,{view:s,model:o}=e;i.register(o,e.modelSchema),s&&(i.extend(e.model,{allowAttributes:[qx(s),"htmlContent"]}),t.data.registerRawContentMatcher({name:s}),n.for("upcast").elementToElement({view:s,model:Gx(e),converterPriority:C.low+2}),n.for("upcast").add(Xx(e,this)),n.for("editingDowncast").elementToStructure({model:{name:o,attributes:[qx(s)]},view:Kx(t,e)}),n.for("dataDowncast").elementToElement({model:o,view:(e,{writer:t})=>Zx(s,e,t)}),n.for("dataDowncast").add(eA(e)));}_registerBlockElement(e){const t=this.editor,i=t.model.schema,n=t.conversion,{view:s,model:o}=e;if(!i.isRegistered(e.model)){if(i.register(e.model,e.modelSchema),!s)return;n.for("upcast").elementToElement({model:o,view:s,converterPriority:C.low+2}),n.for("downcast").elementToElement({model:o,view:s});}s&&(i.extend(e.model,{allowAttributes:qx(s)}),n.for("upcast").add(Xx(e,this)),n.for("downcast").add(eA(e)));}_registerInlineElement(e){const t=this.editor,i=t.model.schema,n=t.conversion,s=e.model;e.appliesToBlock||(i.extend("$text",{allowAttributes:s}),e.attributeProperties&&i.setAttributeProperties(s,e.attributeProperties),n.for("upcast").add(Jx(e,this)),n.for("downcast").attributeToElement({model:s,view:Yx(e)}),e.allowEmpty&&(i.setAttributeProperties(s,{copyFromObject:!1}),i.isRegistered("htmlEmptyElement")||i.register("htmlEmptyElement",{inheritAllFrom:"$inlineObject"}),t.data.htmlProcessor.domConverter.registerInlineObjectMatcher((t=>t.name==e.view&&t.isEmpty&&Array.from(t.getAttributeKeys()).length?{name:!0}:null)),n.for("editingDowncast").elementToElement({model:"htmlEmptyElement",view:Qx(e,!0)}),n.for("dataDowncast").elementToElement({model:"htmlEmptyElement",view:Qx(e)})));}}function oA(e,t,i){const n=t.matchAll(e)||[],s=e.document.stylesProcessor;return n.reduce(((t,{match:n})=>{for(const o of n.styles||[]){const n=s.getRelatedStyles(o).filter((e=>e.split("-").length>o.split("-").length)).sort(((e,t)=>t.split("-").length-e.split("-").length));for(const s of n)i.consume(e,{styles:[s]})&&t.styles.push(s);i.consume(e,{styles:[o]})&&t.styles.push(o);}for(const s of n.classes||[])i.consume(e,{classes:[s]})&&t.classes.push(s);for(const s of n.attributes||[])i.consume(e,{attributes:[s]})&&t.attributes.push(s);return t}),{attributes:[],classes:[],styles:[]})}function rA(e,t){const i={};for(const n of t){const t=e.getAttribute(n);void 0!==t&&Fo(n)&&(i[n]=t);}return i}function aA(e,t){const i=new da(e.document.stylesProcessor);for(const n of t){const t=e.getStyle(n);void 0!==t&&i.set(n,t);}return Object.fromEntries(i.getStylesEntries())}function lA(e,t){const{name:i}=e,n=e[t];return ei(n)?Object.entries(n).map((([e,n])=>({name:i,[t]:{[e]:n}}))):Array.isArray(n)?n.map((e=>({name:i,[t]:[e]}))):[e]}function cA(e){const{name:t,attributes:i,classes:n,styles:s}=e,o=[];return i&&o.push(...lA({name:t,attributes:i},"attributes")),n&&o.push(...lA({name:t,classes:n},"classes")),s&&o.push(...lA({name:t,styles:s},"styles")),o}class dA extends Dr{static get requires(){return [sA]}static get pluginName(){return "CodeBlockElementSupport"}static get isOfficialPlugin(){return !0}init(){if(!this.editor.plugins.has("CodeBlockEditing"))return;const e=this.editor.plugins.get(sA);e.on("register:pre",((t,i)=>{if("codeBlock"!==i.model)return;const n=this.editor,s=n.model.schema,o=n.conversion;s.extend("codeBlock",{allowAttributes:["htmlPreAttributes","htmlContentAttributes"]}),o.for("upcast").add(function(e){return t=>{t.on("element:code",((t,i,n)=>{const s=i.viewItem,o=s.parent;function r(t,s){const o=e.processViewAttributes(t,n);o&&n.writer.setAttribute(s,o,i.modelRange);}o&&o.is("element","pre")&&(r(o,"htmlPreAttributes"),r(s,"htmlContentAttributes"));}),{priority:"low"});}}(e)),o.for("downcast").add((e=>{e.on("attribute:htmlPreAttributes:codeBlock",((e,t,i)=>{if(!i.consumable.consume(t.item,e.name))return;const{attributeOldValue:n,attributeNewValue:s}=t,o=i.mapper.toViewElement(t.item).parent;Ux(i.writer,n,s,o);})),e.on("attribute:htmlContentAttributes:codeBlock",((e,t,i)=>{if(!i.consumable.consume(t.item,e.name))return;const{attributeOldValue:n,attributeNewValue:s}=t,o=i.mapper.toViewElement(t.item);Ux(i.writer,n,s,o);}));})),t.stop();}));}}class uA extends Dr{static get requires(){return [sA]}static get pluginName(){return "DualContentModelElementSupport"}static get isOfficialPlugin(){return !0}init(){this.editor.plugins.get(sA).on("register",((e,t)=>{const i=t,n=this.editor,s=n.model.schema,o=n.conversion;if(!i.paragraphLikeModel)return;if(s.isRegistered(i.model)||s.isRegistered(i.paragraphLikeModel))return;const r={model:i.paragraphLikeModel,view:i.view};s.register(i.model,i.modelSchema),s.register(r.model,{inheritAllFrom:"$block"}),o.for("upcast").elementToElement({view:i.view,model:(e,{writer:t})=>this._hasBlockContent(e)?t.createElement(i.model):t.createElement(r.model),converterPriority:C.low+.5}),o.for("downcast").elementToElement({view:i.view,model:i.model}),this._addAttributeConversion(i),o.for("downcast").elementToElement({view:r.view,model:r.model}),this._addAttributeConversion(r),e.stop();}));}_hasBlockContent(e){const t=this.editor.editing.view,i=t.domConverter.blockElements;for(const n of t.createRangeIn(e).getItems())if(n.is("element")&&i.includes(n.name))return !0;return !1}_addAttributeConversion(e){const t=this.editor,i=t.conversion,n=t.plugins.get(sA);t.model.schema.extend(e.model,{allowAttributes:qx(e.view)}),i.for("upcast").add(Xx(e,n)),i.for("downcast").add(eA(e));}}class hA extends Dr{static get requires(){return [nA,K_]}static get pluginName(){return "HeadingElementSupport"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;if(!e.plugins.has("HeadingEditing"))return;const t=e.config.get("heading.options");this.registerHeadingElements(e,t);}registerHeadingElements(e,t){const i=e.plugins.get(nA),n=[];for(const e of t)"model"in e&&"view"in e&&(i.registerBlockElement({view:e.view,model:e.model}),n.push(e.model));i.extendBlockElement({model:"htmlHgroup",modelSchema:{allowChildren:n}}),i.extendBlockElement({model:"htmlSummary",modelSchema:{allowChildren:n}});}}function mA(e,t,i){const n=e.createRangeOn(t);for(const{item:e}of n.getWalker())if(e.is("element",i))return e}class gA extends Dr{static get requires(){return [sA]}static get pluginName(){return "ImageElementSupport"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;if(!e.plugins.has("ImageInlineEditing")&&!e.plugins.has("ImageBlockEditing"))return;const t=e.model.schema,i=e.conversion,n=e.plugins.get(sA);n.on("register:figure",(()=>{i.for("upcast").add(function(e){return t=>{t.on("element:figure",((t,i,n)=>{const s=i.viewItem;if(!i.modelRange||!s.hasClass("image"))return;const o=e.processViewAttributes(s,n);o&&n.writer.setAttribute("htmlFigureAttributes",o,i.modelRange);}),{priority:"low"});}}(n));})),n.on("register:img",((s,o)=>{"imageBlock"!==o.model&&"imageInline"!==o.model||(t.isRegistered("imageBlock")&&t.extend("imageBlock",{allowAttributes:["htmlImgAttributes","htmlFigureAttributes","htmlLinkAttributes"]}),t.isRegistered("imageInline")&&t.extend("imageInline",{allowAttributes:["htmlA","htmlImgAttributes"]}),i.for("upcast").add(function(e){return t=>{t.on("element:img",((t,i,n)=>{if(!i.modelRange)return;const s=i.viewItem,o=e.processViewAttributes(s,n);o&&n.writer.setAttribute("htmlImgAttributes",o,i.modelRange);}),{priority:"low"});}}(n)),i.for("downcast").add((e=>{function t(t){e.on(`attribute:${t}:imageInline`,((e,t,i)=>{if(!i.consumable.consume(t.item,e.name))return;const{attributeOldValue:n,attributeNewValue:s}=t,o=i.mapper.toViewElement(t.item);Ux(i.writer,n,s,o);}),{priority:"low"});}function i(t,i){e.on(`attribute:${i}:imageBlock`,((e,i,n)=>{if(!n.consumable.test(i.item,e.name))return;const{attributeOldValue:s,attributeNewValue:o}=i,r=n.mapper.toViewElement(i.item),a=mA(n.writer,r,t);a&&(Ux(n.writer,s,o,a),n.consumable.consume(i.item,e.name));}),{priority:"low"}),"a"===t&&e.on("attribute:linkHref:imageBlock",((e,t,i)=>{if(!i.consumable.consume(t.item,"attribute:htmlLinkAttributes:imageBlock"))return;const n=i.mapper.toViewElement(t.item),s=mA(i.writer,n,"a");Wx(i.writer,t.item.getAttribute("htmlLinkAttributes"),s);}),{priority:"low"});}t("htmlImgAttributes"),i("img","htmlImgAttributes"),i("figure","htmlFigureAttributes"),i("a","htmlLinkAttributes");})),e.plugins.has("LinkImage")&&i.for("upcast").add(function(e,t){const i=t.plugins.get("ImageUtils");return t=>{t.on("element:a",((t,n,s)=>{const o=n.viewItem;if(!i.findViewImgElement(o))return;const r=n.modelCursor.parent;if(!r.is("element","imageBlock"))return;const a=e.processViewAttributes(o,s);a&&s.writer.setAttribute("htmlLinkAttributes",a,r);}),{priority:"low"});}}(n,e)),s.stop());}));}}class fA extends Dr{static get requires(){return [sA]}static get pluginName(){return "MediaEmbedElementSupport"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;if(!e.plugins.has("MediaEmbed")||e.config.get("mediaEmbed.previewsInData"))return;const t=e.model.schema,i=e.conversion,n=this.editor.plugins.get(sA),s=this.editor.plugins.get(nA),o=e.config.get("mediaEmbed.elementName");s.registerBlockElement({model:"media",view:o}),n.on("register:figure",(()=>{i.for("upcast").add(function(e){return t=>{t.on("element:figure",((t,i,n)=>{const s=i.viewItem;if(!i.modelRange||!s.hasClass("media"))return;const o=e.processViewAttributes(s,n);o&&n.writer.setAttribute("htmlFigureAttributes",o,i.modelRange);}),{priority:"low"});}}(n));})),n.on(`register:${o}`,((e,s)=>{"media"===s.model&&(t.extend("media",{allowAttributes:[qx(o),"htmlFigureAttributes"]}),i.for("upcast").add(function(e,t){const i=(i,n,s)=>{function o(t,i){const o=e.processViewAttributes(t,s);o&&s.writer.setAttribute(i,o,n.modelRange);}o(n.viewItem,qx(t));};return e=>{e.on(`element:${t}`,i,{priority:"low"});}}(n,o)),i.for("dataDowncast").add(function(e){return t=>{function i(e,i){t.on(`attribute:${i}:media`,((t,i,n)=>{if(!n.consumable.consume(i.item,t.name))return;const{attributeOldValue:s,attributeNewValue:o}=i,r=n.mapper.toViewElement(i.item),a=mA(n.writer,r,e);Ux(n.writer,s,o,a);}));}i(e,qx(e)),i("figure","htmlFigureAttributes");}}(o)),e.stop());}));}}class pA extends Dr{static get requires(){return [sA]}static get pluginName(){return "ScriptElementSupport"}static get isOfficialPlugin(){return !0}init(){const e=this.editor.plugins.get(sA);e.on("register:script",((t,i)=>{const n=this.editor,s=n.model.schema,o=n.conversion;s.register("htmlScript",i.modelSchema),s.extend("htmlScript",{allowAttributes:["htmlScriptAttributes","htmlContent"],isContent:!0}),n.data.registerRawContentMatcher({name:"script"}),o.for("upcast").elementToElement({view:"script",model:Gx(i)}),o.for("upcast").add(Xx(i,e)),o.for("downcast").elementToElement({model:"htmlScript",view:(e,{writer:t})=>Zx("script",e,t)}),o.for("downcast").add(eA(i)),t.stop();}));}}class bA extends Dr{static get requires(){return [sA]}static get pluginName(){return "TableElementSupport"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;if(!e.plugins.has("TableEditing"))return;const t=e.model.schema,i=e.conversion,n=e.plugins.get(sA),s=e.plugins.get("TableUtils");n.on("register:figure",(()=>{i.for("upcast").add(function(e){return t=>{t.on("element:figure",((t,i,n)=>{const s=i.viewItem;if(!i.modelRange||!s.hasClass("table"))return;const o=e.processViewAttributes(s,n);o&&n.writer.setAttribute("htmlFigureAttributes",o,i.modelRange);}),{priority:"low"});}}(n));})),n.on("register:table",((o,r)=>{"table"===r.model&&(t.extend("table",{allowAttributes:["htmlTableAttributes","htmlFigureAttributes","htmlTheadAttributes","htmlTbodyAttributes"]}),i.for("upcast").add(function(e){return t=>{t.on("element:table",((t,i,n)=>{if(!i.modelRange)return;const s=i.viewItem;o(s,"htmlTableAttributes");for(const e of s.getChildren())e.is("element","thead")&&o(e,"htmlTheadAttributes"),e.is("element","tbody")&&o(e,"htmlTbodyAttributes");function o(t,s){const o=e.processViewAttributes(t,n);o&&n.writer.setAttribute(s,o,i.modelRange);}}),{priority:"low"});}}(n)),i.for("downcast").add((e=>{function t(t,i){e.on(`attribute:${i}:table`,((e,i,n)=>{if(!n.consumable.test(i.item,e.name))return;const s=n.mapper.toViewElement(i.item),o=mA(n.writer,s,t);o&&(n.consumable.consume(i.item,e.name),Ux(n.writer,i.attributeOldValue,i.attributeNewValue,o));}));}t("table","htmlTableAttributes"),t("figure","htmlFigureAttributes"),t("thead","htmlTheadAttributes"),t("tbody","htmlTbodyAttributes");})),e.model.document.registerPostFixer(function(e,t){return i=>{const n=e.document.differ.getChanges();let s=!1;for(const e of n){if("attribute"!=e.type||"headingRows"!=e.attributeKey)continue;const n=e.range.start.nodeAfter,o=n.getAttribute("htmlTheadAttributes"),r=n.getAttribute("htmlTbodyAttributes");o&&!e.attributeNewValue?(i.removeAttribute("htmlTheadAttributes",n),s=!0):r&&e.attributeNewValue==t.getRows(n)&&(i.removeAttribute("htmlTbodyAttributes",n),s=!0);}return s}}(e.model,s)),o.stop());}));}}class wA extends Dr{static get requires(){return [sA]}static get pluginName(){return "StyleElementSupport"}static get isOfficialPlugin(){return !0}init(){const e=this.editor.plugins.get(sA);e.on("register:style",((t,i)=>{const n=this.editor,s=n.model.schema,o=n.conversion;s.register("htmlStyle",i.modelSchema),s.extend("htmlStyle",{allowAttributes:["htmlStyleAttributes","htmlContent"],isContent:!0}),n.data.registerRawContentMatcher({name:"style"}),o.for("upcast").elementToElement({view:"style",model:Gx(i)}),o.for("upcast").add(Xx(i,e)),o.for("downcast").elementToElement({model:"htmlStyle",view:(e,{writer:t})=>Zx("style",e,t)}),o.for("downcast").add(eA(i)),t.stop();}));}}class _A extends Dr{static get requires(){return [sA]}static get pluginName(){return "ListElementSupport"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;if(!e.plugins.has("ListEditing"))return;const t=e.model.schema,i=e.conversion,n=e.plugins.get(sA),s=e.plugins.get("ListEditing"),o=e.plugins.get("ListUtils"),r=["ul","ol","li"];s.registerDowncastStrategy({scope:"item",attributeName:"htmlLiAttributes",setAttributeOnDowncast:Wx}),s.registerDowncastStrategy({scope:"list",attributeName:"htmlUlAttributes",setAttributeOnDowncast:Wx}),s.registerDowncastStrategy({scope:"list",attributeName:"htmlOlAttributes",setAttributeOnDowncast:Wx}),n.on("register",((e,s)=>{if(!r.includes(s.view))return;if(e.stop(),t.checkAttribute("$block","htmlLiAttributes"))return;const o=r.map((e=>qx(e)));t.extend("$listItem",{allowAttributes:o}),i.for("upcast").add((e=>{e.on("element:ul",vA("htmlUlAttributes",n),{priority:"low"}),e.on("element:ol",vA("htmlOlAttributes",n),{priority:"low"}),e.on("element:li",vA("htmlLiAttributes",n),{priority:"low"});}));})),s.on("postFixer",((e,{listNodes:t,writer:i})=>{for(const{node:n,previousNodeInList:s}of t)if(s){if(s.getAttribute("listType")==n.getAttribute("listType")){const t=yA(s.getAttribute("listType")),o=s.getAttribute(t);!Ls(n.getAttribute(t),o)&&i.model.schema.checkAttribute(n,t)&&(i.setAttribute(t,o,n),e.return=!0);}if(s.getAttribute("listItemId")==n.getAttribute("listItemId")){const t=s.getAttribute("htmlLiAttributes");!Ls(n.getAttribute("htmlLiAttributes"),t)&&i.model.schema.checkAttribute(n,"htmlLiAttributes")&&(i.setAttribute("htmlLiAttributes",t,n),e.return=!0);}}})),s.on("postFixer",((e,{listNodes:t,writer:i})=>{for(const{node:n}of t){const t=n.getAttribute("listType");!o.isNumberedListType(t)&&n.getAttribute("htmlOlAttributes")&&(i.removeAttribute("htmlOlAttributes",n),e.return=!0),o.isNumberedListType(t)&&n.getAttribute("htmlUlAttributes")&&(i.removeAttribute("htmlUlAttributes",n),e.return=!0);}}));}afterInit(){const e=this.editor;if(!e.commands.get("indentList"))return;const t=e.commands.get("indentList");this.listenTo(t,"afterExecute",((t,i)=>{e.model.change((t=>{for(const n of i){const i=yA(n.getAttribute("listType"));e.model.schema.checkAttribute(n,i)&&t.setAttribute(i,{},n);}}));}));}}function vA(e,t){return (i,n,s)=>{const o=n.viewItem;n.modelRange||Object.assign(n,s.convertChildren(n.viewItem,n.modelCursor));const r=t.processViewAttributes(o,s);for(const t of n.modelRange.getItems({shallow:!0}))t.hasAttribute("listItemId")&&(t.hasAttribute("htmlUlAttributes")||t.hasAttribute("htmlOlAttributes")||s.writer.model.schema.checkAttribute(t,e)&&s.writer.setAttribute(e,r||{},t));}}function yA(e){return "numbered"===e||"customNumbered"==e?"htmlOlAttributes":"htmlUlAttributes"}class kA extends Dr{static get requires(){return [sA,nA]}static get pluginName(){return "CustomElementSupport"}static get isOfficialPlugin(){return !0}init(){const e=this.editor.plugins.get(sA),t=this.editor.plugins.get(nA);e.on("register:$customElement",((i,n)=>{i.stop();const s=this.editor,o=s.model.schema,r=s.conversion,a=s.editing.view.domConverter.unsafeElements,l=s.data.htmlProcessor.domConverter.preElements;o.register(n.model,n.modelSchema),o.extend(n.model,{allowAttributes:["htmlElementName","htmlCustomElementAttributes","htmlContent"],isContent:!0}),s.data.htmlProcessor.domConverter.registerRawContentMatcher({name:"template"}),r.for("upcast").elementToElement({view:/.*/,model:(i,o)=>{if("$comment"==i.name)return null;if(!function(e){try{document.createElement(e);}catch(e){return !1}return !0}(i.name))return null;if(t.getDefinitionsForView(i.name).size)return null;a.includes(i.name)||a.push(i.name),l.includes(i.name)||l.push(i.name);const r=o.writer.createElement(n.model,{htmlElementName:i.name}),c=e.processViewAttributes(i,o);let d;if(c&&o.writer.setAttribute("htmlCustomElementAttributes",c,r),i.is("element","template")&&i.getCustomProperty("$rawContent"))d=i.getCustomProperty("$rawContent");else {const e=new ju(i.document).createDocumentFragment(i),t=s.data.htmlProcessor.domConverter.viewToDom(e),n=t.firstChild;for(;n.firstChild;)t.appendChild(n.firstChild);n.remove(),d=s.data.htmlProcessor.htmlWriter.getHtml(t);}o.writer.setAttribute("htmlContent",d,r);for(const{item:e}of s.editing.view.createRangeIn(i))o.consumable.consume(e,{name:!0});return r},converterPriority:"low"}),r.for("editingDowncast").elementToElement({model:{name:n.model,attributes:["htmlElementName","htmlCustomElementAttributes","htmlContent"]},view:(e,{writer:t})=>{const i=e.getAttribute("htmlElementName"),n=t.createRawElement(i);return e.hasAttribute("htmlCustomElementAttributes")&&Wx(t,e.getAttribute("htmlCustomElementAttributes"),n),n}}),r.for("dataDowncast").elementToElement({model:{name:n.model,attributes:["htmlElementName","htmlCustomElementAttributes","htmlContent"]},view:(e,{writer:t})=>{const i=e.getAttribute("htmlElementName"),n=e.getAttribute("htmlContent"),s=t.createRawElement(i,null,((e,t)=>{t.setContentOf(e,n);}));return e.hasAttribute("htmlCustomElementAttributes")&&Wx(t,e.getAttribute("htmlCustomElementAttributes"),s),s}});}));}}class CA extends Dr{static get pluginName(){return "GeneralHtmlSupport"}static get isOfficialPlugin(){return !0}static get requires(){return [sA,dA,uA,hA,gA,fA,pA,bA,wA,_A,kA]}init(){const e=this.editor,t=e.plugins.get(sA);t.loadAllowedEmptyElementsConfig(e.config.get("htmlSupport.allowEmpty")||[]),t.loadAllowedConfig(e.config.get("htmlSupport.allow")||[]),t.loadDisallowedConfig(e.config.get("htmlSupport.disallow")||[]);}getGhsAttributeNameForElement(e){const t=this.editor.plugins.get("DataSchema"),i=Array.from(t.getDefinitionsForView(e,!1)),n=i.find((e=>e.isInline&&!i[0].isObject));return n?n.model:qx(e)}addModelHtmlClass(e,t,i){const n=this.editor.model,s=this.getGhsAttributeNameForElement(e);n.change((e=>{for(const o of xA(n,i,s))jx(e,o,s,"classes",(e=>{for(const i of gr(t))e.add(i);}));}));}removeModelHtmlClass(e,t,i){const n=this.editor.model,s=this.getGhsAttributeNameForElement(e);n.change((e=>{for(const o of xA(n,i,s))jx(e,o,s,"classes",(e=>{for(const i of gr(t))e.delete(i);}));}));}setModelHtmlAttributes(e,t,i){const n=this.editor.model,s=this.getGhsAttributeNameForElement(e);n.change((e=>{for(const o of xA(n,i,s))jx(e,o,s,"attributes",(e=>{for(const[i,n]of Object.entries(t))e.set(i,n);}));}));}removeModelHtmlAttributes(e,t,i){const n=this.editor.model,s=this.getGhsAttributeNameForElement(e);n.change((e=>{for(const o of xA(n,i,s))jx(e,o,s,"attributes",(e=>{for(const i of gr(t))e.delete(i);}));}));}setModelHtmlStyles(e,t,i){const n=this.editor.model,s=this.getGhsAttributeNameForElement(e);n.change((e=>{for(const o of xA(n,i,s))jx(e,o,s,"styles",(e=>{for(const[i,n]of Object.entries(t))e.set(i,n);}));}));}removeModelHtmlStyles(e,t,i){const n=this.editor.model,s=this.getGhsAttributeNameForElement(e);n.change((e=>{for(const o of xA(n,i,s))jx(e,o,s,"styles",(e=>{for(const i of gr(t))e.delete(i);}));}));}}function*xA(e,t,i){if(t)if(!(Symbol.iterator in t)&&t.is("documentSelection")&&t.isCollapsed)e.schema.checkAttributeInSelection(t,i)&&(yield t);else for(const n of function(e,t,i){return !(Symbol.iterator in t)&&(t.is("node")||t.is("$text")||t.is("$textProxy"))?e.schema.checkAttribute(t,i)?[e.createRangeOn(t)]:[]:e.schema.getValidRanges(e.createSelection(t).getRanges(),i)}(e,t,i))yield*n.getItems({shallow:!0});}class AA extends Dr{static get pluginName(){return "HtmlComment"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=new Map;e.data.processor.skipComments=!1,e.model.schema.addAttributeCheck(((e,t)=>{if(e.endsWith("$root")&&t.startsWith("$comment"))return !0})),e.conversion.for("upcast").elementToMarker({view:"$comment",model:e=>{const i=`$comment:${k()}`,n=e.getCustomProperty("$rawContent");return t.set(i,n),i}}),e.conversion.for("dataDowncast").markerToElement({model:"$comment",view:(e,{writer:t})=>{let i;for(const t of this.editor.model.document.getRootNames())if(i=this.editor.model.document.getRoot(t),i.hasAttribute(e.markerName))break;const n=e.markerName,s=i.getAttribute(n),o=t.createUIElement("$comment");return t.setCustomProperty("$rawContent",s,o),o}}),e.model.document.registerPostFixer((i=>{let n=!1;const s=e.model.document.differ.getChangedMarkers().filter((e=>e.name.startsWith("$comment:")));for(const e of s){const{oldRange:s,newRange:o}=e.data;if(!s||!o||s.root!=o.root){if(s){const t=s.root;t.hasAttribute(e.name)&&(i.removeAttribute(e.name,t),n=!0);}if(o){const s=o.root;"$graveyard"==s.rootName?(i.removeMarker(e.name),n=!0):s.hasAttribute(e.name)||(i.setAttribute(e.name,t.get(e.name)||"",s),n=!0);}}}return n})),e.data.on("set",(()=>{for(const t of e.model.markers.getMarkersGroup("$comment"))this.removeHtmlComment(t.name);}),{priority:"high"}),e.model.on("deleteContent",((t,[i])=>{for(const t of i.getRanges()){const i=e.model.schema.getLimitElement(t),n=e.model.createPositionAt(i,0),s=e.model.createPositionAt(i,"end");let o;o=n.isTouching(t.start)&&s.isTouching(t.end)?this.getHtmlCommentsInRange(e.model.createRange(n,s)):this.getHtmlCommentsInRange(t,{skipBoundaries:!0});for(const e of o)this.removeHtmlComment(e);}}),{priority:"high"});}createHtmlComment(e,t){const i=k(),n=this.editor.model,s=n.document.getRoot(e.root.rootName),o=`$comment:${i}`;return n.change((i=>{const n=i.createRange(e);return i.addMarker(o,{usingOperation:!0,affectsData:!0,range:n}),i.setAttribute(o,t,s),o}))}removeHtmlComment(e){const t=this.editor,i=t.model.markers.get(e);return !!i&&(t.model.change((e=>{e.removeMarker(i);})),!0)}getHtmlCommentData(e){const t=this.editor.model.markers.get(e);if(!t)return null;let i="";for(const t of this.editor.model.document.getRoots())if(t.hasAttribute(e)){i=t.getAttribute(e);break}return {content:i,position:t.getStart()}}getHtmlCommentsInRange(e,{skipBoundaries:t=!1}={}){const i=!t;return Array.from(this.editor.model.markers.getMarkersGroup("$comment")).filter((t=>function(e,t){const n=e.getRange().start;return (n.isAfter(t.start)||i&&n.isEqual(t.start))&&(n.isBefore(t.end)||i&&n.isEqual(t.end))}(t,e))).map((e=>e.name))}}class EA extends vd{toView(e){if(!/<(?:html|body|head|meta)(?:\s[^>]*)?>/i.test(e.trim().slice(0,1e4)))return super.toView(e);let t="",i="";e=(e=e.trim().replace(/<\?xml\s[^?]*\?>/i,(e=>(i=e,"")))).trim().replace(/^]*?>/i,(e=>(t=e,"")));const n=this._toDom(e),s=this.domConverter.domToView(n,{skipComments:this.skipComments}),o=new ju(s.document);return o.setCustomProperty("$fullPageDocument",n.ownerDocument.documentElement.outerHTML,s),t&&o.setCustomProperty("$fullPageDocType",t,s),i&&o.setCustomProperty("$fullPageXmlDeclaration",i,s),s}toData(e){let t=super.toData(e);const i=e.getCustomProperty("$fullPageDocument"),n=e.getCustomProperty("$fullPageDocType"),s=e.getCustomProperty("$fullPageXmlDeclaration");return i&&(t=i.replace(/<\/body\s*>/,t+"$&"),n&&(t=n+"\n"+t),s&&(t=s+"\n"+t)),t}}class TA extends Dr{static get pluginName(){return "FullPage"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=["$fullPageDocument","$fullPageDocType","$fullPageXmlDeclaration"];e.data.processor=new EA(e.data.viewDocument),e.model.schema.extend("$root",{allowAttributes:t}),e.data.on("toModel",((i,[n])=>{const s=e.model.document.getRoot();e.model.change((e=>{for(const i of t){const t=n.getCustomProperty(i);t&&e.setAttribute(i,t,s);}}));}),{priority:"low"}),e.data.on("toView",((e,[i])=>{if(!i.is("rootElement"))return;const n=i,s=e.return;if(!n.hasAttribute("$fullPageDocument"))return;const o=new ju(s.document);for(const e of t){const t=n.getAttribute(e);t&&o.setCustomProperty(e,t,s);}}),{priority:"low"}),e.data.on("set",(()=>{const i=e.model.document.getRoot();e.model.change((e=>{for(const n of t)i.hasAttribute(n)&&e.removeAttribute(n,i);}));}),{priority:"high"}),e.data.on("get",((e,t)=>{t[0]||(t[0]={}),t[0].trim=!1;}),{priority:"high"});}}function PA(e){return e.createContainerElement("figure",{class:"image"},[e.createEmptyElement("img"),e.createSlot("children")])}function SA(e,t){const i=e.plugins.get("ImageUtils"),n=e.plugins.has("ImageInlineEditing")&&e.plugins.has("ImageBlockEditing");return e=>{if(!i.isInlineImageView(e))return null;if(!n)return s(e);return ("block"==e.getStyle("display")||e.findAncestor(i.isBlockImageView)?"imageBlock":"imageInline")!==t?null:s(e)};function s(e){const t={name:!0};return e.hasAttribute("src")&&(t.attributes=["src"]),t}}function IA(e,t){const i=wr(t.getSelectedBlocks());return !i||e.isObject(i)||i.isEmpty&&"listItem"!=i.name?"imageBlock":"imageInline"}function VA(e){return e&&e.endsWith("px")?parseInt(e):null}function RA(e){const t=VA(e.getStyle("width")),i=VA(e.getStyle("height"));return !(!t||!i)}const OA=/^(image|image-inline)$/;class BA extends Dr{_domEmitter=new(go());static get pluginName(){return "ImageUtils"}static get isOfficialPlugin(){return !0}isImage(e){return this.isInlineImage(e)||this.isBlockImage(e)}isInlineImageView(e){return !!e&&e.is("element","img")}isBlockImageView(e){return !!e&&e.is("element","figure")&&e.hasClass("image")}insertImage(e={},t=null,i=null,n={}){const s=this.editor,o=s.model,r=o.document.selection,a=MA(s,t||r,i);e={...Object.fromEntries(r.getAttributes()),...e};for(const t in e)o.schema.checkAttribute(a,t)||delete e[t];return o.change((i=>{const{setImageSizes:s=!0}=n,r=i.createElement(a,e);return o.insertObject(r,t,null,{setSelection:"on",findOptimalPosition:t||"imageInline"==a?void 0:"auto"}),r.parent?(s&&this.setImageNaturalSizeAttributes(r),r):null}))}setImageNaturalSizeAttributes(e){const t=e.getAttribute("src");t&&(e.getAttribute("width")||e.getAttribute("height")||this.editor.model.change((n=>{const s=new i.window.Image;this._domEmitter.listenTo(s,"load",(()=>{e.getAttribute("width")||e.getAttribute("height")||this.editor.model.enqueueChange(n.batch,(t=>{t.setAttribute("width",s.naturalWidth,e),t.setAttribute("height",s.naturalHeight,e);})),this._domEmitter.stopListening(s,"load");})),s.src=t;})));}getClosestSelectedImageWidget(e){const t=e.getFirstPosition();if(!t)return null;const i=e.getSelectedElement();if(i&&this.isImageWidget(i))return i;let n=t.parent;for(;n;){if(n.is("element")&&this.isImageWidget(n))return n;n=n.parent;}return null}getClosestSelectedImageElement(e){const t=e.getSelectedElement();return this.isImage(t)?t:e.getFirstPosition().findAncestor("imageBlock")}getImageWidgetFromImageView(e){return e.findAncestor({classes:OA})}isImageAllowed(){const e=this.editor.model.document.selection;return function(e,t){const i=MA(e,t,null);if("imageBlock"==i){const i=function(e,t){const i=hy(e,t),n=i.start.parent;if(n.isEmpty&&!n.is("element","$root"))return n.parent;return n}(t,e.model);if(e.model.schema.checkChild(i,"imageBlock"))return !0}else if(e.model.schema.checkChild(t.focus,"imageInline"))return !0;return !1}(this.editor,e)&&function(e){return [...e.focus.getAncestors()].every((e=>!e.is("element","imageBlock")))}(e)}toImageWidget(e,t,i){t.setCustomProperty("image",!0,e);return oy(e,t,{label:()=>{const t=this.findViewImgElement(e).getAttribute("alt");return t?`${t} ${i}`:i}})}isImageWidget(e){return !!e.getCustomProperty("image")&&sy(e)}isBlockImage(e){return !!e&&e.is("element","imageBlock")}isInlineImage(e){return !!e&&e.is("element","imageInline")}findViewImgElement(e){if(this.isInlineImageView(e))return e;const t=this.editor.editing.view;for(const{item:i}of t.createRangeIn(e))if(this.isInlineImageView(i))return i}destroy(){return this._domEmitter.stopListening(),super.destroy()}}function MA(e,t,i){const n=e.model.schema,s=e.config.get("image.insert.type");return e.plugins.has("ImageBlockEditing")?e.plugins.has("ImageInlineEditing")?i||("inline"===s?"imageInline":"auto"!==s?"imageBlock":t.is("selection")?IA(n,t):n.checkChild(t,"imageInline")?"imageInline":"imageBlock"):"imageBlock":"imageInline"}const LA=new RegExp(String(/^(http(s)?:\/\/)?[\w-]+\.[\w.~:/[\]@!$&'()*+,;=%-]+/.source+/\.(jpg|jpeg|png|gif|ico|webp|JPG|JPEG|PNG|GIF|ICO|WEBP)/.source+/(\?[\w.~:/[\]@!$&'()*+,;=%-]*)?/.source+/(#[\w.~:/[\]@!$&'()*+,;=%-]*)?$/.source));class FA extends Dr{static get requires(){return [Qy,BA,lC,Rw]}static get pluginName(){return "AutoImage"}static get isOfficialPlugin(){return !0}_timeoutId;_positionToInsert;constructor(e){super(e),this._timeoutId=null,this._positionToInsert=null;}init(){const e=this.editor,t=e.model.document,n=e.plugins.get("ClipboardPipeline");this.listenTo(n,"inputTransformation",(()=>{const e=t.selection.getFirstRange(),i=su.fromPosition(e.start);i.stickiness="toPrevious";const n=su.fromPosition(e.end);n.stickiness="toNext",t.once("change:data",(()=>{this._embedImageBetweenPositions(i,n),i.detach(),n.detach();}),{priority:"high"});})),e.commands.get("undo").on("execute",(()=>{this._timeoutId&&(i.window.clearTimeout(this._timeoutId),this._positionToInsert.detach(),this._timeoutId=null,this._positionToInsert=null);}),{priority:"high"});}_embedImageBetweenPositions(e,t){const i=this.editor,n=new fc(e,t),s=n.getWalker({ignoreElementEnd:!0}),o=Object.fromEntries(i.model.document.selection.getAttributes()),r=this.editor.plugins.get("ImageUtils");let a="";for(const e of s)e.item.is("$textProxy")&&(a+=e.item.data);a=a.trim(),a.match(LA)?(this._positionToInsert=su.fromPosition(e),this._timeoutId=setTimeout((()=>{if(!i.commands.get("insertImage").isEnabled)return void n.detach();i.model.change((e=>{let t;this._timeoutId=null,e.remove(n),n.detach(),"$graveyard"!==this._positionToInsert.root.rootName&&(t=this._positionToInsert.toPosition()),r.insertImage({...o,src:a},t),this._positionToInsert.detach(),this._positionToInsert=null;}));i.plugins.get("Delete").requestUndoOnBackspace();}),100)):n.detach();}}class NA extends Hr{refresh(){const e=this.editor.plugins.get("ImageUtils").getClosestSelectedImageElement(this.editor.model.document.selection);this.isEnabled=!!e,this.isEnabled&&e.hasAttribute("alt")?this.value=e.getAttribute("alt"):this.value=!1;}execute(e){const t=this.editor,i=t.plugins.get("ImageUtils"),n=t.model,s=i.getClosestSelectedImageElement(n.document.selection);n.change((t=>{t.setAttribute("alt",e.newValue,s);}));}}class DA extends Dr{static get requires(){return [BA]}static get pluginName(){return "ImageTextAlternativeEditing"}static get isOfficialPlugin(){return !0}init(){this.editor.commands.add("imageTextAlternative",new NA(this.editor));}}class zA extends lg{focusTracker;keystrokes;labeledInput;saveButtonView;cancelButtonView;_focusables;_focusCycler;constructor(e){super(e);const t=this.locale.t;this.focusTracker=new _r,this.keystrokes=new Cr,this.labeledInput=this._createLabeledInputView(),this.saveButtonView=this._createButton(t("Save"),vm.check,"ck-button-save"),this.saveButtonView.type="submit",this.cancelButtonView=this._createButton(t("Cancel"),vm.cancel,"ck-button-cancel","cancel"),this._focusables=new zm,this._focusCycler=new _g({focusables:this._focusables,focusTracker:this.focusTracker,keystrokeHandler:this.keystrokes,actions:{focusPrevious:"shift + tab",focusNext:"tab"}}),this.setTemplate({tag:"form",attributes:{class:["ck","ck-text-alternative-form","ck-responsive-form"],tabindex:"-1"},children:[this.labeledInput,this.saveButtonView,this.cancelButtonView]});}render(){super.render(),this.keystrokes.listenTo(this.element),hg({view:this}),[this.labeledInput,this.saveButtonView,this.cancelButtonView].forEach((e=>{this._focusables.add(e),this.focusTracker.add(e.element);}));}destroy(){super.destroy(),this.focusTracker.destroy(),this.keystrokes.destroy();}_createButton(e,t,i,n){const s=new pg(this.locale);return s.set({label:e,icon:t,tooltip:!0}),s.extendTemplate({attributes:{class:i}}),n&&s.delegate("execute").to(this,n),s}_createLabeledInputView(){const e=this.locale.t,t=new pf(this.locale,cp);return t.label=e("Text alternative"),t}}function HA(e){const t=e.editing.view,i=Df.defaultPositions,n=e.plugins.get("ImageUtils");return {target:t.domConverter.mapViewToDom(n.getClosestSelectedImageWidget(t.document.selection)),positions:[i.northArrowSouth,i.northArrowSouthWest,i.northArrowSouthEast,i.southArrowNorth,i.southArrowNorthWest,i.southArrowNorthEast,i.viewportStickyNorth]}}class $A extends Dr{_balloon;_form;static get requires(){return [Db]}static get pluginName(){return "ImageTextAlternativeUI"}static get isOfficialPlugin(){return !0}init(){this._createButton();}destroy(){super.destroy(),this._form&&this._form.destroy();}_createButton(){const e=this.editor,t=e.t;e.ui.componentFactory.add("imageTextAlternative",(i=>{const n=e.commands.get("imageTextAlternative"),s=new pg(i);return s.set({label:t("Change image text alternative"),icon:vm.textAlternative,tooltip:!0}),s.bind("isEnabled").to(n,"isEnabled"),s.bind("isOn").to(n,"value",(e=>!!e)),this.listenTo(s,"execute",(()=>{this._showForm();})),s}));}_createForm(){const e=this.editor,t=e.editing.view.document,i=e.plugins.get("ImageUtils");this._balloon=this.editor.plugins.get("ContextualBalloon"),this._form=new(ug(zA))(e.locale),this._form.render(),this.listenTo(this._form,"submit",(()=>{e.execute("imageTextAlternative",{newValue:this._form.labeledInput.fieldView.element.value}),this._hideForm(!0);})),this.listenTo(this._form,"cancel",(()=>{this._hideForm(!0);})),this._form.keystrokes.set("Esc",((e,t)=>{this._hideForm(!0),t();})),this.listenTo(e.ui,"update",(()=>{i.getClosestSelectedImageWidget(t.selection)?this._isVisible&&function(e){const t=e.plugins.get("ContextualBalloon");if(e.plugins.get("ImageUtils").getClosestSelectedImageWidget(e.editing.view.document.selection)){const i=HA(e);t.updatePosition(i);}}(e):this._hideForm(!0);})),cg({emitter:this._form,activator:()=>this._isVisible,contextElements:()=>[this._balloon.view.element],callback:()=>this._hideForm()});}_showForm(){if(this._isVisible)return;this._form||this._createForm();const e=this.editor,t=e.commands.get("imageTextAlternative"),i=this._form.labeledInput;this._form.disableCssTransitions(),this._isInBalloon||this._balloon.add({view:this._form,position:HA(e)}),i.fieldView.value=i.fieldView.element.value=t.value||"",this._form.labeledInput.fieldView.select(),this._form.enableCssTransitions();}_hideForm(e=!1){this._isInBalloon&&(this._form.focusTracker.isFocused&&this._form.saveButtonView.focus(),this._balloon.remove(this._form),e&&this.editor.editing.view.focus());}get _isVisible(){return !!this._balloon&&this._balloon.visibleView===this._form}get _isInBalloon(){return !!this._balloon&&this._balloon.hasView(this._form)}}class UA extends Dr{static get requires(){return [DA,$A]}static get pluginName(){return "ImageTextAlternative"}static get isOfficialPlugin(){return !0}}function WA(e,t){const i=(t,i,n)=>{if(!n.consumable.consume(i.item,t.name))return;const s=n.writer,o=n.mapper.toViewElement(i.item),r=e.findViewImgElement(o);null===i.attributeNewValue?(s.removeAttribute("srcset",r),s.removeAttribute("sizes",r)):i.attributeNewValue&&(s.setAttribute("srcset",i.attributeNewValue,r),s.setAttribute("sizes","100vw",r));};return e=>{e.on(`attribute:srcset:${t}`,i);}}function jA(e,t,i){const n=(t,i,n)=>{if(!n.consumable.consume(i.item,t.name))return;const s=n.writer,o=n.mapper.toViewElement(i.item),r=e.findViewImgElement(o);s.setAttribute(i.attributeKey,i.attributeNewValue||"",r);};return e=>{e.on(`attribute:${i}:${t}`,n);}}class qA extends Al{observe(e){this.listenTo(e,"load",((e,t)=>{const i=t.target;this.checkShouldIgnoreEventFromTarget(i)||"IMG"==i.tagName&&this._fireEvents(t);}),{useCapture:!0});}stopObserving(e){this.stopListening(e);}_fireEvents(e){this.isEnabled&&(this.document.fire("layoutChanged"),this.document.fire("imageLoaded",e));}}class GA extends Hr{constructor(e){super(e);const t=e.config.get("image.insert.type");e.plugins.has("ImageBlockEditing")||"block"===t&&E("image-block-plugin-required"),e.plugins.has("ImageInlineEditing")||"inline"===t&&E("image-inline-plugin-required");}refresh(){const e=this.editor.plugins.get("ImageUtils");this.isEnabled=e.isImageAllowed();}execute(e){const t=gr(e.source),i=this.editor.model.document.selection,n=this.editor.plugins.get("ImageUtils"),s=Object.fromEntries(i.getAttributes());t.forEach(((t,o)=>{const r=i.getSelectedElement();if("string"==typeof t&&(t={src:t}),o&&r&&n.isImage(r)){const i=this.editor.model.createPositionAfter(r);n.insertImage({...t,...s},i,e.imageType);}else n.insertImage({...t,...s},null,e.imageType);}));}}class KA extends Hr{constructor(e){super(e),this.decorate("cleanupImage");}refresh(){const e=this.editor.plugins.get("ImageUtils"),t=this.editor.model.document.selection.getSelectedElement();this.isEnabled=e.isImage(t),this.value=this.isEnabled?t.getAttribute("src"):null;}execute(e){const t=this.editor.model.document.selection.getSelectedElement(),i=this.editor.plugins.get("ImageUtils");this.editor.model.change((n=>{n.setAttribute("src",e.source,t),this.cleanupImage(n,t),i.setImageNaturalSizeAttributes(t);}));}cleanupImage(e,t){e.removeAttribute("srcset",t),e.removeAttribute("sizes",t),e.removeAttribute("sources",t),e.removeAttribute("width",t),e.removeAttribute("height",t),e.removeAttribute("alt",t);}}class ZA extends Dr{static get requires(){return [BA]}static get pluginName(){return "ImageEditing"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.conversion;e.editing.view.addObserver(qA),t.for("upcast").attributeToAttribute({view:{name:"img",key:"alt"},model:"alt"}).attributeToAttribute({view:{name:"img",key:"srcset"},model:"srcset"});const i=new GA(e),n=new KA(e);e.commands.add("insertImage",i),e.commands.add("replaceImageSource",n),e.commands.add("imageInsert",i);}}class JA extends Dr{static get requires(){return [BA]}static get pluginName(){return "ImageSizeAttributes"}static get isOfficialPlugin(){return !0}afterInit(){this._registerSchema(),this._registerConverters("imageBlock"),this._registerConverters("imageInline");}_registerSchema(){this.editor.plugins.has("ImageBlockEditing")&&this.editor.model.schema.extend("imageBlock",{allowAttributes:["width","height"]}),this.editor.plugins.has("ImageInlineEditing")&&this.editor.model.schema.extend("imageInline",{allowAttributes:["width","height"]});}_registerConverters(e){const t=this.editor,i=t.plugins.get("ImageUtils"),n="imageBlock"===e?"figure":"img";function s(t,n,s,o){t.on(`attribute:${n}:${e}`,((t,n,r)=>{if(!r.consumable.consume(n.item,t.name))return;const a=r.writer,l=r.mapper.toViewElement(n.item),c=i.findViewImgElement(l);if(null!==n.attributeNewValue?a.setAttribute(s,n.attributeNewValue,c):a.removeAttribute(s,c),n.item.hasAttribute("sources"))return;const d=n.item.hasAttribute("resizedWidth");if("imageInline"===e&&!d&&!o)return;const u=n.item.getAttribute("width"),h=n.item.getAttribute("height");u&&h&&a.setStyle("aspect-ratio",`${u}/${h}`,c);}));}t.conversion.for("upcast").attributeToAttribute({view:{name:n,styles:{width:/.+/}},model:{key:"width",value:e=>RA(e)?VA(e.getStyle("width")):null}}).attributeToAttribute({view:{name:n,key:"width"},model:"width"}).attributeToAttribute({view:{name:n,styles:{height:/.+/}},model:{key:"height",value:e=>RA(e)?VA(e.getStyle("height")):null}}).attributeToAttribute({view:{name:n,key:"height"},model:"height"}),t.conversion.for("editingDowncast").add((e=>{s(e,"width","width",!0),s(e,"height","height",!0);})),t.conversion.for("dataDowncast").add((e=>{s(e,"width","width",!1),s(e,"height","height",!1);}));}}class QA extends Hr{_modelElementName;constructor(e,t){super(e),this._modelElementName=t;}refresh(){const e=this.editor.plugins.get("ImageUtils"),t=e.getClosestSelectedImageElement(this.editor.model.document.selection);"imageBlock"===this._modelElementName?this.isEnabled=e.isInlineImage(t):this.isEnabled=e.isBlockImage(t);}execute(e={}){const t=this.editor,i=this.editor.model,n=t.plugins.get("ImageUtils"),s=n.getClosestSelectedImageElement(i.document.selection),o=Object.fromEntries(s.getAttributes());return o.src||o.uploadId?i.change((t=>{const{setImageSizes:r=!0}=e,a=Array.from(i.markers).filter((e=>e.getRange().containsItem(s))),l=n.insertImage(o,i.createSelection(s,"on"),this._modelElementName,{setImageSizes:r});if(!l)return null;const c=t.createRangeOn(l);for(const e of a){const i=e.getRange(),n="$graveyard"!=i.root.rootName?i.getJoined(c,!0):c;t.updateMarker(e,{range:n});}return {oldElement:s,newElement:l}})):null}}class YA extends Dr{static get requires(){return [BA]}static get pluginName(){return "ImagePlaceholder"}static get isOfficialPlugin(){return !0}afterInit(){this._setupSchema(),this._setupConversion(),this._setupLoadListener();}_setupSchema(){const e=this.editor.model.schema;e.isRegistered("imageBlock")&&e.extend("imageBlock",{allowAttributes:["placeholder"]}),e.isRegistered("imageInline")&&e.extend("imageInline",{allowAttributes:["placeholder"]});}_setupConversion(){const e=this.editor,t=e.conversion,i=e.plugins.get("ImageUtils");t.for("editingDowncast").add((e=>{e.on("attribute:placeholder",((e,t,n)=>{if(!n.consumable.test(t.item,e.name))return;if(!t.item.is("element","imageBlock")&&!t.item.is("element","imageInline"))return;n.consumable.consume(t.item,e.name);const s=n.writer,o=n.mapper.toViewElement(t.item),r=i.findViewImgElement(o);t.attributeNewValue?(s.addClass("image_placeholder",r),s.setStyle("background-image",`url(${t.attributeNewValue})`,r),s.setCustomProperty("editingPipeline:doNotReuseOnce",!0,r)):(s.removeClass("image_placeholder",r),s.removeStyle("background-image",r));}));}));}_setupLoadListener(){const e=this.editor,t=e.model,i=e.editing,n=i.view,s=e.plugins.get("ImageUtils");n.addObserver(qA),this.listenTo(n.document,"imageLoaded",((e,o)=>{const r=n.domConverter.mapDomToView(o.target);if(!r)return;const a=s.getImageWidgetFromImageView(r);if(!a)return;const l=i.mapper.toModelElement(a);l&&l.hasAttribute("placeholder")&&t.enqueueChange({isUndoable:!1},(e=>{e.removeAttribute("placeholder",l);}));}));}}class XA extends Dr{static get requires(){return [ZA,JA,BA,YA,Jv]}static get pluginName(){return "ImageBlockEditing"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;e.model.schema.register("imageBlock",{inheritAllFrom:"$blockObject",allowAttributes:["alt","src","srcset"]}),this._setupConversion(),e.plugins.has("ImageInlineEditing")&&(e.commands.add("imageTypeBlock",new QA(this.editor,"imageBlock")),this._setupClipboardIntegration());}_setupConversion(){const e=this.editor,t=e.t,i=e.conversion,n=e.plugins.get("ImageUtils");i.for("dataDowncast").elementToStructure({model:"imageBlock",view:(e,{writer:t})=>PA(t)}),i.for("editingDowncast").elementToStructure({model:"imageBlock",view:(e,{writer:i})=>n.toImageWidget(PA(i),i,t("image widget"))}),i.for("downcast").add(jA(n,"imageBlock","src")).add(jA(n,"imageBlock","alt")).add(WA(n,"imageBlock")),i.for("upcast").elementToElement({view:SA(e,"imageBlock"),model:(e,{writer:t})=>t.createElement("imageBlock",e.hasAttribute("src")?{src:e.getAttribute("src")}:void 0)}).add(function(e){const t=(t,i,n)=>{if(!n.consumable.test(i.viewItem,{name:!0,classes:"image"}))return;const s=e.findViewImgElement(i.viewItem);if(!s||!n.consumable.test(s,{name:!0}))return;n.consumable.consume(i.viewItem,{name:!0,classes:"image"});const o=wr(n.convertItem(s,i.modelCursor).modelRange.getItems());o?(n.convertChildren(i.viewItem,o),n.updateConversionResult(o,i)):n.consumable.revert(i.viewItem,{name:!0,classes:"image"});};return e=>{e.on("element:figure",t);}}(n));}_setupClipboardIntegration(){const e=this.editor,t=e.model,i=e.editing.view,n=e.plugins.get("ImageUtils"),s=e.plugins.get("ClipboardPipeline");this.listenTo(s,"inputTransformation",((s,o)=>{const r=Array.from(o.content.getChildren());let a;if(!r.every(n.isInlineImageView))return;a=o.targetRanges?e.editing.mapper.toModelRange(o.targetRanges[0]):t.document.selection.getFirstRange();const l=t.createSelection(a);if("imageBlock"===IA(t.schema,l)){const e=new ju(i.document),t=r.map((t=>e.createElement("figure",{class:"image"},t)));o.content=e.createDocumentFragment(t);}})),this.listenTo(s,"contentInsertion",((e,i)=>{"paste"===i.method&&t.change((e=>{const t=e.createRangeIn(i.content);for(const e of t.getItems())e.is("element","imageBlock")&&n.setImageNaturalSizeAttributes(e);}));}));}}class eE extends lg{focusTracker;keystrokes;_focusables;_focusCycler;children;constructor(e,t=[]){super(e),this.focusTracker=new _r,this.keystrokes=new Cr,this._focusables=new zm,this.children=this.createCollection(),this._focusCycler=new _g({focusables:this._focusables,focusTracker:this.focusTracker,keystrokeHandler:this.keystrokes,actions:{focusPrevious:"shift + tab",focusNext:"tab"}});for(const e of t)this.children.add(e),this._focusables.add(e),e instanceof jg&&this._focusables.addMany(e.children);this.setTemplate({tag:"form",attributes:{class:["ck","ck-image-insert-form"],tabindex:-1},children:this.children});}render(){super.render(),hg({view:this});for(const e of this._focusables)this.focusTracker.add(e.element);this.keystrokes.listenTo(this.element);const e=e=>e.stopPropagation();this.keystrokes.set("arrowright",e),this.keystrokes.set("arrowleft",e),this.keystrokes.set("arrowup",e),this.keystrokes.set("arrowdown",e);}destroy(){super.destroy(),this.focusTracker.destroy(),this.keystrokes.destroy();}focus(){this._focusCycler.focusFirst();}}class tE extends Dr{static get pluginName(){return "ImageInsertUI"}static get isOfficialPlugin(){return !0}static get requires(){return [BA]}dropdownView;_integrations=new Map;constructor(e){super(e),e.config.define("image.insert.integrations",["upload","assetManager","url"]);}init(){const e=this.editor,t=e.model.document.selection,i=e.plugins.get("ImageUtils");this.set("isImageSelected",!1),this.listenTo(e.model.document,"change",(()=>{this.isImageSelected=i.isImage(t.getSelectedElement());}));const n=e=>this._createToolbarComponent(e);e.ui.componentFactory.add("insertImage",n),e.ui.componentFactory.add("imageInsert",n),e.ui.componentFactory.add("menuBar:insertImage",(e=>this._createMenuBarComponent(e)));}registerIntegration({name:e,observable:t,buttonViewCreator:i,formViewCreator:n,menuBarButtonViewCreator:s,requiresForm:o=!1}){this._integrations.has(e)&&E("image-insert-integration-exists",{name:e}),this._integrations.set(e,{observable:t,buttonViewCreator:i,menuBarButtonViewCreator:s,formViewCreator:n,requiresForm:o});}_createToolbarComponent(e){const t=this.editor,i=e.t,n=this._prepareIntegrations();if(!n.length)return null;let s;const o=n[0];if(1==n.length){if(!o.requiresForm)return o.buttonViewCreator(!0);s=o.buttonViewCreator(!0);}else {const t=o.buttonViewCreator(!1);s=new Yf(e,t),s.tooltip=!0,s.bind("label").to(this,"isImageSelected",(e=>i(e?"Replace image":"Insert image")));}const r=this.dropdownView=Xf(e,s),a=n.map((({observable:e})=>"function"==typeof e?e():e));return r.bind("isEnabled").toMany(a,"isEnabled",((...e)=>e.some((e=>e)))),r.once("change:isOpen",(()=>{const e=n.map((({formViewCreator:e})=>e(1==n.length))),i=new eE(t.locale,e);r.panelView.children.add(i);})),r}_createMenuBarComponent(e){const t=e.t,i=this._prepareIntegrations();if(!i.length)return null;let n;const s=i[0];if(1==i.length)n=s.menuBarButtonViewCreator(!0);else {n=new aw(e);const s=new lw(e);n.panelView.children.add(s),n.buttonView.set({icon:vm.image,label:t("Image")});for(const t of i){const i=new ub(e,n),o=t.menuBarButtonViewCreator(!1);i.children.add(o),s.items.add(i);}}return n}_prepareIntegrations(){const e=this.editor.config.get("image.insert.integrations"),t=[];if(!e.length)return E("image-insert-integrations-not-specified"),t;for(const i of e)this._integrations.has(i)?t.push(this._integrations.get(i)):["upload","assetManager","url"].includes(i)||E("image-insert-unknown-integration",{item:i});return t.length||E("image-insert-integrations-not-registered"),t}}class iE extends Dr{static get requires(){return [XA,Ty,UA,tE]}static get pluginName(){return "ImageBlock"}static get isOfficialPlugin(){return !0}}class nE extends Dr{static get requires(){return [ZA,JA,BA,YA,Jv]}static get pluginName(){return "ImageInlineEditing"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;e.model.schema.register("imageInline",{inheritAllFrom:"$inlineObject",allowAttributes:["alt","src","srcset"],disallowIn:["caption"]}),this._setupConversion(),e.plugins.has("ImageBlockEditing")&&(e.commands.add("imageTypeInline",new QA(this.editor,"imageInline")),this._setupClipboardIntegration());}_setupConversion(){const e=this.editor,t=e.t,i=e.conversion,n=e.plugins.get("ImageUtils");i.for("dataDowncast").elementToElement({model:"imageInline",view:(e,{writer:t})=>t.createEmptyElement("img")}),i.for("editingDowncast").elementToStructure({model:"imageInline",view:(e,{writer:i})=>n.toImageWidget(function(e){return e.createContainerElement("span",{class:"image-inline"},e.createEmptyElement("img"))}(i),i,t("image widget"))}),i.for("downcast").add(jA(n,"imageInline","src")).add(jA(n,"imageInline","alt")).add(WA(n,"imageInline")),i.for("upcast").elementToElement({view:SA(e,"imageInline"),model:(e,{writer:t})=>t.createElement("imageInline",e.hasAttribute("src")?{src:e.getAttribute("src")}:void 0)});}_setupClipboardIntegration(){const e=this.editor,t=e.model,i=e.editing.view,n=e.plugins.get("ImageUtils"),s=e.plugins.get("ClipboardPipeline");this.listenTo(s,"inputTransformation",((s,o)=>{const r=Array.from(o.content.getChildren());let a;if(!r.every(n.isBlockImageView))return;a=o.targetRanges?e.editing.mapper.toModelRange(o.targetRanges[0]):t.document.selection.getFirstRange();const l=t.createSelection(a);if("imageInline"===IA(t.schema,l)){const e=new ju(i.document),t=r.map((t=>1===t.childCount?(Array.from(t.getAttributes()).forEach((i=>e.setAttribute(...i,n.findViewImgElement(t)))),t.getChild(0)):t));o.content=e.createDocumentFragment(t);}})),this.listenTo(s,"contentInsertion",((e,i)=>{"paste"===i.method&&t.change((e=>{const t=e.createRangeIn(i.content);for(const e of t.getItems())e.is("element","imageInline")&&n.setImageNaturalSizeAttributes(e);}));}));}}class sE extends Dr{static get requires(){return [nE,Ty,UA,tE]}static get pluginName(){return "ImageInline"}static get isOfficialPlugin(){return !0}}class oE extends Dr{static get requires(){return [iE,sE]}static get pluginName(){return "Image"}static get isOfficialPlugin(){return !0}}class rE extends Dr{static get pluginName(){return "ImageCaptionUtils"}static get isOfficialPlugin(){return !0}static get requires(){return [BA]}getCaptionFromImageModelElement(e){for(const t of e.getChildren())if(t&&t.is("element","caption"))return t;return null}getCaptionFromModelSelection(e){const t=this.editor.plugins.get("ImageUtils"),i=e.getFirstPosition().findAncestor("caption");return i&&t.isBlockImage(i.parent)?i:null}matchImageCaptionViewElement(e){const t=this.editor.plugins.get("ImageUtils");return "figcaption"==e.name&&t.isBlockImageView(e.parent)?{name:!0}:null}}class aE extends Hr{refresh(){const e=this.editor,t=e.plugins.get("ImageCaptionUtils"),i=e.plugins.get("ImageUtils");if(!e.plugins.has(XA))return this.isEnabled=!1,void(this.value=!1);const n=e.model.document.selection,s=n.getSelectedElement();if(!s){const e=t.getCaptionFromModelSelection(n);return this.isEnabled=!!e,void(this.value=!!e)}this.isEnabled=i.isImage(s),this.isEnabled?this.value=!!t.getCaptionFromImageModelElement(s):this.value=!1;}execute(e={}){const{focusCaptionOnShow:t}=e;this.editor.model.change((e=>{this.value?this._hideImageCaption(e):this._showImageCaption(e,t);}));}_showImageCaption(e,t){const i=this.editor.model.document.selection,n=this.editor.plugins.get("ImageCaptionEditing"),s=this.editor.plugins.get("ImageUtils");let o=i.getSelectedElement();const r=n._getSavedCaption(o);s.isInlineImage(o)&&(this.editor.execute("imageTypeBlock"),o=i.getSelectedElement());const a=r||e.createElement("caption");e.append(a,o),t&&e.setSelection(a,"in");}_hideImageCaption(e){const t=this.editor,i=t.model.document.selection,n=t.plugins.get("ImageCaptionEditing"),s=t.plugins.get("ImageCaptionUtils");let o,r=i.getSelectedElement();r?o=s.getCaptionFromImageModelElement(r):(o=s.getCaptionFromModelSelection(i),r=o.parent),n._saveCaption(r,o),e.setSelection(r,"on"),e.remove(o);}}class lE extends Dr{static get requires(){return [BA,rE]}static get pluginName(){return "ImageCaptionEditing"}static get isOfficialPlugin(){return !0}_savedCaptionsMap;constructor(e){super(e),this._savedCaptionsMap=new WeakMap;}init(){const e=this.editor,t=e.model.schema;t.isRegistered("caption")?t.extend("caption",{allowIn:"imageBlock"}):t.register("caption",{allowIn:"imageBlock",allowContentOf:"$block",isLimit:!0}),e.commands.add("toggleImageCaption",new aE(this.editor)),this._setupConversion(),this._setupImageTypeCommandsIntegration(),this._registerCaptionReconversion();}_setupConversion(){const e=this.editor,t=e.editing.view,i=e.plugins.get("ImageUtils"),n=e.plugins.get("ImageCaptionUtils"),s=e.t;e.conversion.for("upcast").elementToElement({view:e=>n.matchImageCaptionViewElement(e),model:"caption"}),e.conversion.for("dataDowncast").elementToElement({model:"caption",view:(e,{writer:t})=>i.isBlockImage(e.parent)?t.createContainerElement("figcaption"):null}),e.conversion.for("editingDowncast").elementToElement({model:"caption",view:(e,{writer:n})=>{if(!i.isBlockImage(e.parent))return null;const o=n.createEditableElement("figcaption");n.setCustomProperty("imageCaption",!0,o),o.placeholder=s("Enter image caption"),Zr({view:t,element:o,keepOnFocus:!0});const r=e.parent.getAttribute("alt");return uy(o,n,{label:r?s("Caption for image: %0",[r]):s("Caption for the image")})}});}_setupImageTypeCommandsIntegration(){const e=this.editor,t=e.plugins.get("ImageUtils"),i=e.plugins.get("ImageCaptionUtils"),n=e.commands.get("imageTypeInline"),s=e.commands.get("imageTypeBlock"),o=e=>{if(!e.return)return;const{oldElement:n,newElement:s}=e.return;if(!n)return;if(t.isBlockImage(n)){const e=i.getCaptionFromImageModelElement(n);if(e)return void this._saveCaption(s,e)}const o=this._getSavedCaption(n);o&&this._saveCaption(s,o);};n&&this.listenTo(n,"execute",o,{priority:"low"}),s&&this.listenTo(s,"execute",o,{priority:"low"});}_getSavedCaption(e){const t=this._savedCaptionsMap.get(e);return t?ql.fromJSON(t):null}_saveCaption(e,t){this._savedCaptionsMap.set(e,t.toJSON());}_registerCaptionReconversion(){const e=this.editor,t=e.model,i=e.plugins.get("ImageUtils"),n=e.plugins.get("ImageCaptionUtils");t.document.on("change:data",(()=>{const s=t.document.differ.getChanges();for(const t of s){if("alt"!==t.attributeKey)continue;const s=t.range.start.nodeAfter;if(i.isBlockImage(s)){const t=n.getCaptionFromImageModelElement(s);if(!t)return;e.editing.reconvertItem(t);}}}));}}class cE extends Dr{static get requires(){return [rE]}static get pluginName(){return "ImageCaptionUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.editing.view,i=e.plugins.get("ImageCaptionUtils"),n=e.t;e.ui.componentFactory.add("toggleImageCaption",(s=>{const o=e.commands.get("toggleImageCaption"),r=new pg(s);return r.set({icon:vm.caption,tooltip:!0,isToggleable:!0}),r.bind("isOn","isEnabled").to(o,"value","isEnabled"),r.bind("label").to(o,"value",(e=>n(e?"Toggle caption off":"Toggle caption on"))),this.listenTo(r,"execute",(()=>{e.execute("toggleImageCaption",{focusCaptionOnShow:!0});const n=i.getCaptionFromModelSelection(e.model.document.selection);if(n){const i=e.editing.mapper.toViewElement(n);t.scrollToTheSelection(),t.change((e=>{e.addClass("image__caption_highlighted",i);}));}e.editing.view.focus();})),r}));}}class dE extends Dr{static get requires(){return [lE,cE]}static get pluginName(){return "ImageCaption"}static get isOfficialPlugin(){return !0}}function uE(e){const t=e.map((e=>e.replace("+","\\+")));return new RegExp(`^image\\/(${t.join("|")})$`)}function hE(e){return new Promise(((t,n)=>{const s=e.getAttribute("src");fetch(s).then((e=>e.blob())).then((e=>{const i=mE(e,s),n=i.replace("image/",""),o=new File([e],`image.${n}`,{type:i});t(o);})).catch((e=>e&&"TypeError"===e.name?function(e){return function(e){return new Promise(((t,n)=>{const s=i.document.createElement("img");s.addEventListener("load",(()=>{const e=i.document.createElement("canvas");e.width=s.width,e.height=s.height;e.getContext("2d").drawImage(s,0,0),e.toBlob((e=>e?t(e):n()));})),s.addEventListener("error",(()=>n())),s.src=e;}))}(e).then((t=>{const i=mE(t,e),n=i.replace("image/","");return new File([t],`image.${n}`,{type:i})}))}(s).then(t).catch(n):n(e)));}))}function mE(e,t){return e.type?e.type:t.match(/data:(image\/\w+);base64/)?t.match(/data:(image\/\w+);base64/)[1].toLowerCase():"image/jpeg"}class gE extends Dr{static get pluginName(){return "ImageUploadUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;e.ui.componentFactory.add("uploadImage",(()=>this._createToolbarButton())),e.ui.componentFactory.add("imageUpload",(()=>this._createToolbarButton())),e.ui.componentFactory.add("menuBar:uploadImage",(()=>this._createMenuBarButton("standalone"))),e.plugins.has("ImageInsertUI")&&e.plugins.get("ImageInsertUI").registerIntegration({name:"upload",observable:()=>e.commands.get("uploadImage"),buttonViewCreator:()=>this._createToolbarButton(),formViewCreator:()=>this._createDropdownButton(),menuBarButtonViewCreator:e=>this._createMenuBarButton(e?"insertOnly":"insertNested")});}_createButton(e){const t=this.editor,i=t.locale,n=t.commands.get("uploadImage"),s=t.config.get("image.upload.types"),o=uE(s),r=new e(t.locale),a=i.t;return r.set({acceptedType:s.map((e=>`image/${e}`)).join(","),allowMultipleFiles:!0,label:a("Upload from computer"),icon:vm.imageUpload}),r.bind("isEnabled").to(n),r.on("done",((e,i)=>{const n=Array.from(i).filter((e=>o.test(e.type)));n.length&&(t.execute("uploadImage",{file:n}),t.editing.view.focus());})),r}_createToolbarButton(){const e=this.editor.locale.t,t=this.editor.plugins.get("ImageInsertUI"),i=this.editor.commands.get("uploadImage"),n=this._createButton(zg);return n.tooltip=!0,n.bind("label").to(t,"isImageSelected",i,"isAccessAllowed",((t,i)=>e(i?t?"Replace image from computer":"Upload image from computer":"You have no image upload permissions."))),n}_createDropdownButton(){const e=this.editor.locale.t,t=this.editor.plugins.get("ImageInsertUI"),i=this._createButton(zg);return i.withText=!0,i.bind("label").to(t,"isImageSelected",(t=>e(t?"Replace from computer":"Upload from computer"))),i.on("execute",(()=>{t.dropdownView.isOpen=!1;})),i}_createMenuBarButton(e){const t=this.editor.locale.t,i=this._createButton(dw);switch(i.withText=!0,e){case"standalone":i.label=t("Image from computer");break;case"insertOnly":i.label=t("Image");break;case"insertNested":i.label=t("From computer");}return i}}class fE extends Dr{static get pluginName(){return "ImageUploadProgress"}static get isOfficialPlugin(){return !0}placeholder;constructor(e){super(e),this.placeholder="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";}init(){const e=this.editor;e.plugins.has("ImageBlockEditing")&&e.editing.downcastDispatcher.on("attribute:uploadStatus:imageBlock",this.uploadStatusChange),e.plugins.has("ImageInlineEditing")&&e.editing.downcastDispatcher.on("attribute:uploadStatus:imageInline",this.uploadStatusChange);}uploadStatusChange=(e,t,i)=>{const n=this.editor,s=t.item,o=s.getAttribute("uploadId");if(!i.consumable.consume(t.item,e.name))return;const r=n.plugins.get("ImageUtils"),a=n.plugins.get(km),l=o?t.attributeNewValue:null,c=this.placeholder,d=n.editing.mapper.toViewElement(s),u=i.writer;if("reading"==l)return pE(d,u),void bE(r,c,d,u);if("uploading"==l){const e=a.loaders.get(o);return pE(d,u),void(e?(wE(d,u),function(e,t,i,n){const s=function(e){const t=e.createUIElement("div",{class:"ck-progress-bar"});return e.setCustomProperty("progressBar",!0,t),t}(t);t.insert(t.createPositionAt(e,"end"),s),i.on("change:uploadedPercent",((e,t,i)=>{n.change((e=>{e.setStyle("width",i+"%",s);}));}));}(d,u,e,n.editing.view),function(e,t,i,n){if(n.data){const s=e.findViewImgElement(t);i.setAttribute("src",n.data,s);}}(r,d,u,e)):bE(r,c,d,u))}"complete"==l&&a.loaders.get(o)&&function(e,t,i){const n=t.createUIElement("div",{class:"ck-image-upload-complete-icon"});t.insert(t.createPositionAt(e,"end"),n),setTimeout((()=>{i.change((e=>e.remove(e.createRangeOn(n))));}),3e3);}(d,u,n.editing.view),function(e,t){vE(e,t,"progressBar");}(d,u),wE(d,u),function(e,t){t.removeClass("ck-appear",e);}(d,u);}}function pE(e,t){e.hasClass("ck-appear")||t.addClass("ck-appear",e);}function bE(e,t,i,n){i.hasClass("ck-image-upload-placeholder")||n.addClass("ck-image-upload-placeholder",i);const s=e.findViewImgElement(i);s.getAttribute("src")!==t&&n.setAttribute("src",t,s),_E(i,"placeholder")||n.insert(n.createPositionAfter(s),function(e){const t=e.createUIElement("div",{class:"ck-upload-placeholder-loader"});return e.setCustomProperty("placeholder",!0,t),t}(n));}function wE(e,t){e.hasClass("ck-image-upload-placeholder")&&t.removeClass("ck-image-upload-placeholder",e),vE(e,t,"placeholder");}function _E(e,t){for(const i of e.getChildren())if(i.getCustomProperty(t))return i}function vE(e,t,i){const n=_E(e,i);n&&t.remove(t.createRangeOn(n));}class yE extends Hr{constructor(e){super(e),this.set("isAccessAllowed",!0);}refresh(){const e=this.editor,t=e.plugins.get("ImageUtils"),i=e.model.document.selection.getSelectedElement();this.isEnabled=t.isImageAllowed()||t.isImage(i);}execute(e){const t=gr(e.file),i=this.editor.model.document.selection,n=this.editor.plugins.get("ImageUtils"),s=Object.fromEntries(i.getAttributes());t.forEach(((e,t)=>{const o=i.getSelectedElement();if(t&&o&&n.isImage(o)){const t=this.editor.model.createPositionAfter(o);this._uploadImage(e,s,t);}else this._uploadImage(e,s);}));}_uploadImage(e,t,i){const n=this.editor,s=n.plugins.get(km).createLoader(e),o=n.plugins.get("ImageUtils");s&&o.insertImage({...t,uploadId:s.id},i);}}class kE extends Dr{static get requires(){return [km,Lb,Jv,BA]}static get pluginName(){return "ImageUploadEditing"}static get isOfficialPlugin(){return !0}_uploadImageElements;constructor(e){super(e),e.config.define("image",{upload:{types:["jpeg","png","gif","bmp","webp","tiff"]}}),this._uploadImageElements=new Map;}init(){const e=this.editor,t=e.model.document,i=e.conversion,n=e.plugins.get(km),s=e.plugins.get("ImageUtils"),o=e.plugins.get("ClipboardPipeline"),r=uE(e.config.get("image.upload.types")),a=new yE(e);e.commands.add("uploadImage",a),e.commands.add("imageUpload",a),i.for("upcast").attributeToAttribute({view:{name:"img",key:"uploadId"},model:"uploadId"}),this.listenTo(e.editing.view.document,"clipboardInput",((t,i)=>{if(n=i.dataTransfer,Array.from(n.types).includes("text/html")&&""!==n.getData("text/html"))return;var n;const s=Array.from(i.dataTransfer.files).filter((e=>!!e&&r.test(e.type)));if(!s.length)return;t.stop(),e.model.change((t=>{i.targetRanges&&t.setSelection(i.targetRanges.map((t=>e.editing.mapper.toModelRange(t)))),e.execute("uploadImage",{file:s});}));if(!e.commands.get("uploadImage").isAccessAllowed){const t=e.plugins.get("Notification"),i=e.locale.t;t.showWarning(i("You have no image upload permissions."),{namespace:"image"});}})),this.listenTo(o,"inputTransformation",((t,i)=>{const o=Array.from(e.editing.view.createRangeIn(i.content)).map((e=>e.item)).filter((e=>function(e,t){return !(!e.isInlineImageView(t)||!t.getAttribute("src")||!t.getAttribute("src").match(/^data:image\/\w+;base64,/g)&&!t.getAttribute("src").match(/^blob:/g))}(s,e)&&!e.getAttribute("uploadProcessed"))).map((e=>({promise:hE(e),imageElement:e})));if(!o.length)return;const r=new ju(e.editing.view.document);for(const e of o){r.setAttribute("uploadProcessed",!0,e.imageElement);const t=n.createLoader(e.promise);t&&(r.setAttribute("src","",e.imageElement),r.setAttribute("uploadId",t.id,e.imageElement));}})),e.editing.view.document.on("dragover",((e,t)=>{t.preventDefault();})),t.on("change",(()=>{const i=t.differ.getChanges({includeChangesInGraveyard:!0}).reverse(),s=new Set;for(const t of i)if("insert"==t.type&&"$text"!=t.name){const i=t.position.nodeAfter,o="$graveyard"==t.position.root.rootName;for(const t of CE(e,i)){const e=t.getAttribute("uploadId");if(!e)continue;const i=n.loaders.get(e);i&&(o?s.has(e)||i.abort():(s.add(e),this._uploadImageElements.set(e,t),"idle"==i.status&&this._readAndUpload(i)));}}})),this.on("uploadComplete",((e,{imageElement:t,data:i})=>{const n=i.urls?i.urls:i;this.editor.model.change((e=>{e.setAttribute("src",n.default,t),this._parseAndSetSrcsetAttributeOnImage(n,t,e),s.setImageNaturalSizeAttributes(t);}));}),{priority:"low"});}afterInit(){const e=this.editor.model.schema;this.editor.plugins.has("ImageBlockEditing")&&e.extend("imageBlock",{allowAttributes:["uploadId","uploadStatus"]}),this.editor.plugins.has("ImageInlineEditing")&&e.extend("imageInline",{allowAttributes:["uploadId","uploadStatus"]});}_readAndUpload(e){const t=this.editor,i=t.model,n=t.locale.t,s=t.plugins.get(km),r=t.plugins.get(Lb),a=t.plugins.get("ImageUtils"),l=this._uploadImageElements;return i.enqueueChange({isUndoable:!1},(t=>{t.setAttribute("uploadStatus","reading",l.get(e.id));})),e.read().then((()=>{const s=e.upload(),r=l.get(e.id);if(o.isSafari){const e=t.editing.mapper.toViewElement(r),i=a.findViewImgElement(e);t.editing.view.once("render",(()=>{if(!i.parent)return;const e=t.editing.view.domConverter.mapViewToDom(i.parent);if(!e)return;const n=e.style.display;e.style.display="none",e._ckHack=e.offsetHeight,e.style.display=n;}));}return t.ui&&t.ui.ariaLiveAnnouncer.announce(n("Uploading image")),i.enqueueChange({isUndoable:!1},(e=>{e.setAttribute("uploadStatus","uploading",r);})),s})).then((s=>{i.enqueueChange({isUndoable:!1},(i=>{const o=l.get(e.id);i.setAttribute("uploadStatus","complete",o),t.ui&&t.ui.ariaLiveAnnouncer.announce(n("Image upload complete")),this.fire("uploadComplete",{data:s,imageElement:o});})),c();})).catch((s=>{if(t.ui&&t.ui.ariaLiveAnnouncer.announce(n("Error during image upload")),"error"!==e.status&&"aborted"!==e.status)throw s;"error"==e.status&&s&&r.showWarning(s,{title:n("Upload failed"),namespace:"upload"}),i.enqueueChange({isUndoable:!1},(t=>{t.remove(l.get(e.id));})),c();}));function c(){i.enqueueChange({isUndoable:!1},(t=>{const i=l.get(e.id);t.removeAttribute("uploadId",i),t.removeAttribute("uploadStatus",i),l.delete(e.id);})),s.destroyLoader(e);}}_parseAndSetSrcsetAttributeOnImage(e,t,i){let n=0;const s=Object.keys(e).filter((e=>{const t=parseInt(e,10);if(!isNaN(t))return n=Math.max(n,t),!0})).map((t=>`${e[t]} ${t}w`)).join(", ");if(""!=s){const e={srcset:s};t.hasAttribute("width")||t.hasAttribute("height")||(e.width=n),i.setAttributes(e,t);}}}function CE(e,t){const i=e.plugins.get("ImageUtils");return Array.from(e.model.createRangeOn(t)).filter((e=>i.isImage(e.item))).map((e=>e.item))}class xE extends Dr{static get pluginName(){return "ImageUpload"}static get isOfficialPlugin(){return !0}static get requires(){return [kE,gE,fE]}}class AE extends lg{urlInputView;keystrokes;constructor(e){super(e),this.set("imageURLInputValue",""),this.set("isImageSelected",!1),this.set("isEnabled",!0),this.keystrokes=new Cr,this.urlInputView=this._createUrlInputView(),this.setTemplate({tag:"div",attributes:{class:["ck","ck-image-insert-url"]},children:[this.urlInputView,{tag:"div",attributes:{class:["ck","ck-image-insert-url__action-row"]}}]});}render(){super.render(),this.keystrokes.listenTo(this.element);}destroy(){super.destroy(),this.keystrokes.destroy();}_createUrlInputView(){const e=this.locale,t=e.t,i=new pf(e,cp);return i.bind("label").to(this,"isImageSelected",(e=>t(e?"Update image URL":"Insert image via URL"))),i.bind("isEnabled").to(this),i.fieldView.inputMode="url",i.fieldView.placeholder="https://example.com/image.png",i.fieldView.bind("value").to(this,"imageURLInputValue",(e=>e||"")),i.fieldView.on("input",(()=>{this.imageURLInputValue=i.fieldView.element.value.trim();})),i}focus(){this.urlInputView.focus();}}class EE extends Dr{_imageInsertUI;_formView;static get pluginName(){return "ImageInsertViaUrlUI"}static get isOfficialPlugin(){return !0}static get requires(){return [tE,Sg]}init(){this.editor.ui.componentFactory.add("insertImageViaUrl",(()=>this._createToolbarButton())),this.editor.ui.componentFactory.add("menuBar:insertImageViaUrl",(()=>this._createMenuBarButton("standalone")));}afterInit(){this._imageInsertUI=this.editor.plugins.get("ImageInsertUI"),this._imageInsertUI.registerIntegration({name:"url",observable:()=>this.editor.commands.get("insertImage"),buttonViewCreator:()=>this._createToolbarButton(),formViewCreator:()=>this._createDropdownButton(),menuBarButtonViewCreator:e=>this._createMenuBarButton(e?"insertOnly":"insertNested")});}_createInsertUrlButton(e){const t=new e(this.editor.locale);return t.icon=vm.imageUrl,t.on("execute",(()=>{this._showModal();})),t}_createToolbarButton(){const e=this.editor.locale.t,t=this._createInsertUrlButton(pg);return t.tooltip=!0,t.bind("label").to(this._imageInsertUI,"isImageSelected",(t=>e(t?"Update image URL":"Insert image via URL"))),t}_createDropdownButton(){const e=this.editor.locale.t,t=this._createInsertUrlButton(pg);return t.withText=!0,t.bind("label").to(this._imageInsertUI,"isImageSelected",(t=>e(t?"Update image URL":"Insert via URL"))),t}_createMenuBarButton(e){const t=this.editor.locale.t,i=this._createInsertUrlButton(Rg);switch(i.withText=!0,e){case"standalone":i.label=t("Image via URL");break;case"insertOnly":i.label=t("Image");break;case"insertNested":i.label=t("Via URL");}return i}_createInsertUrlView(){const e=this.editor,t=e.locale,i=e.commands.get("replaceImageSource"),n=e.commands.get("insertImage"),s=new AE(t);return s.bind("isImageSelected").to(this._imageInsertUI),s.bind("isEnabled").toMany([n,i],"isEnabled",((...e)=>e.some((e=>e)))),s}_showModal(){const e=this.editor,t=e.locale.t,i=e.plugins.get("Dialog");this._formView||(this._formView=this._createInsertUrlView(),this._formView.on("submit",(()=>this._handleSave())));const n=e.commands.get("replaceImageSource");this._formView.imageURLInputValue=n.value||"",i.show({id:"insertImageViaUrl",title:this._imageInsertUI.isImageSelected?t("Update image URL"):t("Insert image via URL"),isModal:!0,content:this._formView,actionButtons:[{label:t("Cancel"),withText:!0,onExecute:()=>i.hide()},{label:t("Accept"),class:"ck-button-action",withText:!0,onExecute:()=>this._handleSave()}]});}_handleSave(){this.editor.commands.get("replaceImageSource").isEnabled?this.editor.execute("replaceImageSource",{source:this._formView.imageURLInputValue}):this.editor.execute("insertImage",{source:this._formView.imageURLInputValue}),this.editor.plugins.get("Dialog").hide();}}class TE extends Dr{static get pluginName(){return "ImageInsertViaUrl"}static get isOfficialPlugin(){return !0}static get requires(){return [EE,tE]}}class PE extends Dr{static get pluginName(){return "ImageInsert"}static get isOfficialPlugin(){return !0}static get requires(){return [xE,TE,tE]}}class SE extends Hr{refresh(){const e=this.editor,t=e.plugins.get("ImageUtils").getClosestSelectedImageElement(e.model.document.selection);this.isEnabled=!!t,t&&t.hasAttribute("resizedWidth")?this.value={width:t.getAttribute("resizedWidth"),height:null}:this.value=null;}execute(e){const t=this.editor,i=t.model,n=t.plugins.get("ImageUtils"),s=n.getClosestSelectedImageElement(i.document.selection);this.value={width:e.width,height:null},s&&i.change((t=>{t.setAttribute("resizedWidth",e.width,s),t.removeAttribute("resizedHeight",s),n.setImageNaturalSizeAttributes(s);}));}}class IE extends Dr{static get requires(){return [BA]}static get pluginName(){return "ImageResizeEditing"}static get isOfficialPlugin(){return !0}constructor(e){super(e),e.config.define("image",{resizeUnit:"%",resizeOptions:[{name:"resizeImage:original",value:null,icon:"original"},{name:"resizeImage:custom",value:"custom",icon:"custom"},{name:"resizeImage:25",value:"25",icon:"small"},{name:"resizeImage:50",value:"50",icon:"medium"},{name:"resizeImage:75",value:"75",icon:"large"}]});}init(){const e=this.editor,t=new SE(e);this._registerConverters("imageBlock"),this._registerConverters("imageInline"),e.commands.add("resizeImage",t),e.commands.add("imageResize",t);}afterInit(){this._registerSchema();}_registerSchema(){this.editor.plugins.has("ImageBlockEditing")&&this.editor.model.schema.extend("imageBlock",{allowAttributes:["resizedWidth","resizedHeight"]}),this.editor.plugins.has("ImageInlineEditing")&&this.editor.model.schema.extend("imageInline",{allowAttributes:["resizedWidth","resizedHeight"]});}_registerConverters(e){const t=this.editor,i=t.plugins.get("ImageUtils");t.conversion.for("downcast").add((t=>t.on(`attribute:resizedWidth:${e}`,((e,t,i)=>{if(!i.consumable.consume(t.item,e.name))return;const n=i.writer,s=i.mapper.toViewElement(t.item);null!==t.attributeNewValue?(n.setStyle("width",t.attributeNewValue,s),n.addClass("image_resized",s)):(n.removeStyle("width",s),n.removeClass("image_resized",s));})))),t.conversion.for("dataDowncast").attributeToAttribute({model:{name:e,key:"resizedHeight"},view:e=>({key:"style",value:{height:e}})}),t.conversion.for("editingDowncast").add((t=>t.on(`attribute:resizedHeight:${e}`,((t,n,s)=>{if(!s.consumable.consume(n.item,t.name))return;const o=s.writer,r=s.mapper.toViewElement(n.item),a="imageInline"===e?i.findViewImgElement(r):r;null!==n.attributeNewValue?o.setStyle("height",n.attributeNewValue,a):o.removeStyle("height",a);})))),t.conversion.for("upcast").attributeToAttribute({view:{name:"imageBlock"===e?"figure":"img",styles:{width:/.+/}},model:{key:"resizedWidth",value:e=>RA(e)?null:e.getStyle("width")}}),t.conversion.for("upcast").attributeToAttribute({view:{name:"imageBlock"===e?"figure":"img",styles:{height:/.+/}},model:{key:"resizedHeight",value:e=>RA(e)?null:e.getStyle("height")}});}}const VE=(()=>({small:vm.objectSizeSmall,medium:vm.objectSizeMedium,large:vm.objectSizeLarge,custom:vm.objectSizeCustom,original:vm.objectSizeFull}))();class RE extends Dr{static get requires(){return [IE]}static get pluginName(){return "ImageResizeButtons"}static get isOfficialPlugin(){return !0}_resizeUnit;constructor(e){super(e),this._resizeUnit=e.config.get("image.resizeUnit");}init(){const e=this.editor,t=e.config.get("image.resizeOptions"),i=e.commands.get("resizeImage");this.bind("isEnabled").to(i);for(const e of t)this._registerImageResizeButton(e);this._registerImageResizeDropdown(t);}_registerImageResizeButton(e){const t=this.editor,{name:i,value:n,icon:s}=e;t.ui.componentFactory.add(i,(i=>{const o=new pg(i),r=t.commands.get("resizeImage"),a=this._getOptionLabelValue(e,!0);if(!VE[s])throw new A("imageresizebuttons-missing-icon",t,e);if(o.set({label:a,icon:VE[s],tooltip:a,isToggleable:!0}),o.bind("isEnabled").to(this),t.plugins.has("ImageCustomResizeUI")&&OE(e)){const e=t.plugins.get("ImageCustomResizeUI");this.listenTo(o,"execute",(()=>{e._showForm(this._resizeUnit);}));}else {const e=n?n+this._resizeUnit:null;o.bind("isOn").to(r,"value",BE(e)),this.listenTo(o,"execute",(()=>{t.execute("resizeImage",{width:e});}));}return o}));}_registerImageResizeDropdown(e){const t=this.editor,i=t.t,n=e.find((e=>!e.value)),s=s=>{const o=t.commands.get("resizeImage"),r=Xf(s,Af),a=r.buttonView,l=i("Resize image");return a.set({tooltip:l,commandValue:n.value,icon:VE.medium,isToggleable:!0,label:this._getOptionLabelValue(n),withText:!0,class:"ck-resize-image-button",ariaLabel:l,ariaLabelledBy:void 0}),a.bind("label").to(o,"value",(e=>e&&e.width?e.width:this._getOptionLabelValue(n))),r.bind("isEnabled").to(this),sp(r,(()=>this._getResizeDropdownListItemDefinitions(e,o)),{ariaLabel:i("Image resize list"),role:"menu"}),this.listenTo(r,"execute",(e=>{"onClick"in e.source?e.source.onClick():(t.execute(e.source.commandName,{width:e.source.commandValue}),t.editing.view.focus());})),r};t.ui.componentFactory.add("resizeImage",s),t.ui.componentFactory.add("imageResize",s);}_getOptionLabelValue(e,t=!1){const i=this.editor.t;return e.label?e.label:t?OE(e)?i("Custom image size"):e.value?i("Resize image to %0",e.value+this._resizeUnit):i("Resize image to the original size"):OE(e)?i("Custom"):e.value?e.value+this._resizeUnit:i("Original")}_getResizeDropdownListItemDefinitions(e,t){const{editor:i}=this,n=new br,s=e.map((e=>OE(e)?{...e,valueWithUnits:"custom"}:e.value?{...e,valueWithUnits:`${e.value}${this._resizeUnit}`}:{...e,valueWithUnits:null}));for(const e of s){let a=null;if(i.plugins.has("ImageCustomResizeUI")&&OE(e)){const n=i.plugins.get("ImageCustomResizeUI");a={type:"button",model:new Fb({label:this._getOptionLabelValue(e),role:"menuitemradio",withText:!0,icon:null,onClick:()=>{n._showForm(this._resizeUnit);}})};const l=(r="valueWithUnits",(se(o=s)?ne:Os)(o,hs(r)));a.model.bind("isOn").to(t,"value",ME(l));}else a={type:"button",model:new Fb({commandName:"resizeImage",commandValue:e.valueWithUnits,label:this._getOptionLabelValue(e),role:"menuitemradio",withText:!0,icon:null})},a.model.bind("isOn").to(t,"value",BE(e.valueWithUnits));a.model.bind("isEnabled").to(t,"isEnabled"),n.add(a);}var o,r;return n}}function OE(e){return "custom"===e.value}function BE(e){return t=>null===e&&t===e||null!==t&&t.width===e}function ME(e){return t=>!e.some((e=>BE(e)(t)))}const LE="image_resized";class FE extends Dr{static get requires(){return [Ly,BA]}static get pluginName(){return "ImageResizeHandles"}static get isOfficialPlugin(){return !0}init(){const e=this.editor.commands.get("resizeImage");this.bind("isEnabled").to(e),this._setupResizerCreator();}_setupResizerCreator(){const e=this.editor,t=e.editing.view,i=e.plugins.get("ImageUtils");t.addObserver(qA),this.listenTo(t.document,"imageLoaded",((n,s)=>{if(!s.target.matches("figure.image.ck-widget > img,figure.image.ck-widget > picture > img,figure.image.ck-widget > a > img,figure.image.ck-widget > a > picture > img,span.image-inline.ck-widget > img,span.image-inline.ck-widget > picture > img"))return;const o=e.editing.view.domConverter,r=o.domToView(s.target),a=i.getImageWidgetFromImageView(r);let l=this.editor.plugins.get(Ly).getResizerByViewElement(a);if(l)return void l.redraw();const c=e.editing.mapper,d=c.toModelElement(a);l=e.plugins.get(Ly).attachTo({unit:e.config.get("image.resizeUnit"),modelElement:d,viewElement:a,editor:e,getHandleHost:e=>e.querySelector("img"),getResizeHost:()=>o.mapViewToDom(c.toViewElement(d)),isCentered:()=>"alignCenter"==d.getAttribute("imageStyle"),onCommit(i){t.change((e=>{e.removeClass(LE,a);})),e.execute("resizeImage",{width:i});}}),l.on("updateSize",(()=>{a.hasClass(LE)||t.change((e=>{e.addClass(LE,a);}));const e="imageInline"===d.name?r:a;e.getStyle("height")&&t.change((t=>{t.removeStyle("height",e);}));})),l.bind("isEnabled").to(this);}));}}function NE(e){if(!e)return null;const[,t,i]=e.trim().match(/([.,\d]+)(%|px)$/)||[],n=Number.parseFloat(t);return Number.isNaN(n)?null:{value:n,unit:i}}function DE(e,t,i){return "px"===i?{value:t.value,unit:"px"}:{value:t.value/e*100,unit:"%"}}function zE(e){const{editing:t}=e,i=e.plugins.get("ImageUtils").getClosestSelectedImageElement(e.model.document.selection);if(!i)return null;const n=t.mapper.toViewElement(i);return {model:i,view:n,dom:t.view.domConverter.mapViewToDom(n)}}class HE extends lg{focusTracker;keystrokes;unit;labeledInput;saveButtonView;cancelButtonView;_focusables;_focusCycler;_validators;constructor(e,t,i){super(e);const n=this.locale.t;this.focusTracker=new _r,this.keystrokes=new Cr,this.unit=t,this.labeledInput=this._createLabeledInputView(),this.saveButtonView=this._createButton(n("Save"),vm.check,"ck-button-save"),this.saveButtonView.type="submit",this.cancelButtonView=this._createButton(n("Cancel"),vm.cancel,"ck-button-cancel","cancel"),this._focusables=new zm,this._validators=i,this._focusCycler=new _g({focusables:this._focusables,focusTracker:this.focusTracker,keystrokeHandler:this.keystrokes,actions:{focusPrevious:"shift + tab",focusNext:"tab"}}),this.setTemplate({tag:"form",attributes:{class:["ck","ck-image-custom-resize-form","ck-responsive-form"],tabindex:"-1"},children:[this.labeledInput,this.saveButtonView,this.cancelButtonView]});}render(){super.render(),this.keystrokes.listenTo(this.element),hg({view:this}),[this.labeledInput,this.saveButtonView,this.cancelButtonView].forEach((e=>{this._focusables.add(e),this.focusTracker.add(e.element);}));}destroy(){super.destroy(),this.focusTracker.destroy(),this.keystrokes.destroy();}_createButton(e,t,i,n){const s=new pg(this.locale);return s.set({label:e,icon:t,tooltip:!0}),s.extendTemplate({attributes:{class:i}}),n&&s.delegate("execute").to(this,n),s}_createLabeledInputView(){const e=this.locale.t,t=new pf(this.locale,dp);return t.label=e("Resize image (in %0)",this.unit),t.fieldView.set({step:.1}),t}isValid(){this.resetFormStatus();for(const e of this._validators){const t=e(this);if(t)return this.labeledInput.errorText=t,!1}return !0}resetFormStatus(){this.labeledInput.errorText=null;}get rawSize(){const{element:e}=this.labeledInput.fieldView;return e?e.value:null}get parsedSize(){const{rawSize:e}=this;if(null===e)return null;const t=Number.parseFloat(e);return Number.isNaN(t)?null:t}get sizeWithUnits(){const{parsedSize:e,unit:t}=this;return null===e?null:`${e}${t}`}}class $E extends Dr{_balloon;_form;static get requires(){return [Db]}static get pluginName(){return "ImageCustomResizeUI"}static get isOfficialPlugin(){return !0}destroy(){super.destroy(),this._form&&this._form.destroy();}_createForm(e){const t=this.editor;this._balloon=this.editor.plugins.get("ContextualBalloon"),this._form=new(ug(HE))(t.locale,e,function(e){const t=e.t;return [e=>""===e.rawSize.trim()?t("The value must not be empty."):null===e.parsedSize?t("The value should be a plain number."):void 0]}(t)),this._form.render(),this.listenTo(this._form,"submit",(()=>{this._form.isValid()&&(t.execute("resizeImage",{width:this._form.sizeWithUnits}),this._hideForm(!0));})),this.listenTo(this._form.labeledInput,"change:errorText",(()=>{t.ui.update();})),this.listenTo(this._form,"cancel",(()=>{this._hideForm(!0);})),this._form.keystrokes.set("Esc",((e,t)=>{this._hideForm(!0),t();})),cg({emitter:this._form,activator:()=>this._isVisible,contextElements:()=>[this._balloon.view.element],callback:()=>this._hideForm()});}_showForm(e){if(this._isVisible)return;this._form||this._createForm(e);const t=this.editor,i=this._form.labeledInput;this._form.disableCssTransitions(),this._form.resetFormStatus(),this._isInBalloon||this._balloon.add({view:this._form,position:HA(t)});const n=function(e,t){const i=zE(e);if(!i)return null;const n=NE(i.model.getAttribute("resizedWidth")||null);return n?n.unit===t?n:DE(fy(i.dom),{unit:"px",value:new Eo(i.dom).width},t):null}(t,e),s=n?n.value.toFixed(1):"",o=function(e,t){const i=zE(e);if(!i)return null;const n=fy(i.dom),s=NE(window.getComputedStyle(i.dom).minWidth)||{value:1,unit:"px"};return {unit:t,lower:Math.max(.1,DE(n,s,t).value),upper:"px"===t?n:100}}(t,e);i.fieldView.value=i.fieldView.element.value=s,o&&Object.assign(i.fieldView,{min:o.lower.toFixed(1),max:Math.ceil(o.upper).toFixed(1)}),this._form.labeledInput.fieldView.select(),this._form.enableCssTransitions();}_hideForm(e=!1){this._isInBalloon&&(this._form.focusTracker.isFocused&&this._form.saveButtonView.focus(),this._balloon.remove(this._form),e&&this.editor.editing.view.focus());}get _isVisible(){return !!this._balloon&&this._balloon.visibleView===this._form}get _isInBalloon(){return !!this._balloon&&this._balloon.hasView(this._form)}}class UE extends Dr{static get requires(){return [IE,FE,$E,RE]}static get pluginName(){return "ImageResize"}static get isOfficialPlugin(){return !0}}class WE extends Hr{_defaultStyles;_styles;constructor(e,t){super(e),this._defaultStyles={imageBlock:!1,imageInline:!1},this._styles=new Map(t.map((e=>{if(e.isDefault)for(const t of e.modelElements)this._defaultStyles[t]=e.name;return [e.name,e]})));}refresh(){const e=this.editor.plugins.get("ImageUtils").getClosestSelectedImageElement(this.editor.model.document.selection);this.isEnabled=!!e,this.isEnabled?e.hasAttribute("imageStyle")?this.value=e.getAttribute("imageStyle"):this.value=this._defaultStyles[e.name]:this.value=!1;}execute(e={}){const t=this.editor,i=t.model,n=t.plugins.get("ImageUtils");i.change((t=>{const s=e.value,{setImageSizes:o=!0}=e;let r=n.getClosestSelectedImageElement(i.document.selection);s&&this.shouldConvertImageType(s,r)&&(this.editor.execute(n.isBlockImage(r)?"imageTypeInline":"imageTypeBlock",{setImageSizes:o}),r=n.getClosestSelectedImageElement(i.document.selection)),!s||this._styles.get(s).isDefault?t.removeAttribute("imageStyle",r):t.setAttribute("imageStyle",s,r),o&&n.setImageNaturalSizeAttributes(r);}));}shouldConvertImageType(e,t){return !this._styles.get(e).modelElements.includes(t.name)}}const jE={get inline(){return {name:"inline",title:"In line",icon:vm.objectInline,modelElements:["imageInline"],isDefault:!0}},get alignLeft(){return {name:"alignLeft",title:"Left aligned image",icon:vm.objectLeft,modelElements:["imageBlock","imageInline"],className:"image-style-align-left"}},get alignBlockLeft(){return {name:"alignBlockLeft",title:"Left aligned image",icon:vm.objectBlockLeft,modelElements:["imageBlock"],className:"image-style-block-align-left"}},get alignCenter(){return {name:"alignCenter",title:"Centered image",icon:vm.objectCenter,modelElements:["imageBlock"],className:"image-style-align-center"}},get alignRight(){return {name:"alignRight",title:"Right aligned image",icon:vm.objectRight,modelElements:["imageBlock","imageInline"],className:"image-style-align-right"}},get alignBlockRight(){return {name:"alignBlockRight",title:"Right aligned image",icon:vm.objectBlockRight,modelElements:["imageBlock"],className:"image-style-block-align-right"}},get block(){return {name:"block",title:"Centered image",icon:vm.objectCenter,modelElements:["imageBlock"],isDefault:!0}},get side(){return {name:"side",title:"Side image",icon:vm.objectRight,modelElements:["imageBlock"],className:"image-style-side"}}},qE=(()=>({full:vm.objectFullWidth,left:vm.objectBlockLeft,right:vm.objectBlockRight,center:vm.objectCenter,inlineLeft:vm.objectLeft,inlineRight:vm.objectRight,inline:vm.objectInline}))(),GE=[{name:"imageStyle:wrapText",title:"Wrap text",defaultItem:"imageStyle:alignLeft",items:["imageStyle:alignLeft","imageStyle:alignRight"]},{name:"imageStyle:breakText",title:"Break text",defaultItem:"imageStyle:block",items:["imageStyle:alignBlockLeft","imageStyle:block","imageStyle:alignBlockRight"]}];function KE(e){E("image-style-configuration-definition-invalid",e);}var ZE={normalizeStyles:function(e){return (e.configuredStyles.options||[]).map((e=>function(e){e="string"==typeof e?jE[e]?{...jE[e]}:{name:e}:function(e,t){const i={...t};for(const n in e)Object.prototype.hasOwnProperty.call(t,n)||(i[n]=e[n]);return i}(jE[e.name],e);"string"==typeof e.icon&&(e.icon=qE[e.icon]||e.icon);return e}(e))).filter((t=>function(e,{isBlockPluginLoaded:t,isInlinePluginLoaded:i}){const{modelElements:n,name:s}=e;if(!(n&&n.length&&s))return KE({style:e}),!1;{const s=[t?"imageBlock":null,i?"imageInline":null];if(!n.some((e=>s.includes(e))))return E("image-style-missing-dependency",{style:e,missingPlugins:n.map((e=>"imageBlock"===e?"ImageBlockEditing":"ImageInlineEditing"))}),!1}return !0}(t,e)))},getDefaultStylesConfiguration:function(e,t){return e&&t?{options:["inline","alignLeft","alignRight","alignCenter","alignBlockLeft","alignBlockRight","block","side"]}:e?{options:["block","side"]}:t?{options:["inline","alignLeft","alignRight"]}:{}},getDefaultDropdownDefinitions:function(e){return e.has("ImageBlockEditing")&&e.has("ImageInlineEditing")?[...GE]:[]},warnInvalidStyle:KE,DEFAULT_OPTIONS:jE,DEFAULT_ICONS:qE,DEFAULT_DROPDOWN_DEFINITIONS:GE};function JE(e,t){for(const i of t)if(i.name===e)return i}class QE extends Dr{static get pluginName(){return "ImageStyleEditing"}static get isOfficialPlugin(){return !0}static get requires(){return [BA]}normalizedStyles;init(){const{normalizeStyles:e,getDefaultStylesConfiguration:t}=ZE,i=this.editor,n=i.plugins.has("ImageBlockEditing"),s=i.plugins.has("ImageInlineEditing");i.config.define("image.styles",t(n,s)),this.normalizedStyles=e({configuredStyles:i.config.get("image.styles"),isBlockPluginLoaded:n,isInlinePluginLoaded:s}),this._setupConversion(n,s),this._setupPostFixer(),i.commands.add("imageStyle",new WE(i,this.normalizedStyles));}_setupConversion(e,t){const i=this.editor,n=i.model.schema,s=(o=this.normalizedStyles,(e,t,i)=>{if(!i.consumable.consume(t.item,e.name))return;const n=JE(t.attributeNewValue,o),s=JE(t.attributeOldValue,o),r=i.mapper.toViewElement(t.item),a=i.writer;s&&a.removeClass(s.className,r),n&&a.addClass(n.className,r);});var o;const r=function(e){const t={imageInline:e.filter((e=>!e.isDefault&&e.modelElements.includes("imageInline"))),imageBlock:e.filter((e=>!e.isDefault&&e.modelElements.includes("imageBlock")))};return (e,i,n)=>{if(!i.modelRange)return;const s=i.viewItem,o=wr(i.modelRange.getItems());if(o&&n.schema.checkAttribute(o,"imageStyle"))for(const e of t[o.name])n.consumable.consume(s,{classes:e.className})&&n.writer.setAttribute("imageStyle",e.name,o);}}(this.normalizedStyles);i.editing.downcastDispatcher.on("attribute:imageStyle",s),i.data.downcastDispatcher.on("attribute:imageStyle",s),e&&(n.extend("imageBlock",{allowAttributes:"imageStyle"}),i.data.upcastDispatcher.on("element:figure",r,{priority:"low"})),t&&(n.extend("imageInline",{allowAttributes:"imageStyle"}),i.data.upcastDispatcher.on("element:img",r,{priority:"low"}));}_setupPostFixer(){const e=this.editor,t=e.model.document,i=e.plugins.get(BA),n=new Map(this.normalizedStyles.map((e=>[e.name,e])));t.registerPostFixer((e=>{let s=!1;for(const o of t.differ.getChanges())if("insert"==o.type||"attribute"==o.type&&"imageStyle"==o.attributeKey){let t="insert"==o.type?o.position.nodeAfter:o.range.start.nodeAfter;if(t&&t.is("element","paragraph")&&t.childCount>0&&(t=t.getChild(0)),!i.isImage(t))continue;const r=t.getAttribute("imageStyle");if(!r)continue;const a=n.get(r);a&&a.modelElements.includes(t.name)||(e.removeAttribute("imageStyle",t),s=!0);}return s}));}}class YE extends Dr{static get requires(){return [QE]}static get pluginName(){return "ImageStyleUI"}static get isOfficialPlugin(){return !0}get localizedDefaultStylesTitles(){const e=this.editor.t;return {"Wrap text":e("Wrap text"),"Break text":e("Break text"),"In line":e("In line"),"Full size image":e("Full size image"),"Side image":e("Side image"),"Left aligned image":e("Left aligned image"),"Centered image":e("Centered image"),"Right aligned image":e("Right aligned image")}}init(){const e=this.editor.plugins,t=this.editor.config.get("image.toolbar")||[],i=XE(e.get("ImageStyleEditing").normalizedStyles,this.localizedDefaultStylesTitles);for(const e of i)this._createButton(e);const n=XE([...t.filter(ue),...ZE.getDefaultDropdownDefinitions(e)],this.localizedDefaultStylesTitles);for(const e of n)this._createDropdown(e,i);}_createDropdown(e,t){const i=this.editor.ui.componentFactory;i.add(e.name,(n=>{let s;const{defaultItem:o,items:r,title:a}=e,l=r.filter((e=>t.find((({name:t})=>eT(t)===e)))).map((e=>{const t=i.create(e);return e===o&&(s=t),t}));r.length!==l.length&&ZE.warnInvalidStyle({dropdown:e});const c=Xf(n,Yf),d=c.buttonView,u=d.arrowView;return ip(c,l,{enableActiveItemFocusOnDropdownOpen:!0}),d.set({label:tT(a,s.label),class:null,tooltip:!0}),u.unbind("label"),u.set({label:a}),d.bind("icon").toMany(l,"isOn",((...e)=>{const t=e.findIndex(be);return t<0?s.icon:l[t].icon})),d.bind("label").toMany(l,"isOn",((...e)=>{const t=e.findIndex(be);return tT(a,t<0?s.label:l[t].label)})),d.bind("isOn").toMany(l,"isOn",((...e)=>e.some(be))),d.bind("class").toMany(l,"isOn",((...e)=>e.some(be)?"ck-splitbutton_flatten":void 0)),d.on("execute",(()=>{l.some((({isOn:e})=>e))?c.isOpen=!c.isOpen:s.fire("execute");})),c.bind("isEnabled").toMany(l,"isEnabled",((...e)=>e.some(be))),this.listenTo(c,"execute",(()=>{this.editor.editing.view.focus();})),c}));}_createButton(e){const t=e.name;this.editor.ui.componentFactory.add(eT(t),(i=>{const n=this.editor.commands.get("imageStyle"),s=new pg(i);return s.set({label:e.title,icon:e.icon,tooltip:!0,isToggleable:!0}),s.bind("isEnabled").to(n,"isEnabled"),s.bind("isOn").to(n,"value",(e=>e===t)),s.on("execute",this._executeCommand.bind(this,t)),s}));}_executeCommand(e){this.editor.execute("imageStyle",{value:e}),this.editor.editing.view.focus();}}function XE(e,t){for(const i of e)t[i.title]&&(i.title=t[i.title]);return e}function eT(e){return `imageStyle:${e}`}function tT(e,t){return (e?e+": ":"")+t}class iT extends Dr{static get requires(){return [QE,YE]}static get pluginName(){return "ImageStyle"}static get isOfficialPlugin(){return !0}}class nT extends Dr{static get requires(){return [Sy,BA]}static get pluginName(){return "ImageToolbar"}static get isOfficialPlugin(){return !0}afterInit(){const e=this.editor,t=e.t,i=e.plugins.get(Sy),n=e.plugins.get("ImageUtils");var s;i.register("image",{ariaLabel:t("Image toolbar"),items:(s=e.config.get("image.toolbar")||[],s.map((e=>ue(e)?e.name:e))),getRelatedElement:e=>n.getClosestSelectedImageWidget(e)});}}class sT extends Dr{static get requires(){return [ZA,BA]}static get pluginName(){return "PictureEditing"}static get isOfficialPlugin(){return !0}afterInit(){const e=this.editor;e.plugins.has("ImageBlockEditing")&&e.model.schema.extend("imageBlock",{allowAttributes:["sources"]}),e.plugins.has("ImageInlineEditing")&&e.model.schema.extend("imageInline",{allowAttributes:["sources"]}),this._setupConversion(),this._setupImageUploadEditingIntegration();}_setupConversion(){const e=this.editor,t=e.conversion,i=e.plugins.get("ImageUtils");t.for("upcast").add(function(e){const t=["srcset","media","type","sizes"],i=(i,n,s)=>{const o=n.viewItem;if(!s.consumable.test(o,{name:!0}))return;const r=new Map;for(const e of o.getChildren())if(e.is("element","source")){const i={};for(const n of t)e.hasAttribute(n)&&s.consumable.test(e,{attributes:n})&&(i[n]=e.getAttribute(n));Object.keys(i).length&&r.set(e,i);}const a=e.findViewImgElement(o);if(!a)return;let l=n.modelCursor.parent;if(!l.is("element","imageBlock")){const e=s.convertItem(a,n.modelCursor);n.modelRange=e.modelRange,n.modelCursor=e.modelCursor,l=wr(e.modelRange.getItems());}s.consumable.consume(o,{name:!0});for(const[e,t]of r)s.consumable.consume(e,{attributes:Object.keys(t)});r.size&&s.writer.setAttribute("sources",Array.from(r.values()),l),s.convertChildren(o,l);};return e=>{e.on("element:picture",i);}}(i)),t.for("downcast").add(function(e){const t=(t,i,n)=>{if(!n.consumable.consume(i.item,t.name))return;const s=n.writer,o=n.mapper.toViewElement(i.item),r=e.findViewImgElement(o),a=i.attributeNewValue;if(a&&a.length){const e=[];let t=r.parent;for(;t&&t.is("attributeElement");){const i=t.parent;s.unwrap(s.createRangeOn(r),t),e.unshift(t),t=i;}const i=r.parent.is("element","picture"),n=i?r.parent:s.createContainerElement("picture",null);i||s.insert(s.createPositionBefore(r),n),s.remove(s.createRangeIn(n)),s.insert(s.createPositionAt(n,"end"),a.map((e=>s.createEmptyElement("source",e)))),s.move(s.createRangeOn(r),s.createPositionAt(n,"end"));for(const t of e)s.wrap(s.createRangeOn(n),t);}else if(r.parent.is("element","picture")){const e=r.parent;s.move(s.createRangeOn(r),s.createPositionBefore(e)),s.remove(e);}};return e=>{e.on("attribute:sources:imageBlock",t),e.on("attribute:sources:imageInline",t);}}(i));}_setupImageUploadEditingIntegration(){const e=this.editor;if(!e.plugins.has("ImageUploadEditing"))return;const t=e.plugins.get("ImageUploadEditing");this.listenTo(t,"uploadComplete",((t,{imageElement:i,data:n})=>{const s=n.sources;s&&e.model.change((e=>{e.setAttributes({sources:s},i);}));}));}}class oT extends Dr{static get pluginName(){return "IndentEditing"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;e.commands.add("indent",new Ur(e)),e.commands.add("outdent",new Ur(e));}}class rT extends Dr{static get pluginName(){return "IndentUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.locale,i=e.t,n="ltr"==t.uiLanguageDirection?vm.indent:vm.outdent,s="ltr"==t.uiLanguageDirection?vm.outdent:vm.indent;this._defineButton("indent",i("Increase indent"),n),this._defineButton("outdent",i("Decrease indent"),s);}_defineButton(e,t,i){const n=this.editor;n.ui.componentFactory.add(e,(()=>{const n=this._createButton(pg,e,t,i);return n.set({tooltip:!0}),n})),n.ui.componentFactory.add("menuBar:"+e,(()=>this._createButton(Rg,e,t,i)));}_createButton(e,t,i,n){const s=this.editor,o=s.commands.get(t),r=new e(s.locale);return r.set({label:i,icon:n}),r.bind("isEnabled").to(o,"isEnabled"),this.listenTo(r,"execute",(()=>{s.execute(t),s.editing.view.focus();})),r}}class aT extends Dr{static get pluginName(){return "Indent"}static get isOfficialPlugin(){return !0}static get requires(){return [oT,rT]}}class lT extends Hr{_indentBehavior;constructor(e,t){super(e),this._indentBehavior=t;}refresh(){const e=wr(this.editor.model.document.selection.getSelectedBlocks());e&&this._isIndentationChangeAllowed(e)?this.isEnabled=this._indentBehavior.checkEnabled(e.getAttribute("blockIndent")):this.isEnabled=!1;}execute(){const e=this.editor.model,t=this._getBlocksToChange();e.change((e=>{for(const i of t){const t=i.getAttribute("blockIndent"),n=this._indentBehavior.getNextIndent(t);n?e.setAttribute("blockIndent",n,i):e.removeAttribute("blockIndent",i);}}));}_getBlocksToChange(){const e=this.editor.model.document.selection;return Array.from(e.getSelectedBlocks()).filter((e=>this._isIndentationChangeAllowed(e)))}_isIndentationChangeAllowed(e){const t=this.editor;if(!t.model.schema.checkAttribute(e,"blockIndent"))return !1;if(!t.plugins.has("ListUtils"))return !0;if(!this._indentBehavior.isForward)return !0;return !t.plugins.get("ListUtils").isListItemBlock(e)}}class cT{isForward;offset;unit;constructor(e){this.isForward="forward"===e.direction,this.offset=e.offset,this.unit=e.unit;}checkEnabled(e){const t=parseFloat(e||"0");return this.isForward||t>0}getNextIndent(e){const t=parseFloat(e||"0");if(!(!e||e.endsWith(this.unit)))return this.isForward?this.offset+this.unit:void 0;const i=t+(this.isForward?this.offset:-this.offset);return i>0?i+this.unit:void 0}}class dT{isForward;classes;constructor(e){this.isForward="forward"===e.direction,this.classes=e.classes;}checkEnabled(e){const t=this.classes.indexOf(e);return this.isForward?t=0}getNextIndent(e){const t=this.classes.indexOf(e),i=this.isForward?1:-1;return this.classes[t+i]}}const uT=["paragraph","heading1","heading2","heading3","heading4","heading5","heading6"];class hT extends Dr{constructor(e){super(e),e.config.define("indentBlock",{offset:40,unit:"px"});}static get pluginName(){return "IndentBlock"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.config.get("indentBlock");t.classes&&t.classes.length?(this._setupConversionUsingClasses(t.classes),e.commands.add("indentBlock",new lT(e,new dT({direction:"forward",classes:t.classes}))),e.commands.add("outdentBlock",new lT(e,new dT({direction:"backward",classes:t.classes})))):(e.data.addStyleProcessorRules(Ih),this._setupConversionUsingOffset(),e.commands.add("indentBlock",new lT(e,new cT({direction:"forward",offset:t.offset,unit:t.unit}))),e.commands.add("outdentBlock",new lT(e,new cT({direction:"backward",offset:t.offset,unit:t.unit}))));}afterInit(){const e=this.editor,t=e.model.schema,i=e.commands.get("indent"),n=e.commands.get("outdent"),s=e.config.get("heading.options");(s&&s.map((e=>e.model))||uT).forEach((e=>{t.isRegistered(e)&&t.extend(e,{allowAttributes:"blockIndent"});})),t.setAttributeProperties("blockIndent",{isFormatting:!0}),i.registerChildCommand(e.commands.get("indentBlock")),n.registerChildCommand(e.commands.get("outdentBlock"));}_setupConversionUsingOffset(){const e=this.editor.conversion,t="rtl"===this.editor.locale.contentLanguageDirection?"margin-right":"margin-left";e.for("upcast").attributeToAttribute({view:{styles:{[t]:/[\s\S]+/}},model:{key:"blockIndent",value:e=>{if(!e.is("element","li"))return e.getStyle(t)}}}),e.for("downcast").attributeToAttribute({model:"blockIndent",view:e=>({key:"style",value:{[t]:e}})});}_setupConversionUsingClasses(e){const t={model:{key:"blockIndent",values:[]},view:{}};for(const i of e)t.model.values.push(i),t.view[i]={key:"class",value:[i]};this.editor.conversion.attributeToAttribute(t);}}function mT(e,t){return `${e}:${t=t||mr(e)}`}class gT extends Hr{refresh(){const e=this.editor.model,t=e.document;this.value=this._getValueFromFirstAllowedNode(),this.isEnabled=e.schema.checkAttributeInSelection(t.selection,"language");}execute({languageCode:e,textDirection:t}={}){const i=this.editor.model,n=i.document.selection,s=!!e&&mT(e,t);i.change((e=>{if(n.isCollapsed)s?e.setSelectionAttribute("language",s):e.removeSelectionAttribute("language");else {const t=i.schema.getValidRanges(n.getRanges(),"language");for(const i of t)s?e.setAttribute("language",s,i):e.removeAttribute("language",i);}}));}_getValueFromFirstAllowedNode(){const e=this.editor.model,t=e.schema,i=e.document.selection;if(i.isCollapsed)return i.getAttribute("language")||!1;for(const e of i.getRanges())for(const i of e.getItems())if(t.checkAttribute(i,"language"))return i.getAttribute("language")||!1;return !1}}class fT extends Dr{static get pluginName(){return "TextPartLanguageEditing"}static get isOfficialPlugin(){return !0}constructor(e){super(e),e.config.define("language",{textPartLanguage:[{title:"Arabic",languageCode:"ar"},{title:"French",languageCode:"fr"},{title:"Spanish",languageCode:"es"}]});}init(){const e=this.editor;e.model.schema.extend("$text",{allowAttributes:"language"}),e.model.schema.setAttributeProperties("language",{copyOnEnter:!0}),this._defineConverters(),e.commands.add("textPartLanguage",new gT(e));}_defineConverters(){const e=this.editor.conversion;e.for("upcast").elementToAttribute({model:{key:"language",value:e=>mT(e.getAttribute("lang"),e.getAttribute("dir"))},view:{name:"span",attributes:{lang:/[\s\S]+/}}}),e.for("downcast").attributeToElement({model:"language",view:(e,{writer:t},i)=>{if(!e)return;if(!i.item.is("$textProxy")&&!i.item.is("documentSelection"))return;const{languageCode:n,textDirection:s}=function(e){const[t,i]=e.split(":");return {languageCode:t,textDirection:i}}(e);return t.createAttributeElement("span",{lang:n,dir:s})}});}}class pT extends Dr{static get pluginName(){return "TextPartLanguageUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.t,i=t("Choose language"),n=t("Language");e.ui.componentFactory.add("textPartLanguage",(t=>{const{definitions:s,titles:o}=this._getItemMetadata(),r=e.commands.get("textPartLanguage"),a=Xf(t);return sp(a,s,{ariaLabel:n,role:"menu"}),a.buttonView.set({ariaLabel:n,ariaLabelledBy:void 0,isOn:!1,withText:!0,tooltip:n}),a.extendTemplate({attributes:{class:["ck-text-fragment-language-dropdown"]}}),a.bind("isEnabled").to(r,"isEnabled"),a.buttonView.bind("label").to(r,"value",(e=>e&&o[e]||i)),a.buttonView.bind("ariaLabel").to(r,"value",(e=>{const t=e&&o[e];return t?`${t}, ${n}`:n})),this.listenTo(a,"execute",(t=>{r.execute({languageCode:t.source.languageCode,textDirection:t.source.textDirection}),e.editing.view.focus();})),a})),e.ui.componentFactory.add("menuBar:textPartLanguage",(i=>{const{definitions:s}=this._getItemMetadata(),o=e.commands.get("textPartLanguage"),r=new aw(i);r.buttonView.set({label:n});const a=new lw(i);a.set({ariaLabel:t("Language"),role:"menu"});for(const e of s){if("button"!=e.type){a.items.add(new Sf(i));continue}const t=new ub(i,r),n=new Rg(i);n.set({role:"menuitemradio",isToggleable:!0}),n.bind(...Object.keys(e.model)).to(e.model),n.delegate("execute").to(r),t.children.add(n),a.items.add(t);}return r.bind("isEnabled").to(o,"isEnabled"),r.panelView.children.add(a),r.on("execute",(t=>{o.execute({languageCode:t.source.languageCode,textDirection:t.source.textDirection}),e.editing.view.focus();})),r}));}_getItemMetadata(){const e=this.editor,t=new br,i={},n=e.commands.get("textPartLanguage"),s=e.config.get("language.textPartLanguage"),o=(0, e.locale.t)("Remove language");t.add({type:"button",model:new Fb({label:o,languageCode:!1,withText:!0})}),t.add({type:"separator"});for(const e of s){const s={type:"button",model:new Fb({label:e.title,languageCode:e.languageCode,role:"menuitemradio",textDirection:e.textDirection,withText:!0})},o=mT(e.languageCode,e.textDirection);s.model.bind("isOn").to(n,"value",(e=>e===o)),t.add(s),i[o]=e.title;}return {definitions:t,titles:i}}}class bT extends Dr{static get requires(){return [fT,pT]}static get pluginName(){return "TextPartLanguage"}static get isOfficialPlugin(){return !0}}class wT{_definitions=new Set;get length(){return this._definitions.size}add(e){Array.isArray(e)?e.forEach((e=>this._definitions.add(e))):this._definitions.add(e);}getDispatcher(){return e=>{e.on("attribute:linkHref",((e,t,i)=>{if(!i.consumable.test(t.item,"attribute:linkHref"))return;if(!t.item.is("selection")&&!i.schema.isInline(t.item))return;const n=i.writer,s=n.document.selection;for(const e of this._definitions){const o=n.createAttributeElement("a",e.attributes,{priority:5});e.classes&&n.addClass(e.classes,o);for(const t in e.styles)n.setStyle(t,e.styles[t],o);n.setCustomProperty("link",!0,o),e.callback(t.attributeNewValue)?t.item.is("selection")?n.wrap(s.getFirstRange(),o):n.wrap(i.mapper.toViewRange(t.range),o):n.unwrap(i.mapper.toViewRange(t.range),o);}}),{priority:"high"});}}getDispatcherForLinkedImage(){return e=>{e.on("attribute:linkHref:imageBlock",((e,t,{writer:i,mapper:n})=>{const s=n.toViewElement(t.item),o=Array.from(s.getChildren()).find((e=>e.is("element","a")));if(o)for(const e of this._definitions){const n=xr(e.attributes);if(e.callback(t.attributeNewValue)){for(const[e,t]of n)"class"===e?i.addClass(t,o):i.setAttribute(e,t,o);e.classes&&i.addClass(e.classes,o);for(const t in e.styles)i.setStyle(t,e.styles[t],o);}else {for(const[e,t]of n)"class"===e?i.removeClass(t,o):i.removeAttribute(e,o);e.classes&&i.removeClass(e.classes,o);for(const t in e.styles)i.removeStyle(t,o);}}}));}}}const _T=/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205f\u3000]/g,vT=/^[\S]+@((?![-_])(?:[-\w\u00a1-\uffff]{0,63}[^-_]\.))+(?:[a-z\u00a1-\uffff]{2,})$/i,yT=/^((\w+:(\/{2,})?)|(\W))/i,kT=["https?","ftps?","mailto"],CT="Ctrl+K";function xT(e,{writer:t}){const i=t.createAttributeElement("a",{href:e},{priority:5});return t.setCustomProperty("link",!0,i),i}function AT(e,t=kT){const i=String(e),n=t.join("|");return function(e,t){const i=e.replace(_T,"");return !!i.match(t)}(i,new RegExp(`${"^(?:(?:):|[^a-z]|[a-z+.-]+(?:[^a-z+.:-]|$))".replace("",n)}`,"i"))?i:"#"}function ET(e,t){return !!e&&t.checkAttribute(e.name,"linkHref")}function TT(e,t){const i=(n=e,vT.test(n)?"mailto:":t);var n;const s=!!i&&!PT(e);return e&&s?i+e:e}function PT(e){return yT.test(e)}function ST(e){window.open(e,"_blank","noopener");}class IT extends Hr{manualDecorators=new br;automaticDecorators=new wT;restoreManualDecoratorStates(){for(const e of this.manualDecorators)e.value=this._getDecoratorStateFromModel(e.id);}refresh(){const e=this.editor.model,t=e.document.selection,i=t.getSelectedElement()||wr(t.getSelectedBlocks());ET(i,e.schema)?(this.value=i.getAttribute("linkHref"),this.isEnabled=e.schema.checkAttribute(i,"linkHref")):(this.value=t.getAttribute("linkHref"),this.isEnabled=e.schema.checkAttributeInSelection(t,"linkHref"));for(const e of this.manualDecorators)e.value=this._getDecoratorStateFromModel(e.id);}execute(e,t={}){const i=this.editor.model,n=i.document.selection,s=[],o=[];for(const e in t)t[e]?s.push(e):o.push(e);i.change((t=>{if(n.isCollapsed){const r=n.getFirstPosition();if(n.hasAttribute("linkHref")){const a=VT(n);let l=Qw(r,"linkHref",n.getAttribute("linkHref"),i);n.getAttribute("linkHref")===a&&(l=this._updateLinkContent(i,t,l,e)),t.setAttribute("linkHref",e,l),s.forEach((e=>{t.setAttribute(e,!0,l);})),o.forEach((e=>{t.removeAttribute(e,l);})),t.setSelection(t.createPositionAfter(l.end.nodeBefore));}else if(""!==e){const o=xr(n.getAttributes());o.set("linkHref",e),s.forEach((e=>{o.set(e,!0);}));const{end:a}=i.insertContent(t.createText(e,o),r);t.setSelection(a);}["linkHref",...s,...o].forEach((e=>{t.removeSelectionAttribute(e);}));}else {const r=i.schema.getValidRanges(n.getRanges(),"linkHref"),a=[];for(const e of n.getSelectedBlocks())i.schema.checkAttribute(e,"linkHref")&&a.push(t.createRangeOn(e));const l=a.slice();for(const e of r)this._isRangeToUpdate(e,a)&&l.push(e);for(const r of l){let a=r;if(1===l.length){const s=VT(n);n.getAttribute("linkHref")===s&&(a=this._updateLinkContent(i,t,r,e),t.setSelection(t.createSelection(a)));}t.setAttribute("linkHref",e,a),s.forEach((e=>{t.setAttribute(e,!0,a);})),o.forEach((e=>{t.removeAttribute(e,a);}));}}}));}_getDecoratorStateFromModel(e){const t=this.editor.model,i=t.document.selection,n=i.getSelectedElement();return ET(n,t.schema)?n.getAttribute(e):i.getAttribute(e)}_isRangeToUpdate(e,t){for(const i of t)if(i.containsRange(e))return !1;return !0}_updateLinkContent(e,t,i,n){const s=t.createText(n,{linkHref:n});return e.insertContent(s,i)}}function VT(e){if(e.isCollapsed){const t=e.getFirstPosition();return t.textNode&&t.textNode.data}{const t=Array.from(e.getFirstRange().getItems());if(t.length>1)return null;const i=t[0];return i.is("$text")||i.is("$textProxy")?i.data:null}}class RT extends Hr{refresh(){const e=this.editor.model,t=e.document.selection,i=t.getSelectedElement();ET(i,e.schema)?this.isEnabled=e.schema.checkAttribute(i,"linkHref"):this.isEnabled=e.schema.checkAttributeInSelection(t,"linkHref");}execute(){const e=this.editor,t=this.editor.model,i=t.document.selection,n=e.commands.get("link");t.change((e=>{const s=i.isCollapsed?[Qw(i.getFirstPosition(),"linkHref",i.getAttribute("linkHref"),t)]:t.schema.getValidRanges(i.getRanges(),"linkHref");for(const t of s)if(e.removeAttribute("linkHref",t),n)for(const i of n.manualDecorators)e.removeAttribute(i.id,t);}));}}class OT extends(Zs()){id;defaultValue;label;attributes;classes;styles;constructor({id:e,label:t,attributes:i,classes:n,styles:s,defaultValue:o}){super(),this.id=e,this.set("value",void 0),this.defaultValue=o,this.label=t,this.attributes=i,this.classes=n,this.styles=s;}_createPattern(){return {attributes:this.attributes,classes:this.classes,styles:this.styles}}}const BT="automatic",MT=/^(https?:)?\/\//;class LT extends Dr{static get pluginName(){return "LinkEditing"}static get isOfficialPlugin(){return !0}static get requires(){return [Lw,yw,Jv]}constructor(e){super(e),e.config.define("link",{allowCreatingEmptyLinks:!1,addTargetToExternalLinks:!1});}init(){const e=this.editor,t=this.editor.config.get("link.allowedProtocols");e.model.schema.extend("$text",{allowAttributes:"linkHref"}),e.conversion.for("dataDowncast").attributeToElement({model:"linkHref",view:xT}),e.conversion.for("editingDowncast").attributeToElement({model:"linkHref",view:(e,i)=>xT(AT(e,t),i)}),e.conversion.for("upcast").elementToAttribute({view:{name:"a",attributes:{href:!0}},model:{key:"linkHref",value:e=>e.getAttribute("href")}}),e.commands.add("link",new IT(e)),e.commands.add("unlink",new RT(e));const i=function(e,t){const i={"Open in a new tab":e("Open in a new tab"),Downloadable:e("Downloadable")};return t.forEach((e=>("label"in e&&i[e.label]&&(e.label=i[e.label]),e))),t}(e.t,function(e){const t=[];if(e)for(const[i,n]of Object.entries(e)){const e=Object.assign({},n,{id:`link${wi(i)}`});t.push(e);}return t}(e.config.get("link.decorators")));this._enableAutomaticDecorators(i.filter((e=>e.mode===BT))),this._enableManualDecorators(i.filter((e=>"manual"===e.mode)));e.plugins.get(Lw).registerAttribute("linkHref"),Xw(e,"linkHref","a","ck-link_selected"),this._enableLinkOpen(),this._enableSelectionAttributesFixer(),this._enableClipboardIntegration();}_enableAutomaticDecorators(e){const t=this.editor,i=t.commands.get("link").automaticDecorators;t.config.get("link.addTargetToExternalLinks")&&i.add({id:"linkIsExternal",mode:BT,callback:e=>!!e&&MT.test(e),attributes:{target:"_blank",rel:"noopener noreferrer"}}),i.add(e),i.length&&t.conversion.for("downcast").add(i.getDispatcher());}_enableManualDecorators(e){if(!e.length)return;const t=this.editor,i=t.commands.get("link").manualDecorators;e.forEach((e=>{t.model.schema.extend("$text",{allowAttributes:e.id});const n=new OT(e);i.add(n),t.conversion.for("downcast").attributeToElement({model:n.id,view:(e,{writer:t,schema:i},{item:s})=>{if((s.is("selection")||i.isInline(s))&&e){const e=t.createAttributeElement("a",n.attributes,{priority:5});n.classes&&t.addClass(n.classes,e);for(const i in n.styles)t.setStyle(i,n.styles[i],e);return t.setCustomProperty("link",!0,e),e}}}),t.conversion.for("upcast").elementToAttribute({view:{name:"a",...n._createPattern()},model:{key:n.id}});}));}_enableLinkOpen(){const e=this.editor,t=e.editing.view.document;this.listenTo(t,"click",((e,t)=>{if(!(o.isMac?t.domEvent.metaKey:t.domEvent.ctrlKey))return;let i=t.domTarget;if("a"!=i.tagName.toLowerCase()&&(i=i.closest("a")),!i)return;const n=i.getAttribute("href");n&&(e.stop(),t.preventDefault(),ST(n));}),{context:"$capture"}),this.listenTo(t,"keydown",((t,i)=>{const n=e.commands.get("link").value;!!n&&i.keyCode===nr.enter&&i.altKey&&(t.stop(),ST(n));}));}_enableSelectionAttributesFixer(){const e=this.editor.model,t=e.document.selection;this.listenTo(t,"change:attribute",((i,{attributeKeys:n})=>{n.includes("linkHref")&&!t.hasAttribute("linkHref")&&e.change((t=>{var i;!function(e,t){e.removeSelectionAttribute("linkHref");for(const i of t)e.removeSelectionAttribute(i);}(t,(i=e.schema,i.getDefinition("$text").allowAttributes.filter((e=>e.startsWith("link")))));}));}));}_enableClipboardIntegration(){const e=this.editor,t=e.model,i=this.editor.config.get("link.defaultProtocol");i&&this.listenTo(e.plugins.get("ClipboardPipeline"),"contentInsertion",((e,n)=>{t.change((e=>{const t=e.createRangeIn(n.content);for(const n of t.getItems())if(n.hasAttribute("linkHref")){const t=TT(n.getAttribute("linkHref"),i);e.setAttribute("linkHref",t,n);}}));}));}}class FT extends lg{focusTracker=new _r;keystrokes=new Cr;urlInputView;saveButtonView;cancelButtonView;_manualDecoratorSwitches;children;_validators;_focusables=new zm;_focusCycler;constructor(e,t,i){super(e);const n=e.t;this._validators=i,this.urlInputView=this._createUrlInput(),this.saveButtonView=this._createButton(n("Save"),vm.check,"ck-button-save"),this.saveButtonView.type="submit",this.cancelButtonView=this._createButton(n("Cancel"),vm.cancel,"ck-button-cancel","cancel"),this._manualDecoratorSwitches=this._createManualDecoratorSwitches(t),this.children=this._createFormChildren(t.manualDecorators),this._focusCycler=new _g({focusables:this._focusables,focusTracker:this.focusTracker,keystrokeHandler:this.keystrokes,actions:{focusPrevious:"shift + tab",focusNext:"tab"}});const s=["ck","ck-link-form","ck-responsive-form"];t.manualDecorators.length&&s.push("ck-link-form_layout-vertical","ck-vertical-form"),this.setTemplate({tag:"form",attributes:{class:s,tabindex:"-1"},children:this.children});}getDecoratorSwitchesState(){return Array.from(this._manualDecoratorSwitches).reduce(((e,t)=>(e[t.name]=t.isOn,e)),{})}render(){super.render(),hg({view:this});[this.urlInputView,...this._manualDecoratorSwitches,this.saveButtonView,this.cancelButtonView].forEach((e=>{this._focusables.add(e),this.focusTracker.add(e.element);})),this.keystrokes.listenTo(this.element);}destroy(){super.destroy(),this.focusTracker.destroy(),this.keystrokes.destroy();}focus(){this._focusCycler.focusFirst();}isValid(){this.resetFormStatus();for(const e of this._validators){const t=e(this);if(t)return this.urlInputView.errorText=t,!1}return !0}resetFormStatus(){this.urlInputView.errorText=null;}_createUrlInput(){const e=this.locale.t,t=new pf(this.locale,cp);return t.fieldView.inputMode="url",t.label=e("Link URL"),t}_createButton(e,t,i,n){const s=new pg(this.locale);return s.set({label:e,icon:t,tooltip:!0}),s.extendTemplate({attributes:{class:i}}),n&&s.delegate("execute").to(this,n),s}_createManualDecoratorSwitches(e){const t=this.createCollection();for(const i of e.manualDecorators){const n=new Dg(this.locale);n.set({name:i.id,label:i.label,withText:!0}),n.bind("isOn").toMany([i,e],"value",((e,t)=>void 0===t&&void 0===e?!!i.defaultValue:!!e)),n.on("execute",(()=>{i.set("value",!n.isOn);})),t.add(n);}return t}_createFormChildren(e){const t=this.createCollection();if(t.add(this.urlInputView),e.length){const e=new lg;e.setTemplate({tag:"ul",children:this._manualDecoratorSwitches.map((e=>({tag:"li",children:[e],attributes:{class:["ck","ck-list__item"]}}))),attributes:{class:["ck","ck-reset","ck-list"]}}),t.add(e);}return t.add(this.saveButtonView),t.add(this.cancelButtonView),t}get url(){const{element:e}=this.urlInputView.fieldView;return e?e.value.trim():null}}class NT extends lg{focusTracker=new _r;keystrokes=new Cr;previewButtonView;unlinkButtonView;editButtonView;_focusables=new zm;_focusCycler;_linkConfig;constructor(e,t={}){super(e);const i=e.t;this.previewButtonView=this._createPreviewButton(),this.unlinkButtonView=this._createButton(i("Unlink"),'',"unlink"),this.editButtonView=this._createButton(i("Edit link"),vm.pencil,"edit"),this.set("href",void 0),this._linkConfig=t,this._focusCycler=new _g({focusables:this._focusables,focusTracker:this.focusTracker,keystrokeHandler:this.keystrokes,actions:{focusPrevious:"shift + tab",focusNext:"tab"}}),this.setTemplate({tag:"div",attributes:{class:["ck","ck-link-actions","ck-responsive-form"],tabindex:"-1"},children:[this.previewButtonView,this.editButtonView,this.unlinkButtonView]});}render(){super.render();[this.previewButtonView,this.editButtonView,this.unlinkButtonView].forEach((e=>{this._focusables.add(e),this.focusTracker.add(e.element);})),this.keystrokes.listenTo(this.element);}destroy(){super.destroy(),this.focusTracker.destroy(),this.keystrokes.destroy();}focus(){this._focusCycler.focusFirst();}_createButton(e,t,i){const n=new pg(this.locale);return n.set({label:e,icon:t,tooltip:!0}),n.delegate("execute").to(this,i),n}_createPreviewButton(){const e=new pg(this.locale),t=this.bindTemplate,i=this.t;return e.set({withText:!0,tooltip:i("Open link in new tab")}),e.extendTemplate({attributes:{class:["ck","ck-link-actions__preview"],href:t.to("href",(e=>e&&AT(e,this._linkConfig.allowedProtocols))),target:"_blank",rel:"noopener noreferrer"}}),e.bind("label").to(this,"href",(e=>e||i("This link has no URL"))),e.bind("isEnabled").to(this,"href",(e=>!!e)),e.template.tag="a",e.template.eventListeners={},e}}var DT='';const zT="link-ui";class HT extends Dr{actionsView=null;formView=null;_balloon;static get requires(){return [Db]}static get pluginName(){return "LinkUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=this.editor.t;e.editing.view.addObserver(Uu),this._balloon=e.plugins.get(Db),this._createToolbarLinkButton(),this._enableBalloonActivators(),e.conversion.for("editingDowncast").markerToHighlight({model:zT,view:{classes:["ck-fake-link-selection"]}}),e.conversion.for("editingDowncast").markerToElement({model:zT,view:(e,{writer:t})=>{if(!e.markerRange.isCollapsed)return null;const i=t.createUIElement("span");return t.addClass(["ck-fake-link-selection","ck-fake-link-selection_collapsed"],i),i}}),e.accessibility.addKeystrokeInfos({keystrokes:[{label:t("Create link"),keystroke:CT},{label:t("Move out of a link"),keystroke:[["arrowleft","arrowleft"],["arrowright","arrowright"]]}]});}destroy(){super.destroy(),this.formView&&this.formView.destroy(),this.actionsView&&this.actionsView.destroy();}_createViews(){this.actionsView=this._createActionsView(),this.formView=this._createFormView(),this._enableUserBalloonInteractions();}_createActionsView(){const e=this.editor,t=new NT(e.locale,e.config.get("link")),i=e.commands.get("link"),n=e.commands.get("unlink");return t.bind("href").to(i,"value"),t.editButtonView.bind("isEnabled").to(i),t.unlinkButtonView.bind("isEnabled").to(n),this.listenTo(t,"edit",(()=>{this._addFormView();})),this.listenTo(t,"unlink",(()=>{e.execute("unlink"),this._hideUI();})),t.keystrokes.set("Esc",((e,t)=>{this._hideUI(),t();})),t.keystrokes.set(CT,((e,t)=>{this._addFormView(),t();})),t}_createFormView(){const e=this.editor,t=e.commands.get("link"),i=e.config.get("link.defaultProtocol"),n=new(ug(FT))(e.locale,t,function(e){const t=e.t,i=e.config.get("link.allowCreatingEmptyLinks");return [e=>{if(!i&&!e.url.length)return t("Link URL must not be empty.")}]}(e));return n.urlInputView.fieldView.bind("value").to(t,"value"),n.urlInputView.bind("isEnabled").to(t,"isEnabled"),n.saveButtonView.bind("isEnabled").to(t,"isEnabled"),this.listenTo(n,"submit",(()=>{if(n.isValid()){const{value:t}=n.urlInputView.fieldView.element,s=TT(t,i);e.execute("link",s,n.getDecoratorSwitchesState()),this._closeFormView();}})),this.listenTo(n.urlInputView,"change:errorText",(()=>{e.ui.update();})),this.listenTo(n,"cancel",(()=>{this._closeFormView();})),n.keystrokes.set("Esc",((e,t)=>{this._closeFormView(),t();})),n}_createToolbarLinkButton(){const e=this.editor;e.ui.componentFactory.add("link",(()=>{const e=this._createButton(pg);return e.set({tooltip:!0}),e})),e.ui.componentFactory.add("menuBar:link",(()=>{const e=this._createButton(Rg);return e.set({role:"menuitemcheckbox"}),e}));}_createButton(e){const t=this.editor,i=t.locale,n=t.commands.get("link"),s=new e(t.locale),o=i.t;return s.set({label:o("Link"),icon:DT,keystroke:CT,isToggleable:!0}),s.bind("isEnabled").to(n,"isEnabled"),s.bind("isOn").to(n,"value",(e=>!!e)),this.listenTo(s,"execute",(()=>this._showUI(!0))),s}_enableBalloonActivators(){const e=this.editor,t=e.editing.view.document;this.listenTo(t,"click",(()=>{this._getSelectedLinkElement()&&this._showUI();})),e.keystrokes.set(CT,((t,i)=>{i(),e.commands.get("link").isEnabled&&this._showUI(!0);}));}_enableUserBalloonInteractions(){this.editor.keystrokes.set("Tab",((e,t)=>{this._areActionsVisible&&!this.actionsView.focusTracker.isFocused&&(this.actionsView.focus(),t());}),{priority:"high"}),this.editor.keystrokes.set("Esc",((e,t)=>{this._isUIVisible&&(this._hideUI(),t());})),cg({emitter:this.formView,activator:()=>this._isUIInPanel,contextElements:()=>[this._balloon.view.element],callback:()=>this._hideUI()});}_addActionsView(){this.actionsView||this._createViews(),this._areActionsInPanel||this._balloon.add({view:this.actionsView,position:this._getBalloonPositionData()});}_addFormView(){if(this.formView||this._createViews(),this._isFormInPanel)return;const e=this.editor.commands.get("link");this.formView.disableCssTransitions(),this.formView.resetFormStatus(),this._balloon.add({view:this.formView,position:this._getBalloonPositionData()}),this.formView.urlInputView.fieldView.value=e.value||"",this._balloon.visibleView===this.formView&&this.formView.urlInputView.fieldView.select(),this.formView.enableCssTransitions();}_closeFormView(){const e=this.editor.commands.get("link");e.restoreManualDecoratorStates(),void 0!==e.value?this._removeFormView():this._hideUI();}_removeFormView(){this._isFormInPanel&&(this.formView.saveButtonView.focus(),this.formView.urlInputView.fieldView.reset(),this._balloon.remove(this.formView),this.editor.editing.view.focus(),this._hideFakeVisualSelection());}_showUI(e=!1){this.formView||this._createViews(),this._getSelectedLinkElement()?(this._areActionsVisible?this._addFormView():this._addActionsView(),e&&this._balloon.showStack("main")):(this._showFakeVisualSelection(),this._addActionsView(),e&&this._balloon.showStack("main"),this._addFormView()),this._startUpdatingUI();}_hideUI(){if(!this._isUIInPanel)return;const e=this.editor;this.stopListening(e.ui,"update"),this.stopListening(this._balloon,"change:visibleView"),e.editing.view.focus(),this._removeFormView(),this._balloon.remove(this.actionsView),this._hideFakeVisualSelection();}_startUpdatingUI(){const e=this.editor,t=e.editing.view.document;let i=this._getSelectedLinkElement(),n=o();const s=()=>{const e=this._getSelectedLinkElement(),t=o();i&&!e||!i&&t!==n?this._hideUI():this._isUIVisible&&this._balloon.updatePosition(this._getBalloonPositionData()),i=e,n=t;};function o(){return t.selection.focus.getAncestors().reverse().find((e=>e.is("element")))}this.listenTo(e.ui,"update",s),this.listenTo(this._balloon,"change:visibleView",s);}get _isFormInPanel(){return !!this.formView&&this._balloon.hasView(this.formView)}get _areActionsInPanel(){return !!this.actionsView&&this._balloon.hasView(this.actionsView)}get _areActionsVisible(){return !!this.actionsView&&this._balloon.visibleView===this.actionsView}get _isUIInPanel(){return this._isFormInPanel||this._areActionsInPanel}get _isUIVisible(){const e=this._balloon.visibleView;return !!this.formView&&e==this.formView||this._areActionsVisible}_getBalloonPositionData(){const e=this.editor.editing.view,t=this.editor.model,i=e.document;let n;if(t.markers.has(zT)){const t=Array.from(this.editor.editing.mapper.markerNameToElements(zT)),i=e.createRange(e.createPositionBefore(t[0]),e.createPositionAfter(t[t.length-1]));n=e.domConverter.viewRangeToDom(i);}else n=()=>{const t=this._getSelectedLinkElement();return t?e.domConverter.mapViewToDom(t):e.domConverter.viewRangeToDom(i.selection.getFirstRange())};return {target:n}}_getSelectedLinkElement(){const e=this.editor.editing.view,t=e.document.selection,i=t.getSelectedElement();if(t.isCollapsed||i&&sy(i))return $T(t.getFirstPosition());{const i=t.getFirstRange().getTrimmed(),n=$T(i.start),s=$T(i.end);return n&&n==s&&e.createRangeIn(n).getTrimmed().isEqual(i)?n:null}}_showFakeVisualSelection(){const e=this.editor.model;e.change((t=>{const i=e.document.selection.getFirstRange();if(e.markers.has(zT))t.updateMarker(zT,{range:i});else if(i.start.isAtEnd){const n=i.start.getLastMatchingPosition((({item:t})=>!e.schema.isContent(t)),{boundaries:i});t.addMarker(zT,{usingOperation:!1,affectsData:!1,range:t.createRange(n,i.end)});}else t.addMarker(zT,{usingOperation:!1,affectsData:!1,range:i});}));}_hideFakeVisualSelection(){const e=this.editor.model;e.markers.has(zT)&&e.change((e=>{e.removeMarker(zT);}));}}function $T(e){return e.getAncestors().find((e=>{return (t=e).is("attributeElement")&&!!t.getCustomProperty("link");var t;}))||null}const UT=new RegExp("(^|\\s)(((?:(?:(?:https?|ftp):)?\\/\\/)(?:\\S+(?::\\S*)?@)?(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(((?!www\\.)|(www\\.))(?![-_])(?:[-_a-z0-9\\u00a1-\\uffff]{1,63}\\.)+(?:[a-z\\u00a1-\\uffff]{2,63})))(?::\\d{2,5})?(?:[/?#]\\S*)?)|((www.|(\\S+@))((?![-_])(?:[-_a-z0-9\\u00a1-\\uffff]{1,63}\\.))+(?:[a-z\\u00a1-\\uffff]{2,63})))$","i");class WT extends Dr{static get requires(){return [Rw,LT]}static get pluginName(){return "AutoLink"}static get isOfficialPlugin(){return !0}init(){const e=this.editor.model.document.selection;e.on("change:range",(()=>{this.isEnabled=!e.anchor.parent.is("element","codeBlock");})),this._enableTypingHandling();}afterInit(){this._enableEnterHandling(),this._enableShiftEnterHandling(),this._enablePasteLinking();}_expandLinkRange(e,t){return t.textNode&&t.textNode.hasAttribute("linkHref")?Qw(t,"linkHref",t.textNode.getAttribute("linkHref"),e):null}_selectEntireLinks(e,t){const i=this.editor.model,n=i.document.selection,s=n.getFirstPosition(),o=n.getLastPosition();let r=t.getJoined(this._expandLinkRange(i,s)||t);r&&(r=r.getJoined(this._expandLinkRange(i,o)||t)),r&&(r.start.isBefore(s)||r.end.isAfter(o))&&e.setSelection(r);}_enablePasteLinking(){const e=this.editor,t=e.model,i=t.document.selection,n=e.plugins.get("ClipboardPipeline"),s=e.commands.get("link");n.on("inputTransformation",((e,n)=>{if(!this.isEnabled||!s.isEnabled||i.isCollapsed||"paste"!==n.method)return;if(i.rangeCount>1)return;const o=i.getFirstRange(),r=n.dataTransfer.getData("text/plain");if(!r)return;const a=r.match(UT);a&&a[2]===r&&(t.change((e=>{this._selectEntireLinks(e,o),s.execute(r);})),e.stop());}),{priority:"high"});}_enableTypingHandling(){const e=this.editor,t=new Mw(e.model,(e=>{if(!function(e){return e.length>4&&" "===e[e.length-1]&&" "!==e[e.length-2]}(e))return;const t=jT(e.substr(0,e.length-1));return t?{url:t}:void 0}));t.on("matched:data",((t,i)=>{const{batch:n,range:s,url:o}=i;if(!n.isTyping)return;const r=s.end.getShiftedBy(-1),a=r.getShiftedBy(-o.length),l=e.model.createRange(a,r);this._applyAutoLink(o,l);})),t.bind("isEnabled").to(this);}_enableEnterHandling(){const e=this.editor,t=e.model,i=e.commands.get("enter");i&&i.on("execute",(()=>{const e=t.document.selection.getFirstPosition();if(!e.parent.previousSibling)return;const i=t.createRangeIn(e.parent.previousSibling);this._checkAndApplyAutoLinkOnRange(i);}));}_enableShiftEnterHandling(){const e=this.editor,t=e.model,i=e.commands.get("shiftEnter");i&&i.on("execute",(()=>{const e=t.document.selection.getFirstPosition(),i=t.createRange(t.createPositionAt(e.parent,0),e.getShiftedBy(-1));this._checkAndApplyAutoLinkOnRange(i);}));}_checkAndApplyAutoLinkOnRange(e){const t=this.editor.model,{text:i,range:n}=Bw(e,t),s=jT(i);if(s){const e=t.createRange(n.end.getShiftedBy(-s.length),n.end);this._applyAutoLink(s,e);}}_applyAutoLink(e,t){const i=this.editor.model,n=TT(e,this.editor.config.get("link.defaultProtocol"));this.isEnabled&&function(e,t){return t.schema.checkAttributeInSelection(t.createSelection(e),"linkHref")}(t,i)&&PT(n)&&!function(e){const t=e.start.nodeAfter;return !!t&&t.hasAttribute("linkHref")}(t)&&this._persistAutoLink(n,t);}_persistAutoLink(e,t){const i=this.editor.model,n=this.editor.plugins.get("Delete");i.enqueueChange((s=>{s.setAttribute("linkHref",e,t),i.enqueueChange((()=>{n.requestUndoOnBackspace();}));}));}}function jT(e){const t=UT.exec(e);return t?t[2]:null}class qT extends Dr{static get requires(){return [LT,HT,WT]}static get pluginName(){return "Link"}static get isOfficialPlugin(){return !0}}class GT extends Dr{static get requires(){return ["ImageEditing","ImageUtils",LT]}static get pluginName(){return "LinkImageEditing"}static get isOfficialPlugin(){return !0}afterInit(){const e=this.editor,t=e.model.schema;e.plugins.has("ImageBlockEditing")&&t.extend("imageBlock",{allowAttributes:["linkHref"]}),e.conversion.for("upcast").add(function(e){const t=e.plugins.has("ImageInlineEditing"),i=e.plugins.get("ImageUtils");return e=>{e.on("element:a",((e,n,s)=>{const o=n.viewItem,r=i.findViewImgElement(o);if(!r)return;const a=r.findAncestor((e=>i.isBlockImageView(e)));if(t&&!a)return;const l={attributes:["href"]};if(!s.consumable.consume(o,l))return;const c=o.getAttribute("href");if(!c)return;let d=n.modelCursor.parent;if(!d.is("element","imageBlock")){const e=s.convertItem(r,n.modelCursor);n.modelRange=e.modelRange,n.modelCursor=e.modelCursor,d=n.modelCursor.nodeBefore;}d&&d.is("element","imageBlock")&&s.writer.setAttribute("linkHref",c,d);}),{priority:"high"});}}(e)),e.conversion.for("downcast").add(function(e){const t=e.plugins.get("ImageUtils");return e=>{e.on("attribute:linkHref:imageBlock",((e,i,n)=>{if(!n.consumable.consume(i.item,e.name))return;const s=n.mapper.toViewElement(i.item),o=n.writer,r=Array.from(s.getChildren()).find((e=>e.is("element","a"))),a=t.findViewImgElement(s),l=a.parent.is("element","picture")?a.parent:a;if(r)i.attributeNewValue?o.setAttribute("href",i.attributeNewValue,r):(o.move(o.createRangeOn(l),o.createPositionAt(s,0)),o.remove(r));else {const e=o.createContainerElement("a",{href:i.attributeNewValue});o.insert(o.createPositionAt(s,0),e),o.move(o.createRangeOn(l),o.createPositionAt(e,0));}}),{priority:"high"});}}(e)),this._enableAutomaticDecorators(),this._enableManualDecorators();}_enableAutomaticDecorators(){const e=this.editor,t=e.commands.get("link").automaticDecorators;t.length&&e.conversion.for("downcast").add(t.getDispatcherForLinkedImage());}_enableManualDecorators(){const e=this.editor,t=e.commands.get("link");for(const i of t.manualDecorators)e.plugins.has("ImageBlockEditing")&&e.model.schema.extend("imageBlock",{allowAttributes:i.id}),e.plugins.has("ImageInlineEditing")&&e.model.schema.extend("imageInline",{allowAttributes:i.id}),e.conversion.for("downcast").add(KT(i)),e.conversion.for("upcast").add(ZT(e,i));}}function KT(e){return t=>{t.on(`attribute:${e.id}:imageBlock`,((t,i,n)=>{const s=n.mapper.toViewElement(i.item),o=Array.from(s.getChildren()).find((e=>e.is("element","a")));if(o){for(const[t,i]of xr(e.attributes))n.writer.setAttribute(t,i,o);e.classes&&n.writer.addClass(e.classes,o);for(const t in e.styles)n.writer.setStyle(t,e.styles[t],o);}}));}}function ZT(e,t){const i=e.plugins.has("ImageInlineEditing"),n=e.plugins.get("ImageUtils");return e=>{e.on("element:a",((e,s,o)=>{const r=s.viewItem,a=n.findViewImgElement(r);if(!a)return;const l=a.findAncestor((e=>n.isBlockImageView(e)));if(i&&!l)return;const c=new aa(t._createPattern()).match(r);if(!c)return;if(!o.consumable.consume(r,c.match))return;const d=s.modelCursor.nodeBefore||s.modelCursor.parent;o.writer.setAttribute(t.id,!0,d);}),{priority:"high"});}}class JT extends Dr{static get requires(){return [LT,HT,"ImageBlockEditing"]}static get pluginName(){return "LinkImageUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.editing.view.document;this.listenTo(t,"click",((t,i)=>{this._isSelectedLinkedImage(e.model.document.selection)&&(i.preventDefault(),t.stop());}),{priority:"high"}),this._createToolbarLinkImageButton();}_createToolbarLinkImageButton(){const e=this.editor,t=e.t;e.ui.componentFactory.add("linkImage",(i=>{const n=new pg(i),s=e.plugins.get("LinkUI"),o=e.commands.get("link");return n.set({isEnabled:!0,label:t("Link image"),icon:DT,keystroke:CT,tooltip:!0,isToggleable:!0}),n.bind("isEnabled").to(o,"isEnabled"),n.bind("isOn").to(o,"value",(e=>!!e)),this.listenTo(n,"execute",(()=>{this._isSelectedLinkedImage(e.model.document.selection)?s._addActionsView():s._showUI(!0);})),n}));}_isSelectedLinkedImage(e){const t=e.getSelectedElement();return this.editor.plugins.get("ImageUtils").isImage(t)&&t.hasAttribute("linkHref")}}class QT extends Dr{static get requires(){return [GT,JT]}static get pluginName(){return "LinkImage"}static get isOfficialPlugin(){return !0}}class YT{_startElement;_referenceIndent;_isForward;_includeSelf;_sameAttributes;_sameIndent;_lowerIndent;_higherIndent;constructor(e,t){this._startElement=e,this._referenceIndent=e.getAttribute("listIndent"),this._isForward="forward"==t.direction,this._includeSelf=!!t.includeSelf,this._sameAttributes=gr(t.sameAttributes||[]),this._sameIndent=!!t.sameIndent,this._lowerIndent=!!t.lowerIndent,this._higherIndent=!!t.higherIndent;}static first(e,t){return wr(new this(e,t)[Symbol.iterator]())}*[Symbol.iterator](){const e=[];for(const{node:t}of XT(this._getStartNode(),this._isForward?"forward":"backward")){const i=t.getAttribute("listIndent");if(ithis._referenceIndent){if(!this._higherIndent)continue;if(!this._isForward){e.push(t);continue}}else {if(!this._sameIndent){if(this._higherIndent){e.length&&(yield*e,e.length=0);break}continue}if(this._sameAttributes.some((e=>t.getAttribute(e)!==this._startElement.getAttribute(e))))break}e.length&&(yield*e,e.length=0),yield t;}}_getStartNode(){return this._includeSelf?this._startElement:this._isForward?this._startElement.nextSibling:this._startElement.previousSibling}}function*XT(e,t="forward"){const i="forward"==t,n=[];let s=null;for(;iP(e);){let t=null;if(s){const i=e.getAttribute("listIndent"),o=s.getAttribute("listIndent");i>o?n[o]=s:ie.getAttribute("listItemId")!=t))}function fP(e){return Array.from(e).filter((e=>"$graveyard"!==e.root.rootName)).sort(((e,t)=>e.index-t.index))}function pP(e){const t=e.document.selection.getSelectedElement();return t&&e.schema.isObject(t)&&e.schema.isBlock(t)?t:null}function bP(e,t){return t.checkChild(e.parent,"listItem")&&t.checkChild(e,"$text")&&!t.isObject(e)}function wP(e){return "numbered"==e||"customNumbered"==e}function _P(e,t,i){return sP(t,{direction:"forward"}).pop().index>e.index?uP(e,t,i):[]}class vP extends Hr{_direction;constructor(e,t){super(e),this._direction=t;}refresh(){this.isEnabled=this._checkEnabled();}execute(){const e=this.editor.model,t=yP(e.document.selection);e.change((e=>{const i=[];gP(t)&&!rP(t[0])?("forward"==this._direction&&i.push(...hP(t,e)),i.push(...dP(t[0],e))):"forward"==this._direction?i.push(...hP(t,e,{expand:!0})):i.push(...function(e,t){const i=lP(e=gr(e)),n=new Set,s=Math.min(...i.map((e=>e.getAttribute("listIndent")))),o=new Map;for(const e of i)o.set(e,YT.first(e,{lowerIndent:!0}));for(const e of i){if(n.has(e))continue;n.add(e);const i=e.getAttribute("listIndent")-1;if(i<0)mP(e,t);else {if(e.getAttribute("listIndent")==s){const i=_P(e,o.get(e),t);for(const e of i)n.add(e);if(i.length)continue}t.setAttribute("listIndent",i,e);}}return fP(n)}(t,e));for(const t of i){if(!t.hasAttribute("listType"))continue;const i=YT.first(t,{sameIndent:!0});i&&e.setAttribute("listType",i.getAttribute("listType"),t);}this._fireAfterExecute(i);}));}_fireAfterExecute(e){this.fire("afterExecute",fP(new Set(e)));}_checkEnabled(){let e=yP(this.editor.model.document.selection),t=e[0];if(!t)return !1;if("backward"==this._direction)return !0;if(gP(e)&&!rP(e[0]))return !0;e=lP(e),t=e[0];const i=YT.first(t,{sameIndent:!0});return !!i&&i.getAttribute("listType")==t.getAttribute("listType")}}function yP(e){const t=Array.from(e.getSelectedBlocks()),i=t.findIndex((e=>!iP(e)));return -1!=i&&(t.length=i),t}class kP extends Hr{type;_listWalkerOptions;constructor(e,t,i={}){super(e),this.type=t,this._listWalkerOptions=i.multiLevel?{higherIndent:!0,lowerIndent:!0,sameAttributes:[]}:void 0;}refresh(){this.value=this._getValue(),this.isEnabled=this._checkEnabled();}execute(e={}){const t=this.editor.model,i=t.document,n=pP(t),s=Array.from(i.selection.getSelectedBlocks()).filter((e=>t.schema.checkAttribute(e,"listType")||bP(e,t.schema))),o=void 0!==e.forceValue?!e.forceValue:this.value;t.change((r=>{if(o){const e=s[s.length-1],t=sP(e,{direction:"forward"}),i=[];t.length>1&&i.push(...dP(t[1],r)),i.push(...mP(s,r)),i.push(...function(e,t){const i=[];let n=Number.POSITIVE_INFINITY;for(const{node:s}of XT(e.nextSibling,"forward")){const e=s.getAttribute("listIndent");if(0==e)break;e{const{firstElement:o,lastElement:r}=this._getMergeSubjectElements(i,e),a=o.getAttribute("listIndent")||0,l=r.getAttribute("listIndent"),c=r.getAttribute("listItemId");if(a!=l){const e=(d=r,Array.from(new YT(d,{direction:"forward",higherIndent:!0})));n.push(...hP([r,...e],s,{indentBy:a-l,expand:a{const t=dP(this._getStartBlock(),e);this._fireAfterExecute(t);}));}_fireAfterExecute(e){this.fire("afterExecute",fP(new Set(e)));}_checkEnabled(){const e=this.editor.model.document.selection,t=this._getStartBlock();return e.isCollapsed&&iP(t)&&!rP(t)}_getStartBlock(){const e=this.editor.model.document.selection.getFirstPosition().parent;return "before"==this._direction?e:e.nextSibling}}class AP extends Dr{static get pluginName(){return "ListUtils"}static get isOfficialPlugin(){return !0}expandListBlocksToCompleteList(e){return cP(e)}isFirstBlockOfListItem(e){return rP(e)}isListItemBlock(e){return iP(e)}expandListBlocksToCompleteItems(e,t={}){return lP(e,t)}isNumberedListType(e){return wP(e)}}function EP(e){return e.is("element","ol")||e.is("element","ul")}function TP(e){return e.is("element","li")}function PP(e,t,i,n=VP(i,t)){return e.createAttributeElement(IP(i),null,{priority:2*t/100-100,id:n})}function SP(e,t,i){return e.createAttributeElement("li",null,{priority:(2*t+1)/100-100,id:i})}function IP(e){return "numbered"==e||"customNumbered"==e?"ol":"ul"}function VP(e,t){return `list-${e}-${t}`}function RP(e,t){const i=e.nodeBefore;if(iP(i)){let e=i;for(const{node:i}of XT(e,"backward"))if(e=i,t.has(e))return;t.set(i,e);}else {const i=e.nodeAfter;iP(i)&&t.set(i,i);}}function OP(){return (e,t,i)=>{const{writer:n,schema:s}=i;if(!t.modelRange)return;const o=Array.from(t.modelRange.getItems({shallow:!0})).filter((e=>s.checkAttribute(e,"listItemId")));if(!o.length)return;const r=tP.next(),a=function(e){let t=0,i=e.parent;for(;i;){if(TP(i))t++;else {const e=i.previousSibling;e&&TP(e)&&t++;}i=i.parent;}return t}(t.viewItem);let l=t.viewItem.parent&&t.viewItem.parent.is("element","ol")?"numbered":"bulleted";const c=o[0].getAttribute("listType");c&&(l=c);const d={listItemId:r,listIndent:a,listType:l};for(const e of o)e.hasAttribute("listItemId")||n.setAttributes(d,e);o.length>1&&o[1].getAttribute("listItemId")!=d.listItemId&&i.keepEmptyElement(o[0]);}}function BP(e,t,i,{dataPipeline:n}={}){const s=function(e){return (t,i)=>{const n=[];for(const i of e)t.hasAttribute(i)&&n.push(`attribute:${i}`);return !!n.every((e=>!1!==i.test(t,e)))&&(n.forEach((e=>i.consume(t,e))),!0)}}(e);return (o,r,a)=>{const{writer:l,mapper:c,consumable:d}=a,u=r.item;if(!e.includes(r.attributeKey))return;if(!s(u,d))return;const h=function(e,t,i){const n=i.createRangeOn(e),s=t.toViewRange(n).getTrimmed();return s.end.nodeBefore}(u,c,i);LP(h,l,c),function(e,t){let i=e.parent;for(;i.is("attributeElement")&&["ul","ol","li"].includes(i.name);){const n=i.parent;t.unwrap(t.createRangeOn(e),i),i=n;}}(h,l);const m=function(e,t,i,n,{dataPipeline:s}){let o=n.createRangeOn(t);if(!rP(e))return o;for(const r of i){if("itemMarker"!=r.scope)continue;const i=r.createElement(n,e,{dataPipeline:s});if(!i)continue;if(n.setCustomProperty("listItemMarker",!0,i),r.canInjectMarkerIntoElement&&r.canInjectMarkerIntoElement(e)?n.insert(n.createPositionAt(t,0),i):(n.insert(o.start,i),o=n.createRange(n.createPositionBefore(i),n.createPositionAfter(t))),!r.createWrapperElement||!r.canWrapElement)continue;const a=r.createWrapperElement(n,e,{dataPipeline:s});n.setCustomProperty("listItemWrapper",!0,a),r.canWrapElement(e)?o=n.wrap(o,a):(o=n.wrap(n.createRangeOn(i),a),o=n.createRange(o.start,n.createPositionAfter(t)));}return o}(u,h,t,l,{dataPipeline:n});!function(e,t,i,n){if(!e.hasAttribute("listIndent"))return;const s=e.getAttribute("listIndent");let o=e;for(let e=s;e>=0;e--){const s=SP(n,e,o.getAttribute("listItemId")),r=PP(n,e,o.getAttribute("listType"));for(const e of i)"list"!=e.scope&&"item"!=e.scope||!o.hasAttribute(e.attributeName)||e.setAttributeOnDowncast(n,o.getAttribute(e.attributeName),"list"==e.scope?r:s);if(t=n.wrap(t,s),t=n.wrap(t,r),0==e)break;if(o=YT.first(o,{lowerIndent:!0}),!o)break}}(u,m,t,l);}}function MP(e,{dataPipeline:t}={}){return (i,{writer:n})=>{if(!FP(i,e))return null;if(!t)return n.createContainerElement("span",{class:"ck-list-bogus-paragraph"});const s=n.createContainerElement("p");return n.setCustomProperty("dataPipeline:transparentRendering",!0,s),s}}function LP(e,t,i){for(;e.parent.is("attributeElement")&&e.parent.getCustomProperty("listItemWrapper");)t.unwrap(t.createRangeOn(e),e.parent);const n=[];s(t.createPositionBefore(e).getWalker({direction:"backward"})),s(t.createRangeIn(e).getWalker());for(const e of n)t.remove(e);function s(e){for(const{item:t}of e){if(t.is("element")&&i.toModelElement(t))break;t.is("element")&&t.getCustomProperty("listItemMarker")&&n.push(t);}}}function FP(e,t,i=nP(e)){if(!iP(e))return !1;for(const i of e.getAttributeKeys())if(!i.startsWith("selection:")&&!t.includes(i))return !1;return i.length<2}const NP=["listType","listIndent","listItemId"];class DP extends Dr{_downcastStrategies=[];static get pluginName(){return "ListEditing"}static get isOfficialPlugin(){return !0}static get requires(){return [K_,Rw,AP,Jv]}constructor(e){super(e),e.config.define("list.multiBlock",!0);}init(){const e=this.editor,t=e.model,i=e.config.get("list.multiBlock");if(e.plugins.has("LegacyListEditing"))throw new A("list-feature-conflict",this,{conflictPlugin:"LegacyListEditing"});t.schema.register("$listItem",{allowAttributes:NP}),i?(t.schema.extend("$container",{allowAttributesOf:"$listItem"}),t.schema.extend("$block",{allowAttributesOf:"$listItem"}),t.schema.extend("$blockObject",{allowAttributesOf:"$listItem"})):t.schema.register("listItem",{inheritAllFrom:"$block",allowAttributesOf:"$listItem"});for(const e of NP)t.schema.setAttributeProperties(e,{copyOnReplace:!0});e.commands.add("numberedList",new kP(e,"numbered")),e.commands.add("bulletedList",new kP(e,"bulleted")),e.commands.add("customNumberedList",new kP(e,"customNumbered",{multiLevel:!0})),e.commands.add("customBulletedList",new kP(e,"customBulleted",{multiLevel:!0})),e.commands.add("indentList",new vP(e,"forward")),e.commands.add("outdentList",new vP(e,"backward")),e.commands.add("splitListItemBefore",new xP(e,"before")),e.commands.add("splitListItemAfter",new xP(e,"after")),i&&(e.commands.add("mergeListItemBackward",new CP(e,"backward")),e.commands.add("mergeListItemForward",new CP(e,"forward"))),this._setupDeleteIntegration(),this._setupEnterIntegration(),this._setupTabIntegration(),this._setupClipboardIntegration(),this._setupAccessibilityIntegration();}afterInit(){const e=this.editor.commands,t=e.get("indent"),i=e.get("outdent");t&&t.registerChildCommand(e.get("indentList"),{priority:"high"}),i&&i.registerChildCommand(e.get("outdentList"),{priority:"lowest"}),this._setupModelPostFixing(),this._setupConversion();}registerDowncastStrategy(e){this._downcastStrategies.push(e);}getListAttributeNames(){return [...NP,...this._downcastStrategies.map((e=>e.attributeName))]}_setupDeleteIntegration(){const e=this.editor,t=e.commands.get("mergeListItemBackward"),i=e.commands.get("mergeListItemForward");this.listenTo(e.editing.view.document,"delete",((n,s)=>{const o=e.model.document.selection;pP(e.model)||e.model.change((()=>{const r=o.getFirstPosition();if(o.isCollapsed&&"backward"==s.direction){if(!r.isAtStart)return;const i=r.parent;if(!iP(i))return;if(YT.first(i,{sameAttributes:"listType",sameIndent:!0})||0!==i.getAttribute("listIndent")){if(!t||!t.isEnabled)return;t.execute({shouldMergeOnBlocksContentLevel:zP(e.model,"backward")});}else aP(i)||e.execute("splitListItemAfter"),e.execute("outdentList");s.preventDefault(),n.stop();}else {if(o.isCollapsed&&!o.getLastPosition().isAtEnd)return;if(!i||!i.isEnabled)return;i.execute({shouldMergeOnBlocksContentLevel:zP(e.model,"forward")}),s.preventDefault(),n.stop();}}));}),{context:"li"});}_setupEnterIntegration(){const e=this.editor,t=e.model,i=e.commands,n=i.get("enter");this.listenTo(e.editing.view.document,"enter",((i,n)=>{const s=t.document,o=s.selection.getFirstPosition().parent;if(s.selection.isCollapsed&&iP(o)&&o.isEmpty&&!n.isSoft){const t=rP(o),s=aP(o);t&&s?(e.execute("outdentList"),n.preventDefault(),i.stop()):t&&!s?(e.execute("splitListItemAfter"),n.preventDefault(),i.stop()):s&&(e.execute("splitListItemBefore"),n.preventDefault(),i.stop());}}),{context:"li"}),this.listenTo(n,"afterExecute",(()=>{const t=i.get("splitListItemBefore");if(t.refresh(),!t.isEnabled)return;2===nP(e.model.document.selection.getLastPosition().parent).length&&t.execute();}));}_setupTabIntegration(){const e=this.editor;this.listenTo(e.editing.view.document,"tab",((t,i)=>{const n=i.shiftKey?"outdentList":"indentList";this.editor.commands.get(n).isEnabled&&(e.execute(n),i.stopPropagation(),i.preventDefault(),t.stop());}),{context:"li"});}_setupConversion(){const e=this.editor,t=e.model,i=this.getListAttributeNames(),n=e.config.get("list.multiBlock"),s=n?"paragraph":"listItem";e.conversion.for("upcast").elementToElement({view:"li",model:(e,{writer:t})=>t.createElement(s,{listType:""})}).elementToElement({view:"p",model:(e,{writer:t})=>e.parent&&e.parent.is("element","li")?t.createElement(s,{listType:""}):null,converterPriority:"high"}).add((e=>{e.on("element:li",OP());})),n||e.conversion.for("downcast").elementToElement({model:"listItem",view:"p"}),e.conversion.for("editingDowncast").elementToElement({model:s,view:MP(i),converterPriority:"high"}).add((e=>{var n;e.on("attribute",BP(i,this._downcastStrategies,t)),e.on("remove",(n=t.schema,(e,t,i)=>{const{writer:s,mapper:o}=i,r=e.name.split(":")[1];if(!n.checkAttribute(r,"listItemId"))return;const a=o.toViewPosition(t.position),l=t.position.getShiftedBy(t.length),c=o.toViewPosition(l,{isPhantom:!0}),d=s.createRange(a,c).getTrimmed().end.nodeBefore;d&&LP(d,s,o);}));})),e.conversion.for("dataDowncast").elementToElement({model:s,view:MP(i,{dataPipeline:!0}),converterPriority:"high"}).add((e=>{e.on("attribute",BP(i,this._downcastStrategies,t,{dataPipeline:!0}));}));const o=(r=this._downcastStrategies,a=e.editing.view,(e,t)=>{if(t.modelPosition.offset>0)return;const i=t.modelPosition.parent;if(!iP(i))return;if(!r.some((e=>"itemMarker"==e.scope&&e.canInjectMarkerIntoElement&&e.canInjectMarkerIntoElement(i))))return;const n=t.mapper.toViewElement(i),s=a.createRangeIn(n),o=s.getWalker();let l=s.start;for(const{item:e}of o){if(e.is("element")&&t.mapper.toModelElement(e)||e.is("$textProxy"))break;e.is("element")&&e.getCustomProperty("listItemMarker")&&(l=a.createPositionAfter(e),o.skip((({previousPosition:e})=>!e.isEqual(l))));}t.viewPosition=l;});var r,a;e.editing.mapper.on("modelToViewPosition",o),e.data.mapper.on("modelToViewPosition",o),this.listenTo(t.document,"change:data",function(e,t,i,n){return ()=>{const n=e.document.differ.getChanges(),r=[],a=new Map,l=new Set;for(const e of n)if("insert"==e.type&&"$text"!=e.name)RP(e.position,a),e.attributes.has("listItemId")?l.add(e.position.nodeAfter):RP(e.position.getShiftedBy(e.length),a);else if("remove"==e.type&&e.attributes.has("listItemId"))RP(e.position,a);else if("attribute"==e.type){const t=e.range.start.nodeAfter;i.includes(e.attributeKey)?(RP(e.range.start,a),null===e.attributeNewValue?(RP(e.range.start.getShiftedBy(1),a),o(t)&&r.push(t)):l.add(t)):iP(t)&&o(t)&&r.push(t);}for(const e of a.values())r.push(...s(e,l));for(const e of new Set(r))t.reconvertItem(e);};function s(e,t){const n=[],s=new Set,a=[];for(const{node:l,previous:c}of XT(e,"forward")){if(s.has(l))continue;const e=l.getAttribute("listIndent");c&&ei.includes(e))));const d=sP(l,{direction:"forward"});for(const e of d)s.add(e),(o(e,d)||r(e,a,t))&&n.push(e);}return n}function o(e,s){const o=t.mapper.toViewElement(e);if(!o)return !1;if(n.fire("checkElement",{modelElement:e,viewElement:o}))return !0;if(!e.is("element","paragraph")&&!e.is("element","listItem"))return !1;const r=FP(e,i,s);return !(!r||!o.is("element","p"))||!(r||!o.is("element","span"))}function r(e,i,s){if(s.has(e))return !1;const o=t.mapper.toViewElement(e);let r=i.length-1;for(let e=o.parent;!e.is("editableElement");e=e.parent){const t=TP(e),s=EP(e);if(!s&&!t)continue;const o="checkAttributes:"+(t?"item":"list");if(n.fire(o,{viewElement:e,modelAttributes:i[r]}))break;if(s&&(r--,r<0))return !1}return !0}}(t,e.editing,i,this),{priority:"high"}),this.on("checkAttributes:item",((e,{viewElement:t,modelAttributes:i})=>{t.id!=i.listItemId&&(e.return=!0,e.stop());})),this.on("checkAttributes:list",((e,{viewElement:t,modelAttributes:i})=>{t.name==IP(i.listType)&&t.id==VP(i.listType,i.listIndent)||(e.return=!0,e.stop());}));}_setupModelPostFixing(){const e=this.editor.model,t=this.getListAttributeNames();e.document.registerPostFixer((i=>function(e,t,i,n){const s=e.document.differ.getChanges(),o=new Map,r=n.editor.config.get("list.multiBlock");let a=!1;for(const n of s){if("insert"==n.type&&"$text"!=n.name){const s=n.position.nodeAfter;if(!e.schema.checkAttribute(s,"listItemId"))for(const e of Array.from(s.getAttributeKeys()))i.includes(e)&&(t.removeAttribute(e,s),a=!0);RP(n.position,o),n.attributes.has("listItemId")||RP(n.position.getShiftedBy(n.length),o);for(const{item:t,previousPosition:i}of e.createRangeIn(s))iP(t)&&RP(i,o);}else "remove"==n.type?RP(n.position,o):"attribute"==n.type&&i.includes(n.attributeKey)&&(RP(n.range.start,o),null===n.attributeNewValue&&RP(n.range.start.getShiftedBy(1),o));if(!r&&"attribute"==n.type&&NP.includes(n.attributeKey)){const e=n.range.start.nodeAfter;null===n.attributeNewValue&&e&&e.is("element","listItem")?(t.rename(e,"paragraph"),a=!0):null===n.attributeOldValue&&e&&e.is("element")&&"listItem"!=e.name&&(t.rename(e,"listItem"),a=!0);}}const l=new Set;for(const e of o.values())a=n.fire("postFixer",{listNodes:new eP(e),listHead:e,writer:t,seenIds:l})||a;return a}(e,i,t,this))),this.on("postFixer",((e,{listNodes:t,writer:i})=>{e.return=function(e,t){let i=0,n=-1,s=null,o=!1;for(const{node:r}of e){const e=r.getAttribute("listIndent");if(e>i){let a;null===s?(s=e-i,a=i):(s>e&&(s=e),a=e-s),a>n+1&&(a=n+1),t.setAttribute("listIndent",a,r),o=!0,n=a;}else s=null,i=e+1,n=e;}return o}(t,i)||e.return;}),{priority:"high"}),this.on("postFixer",((e,{listNodes:t,writer:i,seenIds:n})=>{e.return=function(e,t,i){const n=new Set;let s=!1;for(const{node:o}of e){if(n.has(o))continue;let e=o.getAttribute("listType"),r=o.getAttribute("listItemId");if(t.has(r)&&(r=tP.next()),t.add(r),o.is("element","listItem"))o.getAttribute("listItemId")!=r&&(i.setAttribute("listItemId",r,o),s=!0);else for(const t of sP(o,{direction:"forward"}))n.add(t),t.getAttribute("listType")!=e&&(r=tP.next(),e=t.getAttribute("listType")),t.getAttribute("listItemId")!=r&&(i.setAttribute("listItemId",r,t),s=!0);}return s}(t,n,i)||e.return;}),{priority:"high"});}_setupClipboardIntegration(){const e=this.editor.model,t=this.editor.plugins.get("ClipboardPipeline");this.listenTo(e,"insertContent",function(e){return (t,[i,n])=>{const s=i.is("documentFragment")?Array.from(i.getChildren()):[i];if(!s.length)return;const o=(n?e.createSelection(n):e.document.selection).getFirstPosition();let r;if(iP(o.parent))r=o.parent;else {if(!iP(o.nodeBefore))return;r=o.nodeBefore;}e.change((e=>{const t=r.getAttribute("listType"),i=r.getAttribute("listIndent"),n=s[0].getAttribute("listIndent")||0,o=Math.max(i-n,0);for(const i of s){const n=iP(i);r.is("element","listItem")&&i.is("element","paragraph")&&e.rename(i,"listItem"),e.setAttributes({listIndent:(n?i.getAttribute("listIndent"):0)+o,listItemId:n?i.getAttribute("listItemId"):tP.next(),listType:t},i);}}));}}(e),{priority:"high"}),this.listenTo(t,"outputTransformation",((t,i)=>{e.change((e=>{const t=Array.from(i.content.getChildren()),n=t[t.length-1];if(t.length>1&&n.is("element")&&n.isEmpty){t.slice(0,-1).every(iP)&&e.remove(n);}if("copy"==i.method||"cut"==i.method){const t=Array.from(i.content.getChildren());gP(t)&&mP(t,e);}}));}));}_setupAccessibilityIntegration(){const e=this.editor,t=e.t;e.accessibility.addKeystrokeInfoGroup({id:"list",label:t("Keystrokes that can be used in a list"),keystrokes:[{label:t("Increase list item indent"),keystroke:"Tab"},{label:t("Decrease list item indent"),keystroke:"Shift+Tab"}]});}}function zP(e,t){const i=e.document.selection;if(!i.isCollapsed)return !pP(e);if("forward"===t)return !0;const n=i.getFirstPosition().parent,s=n.previousSibling;return !e.schema.isObject(s)&&(!!s.isEmpty||gP([n,s]))}function HP(e,t,i,n){e.ui.componentFactory.add(t,(()=>{const s=$P(pg,e,t,i,n);return s.set({tooltip:!0,isToggleable:!0}),s})),e.ui.componentFactory.add(`menuBar:${t}`,(()=>{const s=$P(Rg,e,t,i,n);return s.set({role:"menuitemcheckbox",isToggleable:!0}),s}));}function $P(e,t,i,n,s){const o=t.commands.get(i),r=new e(t.locale);return r.set({label:n,icon:s}),r.bind("isOn","isEnabled").to(o,"value","isEnabled"),r.on("execute",(()=>{t.execute(i),t.editing.view.focus();})),r}class UP extends Dr{static get pluginName(){return "ListUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor.t;this.editor.ui.componentFactory.has("numberedList")||HP(this.editor,"numberedList",e("Numbered List"),vm.numberedList),this.editor.ui.componentFactory.has("bulletedList")||HP(this.editor,"bulletedList",e("Bulleted List"),vm.bulletedList);}}class WP extends Dr{static get requires(){return [DP,UP]}static get pluginName(){return "List"}static get isOfficialPlugin(){return !0}}class jP extends Hr{refresh(){const e=this._getValue();this.value=e,this.isEnabled=null!=e;}execute({startIndex:e=1}={}){const t=this.editor.model,i=t.document;let n=Array.from(i.selection.getSelectedBlocks()).filter((e=>iP(e)&&wP(e.getAttribute("listType"))));n=cP(n),t.change((t=>{for(const i of n)t.setAttribute("listStart",e>=0?e:1,i);}));}_getValue(){const e=wr(this.editor.model.document.selection.getSelectedBlocks());return e&&iP(e)&&wP(e.getAttribute("listType"))?e.getAttribute("listStart"):null}}const qP={},GP={},KP={},ZP=[{listStyle:"disc",typeAttribute:"disc",listType:"bulleted"},{listStyle:"circle",typeAttribute:"circle",listType:"bulleted"},{listStyle:"square",typeAttribute:"square",listType:"bulleted"},{listStyle:"decimal",typeAttribute:"1",listType:"numbered"},{listStyle:"decimal-leading-zero",typeAttribute:null,listType:"numbered"},{listStyle:"lower-roman",typeAttribute:"i",listType:"numbered"},{listStyle:"upper-roman",typeAttribute:"I",listType:"numbered"},{listStyle:"lower-alpha",typeAttribute:"a",listType:"numbered"},{listStyle:"upper-alpha",typeAttribute:"A",listType:"numbered"},{listStyle:"lower-latin",typeAttribute:"a",listType:"numbered"},{listStyle:"upper-latin",typeAttribute:"A",listType:"numbered"}];for(const{listStyle:e,typeAttribute:t,listType:i}of ZP)qP[e]=i,GP[e]=t,t&&(KP[t]=e);function JP(){return ZP.map((e=>e.listStyle))}function QP(e){return qP[e]||null}function YP(e){return KP[e]||null}function XP(e){return GP[e]||null}class eS extends Hr{defaultType;_supportedTypes;constructor(e,t,i){super(e),this.defaultType=t,this._supportedTypes=i;}refresh(){this.value=this._getValue(),this.isEnabled=this._checkEnabled();}execute(e={}){const t=this.editor.model,i=t.document;t.change((t=>{this._tryToConvertItemsToList(e);let n=Array.from(i.selection.getSelectedBlocks()).filter((e=>e.hasAttribute("listType")));if(n.length){n=cP(n);for(const i of n)t.setAttribute("listStyle",e.type||this.defaultType,i);}}));}isStyleTypeSupported(e){return !this._supportedTypes||this._supportedTypes.includes(e)}_getValue(){const e=wr(this.editor.model.document.selection.getSelectedBlocks());return iP(e)?e.getAttribute("listStyle"):null}_checkEnabled(){const e=this.editor,t=e.commands.get("numberedList"),i=e.commands.get("bulletedList");return t.isEnabled||i.isEnabled}_tryToConvertItemsToList(e){if(!e.type)return;const t=QP(e.type);if(!t)return;const i=this.editor,n=`${t}List`;i.commands.get(n).value||i.execute(n);}}class tS extends Hr{refresh(){const e=this._getValue();this.value=e,this.isEnabled=null!=e;}execute(e={}){const t=this.editor.model,i=t.document;let n=Array.from(i.selection.getSelectedBlocks()).filter((e=>iP(e)&&"numbered"==e.getAttribute("listType")));n=cP(n),t.change((t=>{for(const i of n)t.setAttribute("listReversed",!!e.reversed,i);}));}_getValue(){const e=wr(this.editor.model.document.selection.getSelectedBlocks());return iP(e)&&"numbered"==e.getAttribute("listType")?e.getAttribute("listReversed"):null}}function iS(e){return (t,i,n)=>{const{writer:s,schema:o,consumable:r}=n;if(!1===r.test(i.viewItem,e.viewConsumables))return;i.modelRange||Object.assign(i,n.convertChildren(i.viewItem,i.modelCursor));let a=!1;for(const t of i.modelRange.getItems({shallow:!0}))o.checkAttribute(t,e.attributeName)&&e.appliesToListItem(t)&&(t.hasAttribute(e.attributeName)||(s.setAttribute(e.attributeName,e.getAttributeOnUpcast(i.viewItem),t),a=!0));a&&r.consume(i.viewItem,e.viewConsumables);}}class nS extends Dr{static get pluginName(){return "ListPropertiesUtils"}static get isOfficialPlugin(){return !0}getAllSupportedStyleTypes(){return JP()}getListTypeFromListStyleType(e){return QP(e)}getListStyleTypeFromTypeAttribute(e){return YP(e)}getTypeAttributeFromListStyleType(e){return XP(e)}}function sS(e){const{startIndex:t,reversed:i,styles:n}=e;return {styles:oS(n),startIndex:t||!1,reversed:i||!1}}function oS(e){const t={listTypes:["bulleted","numbered"],useAttribute:!1};return !0===e||(e?Array.isArray(e)||"string"==typeof e?t.listTypes=gr(e):(t.listTypes=e.listTypes?gr(e.listTypes):t.listTypes,t.useAttribute=!!e.useAttribute):t.listTypes=[]),t}const rS="default";class aS extends Dr{static get requires(){return [DP,nS]}static get pluginName(){return "ListPropertiesEditing"}static get isOfficialPlugin(){return !0}constructor(e){super(e),e.config.define("list.properties",{styles:!0,startIndex:!1,reversed:!1});}init(){const e=this.editor,t=e.model,i=e.plugins.get(DP),n=function(e){const t=[],i=sS(e);if(e.styles){const e=i.styles.useAttribute;t.push({attributeName:"listStyle",defaultValue:rS,viewConsumables:{styles:"list-style-type"},addCommand(t){let i=JP();e&&(i=i.filter((e=>!!XP(e)))),t.commands.add("listStyle",new eS(t,rS,i));},appliesToListItem:e=>"numbered"==e.getAttribute("listType")||"bulleted"==e.getAttribute("listType"),hasValidAttribute(e){if(!this.appliesToListItem(e))return !e.hasAttribute("listStyle");if(!e.hasAttribute("listStyle"))return !1;const t=e.getAttribute("listStyle");return t==rS||QP(t)==e.getAttribute("listType")},setAttributeOnDowncast(t,i,n){if(i&&i!==rS){if(!e)return void t.setStyle("list-style-type",i,n);{const e=XP(i);if(e)return void t.setAttribute("type",e,n)}}t.removeStyle("list-style-type",n),t.removeAttribute("type",n);},getAttributeOnUpcast(e){const t=e.getStyle("list-style-type");if(t)return t;const i=e.getAttribute("type");return i?YP(i):rS}});}e.reversed&&t.push({attributeName:"listReversed",defaultValue:!1,viewConsumables:{attributes:"reversed"},addCommand(e){e.commands.add("listReversed",new tS(e));},appliesToListItem:e=>"numbered"==e.getAttribute("listType"),hasValidAttribute(e){return this.appliesToListItem(e)==e.hasAttribute("listReversed")},setAttributeOnDowncast(e,t,i){t?e.setAttribute("reversed","reversed",i):e.removeAttribute("reversed",i);},getAttributeOnUpcast:e=>e.hasAttribute("reversed")});e.startIndex&&t.push({attributeName:"listStart",defaultValue:1,viewConsumables:{attributes:"start"},addCommand(e){e.commands.add("listStart",new jP(e));},appliesToListItem:e=>wP(e.getAttribute("listType")),hasValidAttribute(e){return this.appliesToListItem(e)==e.hasAttribute("listStart")},setAttributeOnDowncast(e,t,i){0==t||t>1?e.setAttribute("start",t,i):e.removeAttribute("start",i);},getAttributeOnUpcast(e){const t=e.getAttribute("start");return t>=0?t:1}});return t}(e.config.get("list.properties"));for(const s of n)s.addCommand(e),t.schema.extend("$listItem",{allowAttributes:s.attributeName}),i.registerDowncastStrategy({scope:"list",attributeName:s.attributeName,setAttributeOnDowncast(e,t,i){s.setAttributeOnDowncast(e,t,i);}});e.conversion.for("upcast").add((e=>{for(const t of n)e.on("element:ol",iS(t)),e.on("element:ul",iS(t));})),i.on("checkAttributes:list",((e,{viewElement:t,modelAttributes:i})=>{for(const s of n)s.getAttributeOnUpcast(t)!=i[s.attributeName]&&(e.return=!0,e.stop());})),this.listenTo(e.commands.get("indentList"),"afterExecute",((e,i)=>{t.change((e=>{for(const t of i)for(const i of n)i.appliesToListItem(t)&&e.setAttribute(i.attributeName,i.defaultValue,t);}));})),i.on("postFixer",((e,{listNodes:t,writer:i})=>{for(const{node:s}of t)for(const t of n)t.hasValidAttribute(s)||(t.appliesToListItem(s)?i.setAttribute(t.attributeName,t.defaultValue,s):i.removeAttribute(t.attributeName,s),e.return=!0);})),i.on("postFixer",((e,{listNodes:t,writer:i})=>{for(const{node:s,previousNodeInList:o}of t)if(o&&o.getAttribute("listType")==s.getAttribute("listType"))for(const t of n){const{attributeName:n}=t;if(!t.appliesToListItem(s))continue;const r=o.getAttribute(n);s.getAttribute(n)!=r&&(i.setAttribute(n,r,s),e.return=!0);}}));}}class lS extends lg{children;stylesView=null;additionalPropertiesCollapsibleView=null;startIndexFieldView=null;reversedSwitchButtonView=null;focusTracker=new _r;keystrokes=new Cr;focusables=new zm;focusCycler;constructor(e,{enabledProperties:t,styleButtonViews:i,styleGridAriaLabel:n}){super(e);const s=["ck","ck-list-properties"];this.children=this.createCollection(),this.focusCycler=new _g({focusables:this.focusables,focusTracker:this.focusTracker,keystrokeHandler:this.keystrokes,actions:{focusPrevious:"shift + tab",focusNext:"tab"}}),i&&i.length?(this.stylesView=this._createStylesView(i,n),this.children.add(this.stylesView)):s.push("ck-list-properties_without-styles"),(t.startIndex||t.reversed)&&(this._addNumberedListPropertyViews(t),s.push("ck-list-properties_with-numbered-properties")),this.setTemplate({tag:"div",attributes:{class:s},children:this.children});}render(){if(super.render(),this.stylesView){this.focusables.add(this.stylesView),this.focusTracker.add(this.stylesView.element),(this.startIndexFieldView||this.reversedSwitchButtonView)&&(this.focusables.add(this.children.last.buttonView),this.focusTracker.add(this.children.last.buttonView.element));for(const e of this.stylesView.children)this.stylesView.focusTracker.add(e.element);mg({keystrokeHandler:this.stylesView.keystrokes,focusTracker:this.stylesView.focusTracker,gridItems:this.stylesView.children,numberOfColumns:()=>i.window.getComputedStyle(this.stylesView.element).getPropertyValue("grid-template-columns").split(" ").length,uiLanguageDirection:this.locale&&this.locale.uiLanguageDirection});}if(this.startIndexFieldView){this.focusables.add(this.startIndexFieldView),this.focusTracker.add(this.startIndexFieldView.element);const e=e=>e.stopPropagation();this.keystrokes.set("arrowright",e),this.keystrokes.set("arrowleft",e),this.keystrokes.set("arrowup",e),this.keystrokes.set("arrowdown",e);}this.reversedSwitchButtonView&&(this.focusables.add(this.reversedSwitchButtonView),this.focusTracker.add(this.reversedSwitchButtonView.element)),this.keystrokes.listenTo(this.element);}focus(){this.focusCycler.focusFirst();}focusLast(){this.focusCycler.focusLast();}destroy(){super.destroy(),this.focusTracker.destroy(),this.keystrokes.destroy();}_createStylesView(e,t){const i=new lg(this.locale);return i.children=i.createCollection(),i.children.addMany(e),i.setTemplate({tag:"div",attributes:{"aria-label":t,class:["ck","ck-list-styles-list"]},children:i.children}),i.children.delegate("execute").to(this),i.focus=function(){this.children.first.focus();},i.focusTracker=new _r,i.keystrokes=new Cr,i.render(),i.keystrokes.listenTo(i.element),i}_addNumberedListPropertyViews(e){const t=this.locale.t,i=[];e.startIndex&&(this.startIndexFieldView=this._createStartIndexField(),i.push(this.startIndexFieldView)),e.reversed&&(this.reversedSwitchButtonView=this._createReversedSwitchButton(),i.push(this.reversedSwitchButtonView)),this.stylesView?(this.additionalPropertiesCollapsibleView=new jg(this.locale,i),this.additionalPropertiesCollapsibleView.set({label:t("List properties"),isCollapsed:!0}),this.additionalPropertiesCollapsibleView.buttonView.bind("isEnabled").toMany(i,"isEnabled",((...e)=>e.some((e=>e)))),this.additionalPropertiesCollapsibleView.buttonView.on("change:isEnabled",((e,t,i)=>{i||(this.additionalPropertiesCollapsibleView.isCollapsed=!0);})),this.children.add(this.additionalPropertiesCollapsibleView)):this.children.addMany(i);}_createStartIndexField(){const e=this.locale.t,t=new pf(this.locale,dp);return t.set({label:e("Start at"),class:"ck-numbered-list-properties__start-index"}),t.fieldView.set({min:0,step:1,value:1,inputMode:"numeric"}),t.fieldView.on("input",(()=>{const i=t.fieldView.element,n=i.valueAsNumber;Number.isNaN(n)?t.errorText=e("Invalid start index value."):i.checkValidity()?this.fire("listStart",{startIndex:n}):t.errorText=e("Start index must be greater than 0.");})),t}_createReversedSwitchButton(){const e=this.locale.t,t=new Dg(this.locale);return t.set({withText:!0,label:e("Reversed order"),class:"ck-numbered-list-properties__reversed-order"}),t.delegate("execute").to(this,"listReversed"),t}}class cS extends Dr{static get pluginName(){return "ListPropertiesUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.locale.t,i=e.config.get("list.properties"),n=sS(i),s=n.styles.listTypes;if(s.includes("bulleted")){const i=[{label:t("Toggle the disc list style"),tooltip:t("Disc"),type:"disc",icon:''},{label:t("Toggle the circle list style"),tooltip:t("Circle"),type:"circle",icon:''},{label:t("Toggle the square list style"),tooltip:t("Square"),type:"square",icon:''}],s=t("Bulleted List"),o=t("Bulleted list styles toolbar"),r="bulletedList";e.ui.componentFactory.add(r,dS({editor:e,normalizedConfig:n,parentCommandName:r,buttonLabel:s,buttonIcon:vm.bulletedList,styleGridAriaLabel:o,styleDefinitions:i})),e.ui.componentFactory.add(`menuBar:${r}`,hS({editor:e,normalizedConfig:n,parentCommandName:r,buttonLabel:s,styleGridAriaLabel:o,styleDefinitions:i}));}if(s.includes("numbered")||i.startIndex||i.reversed){const i=[{label:t("Toggle the decimal list style"),tooltip:t("Decimal"),type:"decimal",icon:''},{label:t("Toggle the decimal with leading zero list style"),tooltip:t("Decimal with leading zero"),type:"decimal-leading-zero",icon:''},{label:t("Toggle the lower–roman list style"),tooltip:t("Lower–roman"),type:"lower-roman",icon:''},{label:t("Toggle the upper–roman list style"),tooltip:t("Upper-roman"),type:"upper-roman",icon:''},{label:t("Toggle the lower–latin list style"),tooltip:t("Lower-latin"),type:"lower-latin",icon:''},{label:t("Toggle the upper–latin list style"),tooltip:t("Upper-latin"),type:"upper-latin",icon:''}],o=t("Numbered List"),r=t("Numbered list styles toolbar"),a="numberedList";e.ui.componentFactory.add(a,dS({editor:e,normalizedConfig:n,parentCommandName:a,buttonLabel:o,buttonIcon:vm.numberedList,styleGridAriaLabel:r,styleDefinitions:i})),s.includes("numbered")&&e.ui.componentFactory.add(`menuBar:${a}`,hS({editor:e,normalizedConfig:n,parentCommandName:a,buttonLabel:o,styleGridAriaLabel:r,styleDefinitions:i}));}}}function dS({editor:e,normalizedConfig:t,parentCommandName:i,buttonLabel:n,buttonIcon:s,styleGridAriaLabel:o,styleDefinitions:r}){const a=e.commands.get(i);return l=>{const c=Xf(l,Yf),d=c.buttonView;return c.bind("isEnabled").to(a),c.class="ck-list-styles-dropdown",d.on("execute",(()=>{e.execute(i),e.editing.view.focus();})),d.set({label:n,icon:s,tooltip:!0,isToggleable:!0}),d.bind("isOn").to(a,"value",(e=>!!e)),c.once("change:isOpen",(()=>{const n=function({editor:e,normalizedConfig:t,dropdownView:i,parentCommandName:n,styleDefinitions:s,styleGridAriaLabel:o}){const r=e.locale,a={...t,..."numberedList"!=n?{startIndex:!1,reversed:!1}:null},l=n.replace("List","");let c=null;if(t.styles.listTypes.includes(l)){const t=e.commands.get("listStyle"),i=uS({editor:e,parentCommandName:n,listStyleCommand:t}),o=mS(t);c=s.filter(o).map(i);}const d=new lS(r,{styleGridAriaLabel:o,enabledProperties:a,styleButtonViews:c});t.styles.listTypes.includes(l)&&rp(i,(()=>d.stylesView.children.find((e=>e.isOn))));if(a.startIndex){const t=e.commands.get("listStart");d.startIndexFieldView.bind("isEnabled").to(t),d.startIndexFieldView.fieldView.bind("value").to(t),d.on("listStart",((t,i)=>e.execute("listStart",i)));}if(a.reversed){const t=e.commands.get("listReversed");d.reversedSwitchButtonView.bind("isEnabled").to(t),d.reversedSwitchButtonView.bind("isOn").to(t,"value",(e=>!!e)),d.on("listReversed",(()=>{const i=t.value;e.execute("listReversed",{reversed:!i});}));}return d.delegate("execute").to(i),d}({editor:e,normalizedConfig:t,dropdownView:c,parentCommandName:i,styleGridAriaLabel:o,styleDefinitions:r});c.panelView.children.add(n);})),c.on("execute",(()=>{e.editing.view.focus();})),c}}function uS({editor:e,listStyleCommand:t,parentCommandName:i}){const n=e.locale,s=e.commands.get(i);return ({label:o,type:r,icon:a,tooltip:l})=>{const c=new pg(n);return c.set({label:o,icon:a,tooltip:l}),t.on("change:value",(()=>{c.isOn=t.value===r;})),c.on("execute",(()=>{s.value?t.value===r?e.execute(i):t.value!==r&&e.execute("listStyle",{type:r}):e.model.change((()=>{e.execute("listStyle",{type:r});}));})),c}}function hS({editor:e,normalizedConfig:t,parentCommandName:i,buttonLabel:n,styleGridAriaLabel:s,styleDefinitions:o}){return r=>{const a=new aw(r),l=e.commands.get(i),c=e.commands.get("listStyle"),d=mS(c),u=uS({editor:e,parentCommandName:i,listStyleCommand:c}),h=o.filter(d).map(u),m=new lS(r,{styleGridAriaLabel:s,enabledProperties:{...t,startIndex:!1,reversed:!1},styleButtonViews:h});return m.delegate("execute").to(a),a.buttonView.set({label:n,icon:vm[i]}),a.panelView.children.add(m),a.bind("isEnabled").to(l,"isEnabled"),a.on("execute",(()=>{e.editing.view.focus();})),a}}function mS(e){return "function"==typeof e.isStyleTypeSupported?t=>e.isStyleTypeSupported(t.type):()=>!0}class gS extends Dr{static get requires(){return [aS,cS]}static get pluginName(){return "ListProperties"}static get isOfficialPlugin(){return !0}}class fS extends Hr{constructor(e){super(e),this.on("execute",(()=>{this.refresh();}),{priority:"highest"});}refresh(){const e=this._getSelectedItems();this.value=this._getValue(e),this.isEnabled=!!e.length;}execute(e={}){this.editor.model.change((t=>{const i=this._getSelectedItems(),n=void 0===e.forceValue?!this._getValue(i):e.forceValue;for(const e of i)n?t.setAttribute("todoListChecked",!0,e):t.removeAttribute("todoListChecked",e);}));}_getValue(e){return e.every((e=>e.getAttribute("todoListChecked")))}_getSelectedItems(){const e=this.editor.model,t=e.schema,i=e.document.selection.getFirstRange(),n=i.start.parent,s=[];t.checkAttribute(n,"todoListChecked")&&s.push(...nP(n));for(const e of i.getItems({shallow:!0}))t.checkAttribute(e,"todoListChecked")&&!s.includes(e)&&s.push(...nP(e));return s}}class pS extends Tl{domEventType=["change"];onDomEvent(e){if(e.target){const t=this.view.domConverter.mapDomToView(e.target);t&&t.is("element","input")&&"checkbox"==t.getAttribute("type")&&t.findAncestor({classes:"todo-list__label"})&&this.fire("todoCheckboxChange",e);}}}const bS=rr("Ctrl+Enter");class wS extends Dr{static get pluginName(){return "TodoListEditing"}static get isOfficialPlugin(){return !0}static get requires(){return [DP]}init(){const e=this.editor,t=e.model,i=e.editing,n=e.plugins.get(DP),s=e.config.get("list.multiBlock")?"paragraph":"listItem";e.commands.add("todoList",new kP(e,"todo")),e.commands.add("checkTodoList",new fS(e)),i.view.addObserver(pS),t.schema.extend("$listItem",{allowAttributes:"todoListChecked"}),t.schema.addAttributeCheck((e=>{const t=e.last;if(!t.getAttribute("listItemId")||"todo"!=t.getAttribute("listType"))return !1}),"todoListChecked"),e.conversion.for("upcast").add((e=>{e.on("element:input",((e,t,i)=>{const n=t.modelCursor,s=n.parent,o=t.viewItem;if(!i.consumable.test(o,{name:!0}))return;if("checkbox"!=o.getAttribute("type")||!n.isAtStart||!s.hasAttribute("listType"))return;i.consumable.consume(o,{name:!0});const r=i.writer;r.setAttribute("listType","todo",s),t.viewItem.hasAttribute("checked")&&r.setAttribute("todoListChecked",!0,s),t.modelRange=r.createRange(n);})),e.on("element:li",((e,t,i)=>{const{writer:n,schema:s}=i;if(!t.modelRange)return;const o=Array.from(t.modelRange.getItems({shallow:!0})).filter((e=>"todo"===e.getAttribute("listType")&&s.checkAttribute(e,"listItemId"))).reduce(((e,t)=>{const i=t.getAttribute("listItemId");return e.has(i)||e.set(i,nP(t)),e}),new Map);for(const[,e]of o.entries())if(e.some((e=>e.getAttribute("todoListChecked"))))for(const t of e)n.setAttribute("todoListChecked",!0,t);}),{priority:"low"}),e.on("element:label",_S({name:"label",classes:"todo-list__label"})),e.on("element:label",_S({name:"label",classes:["todo-list__label","todo-list__label_without-description"]})),e.on("element:span",_S({name:"span",classes:"todo-list__label__description"})),e.on("element:ul",function(e){const t=new aa(e);return (e,i,n)=>{const s=t.match(i.viewItem);if(!s)return;const o=s.match;o.name=!1,n.consumable.consume(i.viewItem,o);}}({name:"ul",classes:"todo-list"}));})),e.conversion.for("downcast").elementToElement({model:s,view:(e,{writer:t})=>{if(vS(e,n.getListAttributeNames()))return t.createContainerElement("span",{class:"todo-list__label__description"})},converterPriority:"highest"}),n.registerDowncastStrategy({scope:"list",attributeName:"listType",setAttributeOnDowncast(e,t,i){"todo"==t?e.addClass("todo-list",i):e.removeClass("todo-list",i);}}),n.registerDowncastStrategy({scope:"itemMarker",attributeName:"todoListChecked",createElement(e,t,{dataPipeline:i}){if("todo"!=t.getAttribute("listType"))return null;const n=e.createUIElement("input",{type:"checkbox",...t.getAttribute("todoListChecked")?{checked:"checked"}:null,...i?{disabled:"disabled"}:{tabindex:"-1"}});if(i)return n;const s=e.createContainerElement("span",{contenteditable:"false"},n);return s.getFillerOffset=()=>null,s},canWrapElement:e=>vS(e,n.getListAttributeNames()),createWrapperElement(e,t,{dataPipeline:i}){const s=["todo-list__label"];return vS(t,n.getListAttributeNames())||s.push("todo-list__label_without-description"),e.createAttributeElement(i?"label":"span",{class:s.join(" ")})}}),n.on("checkElement",((e,{modelElement:t,viewElement:i})=>{const s=vS(t,n.getListAttributeNames());i.hasClass("todo-list__label__description")!=s&&(e.return=!0,e.stop());})),n.on("checkElement",((t,{modelElement:i,viewElement:n})=>{const s="todo"==i.getAttribute("listType")&&rP(i);let o=!1;const r=e.editing.view.createPositionBefore(n).getWalker({direction:"backward"});for(const{item:t}of r){if(t.is("element")&&e.editing.mapper.toModelElement(t))break;t.is("element","input")&&"checkbox"==t.getAttribute("type")&&(o=!0);}o!=s&&(t.return=!0,t.stop());})),n.on("postFixer",((e,{listNodes:t,writer:i})=>{for(const{node:n,previousNodeInList:s}of t){if(!s)continue;if(s.getAttribute("listItemId")!=n.getAttribute("listItemId"))continue;const t=s.hasAttribute("todoListChecked"),o=n.hasAttribute("todoListChecked");o&&!t?(i.removeAttribute("todoListChecked",n),e.return=!0):!o&&t&&(i.setAttribute("todoListChecked",!0,n),e.return=!0);}})),t.document.registerPostFixer((e=>{const i=t.document.differ.getChanges();let n=!1;for(const t of i)if("attribute"==t.type&&"listType"==t.attributeKey){const i=t.range.start.nodeAfter;"todo"==t.attributeOldValue&&i.hasAttribute("todoListChecked")&&(e.removeAttribute("todoListChecked",i),n=!0);}else if("insert"==t.type&&"$text"!=t.name)for(const{item:i}of e.createRangeOn(t.position.nodeAfter))i.is("element")&&"todo"!=i.getAttribute("listType")&&i.hasAttribute("todoListChecked")&&(e.removeAttribute("todoListChecked",i),n=!0);return n})),this.listenTo(i.view.document,"keydown",((t,i)=>{or(i)===bS&&(e.execute("checkTodoList"),t.stop());}),{priority:"high"}),this.listenTo(i.view.document,"todoCheckboxChange",((e,t)=>{const n=t.target;if(!n||!n.is("element","input"))return;const s=i.view.createPositionAfter(n),o=i.mapper.toModelPosition(s).parent;o&&iP(o)&&"todo"==o.getAttribute("listType")&&this._handleCheckmarkChange(o);})),this.listenTo(i.view.document,"arrowKey",function(e,t){return (i,n)=>{const s=cr(n.keyCode,t.contentLanguageDirection),o=e.schema,r=e.document.selection;if(!r.isCollapsed)return;const a=r.getFirstPosition(),l=a.parent;if("right"==s&&a.isAtEnd){const t=o.getNearestSelectionRange(e.createPositionAfter(l),"forward");if(!t)return;const s=t.start.parent;s&&iP(s)&&"todo"==s.getAttribute("listType")&&(e.change((e=>e.setSelection(t))),n.preventDefault(),n.stopPropagation(),i.stop());}else if("left"==s&&a.isAtStart&&iP(l)&&"todo"==l.getAttribute("listType")){const t=o.getNearestSelectionRange(e.createPositionBefore(l),"backward");if(!t)return;e.change((e=>e.setSelection(t))),n.preventDefault(),n.stopPropagation(),i.stop();}}}(t,e.locale),{context:"$text"}),this.listenTo(i.mapper,"viewToModelPosition",((e,i)=>{const n=i.viewPosition.parent,s=n.is("attributeElement","li")&&0==i.viewPosition.offset,o=yS(n)&&i.viewPosition.offset<=1,r=n.is("element","span")&&"false"==n.getAttribute("contenteditable")&&yS(n.parent);if(!s&&!o&&!r)return;const a=i.modelPosition.nodeAfter;a&&"todo"==a.getAttribute("listType")&&(i.modelPosition=t.createPositionAt(a,0));}),{priority:"low"}),this._initAriaAnnouncements();}_handleCheckmarkChange(e){const t=this.editor,i=t.model,n=Array.from(i.document.selection.getRanges());i.change((i=>{i.setSelection(e,"end"),t.execute("checkTodoList"),i.setSelection(n);}));}_initAriaAnnouncements(){const{model:e,ui:t,t:i}=this.editor;let n=null;t&&e.document.selection.on("change:range",(()=>{const s=e.document.selection.focus.parent,o=kS(n),r=kS(s);o&&!r?t.ariaLiveAnnouncer.announce(i("Leaving a to-do list")):!o&&r&&t.ariaLiveAnnouncer.announce(i("Entering a to-do list")),n=s;}));}}function _S(e){const t=new aa(e);return (e,i,n)=>{const s=t.match(i.viewItem);s&&n.consumable.consume(i.viewItem,s.match)&&Object.assign(i,n.convertChildren(i.viewItem,i.modelCursor));}}function vS(e,t){return (e.is("element","paragraph")||e.is("element","listItem"))&&"todo"==e.getAttribute("listType")&&rP(e)&&function(e,t){for(const i of e.getAttributeKeys())if(!i.startsWith("selection:")&&!t.includes(i))return !1;return !0}(e,t)}function yS(e){return !!e&&e.is("attributeElement")&&e.hasClass("todo-list__label")}function kS(e){return !!e&&(!(!e.is("element","paragraph")&&!e.is("element","listItem"))&&"todo"==e.getAttribute("listType"))}class CS extends Dr{static get pluginName(){return "TodoListUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor.t;HP(this.editor,"todoList",e("To-do List"),vm.todoList);}}class xS extends Dr{static get requires(){return [wS,CS]}static get pluginName(){return "TodoList"}static get isOfficialPlugin(){return !0}}class AS extends Hr{type;constructor(e,t){super(e),this.type=t;}refresh(){this.value=this._getValue(),this.isEnabled=this._checkEnabled();}execute(e={}){const t=this.editor.model,i=t.document,n=Array.from(i.selection.getSelectedBlocks()).filter((e=>TS(e,t.schema))),s=void 0!==e.forceValue?!e.forceValue:this.value;t.change((e=>{if(s){let t=n[n.length-1].nextSibling,i=Number.POSITIVE_INFINITY,s=[];for(;t&&"listItem"==t.name&&0!==t.getAttribute("listIndent");){const e=t.getAttribute("listIndent");e=i;)o>s.getAttribute("listIndent")&&(o=s.getAttribute("listIndent")),s.getAttribute("listIndent")==o&&e[t?"unshift":"push"](s),s=s[t?"previousSibling":"nextSibling"];}}function TS(e,t){return t.checkChild(e.parent,"listItem")&&!t.isObject(e)}class PS extends Hr{_indentBy;constructor(e,t){super(e),this._indentBy="forward"==t?1:-1;}refresh(){this.isEnabled=this._checkEnabled();}execute(){const e=this.editor.model,t=e.document;let i=Array.from(t.selection.getSelectedBlocks());e.change((e=>{const t=i[i.length-1];let n=t.nextSibling;for(;n&&"listItem"==n.name&&n.getAttribute("listIndent")>t.getAttribute("listIndent");)i.push(n),n=n.nextSibling;this._indentBy<0&&(i=i.reverse());for(const t of i){const i=t.getAttribute("listIndent")+this._indentBy;i<0?e.rename(t,"paragraph"):e.setAttribute("listIndent",i,t);}this.fire("_executeCleanup",i);}));}_checkEnabled(){const e=wr(this.editor.model.document.selection.getSelectedBlocks());if(!e||!e.is("element","listItem"))return !1;if(this._indentBy>0){const t=e.getAttribute("listIndent"),i=e.getAttribute("listType");let n=e.previousSibling;for(;n&&n.is("element","listItem")&&n.getAttribute("listIndent")>=t;){if(n.getAttribute("listIndent")==t)return n.getAttribute("listType")==i;n=n.previousSibling;}return !1}return !0}}function SS(e,t){const i=t.mapper,n=t.writer,s="numbered"==e.getAttribute("listType")?"ol":"ul",o=function(e){const t=e.createContainerElement("li");return t.getFillerOffset=zS,t}(n),r=n.createContainerElement(s,null);return n.insert(n.createPositionAt(r,0),o),i.bindElements(e,o),o}function IS(e,t,i,n){const s=t.parent,o=i.mapper,r=i.writer;let a=o.toViewPosition(n.createPositionBefore(e));const l=OS(e.previousSibling,{sameIndent:!0,smallerIndent:!0,listIndent:e.getAttribute("listIndent")}),c=e.previousSibling;if(l&&l.getAttribute("listIndent")==e.getAttribute("listIndent")){const e=o.toViewElement(l);a=r.breakContainer(r.createPositionAfter(e));}else if(c&&"listItem"==c.name){a=o.toViewPosition(n.createPositionAt(c,"end"));const e=o.findMappedViewAncestor(a),t=BS(e);a=t?r.createPositionBefore(t):r.createPositionAt(e,"end");}else a=o.toViewPosition(n.createPositionBefore(e));if(a=RS(a),r.insert(a,s),c&&"listItem"==c.name){const e=o.toViewElement(c),i=r.createRange(r.createPositionAt(e,0),a).getWalker({ignoreElementEnd:!0});for(const e of i)if(e.item.is("element","li")){const n=r.breakContainer(r.createPositionBefore(e.item)),s=e.item.parent,o=r.createPositionAt(t,"end");VS(r,o.nodeBefore,o.nodeAfter),r.move(r.createRangeOn(s),o),i._position=n;}}else {const i=s.nextSibling;if(i&&(i.is("element","ul")||i.is("element","ol"))){let n=null;for(const t of i.getChildren()){const i=o.toModelElement(t);if(!(i&&i.getAttribute("listIndent")>e.getAttribute("listIndent")))break;n=t;}n&&(r.breakContainer(r.createPositionAfter(n)),r.move(r.createRangeOn(n.parent),r.createPositionAt(t,"end")));}}VS(r,s,s.nextSibling),VS(r,s.previousSibling,s);}function VS(e,t,i){return !t||!i||"ul"!=t.name&&"ol"!=t.name||t.name!=i.name||t.getAttribute("class")!==i.getAttribute("class")?null:e.mergeContainers(e.createPositionAfter(t))}function RS(e){return e.getLastMatchingPosition((e=>e.item.is("uiElement")))}function OS(e,t){const i=!!t.sameIndent,n=!!t.smallerIndent,s=t.listIndent;let o=e;for(;o&&"listItem"==o.name;){const e=o.getAttribute("listIndent");if(i&&s==e||n&&s>e)return o;o="forward"===t.direction?o.nextSibling:o.previousSibling;}return null}function BS(e){for(const t of e.getChildren())if("ul"==t.name||"ol"==t.name)return t;return null}function MS(e,t){const i=[],n=e.parent,s={ignoreElementEnd:!1,startPosition:e,shallow:!0,direction:t},o=n.getAttribute("listIndent"),r=[...new Gl(s)].filter((e=>e.item.is("element"))).map((e=>e.item));for(const e of r){if(!e.is("element","listItem"))break;if(e.getAttribute("listIndent")o)){if(e.getAttribute("listType")!==n.getAttribute("listType"))break;if(e.getAttribute("listStyle")!==n.getAttribute("listStyle"))break;if(e.getAttribute("listReversed")!==n.getAttribute("listReversed"))break;if(e.getAttribute("listStart")!==n.getAttribute("listStart"))break;"backward"===t?i.unshift(e):i.push(e);}}return i}function LS(e){let t=[...e.document.selection.getSelectedBlocks()].filter((e=>e.is("element","listItem"))).map((t=>{const i=e.change((e=>e.createPositionAt(t,0)));return [...MS(i,"backward"),...MS(i,"forward")]})).flat();return t=[...new Set(t)],t}const FS=["disc","circle","square"],NS=["decimal","decimal-leading-zero","lower-roman","upper-roman","lower-latin","upper-latin"];function DS(e){return FS.includes(e)?"bulleted":NS.includes(e)?"numbered":null}function zS(){const e=!this.isEmpty&&("ul"==this.getChild(0).name||"ol"==this.getChild(0).name);return this.isEmpty||e?0:ba.call(this)}class HS extends Dr{static get pluginName(){return "LegacyListUtils"}static get isOfficialPlugin(){return !0}getListTypeFromListStyleType(e){return DS(e)}getSelectedListItems(e){return LS(e)}getSiblingNodes(e,t){return MS(e,t)}}function $S(e){return (t,i,n)=>{const s=n.consumable;if(!s.test(i.item,"insert")||!s.test(i.item,"attribute:listType")||!s.test(i.item,"attribute:listIndent"))return;s.consume(i.item,"insert"),s.consume(i.item,"attribute:listType"),s.consume(i.item,"attribute:listIndent");const o=i.item;IS(o,SS(o,n),n,e);}}const US=(e,t,i)=>{if(!i.consumable.test(t.item,e.name))return;const n=i.mapper.toViewElement(t.item),s=i.writer;s.breakContainer(s.createPositionBefore(n)),s.breakContainer(s.createPositionAfter(n));const o=n.parent,r="numbered"==t.attributeNewValue?"ol":"ul";s.rename(r,o);},WS=(e,t,i)=>{i.consumable.consume(t.item,e.name);const n=i.mapper.toViewElement(t.item).parent,s=i.writer;VS(s,n,n.nextSibling),VS(s,n.previousSibling,n);};const jS=(e,t,i)=>{if(i.consumable.test(t.item,e.name)&&"listItem"!=t.item.name){let e=i.mapper.toViewPosition(t.range.start);const n=i.writer,s=[];for(;("ul"==e.parent.name||"ol"==e.parent.name)&&(e=n.breakContainer(e),"li"==e.parent.name);){const t=e,i=n.createPositionAt(e.parent,"end");if(!t.isEqual(i)){const e=n.remove(n.createRange(t,i));s.push(e);}e=n.createPositionAfter(e.parent);}if(s.length>0){for(let t=0;t0){const t=VS(n,i,i.nextSibling);t&&t.parent==i&&e.offset--;}}VS(n,e.nodeBefore,e.nodeAfter);}}},qS=(e,t,i)=>{const n=i.mapper.toViewPosition(t.position),s=n.nodeBefore,o=n.nodeAfter;VS(i.writer,s,o);},GS=(e,t,i)=>{if(i.consumable.consume(t.viewItem,{name:!0})){const e=i.writer,n=e.createElement("listItem"),s=function(e){let t=0,i=e.parent;for(;i;){if(i.is("element","li"))t++;else {const e=i.previousSibling;e&&e.is("element","li")&&t++;}i=i.parent;}return t}(t.viewItem);e.setAttribute("listIndent",s,n);const o=t.viewItem.parent&&"ol"==t.viewItem.parent.name?"numbered":"bulleted";if(e.setAttribute("listType",o,n),!i.safeInsert(n,t.modelCursor))return;const r=function(e,t,i){const{writer:n,schema:s}=i;let o=n.createPositionAfter(e);for(const r of t)if("ul"==r.name||"ol"==r.name)o=i.convertItem(r,o).modelCursor;else {const t=i.convertItem(r,n.createPositionAt(e,"end")),a=t.modelRange.start.nodeAfter;a&&a.is("element")&&!s.checkChild(e,a.name)&&(e=t.modelCursor.parent.is("element","listItem")?t.modelCursor.parent:YS(t.modelCursor),o=n.createPositionAfter(e));}return o}(n,t.viewItem.getChildren(),i);t.modelRange=e.createRange(t.modelCursor,r),i.updateConversionResult(n,t);}},KS=(e,t,i)=>{if(i.consumable.test(t.viewItem,{name:!0})){const e=Array.from(t.viewItem.getChildren());for(const t of e){!(t.is("element","li")||eI(t))&&t._remove();}}},ZS=(e,t,i)=>{if(i.consumable.test(t.viewItem,{name:!0})){if(0===t.viewItem.childCount)return;const e=[...t.viewItem.getChildren()];let i=!1;for(const t of e)i&&!eI(t)&&t._remove(),eI(t)&&(i=!0);}};function JS(e){return (t,i)=>{if(i.isPhantom)return;const n=i.modelPosition.nodeBefore;if(n&&n.is("element","listItem")){const t=i.mapper.toViewElement(n),s=t.getAncestors().find(eI),o=e.createPositionAt(t,0).getWalker();for(const e of o){if("elementStart"==e.type&&e.item.is("element","li")){i.viewPosition=e.previousPosition;break}if("elementEnd"==e.type&&e.item==s){i.viewPosition=e.nextPosition;break}}}}}const QS=function(e,[t,i]){const n=this;let s,o=t.is("documentFragment")?t.getChild(0):t;if(s=i?n.createSelection(i):n.document.selection,o&&o.is("element","listItem")){const e=s.getFirstPosition();let t=null;if(e.parent.is("element","listItem")?t=e.parent:e.nodeBefore&&e.nodeBefore.is("element","listItem")&&(t=e.nodeBefore),t){const e=t.getAttribute("listIndent");if(e>0)for(;o&&o.is("element","listItem");)o._setAttribute("listIndent",o.getAttribute("listIndent")+e),o=o.nextSibling;}}};function YS(e){const t=new Gl({startPosition:e});let i;do{i=t.next();}while(!i.value.item.is("element","listItem"));return i.value.item}function XS(e,t,i,n,s,o){const r=OS(t.nodeBefore,{sameIndent:!0,smallerIndent:!0,listIndent:e}),a=s.mapper,l=s.writer,c=r?r.getAttribute("listIndent"):null;let d;if(r)if(c==e){const e=a.toViewElement(r).parent;d=l.createPositionAfter(e);}else {const e=o.createPositionAt(r,"end");d=a.toViewPosition(e);}else d=i;d=RS(d);for(const e of [...n.getChildren()])eI(e)&&(d=l.move(l.createRangeOn(e),d).end,VS(l,e,e.nextSibling),VS(l,e.previousSibling,e));}function eI(e){return e.is("element","ol")||e.is("element","ul")}class tI extends Dr{static get pluginName(){return "LegacyListEditing"}static get isOfficialPlugin(){return !0}static get requires(){return [K_,Rw,HS]}init(){const e=this.editor;e.model.schema.register("listItem",{inheritAllFrom:"$block",allowAttributes:["listType","listIndent"]});const t=e.data,i=e.editing;var n;e.model.document.registerPostFixer((t=>function(e,t){const i=e.document.differ.getChanges(),n=new Map;let s=!1;for(const n of i)if("insert"==n.type&&"listItem"==n.name)o(n.position);else if("insert"==n.type&&"listItem"!=n.name){if("$text"!=n.name){const i=n.position.nodeAfter;i.hasAttribute("listIndent")&&(t.removeAttribute("listIndent",i),s=!0),i.hasAttribute("listType")&&(t.removeAttribute("listType",i),s=!0),i.hasAttribute("listStyle")&&(t.removeAttribute("listStyle",i),s=!0),i.hasAttribute("listReversed")&&(t.removeAttribute("listReversed",i),s=!0),i.hasAttribute("listStart")&&(t.removeAttribute("listStart",i),s=!0);for(const t of Array.from(e.createRangeIn(i)).filter((e=>e.item.is("element","listItem"))))o(t.previousPosition);}o(n.position.getShiftedBy(n.length));}else "remove"==n.type&&"listItem"==n.name?o(n.position):("attribute"==n.type&&"listIndent"==n.attributeKey||"attribute"==n.type&&"listType"==n.attributeKey)&&o(n.range.start);for(const e of n.values())r(e),a(e);return s;function o(e){const t=e.nodeBefore;if(t&&t.is("element","listItem")){let e=t;if(n.has(e))return;for(let t=e.previousSibling;t&&t.is("element","listItem");t=e.previousSibling)if(e=t,n.has(e))return;n.set(t,e);}else {const t=e.nodeAfter;t&&t.is("element","listItem")&&n.set(t,t);}}function r(e){let i=0,n=null;for(;e&&e.is("element","listItem");){const o=e.getAttribute("listIndent");if(o>i){let r;null===n?(n=o-i,r=i):(n>o&&(n=o),r=o-n),t.setAttribute("listIndent",r,e),s=!0;}else n=null,i=e.getAttribute("listIndent")+1;e=e.nextSibling;}}function a(e){let i=[],n=null;for(;e&&e.is("element","listItem");){const o=e.getAttribute("listIndent");if(n&&n.getAttribute("listIndent")>o&&(i=i.slice(0,o+1)),0!=o)if(i[o]){const n=i[o];e.getAttribute("listType")!=n&&(t.setAttribute("listType",n,e),s=!0);}else i[o]=e.getAttribute("listType");n=e,e=e.nextSibling;}}}(e.model,t))),i.mapper.registerViewToModelLength("li",iI),t.mapper.registerViewToModelLength("li",iI),i.mapper.on("modelToViewPosition",JS(i.view)),i.mapper.on("viewToModelPosition",(n=e.model,(e,t)=>{const i=t.viewPosition,s=i.parent,o=t.mapper;if("ul"==s.name||"ol"==s.name){if(i.isAtEnd){const e=o.toModelElement(i.nodeBefore),s=o.getModelLength(i.nodeBefore);t.modelPosition=n.createPositionBefore(e).getShiftedBy(s);}else {const e=o.toModelElement(i.nodeAfter);t.modelPosition=n.createPositionBefore(e);}e.stop();}else if("li"==s.name&&i.nodeBefore&&("ul"==i.nodeBefore.name||"ol"==i.nodeBefore.name)){const r=o.toModelElement(s);let a=1,l=i.nodeBefore;for(;l&&eI(l);)a+=o.getModelLength(l),l=l.previousSibling;t.modelPosition=n.createPositionBefore(r).getShiftedBy(a),e.stop();}})),t.mapper.on("modelToViewPosition",JS(i.view)),e.conversion.for("editingDowncast").add((t=>{t.on("insert",jS,{priority:"high"}),t.on("insert:listItem",$S(e.model)),t.on("attribute:listType:listItem",US,{priority:"high"}),t.on("attribute:listType:listItem",WS,{priority:"low"}),t.on("attribute:listIndent:listItem",function(e){return (t,i,n)=>{if(!n.consumable.consume(i.item,"attribute:listIndent"))return;const s=n.mapper.toViewElement(i.item),o=n.writer;o.breakContainer(o.createPositionBefore(s)),o.breakContainer(o.createPositionAfter(s));const r=s.parent,a=r.previousSibling,l=o.createRangeOn(r);o.remove(l),a&&a.nextSibling&&VS(o,a,a.nextSibling),XS(i.attributeOldValue+1,i.range.start,l.start,s,n,e),IS(i.item,s,n,e);for(const e of i.item.getChildren())n.consumable.consume(e,"insert");}}(e.model)),t.on("remove:listItem",function(e){return (t,i,n)=>{const s=n.mapper.toViewPosition(i.position).getLastMatchingPosition((e=>!e.item.is("element","li"))).nodeAfter,o=n.writer;o.breakContainer(o.createPositionBefore(s)),o.breakContainer(o.createPositionAfter(s));const r=s.parent,a=r.previousSibling,l=o.createRangeOn(r),c=o.remove(l);a&&a.nextSibling&&VS(o,a,a.nextSibling),XS(n.mapper.toModelElement(s).getAttribute("listIndent")+1,i.position,l.start,s,n,e);for(const e of o.createRangeIn(c).getItems())n.mapper.unbindViewElement(e);t.stop();}}(e.model)),t.on("remove",qS,{priority:"low"});})),e.conversion.for("dataDowncast").add((t=>{t.on("insert",jS,{priority:"high"}),t.on("insert:listItem",$S(e.model));})),e.conversion.for("upcast").add((e=>{e.on("element:ul",KS,{priority:"high"}),e.on("element:ol",KS,{priority:"high"}),e.on("element:li",ZS,{priority:"high"}),e.on("element:li",GS);})),e.model.on("insertContent",QS,{priority:"high"}),e.commands.add("numberedList",new AS(e,"numbered")),e.commands.add("bulletedList",new AS(e,"bulleted")),e.commands.add("indentList",new PS(e,"forward")),e.commands.add("outdentList",new PS(e,"backward"));const s=i.view.document;this.listenTo(s,"enter",((e,t)=>{const i=this.editor.model.document,n=i.selection.getLastPosition().parent;i.selection.isCollapsed&&"listItem"==n.name&&n.isEmpty&&(this.editor.execute("outdentList"),t.preventDefault(),e.stop());}),{context:"li"}),this.listenTo(s,"delete",((e,t)=>{if("backward"!==t.direction)return;const i=this.editor.model.document.selection;if(!i.isCollapsed)return;const n=i.getFirstPosition();if(!n.isAtStart)return;const s=n.parent;if("listItem"!==s.name)return;s.previousSibling&&"listItem"===s.previousSibling.name||(this.editor.execute("outdentList"),t.preventDefault(),e.stop());}),{context:"li"}),this.listenTo(e.editing.view.document,"tab",((t,i)=>{const n=i.shiftKey?"outdentList":"indentList";this.editor.commands.get(n).isEnabled&&(e.execute(n),i.stopPropagation(),i.preventDefault(),t.stop());}),{context:"li"});}afterInit(){const e=this.editor.commands,t=e.get("indent"),i=e.get("outdent");t&&t.registerChildCommand(e.get("indentList")),i&&i.registerChildCommand(e.get("outdentList"));}}function iI(e){let t=1;for(const i of e.getChildren())if("ul"==i.name||"ol"==i.name)for(const e of i.getChildren())t+=iI(e);return t}class nI extends Dr{static get requires(){return [tI,UP]}static get pluginName(){return "LegacyList"}static get isOfficialPlugin(){return !0}}class sI extends Hr{defaultType;constructor(e,t){super(e),this.defaultType=t;}refresh(){this.value=this._getValue(),this.isEnabled=this._checkEnabled();}execute(e={}){this._tryToConvertItemsToList(e);const t=this.editor.model,i=LS(t);i.length&&t.change((t=>{for(const n of i)t.setAttribute("listStyle",e.type||this.defaultType,n);}));}_getValue(){const e=this.editor.model.document.selection.getFirstPosition().parent;return e&&e.is("element","listItem")?e.getAttribute("listStyle"):null}_checkEnabled(){const e=this.editor,t=e.commands.get("numberedList"),i=e.commands.get("bulletedList");return t.isEnabled||i.isEnabled}_tryToConvertItemsToList(e){if(!e.type)return;const t=DS(e.type);if(!t)return;const i=this.editor,n=`${t}List`;i.commands.get(n).value||i.execute(n);}}class oI extends Hr{refresh(){const e=this._getValue();this.value=e,this.isEnabled=null!=e;}execute(e={}){const t=this.editor.model,i=LS(t).filter((e=>"numbered"==e.getAttribute("listType")));t.change((t=>{for(const n of i)t.setAttribute("listReversed",!!e.reversed,n);}));}_getValue(){const e=this.editor.model.document.selection.getFirstPosition().parent;return e&&e.is("element","listItem")&&"numbered"==e.getAttribute("listType")?e.getAttribute("listReversed"):null}}class rI extends Hr{refresh(){const e=this._getValue();this.value=e,this.isEnabled=null!=e;}execute({startIndex:e=1}={}){const t=this.editor.model,i=LS(t).filter((e=>"numbered"==e.getAttribute("listType")));t.change((t=>{for(const n of i)t.setAttribute("listStart",e>=0?e:1,n);}));}_getValue(){const e=this.editor.model.document.selection.getFirstPosition().parent;return e&&e.is("element","listItem")&&"numbered"==e.getAttribute("listType")?e.getAttribute("listStart"):null}}const aI="default";class lI extends Dr{static get requires(){return [tI]}static get pluginName(){return "LegacyListPropertiesEditing"}static get isOfficialPlugin(){return !0}constructor(e){super(e),e.config.define("list",{properties:{styles:!0,startIndex:!1,reversed:!1}});}init(){const e=this.editor,t=e.model,i=function(e){const t=[];e.styles&&t.push({attributeName:"listStyle",defaultValue:aI,addCommand(e){e.commands.add("listStyle",new sI(e,aI));},appliesToListItem:()=>!0,setAttributeOnDowncast(e,t,i){t&&t!==aI?e.setStyle("list-style-type",t,i):e.removeStyle("list-style-type",i);},getAttributeOnUpcast:e=>e.getStyle("list-style-type")||aI});e.reversed&&t.push({attributeName:"listReversed",defaultValue:!1,addCommand(e){e.commands.add("listReversed",new oI(e));},appliesToListItem:e=>"numbered"==e.getAttribute("listType"),setAttributeOnDowncast(e,t,i){t?e.setAttribute("reversed","reversed",i):e.removeAttribute("reversed",i);},getAttributeOnUpcast:e=>e.hasAttribute("reversed")});e.startIndex&&t.push({attributeName:"listStart",defaultValue:1,addCommand(e){e.commands.add("listStart",new rI(e));},appliesToListItem:e=>"numbered"==e.getAttribute("listType"),setAttributeOnDowncast(e,t,i){0==t||t>1?e.setAttribute("start",t,i):e.removeAttribute("start",i);},getAttributeOnUpcast(e){const t=e.getAttribute("start");return t>=0?t:1}});return t}(e.config.get("list.properties"));t.schema.extend("listItem",{allowAttributes:i.map((e=>e.attributeName))});for(const t of i)t.addCommand(e);var n;this.listenTo(e.commands.get("indentList"),"_executeCleanup",function(e,t){return (i,n)=>{const s=n[0],o=s.getAttribute("listIndent"),r=n.filter((e=>e.getAttribute("listIndent")===o));let a=null;s.previousSibling.getAttribute("listIndent")+1!==o&&(a=OS(s.previousSibling,{sameIndent:!0,direction:"backward",listIndent:o})),e.model.change((e=>{for(const i of r)for(const n of t)if(n.appliesToListItem(i)){const t=null==a?n.defaultValue:a.getAttribute(n.attributeName);e.setAttribute(n.attributeName,t,i);}}));}}(e,i)),this.listenTo(e.commands.get("outdentList"),"_executeCleanup",function(e,t){return (i,n)=>{if(!(n=n.reverse().filter((e=>e.is("element","listItem")))).length)return;const s=n[0].getAttribute("listIndent"),o=n[0].getAttribute("listType");let r=n[0].previousSibling;if(r.is("element","listItem"))for(;r.getAttribute("listIndent")!==s;)r=r.previousSibling;else r=null;r||(r=n[n.length-1].nextSibling),r&&r.is("element","listItem")&&r.getAttribute("listType")===o&&e.model.change((e=>{const i=n.filter((e=>e.getAttribute("listIndent")===s));for(const n of i)for(const i of t)if(i.appliesToListItem(n)){const t=i.attributeName,s=r.getAttribute(t);e.setAttribute(t,s,n);}}));}}(e,i)),this.listenTo(e.commands.get("bulletedList"),"_executeCleanup",uI(e)),this.listenTo(e.commands.get("numberedList"),"_executeCleanup",uI(e)),t.document.registerPostFixer(function(e,t){return i=>{let n=!1;const s=hI(e.model.document.differ.getChanges()).filter((e=>"todo"!==e.getAttribute("listType")));if(!s.length)return n;let o=s[s.length-1].nextSibling;if((!o||!o.is("element","listItem"))&&(o=s[0].previousSibling,o)){const e=s[0].getAttribute("listIndent");for(;o.is("element","listItem")&&o.getAttribute("listIndent")!==e&&(o=o.previousSibling,o););}for(const e of t){const t=e.attributeName;for(const r of s)if(e.appliesToListItem(r))if(r.hasAttribute(t)){const s=r.previousSibling;dI(s,r,e.attributeName)&&(i.setAttribute(t,s.getAttribute(t),r),n=!0);}else cI(o,r,e)?i.setAttribute(t,o.getAttribute(t),r):i.setAttribute(t,e.defaultValue,r),n=!0;else i.removeAttribute(t,r);}return n}}(e,i)),e.conversion.for("upcast").add((n=i,e=>{e.on("element:li",((e,t,i)=>{if(!t.modelRange)return;const s=t.viewItem.parent,o=t.modelRange.start.nodeAfter||t.modelRange.end.nodeBefore;for(const e of n)if(e.appliesToListItem(o)){const t=e.getAttributeOnUpcast(s);i.writer.setAttribute(e.attributeName,t,o);}}),{priority:"low"});})),e.conversion.for("downcast").add(function(e){return i=>{for(const n of e)i.on(`attribute:${n.attributeName}:listItem`,((e,i,s)=>{const o=s.writer,r=i.item,a=OS(r.previousSibling,{sameIndent:!0,listIndent:r.getAttribute("listIndent"),direction:"backward"}),l=s.mapper.toViewElement(r);t(r,a)||o.breakContainer(o.createPositionBefore(l)),n.setAttributeOnDowncast(o,i.attributeNewValue,l.parent);}),{priority:"low"});};function t(e,t){return t&&e.getAttribute("listType")===t.getAttribute("listType")&&e.getAttribute("listIndent")===t.getAttribute("listIndent")&&e.getAttribute("listStyle")===t.getAttribute("listStyle")&&e.getAttribute("listReversed")===t.getAttribute("listReversed")&&e.getAttribute("listStart")===t.getAttribute("listStart")}}(i)),this._mergeListAttributesWhileMergingLists(i);}afterInit(){const e=this.editor;e.commands.get("todoList")&&e.model.document.registerPostFixer(function(e){return t=>{const i=hI(e.model.document.differ.getChanges()).filter((e=>"todo"===e.getAttribute("listType")&&(e.hasAttribute("listStyle")||e.hasAttribute("listReversed")||e.hasAttribute("listStart"))));if(!i.length)return !1;for(const e of i)t.removeAttribute("listStyle",e),t.removeAttribute("listReversed",e),t.removeAttribute("listStart",e);return !0}}(e));}_mergeListAttributesWhileMergingLists(e){const t=this.editor.model;let i;this.listenTo(t,"deleteContent",((e,[t])=>{const n=t.getFirstPosition(),s=t.getLastPosition();if(n.parent===s.parent)return;if(!n.parent.is("element","listItem"))return;const o=s.parent.nextSibling;if(!o||!o.is("element","listItem"))return;const r=OS(n.parent,{sameIndent:!0,listIndent:o.getAttribute("listIndent")});r&&r.getAttribute("listType")===o.getAttribute("listType")&&(i=r);}),{priority:"high"}),this.listenTo(t,"deleteContent",(()=>{i&&(t.change((t=>{const n=OS(i.nextSibling,{sameIndent:!0,listIndent:i.getAttribute("listIndent"),direction:"forward"});if(!n)return void(i=null);const s=[n,...MS(t.createPositionAt(n,0),"forward")];for(const n of s)for(const s of e)if(s.appliesToListItem(n)){const e=s.attributeName,o=i.getAttribute(e);t.setAttribute(e,o,n);}})),i=null);}),{priority:"low"});}}function cI(e,t,i){if(!e)return !1;const n=e.getAttribute(i.attributeName);return !!n&&(n!=i.defaultValue&&e.getAttribute("listType")===t.getAttribute("listType"))}function dI(e,t,i){if(!e||!e.is("element","listItem"))return !1;if(t.getAttribute("listType")!==e.getAttribute("listType"))return !1;const n=e.getAttribute("listIndent");if(n<1||n!==t.getAttribute("listIndent"))return !1;const s=e.getAttribute(i);return !(!s||s===t.getAttribute(i))}function uI(e){return (t,i)=>{i=i.filter((e=>e.is("element","listItem"))),e.model.change((e=>{for(const t of i)e.removeAttribute("listStyle",t);}));}}function hI(e){const t=[];for(const i of e){const e=mI(i);e&&e.is("element","listItem")&&t.push(e);}return t}function mI(e){return "attribute"===e.type?e.range.start.nodeAfter:"insert"===e.type?e.position.nodeAfter:null}class gI extends Dr{static get requires(){return [lI,cS]}static get pluginName(){return "LegacyListProperties"}static get isOfficialPlugin(){return !0}}const fI="todoListChecked";class pI extends Hr{_selectedElements;constructor(e){super(e),this._selectedElements=[],this.on("execute",(()=>{this.refresh();}),{priority:"highest"});}refresh(){this._selectedElements=this._getSelectedItems(),this.value=this._selectedElements.every((e=>!!e.getAttribute(fI))),this.isEnabled=!!this._selectedElements.length;}_getSelectedItems(){const e=this.editor.model,t=e.schema,i=e.document.selection.getFirstRange(),n=i.start.parent,s=[];t.checkAttribute(n,fI)&&s.push(n);for(const e of i.getItems())t.checkAttribute(e,fI)&&!s.includes(e)&&s.push(e);return s}execute(e={}){this.editor.model.change((t=>{for(const i of this._selectedElements){(void 0===e.forceValue?!this.value:e.forceValue)?t.setAttribute(fI,!0,i):t.removeAttribute(fI,i);}}));}}const bI=(e,t,i)=>{const n=t.modelCursor,s=n.parent,o=t.viewItem;if("checkbox"!=o.getAttribute("type")||"listItem"!=s.name||!n.isAtStart)return;if(!i.consumable.consume(o,{name:!0}))return;const r=i.writer;r.setAttribute("listType","todo",s),t.viewItem.hasAttribute("checked")&&r.setAttribute("todoListChecked",!0,s),t.modelRange=r.createRange(n);};function wI(e){return (t,i)=>{const n=i.modelPosition,s=n.parent;if(!s.is("element","listItem")||"todo"!=s.getAttribute("listType"))return;const o=vI(i.mapper.toViewElement(s),e);o&&(i.viewPosition=i.mapper.findPositionIn(o,n.offset));}}function _I(e,t,i,n){return t.createUIElement("label",{class:"todo-list__label",contenteditable:!1},(function(t){const s=ro(document,"input",{type:"checkbox",tabindex:"-1"});i&&s.setAttribute("checked","checked"),s.addEventListener("change",(()=>n(e)));const o=this.toDomElement(t);return o.appendChild(s),o}))}function vI(e,t){const i=t.createRangeIn(e);for(const e of i)if(e.item.is("containerElement","span")&&e.item.hasClass("todo-list__label__description"))return e.item}const yI=rr("Ctrl+Enter");class kI extends Dr{static get pluginName(){return "LegacyTodoListEditing"}static get isOfficialPlugin(){return !0}static get requires(){return [tI]}init(){const e=this.editor,{editing:t,data:i,model:n}=e;n.schema.extend("listItem",{allowAttributes:["todoListChecked"]}),n.schema.addAttributeCheck(((e,t)=>{const i=e.last;if("todoListChecked"==t&&"listItem"==i.name&&"todo"!=i.getAttribute("listType"))return !1})),e.commands.add("todoList",new AS(e,"todo"));const s=new pI(e);var o,r;e.commands.add("checkTodoList",s),e.commands.add("todoListCheck",s),i.downcastDispatcher.on("insert:listItem",function(e){return (t,i,n)=>{const s=n.consumable;if(!s.test(i.item,"insert")||!s.test(i.item,"attribute:listType")||!s.test(i.item,"attribute:listIndent"))return;if("todo"!=i.item.getAttribute("listType"))return;const o=i.item;s.consume(o,"insert"),s.consume(o,"attribute:listType"),s.consume(o,"attribute:listIndent"),s.consume(o,"attribute:todoListChecked");const r=n.writer,a=SS(o,n);r.addClass("todo-list",a.parent);const l=r.createContainerElement("label",{class:"todo-list__label"}),c=r.createEmptyElement("input",{type:"checkbox",disabled:"disabled"}),d=r.createContainerElement("span",{class:"todo-list__label__description"});o.getAttribute("todoListChecked")&&r.setAttribute("checked","checked",c),r.insert(r.createPositionAt(a,0),l),r.insert(r.createPositionAt(l,0),c),r.insert(r.createPositionAfter(c),d),IS(o,a,n,e);}}(n),{priority:"high"}),i.upcastDispatcher.on("element:input",bI,{priority:"high"}),t.downcastDispatcher.on("insert:listItem",function(e,t){return (i,n,s)=>{const o=s.consumable;if(!o.test(n.item,"insert")||!o.test(n.item,"attribute:listType")||!o.test(n.item,"attribute:listIndent"))return;if("todo"!=n.item.getAttribute("listType"))return;const r=n.item;o.consume(r,"insert"),o.consume(r,"attribute:listType"),o.consume(r,"attribute:listIndent"),o.consume(r,"attribute:todoListChecked");const a=s.writer,l=SS(r,s),c=!!r.getAttribute("todoListChecked"),d=_I(r,a,c,t),u=a.createContainerElement("span",{class:"todo-list__label__description"});a.addClass("todo-list",l.parent),a.insert(a.createPositionAt(l,0),d),a.insert(a.createPositionAfter(d),u),IS(r,l,s,e);}}(n,(e=>this._handleCheckmarkChange(e))),{priority:"high"}),t.downcastDispatcher.on("attribute:listType:listItem",(o=e=>this._handleCheckmarkChange(e),r=t.view,(e,t,i)=>{if(!i.consumable.consume(t.item,e.name))return;const n=i.mapper.toViewElement(t.item),s=i.writer,a=function(e,t){const i=t.createRangeIn(e);for(const e of i)if(e.item.is("uiElement","label"))return e.item}(n,r);if("todo"==t.attributeNewValue){const e=!!t.item.getAttribute("todoListChecked"),i=_I(t.item,s,e,o),r=s.createContainerElement("span",{class:"todo-list__label__description"}),a=s.createRangeIn(n),l=BS(n),c=RS(a.start),d=l?s.createPositionBefore(l):a.end,u=s.createRange(c,d);s.addClass("todo-list",n.parent),s.move(u,s.createPositionAt(r,0)),s.insert(s.createPositionAt(n,0),i),s.insert(s.createPositionAfter(i),r);}else if("todo"==t.attributeOldValue){const e=vI(n,r);s.removeClass("todo-list",n.parent),s.remove(a),s.move(s.createRangeIn(e),s.createPositionBefore(e)),s.remove(e);}})),t.downcastDispatcher.on("attribute:todoListChecked:listItem",function(e){return (t,i,n)=>{if("todo"!=i.item.getAttribute("listType"))return;if(!n.consumable.consume(i.item,"attribute:todoListChecked"))return;const{mapper:s,writer:o}=n,r=!!i.item.getAttribute("todoListChecked"),a=s.toViewElement(i.item).getChild(0),l=_I(i.item,o,r,e);o.insert(o.createPositionAfter(a),l),o.remove(a);}}((e=>this._handleCheckmarkChange(e)))),t.mapper.on("modelToViewPosition",wI(t.view)),i.mapper.on("modelToViewPosition",wI(t.view)),this.listenTo(t.view.document,"arrowKey",function(e,t){return (i,n)=>{if("left"!=cr(n.keyCode,t.contentLanguageDirection))return;const s=e.schema,o=e.document.selection;if(!o.isCollapsed)return;const r=o.getFirstPosition(),a=r.parent;if("listItem"===a.name&&"todo"==a.getAttribute("listType")&&r.isAtStart){const t=s.getNearestSelectionRange(e.createPositionBefore(a),"backward");t&&e.change((e=>e.setSelection(t))),n.preventDefault(),n.stopPropagation(),i.stop();}}}(n,e.locale),{context:"li"}),this.listenTo(t.view.document,"keydown",((t,i)=>{or(i)===yI&&(e.execute("checkTodoList"),t.stop());}),{priority:"high"});const a=new Set;this.listenTo(n,"applyOperation",((e,t)=>{const i=t[0];if("rename"==i.type&&"listItem"==i.oldName){const e=i.position.nodeAfter;e.hasAttribute("todoListChecked")&&a.add(e);}else if("changeAttribute"==i.type&&"listType"==i.key&&"todo"===i.oldValue)for(const e of i.range.getItems())e.hasAttribute("todoListChecked")&&"todo"!==e.getAttribute("listType")&&a.add(e);})),n.document.registerPostFixer((e=>{let t=!1;for(const i of a)e.removeAttribute("todoListChecked",i),t=!0;return a.clear(),t})),this._initAriaAnnouncements();}_handleCheckmarkChange(e){const t=this.editor,i=t.model,n=Array.from(i.document.selection.getRanges());i.change((i=>{i.setSelection(e,"end"),t.execute("checkTodoList"),i.setSelection(n);}));}_initAriaAnnouncements(){const{model:e,ui:t,t:i}=this.editor;let n=null;t&&e.document.selection.on("change:range",(()=>{const s=e.document.selection.focus.parent,o=CI(n),r=CI(s);o&&!r?t.ariaLiveAnnouncer.announce(i("Leaving a to-do list")):!o&&r&&t.ariaLiveAnnouncer.announce(i("Entering a to-do list")),n=s;}));}}function CI(e){return !!e&&e.is("element","listItem")&&"todo"===e.getAttribute("listType")}class xI extends Dr{static get requires(){return [kI,CS]}static get pluginName(){return "LegacyTodoList"}static get isOfficialPlugin(){return !0}}class AI extends Dr{static get pluginName(){return "AdjacentListsSupport"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;e.model.schema.register("listSeparator",{allowWhere:"$block",isBlock:!0}),e.conversion.for("upcast").add((e=>{e.on("element:ol",EI()),e.on("element:ul",EI());})).elementToElement({model:"listSeparator",view:"ck-list-separator"}),e.conversion.for("editingDowncast").elementToElement({model:"listSeparator",view:{name:"div",classes:["ck-list-separator","ck-hidden"]}}),e.conversion.for("dataDowncast").elementToElement({model:"listSeparator",view:(e,t)=>{const i=t.writer.createContainerElement("ck-list-separator");return t.writer.setCustomProperty("dataPipeline:transparentRendering",!0,i),i.getFillerOffset=()=>null,i}});}}function EI(){return (e,t,i)=>{const n=t.viewItem,s=n.nextSibling;if(!s)return;if(n.name!==s.name)return;t.modelRange||Object.assign(t,i.convertChildren(t.viewItem,t.modelCursor));const o=i.writer,r=o.createElement("listSeparator");if(!i.safeInsert(r,t.modelCursor))return;const a=i.getSplitParts(r);t.modelRange=o.createRange(t.modelRange.start,o.createPositionAfter(a[a.length-1])),i.updateConversionResult(r,t);}}class TI extends Dr{static get requires(){return [WP]}static get pluginName(){return "DocumentList"}static get isOfficialPlugin(){return !0}constructor(e){super(e),E("plugin-obsolete-documentlist",{pluginName:"DocumentList"});}}class PI extends Dr{static get requires(){return [gS]}static get pluginName(){return "DocumentListProperties"}static get isOfficialPlugin(){return !0}constructor(e){super(e),E("plugin-obsolete-documentlistproperties",{pluginName:"DocumentListProperties"});}}class SI extends Dr{static get requires(){return [xS]}static get pluginName(){return "TodoDocumentList"}static get isOfficialPlugin(){return !0}constructor(e){super(e),E("plugin-obsolete-tododocumentlist",{pluginName:"TodoDocumentList"});}}function II(){return {baseUrl:null,breaks:!1,extensions:null,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1}}let VI={baseUrl:null,breaks:!1,extensions:null,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1};const RI=/[&<>"']/,OI=/[&<>"']/g,BI=/[<>"']|&(?!#?\w+;)/,MI=/[<>"']|&(?!#?\w+;)/g,LI={"&":"&","<":"<",">":">",'"':""","'":"'"},FI=e=>LI[e];function NI(e,t){if(t){if(RI.test(e))return e.replace(OI,FI)}else if(BI.test(e))return e.replace(MI,FI);return e}const DI=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;function zI(e){return e.replace(DI,((e,t)=>"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""))}const HI=/(^|[^\[])\^/g;function $I(e,t){e=e.source||e,t=t||"";const i={replace:(t,n)=>(n=(n=n.source||n).replace(HI,"$1"),e=e.replace(t,n),i),getRegex:()=>new RegExp(e,t)};return i}const UI=/[^\w:]/g,WI=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;function jI(e,t,i){if(e){let e;try{e=decodeURIComponent(zI(i)).replace(UI,"").toLowerCase();}catch(e){return null}if(0===e.indexOf("javascript:")||0===e.indexOf("vbscript:")||0===e.indexOf("data:"))return null}t&&!WI.test(i)&&(i=function(e,t){qI[" "+e]||(GI.test(e)?qI[" "+e]=e+"/":qI[" "+e]=XI(e,"/",!0));e=qI[" "+e];const i=-1===e.indexOf(":");return "//"===t.substring(0,2)?i?t:e.replace(KI,"$1")+t:"/"===t.charAt(0)?i?t:e.replace(ZI,"$1")+t:e+t}(t,i));try{i=encodeURI(i).replace(/%25/g,"%");}catch(e){return null}return i}const qI={},GI=/^[^:]+:\/*[^/]*$/,KI=/^([^:]+:)[\s\S]*$/,ZI=/^([^:]+:\/*[^/]*)[\s\S]*$/;const JI={exec:function(){}};function QI(e){let t,i,n=1;for(;n{let n=!1,s=t;for(;--s>=0&&"\\"===i[s];)n=!n;return n?"|":" |"})).split(/ \|/);let n=0;if(i[0].trim()||i.shift(),i.length>0&&!i[i.length-1].trim()&&i.pop(),i.length>t)i.splice(t);else for(;i.length1;)1&t&&(i+=e),t>>=1,e+=e;return i+e}function iV(e,t,i,n){const s=t.href,o=t.title?NI(t.title):null,r=e[1].replace(/\\([\[\]])/g,"$1");if("!"!==e[0].charAt(0)){n.state.inLink=!0;const e={type:"link",raw:i,href:s,title:o,text:r,tokens:n.inlineTokens(r,[])};return n.state.inLink=!1,e}return {type:"image",raw:i,href:s,title:o,text:NI(r)}}class nV{constructor(e){this.options=e||VI;}space(e){const t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)return {type:"space",raw:t[0]}}code(e){const t=this.rules.block.code.exec(e);if(t){const e=t[0].replace(/^ {1,4}/gm,"");return {type:"code",raw:t[0],codeBlockStyle:"indented",text:this.options.pedantic?e:XI(e,"\n")}}}fences(e){const t=this.rules.block.fences.exec(e);if(t){const e=t[0],i=function(e,t){const i=e.match(/^(\s+)(?:```)/);if(null===i)return t;const n=i[1];return t.split("\n").map((e=>{const t=e.match(/^\s+/);if(null===t)return e;const[i]=t;return i.length>=n.length?e.slice(n.length):e})).join("\n")}(e,t[3]||"");return {type:"code",raw:e,lang:t[2]?t[2].trim():t[2],text:i}}}heading(e){const t=this.rules.block.heading.exec(e);if(t){let e=t[2].trim();if(/#$/.test(e)){const t=XI(e,"#");this.options.pedantic?e=t.trim():t&&!/ $/.test(t)||(e=t.trim());}const i={type:"heading",raw:t[0],depth:t[1].length,text:e,tokens:[]};return this.lexer.inline(i.text,i.tokens),i}}hr(e){const t=this.rules.block.hr.exec(e);if(t)return {type:"hr",raw:t[0]}}blockquote(e){const t=this.rules.block.blockquote.exec(e);if(t){const e=t[0].replace(/^ *> ?/gm,"");return {type:"blockquote",raw:t[0],tokens:this.lexer.blockTokens(e,[]),text:e}}}list(e){let t=this.rules.block.list.exec(e);if(t){let i,n,s,o,r,a,l,c,d,u,h,m,g=t[1].trim();const f=g.length>1,p={type:"list",raw:"",ordered:f,start:f?+g.slice(0,-1):"",loose:!1,items:[]};g=f?`\\d{1,9}\\${g.slice(-1)}`:`\\${g}`,this.options.pedantic&&(g=f?g:"[*+-]");const b=new RegExp(`^( {0,3}${g})((?: [^\\n]*)?(?:\\n|$))`);for(;e&&(m=!1,t=b.exec(e))&&!this.rules.block.hr.test(e);){if(i=t[0],e=e.substring(i.length),c=t[2].split("\n",1)[0],d=e.split("\n",1)[0],this.options.pedantic?(o=2,h=c.trimLeft()):(o=t[2].search(/[^ ]/),o=o>4?1:o,h=c.slice(o),o+=t[1].length),a=!1,!c&&/^ *$/.test(d)&&(i+=d+"\n",e=e.substring(d.length+1),m=!0),!m){const t=new RegExp(`^ {0,${Math.min(3,o-1)}}(?:[*+-]|\\d{1,9}[.)])`);for(;e&&(u=e.split("\n",1)[0],c=u,this.options.pedantic&&(c=c.replace(/^ {1,4}(?=( {4})*[^ ])/g," ")),!t.test(c));){if(c.search(/[^ ]/)>=o||!c.trim())h+="\n"+c.slice(o);else {if(a)break;h+="\n"+c;}a||c.trim()||(a=!0),i+=u+"\n",e=e.substring(u.length+1);}}p.loose||(l?p.loose=!0:/\n *\n *$/.test(i)&&(l=!0)),this.options.gfm&&(n=/^\[[ xX]\] /.exec(h),n&&(s="[ ] "!==n[0],h=h.replace(/^\[[ xX]\] +/,""))),p.items.push({type:"list_item",raw:i,task:!!n,checked:s,loose:!1,text:h}),p.raw+=i;}p.items[p.items.length-1].raw=i.trimRight(),p.items[p.items.length-1].text=h.trimRight(),p.raw=p.raw.trimRight();const w=p.items.length;for(r=0;r"space"===e.type)),t=e.every((e=>{const t=e.raw.split("");let i=0;for(const e of t)if("\n"===e&&(i+=1),i>1)return !0;return !1}));!p.loose&&e.length&&t&&(p.loose=!0,p.items[r].loose=!0);}return p}}html(e){const t=this.rules.block.html.exec(e);if(t){const e={type:"html",raw:t[0],pre:!this.options.sanitizer&&("pre"===t[1]||"script"===t[1]||"style"===t[1]),text:t[0]};return this.options.sanitize&&(e.type="paragraph",e.text=this.options.sanitizer?this.options.sanitizer(t[0]):NI(t[0]),e.tokens=[],this.lexer.inline(e.text,e.tokens)),e}}def(e){const t=this.rules.block.def.exec(e);if(t){t[3]&&(t[3]=t[3].substring(1,t[3].length-1));return {type:"def",tag:t[1].toLowerCase().replace(/\s+/g," "),raw:t[0],href:t[2],title:t[3]}}}table(e){const t=this.rules.block.table.exec(e);if(t){const e={type:"table",header:YI(t[1]).map((e=>({text:e}))),align:t[2].replace(/^ *|\| *$/g,"").split(/ *\| */),rows:t[3]&&t[3].trim()?t[3].replace(/\n[ \t]*$/,"").split("\n"):[]};if(e.header.length===e.align.length){e.raw=t[0];let i,n,s,o,r=e.align.length;for(i=0;i({text:e})));for(r=e.header.length,n=0;n/i.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&/^<(pre|code|kbd|script)(\s|>)/i.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:this.options.sanitize?"text":"html",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,text:this.options.sanitize?this.options.sanitizer?this.options.sanitizer(t[0]):NI(t[0]):t[0]}}link(e){const t=this.rules.inline.link.exec(e);if(t){const e=t[2].trim();if(!this.options.pedantic&&/^$/.test(e))return;const t=XI(e.slice(0,-1),"\\");if((e.length-t.length)%2==0)return}else {const e=function(e,t){if(-1===e.indexOf(t[1]))return -1;const i=e.length;let n=0,s=0;for(;s-1){const i=(0===t[0].indexOf("!")?5:4)+t[1].length+e;t[2]=t[2].substring(0,e),t[0]=t[0].substring(0,i).trim(),t[3]="";}}let i=t[2],n="";if(this.options.pedantic){const e=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(i);e&&(i=e[1],n=e[3]);}else n=t[3]?t[3].slice(1,-1):"";return i=i.trim(),/^$/.test(e)?i.slice(1):i.slice(1,-1)),iV(t,{href:i?i.replace(this.rules.inline._escapes,"$1"):i,title:n?n.replace(this.rules.inline._escapes,"$1"):n},t[0],this.lexer)}}reflink(e,t){let i;if((i=this.rules.inline.reflink.exec(e))||(i=this.rules.inline.nolink.exec(e))){let e=(i[2]||i[1]).replace(/\s+/g," ");if(e=t[e.toLowerCase()],!e||!e.href){const e=i[0].charAt(0);return {type:"text",raw:e,text:e}}return iV(i,e,i[0],this.lexer)}}emStrong(e,t,i=""){let n=this.rules.inline.emStrong.lDelim.exec(e);if(!n)return;if(n[3]&&i.match(/[\p{L}\p{N}]/u))return;const s=n[1]||n[2]||"";if(!s||s&&(""===i||this.rules.inline.punctuation.exec(i))){const i=n[0].length-1;let s,o,r=i,a=0;const l="*"===n[0][0]?this.rules.inline.emStrong.rDelimAst:this.rules.inline.emStrong.rDelimUnd;for(l.lastIndex=0,t=t.slice(-1*e.length+i);null!=(n=l.exec(t));){if(s=n[1]||n[2]||n[3]||n[4]||n[5]||n[6],!s)continue;if(o=s.length,n[3]||n[4]){r+=o;continue}if((n[5]||n[6])&&i%3&&!((i+o)%3)){a+=o;continue}if(r-=o,r>0)continue;if(o=Math.min(o,o+r+a),Math.min(i,o)%2){const t=e.slice(1,i+n.index+o);return {type:"em",raw:e.slice(0,i+n.index+o+1),text:t,tokens:this.lexer.inlineTokens(t,[])}}const t=e.slice(2,i+n.index+o-1);return {type:"strong",raw:e.slice(0,i+n.index+o+1),text:t,tokens:this.lexer.inlineTokens(t,[])}}}}codespan(e){const t=this.rules.inline.code.exec(e);if(t){let e=t[2].replace(/\n/g," ");const i=/[^ ]/.test(e),n=/^ /.test(e)&&/ $/.test(e);return i&&n&&(e=e.substring(1,e.length-1)),e=NI(e,!0),{type:"codespan",raw:t[0],text:e}}}br(e){const t=this.rules.inline.br.exec(e);if(t)return {type:"br",raw:t[0]}}del(e){const t=this.rules.inline.del.exec(e);if(t)return {type:"del",raw:t[0],text:t[2],tokens:this.lexer.inlineTokens(t[2],[])}}autolink(e,t){const i=this.rules.inline.autolink.exec(e);if(i){let e,n;return "@"===i[2]?(e=NI(this.options.mangle?t(i[1]):i[1]),n="mailto:"+e):(e=NI(i[1]),n=e),{type:"link",raw:i[0],text:e,href:n,tokens:[{type:"text",raw:e,text:e}]}}}url(e,t){let i;if(i=this.rules.inline.url.exec(e)){let e,n;if("@"===i[2])e=NI(this.options.mangle?t(i[0]):i[0]),n="mailto:"+e;else {let t;do{t=i[0],i[0]=this.rules.inline._backpedal.exec(i[0])[0];}while(t!==i[0]);e=NI(i[0]),n="www."===i[1]?"http://"+e:e;}return {type:"link",raw:i[0],text:e,href:n,tokens:[{type:"text",raw:e,text:e}]}}}inlineText(e,t){const i=this.rules.inline.text.exec(e);if(i){let e;return e=this.lexer.state.inRawBlock?this.options.sanitize?this.options.sanitizer?this.options.sanitizer(i[0]):NI(i[0]):i[0]:NI(this.options.smartypants?t(i[0]):i[0]),{type:"text",raw:i[0],text:e}}}}const sV={newline:/^(?: *(?:\n|$))+/,code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,fences:/^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( {0,3}bull)( [^\n]+?)?(?:\n|$)/,html:"^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))",def:/^ {0,3}\[(label)\]: *(?:\n *)?]+)>?(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,table:JI,lheading:/^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,_paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,text:/^[^\n]+/,_label:/(?!\s*\])(?:\\.|[^\[\]\\])+/,_title:/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/};sV.def=$I(sV.def).replace("label",sV._label).replace("title",sV._title).getRegex(),sV.bullet=/(?:[*+-]|\d{1,9}[.)])/,sV.listItemStart=$I(/^( *)(bull) */).replace("bull",sV.bullet).getRegex(),sV.list=$I(sV.list).replace(/bull/g,sV.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+sV.def.source+")").getRegex(),sV._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",sV._comment=/|$)/,sV.html=$I(sV.html,"i").replace("comment",sV._comment).replace("tag",sV._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),sV.paragraph=$I(sV._paragraph).replace("hr",sV.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",sV._tag).getRegex(),sV.blockquote=$I(sV.blockquote).replace("paragraph",sV.paragraph).getRegex(),sV.normal=QI({},sV),sV.gfm=QI({},sV.normal,{table:"^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"}),sV.gfm.table=$I(sV.gfm.table).replace("hr",sV.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",sV._tag).getRegex(),sV.gfm.paragraph=$I(sV._paragraph).replace("hr",sV.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("table",sV.gfm.table).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",sV._tag).getRegex(),sV.pedantic=QI({},sV.normal,{html:$I("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",sV._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:JI,paragraph:$I(sV.normal._paragraph).replace("hr",sV.hr).replace("heading"," *#{1,6} *[^\n]").replace("lheading",sV.lheading).replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").getRegex()});const oV={escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:JI,tag:"^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^",link:/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(ref)\]/,nolink:/^!?\[(ref)\](?:\[\])?/,reflinkSearch:"reflink|nolink(?!\\()",emStrong:{lDelim:/^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,rDelimAst:/^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,rDelimUnd:/^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/},code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,br:/^( {2,}|\\)\n(?!\s*$)/,del:JI,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\.5&&(i="x"+i.toString(16)),n+="&#"+i+";";return n}oV._punctuation="!\"#$%&'()+\\-.,/:;<=>?@\\[\\]`^{|}~",oV.punctuation=$I(oV.punctuation).replace(/punctuation/g,oV._punctuation).getRegex(),oV.blockSkip=/\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g,oV.escapedEmSt=/\\\*|\\_/g,oV._comment=$I(sV._comment).replace("(?:--\x3e|$)","--\x3e").getRegex(),oV.emStrong.lDelim=$I(oV.emStrong.lDelim).replace(/punct/g,oV._punctuation).getRegex(),oV.emStrong.rDelimAst=$I(oV.emStrong.rDelimAst,"g").replace(/punct/g,oV._punctuation).getRegex(),oV.emStrong.rDelimUnd=$I(oV.emStrong.rDelimUnd,"g").replace(/punct/g,oV._punctuation).getRegex(),oV._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,oV._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,oV._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,oV.autolink=$I(oV.autolink).replace("scheme",oV._scheme).replace("email",oV._email).getRegex(),oV._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,oV.tag=$I(oV.tag).replace("comment",oV._comment).replace("attribute",oV._attribute).getRegex(),oV._label=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,oV._href=/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/,oV._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,oV.link=$I(oV.link).replace("label",oV._label).replace("href",oV._href).replace("title",oV._title).getRegex(),oV.reflink=$I(oV.reflink).replace("label",oV._label).replace("ref",sV._label).getRegex(),oV.nolink=$I(oV.nolink).replace("ref",sV._label).getRegex(),oV.reflinkSearch=$I(oV.reflinkSearch,"g").replace("reflink",oV.reflink).replace("nolink",oV.nolink).getRegex(),oV.normal=QI({},oV),oV.pedantic=QI({},oV.normal,{strong:{start:/^__|\*\*/,middle:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,endAst:/\*\*(?!\*)/g,endUnd:/__(?!_)/g},em:{start:/^_|\*/,middle:/^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,endAst:/\*(?!\*)/g,endUnd:/_(?!_)/g},link:$I(/^!?\[(label)\]\((.*?)\)/).replace("label",oV._label).getRegex(),reflink:$I(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",oV._label).getRegex()}),oV.gfm=QI({},oV.normal,{escape:$I(oV.escape).replace("])","~|])").getRegex(),_extended_email:/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,url:/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\!!(i=n.call({lexer:this},e,t))&&(e=e.substring(i.raw.length),t.push(i),!0)))))if(i=this.tokenizer.space(e))e=e.substring(i.raw.length),1===i.raw.length&&t.length>0?t[t.length-1].raw+="\n":t.push(i);else if(i=this.tokenizer.code(e))e=e.substring(i.raw.length),n=t[t.length-1],!n||"paragraph"!==n.type&&"text"!==n.type?t.push(i):(n.raw+="\n"+i.raw,n.text+="\n"+i.text,this.inlineQueue[this.inlineQueue.length-1].src=n.text);else if(i=this.tokenizer.fences(e))e=e.substring(i.raw.length),t.push(i);else if(i=this.tokenizer.heading(e))e=e.substring(i.raw.length),t.push(i);else if(i=this.tokenizer.hr(e))e=e.substring(i.raw.length),t.push(i);else if(i=this.tokenizer.blockquote(e))e=e.substring(i.raw.length),t.push(i);else if(i=this.tokenizer.list(e))e=e.substring(i.raw.length),t.push(i);else if(i=this.tokenizer.html(e))e=e.substring(i.raw.length),t.push(i);else if(i=this.tokenizer.def(e))e=e.substring(i.raw.length),n=t[t.length-1],!n||"paragraph"!==n.type&&"text"!==n.type?this.tokens.links[i.tag]||(this.tokens.links[i.tag]={href:i.href,title:i.title}):(n.raw+="\n"+i.raw,n.text+="\n"+i.raw,this.inlineQueue[this.inlineQueue.length-1].src=n.text);else if(i=this.tokenizer.table(e))e=e.substring(i.raw.length),t.push(i);else if(i=this.tokenizer.lheading(e))e=e.substring(i.raw.length),t.push(i);else {if(s=e,this.options.extensions&&this.options.extensions.startBlock){let t=1/0;const i=e.slice(1);let n;this.options.extensions.startBlock.forEach((function(e){n=e.call({lexer:this},i),"number"==typeof n&&n>=0&&(t=Math.min(t,n));})),t<1/0&&t>=0&&(s=e.substring(0,t+1));}if(this.state.top&&(i=this.tokenizer.paragraph(s)))n=t[t.length-1],o&&"paragraph"===n.type?(n.raw+="\n"+i.raw,n.text+="\n"+i.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=n.text):t.push(i),o=s.length!==e.length,e=e.substring(i.raw.length);else if(i=this.tokenizer.text(e))e=e.substring(i.raw.length),n=t[t.length-1],n&&"text"===n.type?(n.raw+="\n"+i.raw,n.text+="\n"+i.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=n.text):t.push(i);else if(e){const t="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(t);break}throw new Error(t)}}return this.state.top=!0,t}inline(e,t){this.inlineQueue.push({src:e,tokens:t});}inlineTokens(e,t=[]){let i,n,s,o,r,a,l=e;if(this.tokens.links){const e=Object.keys(this.tokens.links);if(e.length>0)for(;null!=(o=this.tokenizer.rules.inline.reflinkSearch.exec(l));)e.includes(o[0].slice(o[0].lastIndexOf("[")+1,-1))&&(l=l.slice(0,o.index)+"["+tV("a",o[0].length-2)+"]"+l.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex));}for(;null!=(o=this.tokenizer.rules.inline.blockSkip.exec(l));)l=l.slice(0,o.index)+"["+tV("a",o[0].length-2)+"]"+l.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);for(;null!=(o=this.tokenizer.rules.inline.escapedEmSt.exec(l));)l=l.slice(0,o.index)+"++"+l.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);for(;e;)if(r||(a=""),r=!1,!(this.options.extensions&&this.options.extensions.inline&&this.options.extensions.inline.some((n=>!!(i=n.call({lexer:this},e,t))&&(e=e.substring(i.raw.length),t.push(i),!0)))))if(i=this.tokenizer.escape(e))e=e.substring(i.raw.length),t.push(i);else if(i=this.tokenizer.tag(e))e=e.substring(i.raw.length),n=t[t.length-1],n&&"text"===i.type&&"text"===n.type?(n.raw+=i.raw,n.text+=i.text):t.push(i);else if(i=this.tokenizer.link(e))e=e.substring(i.raw.length),t.push(i);else if(i=this.tokenizer.reflink(e,this.tokens.links))e=e.substring(i.raw.length),n=t[t.length-1],n&&"text"===i.type&&"text"===n.type?(n.raw+=i.raw,n.text+=i.text):t.push(i);else if(i=this.tokenizer.emStrong(e,l,a))e=e.substring(i.raw.length),t.push(i);else if(i=this.tokenizer.codespan(e))e=e.substring(i.raw.length),t.push(i);else if(i=this.tokenizer.br(e))e=e.substring(i.raw.length),t.push(i);else if(i=this.tokenizer.del(e))e=e.substring(i.raw.length),t.push(i);else if(i=this.tokenizer.autolink(e,aV))e=e.substring(i.raw.length),t.push(i);else if(this.state.inLink||!(i=this.tokenizer.url(e,aV))){if(s=e,this.options.extensions&&this.options.extensions.startInline){let t=1/0;const i=e.slice(1);let n;this.options.extensions.startInline.forEach((function(e){n=e.call({lexer:this},i),"number"==typeof n&&n>=0&&(t=Math.min(t,n));})),t<1/0&&t>=0&&(s=e.substring(0,t+1));}if(i=this.tokenizer.inlineText(s,rV))e=e.substring(i.raw.length),"_"!==i.raw.slice(-1)&&(a=i.raw.slice(-1)),r=!0,n=t[t.length-1],n&&"text"===n.type?(n.raw+=i.raw,n.text+=i.text):t.push(i);else if(e){const t="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(t);break}throw new Error(t)}}else e=e.substring(i.raw.length),t.push(i);return t}}class cV{constructor(e){this.options=e||VI;}code(e,t,i){const n=(t||"").match(/\S*/)[0];if(this.options.highlight){const t=this.options.highlight(e,n);null!=t&&t!==e&&(i=!0,e=t);}return e=e.replace(/\n$/,"")+"\n",n?'
'+(i?e:NI(e,!0))+"
\n":"
"+(i?e:NI(e,!0))+"
\n"}blockquote(e){return "
\n"+e+"
\n"}html(e){return e}heading(e,t,i,n){return this.options.headerIds?"'+e+"\n":""+e+"\n"}hr(){return this.options.xhtml?"
\n":"
\n"}list(e,t,i){const n=t?"ol":"ul";return "<"+n+(t&&1!==i?' start="'+i+'"':"")+">\n"+e+"\n"}listitem(e){return "
  • "+e+"
  • \n"}checkbox(e){return " "}paragraph(e){return "

    "+e+"

    \n"}table(e,t){return t&&(t=""+t+""),"\n\n"+e+"\n"+t+"
    \n"}tablerow(e){return "\n"+e+"\n"}tablecell(e,t){const i=t.header?"th":"td";return (t.align?"<"+i+' align="'+t.align+'">':"<"+i+">")+e+"\n"}strong(e){return ""+e+""}em(e){return ""+e+""}codespan(e){return ""+e+""}br(){return this.options.xhtml?"
    ":"
    "}del(e){return ""+e+""}link(e,t,i){if(null===(e=jI(this.options.sanitize,this.options.baseUrl,e)))return i;let n='",n}image(e,t,i){if(null===(e=jI(this.options.sanitize,this.options.baseUrl,e)))return i;let n=''+i+'":">",n}text(e){return e}}class dV{strong(e){return e}em(e){return e}codespan(e){return e}del(e){return e}html(e){return e}text(e){return e}link(e,t,i){return ""+i}image(e,t,i){return ""+i}br(){return ""}}class uV{constructor(){this.seen={};}serialize(e){return e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-")}getNextSafeSlug(e,t){let i=e,n=0;if(this.seen.hasOwnProperty(i)){n=this.seen[e];do{n++,i=e+"-"+n;}while(this.seen.hasOwnProperty(i))}return t||(this.seen[e]=n,this.seen[i]=0),i}slug(e,t={}){const i=this.serialize(e);return this.getNextSafeSlug(i,t.dryrun)}}class hV{constructor(e){this.options=e||VI,this.options.renderer=this.options.renderer||new cV,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new dV,this.slugger=new uV;}static parse(e,t){return new hV(t).parse(e)}static parseInline(e,t){return new hV(t).parseInline(e)}parse(e,t=!0){let i,n,s,o,r,a,l,c,d,u,h,m,g,f,p,b,w,_,v,y="";const k=e.length;for(i=0;i0&&"paragraph"===p.tokens[0].type?(p.tokens[0].text=_+" "+p.tokens[0].text,p.tokens[0].tokens&&p.tokens[0].tokens.length>0&&"text"===p.tokens[0].tokens[0].type&&(p.tokens[0].tokens[0].text=_+" "+p.tokens[0].tokens[0].text)):p.tokens.unshift({type:"text",text:_}):f+=_),f+=this.parse(p.tokens,g),d+=this.renderer.listitem(f,w,b);y+=this.renderer.list(d,h,m);continue;case"html":y+=this.renderer.html(u.text);continue;case"paragraph":y+=this.renderer.paragraph(this.parseInline(u.tokens));continue;case"text":for(d=u.tokens?this.parseInline(u.tokens):u.text;i+1{n(e.text,e.lang,(function(t,i){if(t)return o(t);null!=i&&i!==e.text&&(e.text=i,e.escaped=!0),r--,0===r&&o();}));}),0));})),void(0===r&&o())}try{const i=lV.lex(e,t);return t.walkTokens&&mV.walkTokens(i,t.walkTokens),hV.parse(i,t)}catch(e){if(e.message+="\nPlease report this to https://github.com/markedjs/marked.",t.silent)return "

    An error occurred:

    "+NI(e.message+"",!0)+"
    ";throw e}}mV.options=mV.setOptions=function(e){var t;return QI(mV.defaults,e),t=mV.defaults,VI=t,mV},mV.getDefaults=II,mV.defaults=VI,mV.use=function(...e){const t=QI({},...e),i=mV.defaults.extensions||{renderers:{},childTokens:{}};let n;e.forEach((e=>{if(e.extensions&&(n=!0,e.extensions.forEach((e=>{if(!e.name)throw new Error("extension name required");if(e.renderer){const t=i.renderers?i.renderers[e.name]:null;i.renderers[e.name]=t?function(...i){let n=e.renderer.apply(this,i);return !1===n&&(n=t.apply(this,i)),n}:e.renderer;}if(e.tokenizer){if(!e.level||"block"!==e.level&&"inline"!==e.level)throw new Error("extension level must be 'block' or 'inline'");i[e.level]?i[e.level].unshift(e.tokenizer):i[e.level]=[e.tokenizer],e.start&&("block"===e.level?i.startBlock?i.startBlock.push(e.start):i.startBlock=[e.start]:"inline"===e.level&&(i.startInline?i.startInline.push(e.start):i.startInline=[e.start]));}e.childTokens&&(i.childTokens[e.name]=e.childTokens);}))),e.renderer){const i=mV.defaults.renderer||new cV;for(const t in e.renderer){const n=i[t];i[t]=(...s)=>{let o=e.renderer[t].apply(i,s);return !1===o&&(o=n.apply(i,s)),o};}t.renderer=i;}if(e.tokenizer){const i=mV.defaults.tokenizer||new nV;for(const t in e.tokenizer){const n=i[t];i[t]=(...s)=>{let o=e.tokenizer[t].apply(i,s);return !1===o&&(o=n.apply(i,s)),o};}t.tokenizer=i;}if(e.walkTokens){const i=mV.defaults.walkTokens;t.walkTokens=function(t){e.walkTokens.call(this,t),i&&i.call(this,t);};}n&&(t.extensions=i),mV.setOptions(t);}));},mV.walkTokens=function(e,t){for(const i of e)switch(t.call(mV,i),i.type){case"table":for(const e of i.header)mV.walkTokens(e.tokens,t);for(const e of i.rows)for(const i of e)mV.walkTokens(i.tokens,t);break;case"list":mV.walkTokens(i.items,t);break;default:mV.defaults.extensions&&mV.defaults.extensions.childTokens&&mV.defaults.extensions.childTokens[i.type]?mV.defaults.extensions.childTokens[i.type].forEach((function(e){mV.walkTokens(i[e],t);})):i.tokens&&mV.walkTokens(i.tokens,t);}},mV.parseInline=function(e,t){if(null==e)throw new Error("marked.parseInline(): input parameter is undefined or null");if("string"!=typeof e)throw new Error("marked.parseInline(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected");eV(t=QI({},mV.defaults,t||{}));try{const i=lV.lexInline(e,t);return t.walkTokens&&mV.walkTokens(i,t.walkTokens),hV.parseInline(i,t)}catch(e){if(e.message+="\nPlease report this to https://github.com/markedjs/marked.",t.silent)return "

    An error occurred:

    "+NI(e.message+"",!0)+"
    ";throw e}},mV.Parser=hV,mV.parser=hV.parse,mV.Renderer=cV,mV.TextRenderer=dV,mV.Lexer=lV,mV.lexer=lV.lex,mV.Tokenizer=nV,mV.Slugger=uV,mV.parse=mV,mV.options,mV.setOptions,mV.use,mV.walkTokens,mV.parseInline,hV.parse,lV.lex;class gV{_parser;_options={gfm:!0,breaks:!0,tables:!0,xhtml:!0,headerIds:!1};constructor(){mV.use({tokenizer:{autolink:()=>null,url:()=>null},renderer:{checkbox(...e){return Object.getPrototypeOf(this).checkbox.call(this,...e).trimRight()},code(...e){return Object.getPrototypeOf(this).code.call(this,...e).replace("\n","")}}}),this._parser=mV;}parse(e){return this._parser.parse(e,this._options)}}function fV(e,t){return Array(t+1).join(e)}var pV=["ADDRESS","ARTICLE","ASIDE","AUDIO","BLOCKQUOTE","BODY","CANVAS","CENTER","DD","DIR","DIV","DL","DT","FIELDSET","FIGCAPTION","FIGURE","FOOTER","FORM","FRAMESET","H1","H2","H3","H4","H5","H6","HEADER","HGROUP","HR","HTML","ISINDEX","LI","MAIN","MENU","NAV","NOFRAMES","NOSCRIPT","OL","OUTPUT","P","PRE","SECTION","TABLE","TBODY","TD","TFOOT","TH","THEAD","TR","UL"];function bV(e){return yV(e,pV)}var wV=["AREA","BASE","BR","COL","COMMAND","EMBED","HR","IMG","INPUT","KEYGEN","LINK","META","PARAM","SOURCE","TRACK","WBR"];function _V(e){return yV(e,wV)}var vV=["A","TABLE","THEAD","TBODY","TFOOT","TH","TD","IFRAME","SCRIPT","AUDIO","VIDEO"];function yV(e,t){return t.indexOf(e.nodeName)>=0}function kV(e,t){return e.getElementsByTagName&&t.some((function(t){return e.getElementsByTagName(t).length}))}var CV={};function xV(e){return e?e.replace(/(\n+\s*)+/g,"\n"):""}function AV(e){for(var t in this.options=e,this._keep=[],this._remove=[],this.blankRule={replacement:e.blankReplacement},this.keepReplacement=e.keepReplacement,this.defaultRule={replacement:e.defaultReplacement},this.array=[],e.rules)this.array.push(e.rules[t]);}function EV(e,t,i){for(var n=0;n-1)return !0}else {if("function"!=typeof n)throw new TypeError("`filter` needs to be a string, array, or function");if(n.call(e,t,i))return !0}}function PV(e){var t=e.nextSibling||e.parentNode;return e.parentNode.removeChild(e),t}function SV(e,t,i){return e&&e.parentNode===t||i(t)?t.nextSibling||t.parentNode:t.firstChild||t.nextSibling||t.parentNode}CV.paragraph={filter:"p",replacement:function(e){return "\n\n"+e+"\n\n"}},CV.lineBreak={filter:"br",replacement:function(e,t,i){return i.br+"\n"}},CV.heading={filter:["h1","h2","h3","h4","h5","h6"],replacement:function(e,t,i){var n=Number(t.nodeName.charAt(1));return "setext"===i.headingStyle&&n<3?"\n\n"+e+"\n"+fV(1===n?"=":"-",e.length)+"\n\n":"\n\n"+fV("#",n)+" "+e+"\n\n"}},CV.blockquote={filter:"blockquote",replacement:function(e){return "\n\n"+(e=(e=e.replace(/^\n+|\n+$/g,"")).replace(/^/gm,"> "))+"\n\n"}},CV.list={filter:["ul","ol"],replacement:function(e,t){var i=t.parentNode;return "LI"===i.nodeName&&i.lastElementChild===t?"\n"+e:"\n\n"+e+"\n\n"}},CV.listItem={filter:"li",replacement:function(e,t,i){e=e.replace(/^\n+/,"").replace(/\n+$/,"\n").replace(/\n/gm,"\n ");var n=i.bulletListMarker+" ",s=t.parentNode;if("OL"===s.nodeName){var o=s.getAttribute("start"),r=Array.prototype.indexOf.call(s.children,t);n=(o?Number(o)+r:r+1)+". ";}return n+e+(t.nextSibling&&!/\n$/.test(e)?"\n":"")}},CV.indentedCodeBlock={filter:function(e,t){return "indented"===t.codeBlockStyle&&"PRE"===e.nodeName&&e.firstChild&&"CODE"===e.firstChild.nodeName},replacement:function(e,t,i){return "\n\n "+t.firstChild.textContent.replace(/\n/g,"\n ")+"\n\n"}},CV.fencedCodeBlock={filter:function(e,t){return "fenced"===t.codeBlockStyle&&"PRE"===e.nodeName&&e.firstChild&&"CODE"===e.firstChild.nodeName},replacement:function(e,t,i){for(var n,s=((t.firstChild.getAttribute("class")||"").match(/language-(\S+)/)||[null,""])[1],o=t.firstChild.textContent,r=i.fence.charAt(0),a=3,l=new RegExp("^"+r+"{3,}","gm");n=l.exec(o);)n[0].length>=a&&(a=n[0].length+1);var c=fV(r,a);return "\n\n"+c+s+"\n"+o.replace(/\n$/,"")+"\n"+c+"\n\n"}},CV.horizontalRule={filter:"hr",replacement:function(e,t,i){return "\n\n"+i.hr+"\n\n"}},CV.inlineLink={filter:function(e,t){return "inlined"===t.linkStyle&&"A"===e.nodeName&&e.getAttribute("href")},replacement:function(e,t){var i=t.getAttribute("href");i&&(i=i.replace(/([()])/g,"\\$1"));var n=xV(t.getAttribute("title"));return n&&(n=' "'+n.replace(/"/g,'\\"')+'"'),"["+e+"]("+i+n+")"}},CV.referenceLink={filter:function(e,t){return "referenced"===t.linkStyle&&"A"===e.nodeName&&e.getAttribute("href")},replacement:function(e,t,i){var n,s,o=t.getAttribute("href"),r=xV(t.getAttribute("title"));switch(r&&(r=' "'+r+'"'),i.linkReferenceStyle){case"collapsed":n="["+e+"][]",s="["+e+"]: "+o+r;break;case"shortcut":n="["+e+"]",s="["+e+"]: "+o+r;break;default:var a=this.references.length+1;n="["+e+"]["+a+"]",s="["+a+"]: "+o+r;}return this.references.push(s),n},references:[],append:function(e){var t="";return this.references.length&&(t="\n\n"+this.references.join("\n")+"\n\n",this.references=[]),t}},CV.emphasis={filter:["em","i"],replacement:function(e,t,i){return e.trim()?i.emDelimiter+e+i.emDelimiter:""}},CV.strong={filter:["strong","b"],replacement:function(e,t,i){return e.trim()?i.strongDelimiter+e+i.strongDelimiter:""}},CV.code={filter:function(e){var t=e.previousSibling||e.nextSibling,i="PRE"===e.parentNode.nodeName&&!t;return "CODE"===e.nodeName&&!i},replacement:function(e){if(!e)return "";e=e.replace(/\r?\n|\r/g," ");for(var t=/^`|^ .*?[^ ].* $|`$/.test(e)?" ":"",i="`",n=e.match(/`+/gm)||[];-1!==n.indexOf(i);)i+="`";return i+t+e+t+i}},CV.image={filter:"img",replacement:function(e,t){var i=xV(t.getAttribute("alt")),n=t.getAttribute("src")||"",s=xV(t.getAttribute("title"));return n?"!["+i+"]("+n+(s?' "'+s+'"':"")+")":""}},AV.prototype={add:function(e,t){this.array.unshift(t);},keep:function(e){this._keep.unshift({filter:e,replacement:this.keepReplacement});},remove:function(e){this._remove.unshift({filter:e,replacement:function(){return ""}});},forNode:function(e){return e.isBlank?this.blankRule:(t=EV(this.array,e,this.options))||(t=EV(this._keep,e,this.options))||(t=EV(this._remove,e,this.options))?t:this.defaultRule;var t;},forEach:function(e){for(var t=0;t'+e+"","text/html").getElementById("turndown-root"):i=e.cloneNode(!0);return function(e){var t=e.element,i=e.isBlock,n=e.isVoid,s=e.isPre||function(e){return "PRE"===e.nodeName};if(t.firstChild&&!s(t)){for(var o=null,r=!1,a=null,l=SV(a,t,s);l!==t;){if(3===l.nodeType||4===l.nodeType){var c=l.data.replace(/[ \r\n\t]+/g," ");if(o&&!/ $/.test(o.data)||r||" "!==c[0]||(c=c.substr(1)),!c){l=PV(l);continue}l.data=c,o=l;}else {if(1!==l.nodeType){l=PV(l);continue}i(l)||"BR"===l.nodeName?(o&&(o.data=o.data.replace(/ $/,"")),o=null,r=!1):n(l)||s(l)?(o=null,r=!0):o&&(r=!1);}var d=SV(a,l,s);a=l,l=d;}o&&(o.data=o.data.replace(/ $/,""),o.data||PV(o));}}({element:i,isBlock:bV,isVoid:_V,isPre:t.preformattedCode?BV:null}),i}function BV(e){return "PRE"===e.nodeName||"CODE"===e.nodeName}function MV(e,t){return e.isBlock=bV(e),e.isCode="CODE"===e.nodeName||e.parentNode.isCode,e.isBlank=function(e){return !_V(e)&&!function(e){return yV(e,vV)}(e)&&/^\s*$/i.test(e.textContent)&&!function(e){return kV(e,wV)}(e)&&!function(e){return kV(e,vV)}(e)}(e),e.flankingWhitespace=function(e,t){if(e.isBlock||t.preformattedCode&&e.isCode)return {leading:"",trailing:""};var i=(n=e.textContent,s=n.match(/^(([ \t\r\n]*)(\s*))(?:(?=\S)[\s\S]*\S)?((\s*?)([ \t\r\n]*))$/),{leading:s[1],leadingAscii:s[2],leadingNonAscii:s[3],trailing:s[4],trailingNonAscii:s[5],trailingAscii:s[6]});var n,s;i.leadingAscii&&LV("left",e,t)&&(i.leading=i.leadingNonAscii);i.trailingAscii&&LV("right",e,t)&&(i.trailing=i.trailingNonAscii);return {leading:i.leading,trailing:i.trailing}}(e,t),e}function LV(e,t,i){var n,s,o;return "left"===e?(n=t.previousSibling,s=/ $/):(n=t.nextSibling,s=/^ /),n&&(3===n.nodeType?o=s.test(n.nodeValue):i.preformattedCode&&"CODE"===n.nodeName?o=!1:1!==n.nodeType||bV(n)||(o=s.test(n.textContent))),o}var FV=Array.prototype.reduce,NV=[[/\\/g,"\\\\"],[/\*/g,"\\*"],[/^-/g,"\\-"],[/^\+ /g,"\\+ "],[/^(=+)/g,"\\$1"],[/^(#{1,6}) /g,"\\$1 "],[/`/g,"\\`"],[/^~~~/g,"\\~~~"],[/\[/g,"\\["],[/\]/g,"\\]"],[/^>/g,"\\>"],[/_/g,"\\_"],[/^(\d+)\. /g,"$1\\. "]];function DV(e){if(!(this instanceof DV))return new DV(e);var t={rules:CV,headingStyle:"setext",hr:"* * *",bulletListMarker:"*",codeBlockStyle:"indented",fence:"```",emDelimiter:"_",strongDelimiter:"**",linkStyle:"inlined",linkReferenceStyle:"full",br:" ",preformattedCode:!1,blankReplacement:function(e,t){return t.isBlock?"\n\n":""},keepReplacement:function(e,t){return t.isBlock?"\n\n"+t.outerHTML+"\n\n":t.outerHTML},defaultReplacement:function(e,t){return t.isBlock?"\n\n"+e+"\n\n":e}};this.options=function(e){for(var t=1;t0&&"\n"===e[t-1];)t--;return e.substring(0,t)}(e),n=t.replace(/^\n*/,""),s=Math.max(e.length-i.length,t.length-n.length);return i+"\n\n".substring(0,s)+n}DV.prototype={turndown:function(e){if(!function(e){return null!=e&&("string"==typeof e||e.nodeType&&(1===e.nodeType||9===e.nodeType||11===e.nodeType))}(e))throw new TypeError(e+" is not a string, or an element/document/fragment node.");if(""===e)return "";var t=zV.call(this,new OV(e,this.options));return HV.call(this,t)},use:function(e){if(Array.isArray(e))for(var t=0;t]*)/.source,"gi");class iR extends DV{escape(e){const t=super.escape;function i(e){return e=(e=t(e)).replace(/s&&(n+=i(e.substring(s,o)));const r=t[0];n+=r,s=o+r.length;}return s0;){const i=e[t-1];if("?!.,:*_~'\"".includes(i))t--;else {if(")"!=i)break;{let i=0;for(let n=0;n"checkbox"===e.type&&("LI"===e.parentNode.nodeName||"LI"===e.parentNode.parentNode.nodeName),replacement:(e,t)=>(t.checked?"[x]":"[ ]")+" "});}}class sR{_htmlDP;_markdown2html;_html2markdown;constructor(e){this._htmlDP=new vd(e),this._markdown2html=new gV,this._html2markdown=new nR;}keepHtml(e){this._html2markdown.keep([e]);}toView(e){const t=this._markdown2html.parse(e);return this._htmlDP.toView(t)}toData(e){const t=this._htmlDP.toData(e);return this._html2markdown.parse(t)}registerRawContentMatcher(e){this._htmlDP.registerRawContentMatcher(e);}useFillerType(){}}class oR extends Dr{constructor(e){super(e),e.data.processor=new sR(e.data.viewDocument);}static get pluginName(){return "Markdown"}static get isOfficialPlugin(){return !0}}const rR=["SPAN","BR","PRE","CODE"];class aR extends Dr{_gfmDataProcessor;constructor(e){super(e),this._gfmDataProcessor=new sR(e.data.viewDocument);}static get pluginName(){return "PasteFromMarkdownExperimental"}static get isOfficialPlugin(){return !0}static get requires(){return [Jv]}init(){const e=this.editor,t=e.editing.view.document,i=e.plugins.get("ClipboardPipeline");let n=!1;this.listenTo(t,"keydown",((e,t)=>{n=t.shiftKey;})),this.listenTo(i,"inputTransformation",((e,t)=>{if(n)return;const i=t.dataTransfer.getData("text/html");if(!i){const e=t.dataTransfer.getData("text/plain");return void(t.content=this._gfmDataProcessor.toView(e))}const s=this._parseMarkdownFromHtml(i);s&&(t.content=this._gfmDataProcessor.toView(s));}));}_parseMarkdownFromHtml(e){const t=this._removeOsSpecificTags(e);if(!this._containsOnlyAllowedFirstLevelTags(t))return null;const i=this._removeFirstLevelWrapperTagsAndBrs(t);return this._containsAnyRemainingHtmlTags(i)?null:this._replaceHtmlReservedEntitiesWithCharacters(i)}_removeOsSpecificTags(e){return e.replace(/^]*>/,"").trim().replace(/^/,"").replace(/<\/html>$/,"").trim().replace(/^/,"").replace(/<\/body>$/,"").trim().replace(/^/,"").replace(/$/,"").trim()}_containsOnlyAllowedFirstLevelTags(e){const t=new DOMParser,{body:i}=t.parseFromString(e,"text/html");return Array.from(i.children).map((e=>e.tagName)).every((e=>rR.includes(e)))}_removeFirstLevelWrapperTagsAndBrs(e){const t=new DOMParser,{body:i}=t.parseFromString(e,"text/html"),n=i.querySelectorAll("br");for(const e of n)e.replaceWith("\n");const s=i.querySelectorAll(":scope > *");for(const e of s){const t=e.cloneNode(!0);e.replaceWith(...t.childNodes);}return i.innerHTML}_containsAnyRemainingHtmlTags(e){return e.includes("<")}_replaceHtmlReservedEntitiesWithCharacters(e){return e.replace(/>/g,">").replace(/</g,"<").replace(/ /g," ")}}function lR(e,t){const i=(i,n,s)=>{if(!s.consumable.consume(n.item,i.name))return;const o=n.attributeNewValue,r=s.writer,a=s.mapper.toViewElement(n.item),l=[...a.getChildren()].find((e=>e.getCustomProperty("media-content")));r.remove(l);const c=e.getMediaViewElement(r,o,t);r.insert(r.createPositionAt(a,0),c);};return e=>{e.on("attribute:url:media",i);}}function cR(e){const t=e.getSelectedElement();return t&&function(e){return !!e.getCustomProperty("media")&&sy(e)}(t)?t:null}function dR(e,t,i,n){return e.createContainerElement("figure",{class:"media"},[t.getMediaViewElement(e,i,n),e.createSlot()])}function uR(e){const t=e.getSelectedElement();return t&&t.is("element","media")?t:null}function hR(e,t,i,n){e.change((s=>{const o=s.createElement("media",{url:t});e.insertObject(o,i,null,{setSelection:"on",findOptimalPosition:n?"auto":void 0});}));}class mR extends Hr{refresh(){const e=this.editor.model,t=e.document.selection,i=uR(t);this.value=i?i.getAttribute("url"):void 0,this.isEnabled=function(e){const t=e.getSelectedElement();return !!t&&"media"===t.name}(t)||function(e,t){const i=hy(e,t);let n=i.start.parent;n.isEmpty&&!t.schema.isLimit(n)&&(n=n.parent);return t.schema.checkChild(n,"media")}(t,e);}execute(e){const t=this.editor.model,i=t.document.selection,n=uR(i);n?t.change((t=>{t.setAttribute("url",e,n);})):hR(t,e,i,!0);}}class gR{locale;providerDefinitions;constructor(e,t){const i=t.providers,n=t.extraProviders||[],s=new Set(t.removeProviders),o=i.concat(n).filter((e=>{const t=e.name;return t?!s.has(t):(E("media-embed-no-provider-name",{provider:e}),!1)}));this.locale=e,this.providerDefinitions=o;}hasMedia(e){return !!this._getMedia(e)}getMediaViewElement(e,t,i){return this._getMedia(t).getViewElement(e,i)}_getMedia(e){if(!e)return new fR(this.locale);e=e.trim();for(const t of this.providerDefinitions){const i=t.html,n=gr(t.url);for(const t of n){const n=this._getUrlMatches(e,t);if(n)return new fR(this.locale,e,n,i)}}return null}_getUrlMatches(e,t){let i=e.match(t);if(i)return i;let n=e.replace(/^https?:\/\//,"");return i=n.match(t),i||(n=n.replace(/^www\./,""),i=n.match(t),i||null)}}class fR{url;_locale;_match;_previewRenderer;constructor(e,t,i,n){this.url=this._getValidUrl(t),this._locale=e,this._match=i,this._previewRenderer=n;}getViewElement(e,t){const i={};let n;if(t.renderForEditingView||t.renderMediaPreview&&this.url&&this._previewRenderer){this.url&&(i["data-oembed-url"]=this.url),t.renderForEditingView&&(i.class="ck-media__wrapper");const s=this._getPreviewHtml(t);n=e.createRawElement("div",i,((e,t)=>{t.setContentOf(e,s);}));}else this.url&&(i.url=this.url),n=e.createEmptyElement(t.elementName,i);return e.setCustomProperty("media-content",!0,n),n}_getPreviewHtml(e){return this._previewRenderer?this._previewRenderer(this._match):this.url&&e.renderForEditingView?this._getPlaceholderHtml():""}_getPlaceholderHtml(){const e=new gg,t=this._locale.t;e.content='',e.viewBox="0 0 64 42";return new Hm({tag:"div",attributes:{class:"ck ck-reset_all ck-media__placeholder"},children:[{tag:"div",attributes:{class:"ck-media__placeholder__icon"},children:[e]},{tag:"a",attributes:{class:"ck-media__placeholder__url",target:"_blank",rel:"noopener noreferrer",href:this.url,"data-cke-tooltip-text":t("Open media in new tab")},children:[{tag:"span",attributes:{class:"ck-media__placeholder__url__text"},children:[this.url]}]}]}).render().outerHTML}_getValidUrl(e){return e?e.match(/^https?/)?e:"https://"+e:null}}class pR extends Dr{static get pluginName(){return "MediaEmbedEditing"}static get isOfficialPlugin(){return !0}registry;constructor(e){super(e),e.config.define("mediaEmbed",{elementName:"oembed",providers:[{name:"dailymotion",url:[/^dailymotion\.com\/video\/(\w+)/,/^dai.ly\/(\w+)/],html:e=>`
    `},{name:"spotify",url:[/^open\.spotify\.com\/(artist\/\w+)/,/^open\.spotify\.com\/(album\/\w+)/,/^open\.spotify\.com\/(track\/\w+)/],html:e=>`
    `},{name:"youtube",url:[/^(?:m\.)?youtube\.com\/watch\?v=([\w-]+)(?:&t=(\d+))?/,/^(?:m\.)?youtube\.com\/shorts\/([\w-]+)(?:\?t=(\d+))?/,/^(?:m\.)?youtube\.com\/v\/([\w-]+)(?:\?t=(\d+))?/,/^youtube\.com\/embed\/([\w-]+)(?:\?start=(\d+))?/,/^youtu\.be\/([\w-]+)(?:\?t=(\d+))?/],html:e=>{const t=e[1],i=e[2];return `
    `}},{name:"vimeo",url:[/^vimeo\.com\/(\d+)/,/^vimeo\.com\/[^/]+\/[^/]+\/video\/(\d+)/,/^vimeo\.com\/album\/[^/]+\/video\/(\d+)/,/^vimeo\.com\/channels\/[^/]+\/(\d+)/,/^vimeo\.com\/groups\/[^/]+\/videos\/(\d+)/,/^vimeo\.com\/ondemand\/[^/]+\/(\d+)/,/^player\.vimeo\.com\/video\/(\d+)/],html:e=>`
    `},{name:"instagram",url:[/^instagram\.com\/p\/(\w+)/,/^instagram\.com\/reel\/(\w+)/]},{name:"twitter",url:[/^twitter\.com/,/^x\.com/]},{name:"googleMaps",url:[/^google\.com\/maps/,/^goo\.gl\/maps/,/^maps\.google\.com/,/^maps\.app\.goo\.gl/]},{name:"flickr",url:/^flickr\.com/},{name:"facebook",url:/^facebook\.com/}]}),this.registry=new gR(e.locale,e.config.get("mediaEmbed"));}init(){const e=this.editor,t=e.model.schema,i=e.t,n=e.conversion,s=e.config.get("mediaEmbed.previewsInData"),o=e.config.get("mediaEmbed.elementName"),r=this.registry;e.commands.add("mediaEmbed",new mR(e)),t.register("media",{inheritAllFrom:"$blockObject",allowAttributes:["url"]}),n.for("dataDowncast").elementToStructure({model:"media",view:(e,{writer:t})=>{const i=e.getAttribute("url");return dR(t,r,i,{elementName:o,renderMediaPreview:!!i&&s})}}),n.for("dataDowncast").add(lR(r,{elementName:o,renderMediaPreview:s})),n.for("editingDowncast").elementToStructure({model:"media",view:(e,{writer:t})=>{const n=e.getAttribute("url");return function(e,t,i){return t.setCustomProperty("media",!0,e),oy(e,t,{label:i})}(dR(t,r,n,{elementName:o,renderForEditingView:!0}),t,i("media widget"))}}),n.for("editingDowncast").add(lR(r,{elementName:o,renderForEditingView:!0})),n.for("upcast").elementToElement({view:e=>["oembed",o].includes(e.name)&&e.getAttribute("url")?{name:!0}:null,model:(e,{writer:t})=>{const i=e.getAttribute("url");return r.hasMedia(i)?t.createElement("media",{url:i}):null}}).elementToElement({view:{name:"div",attributes:{"data-oembed-url":!0}},model:(e,{writer:t})=>{const i=e.getAttribute("data-oembed-url");return r.hasMedia(i)?t.createElement("media",{url:i}):null}}).add((e=>{e.on("element:figure",((e,t,i)=>{if(!i.consumable.consume(t.viewItem,{name:!0,classes:"media"}))return;const{modelRange:n,modelCursor:s}=i.convertChildren(t.viewItem,t.modelCursor);t.modelRange=n,t.modelCursor=s;wr(n.getItems())||i.consumable.revert(t.viewItem,{name:!0,classes:"media"});}));}));}}const bR=/^(?:http(s)?:\/\/)?[\w-]+\.[\w-.~:/?#[\]@!$&'()*+,;=%]+$/;class wR extends Dr{static get requires(){return [Qy,Rw,lC]}static get pluginName(){return "AutoMediaEmbed"}static get isOfficialPlugin(){return !0}_timeoutId;_positionToInsert;constructor(e){super(e),this._timeoutId=null,this._positionToInsert=null;}init(){const e=this.editor,t=e.model.document,n=e.plugins.get("ClipboardPipeline");this.listenTo(n,"inputTransformation",(()=>{const e=t.selection.getFirstRange(),i=su.fromPosition(e.start);i.stickiness="toPrevious";const n=su.fromPosition(e.end);n.stickiness="toNext",t.once("change:data",(()=>{this._embedMediaBetweenPositions(i,n),i.detach(),n.detach();}),{priority:"high"});}));e.commands.get("undo").on("execute",(()=>{this._timeoutId&&(i.window.clearTimeout(this._timeoutId),this._positionToInsert.detach(),this._timeoutId=null,this._positionToInsert=null);}),{priority:"high"});}_embedMediaBetweenPositions(e,t){const n=this.editor,s=n.plugins.get(pR).registry,o=new fc(e,t),r=o.getWalker({ignoreElementEnd:!0});let a="";for(const e of r)e.item.is("$textProxy")&&(a+=e.item.data);if(a=a.trim(),!a.match(bR))return void o.detach();if(!s.hasMedia(a))return void o.detach();n.commands.get("mediaEmbed").isEnabled?(this._positionToInsert=su.fromPosition(e),this._timeoutId=i.window.setTimeout((()=>{n.model.change((e=>{this._timeoutId=null,e.remove(o),o.detach();let t=null;"$graveyard"!==this._positionToInsert.root.rootName&&(t=this._positionToInsert),hR(n.model,a,t,!1),this._positionToInsert.detach(),this._positionToInsert=null;})),n.plugins.get(Rw).requestUndoOnBackspace();}),100)):o.detach();}}class _R extends lg{focusTracker;keystrokes;urlInputView;_validators;_urlInputViewInfoDefault;_urlInputViewInfoTip;constructor(e,t){super(t),this.focusTracker=new _r,this.keystrokes=new Cr,this.set("mediaURLInputValue",""),this.urlInputView=this._createUrlInput(),this._validators=e,this.setTemplate({tag:"form",attributes:{class:["ck","ck-media-form","ck-responsive-form"],tabindex:"-1"},children:[this.urlInputView]});}render(){super.render(),hg({view:this}),this.focusTracker.add(this.urlInputView.element),this.keystrokes.listenTo(this.element);}destroy(){super.destroy(),this.focusTracker.destroy(),this.keystrokes.destroy();}focus(){this.urlInputView.focus();}get url(){return this.urlInputView.fieldView.element.value.trim()}set url(e){this.urlInputView.fieldView.value=e.trim();}isValid(){this.resetFormStatus();for(const e of this._validators){const t=e(this);if(t)return this.urlInputView.errorText=t,!1}return !0}resetFormStatus(){this.urlInputView.errorText=null,this.urlInputView.infoText=this._urlInputViewInfoDefault;}_createUrlInput(){const e=this.locale.t,t=new pf(this.locale,cp),i=t.fieldView;return this._urlInputViewInfoDefault=e("Paste the media URL in the input."),this._urlInputViewInfoTip=e("Tip: Paste the URL into the content to embed faster."),t.label=e("Media URL"),t.infoText=this._urlInputViewInfoDefault,i.inputMode="url",i.on("input",(()=>{t.infoText=i.element.value?this._urlInputViewInfoTip:this._urlInputViewInfoDefault,this.mediaURLInputValue=i.element.value.trim();})),t}}class vR extends Dr{static get requires(){return [pR,Sg]}static get pluginName(){return "MediaEmbedUI"}static get isOfficialPlugin(){return !0}_formView;init(){const e=this.editor;e.ui.componentFactory.add("mediaEmbed",(()=>{const e=this.editor.locale.t,t=this._createDialogButton(pg);return t.tooltip=!0,t.label=e("Insert media"),t})),e.ui.componentFactory.add("menuBar:mediaEmbed",(()=>{const e=this.editor.locale.t,t=this._createDialogButton(Rg);return t.label=e("Media"),t}));}_createDialogButton(e){const t=this.editor,i=new e(t.locale),n=t.commands.get("mediaEmbed"),s=this.editor.plugins.get("Dialog");return i.icon='',i.bind("isEnabled").to(n,"isEnabled"),i.on("execute",(()=>{"mediaEmbed"===s.id?s.hide():this._showDialog();})),i}_showDialog(){const e=this.editor,t=e.plugins.get("Dialog"),i=e.commands.get("mediaEmbed"),n=e.locale.t;if(!this._formView){const t=e.plugins.get(pR).registry;this._formView=new(ug(_R))(function(e,t){return [t=>{if(!t.url.length)return e("The URL must not be empty.")},i=>{if(!t.hasMedia(i.url))return e("This media URL is not supported.")}]}(e.t,t),e.locale),this._formView.on("submit",(()=>this._handleSubmitForm()));}t.show({id:"mediaEmbed",title:n("Insert media"),content:this._formView,isModal:!0,onShow:()=>{this._formView.url=i.value||"",this._formView.resetFormStatus(),this._formView.urlInputView.fieldView.select();},actionButtons:[{label:n("Cancel"),withText:!0,onExecute:()=>t.hide()},{label:n("Accept"),class:"ck-button-action",withText:!0,onExecute:()=>this._handleSubmitForm()}]});}_handleSubmitForm(){const e=this.editor,t=e.plugins.get("Dialog");this._formView.isValid()&&(e.execute("mediaEmbed",this._formView.url),t.hide(),e.editing.view.focus());}}class yR extends Dr{static get requires(){return [pR,vR,wR,Ty]}static get pluginName(){return "MediaEmbed"}static get isOfficialPlugin(){return !0}}class kR extends Dr{static get requires(){return [Sy]}static get pluginName(){return "MediaEmbedToolbar"}static get isOfficialPlugin(){return !0}afterInit(){const e=this.editor,t=e.t;e.plugins.get(Sy).register("mediaEmbed",{ariaLabel:t("Media toolbar"),items:e.config.get("mediaEmbed.toolbar")||[],getRelatedElement:cR});}}const CR={"(":")","[":"]","{":"}"};class xR extends Hr{constructor(e){super(e),this._isEnabledBasedOnSelection=!1;}refresh(){const e=this.editor.model,t=e.document;this.isEnabled=e.schema.checkAttributeInSelection(t.selection,"mention");}execute(e){const t=this.editor.model,i=t.document.selection,n="string"==typeof e.mention?{id:e.mention}:e.mention,s=n.id,o=e.range||i.getFirstRange();if(!t.canEditAt(o))return;const r=e.text||s,a=ER({_text:r,id:s},n);if(1!=e.marker.length)throw new A("mentioncommand-incorrect-marker",this);if(s.charAt(0)!=e.marker)throw new A("mentioncommand-incorrect-id",this);t.change((e=>{const n=xr(i.getAttributes()),s=new Map(n.entries());s.set("mention",a);const l=t.insertContent(e.createText(r,s),o),c=l.start.nodeBefore,d=l.end.nodeAfter,u=d&&d.is("$text")&&d.data.startsWith(" ");let h=!1;if(c&&d&&c.is("$text")&&d.is("$text")){const e=c.data.slice(-1),t=e in CR,i=t&&d.data.startsWith(CR[e]);h=t&&i;}h||u||t.insertContent(e.createText(" ",n),o.start.getShiftedBy(r.length));}));}}class AR extends Dr{static get pluginName(){return "MentionEditing"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.model,i=t.document;t.schema.extend("$text",{allowAttributes:"mention"}),e.conversion.for("upcast").elementToAttribute({view:{name:"span",key:"data-mention",classes:"mention"},model:{key:"mention",value:e=>TR(e)}}),e.conversion.for("downcast").attributeToElement({model:"mention",view:SR}),e.conversion.for("downcast").add(PR),i.registerPostFixer((e=>function(e,t,i){const n=t.differ.getChanges();let s=!1;for(const t of n){if("attribute"==t.type)continue;const n=t.position;if("$text"==t.name){const t=n.textNode&&n.textNode.nextSibling;s=VR(n.textNode,e)||s,s=VR(t,e)||s,s=VR(n.nodeBefore,e)||s,s=VR(n.nodeAfter,e)||s;}if("$text"!=t.name&&"insert"==t.type){const t=n.nodeAfter;for(const i of e.createRangeIn(t).getItems())s=VR(i,e)||s;}if("insert"==t.type&&i.isInline(t.name)){const t=n.nodeAfter&&n.nodeAfter.nextSibling;s=VR(n.nodeBefore,e)||s,s=VR(t,e)||s;}}return s}(e,i,t.schema))),i.registerPostFixer((e=>function(e,t){const i=t.differ.getChanges();let n=!1;for(const t of i)if("attribute"===t.type&&"mention"!=t.attributeKey){const i=t.range.start.nodeBefore,s=t.range.end.nodeAfter;for(const o of [i,s])IR(o)&&o.getAttribute(t.attributeKey)!=t.attributeNewValue&&(e.setAttribute(t.attributeKey,t.attributeNewValue,o),n=!0);}return n}(e,i))),i.registerPostFixer((e=>function(e,t){const i=t.selection,n=i.focus;if(i.isCollapsed&&i.hasAttribute("mention")&&function(e){const t=e.isAtStart;return e.nodeBefore&&e.nodeBefore.is("$text")||t}(n))return e.removeSelectionAttribute("mention"),!0;return !1}(e,i))),e.commands.add("mention",new xR(e));}}function ER(e,t){return Object.assign({uid:k()},e,t||{})}function TR(e,t){const i=e.getAttribute("data-mention"),n=e.getChild(0);if(!n)return;return ER({id:i,_text:n.data},t)}function PR(e){e.on("attribute:mention",((e,t,i)=>{const n=t.attributeNewValue;if(!t.item.is("$textProxy")||!n)return;const s=t.range.start;(s.textNode||s.nodeAfter).data!=n._text&&i.consumable.consume(t.item,e.name);}),{priority:"highest"});}function SR(e,{writer:t}){if(!e)return;const i={class:"mention","data-mention":e.id},n={id:e.uid,priority:20};return t.createAttributeElement("span",i,n)}function IR(e){if(!e||!e.is("$text")&&!e.is("$textProxy")||!e.hasAttribute("mention"))return !1;return e.data!=e.getAttribute("mention")._text}function VR(e,t){return !!IR(e)&&(t.removeAttribute("mention",e),!0)}class RR extends Vf{selected;position;constructor(e){super(e),this.extendTemplate({attributes:{class:["ck-mentions"],tabindex:"-1"}});}selectFirst(){this.select(0);}selectNext(){const e=this.selected,t=this.items.getIndex(e);this.select(t+1);}selectPrevious(){const e=this.selected,t=this.items.getIndex(e);this.select(t-1);}select(e){let t=0;e>0&&e{i?(this.domElement.classList.add("ck-on"),this.domElement.classList.remove("ck-off")):(this.domElement.classList.add("ck-off"),this.domElement.classList.remove("ck-on"));})),this.listenTo(this.domElement,"click",(()=>{this.fire("execute");}));}render(){super.render(),this.element=this.domElement;}focus(){this.domElement.focus();}}class BR extends Pf{item;marker;highlight(){this.children.first.isOn=!0;}removeHighlight(){this.children.first.isOn=!1;}}const MR=[nr.arrowup,nr.arrowdown,nr.esc],LR=[nr.enter,nr.tab];class FR extends Dr{_mentionsView;_mentionsConfigurations;_balloon;_items=new br;_lastRequested;_requestFeedDebounced;static get pluginName(){return "MentionUI"}static get isOfficialPlugin(){return !0}static get requires(){return [Db]}constructor(e){super(e),this._mentionsView=this._createMentionView(),this._mentionsConfigurations=new Map,this._requestFeedDebounced=vs(this._requestFeed,100),e.config.define("mention",{feeds:[]});}init(){const e=this.editor,t=e.config.get("mention.commitKeys")||LR,i=MR.concat(t);this._balloon=e.plugins.get(Db),e.editing.view.document.on("keydown",((e,n)=>{var s;s=n.keyCode,i.includes(s)&&this._isUIVisible&&(n.preventDefault(),e.stop(),n.keyCode==nr.arrowdown&&this._mentionsView.selectNext(),n.keyCode==nr.arrowup&&this._mentionsView.selectPrevious(),t.includes(n.keyCode)&&this._mentionsView.executeSelected(),n.keyCode==nr.esc&&this._hideUIAndRemoveMarker());}),{priority:"highest"}),cg({emitter:this._mentionsView,activator:()=>this._isUIVisible,contextElements:()=>[this._balloon.view.element],callback:()=>this._hideUIAndRemoveMarker()});const n=e.config.get("mention.feeds");for(const e of n){const{feed:t,marker:i,dropdownLimit:n}=e;if(!$R(i))throw new A("mentionconfig-incorrect-marker",null,{marker:i});const s={marker:i,feedCallback:"function"==typeof t?t.bind(this.editor):HR(t),itemRenderer:e.itemRenderer,dropdownLimit:n};this._mentionsConfigurations.set(i,s);}this._setupTextWatcher(n),this.listenTo(e,"change:isReadOnly",(()=>{this._hideUIAndRemoveMarker();})),this.on("requestFeed:response",((e,t)=>this._handleFeedResponse(t))),this.on("requestFeed:error",(()=>this._hideUIAndRemoveMarker()));}destroy(){super.destroy(),this._mentionsView.destroy();}get _isUIVisible(){return this._balloon.visibleView===this._mentionsView}_createMentionView(){const e=this.editor.locale,t=new RR(e);return t.items.bindTo(this._items).using((i=>{const{item:n,marker:s}=i,{dropdownLimit:o}=this._mentionsConfigurations.get(s),r=o||this.editor.config.get("mention.dropdownLimit")||10;if(t.items.length>=r)return null;const a=new BR(e),l=this._renderItem(n,s);return l.delegate("execute").to(a),a.children.add(l),a.item=n,a.marker=s,a.on("execute",(()=>{t.fire("execute",{item:n,marker:s});})),a})),t.on("execute",((e,t)=>{const i=this.editor,n=i.model,s=t.item,o=t.marker,r=i.model.markers.get("mention"),a=n.createPositionAt(n.document.selection.focus),l=n.createPositionAt(r.getStart()),c=n.createRange(l,a);this._hideUIAndRemoveMarker(),i.execute("mention",{mention:s,text:s.text,marker:o,range:c}),i.editing.view.focus();})),t}_getItemRenderer(e){const{itemRenderer:t}=this._mentionsConfigurations.get(e);return t}_requestFeed(e,t){this._lastRequested=t;const{feedCallback:i}=this._mentionsConfigurations.get(e),n=i(t);n instanceof Promise?n.then((i=>{this._lastRequested==t?this.fire("requestFeed:response",{feed:i,marker:e,feedText:t}):this.fire("requestFeed:discarded",{feed:i,marker:e,feedText:t});})).catch((t=>{this.fire("requestFeed:error",{error:t}),E("mention-feed-callback-error",{marker:e});})):this.fire("requestFeed:response",{feed:n,marker:e,feedText:t});}_setupTextWatcher(e){const t=this.editor,i=e.map((e=>({...e,pattern:zR(e.marker,e.minimumCharacters||0)}))),n=new Mw(t.model,function(e){const t=t=>{const i=DR(e,t);if(!i)return !1;let n=0;0!==i.position&&(n=i.position-1);const s=t.substring(n);return i.pattern.test(s)};return t}(i));n.on("matched",((e,n)=>{const s=DR(i,n.text),o=t.model.document.selection.focus,r=t.model.createPositionAt(o.parent,s.position);if(function(e){const t=e.textNode&&e.textNode.hasAttribute("mention"),i=e.nodeBefore;return t||i&&i.is("$text")&&i.hasAttribute("mention")}(o)||function(e){const t=e.nodeAfter;return t&&t.is("$text")&&t.hasAttribute("mention")}(r))return void this._hideUIAndRemoveMarker();const a=function(e,t){let i=0;0!==e.position&&(i=e.position-1);const n=zR(e.marker,0),s=t.substring(i);return s.match(n)[2]}(s,n.text),l=s.marker.length+a.length,c=o.getShiftedBy(-l),d=o.getShiftedBy(-a.length),u=t.model.createRange(c,d);if(UR(t)){const e=t.model.markers.get("mention");t.model.change((t=>{t.updateMarker(e,{range:u});}));}else t.model.change((e=>{e.addMarker("mention",{range:u,usingOperation:!1,affectsData:!1});}));this._requestFeedDebounced(s.marker,a);})),n.on("unmatched",(()=>{this._hideUIAndRemoveMarker();}));const s=t.commands.get("mention");return n.bind("isEnabled").to(s),n}_handleFeedResponse(e){const{feed:t,marker:i}=e;if(!UR(this.editor))return;this._items.clear();for(const e of t){const t="object"!=typeof e?{id:e,text:e}:e;this._items.add({item:t,marker:i});}const n=this.editor.model.markers.get("mention");this._items.length?this._showOrUpdateUI(n):this._hideUIAndRemoveMarker();}_showOrUpdateUI(e){this._isUIVisible?this._balloon.updatePosition(this._getBalloonPanelPositionData(e,this._mentionsView.position)):this._balloon.add({view:this._mentionsView,position:this._getBalloonPanelPositionData(e,this._mentionsView.position),singleViewMode:!0}),this._mentionsView.position=this._balloon.view.position,this._mentionsView.selectFirst();}_hideUIAndRemoveMarker(){this._balloon.hasView(this._mentionsView)&&this._balloon.remove(this._mentionsView),UR(this.editor)&&this.editor.model.change((e=>e.removeMarker("mention"))),this._mentionsView.position=void 0;}_renderItem(e,t){const i=this.editor;let n,s=e.id;const o=this._getItemRenderer(t);if(o){const t=o(e);"string"!=typeof t?n=new OR(i.locale,t):s=t;}if(!n){const e=new pg(i.locale);e.label=s,e.withText=!0,n=e;}return n}_getBalloonPanelPositionData(e,t){const i=this.editor,n=i.editing,s=n.view.domConverter,o=n.mapper;return {target:()=>{let t=e.getRange();"$graveyard"==t.start.root.rootName&&(t=i.model.document.selection.getFirstRange());const n=o.toViewRange(t);return Eo.getDomRangeRects(s.viewRangeToDom(n)).pop()},limiter:()=>{const e=this.editor.editing.view,t=e.document.selection.editableElement;return t?e.domConverter.mapViewToDom(t.root):null},positions:NR(t,i.locale.uiLanguageDirection)}}}function NR(e,t){const i={caret_se:e=>({top:e.bottom+3,left:e.right,name:"caret_se",config:{withArrow:!1}}),caret_ne:(e,t)=>({top:e.top-t.height-3,left:e.right,name:"caret_ne",config:{withArrow:!1}}),caret_sw:(e,t)=>({top:e.bottom+3,left:e.right-t.width,name:"caret_sw",config:{withArrow:!1}}),caret_nw:(e,t)=>({top:e.top-t.height-3,left:e.right-t.width,name:"caret_nw",config:{withArrow:!1}})};return Object.prototype.hasOwnProperty.call(i,e)?[i[e]]:"rtl"!==t?[i.caret_se,i.caret_sw,i.caret_ne,i.caret_nw]:[i.caret_sw,i.caret_se,i.caret_nw,i.caret_ne]}function DR(e,t){let i;for(const n of e){const e=t.lastIndexOf(n.marker);e>0&&!t.substring(e-1).match(n.pattern)||(!i||e>=i.position)&&(i={marker:n.marker,position:e,minimumCharacters:n.minimumCharacters,pattern:n.pattern});}return i}function zR(e,t){const i=0==t?"*":`{${t},}`,n=o.features.isRegExpUnicodePropertySupported?"\\p{Ps}\\p{Pi}\"'":"\\(\\[{\"'";e=e.replace(/[.*+?^${}()\-|[\]\\]/g,"\\$&");return new RegExp(`(?:^|[ ${n}])([${e}])(.${i})$`,"u")}function HR(e){return t=>e.filter((e=>("string"==typeof e?e:String(e.id)).toLowerCase().includes(t.toLowerCase())))}function $R(e){return e&&1==e.length}function UR(e){return e.model.markers.has("mention")}class WR extends Dr{toMentionAttribute(e,t){return TR(e,t)}static get pluginName(){return "Mention"}static get isOfficialPlugin(){return !0}static get requires(){return [AR,FR]}}const jR=Oo("px");class qR extends Bb{_options;constructor(e,t){super(e);const i=this.bindTemplate;this.set("top",0),this.set("height",0),this._options=t,this.extendTemplate({attributes:{tabindex:-1,"aria-hidden":"true",class:["ck-minimap__iframe"],style:{top:i.to("top",(e=>jR(e))),height:i.to("height",(e=>jR(e)))}}});}render(){return super.render().then((()=>{this._prepareDocument();}))}setHeight(e){this.height=e;}setTopOffset(e){this.top=e;}_prepareDocument(){const e=this.element.contentWindow.document,t=e.adoptNode(this._options.domRootClone),i=this._options.useSimplePreview?"\n\t\t\t.ck.ck-editor__editable_inline img {\n\t\t\t\tfilter: contrast( 0 );\n\t\t\t}\n\n\t\t\tp, li, a, figcaption, span {\n\t\t\t\tbackground: hsl(0, 0%, 80%) !important;\n\t\t\t\tcolor: hsl(0, 0%, 80%) !important;\n\t\t\t}\n\n\t\t\th1, h2, h3, h4 {\n\t\t\t\tbackground: hsl(0, 0%, 60%) !important;\n\t\t\t\tcolor: hsl(0, 0%, 60%) !important;\n\t\t\t}\n\t\t":"",n=`\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t${this._options.pageStyles.map((e=>"string"==typeof e?``:``)).join("\n")}\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t`;e.open(),e.write(n),e.close(),e.body.appendChild(t);}}const GR=Oo("px");class KR extends lg{constructor(e){super(e);const t=this.bindTemplate;this.set("height",0),this.set("top",0),this.set("scrollProgress",0),this.set("_isDragging",!1),this.setTemplate({tag:"div",attributes:{class:["ck","ck-minimap__position-tracker",t.if("_isDragging","ck-minimap__position-tracker_dragging")],style:{top:t.to("top",(e=>GR(e))),height:t.to("height",(e=>GR(e)))},"data-progress":t.to("scrollProgress")},on:{mousedown:t.to((()=>{this._isDragging=!0;}))}});}render(){super.render(),this.listenTo(i.document,"mousemove",((e,t)=>{this._isDragging&&this.fire("drag",t.movementY);}),{useCapture:!0}),this.listenTo(i.document,"mouseup",(()=>{this._isDragging=!1;}),{useCapture:!0});}setHeight(e){this.height=e;}setTopOffset(e){this.top=e;}setScrollProgress(e){this.scrollProgress=e;}}class ZR extends lg{_positionTrackerView;_scaleRatio;_minimapIframeView;constructor({locale:e,scaleRatio:t,pageStyles:i,extraClasses:n,useSimplePreview:s,domRootClone:o}){super(e);const r=this.bindTemplate;this._positionTrackerView=new KR(e),this._positionTrackerView.delegate("drag").to(this),this._scaleRatio=t,this._minimapIframeView=new qR(e,{useSimplePreview:s,pageStyles:i,extraClasses:n,scaleRatio:t,domRootClone:o}),this.setTemplate({tag:"div",attributes:{class:["ck","ck-minimap"]},children:[this._positionTrackerView],on:{click:r.to(this._handleMinimapClick.bind(this)),wheel:r.to(this._handleMinimapMouseWheel.bind(this))}});}destroy(){this._minimapIframeView.destroy(),super.destroy();}get height(){return new Eo(this.element).height}get scrollHeight(){return Math.max(0,Math.min(this.height,this._minimapIframeView.height)-this._positionTrackerView.height)}render(){super.render(),this._minimapIframeView.render(),this.element.appendChild(this._minimapIframeView.element);}setContentHeight(e){this._minimapIframeView.setHeight(e*this._scaleRatio);}setScrollProgress(e){const t=this._minimapIframeView,i=this._positionTrackerView;if(t.heighto.markToSync("children",t))),n.on("change:attributes",((e,t)=>o.markToSync("attributes",t))),n.on("change:text",((e,t)=>o.markToSync("text",t))),o.render(),e.editing.view.on("render",(()=>o.render())),e.on("destroy",(()=>{s.unbindDomElement(r);})),r}function QR(e){return new Eo(e===i.document.body?i.window:e)}function YR(e){return e===i.document.body?i.window:e}class XR extends Dr{static get pluginName(){return "Minimap"}static get isOfficialPlugin(){return !0}_minimapView;_scrollableRootAncestor;_editingRootElement;init(){const e=this.editor;this._minimapView=null,this._scrollableRootAncestor=null,this.listenTo(e.ui,"ready",this._onUiReady.bind(this));}destroy(){super.destroy(),this._minimapView.destroy(),this._minimapView.element.remove();}_onUiReady(){const e=this.editor,t=this._editingRootElement=e.ui.getEditableElement();this._scrollableRootAncestor=bo(t),t.ownerDocument.body.contains(t)?(this._initializeMinimapView(),this.listenTo(e.editing.view,"render",(()=>{"ready"===e.state&&this._syncMinimapToEditingRootScrollPosition();})),this._syncMinimapToEditingRootScrollPosition()):e.ui.once("update",this._onUiReady.bind(this));}_initializeMinimapView(){const e=this.editor,t=e.locale,n=e.config.get("minimap.useSimplePreview"),s=e.config.get("minimap.container"),o=this._scrollableRootAncestor,r=QR(this._editingRootElement).width,a=QR(s).width/r,l=this._minimapView=new ZR({locale:t,scaleRatio:a,pageStyles:Array.from(i.document.styleSheets).map((e=>e.href&&!e.href.startsWith(i.window.location.origin)?{href:e.href}:Array.from(e.cssRules).filter((e=>!(e instanceof CSSMediaRule))).map((e=>e.cssText)).join(" \n"))),extraClasses:e.config.get("minimap.extraClasses"),useSimplePreview:n,domRootClone:JR(e)});l.render(),l.listenTo(i.document,"scroll",((e,t)=>{if(o===i.document.body){if(t.target!==i.document)return}else if(t.target!==o)return;this._syncMinimapToEditingRootScrollPosition();}),{useCapture:!0,usePassive:!0}),l.listenTo(i.window,"resize",(()=>{this._syncMinimapToEditingRootScrollPosition();})),l.on("drag",((e,t)=>{let n;n=0===l.scrollHeight?0:t/l.scrollHeight;const s=n*(o.scrollHeight-((r=o)===i.document.body?i.window.innerHeight:r.clientHeight));var r;YR(o).scrollBy(0,Math.round(s));})),l.on("click",((e,t)=>{const i=t*o.scrollHeight;YR(o).scrollBy(0,Math.round(i));})),s.appendChild(l.element);}_syncMinimapToEditingRootScrollPosition(){const e=this._editingRootElement,t=this._minimapView;t.setContentHeight(e.offsetHeight);const i=QR(e),n=QR(this._scrollableRootAncestor);let s;n.contains(i)||i.top>n.top?s=0:(s=(i.top-n.top)/(n.height-i.height),s=Math.max(0,Math.min(s,1))),t.setPositionTrackerHeight(n.getIntersection(i).height),t.setScrollProgress(s);}}class eO extends Hr{refresh(){const e=this.editor.model,t=e.schema,i=e.document.selection;this.isEnabled=function(e,t,i){const n=function(e,t){const i=hy(e,t),n=i.start.parent;if(n.isEmpty&&!n.is("element","$root"))return n.parent;return n}(e,i);return t.checkChild(n,"pageBreak")}(i,t,e);}execute(){const e=this.editor.model;e.change((t=>{const i=t.createElement("pageBreak");e.insertObject(i,null,null,{setSelection:"after"});}));}}class tO extends Dr{static get pluginName(){return "PageBreakEditing"}static get isOfficialPlugin(){return !0}init(){const e=this.editor,t=e.model.schema,i=e.t,n=e.conversion;t.register("pageBreak",{inheritAllFrom:"$blockObject"}),n.for("dataDowncast").elementToStructure({model:"pageBreak",view:(e,{writer:t})=>t.createContainerElement("div",{class:"page-break",style:"page-break-after: always"},t.createContainerElement("span",{style:"display: none"}))}),n.for("editingDowncast").elementToStructure({model:"pageBreak",view:(e,{writer:t})=>{const n=i("Page break"),s=t.createContainerElement("div"),o=t.createRawElement("span",{class:"page-break__label"},(function(e){e.innerText=i("Page break");}));return t.addClass("page-break",s),t.insert(t.createPositionAt(s,0),o),function(e,t,i){return t.setCustomProperty("pageBreak",!0,e),oy(e,t,{label:i})}(s,t,n)}}),n.for("upcast").elementToElement({view:e=>{const t="always"==e.getStyle("page-break-before"),i="always"==e.getStyle("page-break-after");if(!t&&!i)return null;if(1==e.childCount){const t=e.getChild(0);if(!t.is("element","span")||"none"!=t.getStyle("display"))return null}else if(e.childCount>1)return null;return {name:!0}},model:"pageBreak",converterPriority:"high"}),e.commands.add("pageBreak",new eO(e));}}class iO extends Dr{static get pluginName(){return "PageBreakUI"}static get isOfficialPlugin(){return !0}init(){const e=this.editor;e.ui.componentFactory.add("pageBreak",(()=>{const e=this._createButton(pg);return e.set({tooltip:!0}),e})),e.ui.componentFactory.add("menuBar:pageBreak",(()=>this._createButton(Rg)));}_createButton(e){const t=this.editor,i=t.locale,n=t.commands.get("pageBreak"),s=new e(t.locale),o=i.t;return s.set({label:o("Page break"),icon:''}),s.bind("isEnabled").to(n,"isEnabled"),this.listenTo(s,"execute",(()=>{t.execute("pageBreak"),t.editing.view.focus();})),s}}class nO extends Dr{static get requires(){return [tO,iO,Ty]}static get pluginName(){return "PageBreak"}static get isOfficialPlugin(){return !0}}function sO(e){return void 0!==e&&e.endsWith("px")}function oO(e){return e.toFixed(2).replace(/\.?0+$/,"")+"px"}function rO(e,t,i){if(!e.childCount)return;const n=new ju(e.document),s=function(e,t){const i=t.createRangeIn(e),n=[],s=new Set;for(const e of i.getItems()){if(!e.is("element")||!e.name.match(/^(p|h\d+|li|div)$/))continue;let t=gO(e);if(void 0===t||0!=parseFloat(t)||Array.from(e.getClassNames()).find((e=>e.startsWith("MsoList")))||(t=void 0),e.hasStyle("mso-list")||void 0!==t&&s.has(t)){const i=hO(e);n.push({element:e,id:i.id,order:i.order,indent:i.indent,marginLeft:t}),void 0!==t&&s.add(t);}else s.clear();}return n}(e,n);if(!s.length)return;const o={},r=[];for(const e of s)if(void 0!==e.indent){aO(e)||(r.length=0);const s=`${e.id}:${e.indent}`,a=Math.min(e.indent-1,r.length);if(ar.length-1||r[a].listElement.name!=l.type){0==a&&"ol"==l.type&&void 0!==e.id&&o[s]&&(l.startIndex=o[s]);const t=uO(l,n,i);if(sO(e.marginLeft)&&(0==a||sO(r[a-1].marginLeft))){let i=e.marginLeft;a>0&&(i=oO(parseFloat(i)-parseFloat(r[a-1].marginLeft))),n.setStyle("padding-left",i,t);}if(0==r.length){const i=e.element.parent,s=i.getChildIndex(e.element)+1;n.insertChild(s,t,i);}else {const e=r[a-1].listItemElements;n.appendChild(t,e[e.length-1]);}r[a]={...e,listElement:t,listItemElements:[]},0==a&&void 0!==e.id&&(o[s]=l.startIndex||1);}}const l="li"==e.element.name?e.element:n.createElement("li");n.appendChild(l,r[a].listElement),r[a].listItemElements.push(l),0==a&&void 0!==e.id&&o[s]++,e.element!=l&&n.appendChild(e.element,l),mO(e.element,n),n.removeStyle("text-indent",e.element),n.removeStyle("margin-left",e.element);}else {const t=r.find((t=>t.marginLeft==e.marginLeft));if(t){const i=t.listItemElements;n.appendChild(e.element,i[i.length-1]),n.removeStyle("margin-left",e.element);}else r.length=0;}}function aO(e){const t=e.element.previousSibling;return lO(t||e.element.parent)}function lO(e){return e.is("element","ol")||e.is("element","ul")}function cO(e,t){const i=new RegExp(`@list l${e.id}:level${e.indent}\\s*({[^}]*)`,"gi"),n=/mso-level-number-format:([^;]{0,100});/gi,s=/mso-level-start-at:\s{0,100}([0-9]{0,10})\s{0,100};/gi,o=new RegExp(`@list\\s+l${e.id}:level\\d\\s*{[^{]*mso-level-text:"%\\d\\\\.`,"gi"),r=new RegExp(`@list l${e.id}:level\\d\\s*{[^{]*mso-level-number-format:`,"gi"),a=o.exec(t),l=r.exec(t),c=a&&!l,d=i.exec(t);let u="decimal",h="ol",m=null;if(d&&d[1]){const t=n.exec(d[1]);if(t&&t[1]&&(u=t[1].trim(),h="bullet"!==u&&"image"!==u?"ol":"ul"),"bullet"===u){const t=function(e){if("li"==e.name&&"ul"==e.parent.name&&e.parent.hasAttribute("type"))return e.parent.getAttribute("type");const t=function(e){if(e.getChild(0).is("$text"))return null;for(const t of e.getChildren()){if(!t.is("element","span"))continue;const e=t.getChild(0);if(e)return e.is("$text")?e:e.getChild(0)}return null}(e);if(!t)return null;const i=t._data;if("o"===i)return "circle";if("·"===i)return "disc";if("§"===i)return "square";return null}(e.element);t&&(u=t);}else {const e=s.exec(d[1]);e&&e[1]&&(m=parseInt(e[1]));}c&&(h="ol");}return {type:h,startIndex:m,style:dO(u),isLegalStyleList:c}}function dO(e){if(e.startsWith("arabic-leading-zero"))return "decimal-leading-zero";switch(e){case"alpha-upper":return "upper-alpha";case"alpha-lower":return "lower-alpha";case"roman-upper":return "upper-roman";case"roman-lower":return "lower-roman";case"circle":case"disc":case"square":return e;default:return null}}function uO(e,t,i){const n=t.createElement(e.type);return e.style&&t.setStyle("list-style-type",e.style,n),e.startIndex&&e.startIndex>1&&t.setAttribute("start",e.startIndex,n),e.isLegalStyleList&&i&&t.addClass("legal-list",n),n}function hO(e){const t=e.getStyle("mso-list");if(void 0===t)return {};const i=t.match(/(^|\s{1,100})l(\d+)/i),n=t.match(/\s{0,100}lfo(\d+)/i),s=t.match(/\s{0,100}level(\d+)/i);return i&&n&&s?{id:i[2],order:n[1],indent:parseInt(s[1])}:{indent:1}}function mO(e,t){const i=new aa({name:"span",styles:{"mso-list":"Ignore"}}),n=t.createRangeIn(e);for(const e of n)"elementStart"===e.type&&i.match(e.item)&&t.remove(e.item);}function gO(e){const t=e.getStyle("margin-left");return void 0===t||t.endsWith("px")?t:function(e){const t=parseFloat(e);return e.endsWith("pt")?oO(96*t/72):e.endsWith("pc")?oO(12*t*96/72):e.endsWith("in")?oO(96*t):e.endsWith("cm")?oO(96*t/2.54):e.endsWith("mm")?oO(t/10*96/2.54):e}(t)}function fO(e,t){if(!e.childCount)return;const i=new ju(e.document),n=function(e,t){const i=t.createRangeIn(e),n=new aa({name:/v:(.+)/}),s=[];for(const e of i){if("elementStart"!=e.type)continue;const t=e.item,i=t.previousSibling,o=i&&i.is("element")?i.name:null,r=["Chart"],a=n.match(t),l=t.getAttribute("o:gfxdata"),c="v:shapetype"===o,d=l&&r.some((e=>t.getAttribute("id").includes(e)));a&&l&&!c&&!d&&s.push(e.item.getAttribute("id"));}return s}(e,i);!function(e,t,i){const n=i.createRangeIn(t),s=new aa({name:"img"}),o=[];for(const t of n)if(t.item.is("element")&&s.match(t.item)){const i=t.item,n=i.getAttribute("v:shapes")?i.getAttribute("v:shapes").split(" "):[];n.length&&n.every((t=>e.indexOf(t)>-1))?o.push(i):i.getAttribute("src")||o.push(i);}for(const e of o)i.remove(e);}(n,e,i),function(e,t,i){const n=i.createRangeIn(t),s=[];for(const t of n)if("elementStart"==t.type&&t.item.is("element","v:shape")){const i=t.item.getAttribute("id");if(e.includes(i))continue;o(t.item.parent.getChildren(),i)||s.push(t.item);}for(const e of s){const t={src:r(e)};e.hasAttribute("alt")&&(t.alt=e.getAttribute("alt"));const n=i.createElement("img",t);i.insertChild(e.index+1,n,e.parent);}function o(e,t){for(const i of e)if(i.is("element")){if("img"==i.name&&i.getAttribute("v:shapes")==t)return !0;if(o(i.getChildren(),t))return !0}return !1}function r(e){for(const t of e.getChildren())if(t.is("element")&&t.getAttribute("src"))return t.getAttribute("src")}}(n,e,i),function(e,t){const i=t.createRangeIn(e),n=new aa({name:/v:(.+)/}),s=[];for(const e of i)"elementStart"==e.type&&n.match(e.item)&&s.push(e.item);for(const e of s)t.remove(e);}(e,i);const s=function(e,t){const i=t.createRangeIn(e),n=new aa({name:"img"}),s=[];for(const e of i)e.item.is("element")&&n.match(e.item)&&e.item.getAttribute("src").startsWith("file://")&&s.push(e.item);return s}(e,i);s.length&&function(e,t,i){if(e.length===t.length)for(let n=0;nString.fromCharCode(parseInt(e,16)))).join(""))}const bO=//i,wO=/xmlns:o="urn:schemas-microsoft-com/i;class _O{document;hasMultiLevelListPlugin;constructor(e,t=!1){this.document=e,this.hasMultiLevelListPlugin=t;}isActive(e){return bO.test(e)||wO.test(e)}execute(e){const{body:t,stylesString:i}=e._parsedData;rO(t,i,this.hasMultiLevelListPlugin),fO(t,e.dataTransfer.getData("text/rtf")),function(e){const t=[],i=new ju(e.document);for(const{item:n}of i.createRangeIn(e))if(n.is("element")){for(const e of n.getClassNames())/\bmso/gi.exec(e)&&i.removeClass(e,n);for(const e of n.getStyleNames())/\bmso/gi.exec(e)&&i.removeStyle(e,n);(n.is("element","w:sdt")||n.is("element","w:sdtpr")&&n.isEmpty||n.is("element","o:p")&&n.isEmpty)&&t.push(n);}for(const e of t){const t=e.parent,n=t.getChildIndex(e);i.insertChild(n,e.getChildren(),t),i.remove(e);}}(t),e.content=t;}}function vO(e,t,i,{blockElements:n,inlineObjectElements:s}){let o=i.createPositionAt(e,"forward"==t?"after":"before");return o=o.getLastMatchingPosition((({item:e})=>e.is("element")&&!n.includes(e.name)&&!s.includes(e.name)),{direction:t}),"forward"==t?o.nodeAfter:o.nodeBefore}function yO(e,t){return !!e&&e.is("element")&&t.includes(e.name)}const kO=/id=("|')docs-internal-guid-[-0-9a-f]+("|')/i;class CO{document;constructor(e){this.document=e;}isActive(e){return kO.test(e)}execute(e){const t=new ju(this.document),{body:i}=e._parsedData;!function(e,t){for(const i of e.getChildren())if(i.is("element","b")&&"normal"===i.getStyle("font-weight")){const n=e.getChildIndex(i);t.remove(i),t.insertChild(n,i.getChildren(),e);}}(i,t),function(e,t){for(const i of t.createRangeIn(e)){const e=i.item;if(e.is("element","li")){const i=e.getChild(0);i&&i.is("element","p")&&t.unwrapElement(i);}}}(i,t),function(e,t){const i=new Ba(t.document.stylesProcessor),n=new yl(i,{renderingMode:"data"}),s=n.blockElements,o=n.inlineObjectElements,r=[];for(const i of t.createRangeIn(e)){const e=i.item;if(e.is("element","br")){const i=vO(e,"forward",t,{blockElements:s,inlineObjectElements:o}),n=vO(e,"backward",t,{blockElements:s,inlineObjectElements:o}),a=yO(i,s);(yO(n,s)||a)&&r.push(e);}}for(const e of r)e.hasClass("Apple-interchange-newline")?t.remove(e):t.replace(e,t.createElement("p"));}(i,t),e.content=i;}}const xO=/(\s+)<\/span>/g,((e,t)=>1===t.length?" ":Array(t.length+1).join("  ").substr(0,t.length)))}function TO(e,t){const i=new DOMParser,n=function(e){return EO(EO(e)).replace(/([^\S\r\n]*?)[\r\n]+([^\S\r\n]*<\/span>)/g,"$1$2").replace(/<\/span>/g,"").replace(/()[\r\n]+(<\/span>)/g,"$1 $2").replace(/ <\//g," <\/o:p>/g," ").replace(/( |\u00A0)<\/o:p>/g,"").replace(/>([^\S\r\n]*[\r\n]\s*)<")}(function(e){const t="",i="",n=e.indexOf(t);if(n<0)return e;const s=e.indexOf(i,n+t.length);return e.substring(0,n+t.length)+(s>=0?e.substring(s):"")}(e=(e=e.replace(/ @@ -227,4 +227,4 @@ Error generating stack: `+u.message+` `:""} - `}static renderFromError(e,n,a,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:a,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 gs=dt("Router");class LA{constructor(e){$(this,"routes",[]);$(this,"templateIdentifier");$(this,"eventHandlers",new Map);$(this,"pendingNavigation",null);$(this,"isNavigating",!1);$(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 a=this.eventHandlers.get(e);a&&await Promise.all(a.map(i=>i(...n)))}async loadRoutes(e){try{const n=e!==void 0&&e>0?e:null,a=await fetch(Ir(`/api/templates/${this.templateIdentifier}/routes`,"json",n));if(!a.ok)throw new Error(`Failed to load routes: ${a.statusText}`);const i=await a.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,gs.log(`Loaded ${this.routes.length} routes${e?` (v=${e})`:""}`);else throw new Error("Invalid routes data format")}catch(n){throw gs.error("Error loading routes:",n),n}}setRoutes(e){this.routes=e,gs.log(`Set ${this.routes.length} routes`)}match(e){const n=this.normalizePathname(e);for(const a of this.routes){const i=this.matchPattern(a.path,n);if(i!==null)return{route:a,params:i}}return null}normalizePathname(e){return e.length>1&&e.endsWith("/")?e.replace(/\/+$/,"")||"/":e}matchPattern(e,n){const a=[];let i=e.replace(/:([^/]+)/g,(f,h)=>(a.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 a.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,a=this.match(e);if(!a){gs.warn(`No route matched for path: ${e}`),this.emit("routeNotFound",e);return}if(a.route.redirect){gs.log(`Redirecting from ${e} to ${a.route.redirect}`),this.navigate(a.route.redirect);return}if(a.route.auth_required){const c=this.getAuthType(a.route,e),d=Sr.getInstance();let f=d.isAuthenticated()&&d.getAuthType()===c;if(f||(f=await d.checkAuth(c)),!f){const h=d.getLoginRedirectUrl(c,e+n);gs.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:a.route.layout,endpoint:a.route.endpoint,params:{...a.route.params||{},...a.params},query:l,auth_required:a.route.auth_required,auth_type:a.route.auth_type,meta:a.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 MA=/^\/admin\/layout-editor\/([^/?#]+)\/?$/;function qy(s){const e=MA.exec(s);return e?{templateIdentifier:e[1]}:null}const Bt=dt("ErrorPageHandler");class $A{constructor(e){$(this,"templateId");$(this,"layoutLoader");$(this,"locale");$(this,"debug");$(this,"renderFunction");$(this,"dataSourceManager");$(this,"globalState");$(this,"errorConfig",null);$(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(Ir(`/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 a=n.data;return!a.error_config||!a.error_config.layouts?(this.debug&&Bt.warn("No error_config found in template.json"),this.configLoaded=!0,null):(this.errorConfig=a.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 a=await this.loadConfig();if(!a)return this.debug&&Bt.warn("No error config available, cannot render error page"),!1;const i=a.layouts[e]||a.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(a){return Bt.error(`Failed to render error page ${e}:`,a),!1}}processInitOptions(e,n,a){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")a[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;a[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((a,i)=>a?.[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 Ot=dt("ModuleAssetLoader");class NA{constructor(){$(this,"loadedAssets",new Map);$(this,"loadingPromises",new Map);$(this,"failedJsAssets",new Set)}hasFailedJsAssets(){return this.failedJsAssets.size>0}getFailedJsAssets(){return[...this.failedJsAssets]}async loadActiveExtensionAssets(e){if(!e||e.length===0){Ot.log("No module assets to load");return}const n=[...e].sort((d,f)=>d.priority-f.priority);Ot.log("Loading module assets:",n.map(d=>d.identifier));const a=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([...a,...i]),c=l.filter(d=>d.status==="rejected");if(c.length>0){Ot.warn(`Some module assets failed to load (${c.length}/${l.length}); continuing with the rest`,this.getFailedJsAssets());return}Ot.log("All module assets loaded successfully")}async loadBundle(e,n,a){const i=[];if(a&&i.push(this.loadBundleCss(e,a)),n&&i.push(this.loadBundleJs(e,n)),i.length===0){Ot.log(`No bundle assets to load for: ${e}`);return}await Promise.all(i)}async loadBundleCss(e,n){const a=`ext-bundle-css-${e}`;if(document.getElementById(a)){Ot.log(`Bundle CSS already loaded: ${e}`);return}return new Promise(i=>{const l=document.createElement("link");l.rel="stylesheet",l.href=n,l.id=a,l.onload=()=>{Ot.log(`Bundle CSS loaded: ${e}`),this.registerLoadedAsset(`bundle-${e}`,{type:"css",element:l}),i()},l.onerror=()=>{const c=vg(l.getAttribute("href")??n);if(c!==null&&l.dataset.g7StaticFallback!=="1"){l.dataset.g7StaticFallback="1",Ot.warn(`Bundle CSS static miss, falling back to API: ${e} (${n} -> ${c})`),l.href=jr(c);return}Ot.warn(`Failed to load bundle CSS: ${e} (${n})`),i()},document.head.appendChild(l)})}async loadBundleJs(e,n){const a=`ext-bundle-js-${e}`;if(document.getElementById(a)){Ot.log(`Bundle JS already loaded: ${e}`);return}const i=this.loadingPromises.get(a);if(i)return Ot.log(`Bundle JS already loading: ${e}`),i;const l=vg(n),d=(l!==null?jl(n,{id:a},{label:`bundle JS: ${e}`,retries:0}).catch(()=>(Ot.warn(`Bundle JS static miss, falling back to API: ${e} (${n} -> ${l})`),jl(jr(l),{id:a},{label:`bundle JS: ${e}`}))):jl(n,{id:a},{label:`bundle JS: ${e}`})).then(()=>{Ot.log(`Bundle JS loaded: ${e}`);const f=document.getElementById(a);f&&this.registerLoadedAsset(`bundle-${e}`,{type:"js",element:f}),this.loadingPromises.delete(a)}).catch(f=>{throw Ot.warn(`Failed to load bundle JS: ${e} (${n})`,f),this.failedJsAssets.add(e),this.loadingPromises.delete(a),f});return this.loadingPromises.set(a,d),d}async loadCSS(e,n){const a=`module-css-${e}`;if(document.getElementById(a)){Ot.log(`CSS already loaded: ${e}`);return}return new Promise((i,l)=>{const c=document.createElement("link");c.rel="stylesheet",c.href=n,c.id=a,c.onload=()=>{Ot.log(`CSS loaded: ${e}`),this.registerLoadedAsset(e,{type:"css",element:c}),i()},c.onerror=()=>{Ot.warn(`Failed to load CSS: ${e} (${n})`),i()},document.head.appendChild(c)})}async loadJS(e,n){const a=`module-js-${e}`;if(document.getElementById(a)){Ot.log(`JS already loaded: ${e}`);return}const i=this.loadingPromises.get(e);if(i)return Ot.log(`JS already loading: ${e}`),i;const l=jl(n,{id:a},{label:`JS: ${e}`}).then(()=>{Ot.log(`JS loaded: ${e}`);const c=document.getElementById(a);c&&this.registerLoadedAsset(e,{type:"js",element:c}),this.loadingPromises.delete(e)}).catch(c=>{throw Ot.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 a=this.loadedAssets.get(e)||[];a.push(n),this.loadedAssets.set(e,a)}unloadExtensionAsset(e){const n=this.loadedAssets.get(e);if(!n||n.length===0){Ot.log(`No assets to unload for: ${e}`);return}n.forEach(a=>{a.element.parentNode&&(a.element.parentNode.removeChild(a.element),Ot.log(`${a.type.toUpperCase()} unloaded: ${e}`))}),this.loadedAssets.delete(e),Ot.log(`All assets unloaded for: ${e}`)}unloadAllAssets(){Array.from(this.loadedAssets.keys()).forEach(n=>{this.unloadExtensionAsset(n)}),Ot.log("All module assets unloaded")}isLoaded(e){return this.loadedAssets.has(e)}getLoadedModules(){return Array.from(this.loadedAssets.keys())}}let jf=null;function Hf(){return jf||(jf=new NA),jf}function IA(){if(typeof window>"u")return[];const s=window.G7Config;if(!s?.moduleAssets)return[];const e=[];for(const[n,a]of Object.entries(s.moduleAssets)){const i=a;e.push({identifier:n,js:i.js?jr(i.js):i.js,css:i.css?jr(i.css):i.css,priority:i.priority,external:i.external})}return e}function jA(){if(typeof window>"u")return null;const s=window.G7Config;if(!s?.bundleUrls)return null;const e=s.bundleUrls;return{moduleJs:e.moduleJs?jr(e.moduleJs):e.moduleJs,moduleCss:e.moduleCss?jr(e.moduleCss):e.moduleCss,pluginJs:e.pluginJs?jr(e.pluginJs):e.pluginJs,pluginCss:e.pluginCss?jr(e.pluginCss):e.pluginCss}}function HA(){if(typeof window>"u")return[];const s=window.G7Config;if(!s?.pluginAssets)return[];const e=[];for(const[n,a]of Object.entries(s.pluginAssets)){const i=a;e.push({identifier:n,js:i.js?jr(i.js):i.js,css:i.css?jr(i.css):i.css,priority:i.priority,external:i.external})}return e}const zf=dt("SystemBannerManager");class Rc{static show(e){this.banners.set(e.id,e),this.render(),zf.log(`Banner shown: ${e.id}`)}static hide(e){this.banners.delete(e)&&(this.render(),zf.log(`Banner hidden: ${e}`))}static hideAll(){this.banners.clear(),this.render(),zf.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)),a=this.detectLocale();e.innerHTML=n.map(i=>{const l=this.resolveMessage(i.message,a),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`:"")}}$(Rc,"banners",new Map),$(Rc,"containerId","g7-system-banners");const U=dt("TemplateApp");function Gy(s){const e={};for(const n of s.keys()){if(n in e)continue;const a=s.getAll(n);a.length>1?e[n]=a:a.length===1&&(n.endsWith("[]")?e[n]=a:e[n]=a[0])}return e}const sr=class sr{constructor(e){$(this,"router",null);$(this,"layoutLoader",null);$(this,"errorPageHandler",null);$(this,"config");$(this,"globalState");$(this,"globalStateListeners",new Set);$(this,"currentRouteChangeId",0);$(this,"currentDataSources",[]);$(this,"currentRawDataSources",[]);$(this,"currentRouteParams",{});$(this,"currentQueryParams",new URLSearchParams);$(this,"currentFetchedData",{});$(this,"currentLayoutName","");$(this,"templateErrorHandling",null);$(this,"currentWebSocketSubscriptions",[]);$(this,"extensionCacheVersion",0);$(this,"currentGlobalHeaders",[]);$(this,"transitionOverlayEl",null);$(this,"skeletonOverlayRoot",null);$(this,"skeletonOverlayContainer",null);$(this,"_spinnerState",null);$(this,"modalDataSources",new Map);this.globalState={sidebarOpen:!1},this.loadG7Config(),this.migrateLocaleStorage();const n=this.loadLocaleFromStorage(),a=n||e.locale||"ko";this.config={...e,locale:a},!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 Tn,a={_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,a),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,a),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 a=localStorage.getItem(n);a&&a!==localStorage.getItem(sr.LOCALE_STORAGE_KEY)&&(localStorage.setItem(sr.LOCALE_STORAGE_KEY,a),U.log(`Migrated locale from '${n}' to '${sr.LOCALE_STORAGE_KEY}'`)),localStorage.removeItem(n)}catch(a){U.warn(`Failed to migrate locale key '${n}':`,a)}}async init(){try{to.getInstance().setDebug(this.config.debug),U.log("Initializing with config:",this.config),Tw();const e=yr.getInstance(),n=Sr.getInstance(),a=typeof window<"u"&&Number(window.G7Config?.cache_version)||0,i=a>0?a:this.loadCacheVersionFromStorage()||0,[l,c,d,f,h]=await Promise.all([No({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),Hl(i>0?Nl(`templates/${this.config.templateId}/routes.json`,i):null,Ir(`/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(Ir(`/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 Hl(Nl(`templates/${this.config.templateId}/routes.json`,this.extensionCacheVersion),Ir(`/api/templates/${this.config.templateId}/routes`,"json",this.extensionCacheVersion),{label:"routes.json (reload)"}).then(M=>{if(!M.ok)throw new Error(`Failed to reload routes: ${M.statusText}`);return M.json()}).then(M=>{if(!M.success)throw new Error("Failed to reload routes from API");return M.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:M}=await Promise.resolve().then(()=>Rg),k=M.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(M){U.error("Failed to reload translations:",M)}}}h?.errorHandling&&(this.templateErrorHandling=h.errorHandling,Cr().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 Rf(e),this.extensionCacheVersion>0&&this.layoutLoader.setCacheVersion(this.extensionCacheVersion),U.log("LayoutLoader initialized:",this.layoutLoader);const v=new xr({onUnauthorized:()=>{U.warn("Unauthorized request in error page")}});if(this.errorPageHandler=new $A({templateId:this.config.templateId,layoutLoader:this.layoutLoader,locale:this.config.locale,debug:this.config.debug,renderFunction:ms,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 LA(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(()=>qr),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"&&qy(window.location.pathname)){U.log("Layout editor mode detected — skipping router match"),await ms({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=Hf(),n=jA();if(!n){await this.loadExtensionAssetsIndividually();return}await e.loadBundle("module",n.moduleJs,n.moduleCss),await e.loadBundle("plugin",n.pluginJs,n.pluginCss),U.log("Extension bundle assets loaded successfully")}catch(e){U.warn("Failed to load extension assets:",e)}}async loadExtensionAssetsIndividually(){const e=Hf(),n=IA();n.length>0&&(U.log("Loading module assets (individual fallback):",n.map(i=>i.identifier)),await e.loadActiveExtensionAssets(n));const a=HA();a.length>0&&(U.log("Loading plugin assets (individual fallback):",a.map(i=>i.identifier)),await e.loadActiveExtensionAssets(a))}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 a=e.layout;const i=a==="__preview__";i&&e.params?.token&&(a=`__preview__/${e.params.token}`);const l=await this.layoutLoader.loadLayout(this.config.templateId,a);if(n!==this.currentRouteChangeId){U.log("Route change cancelled (newer request exists):",n);return}U.log("Layout loaded:",l);const c=Cr();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(()=>qr),v=new y;if(i){const Z=S();Z&&Z.setPreviewMode(!0),this.setGlobalState({__isPreview:!0}),Rc.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),Rc.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:[],M=L.length>0&&_.some(Z=>L.includes(Z.id)&&Z.type!=="websocket"&&(Z.loading_strategy||"progressive")!=="background");if((x.length>0||M)&&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(()=>qr),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||{},Ve={...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,Ve);Object.keys(Z).length>0&&(Ve._computed=Z,this.globalState._computed=Z,U.log("Computed values calculated:",Object.keys(Z))),Ve._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={},WC()),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)));Ve._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))}Ve._global={...this.globalState,layoutWarnings:l.warnings||[]};const fe=l.initActions||l.init_actions;if(fe&&fe.length>0){await this.executeInitActions(fe,Ve),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))}Ve._local=Z._local,U.log("_local merged into dataContext:",Z._local)}if(Ve._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,Ve);Object.keys(ge).length>0&&(Ve._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))Ve[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 ms({containerId:"app",layoutJson:l,dataContext:Ve,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(()=>qr);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 ye={};this.processInitOptions([T],{[T.id]:de.data},ye);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(ye).length>0&&(xe._localInit=ye,Object.assign(P,ye)),T.initGlobal&&(xe._global={...this.globalState}),Z(xe)}else if(de.state==="error"&&de.error){const ye=de.error,ie=ye.response?.data?.message;O[T.id]={message:ie||de.error.message,status:ye.response?.status||ye.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(()=>qr),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),ye=ge();if(ye.bindingEngine){const _e=[T];de?.initGlobal&&_e.push("_global"),de?.initLocal&&_e.push("_local"),ye.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 $e=this.getActionDispatcher?.();$e&&await $e.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($e){U.error(`WebSocket onReceive action failed for ${T}:`,$e)}})()},H),U.log("WebSocket subscriptions established:",this.currentWebSocketSubscriptions)}U.log("Layout rendered successfully")}catch(a){U.error("Route change handling failed:",a),this.hideTransitionOverlay(),this.showRouteError(a)}}processInitOptions(e,n,a,i){e.some(c=>c.refetchOnMount===!0&&c.initLocal)&&(a._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"?(a[c.initLocal]=this.deepMerge(m,h),U.log(`initLocal (merged): ${c.id}.data -> _local.${c.initLocal}`)):(a[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"?(a[h]=this.deepMerge(S,y),U.log(`initLocal (merged): ${c.id}.data${m?"."+m:""} -> _local.${h}`)):(a[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];a[_]===void 0&&this.globalState._local?.[_]!==void 0&&(a[_]=JSON.parse(JSON.stringify(this.globalState._local[_]))),this.setValueAtPath(a,y,v,h),U.log(`initLocal map (${h}): ${c.id} ${S} -> _local.${y}`)}else{const _=this.globalState._local?.[y];h==="replace"?(a[y]=v,U.log(`initLocal map (replace): ${c.id} ${S} -> _local.${y}`)):h==="shallow"?_!==void 0&&typeof _=="object"&&typeof v=="object"?(a[y]={..._,...v},U.log(`initLocal map (shallow): ${c.id} ${S} -> _local.${y}`)):(a[y]=v,U.log(`initLocal map: ${c.id} ${S} -> _local.${y}`)):_!==void 0&&typeof _=="object"&&typeof v=="object"?(a[y]=this.deepMerge(_,v),U.log(`initLocal map (deep): ${c.id} ${S} -> _local.${y}`)):(a[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 a={};for(const[i,l]of Object.entries(e))if(typeof l=="string"&&l.startsWith("{{")&&l.endsWith("}}")){const c=l.slice(2,-2).trim();a[i]=this.evaluateExpression(c,n)}else a[i]=l;return a}evaluateExpression(e,n){try{const a=e.split("??").map(i=>i.trim());for(const i of a){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(a){U.warn(`Expression evaluation failed: ${e}`,a);return}}getNestedValue(e,n){const a=n.replace(/\?\./g,".");let i=e;const l=a.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,a){const i=Ta(n);if(i!==null){const l=new Tn,c={data:e,_global:this.globalState,_local:this.globalState._local||{}};try{const d=qn(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 ${a}:`,n,d);return}}return this.getNestedValue(e,n)}async loadLayoutScripts(e,n){const a=[];for(const i of e){if((i.if!==void 0||i.conditions!==void 0)&&!as({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}const c=new Promise((d,f)=>{const h=document.createElement("script");h.src=i.src,h.id=i.id,h.async=i.async??!0,h.onload=()=>{U.log(`Script loaded successfully: ${i.id}`),d()},h.onerror=()=>{U.warn(`Failed to load script: ${i.id} (${i.src})`),d()},document.head.appendChild(h)});a.push(c)}a.length>0&&(await Promise.all(a),U.log(`All scripts loaded: ${e.filter(i=>!document.getElementById(i.id)||a.length>0).map(i=>i.id).join(", ")}`))}isAllowedScriptSrc(e){if(typeof e!="string")return!1;const n=e.trim();if(n==="")return!1;const a=sr.normalizeScriptSrcForOriginCheck(n),i=a.startsWith("//"),l=/^[a-z][a-z0-9+.-]*:/i.test(a);if(!i&&!l&&a.startsWith("/"))return!0;const c=this.extractScriptHost(a);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,a=new URL(n,window.location.origin);return a.protocol!=="http:"&&a.protocol!=="https:"?null:a.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 a=e.slice(2,-2).trim();return!!Od(a,n)}return!!e}catch(a){return U.warn(`Failed to evaluate script condition: ${e}`,a),!1}}showInitError(e){if(gd()){U.warn("Init failed while document is unloading — skipping error screen",e);return}const n=By(e);If.renderFromError("app",n,"초기화 실패",this.config.debug,{templateId:this.config.templateId,locale:this.config.locale},void 0,e)}showTransitionOverlay(e,n){const a=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(!a.enabled)return;if(this.hideTransitionOverlay(),a.style==="skeleton"&&a.skeleton?.component&&a.target&&n){this.renderSkeletonOverlay(a.target,a.skeleton,n,a.fallback_target);return}if(a.style==="spinner"&&a.target){this.renderSpinnerOverlay(a.target,a.spinner,a.fallback_target);return}const i=document.documentElement.classList.contains("dark");let l,c="";switch(a.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(a.target){const d=`#${CSS.escape(a.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,a,i){const c=yr.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=a.components||[];let A;if(f==="fullpage")A=x;else{const k=f==="fallback"?i:e;A=this.findComponentChildrenById(x,k)}const L=ud.createRoot(_);this.skeletonOverlayRoot=L,Oa.flushSync(()=>{L.render(Ye.createElement(c,{components:A,options:{animation:n.animation||"pulse",iteration_count:n.iteration_count||5}}))});const M=f==="fullpage"?"fullpage (#app)":f==="fallback"?`fallback (#${i})`:`target (#${e})`;U.log(`Skeleton overlay rendered [${M}] with "${n.component}" (${A.length} components)`)}findComponentChildrenById(e,n){const a=i=>{for(const l of i){if(l.id===n)return l.children||[];if(l.children&&Array.isArray(l.children)){const c=a(l.children);if(c!==null)return c}}return null};return a(e)||e}renderSpinnerOverlay(e,n,a){let i=document.getElementById(e),l="target";if(!i&&a&&(i=document.getElementById(a),l="fallback"),i||(i=document.getElementById("app"),l="fullpage"),!i){U.log(`Spinner overlay: no target found (target="#${e}", fallback="${a||"none"}"), falling back to opaque overlay`),this.showTransitionOverlay({enabled:!0,style:"opaque",target:e});return}this.hideSkeletonOverlay();const c=l==="fullpage"?"app":l==="fallback"?a: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:a,spinnerConfig:n,resolvedText:h},this._mountSpinnerInTarget(i);const m=l==="fullpage"?"fullpage (#app)":l==="fallback"?`fallback (#${a})`:`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:a}=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=yr.getInstance().getComponent(n.component);if(c){const d=ud.createRoot(i);this.skeletonOverlayRoot=d,Oa.flushSync(()=>{d.render(Ye.createElement(c,{options:{text:a}}))});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 a=document.getElementById(e);!a&&n&&(a=document.getElementById(n)),a||(a=document.getElementById("app")),a&&(this._mountSpinnerInTarget(a),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 Ar&&e.details?.status===401){const a=this.config.templateId||"",i=window.location.pathname,l=a.includes("admin")||i.startsWith("/admin")?"admin":"user",c=i+window.location.search,d=!!zr().getToken()||e.details?.hadToken===!0,f=Sr.getInstance().getLoginRedirectUrl(l,c,d?"session_expired":void 0);window.location.href=f;return}const n=By(e);If.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(Ir(`/api/templates/${this.config.templateId}/config`,"json",null,`_=${Date.now()}`));if(n.ok){const a=await n.json();a?.success&&a?.data?.cache_version!==void 0&&(e=a.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(()=>Rg),a=n.getInstance();this.extensionCacheVersion>0&&a.setCacheVersion(this.extensionCacheVersion);const i=this.config.locale||"ko",l="en";await a.loadTranslations(this.config.templateId,i,"/api",!0),i!==l&&await a.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 ra().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")),Dc(),await No({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(()=>qr),a=n();a&&(a.setDefaultContext({navigate:i=>this.router?.navigate(i)}),a.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(sr.LOCALE_STORAGE_KEY)}catch(e){return U.warn("Failed to load locale from storage:",e),null}}saveLocaleToStorage(e){try{localStorage.setItem(sr.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 a,i;if(this.config.localeApi)a=this.config.localeApi.endpoint,i=this.config.localeApi.method;else{const l=this.config.templateType==="admin";a=l?"/api/admin/users/me/language":"/api/user/profile/update-language",i=l?"PATCH":"POST"}try{const l=this.getXsrfToken(),c=await fetch(a,{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(sr.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(sr.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(a=>{if(a.startsWith(e)&&typeof n[a]?.initModule=="function")try{n[a].initModule(),U.log(`Module handler re-initialized: ${a}`)}catch(i){U.warn(`Failed to re-initialize module handlers for ${a}:`,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(([a,i])=>{n.registerHandler(a,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(a=>{if(a.startsWith(e)&&typeof n[a]?.initPlugin=="function")try{n[a].initPlugin(),U.log(`Plugin handler re-initialized: ${a}`)}catch(i){U.warn(`Failed to re-initialize plugin handlers for ${a}:`,i)}})}getLocale(){return this.config.locale}getErrorPageHandler(){return this.errorPageHandler}getGlobalState(){return{...this.globalState}}setGlobalState(e,n){const a={...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:a,next:this.globalState}),this.globalStateListeners.forEach(l=>{l(this.globalState)}),n?.render!==!1&&Promise.resolve().then(()=>qr).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 a=this.currentDataSources.find(i=>i.id===e);if(!a)for(const[,i]of this.modalDataSources){const l=i.find(c=>c.id===e);if(l){a=l;break}}if(!a){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 xr;this.currentGlobalHeaders.length>0&&i.setGlobalHeaders(this.currentGlobalHeaders);const l=ra(),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([a],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([a],{[e]:y.data},S);const v=ra();if(v.bindingEngine){const x=[e];a.initGlobal&&x.push("_global"),a.initLocal&&x.push("_local"),v.bindingEngine.invalidateCacheByKeys(x)}const _={[e]:y.data};return Object.keys(S).length>0&&(_._localInit=S),a.initGlobal&&(_._global={...this.globalState}),ys(_,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,a){if(!e){U.warn("setDataSource: dataSourceId is required");return}const{merge:i=!1,sync:l=!1}=a||{};i&&this.currentFetchedData[e]?this.currentFetchedData[e]={...this.currentFetchedData[e],...n}:this.currentFetchedData[e]=n,Promise.resolve().then(()=>qr).then(({updateTemplateData:c})=>{c({[e]:this.currentFetchedData[e]},l?{sync:!0}:void 0)}),U.log(`setDataSource: Updated ${e}`,i?"(merged)":"(replaced)")}updateDataSourceItem(e,n,a,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(a));if(S===-1)return U.warn(`updateDataSourceItem: Item with ${c}='${a}' 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:a,updates:i,timestamp:Date.now()}),f||Promise.resolve().then(()=>qr).then(({updateTemplateData:_})=>{_({[e]:this.currentFetchedData[e]},{sync:!1})}),U.log(`updateDataSourceItem: Updated ${e}.${n}[${c}=${a}]`),!0}parseItemPath(e){const n=[],a=/([^\.\[\]]+)|\[(\d+)\]/g;let i;for(;(i=a.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 a={...e};for(const i of Object.keys(n))typeof n[i]=="object"&&n[i]!==null&&!Array.isArray(n[i])?a[i]=this.deepMerge(a[i]||{},n[i]):a[i]=n[i];return a}setValueAtPath(e,n,a,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=ra().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 xr;this.currentGlobalHeaders.length>0&&x.setGlobalHeaders(this.currentGlobalHeaders);const A=ra(),L=A.currentDataContext?._global||{},M=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 M){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=Gy(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)))}ys(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 a={},i=new Tn;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;a[l]=d,U.log(`Computed ${l}:`,d)}catch(d){U.warn(`Failed to calculate computed value: ${l}`,d),a[l]=void 0}return a}isComputedSwitchDefinition(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&"$switch"in e&&"$cases"in e}evaluateComputedExpression(e,n){try{return Od(e,n)}catch(a){U.warn(`Expression evaluation failed: ${e}`,a);return}}async executeInitActions(e,n={}){const{getActionDispatcher:a}=await Promise.resolve().then(()=>qr),i=a();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,a=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=Hf().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>=a){const m=n.filter(y=>!e.customHandlers?.has(y));U.warn("Timeout waiting for handlers:",m),f();return}setTimeout(h,l)};h()})}};$(sr,"LOCALE_STORAGE_KEY","g7_locale"),$(sr,"CACHE_VERSION_STORAGE_KEY","g7_cache_version");let Do=sr;function Uf(s){const e=new Do(s);return s.websocket&&(xc.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=Uf,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 zA(s={}){const{checked:e,value:n,name:a,type:i="checkbox"}=s,c=n!==void 0?n:i==="checkbox"||i==="radio"?e??!1:String(e??""),d={checked:e??!1,value:c,name:a??"",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 UA(s={}){const{button:e=0,clientX:n=0,clientY:a=0}=s;return{button:e,clientX:n,clientY:a,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 PA(){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 BA(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 qA={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 Vy(s){const e=s.replace(/^(dark:|hover:|focus:|active:|disabled:|group-hover:|sm:|md:|lg:|xl:|2xl:)+/,"");for(const[n,a]of Object.entries(qA))if(a.test(e))return n;return null}function Fy(s){const e=s.match(/^((dark:|hover:|focus:|active:|disabled:|group-hover:|sm:|md:|lg:|xl:|2xl:)+)/);return e?e[1]:""}function GA(s,e){if(!e||e.trim()==="")return s;if(!s||s.trim()==="")return e;const n=s.split(/\s+/).filter(Boolean),a=e.split(/\s+/).filter(Boolean),i=new Map;for(const c of a){const d=Vy(c);if(d){const f=Fy(c),h=`${d}:${f}`;i.set(h,c)}}return[...n.filter(c=>{const d=Vy(c);if(!d)return!0;const f=Fy(c),h=`${d}:${f}`;return!i.has(h)}),...a].join(" ")}function VA(s){return Object.entries(s).filter(([,e])=>e).map(([e])=>e).join(" ")}function FA(...s){return s.filter(e=>typeof e=="string"&&e.length>0).join(" ")}const be=dt("G7CoreGlobals");function KA(){window.React=Ye,window.ReactDOM={...dd,createPortal:Oa.createPortal,unstable_batchedUpdates:s=>s()},window.ReactJSXRuntime=BC,be.log("전역 객체 window.React, window.ReactDOM, window.ReactJSXRuntime에 노출됨")}function WA(s){const e=new Map,n=Ma.getInstance();s.componentEvent={on:(a,i)=>(e.has(a)||e.set(a,new Set),e.get(a).add(i),n.trackEventSubscribe(a),()=>{e.get(a)?.delete(i),n.trackEventUnsubscribe(a)}),emit:async(a,i)=>{const l=e.get(a),c=l?.size??0;if(!l||l.size===0)return n.trackEventEmit(a,i,0),[];let d,f=[];try{f=await Promise.all(Array.from(l).map(async h=>{try{return await h(i)}catch(m){throw be.error(`componentEvent: Error in listener for "${a}":`,m),m}}))}catch(h){d=h instanceof Error?h:new Error(String(h))}if(n.trackEventEmit(a,i,c,f,d),d)throw d;return f},off:a=>{e.delete(a),n.trackEventOff(a)},clear:()=>{e.clear(),n.trackEventClear()}},be.log("전역 객체 window.G7Core.componentEvent에 노출됨")}function YA(s){s.__runtime||(s.__runtime={DynamicRenderer:Br,ComponentRegistry:yr,TranslationEngine:xa,DataSourceManager:xr,dataSourceManager:kA,DataBindingEngine:Tn,dataBindingEngine:Md,ActionDispatcher:vo,TranslationReactContext:Df,TranslationProvider:Ec,useTranslation:Ry,ResponsiveContext:of,ResponsiveProvider:cc,useResponsive:lf,responsiveManager:mi,BREAKPOINT_PRESETS:ql,AuthManager:Sr,createLogger:dt,G7DevToolsCore:Ma},be.log("전역 객체 window.G7Core.__runtime(코어 런타임 표면)에 노출됨"))}function XA(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:(a,i)=>e.push(["widget",a,i]),registerNodeEditor:(a,i)=>e.push(["nodeEditor",a,i]),registerCanvasOverlay:(a,i)=>e.push(["canvasOverlay",a,i]),onReady:a=>{typeof a=="function"&&n.push(a)}},be.log("전역 객체 window.G7Core.layoutEditor 예약 접수함(stub) 노출됨")}function JA(s,e){s.useTranslation=Ry,s.t=(n,a)=>{const i=e.getState();if(!i.translationEngine||!i.translationContext)return n;if(a){const l="|"+Object.entries(a).map(([c,d])=>`${c}=${d}`).join("|");return i.translationEngine.translate(n,i.translationContext,l)}return i.translationEngine.translate(n,i.translationContext)},be.log("전역 객체 window.G7Core.useTranslation에 노출됨")}function QA(s,e){s.createChangeEvent=zA,s.createClickEvent=UA,s.createSubmitEvent=PA,s.createKeyboardEvent=BA,s.uuid=()=>typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const a=Math.random()*16|0;return(n==="x"?a:a&3|8).toString(16)}),s.createLogger=dt,be.log("전역 객체 window.G7Core.createLogger에 노출됨"),s.renderItemChildren=(n,a,i,l,c)=>{const d=e.getState(),m={_global:window.__templateApp?.getGlobalState?.()||{},_local:a._local||{},_computed:a._computed||{},...a},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 co(n,m,i,l,v)},s.evaluateCondition=(n,a)=>{if(!n)return!0;const i=e.getState(),c=window.__templateApp?.getGlobalState?.()||{},d={_global:c,_local:c._local||{},_computed:c._computed||{},...a||{}},f=i.bindingEngine??Md;return qg(n,d,f)},s.getComponentMap=()=>yr.getInstance().getComponentMap(),s.renderComponentLayout=(n,a,i)=>{if(!n||!Array.isArray(n)||n.length===0)return null;const l=yr.getInstance().getComponentMap(),c=e.getState(),f=window.__templateApp?.getGlobalState?.()||{},h={_global:f._global||{},_local:f._local||{},_computed:f._computed||{},...a},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 co(n,h,l,i,{translationContext:c.translationContext,translationEngine:c.translationEngine,bindingEngine:c.bindingEngine,actionDispatcher:c.actionDispatcher,getRemountKey:y})},s.renderExpandContent=n=>{const{children:a,row:i,expandContext:l,componentContext:c,keyPrefix:d}=n;if(!a||!Array.isArray(a)||a.length===0)return null;const f=n.componentMap||yr.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=Ta(P);if(G!==null)try{A[O]=qn(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){be.warn("renderExpandContent: expandContext 평가 오류:",O)}const L={row:i,item:i,$item:i,_local:S,_global:m._global||{},_computed:m._computed||{},...A},M=new Set,k=(O,P)=>{const G=L._global?._remountKeys;return O&&G?.[O]&&!M.has(O)?(M.add(O),`${O}-remount-${G[O]}`):O||P};return co(a,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(a,i,l=void 0){if(a==null)return l;const c=Array.isArray(i)?i:[i];if(c.length===0)return a;let d=a;for(const f of c){if(d==null||f==null)return l;d=d[f]}return d??l},be.log("전역 객체 window.G7Core.renderItemChildren에 노출됨"),be.log("전역 객체 window.G7Core.renderComponentLayout에 노출됨"),be.log("전역 객체 window.G7Core.renderExpandContent에 노출됨"),be.log("전역 객체 window.G7Core.$get에 노출됨")}function ZA(s){s.dispatch=async(e,n)=>{const a=window.__templateApp;if(!a)return be.warn("G7Core.dispatch: TemplateApp이 초기화되지 않았습니다."),{success:!1,error:new Error("TemplateApp이 초기화되지 않았습니다.")};const i=a.getActionDispatcher?.();if(!i)return be.warn("G7Core.dispatch: ActionDispatcher를 찾을 수 없습니다."),{success:!1,error:new Error("ActionDispatcher를 찾을 수 없습니다.")};const l=a.getRouter?.(),c=a.getGlobalState?.(),d=a.setGlobalState?.bind(a),h=n?.componentContext||window.__g7ActionContext,m=window.__g7PendingLocalState;let y=h?.state??c;m&&h&&(y=m,be.log("[dispatch] Using __g7PendingLocalState for context.state:",m));let S=h?.data??c;m&&h?.data?._local&&(S={...h.data,_local:m},be.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,...M}=e;i.dispatchAction(M,v)}),{success:!0,debounced:!0}}try{return await i.dispatchAction(e,v)}catch(_){return be.error("G7Core.dispatch: 액션 실행 오류:",_),{success:!1,error:_ instanceof Error?_:new Error(String(_))}}},be.log("전역 객체 window.G7Core.dispatch에 노출됨")}function Oo(s){const e={};for(const[n,a]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 Wy(s,e){const n={...s};for(const a of Object.keys(e))a in n?n[a]!==null&&typeof n[a]=="object"&&!Array.isArray(n[a])&&e[a]!==null&&typeof e[a]=="object"&&!Array.isArray(e[a])&&(n[a]=Wy(n[a],e[a])):n[a]=e[a];return n}function ir(s,e){if(Array.isArray(s)&&!Array.isArray(e)&&ex(e)){const a=Object.keys(e).map(l=>parseInt(l,10));if(!((a.length>0?Math.max(...a):0)>=s.length+a.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[a,i]of Object.entries(e))i!==null&&typeof i=="object"&&!Array.isArray(i)?n[a]!==null&&typeof n[a]=="object"?n[a]=ir(n[a],i):n[a]={...i}:n[a]=i;return n}function tx(s){s.state={get:()=>window.__templateApp?.getGlobalState?.()||{},set:(e,n)=>{const a=window.__templateApp;if(a?.setGlobalState&&a?.getGlobalState){const i=n?.merge||"deep",l=Oo(e);let c;if(i==="replace")c=l;else if(i==="shallow")c={...a.getGlobalState(),...l};else{const d=a.getGlobalState();c=ir(d,l)}a.setGlobalState(c,{render:n?.render})}else be.warn("G7Core.state.set: TemplateApp이 초기화되지 않았습니다.")},setLocal:(e,n)=>{const a=window.__templateApp;if(n?.render===!1&&!n?.selfManaged){const A=window.__g7AutoBindingPaths;A&&A.size>0&&Ky(Oo(e)).some(M=>A.has(M))&&(be.log("[setLocal] render:false + 자동바인딩 경로 겹침 감지 → render:true 자동 승격 (engine-v1.43.0)"),n={...n,render:!0})}if(n?.debounce){const A=a?.getActionDispatcher?.();if(A){const L=n.debounceKey||`setLocal-${Object.keys(e).join(",")}`,{debounce:M,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=Oo(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(M=>l==="replace"?d:l==="shallow"?{...M||{},...d}:ir(M||{},d)),be.log(`[setLocal] scope=${i}: 타겟 컨텍스트에 상태 업데이트 (mergeMode=${l})`,d);return}}be.warn(`[setLocal] scope=${i}: 레이아웃 컨텍스트 스택이 비어있습니다. current로 폴백합니다.`)}const f=window.__g7PendingLocalState,h=a?.getGlobalState?.()?._local||{},S=!((window.__g7LayoutContextStack||[]).length>0)&&c?.state?c.state:void 0,v=S?Wy(h,S):h,_=f||v;let x;if(l==="replace"?x=d:l==="shallow"?x={..._,...d}:x=ir(_,d),a?.setGlobalState&&(a.setGlobalState({_local:x},{render:n?.render}),be.log(`[setLocal] globalLocal updated via setGlobalState (mergeMode=${l}, render=${n?.render??!0}):`,d)),window.__g7PendingLocalState=x,be.log("[setLocal] __g7PendingLocalState updated:",x),window.__g7SequenceLocalSync=x,window.__g7LastSetLocalSnapshot=x,l==="replace")window.__g7ForcedLocalFields=d;else{const A=window.__g7ForcedLocalFields||{};window.__g7ForcedLocalFields=ir(A,d)}if(be.log("[setLocal] __g7ForcedLocalFields updated:",d),l==="replace")window.__g7SetLocalOverrideKeys=d;else{const A=window.__g7SetLocalOverrideKeys||{};window.__g7SetLocalOverrideKeys=ir(A,d)}be.log("[setLocal] __g7SetLocalOverrideKeys updated:",d),c?.setState&&c.setState(A=>l==="replace"?d:l==="shallow"?{...A||{},...d}:ir(A||{},d)),a?.setGlobalState||be.warn("G7Core.state.setLocal: TemplateApp이 없습니다.")},getLocal:()=>{const a=(window.__templateApp?.getGlobalState?.()||{})._local||{},i=window.__g7PendingLocalState;if(i)return ir(a,i);const l=window.__g7LastSetLocalSnapshot;return l&&l!==a?ir(a,l):a},update:e=>{const n=window.__templateApp;if(n?.getGlobalState&&n?.setGlobalState){const a=n.getGlobalState(),i=e(a);n.setGlobalState(i)}else be.warn("G7Core.state.update: TemplateApp이 초기화되지 않았습니다.")},subscribe:e=>{const n=window.__templateApp;return n?.onGlobalStateChange?n.onGlobalStateChange(e):(be.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,a)=>{let i,l,c;typeof e=="string"?(i=e,l=n||{},c=a):(l=e,c=n&&typeof n=="object"&&"merge"in n?n:a);const d=c?.merge||"deep",f=Oo(l);if(i){const y=window.__g7IsolatedStates?.[i];y?.mergeState?y.mergeState(f,d):be.warn(`G7Core.state.setIsolated: scopeId '${i}'를 찾을 수 없습니다.`);return}const h=window.__g7ActionContext;h?.isolatedContext?.mergeState?h.isolatedContext.mergeState(f,d):be.warn("G7Core.state.setIsolated: 액션 컨텍스트에 isolatedContext가 없습니다.")},getParent:()=>{const e=window.__g7LayoutContextStack||[];if(e.length===0)return be.log("[getParent] 레이아웃 컨텍스트 스택이 비어있습니다."),null;const n=e[e.length-1];if(!n)return null;const a=n.dataContext||{};return{_local:n.state||a._local||{},_global:a._global||s.state.get()||{},setState:n.setState}},setParentLocal:(e,n,a)=>{const i=window.__g7LayoutContextStack||[];if(i.length===0){be.warn("[setParentLocal] 레이아웃 컨텍스트 스택이 비어있습니다.");return}const l=i[i.length-1];if(!l?.setState){be.warn("[setParentLocal] 부모 컨텍스트에 setState가 없습니다.");return}let c,d;typeof e=="string"?(c={[e]:n},d=a):(c=e,d=n&&typeof n=="object"&&"merge"in n?n:a);const f=d?.merge||"deep",h=Oo(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=ir(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=ir(_,h)}rf()},setParentGlobal:(e,n)=>{let a;typeof e=="string"?a={[e]:n}:a=e,s.state.set(a),be.log("[setParentGlobal] 전역 상태 업데이트:",a)}},window.__g7IsolatedStates||(window.__g7IsolatedStates={}),s.state.getGlobal=s.state.get,s.state.setGlobal=s.state.set,be.log("전역 객체 window.G7Core.state에 노출됨")}function nx(s){s.dataSource={get:e=>window.__templateApp?.getDataSource?.(e),set:(e,n,a)=>{const i=window.__templateApp;i?.setDataSource?i.setDataSource(e,n,a):be.warn("G7Core.dataSource.set: TemplateApp이 초기화되지 않았습니다.")},refetch:async(e,n)=>{const a=window.__templateApp;if(a?.refetchDataSource)return a.refetchDataSource(e,n);be.warn("G7Core.dataSource.refetch: TemplateApp이 초기화되지 않았습니다.")},updateItem:(e,n,a,i,l)=>{const c=window.__templateApp;return c?.updateDataSourceItem?c.updateDataSourceItem(e,n,a,i,l):(be.warn("G7Core.dataSource.updateItem: TemplateApp이 초기화되지 않았습니다."),!1)},updateData:(e,n,a,i="append")=>{const l=window.__templateApp;if(!l?.getDataSource||!l?.setDataSource)return be.warn("G7Core.dataSource.updateData: TemplateApp이 초기화되지 않았습니다."),!1;const c=l.getDataSource(e);if(!c)return be.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 be.warn(`G7Core.dataSource.updateData: 경로 '${n}'를 찾을 수 없습니다.`),!1;d=f[h]}else d=c;if(!Array.isArray(d))return be.warn("G7Core.dataSource.updateData: 대상 경로의 데이터가 배열이 아닙니다."),!1;if(!Array.isArray(a))return be.warn("G7Core.dataSource.updateData: newData가 배열이 아닙니다."),!1;const m=i==="prepend"?[...a,...d]:[...d,...a];return n&&h?(f[h]=m,l.setDataSource(e,c,{merge:!1})):l.setDataSource(e,m,{merge:!1}),be.log(`G7Core.dataSource.updateData: '${e}'에 ${a.length}개 항목 ${i==="prepend"?"앞에":"뒤에"} 추가됨`),!0}},be.log("전역 객체 window.G7Core.dataSource에 노출됨")}function rx(s,e){s.locale={current:()=>window.__templateApp?.getLocale?.()||"ko",supported:()=>{const a=window.__templateApp?.globalState?.appConfig?.supportedLocales;return Array.isArray(a)&&a.length>0?a:e.getState().templateMetadata?.locales||["ko","en"]},change:async n=>{const a=window.__templateApp;a?.changeLocale?await a.changeLocale(n):be.warn("G7Core.locale.change: TemplateApp이 초기화되지 않았습니다.")}},be.log("전역 객체 window.G7Core.locale에 노출됨")}function ax(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})}},be.log("전역 객체 window.G7Core.toast에 노출됨")}function ix(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||[]},be.log("전역 객체 window.G7Core.modal에 노출됨")}function sx(s){s.style={mergeClasses:GA,conditionalClass:VA,joinClasses:FA},be.log("전역 객체 window.G7Core.style에 노출됨")}function ox(s,e){const{webSocketManager:n}=e;s.websocket={manager:n,subscribe:(a,i,l,c)=>n.subscribe(a,i,l,c),unsubscribe:a=>n.unsubscribe(a),leaveChannel:a=>n.leaveChannel(a),disconnect:()=>n.disconnect(),isInitialized:()=>n.isInitialized(),getSubscriptionCount:()=>n.getSubscriptionCount()},be.log("전역 객체 window.G7Core.websocket에 노출됨")}function lx(s,e){const{transitionManager:n}=e;s.navigation={isPending:()=>n?.getIsPending?.()||!1,onComplete:a=>{if(!n)return a(),()=>{};let i=n.getIsPending();const l=n.subscribe(c=>{c?i=!0:i&&(a(),l())});return l}},be.log("전역 객체 window.G7Core.navigation에 노출됨")}function cx(s){s.plugin={getSettings:e=>window.G7Config?.plugins?.[e],get:(e,n,a)=>window.G7Config?.plugins?.[e]?.[n]??a,getAll:()=>window.G7Config?.plugins??{}},be.log("전역 객체 window.G7Core.plugin에 노출됨")}function ux(s){s.module={getSettings:e=>window.G7Config?.modules?.[e],get:(e,n,a)=>window.G7Config?.modules?.[e]?.[n]??a,getAll:()=>window.G7Config?.modules??{}},be.log("전역 객체 window.G7Core.module에 노출됨")}function dx(s,e){const{transitionManager:n,responsiveManager:a}=e;s.AuthManager=Sr,s.api=zr(),s.TransitionManager=n,s.useTransitionState=Um,s.ResponsiveManager=a,s.useResponsive=lf,s.useControllableState=tE,s.shallowArrayEqual=nE,s.shallowObjectEqual=Bm,s.updateQueryParams=async(i,l)=>{const c=window.__templateApp;if(c?.updateQueryParams)return c.updateQueryParams(i,l);be.warn("G7Core.updateQueryParams: TemplateApp이 초기화되지 않았습니다.")},be.log("전역 객체 window.G7Core.AuthManager에 노출됨"),be.log("전역 객체 window.G7Core.api에 노출됨"),be.log("전역 객체 window.G7Core.ResponsiveManager에 노출됨"),be.log("전역 객체 window.G7Core.useResponsive에 노출됨"),be.log("전역 객체 window.G7Core.useControllableState에 노출됨"),be.log("전역 객체 window.G7Core.updateQueryParams에 노출됨")}function fx(s,e){s.getSlotContext=()=>window.__slotContextValue??null,s.getDynamicRenderer=()=>window.__DynamicRenderer??null,s.getComponentRegistry=()=>e.getComponentRegistry?.()??yr.getInstance(),s.getDataBindingEngine=()=>e.getDataBindingEngine?.()??e.getState().bindingEngine,s.getTranslationEngine=()=>e.getTranslationEngine?.()??e.getState().translationEngine,s.getActionDispatcher=()=>e.getActionDispatcher?.()??e.getState().actionDispatcher,be.log("전역 객체 window.G7Core 슬롯 API에 노출됨 (getSlotContext, getDynamicRenderer 등)")}function hx(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:Jd},be.log("전역 객체 window.G7Core 본인인증(IDV) API에 노출됨 (identity)")}function px(s){if(typeof window>"u")return;KA(),window.G7Core||(window.G7Core={});const e=window.G7Core;YA(e),WA(e),XA(e),dx(e,s),JA(e,s),QA(e,s),ZA(e),tx(e),nx(e),rx(e,s),ax(e),ix(e),sx(e),ox(e,s),lx(e,s),cx(e),ux(e),fx(e,s),hx(e),be.log("G7Core 전역 객체 초기화 완료")}function gx(){const s=window.G7Core;if(!s){be.warn("G7Core가 초기화되지 않았습니다.");return}const e=()=>Ma.getInstance(),n={isEnabled:()=>{try{return e().isEnabled()}catch{return!1}},trackRender:a=>{try{e().isEnabled()&&e().trackRender(a)}catch{}},trackIteration:(a,i,l,c,d)=>{try{e().isEnabled()&&e().trackIteration(a,{source:i,itemVar:l,indexVar:c,sourceLength:d})}catch{}},trackIfCondition:(a,i,l,c)=>{try{e().isEnabled()&&e().trackIfCondition(a,i,l)}catch{}},trackMount:(a,i)=>{try{e().isEnabled()&&e().trackMount(a,{...i,id:a})}catch{}},trackUnmount:a=>{try{e().isEnabled()&&e().trackUnmount(a)}catch{}},trackExpressionEval:a=>{try{e().isEnabled()&&e().trackExpressionEval(a)}catch{}},trackBindingEval:a=>{try{e().isEnabled()&&e().trackBindingEval(a)}catch{}},recordCacheHit:()=>{try{e().isEnabled()&&e().recordCacheHit()}catch{}},recordCacheMiss:()=>{try{e().isEnabled()&&e().recordCacheMiss()}catch{}},trackHandlerRegistration:(a,i,l,c)=>{try{e().isEnabled()&&e().trackHandlerRegistration(a,i,l,c)}catch{}},trackHandlerUnregistration:a=>{try{e().isEnabled()&&e().trackHandlerUnregistration(a)}catch{}},logAction:a=>{try{e().isEnabled()&&e().logAction(a)}catch{}},trackRequest:(a,i)=>{try{return e().isEnabled()?e().trackRequest(a,i):""}catch{return""}},completeRequest:(a,i,l)=>{try{e().isEnabled()&&e().completeRequest(a,i,l)}catch{}},failRequest:(a,i)=>{try{e().isEnabled()&&e().failRequest(a,i)}catch{}},trackDataSourceDefinition:a=>{try{e().isEnabled()&&e().trackDataSourceDefinition(a)}catch{}},trackDataSourceLoading:a=>{try{e().isEnabled()&&e().trackDataSourceLoading(a)}catch{}},trackDataSourceLoaded:(a,i,l)=>{try{e().isEnabled()&&e().trackDataSourceLoaded(a,i,l)}catch{}},trackDataSourceError:(a,i)=>{try{e().isEnabled()&&e().trackDataSourceError(a,i)}catch{}},trackForm:(a,i,l)=>{try{e().isEnabled()&&e().trackForm(a,i,l)}catch{}},untrackForm:a=>{try{e().isEnabled()&&e().untrackForm(a)}catch{}},startStateChange:(a,i,l,c)=>{try{return e().isEnabled()?e().startStateChange(a,i,l,c):""}catch{return""}},completeStateChange:a=>{try{e().isEnabled()&&e().completeStateChange(a)}catch{}},trackComponentRender:(a,i,l,c,d,f)=>{try{e().isEnabled()&&e().trackComponentRender(a,i,l,c,d,f)}catch{}},updateLocalState:a=>{try{e().isEnabled()&&e().updateLocalState(a)}catch{}},updateComputedState:a=>{try{e().isEnabled()&&e().updateComputedState(a)}catch{}},updateParentContext:a=>{try{e().isEnabled()&&e().updateParentContext(a)}catch{}},trackComponentStateSource:(a,i,l,c)=>{try{e().isEnabled()&&e().trackComponentStateSource(a,i,l,c)}catch{}},trackDynamicState:(a,i)=>{try{e().isEnabled()&&e().trackDynamicState(a,i)}catch{}},trackContextFlow:(a,i,l,c,d,f)=>{try{e().isEnabled()&&e().trackContextFlow(a,i,l,c,d,f)}catch{}},trackComponentStyle:(a,i,l,c)=>{try{e().isEnabled()&&e().trackComponentStyle(a,i,l,c)}catch{}},trackAuthEvent:(a,i,l,c)=>{try{e().isEnabled()&&e().trackAuthEvent(a,i,l,c)}catch{}},trackAuthHeader:(a,i,l,c,d)=>{try{e().isEnabled()&&e().trackAuthHeader(a,i,l,c,d)}catch{}},trackLog:(a,i,l)=>{try{e().isEnabled()&&e().trackLog(a,i,l)}catch{}},trackAction:a=>{try{e().isEnabled()&&e().trackAction?.(a)}catch{}},trackDataSourceUpdate:a=>{try{e().isEnabled()&&e().trackDataSourceUpdate?.(a)}catch{}},startSequenceExecution:a=>{try{return e().isEnabled()?e().startSequenceExecution(a):""}catch{return""}},captureSequenceActionBefore:(a,i,l,c,d)=>{try{e().isEnabled()&&e().captureSequenceActionBefore(a,i,l,c,d)}catch{}},captureSequenceActionAfter:(a,i,l,c,d,f)=>{try{e().isEnabled()&&e().captureSequenceActionAfter(a,i,l,c,d,f)}catch{}},endSequenceExecution:(a,i)=>{try{e().isEnabled()&&e().endSequenceExecution(a,i)}catch{}},registerStateCaptureForHandler:(a,i,l)=>{try{e().isEnabled()&&e().registerStateCaptureForHandler(a,i,l)}catch{}},detectStaleClosure:(a,i,l,c,d)=>{try{return e().isEnabled()?e().detectStaleClosure(a,i,l,c,d):[]}catch{return[]}},trackStaleClosureWarning:a=>{try{e().isEnabled()&&e().trackStaleClosureWarning(a)}catch{}},trackModalOpen:a=>{try{e().isEnabled()&&e().trackModalOpen(a)}catch{}},trackModalClose:(a,i)=>{try{e().isEnabled()&&e().trackModalClose(a,i)}catch{}},trackModalStateChange:a=>{try{e().isEnabled()&&e().trackModalStateChange(a)}catch{}},trackNestedContext:a=>{try{return e().isEnabled()?e().trackNestedContext(a):""}catch{return""}},trackNestedContextAccess:(a,i)=>{try{e().isEnabled()&&e().trackNestedContextAccess(a,i)}catch{}},trackComputedProperty:(a,i,l,c,d,f,h)=>{try{e().isEnabled()&&e().trackComputedProperty(a,i,l,c,d,f,h)}catch{}},trackComputedRecalc:(a,i,l,c,d,f,h)=>{try{e().isEnabled()&&e().trackComputedRecalc(a,i,l,c,d,f,h)}catch{}},setNamedActionDefinitions:a=>{try{e().isEnabled()&&e().setNamedActionDefinitions(a)}catch{}},trackNamedActionRef:a=>{try{e().isEnabled()&&e().trackNamedActionRef(a)}catch{}}};s.devTools=n,be.log("G7Core.devTools 인터페이스 초기화 완료")}let Lo=null;function mx(){const s=window.G7Core;return s?.__devtools?Promise.resolve(s.__devtools):Lo||(Lo=new Promise((e,n)=>{const a=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 번들 로드 실패: ${a}`)),{once:!0});return}const d=document.createElement("script");d.id=i,d.src=a,d.async=!1,d.addEventListener("load",l,{once:!0}),d.addEventListener("error",()=>{Lo=null,n(new Error(`DevTools 번들 로드 실패: ${a}`))},{once:!0}),document.head.appendChild(d)}),Lo)}function yx(){const s=window.G7Core;if(!s){be.warn("G7Core가 초기화되지 않았습니다.");return}const e=Ma.getInstance();if(e.initialize(),!e.isEnabled()){window.G7DevTools={isEnabled:()=>!1,enable:()=>{be.log("환경설정 > 고급 설정 > 디버그 모드를 켜세요")}},hd(),be.log("G7DevTools 비활성화됨 (디버그 모드 꺼짐)");return}bx(s,e)}async function bx(s,e){let n;try{n=await mx()}catch(h){be.warn("DevTools 번들 로드 실패 — 최소 API 로 폴백:",h),window.G7DevTools={isEnabled:()=>!1,enable:()=>{}},hd();return}const{DiagnosticEngine:a,getServerConnector:i,getStyleTracker:l}=n;gx(),hd();try{l().enable(),be.log("StyleTracker 활성화됨")}catch(h){be.warn("StyleTracker 활성화 실패:",h)}const c=new a,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){be.warn("DataBindingEngine이 없습니다.");return}return m.evaluateExpression(h,e.getState())},getCacheStats:()=>e.getCacheStats(),clearStats:()=>{e.resetCacheStats(),be.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,be.log("G7DevTools 전역 객체 초기화 완료 (window.G7DevTools)"),vx(n.DevToolsPanel)}function vx(s){if(document.getElementById("g7-devtools-root")){be.log("DevToolsPanel 이미 렌더링됨");return}const e=document.createElement("div");e.id="g7-devtools-root",document.body.appendChild(e);try{dd.createRoot(e).render(Ye.createElement(s)),be.log("DevToolsPanel UI 렌더링 완료")}catch(n){be.error("DevToolsPanel UI 렌더링 실패:",n)}}const Ze=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 Mo=!1;const $o=[];async function Sx(s){try{Ze.log("템플릿 메타데이터 로드 중...",s);const e=s.split("-").map(a=>a.split("_").map(i=>i.charAt(0).toUpperCase()+i.slice(1)).join("")).join(""),n=window[e];return n?.templateMetadata?(Ze.log("템플릿 메타데이터 로드 완료 (전역 변수)",n.templateMetadata),n.templateMetadata):(Ze.warn(`템플릿 번들에 메타데이터가 없습니다. 전역 변수: ${e}`),{identifier:s,locales:["ko","en"],name:{ko:s,en:s},description:{ko:"",en:""},version:"1.0.0",type:"admin"})}catch(e){return Ze.error("템플릿 메타데이터 로드 실패",e),{identifier:s,locales:["ko","en"],name:{ko:s,en:s},description:{ko:"",en:""},version:"1.0.0",type:"admin"}}}function Yy(){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 No(s){try{if(Ze.log("템플릿 엔진 초기화 시작",s),ae.isInitialized)throw new Error("템플릿 엔진이 이미 초기화되었습니다. destroyTemplate()을 먼저 호출하세요.");if(!s.templateId)throw new DA;Mo=s.debug??!1,typeof window<"u"&&(window.G7Config||(window.G7Config={}),window.G7Config.debug=Mo),yx(),ae.templateId=s.templateId,ae.locale=s.locale||"ko",Ze.log("엔진 인스턴스 생성 중..."),ae.registry=yr.getInstance(),ae.bindingEngine=new Tn,ae.translationEngine=xa.getInstance(),s.cacheVersion!==void 0&&s.cacheVersion>0&&ae.translationEngine.setCacheVersion(s.cacheVersion),ae.translationContext={templateId:s.templateId,locale:ae.locale},ae.actionDispatcher=new vo({},ae.translationEngine,ae.translationContext),FC(ae.actionDispatcher),Ze.log("다국어 파일 로드 중...",s.templateId,ae.locale);const e="en",n=[ae.translationEngine.loadTranslations(s.templateId,ae.locale).then(()=>{Ze.log(`다국어 파일 로드 완료: ${ae.locale}`)}).catch(a=>{Ze.warn(`다국어 파일 로드 실패 (${ae.locale}):`,a instanceof Error?a.message:a)})];ae.locale!==e&&n.push(ae.translationEngine.loadTranslations(s.templateId,e).then(()=>{Ze.log(`폴백 다국어 파일 로드 완료: ${e}`)}).catch(a=>{Ze.warn(`폴백 다국어 파일 로드 실패 (${e}):`,a instanceof Error?a.message:a)})),await Promise.allSettled(n),Ze.log("템플릿 메타데이터 로드 중...",s.templateId),ae.templateMetadata=await Sx(s.templateId),ae.isInitialized=!0,Ze.log("템플릿 엔진 초기화 완료 (ComponentRegistry는 별도 로드)")}catch(e){throw Ze.error("템플릿 엔진 초기화 실패",e),ae.isInitialized=!1,ae.registry=null,ae.bindingEngine=null,ae.translationEngine=null,ae.actionDispatcher=null,e}}let Io=null;function Pf(){const s=window.G7Core;return s?.__LayoutEditorChrome?Promise.resolve(s.__LayoutEditorChrome):Io||(Io=new Promise((e,n)=>{const a=window.G7Config?.coreEditorAsset||"/build/core/layout-editor.min.js",i="g7-layout-editor-bundle",l=document.getElementById(i),c=()=>{const f=window.G7Core?.__LayoutEditorChrome;f?e(f):n(new Error("편집기 번들 로드됨 — 그러나 __LayoutEditorChrome 미노출"))};if(window.G7Core=window.G7Core||{},window.G7Core.__onChromeReady=c,l){l.addEventListener("load",c,{once:!0}),l.addEventListener("error",()=>n(new Error(`편집기 번들 로드 실패: ${a}`)),{once:!0});return}const d=document.createElement("script");d.id=i,d.src=a,d.async=!1,d.addEventListener("load",c,{once:!0}),d.addEventListener("error",()=>{Io=null,n(new Error(`편집기 번들 로드 실패: ${a}`))},{once:!0}),document.head.appendChild(d)}),Io)}async function ms(s){try{if(Ze.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=Yy();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||(Ze.log("React Root 생성"),ae.reactRoot=dd.createRoot(e)),typeof window<"u"){const l=qy(window.location.pathname);if(l){Ze.log("레이아웃 편집기 모드 진입",l);let c;try{c=await Pf()}catch(f){Ze.error("레이아웃 편집기 번들 로드 실패",f),If.render(s.containerId,{title:"레이아웃 편집기 로드 실패",message:f instanceof Error?f.message:"편집기 번들을 불러오지 못했습니다.",icon:"fas fa-triangle-exclamation",showStack:!1,showReloadButton:!0,debug:Mo});return}const d=Ye.createElement(c,{templateIdentifier:l.templateIdentifier,initialLocale:ae.locale});ae.reactRoot.render(Ye.createElement(Ec,{translationEngine:ae.translationEngine,translationContext:ae.translationContext,children:Ye.createElement(af,{children:Ye.createElement(cc,{children:Ye.createElement(Of,{children:d})})})}));return}}const a=s.layoutJson.components||[];if(a.length===0){Ze.warn("렌더링할 컴포넌트가 없습니다.");return}const i=s.layoutJson.modals||[];if(Ze.log("modals 배열:",i),Ze.log("modals 개수:",i.length),Ze.log("DynamicRenderer로 렌더링 시작"),ae.reactRoot.render(Ye.createElement(Ec,{translationEngine:ae.translationEngine,translationContext:ae.translationContext},Ye.createElement(af,null,Ye.createElement(cc,null,Ye.createElement(Of,null,[...a.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($m,{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(Py,{key:`modal_${l.id}`,isOpen:f,modalId:l.id,dataSources:l.data_sources,dataContext:ae.currentDataContext,globalStateUpdater:ae.actionDispatcher?.getGlobalStateUpdater(),bindingEngine:ae.bindingEngine,debug:Mo,children:_}):_}))]))))),Ze.log("템플릿 렌더링 완료"),$o.length>0){Ze.log(`대기 중인 데이터 업데이트 ${$o.length}건 적용`);const l=[...$o];$o.length=0;for(const{data:c,options:d}of l)ys(c,d)}}catch(e){throw Ze.error("템플릿 렌더링 실패",e),e}}function ys(s,e){try{if(Ze.log("템플릿 데이터 업데이트 시작",Object.keys(s)),!ae.isInitialized)throw new Error("템플릿 엔진이 초기화되지 않았습니다.");if(!ae.reactRoot||!ae.currentLayoutJson){Ze.log("React 미준비 - 데이터 업데이트 큐잉:",Object.keys(s)),$o.push({data:s,options:e});return}const n=Yy(),a={...ae.currentDataContext._global||{},...s._global||{}},i=ZC(ae.currentDataContext._localInit,s._localInit);ae.currentDataContext={...n,...ae.currentDataContext,...s,_global:a,_localInit:i},a._local!==void 0&&(ae.currentDataContext._local=a._local),a._computed!==void 0&&(ae.currentDataContext._computed=a._computed);const l=ae.currentLayoutJson.components||[],c=ae.currentLayoutJson.modals||[];Ze.log("updateTemplateData - modals 배열:",c),Ze.log("updateTemplateData - modals 개수:",c.length),Ze.log("updateTemplateData - activeModal:",ae.currentDataContext._global?.activeModal);const d=()=>{ae.reactRoot.render(Ye.createElement(Ec,{translationEngine:ae.translationEngine,translationContext:ae.translationContext},Ye.createElement(af,null,Ye.createElement(cc,null,Ye.createElement(Of,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($m,{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(Py,{key:`modal_${f.id}`,isOpen:y,modalId:f.id,dataSources:f.data_sources,dataContext:ae.currentDataContext,globalStateUpdater:ae.actionDispatcher?.getGlobalStateUpdater(),bindingEngine:ae.bindingEngine,debug:Mo,children:L}):L}))])))))};e?.sync?(Ze.log("재렌더링 시작 (sync mode - 즉시 렌더링)"),d()):(Ze.log("재렌더링 시작 (with startTransition)"),N.startTransition(()=>{d()})),Ze.log("템플릿 데이터 업데이트 완료")}catch(n){throw Ze.error("템플릿 데이터 업데이트 실패",n),n}}function Dc(){try{Ze.log("템플릿 정리 시작"),ae.reactRoot&&(Ze.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,Ze.log("템플릿 정리 완료")}catch(s){throw Ze.error("템플릿 정리 실패",s),s}}function ra(){return Object.freeze({...ae})}function Xy(){return ae.actionDispatcher}const jo={initTemplateEngine:No,renderTemplate:ms,updateTemplateData:ys,destroyTemplate:Dc,getState:ra};typeof window<"u"&&(window.G7Core||(window.G7Core={}),window.G7Core.TemplateEngine=jo,px({getState:()=>({translationEngine:ae.translationEngine,translationContext:ae.translationContext,bindingEngine:ae.bindingEngine,actionDispatcher:ae.actionDispatcher,templateMetadata:ae.templateMetadata}),transitionManager:Ur,responsiveManager:mi,webSocketManager:xc}),Ze.log("전역 객체 window.G7Core.TemplateEngine에 노출됨"));const qr=Object.freeze(Object.defineProperty({__proto__:null,DataSourceManager:xr,LayoutLoader:Rf,TemplateApp:Do,TemplateEngine:jo,default:jo,destroyTemplate:Dc,getActionDispatcher:Xy,getState:ra,initTemplateApp:Uf,initTemplateEngine:No,loadLayoutEditorBundle:Pf,renderTemplate:ms,updateTemplateData:ys},Symbol.toStringTag,{value:"Module"}));Xt.DataSourceManager=xr,Xt.LayoutLoader=Rf,Xt.TemplateApp=Do,Xt.TemplateEngine=jo,Xt.default=jo,Xt.destroyTemplate=Dc,Xt.getActionDispatcher=Xy,Xt.getState=ra,Xt.initTemplateApp=Uf,Xt.initTemplateEngine=No,Xt.loadLayoutEditorBundle=Pf,Xt.renderTemplate=ms,Xt.updateTemplateData=ys,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 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||{}); diff --git a/public/install/assets/vendor/font-awesome/6.5.1/LICENSE.txt b/public/install/assets/vendor/font-awesome/6.5.1/LICENSE.txt new file mode 100644 index 00000000..39e18e3d --- /dev/null +++ b/public/install/assets/vendor/font-awesome/6.5.1/LICENSE.txt @@ -0,0 +1,165 @@ +Fonticons, Inc. (https://fontawesome.com) + +-------------------------------------------------------------------------------- + +Font Awesome Free License + +Font Awesome Free is free, open source, and GPL friendly. You can use it for +commercial projects, open source projects, or really almost whatever you want. +Full Font Awesome Free license: https://fontawesome.com/license/free. + +-------------------------------------------------------------------------------- + +# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) + +The Font Awesome Free download is licensed under a Creative Commons +Attribution 4.0 International License and applies to all icons packaged +as SVG and JS file types. + +-------------------------------------------------------------------------------- + +# Fonts: SIL OFL 1.1 License + +In the Font Awesome Free download, the SIL OFL license applies to all icons +packaged as web and desktop font files. + +Copyright (c) 2023 Fonticons, Inc. (https://fontawesome.com) +with Reserved Font Name: "Font Awesome". + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +SIL OPEN FONT LICENSE +Version 1.1 - 26 February 2007 + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting — in part or in whole — any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +-------------------------------------------------------------------------------- + +# Code: MIT License (https://opensource.org/licenses/MIT) + +In the Font Awesome Free download, the MIT license applies to all non-font and +non-icon files. + +Copyright 2023 Fonticons, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in the +Software without restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +-------------------------------------------------------------------------------- + +# Attribution + +Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font +Awesome Free files already contain embedded comments with sufficient +attribution, so you shouldn't need to do anything additional when using these +files normally. + +We've kept attribution comments terse, so we ask that you do not actively work +to remove them from files, especially code. They're a great way for folks to +learn about Font Awesome. + +-------------------------------------------------------------------------------- + +# Brand Icons + +All brand icons are trademarks of their respective owners. The use of these +trademarks does not indicate endorsement of the trademark holder by Font +Awesome, nor vice versa. **Please do not use brand logos for any purpose except +to represent the company, product, or service to which they refer.** diff --git a/public/install/assets/vendor/font-awesome/6.5.1/css/all.inlined.css b/public/install/assets/vendor/font-awesome/6.5.1/css/all.inlined.css new file mode 100644 index 00000000..d499cf3d --- /dev/null +++ b/public/install/assets/vendor/font-awesome/6.5.1/css/all.inlined.css @@ -0,0 +1,9 @@ +/*! + * Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + * Copyright 2023 Fonticons, Inc. + */ +.fa{font-family:var(--fa-style-family,"Font Awesome 6 Free");font-weight:var(--fa-style,900)}.fa,.fa-brands,.fa-classic,.fa-regular,.fa-sharp,.fa-solid,.fab,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:var(--fa-display,inline-block);font-style:normal;font-variant:normal;line-height:1;text-rendering:auto}.fa-classic,.fa-regular,.fa-solid,.far,.fas{font-family:"Font Awesome 6 Free"}.fa-brands,.fab{font-family:"Font Awesome 6 Brands"}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.08333em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.07143em;vertical-align:.05357em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.04167em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:var(--fa-li-margin,2.5em);padding-left:0}.fa-ul>li{position:relative}.fa-li{left:calc(var(--fa-li-width, 2em)*-1);position:absolute;text-align:center;width:var(--fa-li-width,2em);line-height:inherit}.fa-border{border-radius:var(--fa-border-radius,.1em);border:var(--fa-border-width,.08em) var(--fa-border-style,solid) var(--fa-border-color,#eee);padding:var(--fa-border-padding,.2em .25em .15em)}.fa-pull-left{float:left;margin-right:var(--fa-pull-margin,.3em)}.fa-pull-right{float:right;margin-left:var(--fa-pull-margin,.3em)}.fa-beat{-webkit-animation-name:fa-beat;animation-name:fa-beat;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-bounce{-webkit-animation-name:fa-bounce;animation-name:fa-bounce;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{-webkit-animation-name:fa-fade;animation-name:fa-fade;-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade,.fa-fade{-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s)}.fa-beat-fade{-webkit-animation-name:fa-beat-fade;animation-name:fa-beat-fade;-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{-webkit-animation-name:fa-flip;animation-name:fa-flip;-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-shake{-webkit-animation-name:fa-shake;animation-name:fa-shake;-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,linear);animation-timing-function:var(--fa-animation-timing,linear)}.fa-shake,.fa-spin{-webkit-animation-delay:var(--fa-animation-delay,0s);animation-delay:var(--fa-animation-delay,0s);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal)}.fa-spin{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-duration:var(--fa-animation-duration,2s);animation-duration:var(--fa-animation-duration,2s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,linear);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin-reverse{--fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,steps(8));animation-timing-function:var(--fa-animation-timing,steps(8))}@media (prefers-reduced-motion:reduce){.fa-beat,.fa-beat-fade,.fa-bounce,.fa-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{-webkit-animation-delay:-1ms;animation-delay:-1ms;-webkit-animation-duration:1ms;animation-duration:1ms;-webkit-animation-iteration-count:1;animation-iteration-count:1;-webkit-transition-delay:0s;transition-delay:0s;-webkit-transition-duration:0s;transition-duration:0s}}@-webkit-keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(--fa-beat-scale,1.25));transform:scale(var(--fa-beat-scale,1.25))}}@keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(--fa-beat-scale,1.25));transform:scale(var(--fa-beat-scale,1.25))}}@-webkit-keyframes fa-bounce{0%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}10%{-webkit-transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em));transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em));transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}to{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}@keyframes fa-bounce{0%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}10%{-webkit-transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em));transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em));transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}to{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}@-webkit-keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@-webkit-keyframes fa-beat-fade{0%,to{opacity:var(--fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(--fa-beat-fade-scale,1.125));transform:scale(var(--fa-beat-fade-scale,1.125))}}@keyframes fa-beat-fade{0%,to{opacity:var(--fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(--fa-beat-fade-scale,1.125));transform:scale(var(--fa-beat-fade-scale,1.125))}}@-webkit-keyframes fa-flip{50%{-webkit-transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg));transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@keyframes fa-flip{50%{-webkit-transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg));transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@-webkit-keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}8%,24%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}40%,to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}8%,24%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}40%,to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}.fa-rotate-by{-webkit-transform:rotate(var(--fa-rotate-angle,none));transform:rotate(var(--fa-rotate-angle,none))}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%;z-index:var(--fa-stack-z-index,auto)}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:var(--fa-inverse,#fff)} + +.fa-0:before{content:"\30"}.fa-1:before{content:"\31"}.fa-2:before{content:"\32"}.fa-3:before{content:"\33"}.fa-4:before{content:"\34"}.fa-5:before{content:"\35"}.fa-6:before{content:"\36"}.fa-7:before{content:"\37"}.fa-8:before{content:"\38"}.fa-9:before{content:"\39"}.fa-fill-drip:before{content:"\f576"}.fa-arrows-to-circle:before{content:"\e4bd"}.fa-chevron-circle-right:before,.fa-circle-chevron-right:before{content:"\f138"}.fa-at:before{content:"\40"}.fa-trash-alt:before,.fa-trash-can:before{content:"\f2ed"}.fa-text-height:before{content:"\f034"}.fa-user-times:before,.fa-user-xmark:before{content:"\f235"}.fa-stethoscope:before{content:"\f0f1"}.fa-comment-alt:before,.fa-message:before{content:"\f27a"}.fa-info:before{content:"\f129"}.fa-compress-alt:before,.fa-down-left-and-up-right-to-center:before{content:"\f422"}.fa-explosion:before{content:"\e4e9"}.fa-file-alt:before,.fa-file-lines:before,.fa-file-text:before{content:"\f15c"}.fa-wave-square:before{content:"\f83e"}.fa-ring:before{content:"\f70b"}.fa-building-un:before{content:"\e4d9"}.fa-dice-three:before{content:"\f527"}.fa-calendar-alt:before,.fa-calendar-days:before{content:"\f073"}.fa-anchor-circle-check:before{content:"\e4aa"}.fa-building-circle-arrow-right:before{content:"\e4d1"}.fa-volleyball-ball:before,.fa-volleyball:before{content:"\f45f"}.fa-arrows-up-to-line:before{content:"\e4c2"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-circle-minus:before,.fa-minus-circle:before{content:"\f056"}.fa-door-open:before{content:"\f52b"}.fa-right-from-bracket:before,.fa-sign-out-alt:before{content:"\f2f5"}.fa-atom:before{content:"\f5d2"}.fa-soap:before{content:"\e06e"}.fa-heart-music-camera-bolt:before,.fa-icons:before{content:"\f86d"}.fa-microphone-alt-slash:before,.fa-microphone-lines-slash:before{content:"\f539"}.fa-bridge-circle-check:before{content:"\e4c9"}.fa-pump-medical:before{content:"\e06a"}.fa-fingerprint:before{content:"\f577"}.fa-hand-point-right:before{content:"\f0a4"}.fa-magnifying-glass-location:before,.fa-search-location:before{content:"\f689"}.fa-forward-step:before,.fa-step-forward:before{content:"\f051"}.fa-face-smile-beam:before,.fa-smile-beam:before{content:"\f5b8"}.fa-flag-checkered:before{content:"\f11e"}.fa-football-ball:before,.fa-football:before{content:"\f44e"}.fa-school-circle-exclamation:before{content:"\e56c"}.fa-crop:before{content:"\f125"}.fa-angle-double-down:before,.fa-angles-down:before{content:"\f103"}.fa-users-rectangle:before{content:"\e594"}.fa-people-roof:before{content:"\e537"}.fa-people-line:before{content:"\e534"}.fa-beer-mug-empty:before,.fa-beer:before{content:"\f0fc"}.fa-diagram-predecessor:before{content:"\e477"}.fa-arrow-up-long:before,.fa-long-arrow-up:before{content:"\f176"}.fa-burn:before,.fa-fire-flame-simple:before{content:"\f46a"}.fa-male:before,.fa-person:before{content:"\f183"}.fa-laptop:before{content:"\f109"}.fa-file-csv:before{content:"\f6dd"}.fa-menorah:before{content:"\f676"}.fa-truck-plane:before{content:"\e58f"}.fa-record-vinyl:before{content:"\f8d9"}.fa-face-grin-stars:before,.fa-grin-stars:before{content:"\f587"}.fa-bong:before{content:"\f55c"}.fa-pastafarianism:before,.fa-spaghetti-monster-flying:before{content:"\f67b"}.fa-arrow-down-up-across-line:before{content:"\e4af"}.fa-spoon:before,.fa-utensil-spoon:before{content:"\f2e5"}.fa-jar-wheat:before{content:"\e517"}.fa-envelopes-bulk:before,.fa-mail-bulk:before{content:"\f674"}.fa-file-circle-exclamation:before{content:"\e4eb"}.fa-circle-h:before,.fa-hospital-symbol:before{content:"\f47e"}.fa-pager:before{content:"\f815"}.fa-address-book:before,.fa-contact-book:before{content:"\f2b9"}.fa-strikethrough:before{content:"\f0cc"}.fa-k:before{content:"\4b"}.fa-landmark-flag:before{content:"\e51c"}.fa-pencil-alt:before,.fa-pencil:before{content:"\f303"}.fa-backward:before{content:"\f04a"}.fa-caret-right:before{content:"\f0da"}.fa-comments:before{content:"\f086"}.fa-file-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-code-pull-request:before{content:"\e13c"}.fa-clipboard-list:before{content:"\f46d"}.fa-truck-loading:before,.fa-truck-ramp-box:before{content:"\f4de"}.fa-user-check:before{content:"\f4fc"}.fa-vial-virus:before{content:"\e597"}.fa-sheet-plastic:before{content:"\e571"}.fa-blog:before{content:"\f781"}.fa-user-ninja:before{content:"\f504"}.fa-person-arrow-up-from-line:before{content:"\e539"}.fa-scroll-torah:before,.fa-torah:before{content:"\f6a0"}.fa-broom-ball:before,.fa-quidditch-broom-ball:before,.fa-quidditch:before{content:"\f458"}.fa-toggle-off:before{content:"\f204"}.fa-archive:before,.fa-box-archive:before{content:"\f187"}.fa-person-drowning:before{content:"\e545"}.fa-arrow-down-9-1:before,.fa-sort-numeric-desc:before,.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-face-grin-tongue-squint:before,.fa-grin-tongue-squint:before{content:"\f58a"}.fa-spray-can:before{content:"\f5bd"}.fa-truck-monster:before{content:"\f63b"}.fa-w:before{content:"\57"}.fa-earth-africa:before,.fa-globe-africa:before{content:"\f57c"}.fa-rainbow:before{content:"\f75b"}.fa-circle-notch:before{content:"\f1ce"}.fa-tablet-alt:before,.fa-tablet-screen-button:before{content:"\f3fa"}.fa-paw:before{content:"\f1b0"}.fa-cloud:before{content:"\f0c2"}.fa-trowel-bricks:before{content:"\e58a"}.fa-face-flushed:before,.fa-flushed:before{content:"\f579"}.fa-hospital-user:before{content:"\f80d"}.fa-tent-arrow-left-right:before{content:"\e57f"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-binoculars:before{content:"\f1e5"}.fa-microphone-slash:before{content:"\f131"}.fa-box-tissue:before{content:"\e05b"}.fa-motorcycle:before{content:"\f21c"}.fa-bell-concierge:before,.fa-concierge-bell:before{content:"\f562"}.fa-pen-ruler:before,.fa-pencil-ruler:before{content:"\f5ae"}.fa-people-arrows-left-right:before,.fa-people-arrows:before{content:"\e068"}.fa-mars-and-venus-burst:before{content:"\e523"}.fa-caret-square-right:before,.fa-square-caret-right:before{content:"\f152"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-sun-plant-wilt:before{content:"\e57a"}.fa-toilets-portable:before{content:"\e584"}.fa-hockey-puck:before{content:"\f453"}.fa-table:before{content:"\f0ce"}.fa-magnifying-glass-arrow-right:before{content:"\e521"}.fa-digital-tachograph:before,.fa-tachograph-digital:before{content:"\f566"}.fa-users-slash:before{content:"\e073"}.fa-clover:before{content:"\e139"}.fa-mail-reply:before,.fa-reply:before{content:"\f3e5"}.fa-star-and-crescent:before{content:"\f699"}.fa-house-fire:before{content:"\e50c"}.fa-minus-square:before,.fa-square-minus:before{content:"\f146"}.fa-helicopter:before{content:"\f533"}.fa-compass:before{content:"\f14e"}.fa-caret-square-down:before,.fa-square-caret-down:before{content:"\f150"}.fa-file-circle-question:before{content:"\e4ef"}.fa-laptop-code:before{content:"\f5fc"}.fa-swatchbook:before{content:"\f5c3"}.fa-prescription-bottle:before{content:"\f485"}.fa-bars:before,.fa-navicon:before{content:"\f0c9"}.fa-people-group:before{content:"\e533"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-heart-broken:before,.fa-heart-crack:before{content:"\f7a9"}.fa-external-link-square-alt:before,.fa-square-up-right:before{content:"\f360"}.fa-face-kiss-beam:before,.fa-kiss-beam:before{content:"\f597"}.fa-film:before{content:"\f008"}.fa-ruler-horizontal:before{content:"\f547"}.fa-people-robbery:before{content:"\e536"}.fa-lightbulb:before{content:"\f0eb"}.fa-caret-left:before{content:"\f0d9"}.fa-circle-exclamation:before,.fa-exclamation-circle:before{content:"\f06a"}.fa-school-circle-xmark:before{content:"\e56d"}.fa-arrow-right-from-bracket:before,.fa-sign-out:before{content:"\f08b"}.fa-chevron-circle-down:before,.fa-circle-chevron-down:before{content:"\f13a"}.fa-unlock-alt:before,.fa-unlock-keyhole:before{content:"\f13e"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-headphones-alt:before,.fa-headphones-simple:before{content:"\f58f"}.fa-sitemap:before{content:"\f0e8"}.fa-circle-dollar-to-slot:before,.fa-donate:before{content:"\f4b9"}.fa-memory:before{content:"\f538"}.fa-road-spikes:before{content:"\e568"}.fa-fire-burner:before{content:"\e4f1"}.fa-flag:before{content:"\f024"}.fa-hanukiah:before{content:"\f6e6"}.fa-feather:before{content:"\f52d"}.fa-volume-down:before,.fa-volume-low:before{content:"\f027"}.fa-comment-slash:before{content:"\f4b3"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-compress:before{content:"\f066"}.fa-wheat-alt:before,.fa-wheat-awn:before{content:"\e2cd"}.fa-ankh:before{content:"\f644"}.fa-hands-holding-child:before{content:"\e4fa"}.fa-asterisk:before{content:"\2a"}.fa-check-square:before,.fa-square-check:before{content:"\f14a"}.fa-peseta-sign:before{content:"\e221"}.fa-header:before,.fa-heading:before{content:"\f1dc"}.fa-ghost:before{content:"\f6e2"}.fa-list-squares:before,.fa-list:before{content:"\f03a"}.fa-phone-square-alt:before,.fa-square-phone-flip:before{content:"\f87b"}.fa-cart-plus:before{content:"\f217"}.fa-gamepad:before{content:"\f11b"}.fa-circle-dot:before,.fa-dot-circle:before{content:"\f192"}.fa-dizzy:before,.fa-face-dizzy:before{content:"\f567"}.fa-egg:before{content:"\f7fb"}.fa-house-medical-circle-xmark:before{content:"\e513"}.fa-campground:before{content:"\f6bb"}.fa-folder-plus:before{content:"\f65e"}.fa-futbol-ball:before,.fa-futbol:before,.fa-soccer-ball:before{content:"\f1e3"}.fa-paint-brush:before,.fa-paintbrush:before{content:"\f1fc"}.fa-lock:before{content:"\f023"}.fa-gas-pump:before{content:"\f52f"}.fa-hot-tub-person:before,.fa-hot-tub:before{content:"\f593"}.fa-map-location:before,.fa-map-marked:before{content:"\f59f"}.fa-house-flood-water:before{content:"\e50e"}.fa-tree:before{content:"\f1bb"}.fa-bridge-lock:before{content:"\e4cc"}.fa-sack-dollar:before{content:"\f81d"}.fa-edit:before,.fa-pen-to-square:before{content:"\f044"}.fa-car-side:before{content:"\f5e4"}.fa-share-alt:before,.fa-share-nodes:before{content:"\f1e0"}.fa-heart-circle-minus:before{content:"\e4ff"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-microscope:before{content:"\f610"}.fa-sink:before{content:"\e06d"}.fa-bag-shopping:before,.fa-shopping-bag:before{content:"\f290"}.fa-arrow-down-z-a:before,.fa-sort-alpha-desc:before,.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-mitten:before{content:"\f7b5"}.fa-person-rays:before{content:"\e54d"}.fa-users:before{content:"\f0c0"}.fa-eye-slash:before{content:"\f070"}.fa-flask-vial:before{content:"\e4f3"}.fa-hand-paper:before,.fa-hand:before{content:"\f256"}.fa-om:before{content:"\f679"}.fa-worm:before{content:"\e599"}.fa-house-circle-xmark:before{content:"\e50b"}.fa-plug:before{content:"\f1e6"}.fa-chevron-up:before{content:"\f077"}.fa-hand-spock:before{content:"\f259"}.fa-stopwatch:before{content:"\f2f2"}.fa-face-kiss:before,.fa-kiss:before{content:"\f596"}.fa-bridge-circle-xmark:before{content:"\e4cb"}.fa-face-grin-tongue:before,.fa-grin-tongue:before{content:"\f589"}.fa-chess-bishop:before{content:"\f43a"}.fa-face-grin-wink:before,.fa-grin-wink:before{content:"\f58c"}.fa-deaf:before,.fa-deafness:before,.fa-ear-deaf:before,.fa-hard-of-hearing:before{content:"\f2a4"}.fa-road-circle-check:before{content:"\e564"}.fa-dice-five:before{content:"\f523"}.fa-rss-square:before,.fa-square-rss:before{content:"\f143"}.fa-land-mine-on:before{content:"\e51b"}.fa-i-cursor:before{content:"\f246"}.fa-stamp:before{content:"\f5bf"}.fa-stairs:before{content:"\e289"}.fa-i:before{content:"\49"}.fa-hryvnia-sign:before,.fa-hryvnia:before{content:"\f6f2"}.fa-pills:before{content:"\f484"}.fa-face-grin-wide:before,.fa-grin-alt:before{content:"\f581"}.fa-tooth:before{content:"\f5c9"}.fa-v:before{content:"\56"}.fa-bangladeshi-taka-sign:before{content:"\e2e6"}.fa-bicycle:before{content:"\f206"}.fa-rod-asclepius:before,.fa-rod-snake:before,.fa-staff-aesculapius:before,.fa-staff-snake:before{content:"\e579"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-ambulance:before,.fa-truck-medical:before{content:"\f0f9"}.fa-wheat-awn-circle-exclamation:before{content:"\e598"}.fa-snowman:before{content:"\f7d0"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-road-barrier:before{content:"\e562"}.fa-school:before{content:"\f549"}.fa-igloo:before{content:"\f7ae"}.fa-joint:before{content:"\f595"}.fa-angle-right:before{content:"\f105"}.fa-horse:before{content:"\f6f0"}.fa-q:before{content:"\51"}.fa-g:before{content:"\47"}.fa-notes-medical:before{content:"\f481"}.fa-temperature-2:before,.fa-temperature-half:before,.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-dong-sign:before{content:"\e169"}.fa-capsules:before{content:"\f46b"}.fa-poo-bolt:before,.fa-poo-storm:before{content:"\f75a"}.fa-face-frown-open:before,.fa-frown-open:before{content:"\f57a"}.fa-hand-point-up:before{content:"\f0a6"}.fa-money-bill:before{content:"\f0d6"}.fa-bookmark:before{content:"\f02e"}.fa-align-justify:before{content:"\f039"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-helmet-un:before{content:"\e503"}.fa-bullseye:before{content:"\f140"}.fa-bacon:before{content:"\f7e5"}.fa-hand-point-down:before{content:"\f0a7"}.fa-arrow-up-from-bracket:before{content:"\e09a"}.fa-folder-blank:before,.fa-folder:before{content:"\f07b"}.fa-file-medical-alt:before,.fa-file-waveform:before{content:"\f478"}.fa-radiation:before{content:"\f7b9"}.fa-chart-simple:before{content:"\e473"}.fa-mars-stroke:before{content:"\f229"}.fa-vial:before{content:"\f492"}.fa-dashboard:before,.fa-gauge-med:before,.fa-gauge:before,.fa-tachometer-alt-average:before{content:"\f624"}.fa-magic-wand-sparkles:before,.fa-wand-magic-sparkles:before{content:"\e2ca"}.fa-e:before{content:"\45"}.fa-pen-alt:before,.fa-pen-clip:before{content:"\f305"}.fa-bridge-circle-exclamation:before{content:"\e4ca"}.fa-user:before{content:"\f007"}.fa-school-circle-check:before{content:"\e56b"}.fa-dumpster:before{content:"\f793"}.fa-shuttle-van:before,.fa-van-shuttle:before{content:"\f5b6"}.fa-building-user:before{content:"\e4da"}.fa-caret-square-left:before,.fa-square-caret-left:before{content:"\f191"}.fa-highlighter:before{content:"\f591"}.fa-key:before{content:"\f084"}.fa-bullhorn:before{content:"\f0a1"}.fa-globe:before{content:"\f0ac"}.fa-synagogue:before{content:"\f69b"}.fa-person-half-dress:before{content:"\e548"}.fa-road-bridge:before{content:"\e563"}.fa-location-arrow:before{content:"\f124"}.fa-c:before{content:"\43"}.fa-tablet-button:before{content:"\f10a"}.fa-building-lock:before{content:"\e4d6"}.fa-pizza-slice:before{content:"\f818"}.fa-money-bill-wave:before{content:"\f53a"}.fa-area-chart:before,.fa-chart-area:before{content:"\f1fe"}.fa-house-flag:before{content:"\e50d"}.fa-person-circle-minus:before{content:"\e540"}.fa-ban:before,.fa-cancel:before{content:"\f05e"}.fa-camera-rotate:before{content:"\e0d8"}.fa-air-freshener:before,.fa-spray-can-sparkles:before{content:"\f5d0"}.fa-star:before{content:"\f005"}.fa-repeat:before{content:"\f363"}.fa-cross:before{content:"\f654"}.fa-box:before{content:"\f466"}.fa-venus-mars:before{content:"\f228"}.fa-arrow-pointer:before,.fa-mouse-pointer:before{content:"\f245"}.fa-expand-arrows-alt:before,.fa-maximize:before{content:"\f31e"}.fa-charging-station:before{content:"\f5e7"}.fa-shapes:before,.fa-triangle-circle-square:before{content:"\f61f"}.fa-random:before,.fa-shuffle:before{content:"\f074"}.fa-person-running:before,.fa-running:before{content:"\f70c"}.fa-mobile-retro:before{content:"\e527"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-spider:before{content:"\f717"}.fa-hands-bound:before{content:"\e4f9"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-plane-circle-exclamation:before{content:"\e556"}.fa-x-ray:before{content:"\f497"}.fa-spell-check:before{content:"\f891"}.fa-slash:before{content:"\f715"}.fa-computer-mouse:before,.fa-mouse:before{content:"\f8cc"}.fa-arrow-right-to-bracket:before,.fa-sign-in:before{content:"\f090"}.fa-shop-slash:before,.fa-store-alt-slash:before{content:"\e070"}.fa-server:before{content:"\f233"}.fa-virus-covid-slash:before{content:"\e4a9"}.fa-shop-lock:before{content:"\e4a5"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-blender-phone:before{content:"\f6b6"}.fa-building-wheat:before{content:"\e4db"}.fa-person-breastfeeding:before{content:"\e53a"}.fa-right-to-bracket:before,.fa-sign-in-alt:before{content:"\f2f6"}.fa-venus:before{content:"\f221"}.fa-passport:before{content:"\f5ab"}.fa-heart-pulse:before,.fa-heartbeat:before{content:"\f21e"}.fa-people-carry-box:before,.fa-people-carry:before{content:"\f4ce"}.fa-temperature-high:before{content:"\f769"}.fa-microchip:before{content:"\f2db"}.fa-crown:before{content:"\f521"}.fa-weight-hanging:before{content:"\f5cd"}.fa-xmarks-lines:before{content:"\e59a"}.fa-file-prescription:before{content:"\f572"}.fa-weight-scale:before,.fa-weight:before{content:"\f496"}.fa-user-friends:before,.fa-user-group:before{content:"\f500"}.fa-arrow-up-a-z:before,.fa-sort-alpha-up:before{content:"\f15e"}.fa-chess-knight:before{content:"\f441"}.fa-face-laugh-squint:before,.fa-laugh-squint:before{content:"\f59b"}.fa-wheelchair:before{content:"\f193"}.fa-arrow-circle-up:before,.fa-circle-arrow-up:before{content:"\f0aa"}.fa-toggle-on:before{content:"\f205"}.fa-person-walking:before,.fa-walking:before{content:"\f554"}.fa-l:before{content:"\4c"}.fa-fire:before{content:"\f06d"}.fa-bed-pulse:before,.fa-procedures:before{content:"\f487"}.fa-shuttle-space:before,.fa-space-shuttle:before{content:"\f197"}.fa-face-laugh:before,.fa-laugh:before{content:"\f599"}.fa-folder-open:before{content:"\f07c"}.fa-heart-circle-plus:before{content:"\e500"}.fa-code-fork:before{content:"\e13b"}.fa-city:before{content:"\f64f"}.fa-microphone-alt:before,.fa-microphone-lines:before{content:"\f3c9"}.fa-pepper-hot:before{content:"\f816"}.fa-unlock:before{content:"\f09c"}.fa-colon-sign:before{content:"\e140"}.fa-headset:before{content:"\f590"}.fa-store-slash:before{content:"\e071"}.fa-road-circle-xmark:before{content:"\e566"}.fa-user-minus:before{content:"\f503"}.fa-mars-stroke-up:before,.fa-mars-stroke-v:before{content:"\f22a"}.fa-champagne-glasses:before,.fa-glass-cheers:before{content:"\f79f"}.fa-clipboard:before{content:"\f328"}.fa-house-circle-exclamation:before{content:"\e50a"}.fa-file-arrow-up:before,.fa-file-upload:before{content:"\f574"}.fa-wifi-3:before,.fa-wifi-strong:before,.fa-wifi:before{content:"\f1eb"}.fa-bath:before,.fa-bathtub:before{content:"\f2cd"}.fa-underline:before{content:"\f0cd"}.fa-user-edit:before,.fa-user-pen:before{content:"\f4ff"}.fa-signature:before{content:"\f5b7"}.fa-stroopwafel:before{content:"\f551"}.fa-bold:before{content:"\f032"}.fa-anchor-lock:before{content:"\e4ad"}.fa-building-ngo:before{content:"\e4d7"}.fa-manat-sign:before{content:"\e1d5"}.fa-not-equal:before{content:"\f53e"}.fa-border-style:before,.fa-border-top-left:before{content:"\f853"}.fa-map-location-dot:before,.fa-map-marked-alt:before{content:"\f5a0"}.fa-jedi:before{content:"\f669"}.fa-poll:before,.fa-square-poll-vertical:before{content:"\f681"}.fa-mug-hot:before{content:"\f7b6"}.fa-battery-car:before,.fa-car-battery:before{content:"\f5df"}.fa-gift:before{content:"\f06b"}.fa-dice-two:before{content:"\f528"}.fa-chess-queen:before{content:"\f445"}.fa-glasses:before{content:"\f530"}.fa-chess-board:before{content:"\f43c"}.fa-building-circle-check:before{content:"\e4d2"}.fa-person-chalkboard:before{content:"\e53d"}.fa-mars-stroke-h:before,.fa-mars-stroke-right:before{content:"\f22b"}.fa-hand-back-fist:before,.fa-hand-rock:before{content:"\f255"}.fa-caret-square-up:before,.fa-square-caret-up:before{content:"\f151"}.fa-cloud-showers-water:before{content:"\e4e4"}.fa-bar-chart:before,.fa-chart-bar:before{content:"\f080"}.fa-hands-bubbles:before,.fa-hands-wash:before{content:"\e05e"}.fa-less-than-equal:before{content:"\f537"}.fa-train:before{content:"\f238"}.fa-eye-low-vision:before,.fa-low-vision:before{content:"\f2a8"}.fa-crow:before{content:"\f520"}.fa-sailboat:before{content:"\e445"}.fa-window-restore:before{content:"\f2d2"}.fa-plus-square:before,.fa-square-plus:before{content:"\f0fe"}.fa-torii-gate:before{content:"\f6a1"}.fa-frog:before{content:"\f52e"}.fa-bucket:before{content:"\e4cf"}.fa-image:before{content:"\f03e"}.fa-microphone:before{content:"\f130"}.fa-cow:before{content:"\f6c8"}.fa-caret-up:before{content:"\f0d8"}.fa-screwdriver:before{content:"\f54a"}.fa-folder-closed:before{content:"\e185"}.fa-house-tsunami:before{content:"\e515"}.fa-square-nfi:before{content:"\e576"}.fa-arrow-up-from-ground-water:before{content:"\e4b5"}.fa-glass-martini-alt:before,.fa-martini-glass:before{content:"\f57b"}.fa-rotate-back:before,.fa-rotate-backward:before,.fa-rotate-left:before,.fa-undo-alt:before{content:"\f2ea"}.fa-columns:before,.fa-table-columns:before{content:"\f0db"}.fa-lemon:before{content:"\f094"}.fa-head-side-mask:before{content:"\e063"}.fa-handshake:before{content:"\f2b5"}.fa-gem:before{content:"\f3a5"}.fa-dolly-box:before,.fa-dolly:before{content:"\f472"}.fa-smoking:before{content:"\f48d"}.fa-compress-arrows-alt:before,.fa-minimize:before{content:"\f78c"}.fa-monument:before{content:"\f5a6"}.fa-snowplow:before{content:"\f7d2"}.fa-angle-double-right:before,.fa-angles-right:before{content:"\f101"}.fa-cannabis:before{content:"\f55f"}.fa-circle-play:before,.fa-play-circle:before{content:"\f144"}.fa-tablets:before{content:"\f490"}.fa-ethernet:before{content:"\f796"}.fa-eur:before,.fa-euro-sign:before,.fa-euro:before{content:"\f153"}.fa-chair:before{content:"\f6c0"}.fa-check-circle:before,.fa-circle-check:before{content:"\f058"}.fa-circle-stop:before,.fa-stop-circle:before{content:"\f28d"}.fa-compass-drafting:before,.fa-drafting-compass:before{content:"\f568"}.fa-plate-wheat:before{content:"\e55a"}.fa-icicles:before{content:"\f7ad"}.fa-person-shelter:before{content:"\e54f"}.fa-neuter:before{content:"\f22c"}.fa-id-badge:before{content:"\f2c1"}.fa-marker:before{content:"\f5a1"}.fa-face-laugh-beam:before,.fa-laugh-beam:before{content:"\f59a"}.fa-helicopter-symbol:before{content:"\e502"}.fa-universal-access:before{content:"\f29a"}.fa-chevron-circle-up:before,.fa-circle-chevron-up:before{content:"\f139"}.fa-lari-sign:before{content:"\e1c8"}.fa-volcano:before{content:"\f770"}.fa-person-walking-dashed-line-arrow-right:before{content:"\e553"}.fa-gbp:before,.fa-pound-sign:before,.fa-sterling-sign:before{content:"\f154"}.fa-viruses:before{content:"\e076"}.fa-square-person-confined:before{content:"\e577"}.fa-user-tie:before{content:"\f508"}.fa-arrow-down-long:before,.fa-long-arrow-down:before{content:"\f175"}.fa-tent-arrow-down-to-line:before{content:"\e57e"}.fa-certificate:before{content:"\f0a3"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-suitcase:before{content:"\f0f2"}.fa-person-skating:before,.fa-skating:before{content:"\f7c5"}.fa-filter-circle-dollar:before,.fa-funnel-dollar:before{content:"\f662"}.fa-camera-retro:before{content:"\f083"}.fa-arrow-circle-down:before,.fa-circle-arrow-down:before{content:"\f0ab"}.fa-arrow-right-to-file:before,.fa-file-import:before{content:"\f56f"}.fa-external-link-square:before,.fa-square-arrow-up-right:before{content:"\f14c"}.fa-box-open:before{content:"\f49e"}.fa-scroll:before{content:"\f70e"}.fa-spa:before{content:"\f5bb"}.fa-location-pin-lock:before{content:"\e51f"}.fa-pause:before{content:"\f04c"}.fa-hill-avalanche:before{content:"\e507"}.fa-temperature-0:before,.fa-temperature-empty:before,.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-bomb:before{content:"\f1e2"}.fa-registered:before{content:"\f25d"}.fa-address-card:before,.fa-contact-card:before,.fa-vcard:before{content:"\f2bb"}.fa-balance-scale-right:before,.fa-scale-unbalanced-flip:before{content:"\f516"}.fa-subscript:before{content:"\f12c"}.fa-diamond-turn-right:before,.fa-directions:before{content:"\f5eb"}.fa-burst:before{content:"\e4dc"}.fa-house-laptop:before,.fa-laptop-house:before{content:"\e066"}.fa-face-tired:before,.fa-tired:before{content:"\f5c8"}.fa-money-bills:before{content:"\e1f3"}.fa-smog:before{content:"\f75f"}.fa-crutch:before{content:"\f7f7"}.fa-cloud-arrow-up:before,.fa-cloud-upload-alt:before,.fa-cloud-upload:before{content:"\f0ee"}.fa-palette:before{content:"\f53f"}.fa-arrows-turn-right:before{content:"\e4c0"}.fa-vest:before{content:"\e085"}.fa-ferry:before{content:"\e4ea"}.fa-arrows-down-to-people:before{content:"\e4b9"}.fa-seedling:before,.fa-sprout:before{content:"\f4d8"}.fa-arrows-alt-h:before,.fa-left-right:before{content:"\f337"}.fa-boxes-packing:before{content:"\e4c7"}.fa-arrow-circle-left:before,.fa-circle-arrow-left:before{content:"\f0a8"}.fa-group-arrows-rotate:before{content:"\e4f6"}.fa-bowl-food:before{content:"\e4c6"}.fa-candy-cane:before{content:"\f786"}.fa-arrow-down-wide-short:before,.fa-sort-amount-asc:before,.fa-sort-amount-down:before{content:"\f160"}.fa-cloud-bolt:before,.fa-thunderstorm:before{content:"\f76c"}.fa-remove-format:before,.fa-text-slash:before{content:"\f87d"}.fa-face-smile-wink:before,.fa-smile-wink:before{content:"\f4da"}.fa-file-word:before{content:"\f1c2"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-arrows-h:before,.fa-arrows-left-right:before{content:"\f07e"}.fa-house-lock:before{content:"\e510"}.fa-cloud-arrow-down:before,.fa-cloud-download-alt:before,.fa-cloud-download:before{content:"\f0ed"}.fa-children:before{content:"\e4e1"}.fa-blackboard:before,.fa-chalkboard:before{content:"\f51b"}.fa-user-alt-slash:before,.fa-user-large-slash:before{content:"\f4fa"}.fa-envelope-open:before{content:"\f2b6"}.fa-handshake-alt-slash:before,.fa-handshake-simple-slash:before{content:"\e05f"}.fa-mattress-pillow:before{content:"\e525"}.fa-guarani-sign:before{content:"\e19a"}.fa-arrows-rotate:before,.fa-refresh:before,.fa-sync:before{content:"\f021"}.fa-fire-extinguisher:before{content:"\f134"}.fa-cruzeiro-sign:before{content:"\e152"}.fa-greater-than-equal:before{content:"\f532"}.fa-shield-alt:before,.fa-shield-halved:before{content:"\f3ed"}.fa-atlas:before,.fa-book-atlas:before{content:"\f558"}.fa-virus:before{content:"\e074"}.fa-envelope-circle-check:before{content:"\e4e8"}.fa-layer-group:before{content:"\f5fd"}.fa-arrows-to-dot:before{content:"\e4be"}.fa-archway:before{content:"\f557"}.fa-heart-circle-check:before{content:"\e4fd"}.fa-house-chimney-crack:before,.fa-house-damage:before{content:"\f6f1"}.fa-file-archive:before,.fa-file-zipper:before{content:"\f1c6"}.fa-square:before{content:"\f0c8"}.fa-glass-martini:before,.fa-martini-glass-empty:before{content:"\f000"}.fa-couch:before{content:"\f4b8"}.fa-cedi-sign:before{content:"\e0df"}.fa-italic:before{content:"\f033"}.fa-church:before{content:"\f51d"}.fa-comments-dollar:before{content:"\f653"}.fa-democrat:before{content:"\f747"}.fa-z:before{content:"\5a"}.fa-person-skiing:before,.fa-skiing:before{content:"\f7c9"}.fa-road-lock:before{content:"\e567"}.fa-a:before{content:"\41"}.fa-temperature-arrow-down:before,.fa-temperature-down:before{content:"\e03f"}.fa-feather-alt:before,.fa-feather-pointed:before{content:"\f56b"}.fa-p:before{content:"\50"}.fa-snowflake:before{content:"\f2dc"}.fa-newspaper:before{content:"\f1ea"}.fa-ad:before,.fa-rectangle-ad:before{content:"\f641"}.fa-arrow-circle-right:before,.fa-circle-arrow-right:before{content:"\f0a9"}.fa-filter-circle-xmark:before{content:"\e17b"}.fa-locust:before{content:"\e520"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-list-1-2:before,.fa-list-numeric:before,.fa-list-ol:before{content:"\f0cb"}.fa-person-dress-burst:before{content:"\e544"}.fa-money-check-alt:before,.fa-money-check-dollar:before{content:"\f53d"}.fa-vector-square:before{content:"\f5cb"}.fa-bread-slice:before{content:"\f7ec"}.fa-language:before{content:"\f1ab"}.fa-face-kiss-wink-heart:before,.fa-kiss-wink-heart:before{content:"\f598"}.fa-filter:before{content:"\f0b0"}.fa-question:before{content:"\3f"}.fa-file-signature:before{content:"\f573"}.fa-arrows-alt:before,.fa-up-down-left-right:before{content:"\f0b2"}.fa-house-chimney-user:before{content:"\e065"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-puzzle-piece:before{content:"\f12e"}.fa-money-check:before{content:"\f53c"}.fa-star-half-alt:before,.fa-star-half-stroke:before{content:"\f5c0"}.fa-code:before{content:"\f121"}.fa-glass-whiskey:before,.fa-whiskey-glass:before{content:"\f7a0"}.fa-building-circle-exclamation:before{content:"\e4d3"}.fa-magnifying-glass-chart:before{content:"\e522"}.fa-arrow-up-right-from-square:before,.fa-external-link:before{content:"\f08e"}.fa-cubes-stacked:before{content:"\e4e6"}.fa-krw:before,.fa-won-sign:before,.fa-won:before{content:"\f159"}.fa-virus-covid:before{content:"\e4a8"}.fa-austral-sign:before{content:"\e0a9"}.fa-f:before{content:"\46"}.fa-leaf:before{content:"\f06c"}.fa-road:before{content:"\f018"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-person-circle-plus:before{content:"\e541"}.fa-chart-pie:before,.fa-pie-chart:before{content:"\f200"}.fa-bolt-lightning:before{content:"\e0b7"}.fa-sack-xmark:before{content:"\e56a"}.fa-file-excel:before{content:"\f1c3"}.fa-file-contract:before{content:"\f56c"}.fa-fish-fins:before{content:"\e4f2"}.fa-building-flag:before{content:"\e4d5"}.fa-face-grin-beam:before,.fa-grin-beam:before{content:"\f582"}.fa-object-ungroup:before{content:"\f248"}.fa-poop:before{content:"\f619"}.fa-location-pin:before,.fa-map-marker:before{content:"\f041"}.fa-kaaba:before{content:"\f66b"}.fa-toilet-paper:before{content:"\f71e"}.fa-hard-hat:before,.fa-hat-hard:before,.fa-helmet-safety:before{content:"\f807"}.fa-eject:before{content:"\f052"}.fa-arrow-alt-circle-right:before,.fa-circle-right:before{content:"\f35a"}.fa-plane-circle-check:before{content:"\e555"}.fa-face-rolling-eyes:before,.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-object-group:before{content:"\f247"}.fa-chart-line:before,.fa-line-chart:before{content:"\f201"}.fa-mask-ventilator:before{content:"\e524"}.fa-arrow-right:before{content:"\f061"}.fa-map-signs:before,.fa-signs-post:before{content:"\f277"}.fa-cash-register:before{content:"\f788"}.fa-person-circle-question:before{content:"\e542"}.fa-h:before{content:"\48"}.fa-tarp:before{content:"\e57b"}.fa-screwdriver-wrench:before,.fa-tools:before{content:"\f7d9"}.fa-arrows-to-eye:before{content:"\e4bf"}.fa-plug-circle-bolt:before{content:"\e55b"}.fa-heart:before{content:"\f004"}.fa-mars-and-venus:before{content:"\f224"}.fa-home-user:before,.fa-house-user:before{content:"\e1b0"}.fa-dumpster-fire:before{content:"\f794"}.fa-house-crack:before{content:"\e3b1"}.fa-cocktail:before,.fa-martini-glass-citrus:before{content:"\f561"}.fa-face-surprise:before,.fa-surprise:before{content:"\f5c2"}.fa-bottle-water:before{content:"\e4c5"}.fa-circle-pause:before,.fa-pause-circle:before{content:"\f28b"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-apple-alt:before,.fa-apple-whole:before{content:"\f5d1"}.fa-kitchen-set:before{content:"\e51a"}.fa-r:before{content:"\52"}.fa-temperature-1:before,.fa-temperature-quarter:before,.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-cube:before{content:"\f1b2"}.fa-bitcoin-sign:before{content:"\e0b4"}.fa-shield-dog:before{content:"\e573"}.fa-solar-panel:before{content:"\f5ba"}.fa-lock-open:before{content:"\f3c1"}.fa-elevator:before{content:"\e16d"}.fa-money-bill-transfer:before{content:"\e528"}.fa-money-bill-trend-up:before{content:"\e529"}.fa-house-flood-water-circle-arrow-right:before{content:"\e50f"}.fa-poll-h:before,.fa-square-poll-horizontal:before{content:"\f682"}.fa-circle:before{content:"\f111"}.fa-backward-fast:before,.fa-fast-backward:before{content:"\f049"}.fa-recycle:before{content:"\f1b8"}.fa-user-astronaut:before{content:"\f4fb"}.fa-plane-slash:before{content:"\e069"}.fa-trademark:before{content:"\f25c"}.fa-basketball-ball:before,.fa-basketball:before{content:"\f434"}.fa-satellite-dish:before{content:"\f7c0"}.fa-arrow-alt-circle-up:before,.fa-circle-up:before{content:"\f35b"}.fa-mobile-alt:before,.fa-mobile-screen-button:before{content:"\f3cd"}.fa-volume-high:before,.fa-volume-up:before{content:"\f028"}.fa-users-rays:before{content:"\e593"}.fa-wallet:before{content:"\f555"}.fa-clipboard-check:before{content:"\f46c"}.fa-file-audio:before{content:"\f1c7"}.fa-burger:before,.fa-hamburger:before{content:"\f805"}.fa-wrench:before{content:"\f0ad"}.fa-bugs:before{content:"\e4d0"}.fa-rupee-sign:before,.fa-rupee:before{content:"\f156"}.fa-file-image:before{content:"\f1c5"}.fa-circle-question:before,.fa-question-circle:before{content:"\f059"}.fa-plane-departure:before{content:"\f5b0"}.fa-handshake-slash:before{content:"\e060"}.fa-book-bookmark:before{content:"\e0bb"}.fa-code-branch:before{content:"\f126"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-bridge:before{content:"\e4c8"}.fa-phone-alt:before,.fa-phone-flip:before{content:"\f879"}.fa-truck-front:before{content:"\e2b7"}.fa-cat:before{content:"\f6be"}.fa-anchor-circle-exclamation:before{content:"\e4ab"}.fa-truck-field:before{content:"\e58d"}.fa-route:before{content:"\f4d7"}.fa-clipboard-question:before{content:"\e4e3"}.fa-panorama:before{content:"\e209"}.fa-comment-medical:before{content:"\f7f5"}.fa-teeth-open:before{content:"\f62f"}.fa-file-circle-minus:before{content:"\e4ed"}.fa-tags:before{content:"\f02c"}.fa-wine-glass:before{content:"\f4e3"}.fa-fast-forward:before,.fa-forward-fast:before{content:"\f050"}.fa-face-meh-blank:before,.fa-meh-blank:before{content:"\f5a4"}.fa-parking:before,.fa-square-parking:before{content:"\f540"}.fa-house-signal:before{content:"\e012"}.fa-bars-progress:before,.fa-tasks-alt:before{content:"\f828"}.fa-faucet-drip:before{content:"\e006"}.fa-cart-flatbed:before,.fa-dolly-flatbed:before{content:"\f474"}.fa-ban-smoking:before,.fa-smoking-ban:before{content:"\f54d"}.fa-terminal:before{content:"\f120"}.fa-mobile-button:before{content:"\f10b"}.fa-house-medical-flag:before{content:"\e514"}.fa-basket-shopping:before,.fa-shopping-basket:before{content:"\f291"}.fa-tape:before{content:"\f4db"}.fa-bus-alt:before,.fa-bus-simple:before{content:"\f55e"}.fa-eye:before{content:"\f06e"}.fa-face-sad-cry:before,.fa-sad-cry:before{content:"\f5b3"}.fa-audio-description:before{content:"\f29e"}.fa-person-military-to-person:before{content:"\e54c"}.fa-file-shield:before{content:"\e4f0"}.fa-user-slash:before{content:"\f506"}.fa-pen:before{content:"\f304"}.fa-tower-observation:before{content:"\e586"}.fa-file-code:before{content:"\f1c9"}.fa-signal-5:before,.fa-signal-perfect:before,.fa-signal:before{content:"\f012"}.fa-bus:before{content:"\f207"}.fa-heart-circle-xmark:before{content:"\e501"}.fa-home-lg:before,.fa-house-chimney:before{content:"\e3af"}.fa-window-maximize:before{content:"\f2d0"}.fa-face-frown:before,.fa-frown:before{content:"\f119"}.fa-prescription:before{content:"\f5b1"}.fa-shop:before,.fa-store-alt:before{content:"\f54f"}.fa-floppy-disk:before,.fa-save:before{content:"\f0c7"}.fa-vihara:before{content:"\f6a7"}.fa-balance-scale-left:before,.fa-scale-unbalanced:before{content:"\f515"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-comment-dots:before,.fa-commenting:before{content:"\f4ad"}.fa-plant-wilt:before{content:"\e5aa"}.fa-diamond:before{content:"\f219"}.fa-face-grin-squint:before,.fa-grin-squint:before{content:"\f585"}.fa-hand-holding-dollar:before,.fa-hand-holding-usd:before{content:"\f4c0"}.fa-bacterium:before{content:"\e05a"}.fa-hand-pointer:before{content:"\f25a"}.fa-drum-steelpan:before{content:"\f56a"}.fa-hand-scissors:before{content:"\f257"}.fa-hands-praying:before,.fa-praying-hands:before{content:"\f684"}.fa-arrow-right-rotate:before,.fa-arrow-rotate-forward:before,.fa-arrow-rotate-right:before,.fa-redo:before{content:"\f01e"}.fa-biohazard:before{content:"\f780"}.fa-location-crosshairs:before,.fa-location:before{content:"\f601"}.fa-mars-double:before{content:"\f227"}.fa-child-dress:before{content:"\e59c"}.fa-users-between-lines:before{content:"\e591"}.fa-lungs-virus:before{content:"\e067"}.fa-face-grin-tears:before,.fa-grin-tears:before{content:"\f588"}.fa-phone:before{content:"\f095"}.fa-calendar-times:before,.fa-calendar-xmark:before{content:"\f273"}.fa-child-reaching:before{content:"\e59d"}.fa-head-side-virus:before{content:"\e064"}.fa-user-cog:before,.fa-user-gear:before{content:"\f4fe"}.fa-arrow-up-1-9:before,.fa-sort-numeric-up:before{content:"\f163"}.fa-door-closed:before{content:"\f52a"}.fa-shield-virus:before{content:"\e06c"}.fa-dice-six:before{content:"\f526"}.fa-mosquito-net:before{content:"\e52c"}.fa-bridge-water:before{content:"\e4ce"}.fa-person-booth:before{content:"\f756"}.fa-text-width:before{content:"\f035"}.fa-hat-wizard:before{content:"\f6e8"}.fa-pen-fancy:before{content:"\f5ac"}.fa-digging:before,.fa-person-digging:before{content:"\f85e"}.fa-trash:before{content:"\f1f8"}.fa-gauge-simple-med:before,.fa-gauge-simple:before,.fa-tachometer-average:before{content:"\f629"}.fa-book-medical:before{content:"\f7e6"}.fa-poo:before{content:"\f2fe"}.fa-quote-right-alt:before,.fa-quote-right:before{content:"\f10e"}.fa-shirt:before,.fa-t-shirt:before,.fa-tshirt:before{content:"\f553"}.fa-cubes:before{content:"\f1b3"}.fa-divide:before{content:"\f529"}.fa-tenge-sign:before,.fa-tenge:before{content:"\f7d7"}.fa-headphones:before{content:"\f025"}.fa-hands-holding:before{content:"\f4c2"}.fa-hands-clapping:before{content:"\e1a8"}.fa-republican:before{content:"\f75e"}.fa-arrow-left:before{content:"\f060"}.fa-person-circle-xmark:before{content:"\e543"}.fa-ruler:before{content:"\f545"}.fa-align-left:before{content:"\f036"}.fa-dice-d6:before{content:"\f6d1"}.fa-restroom:before{content:"\f7bd"}.fa-j:before{content:"\4a"}.fa-users-viewfinder:before{content:"\e595"}.fa-file-video:before{content:"\f1c8"}.fa-external-link-alt:before,.fa-up-right-from-square:before{content:"\f35d"}.fa-table-cells:before,.fa-th:before{content:"\f00a"}.fa-file-pdf:before{content:"\f1c1"}.fa-bible:before,.fa-book-bible:before{content:"\f647"}.fa-o:before{content:"\4f"}.fa-medkit:before,.fa-suitcase-medical:before{content:"\f0fa"}.fa-user-secret:before{content:"\f21b"}.fa-otter:before{content:"\f700"}.fa-female:before,.fa-person-dress:before{content:"\f182"}.fa-comment-dollar:before{content:"\f651"}.fa-briefcase-clock:before,.fa-business-time:before{content:"\f64a"}.fa-table-cells-large:before,.fa-th-large:before{content:"\f009"}.fa-book-tanakh:before,.fa-tanakh:before{content:"\f827"}.fa-phone-volume:before,.fa-volume-control-phone:before{content:"\f2a0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-clipboard-user:before{content:"\f7f3"}.fa-child:before{content:"\f1ae"}.fa-lira-sign:before{content:"\f195"}.fa-satellite:before{content:"\f7bf"}.fa-plane-lock:before{content:"\e558"}.fa-tag:before{content:"\f02b"}.fa-comment:before{content:"\f075"}.fa-birthday-cake:before,.fa-cake-candles:before,.fa-cake:before{content:"\f1fd"}.fa-envelope:before{content:"\f0e0"}.fa-angle-double-up:before,.fa-angles-up:before{content:"\f102"}.fa-paperclip:before{content:"\f0c6"}.fa-arrow-right-to-city:before{content:"\e4b3"}.fa-ribbon:before{content:"\f4d6"}.fa-lungs:before{content:"\f604"}.fa-arrow-up-9-1:before,.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-litecoin-sign:before{content:"\e1d3"}.fa-border-none:before{content:"\f850"}.fa-circle-nodes:before{content:"\e4e2"}.fa-parachute-box:before{content:"\f4cd"}.fa-indent:before{content:"\f03c"}.fa-truck-field-un:before{content:"\e58e"}.fa-hourglass-empty:before,.fa-hourglass:before{content:"\f254"}.fa-mountain:before{content:"\f6fc"}.fa-user-doctor:before,.fa-user-md:before{content:"\f0f0"}.fa-circle-info:before,.fa-info-circle:before{content:"\f05a"}.fa-cloud-meatball:before{content:"\f73b"}.fa-camera-alt:before,.fa-camera:before{content:"\f030"}.fa-square-virus:before{content:"\e578"}.fa-meteor:before{content:"\f753"}.fa-car-on:before{content:"\e4dd"}.fa-sleigh:before{content:"\f7cc"}.fa-arrow-down-1-9:before,.fa-sort-numeric-asc:before,.fa-sort-numeric-down:before{content:"\f162"}.fa-hand-holding-droplet:before,.fa-hand-holding-water:before{content:"\f4c1"}.fa-water:before{content:"\f773"}.fa-calendar-check:before{content:"\f274"}.fa-braille:before{content:"\f2a1"}.fa-prescription-bottle-alt:before,.fa-prescription-bottle-medical:before{content:"\f486"}.fa-landmark:before{content:"\f66f"}.fa-truck:before{content:"\f0d1"}.fa-crosshairs:before{content:"\f05b"}.fa-person-cane:before{content:"\e53c"}.fa-tent:before{content:"\e57d"}.fa-vest-patches:before{content:"\e086"}.fa-check-double:before{content:"\f560"}.fa-arrow-down-a-z:before,.fa-sort-alpha-asc:before,.fa-sort-alpha-down:before{content:"\f15d"}.fa-money-bill-wheat:before{content:"\e52a"}.fa-cookie:before{content:"\f563"}.fa-arrow-left-rotate:before,.fa-arrow-rotate-back:before,.fa-arrow-rotate-backward:before,.fa-arrow-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-hard-drive:before,.fa-hdd:before{content:"\f0a0"}.fa-face-grin-squint-tears:before,.fa-grin-squint-tears:before{content:"\f586"}.fa-dumbbell:before{content:"\f44b"}.fa-list-alt:before,.fa-rectangle-list:before{content:"\f022"}.fa-tarp-droplet:before{content:"\e57c"}.fa-house-medical-circle-check:before{content:"\e511"}.fa-person-skiing-nordic:before,.fa-skiing-nordic:before{content:"\f7ca"}.fa-calendar-plus:before{content:"\f271"}.fa-plane-arrival:before{content:"\f5af"}.fa-arrow-alt-circle-left:before,.fa-circle-left:before{content:"\f359"}.fa-subway:before,.fa-train-subway:before{content:"\f239"}.fa-chart-gantt:before{content:"\e0e4"}.fa-indian-rupee-sign:before,.fa-indian-rupee:before,.fa-inr:before{content:"\e1bc"}.fa-crop-alt:before,.fa-crop-simple:before{content:"\f565"}.fa-money-bill-1:before,.fa-money-bill-alt:before{content:"\f3d1"}.fa-left-long:before,.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-dna:before{content:"\f471"}.fa-virus-slash:before{content:"\e075"}.fa-minus:before,.fa-subtract:before{content:"\f068"}.fa-chess:before{content:"\f439"}.fa-arrow-left-long:before,.fa-long-arrow-left:before{content:"\f177"}.fa-plug-circle-check:before{content:"\e55c"}.fa-street-view:before{content:"\f21d"}.fa-franc-sign:before{content:"\e18f"}.fa-volume-off:before{content:"\f026"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before,.fa-hands-american-sign-language-interpreting:before,.fa-hands-asl-interpreting:before{content:"\f2a3"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-droplet-slash:before,.fa-tint-slash:before{content:"\f5c7"}.fa-mosque:before{content:"\f678"}.fa-mosquito:before{content:"\e52b"}.fa-star-of-david:before{content:"\f69a"}.fa-person-military-rifle:before{content:"\e54b"}.fa-cart-shopping:before,.fa-shopping-cart:before{content:"\f07a"}.fa-vials:before{content:"\f493"}.fa-plug-circle-plus:before{content:"\e55f"}.fa-place-of-worship:before{content:"\f67f"}.fa-grip-vertical:before{content:"\f58e"}.fa-arrow-turn-up:before,.fa-level-up:before{content:"\f148"}.fa-u:before{content:"\55"}.fa-square-root-alt:before,.fa-square-root-variable:before{content:"\f698"}.fa-clock-four:before,.fa-clock:before{content:"\f017"}.fa-backward-step:before,.fa-step-backward:before{content:"\f048"}.fa-pallet:before{content:"\f482"}.fa-faucet:before{content:"\e005"}.fa-baseball-bat-ball:before{content:"\f432"}.fa-s:before{content:"\53"}.fa-timeline:before{content:"\e29c"}.fa-keyboard:before{content:"\f11c"}.fa-caret-down:before{content:"\f0d7"}.fa-clinic-medical:before,.fa-house-chimney-medical:before{content:"\f7f2"}.fa-temperature-3:before,.fa-temperature-three-quarters:before,.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-mobile-android-alt:before,.fa-mobile-screen:before{content:"\f3cf"}.fa-plane-up:before{content:"\e22d"}.fa-piggy-bank:before{content:"\f4d3"}.fa-battery-3:before,.fa-battery-half:before{content:"\f242"}.fa-mountain-city:before{content:"\e52e"}.fa-coins:before{content:"\f51e"}.fa-khanda:before{content:"\f66d"}.fa-sliders-h:before,.fa-sliders:before{content:"\f1de"}.fa-folder-tree:before{content:"\f802"}.fa-network-wired:before{content:"\f6ff"}.fa-map-pin:before{content:"\f276"}.fa-hamsa:before{content:"\f665"}.fa-cent-sign:before{content:"\e3f5"}.fa-flask:before{content:"\f0c3"}.fa-person-pregnant:before{content:"\e31e"}.fa-wand-sparkles:before{content:"\f72b"}.fa-ellipsis-v:before,.fa-ellipsis-vertical:before{content:"\f142"}.fa-ticket:before{content:"\f145"}.fa-power-off:before{content:"\f011"}.fa-long-arrow-alt-right:before,.fa-right-long:before{content:"\f30b"}.fa-flag-usa:before{content:"\f74d"}.fa-laptop-file:before{content:"\e51d"}.fa-teletype:before,.fa-tty:before{content:"\f1e4"}.fa-diagram-next:before{content:"\e476"}.fa-person-rifle:before{content:"\e54e"}.fa-house-medical-circle-exclamation:before{content:"\e512"}.fa-closed-captioning:before{content:"\f20a"}.fa-hiking:before,.fa-person-hiking:before{content:"\f6ec"}.fa-venus-double:before{content:"\f226"}.fa-images:before{content:"\f302"}.fa-calculator:before{content:"\f1ec"}.fa-people-pulling:before{content:"\e535"}.fa-n:before{content:"\4e"}.fa-cable-car:before,.fa-tram:before{content:"\f7da"}.fa-cloud-rain:before{content:"\f73d"}.fa-building-circle-xmark:before{content:"\e4d4"}.fa-ship:before{content:"\f21a"}.fa-arrows-down-to-line:before{content:"\e4b8"}.fa-download:before{content:"\f019"}.fa-face-grin:before,.fa-grin:before{content:"\f580"}.fa-backspace:before,.fa-delete-left:before{content:"\f55a"}.fa-eye-dropper-empty:before,.fa-eye-dropper:before,.fa-eyedropper:before{content:"\f1fb"}.fa-file-circle-check:before{content:"\e5a0"}.fa-forward:before{content:"\f04e"}.fa-mobile-android:before,.fa-mobile-phone:before,.fa-mobile:before{content:"\f3ce"}.fa-face-meh:before,.fa-meh:before{content:"\f11a"}.fa-align-center:before{content:"\f037"}.fa-book-dead:before,.fa-book-skull:before{content:"\f6b7"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-heart-circle-exclamation:before{content:"\e4fe"}.fa-home-alt:before,.fa-home-lg-alt:before,.fa-home:before,.fa-house:before{content:"\f015"}.fa-calendar-week:before{content:"\f784"}.fa-laptop-medical:before{content:"\f812"}.fa-b:before{content:"\42"}.fa-file-medical:before{content:"\f477"}.fa-dice-one:before{content:"\f525"}.fa-kiwi-bird:before{content:"\f535"}.fa-arrow-right-arrow-left:before,.fa-exchange:before{content:"\f0ec"}.fa-redo-alt:before,.fa-rotate-forward:before,.fa-rotate-right:before{content:"\f2f9"}.fa-cutlery:before,.fa-utensils:before{content:"\f2e7"}.fa-arrow-up-wide-short:before,.fa-sort-amount-up:before{content:"\f161"}.fa-mill-sign:before{content:"\e1ed"}.fa-bowl-rice:before{content:"\e2eb"}.fa-skull:before{content:"\f54c"}.fa-broadcast-tower:before,.fa-tower-broadcast:before{content:"\f519"}.fa-truck-pickup:before{content:"\f63c"}.fa-long-arrow-alt-up:before,.fa-up-long:before{content:"\f30c"}.fa-stop:before{content:"\f04d"}.fa-code-merge:before{content:"\f387"}.fa-upload:before{content:"\f093"}.fa-hurricane:before{content:"\f751"}.fa-mound:before{content:"\e52d"}.fa-toilet-portable:before{content:"\e583"}.fa-compact-disc:before{content:"\f51f"}.fa-file-arrow-down:before,.fa-file-download:before{content:"\f56d"}.fa-caravan:before{content:"\f8ff"}.fa-shield-cat:before{content:"\e572"}.fa-bolt:before,.fa-zap:before{content:"\f0e7"}.fa-glass-water:before{content:"\e4f4"}.fa-oil-well:before{content:"\e532"}.fa-vault:before{content:"\e2c5"}.fa-mars:before{content:"\f222"}.fa-toilet:before{content:"\f7d8"}.fa-plane-circle-xmark:before{content:"\e557"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen-sign:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble-sign:before,.fa-ruble:before{content:"\f158"}.fa-sun:before{content:"\f185"}.fa-guitar:before{content:"\f7a6"}.fa-face-laugh-wink:before,.fa-laugh-wink:before{content:"\f59c"}.fa-horse-head:before{content:"\f7ab"}.fa-bore-hole:before{content:"\e4c3"}.fa-industry:before{content:"\f275"}.fa-arrow-alt-circle-down:before,.fa-circle-down:before{content:"\f358"}.fa-arrows-turn-to-dots:before{content:"\e4c1"}.fa-florin-sign:before{content:"\e184"}.fa-arrow-down-short-wide:before,.fa-sort-amount-desc:before,.fa-sort-amount-down-alt:before{content:"\f884"}.fa-less-than:before{content:"\3c"}.fa-angle-down:before{content:"\f107"}.fa-car-tunnel:before{content:"\e4de"}.fa-head-side-cough:before{content:"\e061"}.fa-grip-lines:before{content:"\f7a4"}.fa-thumbs-down:before{content:"\f165"}.fa-user-lock:before{content:"\f502"}.fa-arrow-right-long:before,.fa-long-arrow-right:before{content:"\f178"}.fa-anchor-circle-xmark:before{content:"\e4ac"}.fa-ellipsis-h:before,.fa-ellipsis:before{content:"\f141"}.fa-chess-pawn:before{content:"\f443"}.fa-first-aid:before,.fa-kit-medical:before{content:"\f479"}.fa-person-through-window:before{content:"\e5a9"}.fa-toolbox:before{content:"\f552"}.fa-hands-holding-circle:before{content:"\e4fb"}.fa-bug:before{content:"\f188"}.fa-credit-card-alt:before,.fa-credit-card:before{content:"\f09d"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-hand-holding-hand:before{content:"\e4f7"}.fa-book-open-reader:before,.fa-book-reader:before{content:"\f5da"}.fa-mountain-sun:before{content:"\e52f"}.fa-arrows-left-right-to-line:before{content:"\e4ba"}.fa-dice-d20:before{content:"\f6cf"}.fa-truck-droplet:before{content:"\e58c"}.fa-file-circle-xmark:before{content:"\e5a1"}.fa-temperature-arrow-up:before,.fa-temperature-up:before{content:"\e040"}.fa-medal:before{content:"\f5a2"}.fa-bed:before{content:"\f236"}.fa-h-square:before,.fa-square-h:before{content:"\f0fd"}.fa-podcast:before{content:"\f2ce"}.fa-temperature-4:before,.fa-temperature-full:before,.fa-thermometer-4:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-bell:before{content:"\f0f3"}.fa-superscript:before{content:"\f12b"}.fa-plug-circle-xmark:before{content:"\e560"}.fa-star-of-life:before{content:"\f621"}.fa-phone-slash:before{content:"\f3dd"}.fa-paint-roller:before{content:"\f5aa"}.fa-hands-helping:before,.fa-handshake-angle:before{content:"\f4c4"}.fa-location-dot:before,.fa-map-marker-alt:before{content:"\f3c5"}.fa-file:before{content:"\f15b"}.fa-greater-than:before{content:"\3e"}.fa-person-swimming:before,.fa-swimmer:before{content:"\f5c4"}.fa-arrow-down:before{content:"\f063"}.fa-droplet:before,.fa-tint:before{content:"\f043"}.fa-eraser:before{content:"\f12d"}.fa-earth-america:before,.fa-earth-americas:before,.fa-earth:before,.fa-globe-americas:before{content:"\f57d"}.fa-person-burst:before{content:"\e53b"}.fa-dove:before{content:"\f4ba"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-socks:before{content:"\f696"}.fa-inbox:before{content:"\f01c"}.fa-section:before{content:"\e447"}.fa-gauge-high:before,.fa-tachometer-alt-fast:before,.fa-tachometer-alt:before{content:"\f625"}.fa-envelope-open-text:before{content:"\f658"}.fa-hospital-alt:before,.fa-hospital-wide:before,.fa-hospital:before{content:"\f0f8"}.fa-wine-bottle:before{content:"\f72f"}.fa-chess-rook:before{content:"\f447"}.fa-bars-staggered:before,.fa-reorder:before,.fa-stream:before{content:"\f550"}.fa-dharmachakra:before{content:"\f655"}.fa-hotdog:before{content:"\f80f"}.fa-blind:before,.fa-person-walking-with-cane:before{content:"\f29d"}.fa-drum:before{content:"\f569"}.fa-ice-cream:before{content:"\f810"}.fa-heart-circle-bolt:before{content:"\e4fc"}.fa-fax:before{content:"\f1ac"}.fa-paragraph:before{content:"\f1dd"}.fa-check-to-slot:before,.fa-vote-yea:before{content:"\f772"}.fa-star-half:before{content:"\f089"}.fa-boxes-alt:before,.fa-boxes-stacked:before,.fa-boxes:before{content:"\f468"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-assistive-listening-systems:before,.fa-ear-listen:before{content:"\f2a2"}.fa-tree-city:before{content:"\e587"}.fa-play:before{content:"\f04b"}.fa-font:before{content:"\f031"}.fa-rupiah-sign:before{content:"\e23d"}.fa-magnifying-glass:before,.fa-search:before{content:"\f002"}.fa-ping-pong-paddle-ball:before,.fa-table-tennis-paddle-ball:before,.fa-table-tennis:before{content:"\f45d"}.fa-diagnoses:before,.fa-person-dots-from-line:before{content:"\f470"}.fa-trash-can-arrow-up:before,.fa-trash-restore-alt:before{content:"\f82a"}.fa-naira-sign:before{content:"\e1f6"}.fa-cart-arrow-down:before{content:"\f218"}.fa-walkie-talkie:before{content:"\f8ef"}.fa-file-edit:before,.fa-file-pen:before{content:"\f31c"}.fa-receipt:before{content:"\f543"}.fa-pen-square:before,.fa-pencil-square:before,.fa-square-pen:before{content:"\f14b"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-person-circle-exclamation:before{content:"\e53f"}.fa-chevron-down:before{content:"\f078"}.fa-battery-5:before,.fa-battery-full:before,.fa-battery:before{content:"\f240"}.fa-skull-crossbones:before{content:"\f714"}.fa-code-compare:before{content:"\e13a"}.fa-list-dots:before,.fa-list-ul:before{content:"\f0ca"}.fa-school-lock:before{content:"\e56f"}.fa-tower-cell:before{content:"\e585"}.fa-down-long:before,.fa-long-arrow-alt-down:before{content:"\f309"}.fa-ranking-star:before{content:"\e561"}.fa-chess-king:before{content:"\f43f"}.fa-person-harassing:before{content:"\e549"}.fa-brazilian-real-sign:before{content:"\e46c"}.fa-landmark-alt:before,.fa-landmark-dome:before{content:"\f752"}.fa-arrow-up:before{content:"\f062"}.fa-television:before,.fa-tv-alt:before,.fa-tv:before{content:"\f26c"}.fa-shrimp:before{content:"\e448"}.fa-list-check:before,.fa-tasks:before{content:"\f0ae"}.fa-jug-detergent:before{content:"\e519"}.fa-circle-user:before,.fa-user-circle:before{content:"\f2bd"}.fa-user-shield:before{content:"\f505"}.fa-wind:before{content:"\f72e"}.fa-car-burst:before,.fa-car-crash:before{content:"\f5e1"}.fa-y:before{content:"\59"}.fa-person-snowboarding:before,.fa-snowboarding:before{content:"\f7ce"}.fa-shipping-fast:before,.fa-truck-fast:before{content:"\f48b"}.fa-fish:before{content:"\f578"}.fa-user-graduate:before{content:"\f501"}.fa-adjust:before,.fa-circle-half-stroke:before{content:"\f042"}.fa-clapperboard:before{content:"\e131"}.fa-circle-radiation:before,.fa-radiation-alt:before{content:"\f7ba"}.fa-baseball-ball:before,.fa-baseball:before{content:"\f433"}.fa-jet-fighter-up:before{content:"\e518"}.fa-diagram-project:before,.fa-project-diagram:before{content:"\f542"}.fa-copy:before{content:"\f0c5"}.fa-volume-mute:before,.fa-volume-times:before,.fa-volume-xmark:before{content:"\f6a9"}.fa-hand-sparkles:before{content:"\e05d"}.fa-grip-horizontal:before,.fa-grip:before{content:"\f58d"}.fa-share-from-square:before,.fa-share-square:before{content:"\f14d"}.fa-child-combatant:before,.fa-child-rifle:before{content:"\e4e0"}.fa-gun:before{content:"\e19b"}.fa-phone-square:before,.fa-square-phone:before{content:"\f098"}.fa-add:before,.fa-plus:before{content:"\2b"}.fa-expand:before{content:"\f065"}.fa-computer:before{content:"\e4e5"}.fa-close:before,.fa-multiply:before,.fa-remove:before,.fa-times:before,.fa-xmark:before{content:"\f00d"}.fa-arrows-up-down-left-right:before,.fa-arrows:before{content:"\f047"}.fa-chalkboard-teacher:before,.fa-chalkboard-user:before{content:"\f51c"}.fa-peso-sign:before{content:"\e222"}.fa-building-shield:before{content:"\e4d8"}.fa-baby:before{content:"\f77c"}.fa-users-line:before{content:"\e592"}.fa-quote-left-alt:before,.fa-quote-left:before{content:"\f10d"}.fa-tractor:before{content:"\f722"}.fa-trash-arrow-up:before,.fa-trash-restore:before{content:"\f829"}.fa-arrow-down-up-lock:before{content:"\e4b0"}.fa-lines-leaning:before{content:"\e51e"}.fa-ruler-combined:before{content:"\f546"}.fa-copyright:before{content:"\f1f9"}.fa-equals:before{content:"\3d"}.fa-blender:before{content:"\f517"}.fa-teeth:before{content:"\f62e"}.fa-ils:before,.fa-shekel-sign:before,.fa-shekel:before,.fa-sheqel-sign:before,.fa-sheqel:before{content:"\f20b"}.fa-map:before{content:"\f279"}.fa-rocket:before{content:"\f135"}.fa-photo-film:before,.fa-photo-video:before{content:"\f87c"}.fa-folder-minus:before{content:"\f65d"}.fa-store:before{content:"\f54e"}.fa-arrow-trend-up:before{content:"\e098"}.fa-plug-circle-minus:before{content:"\e55e"}.fa-sign-hanging:before,.fa-sign:before{content:"\f4d9"}.fa-bezier-curve:before{content:"\f55b"}.fa-bell-slash:before{content:"\f1f6"}.fa-tablet-android:before,.fa-tablet:before{content:"\f3fb"}.fa-school-flag:before{content:"\e56e"}.fa-fill:before{content:"\f575"}.fa-angle-up:before{content:"\f106"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-holly-berry:before{content:"\f7aa"}.fa-chevron-left:before{content:"\f053"}.fa-bacteria:before{content:"\e059"}.fa-hand-lizard:before{content:"\f258"}.fa-notdef:before{content:"\e1fe"}.fa-disease:before{content:"\f7fa"}.fa-briefcase-medical:before{content:"\f469"}.fa-genderless:before{content:"\f22d"}.fa-chevron-right:before{content:"\f054"}.fa-retweet:before{content:"\f079"}.fa-car-alt:before,.fa-car-rear:before{content:"\f5de"}.fa-pump-soap:before{content:"\e06b"}.fa-video-slash:before{content:"\f4e2"}.fa-battery-2:before,.fa-battery-quarter:before{content:"\f243"}.fa-radio:before{content:"\f8d7"}.fa-baby-carriage:before,.fa-carriage-baby:before{content:"\f77d"}.fa-traffic-light:before{content:"\f637"}.fa-thermometer:before{content:"\f491"}.fa-vr-cardboard:before{content:"\f729"}.fa-hand-middle-finger:before{content:"\f806"}.fa-percent:before,.fa-percentage:before{content:"\25"}.fa-truck-moving:before{content:"\f4df"}.fa-glass-water-droplet:before{content:"\e4f5"}.fa-display:before{content:"\e163"}.fa-face-smile:before,.fa-smile:before{content:"\f118"}.fa-thumb-tack:before,.fa-thumbtack:before{content:"\f08d"}.fa-trophy:before{content:"\f091"}.fa-person-praying:before,.fa-pray:before{content:"\f683"}.fa-hammer:before{content:"\f6e3"}.fa-hand-peace:before{content:"\f25b"}.fa-rotate:before,.fa-sync-alt:before{content:"\f2f1"}.fa-spinner:before{content:"\f110"}.fa-robot:before{content:"\f544"}.fa-peace:before{content:"\f67c"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-warehouse:before{content:"\f494"}.fa-arrow-up-right-dots:before{content:"\e4b7"}.fa-splotch:before{content:"\f5bc"}.fa-face-grin-hearts:before,.fa-grin-hearts:before{content:"\f584"}.fa-dice-four:before{content:"\f524"}.fa-sim-card:before{content:"\f7c4"}.fa-transgender-alt:before,.fa-transgender:before{content:"\f225"}.fa-mercury:before{content:"\f223"}.fa-arrow-turn-down:before,.fa-level-down:before{content:"\f149"}.fa-person-falling-burst:before{content:"\e547"}.fa-award:before{content:"\f559"}.fa-ticket-alt:before,.fa-ticket-simple:before{content:"\f3ff"}.fa-building:before{content:"\f1ad"}.fa-angle-double-left:before,.fa-angles-left:before{content:"\f100"}.fa-qrcode:before{content:"\f029"}.fa-clock-rotate-left:before,.fa-history:before{content:"\f1da"}.fa-face-grin-beam-sweat:before,.fa-grin-beam-sweat:before{content:"\f583"}.fa-arrow-right-from-file:before,.fa-file-export:before{content:"\f56e"}.fa-shield-blank:before,.fa-shield:before{content:"\f132"}.fa-arrow-up-short-wide:before,.fa-sort-amount-up-alt:before{content:"\f885"}.fa-house-medical:before{content:"\e3b2"}.fa-golf-ball-tee:before,.fa-golf-ball:before{content:"\f450"}.fa-chevron-circle-left:before,.fa-circle-chevron-left:before{content:"\f137"}.fa-house-chimney-window:before{content:"\e00d"}.fa-pen-nib:before{content:"\f5ad"}.fa-tent-arrow-turn-left:before{content:"\e580"}.fa-tents:before{content:"\e582"}.fa-magic:before,.fa-wand-magic:before{content:"\f0d0"}.fa-dog:before{content:"\f6d3"}.fa-carrot:before{content:"\f787"}.fa-moon:before{content:"\f186"}.fa-wine-glass-alt:before,.fa-wine-glass-empty:before{content:"\f5ce"}.fa-cheese:before{content:"\f7ef"}.fa-yin-yang:before{content:"\f6ad"}.fa-music:before{content:"\f001"}.fa-code-commit:before{content:"\f386"}.fa-temperature-low:before{content:"\f76b"}.fa-biking:before,.fa-person-biking:before{content:"\f84a"}.fa-broom:before{content:"\f51a"}.fa-shield-heart:before{content:"\e574"}.fa-gopuram:before{content:"\f664"}.fa-earth-oceania:before,.fa-globe-oceania:before{content:"\e47b"}.fa-square-xmark:before,.fa-times-square:before,.fa-xmark-square:before{content:"\f2d3"}.fa-hashtag:before{content:"\23"}.fa-expand-alt:before,.fa-up-right-and-down-left-from-center:before{content:"\f424"}.fa-oil-can:before{content:"\f613"}.fa-t:before{content:"\54"}.fa-hippo:before{content:"\f6ed"}.fa-chart-column:before{content:"\e0e3"}.fa-infinity:before{content:"\f534"}.fa-vial-circle-check:before{content:"\e596"}.fa-person-arrow-down-to-line:before{content:"\e538"}.fa-voicemail:before{content:"\f897"}.fa-fan:before{content:"\f863"}.fa-person-walking-luggage:before{content:"\e554"}.fa-arrows-alt-v:before,.fa-up-down:before{content:"\f338"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-calendar:before{content:"\f133"}.fa-trailer:before{content:"\e041"}.fa-bahai:before,.fa-haykal:before{content:"\f666"}.fa-sd-card:before{content:"\f7c2"}.fa-dragon:before{content:"\f6d5"}.fa-shoe-prints:before{content:"\f54b"}.fa-circle-plus:before,.fa-plus-circle:before{content:"\f055"}.fa-face-grin-tongue-wink:before,.fa-grin-tongue-wink:before{content:"\f58b"}.fa-hand-holding:before{content:"\f4bd"}.fa-plug-circle-exclamation:before{content:"\e55d"}.fa-chain-broken:before,.fa-chain-slash:before,.fa-link-slash:before,.fa-unlink:before{content:"\f127"}.fa-clone:before{content:"\f24d"}.fa-person-walking-arrow-loop-left:before{content:"\e551"}.fa-arrow-up-z-a:before,.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-fire-alt:before,.fa-fire-flame-curved:before{content:"\f7e4"}.fa-tornado:before{content:"\f76f"}.fa-file-circle-plus:before{content:"\e494"}.fa-book-quran:before,.fa-quran:before{content:"\f687"}.fa-anchor:before{content:"\f13d"}.fa-border-all:before{content:"\f84c"}.fa-angry:before,.fa-face-angry:before{content:"\f556"}.fa-cookie-bite:before{content:"\f564"}.fa-arrow-trend-down:before{content:"\e097"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-draw-polygon:before{content:"\f5ee"}.fa-balance-scale:before,.fa-scale-balanced:before{content:"\f24e"}.fa-gauge-simple-high:before,.fa-tachometer-fast:before,.fa-tachometer:before{content:"\f62a"}.fa-shower:before{content:"\f2cc"}.fa-desktop-alt:before,.fa-desktop:before{content:"\f390"}.fa-m:before{content:"\4d"}.fa-table-list:before,.fa-th-list:before{content:"\f00b"}.fa-comment-sms:before,.fa-sms:before{content:"\f7cd"}.fa-book:before{content:"\f02d"}.fa-user-plus:before{content:"\f234"}.fa-check:before{content:"\f00c"}.fa-battery-4:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-house-circle-check:before{content:"\e509"}.fa-angle-left:before{content:"\f104"}.fa-diagram-successor:before{content:"\e47a"}.fa-truck-arrow-right:before{content:"\e58b"}.fa-arrows-split-up-and-left:before{content:"\e4bc"}.fa-fist-raised:before,.fa-hand-fist:before{content:"\f6de"}.fa-cloud-moon:before{content:"\f6c3"}.fa-briefcase:before{content:"\f0b1"}.fa-person-falling:before{content:"\e546"}.fa-image-portrait:before,.fa-portrait:before{content:"\f3e0"}.fa-user-tag:before{content:"\f507"}.fa-rug:before{content:"\e569"}.fa-earth-europe:before,.fa-globe-europe:before{content:"\f7a2"}.fa-cart-flatbed-suitcase:before,.fa-luggage-cart:before{content:"\f59d"}.fa-rectangle-times:before,.fa-rectangle-xmark:before,.fa-times-rectangle:before,.fa-window-close:before{content:"\f410"}.fa-baht-sign:before{content:"\e0ac"}.fa-book-open:before{content:"\f518"}.fa-book-journal-whills:before,.fa-journal-whills:before{content:"\f66a"}.fa-handcuffs:before{content:"\e4f8"}.fa-exclamation-triangle:before,.fa-triangle-exclamation:before,.fa-warning:before{content:"\f071"}.fa-database:before{content:"\f1c0"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-bottle-droplet:before{content:"\e4c4"}.fa-mask-face:before{content:"\e1d7"}.fa-hill-rockslide:before{content:"\e508"}.fa-exchange-alt:before,.fa-right-left:before{content:"\f362"}.fa-paper-plane:before{content:"\f1d8"}.fa-road-circle-exclamation:before{content:"\e565"}.fa-dungeon:before{content:"\f6d9"}.fa-align-right:before{content:"\f038"}.fa-money-bill-1-wave:before,.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-life-ring:before{content:"\f1cd"}.fa-hands:before,.fa-sign-language:before,.fa-signing:before{content:"\f2a7"}.fa-calendar-day:before{content:"\f783"}.fa-ladder-water:before,.fa-swimming-pool:before,.fa-water-ladder:before{content:"\f5c5"}.fa-arrows-up-down:before,.fa-arrows-v:before{content:"\f07d"}.fa-face-grimace:before,.fa-grimace:before{content:"\f57f"}.fa-wheelchair-alt:before,.fa-wheelchair-move:before{content:"\e2ce"}.fa-level-down-alt:before,.fa-turn-down:before{content:"\f3be"}.fa-person-walking-arrow-right:before{content:"\e552"}.fa-envelope-square:before,.fa-square-envelope:before{content:"\f199"}.fa-dice:before{content:"\f522"}.fa-bowling-ball:before{content:"\f436"}.fa-brain:before{content:"\f5dc"}.fa-band-aid:before,.fa-bandage:before{content:"\f462"}.fa-calendar-minus:before{content:"\f272"}.fa-circle-xmark:before,.fa-times-circle:before,.fa-xmark-circle:before{content:"\f057"}.fa-gifts:before{content:"\f79c"}.fa-hotel:before{content:"\f594"}.fa-earth-asia:before,.fa-globe-asia:before{content:"\f57e"}.fa-id-card-alt:before,.fa-id-card-clip:before{content:"\f47f"}.fa-magnifying-glass-plus:before,.fa-search-plus:before{content:"\f00e"}.fa-thumbs-up:before{content:"\f164"}.fa-user-clock:before{content:"\f4fd"}.fa-allergies:before,.fa-hand-dots:before{content:"\f461"}.fa-file-invoice:before{content:"\f570"}.fa-window-minimize:before{content:"\f2d1"}.fa-coffee:before,.fa-mug-saucer:before{content:"\f0f4"}.fa-brush:before{content:"\f55d"}.fa-mask:before{content:"\f6fa"}.fa-magnifying-glass-minus:before,.fa-search-minus:before{content:"\f010"}.fa-ruler-vertical:before{content:"\f548"}.fa-user-alt:before,.fa-user-large:before{content:"\f406"}.fa-train-tram:before{content:"\e5b4"}.fa-user-nurse:before{content:"\f82f"}.fa-syringe:before{content:"\f48e"}.fa-cloud-sun:before{content:"\f6c4"}.fa-stopwatch-20:before{content:"\e06f"}.fa-square-full:before{content:"\f45c"}.fa-magnet:before{content:"\f076"}.fa-jar:before{content:"\e516"}.fa-note-sticky:before,.fa-sticky-note:before{content:"\f249"}.fa-bug-slash:before{content:"\e490"}.fa-arrow-up-from-water-pump:before{content:"\e4b6"}.fa-bone:before{content:"\f5d7"}.fa-user-injured:before{content:"\f728"}.fa-face-sad-tear:before,.fa-sad-tear:before{content:"\f5b4"}.fa-plane:before{content:"\f072"}.fa-tent-arrows-down:before{content:"\e581"}.fa-exclamation:before{content:"\21"}.fa-arrows-spin:before{content:"\e4bb"}.fa-print:before{content:"\f02f"}.fa-try:before,.fa-turkish-lira-sign:before,.fa-turkish-lira:before{content:"\e2bb"}.fa-dollar-sign:before,.fa-dollar:before,.fa-usd:before{content:"\24"}.fa-x:before{content:"\58"}.fa-magnifying-glass-dollar:before,.fa-search-dollar:before{content:"\f688"}.fa-users-cog:before,.fa-users-gear:before{content:"\f509"}.fa-person-military-pointing:before{content:"\e54a"}.fa-bank:before,.fa-building-columns:before,.fa-institution:before,.fa-museum:before,.fa-university:before{content:"\f19c"}.fa-umbrella:before{content:"\f0e9"}.fa-trowel:before{content:"\e589"}.fa-d:before{content:"\44"}.fa-stapler:before{content:"\e5af"}.fa-masks-theater:before,.fa-theater-masks:before{content:"\f630"}.fa-kip-sign:before{content:"\e1c4"}.fa-hand-point-left:before{content:"\f0a5"}.fa-handshake-alt:before,.fa-handshake-simple:before{content:"\f4c6"}.fa-fighter-jet:before,.fa-jet-fighter:before{content:"\f0fb"}.fa-share-alt-square:before,.fa-square-share-nodes:before{content:"\f1e1"}.fa-barcode:before{content:"\f02a"}.fa-plus-minus:before{content:"\e43c"}.fa-video-camera:before,.fa-video:before{content:"\f03d"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-person-circle-check:before{content:"\e53e"}.fa-level-up-alt:before,.fa-turn-up:before{content:"\f3bf"} +.fa-sr-only,.fa-sr-only-focusable:not(:focus),.sr-only,.sr-only-focusable:not(:focus){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}:host,:root{--fa-style-family-brands:"Font Awesome 6 Brands";--fa-font-brands:normal 400 1em/1 "Font Awesome 6 Brands"}@font-face{font-family:"Font Awesome 6 Brands";font-style:normal;font-weight:400;font-display:block;src:url(data:font/woff2;base64,d09GMgABAAAAAcp8AAoAAAADFD0AAcoxAwUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAATYCJAQgBmADkFQApX7Ki9Z8y5BYBYgdByAlHopx64DU4DwAANTWnwdlRNZpewBUVVVvCcHdq/YfIPz0y29/+NNf/vaPf/3nf38ZGLsDYtmO6/mG/6/9svPuzA8wu9iFXiB2BGp1L9hlYSJkVCqyy0/5lYAuCG8JN8tgoteJAi/qvJrzIuZl0hcjyZUyhQeoP7H362AKQyvwBDhVFsocLksg5iJHBwDPEiNEdjYt/987rf7eEpRKqpItC8oQsK1YClBZsZS4yZ1OD2CG6MT7gJbJS5ndR9OP2AvEXoKvR9CbhzznJEv2EVk1y4j05WwbX91VM76rXc36WePu/O75vT3HHRyHO+DAH1qcPySMFSuBsO4BuQWB/v4fSff/AslzMi8h8//II9fj9+Ws730jIiMzlSLbAlfZRXaXNF1NypItDVLNfCDaAfGKeEe4AqazB1z9bb//n2zqv/vmlSltp+7MbJ+dmQUW2Nk2gEBCYIOqmxTZ2JFL47vWJAoprTut+3+lyj6J/OPU0uDn+fXf7M9aa4se0TK5Vefqe3VK7xNtURq6G2+kG20gCkS8EY9BzLDkEycjJD8ZeRnSYcZjCsScZDKJ3/fztF7177k8d4h2Zpdnd+c93lmah9J7TwSWZJlk2ZIBI5kDjdOfl5+w3ZTiEJXIKdpFJXFTp5C6bt2k4NSFj5CWn3j4gE19PyHitCGE1ZVGKsrc0xtzbqdWl81bn6swdfj/5zvr9z0DqUZqDTIQ+gmNNAaprKRGxB+tlyf73/tW+p+PBvGFkv1H1QhpP/AraU2MqywZ/ltrn2vsc25GzLmZZdzMauNmVRs3q9u4Wd3GrW7czC5isgpNRnUDfNEAwR9NMRMgv2rggRMk/9c3uxHxsoAnbnYjYrKAEbcaI7KJEQWCRoOcBskv8MiYAJ7Gk1Rf4JOjhfljDG8sb/wG+QyQfCMdb2xrHEsr2xkbMknQX6NRIQsOYrfKmOA9c4oPKSRpq8lY2W3v+6wPKqIEMpmEmogz9z+iLkBNE1sWnM4zkWl1+61maQkJxdiyymiwkM3+n3yTXgUoRUOyMjsbG2L7/p+HqzVetfalJMAwsFeCQS7L8eTrrY/3qvesUK7/AWDlx/snr76+AV/yGX2yAlCCan1tzQlW8BlQ9CWf0ydJ8Ye/Q42tZ9SYP8ewgDUHNB89b7/tExnYabsPHDt+pBVaeQciyzV5jtXww5gD1y6dIdHrPo5lK3Cyl3liB20a6AGLQPAlS2CBMotg0XctUWMBDN+14FsWfNeibx9r0C+UcYQ6GuVhzf+VwPMUi77RrqnnUp0h7TR6ZKNJF/W8b28yNquxqPe3LvqWoEJtqNopliWCbktkCudpm6KvjC9Ovq3DPtuZ2E8QFAsq2lpTIahR/4lgUq8dfbNO5N4e5K/j4rvC1xUYEFTrhKYnY4wbxJhvqzlB0K6IxsQ2WedokSVKdDHOlu/UDWSmjpsvC6yV/brv4701jrFIXoFqi+151cjDXF1v8212iiz0H0fyY6APO6VCtviSOpGlfiDnXLbV2RhdydxWqu0/8zuCzVNyHhyvDRRboouDMQWbDbYw8xH/hhVzT4S7fpVIrSVKFKgUSNAyZ+N3F+oPLc1Y6A83watVlqgfV1ys6JsjCPLjkX5N3RQF3/TpyHxfYtt+BKUWsNEw39Ie5wukG2MJ33FmaU4N6hkd/db/0RJBXVuFcT2/Hgu0Cd8QlLchbRt8HihtfO8PtjS+85bqrxYrkJvHaImvOwis0S6rCN+8ZlviAtfdhp9ddfwQF4jrAN/RtvIPcbM07+s+KfbhdByjh3HHHKGzdtamfoj5tESRhrpuStd9b0+n9HQ75g4FqnArvriIJd/UeUrsU51OpMM/F2m1SI9FZLlCZNojBw6QIzotNo9FGa+0ZfKMwbwK065Hx+C8EMuh2WfZPrnjKS0WNGLSzdvulwffsumtLGYM9iD/moXVRGazOUBD/Ib1OUjmfTyKlNjP+OacN8e5EQvKXNJ66UOHNwPr6shpBVyHjjLIXy782mqWjwPCj10Adom32AEibh5oh0Cfq3Ycvd4m8z/tbh02ulNL9KvX59cRprp9xHYI1+/YIQHzpv/NsdcY06nNBN70NUhdfka+MLvYin0xB2g87oiHbTZTHKnJ54W44jrTb4c4kx3MeQzxZON0iOEVE0BCPelfxid2setiT+LcxbTrzOuAWsdt1kHmXxUYix3gsyZyXXPpOWqz2Rf0gQvEJfPFTlkQAAC+AGAGgLznScAvMN99pHnBDMHX/n9Z4RtwF8DnrQ9AALyFXJAPikAl6AQ9oRf0hj7QF/pBfxgAA2EQDIYhMBSGwXAYASNhFIyGMTAWxsF4mAATYVKBUgVaF2hToG2B9gXWqAFqlGpRs6sN1VZqe3W2Ot+Zlfg8yZ7UI+lDspJcOblR8obkTcnbU0qljEg5mnJPC9WsWhGthFZNq6l10Xq7+rsGuma6FrtWuja53ricGIUFsTCWx6rYFjthPxyIg3AYjsRROAan4QycjUtwNa7HTbgVD+I5vIqP8R3+xH+oYxqZKYgExVJJKk0VqDo1oW7UkwbTMBpB02gmLaSVtJrW0AbaRHvpEB2mo3SaztNd+khfSeUuPJansoPn8Hxexut4I2/j3XySr/B1vs13+R7f58f8nD/zN07mP/yP/zNzKmdJPxkm42QumUfmk6VkU9lKtpcd5RuZIjWZqkfrRfVSenm9pr5S36rv0vfrJ/Uz+lX9rv5Yf6ajbuhpbsUd6a7hruXe4n7ofuz+bJQyuhqTjTnGAmOJscLYYJwwThmXjbvGK+Ot4TSSPNU8tTxbPXs9Dz0vPU7PD68XAHJBHigMJaEq9IRe4Nu/KW3V8eq8x1MyZUTK4ZS7WogWrxXRimlVNDsdmPHbbnC9fF2VKv1xEA7GETgKR+NEdOBsXEA/3G3ErbgdT+NlfIjP8Tv+RRemkYkCKYzCqSSVogpUmRpTN+pBvWkojaAp5KDZtJJW0RpaS5toDx2gw3SEjtN5uk1v6Aup3IUH8ASezrN4Pi/iFbyBt/AO3sun+Trf4rt8j+/zQ37OL/kbO1njf/yfmXXOkiYZICNkgswj88n8sin97S9ZavK7HnzgwcGSRldj0l99ubHOOGacMi79zflmJHnKemr88dKrer95P3nfed/AD/swZ6Gc2XPG54zJ8TtHUg5njps5rmdvnG1SthDbH9sYWw1bjM3fet56znrKmteiWQ5ZVltaWupZKljKW4pYClkUSxAAgPJHSVK+Ku+Vnco6pd/Vr9jrKHYAJQ+AEgegxCoxAEq0Eq4oSpgSpJgVEF6RKTIEi/8iWTjFS/FMPAUQN8VVcUlcBBDbxWaxUSwVU8UUMVlMEhPFMDFUDAEQfQBEbwDRQbQD0IelJ5WeWHpc6cGlu5buXLpTeDU8FZ4Ij4dHw8PhwfBAuD/cG+4Jd4e7wh3htnAr4ZZwc7gULobz4Vw4G84QToTjhP1hX9gddoWdhO1hTpgRpoTJ2R+zH5P9KPs6QLZPtmO2bbZltkG2XrZatnw2ZDOZPzM3Mtcyn2Y+ztyTuSszKFM9Uy2TTr+UPplem16SXpiel56Tnp4elB6Y7pXumG6abpyuna6V+jj1UWpdanlqSKpvqn2qpQTvv6WTq3/cvDt5OHkwOZ+cTW728PaSycn4LR6ZdD3OdyY5TrL5ypu33r6YVDy7R32x/eXVJ611vw7r+9q6IGn9pGVz9Syf2fXt0/+IXW+9lRbij4hEEUUVU1wJ5ZRXQUWVVFZFVdVUV0NNtdRWR1311NdAQ4001kRTzTTXQkuttNbGersddrOvkiQplWSTKsljspCxs/6V9VmemKABGt3wVmmOFiiOtujG3cLFe2I6ymHedrAy5h+sggVxVSx24kJUwyI+WB2LD9bAkoM1sfRgLSw7WBvLD9bBioN1sfJgPaw6WB+rDzbAmoMNsfZgI6zTxv4lH2yCDQebYuPBZth0sDk2H2yBLQdbYuvBVth2sDW2//I2NGm3QHGaTFigIk0m4txO4q/91ayoyRTGbi/xAiXIlVygLbkKC7QjV32B9uRqL9CB3LAFOpIbP6VO5CaRm4LO5LaQO+jzHXJHyB3FEK78zwsM4+pnCwznWt8FRnBt7gIjufb9AqO4XmaB0VzvvsAYrg9fYCzXb1lgHNdvW2A81++ewgRutOVGO0zkxlqa0mRuPM6NJzGFG+9w412c7iKfIZ/FTPJVydfAbPIteIz55FuRb4PZvnwP8r2w2ZfvS74fDqP8zH2BFeQXLLCSwpIFSlBYNkZxCvso7MdkVDjJC6yhcH6MtRRuoXDb3lf4gsLXWIsKV7YFthIrLLCN2HSBisTmX/srnVHszFPYTuxB7IkdxEm0QFHi9AV2ERdPkTxGXEJcht3E5YTz6VcQV2MfcS1xHQ4R1/MeOkzcQNyII8RtxN04RtxL3IczxIM0hXPEY8RTOE+8SAvcRLx5CjcTbyXehluId9LN3G3Eu4mP4nbi88SX6EOuo3mY5lHcRPMizcu4leZ1mvdwB813ND/gAZpfaH7FwzS/07R4lOYvmr8wnuxD9sXT5CByMJ4lh5Mj8Dw5ipyAF8nZydmxJzkHOSfeIOdDu/QWuSC5KN4mVyJXxgfkpjTGR+Tm5BbrUV9uRe60zu2Qu5C74jty920P/EAeTB6KH8nDySPxC3k0eeJnlGfyFPqQZ5FnoyPPoSn0I88lL8Cf5EW0y5hIXkNei3/JG8ib8D95M5VFkLeQt/rJ5w55O3k30Y+8n/cwBpNPk88SQ8h3yA+J4eQn5KfEWPJzWhDjKRuPiQmU7Sn7jGmPyv6UQ4hpKIdRDidmohxFOYaYhXI8TxmzU06inEbMQTmDct4dyTUuF1AuJBahXEK5jFiMcgXlamJJyrWUO4llKXdTHiHWojzOU8QmlKcoTxObUp6lBbE55bkF3qY8P0VsQXmR8jKxJeV1miK2obxJ+ZjYlvIZjYk9KF9Qvr5v6ivfUn6+k4rKr9uCOITy2wLnU8oUcSilpfxJHEb5j65RDKP2ofYnjqYOpA4njqeOpk4kTqNOpk5BnEudihbEZdRpxsQg6rTUOX5tLqqr8IK4mbrmgriFut6CuJW6wYK4jfrOFHE79WvqN8Qd1G8JfUz/HfVP4i7aIbTjiGdpZ+YFxtDOscBY2nkXGE27xAL9aM9cEG/QXrog3qS9akG8RXv9gnib9s4F8Q7tPQviXdpHF8R7tM8uiPdpX14QH9C+tiA+pG0WxEe03YL4mPavBfEJvZEL4lN6YxbEZ/QWWxCf01tyQXxB75Ip4kt6L9B7kfiK3su0IL6h9/EU8S3d7HRzEN/RbUJTxA90B9IdRPxIdwwtiJ/pTlgQv9CdsofxK93pdGcQv9GdR3cB0dDdRncHUenuoin4cDwFOP00wOlnAPAM4PSrtAC/B3D6Rwvw+wCnfzoF/gDg9DsAp38LgD8EOP17KiMAcLYDcHYBfvF2h7NLAGf7AMQBOPt9XkBKAGdvW0DKAGffXEA8gLM/XEAqAGd/u4D4AGf/8hchAeCTH3pNCqCBATCb4AgnYIKAABrQAygKWqTKk1mcpYoWMpWeokWcxVIVnbxQKi9aKpKR9JRJTdpSSZqk3uDhhx9+OP3whz/88EOjhx566KHswx/+8EMPT/8JhRtgM3AFonCD6UngCuwfHx8fT5/sHx9Pjo+PkR9Pjo/LgSsQhRtMh4ErEIUb4BgAgMz+f3YCt+MYQmgD+DupUkncpmboqUBGWbfIe56WF3mapCY1ZSQHjLkuY4y5LmNNyW2bS8ltm0scuYwx5s7AZYwxF2E6RD8IfEQ/CHzsc/cAs+s4wTfCz8BzAfxIKhVRqjJVqLzIZSSvfBS7MgoDasaxoo+iSc00SZOiUPRRbKdJb6fIs0xRLi9yKWlBpVN81KUU7SNHsx3hUkpYf8itq+FJQfyGaVYxwzA8Co9wrNmOOHfVpRTPaCI7+iqIfmeuutQiSr3xaDQa/WytPns2wR2cwCsA/K5UKgpD1c22VaSkimRETWqmqUqo6ZU0klJ1cSPy6tSkoQqoGbfTpNdT2/G2ipVSSfqjK2ydyKjIfftgSZoqpbZ1rkmRFz21U+TZ2GWMaLgtqEU0x3a3thfmUNOJU1UaRrIaRC43Ta9SC6qz+l8EEf1aPeSGbpjcEV4YllWjRoim2TWlRdVqEAlBDd+vBZIxFyeMuUtoaY7tCkqJRQUvlwyTljgalsXdeqM57/u2pbVcxhhzY41SZnIuuG4Y1DQ103EqZcOkJQdNiwq33mjO+b5tabHLGIAGMDvFEb4BQmjDFgDmPaV20iRuU1RmGMgo6xZIkzShJo1kVOQFXlj/QsZsIezp5PhEHJziYrO5iE+b4cr6m20hbMamk8/1OGBLfqXiLz2dMYPthgFn09kJvhrHcIuvo0JFwr1NSj0+4NWIqjhYkxeFSpXffrqUauqJy9izHMEp1TT+nOc6mmZaXDjPgl3rmVz6F3sO1zRKd4NjxtzXX6Gaxh3BrYOrlAvuaJp55XHMNx/f//yx9OqL53BNo1de7zIGCOXZ/+AH8BooAMwi2VDFqk1NOx/KVJhTdu6pTHWLvLeTJnGsegjxYK/F1hbXrtw9Pkskisgp8QkOclh3HcDPomkkIxk+lSdpkvYKkypl0jC3Et+XTtIkBbKxcXCwsUGO/5rjlUYDsdFYaSGoNEbvxwyx0VgZfYObAP4sBXwrrAD4SZrQbIVIu1ehPGuMZPPf2Rtj2SsPHaJRS3C+OZhhNBweTzPAkc+YPbAE5w7R6OL0rw3Ej7U4BMDZ922wbhvAb1OqIr+zUxS22GzmVKwpkK9L0iR9ol1dQO24xbXzF5dXCK684cN97DyDkFH38xJRyjYOq4uhcJGFVSQryxfPr71+HBfx/fLnqu22lIjpxxzgGA4A/J1CqTzLVFbneLxJs3M7TRVux0RSqkhmKi9GdUasMnrNwJj7PyGjpddG/SRFTJP+nc16o0QMXeecc0rE/J2LQYAYBIs/pZz5fZcxHI2uelh6EaZJv5+k6JXndc45NXSd67UqqFrdD0svYswFwNkPZic4wjfBHoCfpxnzPUBNqikTwVblEyJ+x+Kzhq5zwbk5osz2Tnxlm1a1Tc9N8b6n4nME56ah63z6P+VS6dDoWxxGwva/A5vqJXQPXRnvFKve0u62zNqk+aW3hs8x6F/insVqTRi/UHdq94z5zZLNSAuPqwRv4bO+fmG5VGc/yQpXHF76wBr/vk9wgG+EGC7yJakyaRAG4bbaVrGYTdIkLWQQocAu1+3HV+RZV0YyCv+FIdqO4OyXOiRg/0RW1waXqkJEslaTkRBnj41PdQRnDNF+z9oeIpIAXre/vmHc+u/1qMa2qL597Z/pusPsOh7gGBZwe6DV0O42Rn1EfuMIFduyTizOOdc088tfh9ykUrk8HXFNM6ngHA+RhV8pET/m23AAPwqACb40zlDw4VIYSZ/dwE6apHlBszjzrybX1+VFprbVtjryve1FW+MLBSVT8anEbVzq5M28s4QYV10Xlzr5IO8soetWYxyVy+VGpYJYqTQGJ0vlZvN6wBZbucNSJ+8tVeqNK5dqNuqVpd4IK5WG+rttVCo4+DaY0O/khXF12AXwA6lUFE2MI0ZQl5qhNE6UFyk8CkLYyA3fXQ6cfvjBy2ur2PgEaku/xLhwbERrgODwI2NjY30fFxN0vVh9j43IGBfOrVj4pVN8Nb7aY4TKFUMZag3WzvByHZXLSOLL43fvv4cm13WDcs6nEw/RwwHnnOIzOOf0Na+hnHOu68bY9n17bOg6t0lZGQb4ARxACGtZ26k7kUYrs9x9K5TY7R7QwSFBnHU6LtuM8nzT5A940p7i6Bq9b1rikKEMntIOK2hHV56sGbrOkU6/e4k/Fge/OdPJYxAoz05wG8dwHm4GPiZWRaEy6QCWkqeivMfIHBVmi+1+7naMHHbN7txaitd41FmdK5X7OsvtoTPCuQZ25rV625+rb2MbniSsRmVurqV3cPk6Y4Luyo4EYDYhgBM4hMcAUEWsRDKS3gn08q0pFHWgOqg82JmBZmeGIYe8a5ImqdSZ6+HuPCckz++24EVv2uu324jtdn/vpuVjG42VjbmlrN6H15qWMPC7kjy/eyBMTxiRPL/77jwH8MGj4cjaVDm+1TogDnyMtBhzD+nqXe7OczKRrxjPyWw6u65Z4xYsK50FJtUUVb28KFTmo8C3+BcZqdL8OIsLJa+zMLRetGzohuCcm4tfbRqcc2Ho+vKLVq9du3bTTfjzPqI/PRlyzk1dN8RttwlD103O+RCb0yff+148jRdhi2GMtuP7AI6C/R4o4yzukeUQcG30ADA/yjtL6Hlz8+2rw4kBs5XhcDgCtvwIx1ipNMZjpPvWXurk8fy8197OO0s4GUEh/Tk/+662uOMY1gEwiZUqtl2mc6GvRt+rWLrneLM6f15tbanz55UtBLPtg/vvP1gvuW5p/eD++w9smwlho9raUoOB2tpyVR7z8uWNvb29vfX9fZsLmzEcZj20gTsDY5MNYrjmQl4WZ7GnBIRCM5Re6mbzC4gL81n3UuMcGQ+HwyGaWmwvbCFbH1upNHAwnWhsZpzEfnfVs92AptpYSWAye9JR3QkIhuOyAQsRJzaPZjdDXW6/URihb0AdiD8bObuIrM3jf+b6/7wJjqFvVNBA5MJ1Pfjh6AKffylJT/ird25tjb+8Id7XtcB1kV28+LCdHuPBCzYis7mw1y/h0BJdXIp3a/dgrisf3OsTs90QKZgQto3IlrGtbmSEY+gCdMJe2EgDsne0VTLqwfsWLT46YwZPDwFhMplMDOlG8SM3nd886TebFVtuznyqX7elBiwoeGYcqrMglDVHaKvNU7Y0lR+sQ3cVAGMxi57yLOFvE+GNplXPBz+CTZex/i9HFsfSONuNmXNpULfgdgb9pn0d98dMMW5xb6posw9w6uYCgccVWDDb5sL+nc2r4rVNuPw6iwvHIZr182/AnwGKrj3e+mS7tKdnL2qg8U+9MnE0YllcON/6hT7hmmOnsRCX2uzF6rrtNOm1wcrAZczEPCSue3E6rguctGBs2Ld4700p4x8NL34VecqnPSNV5RfJCxm5b32rG0VyoO91tufZr7PdJTHCPzAqZ2cVw5Id6iSMvu66X5/+WwW8tLAg+9c4wrfA0tchVJ5NYeezpXje1TAsIT3PkSAsTb+7vA5/3yxPv4zLl3eJ6SiyzBJemP755S5GFg7rRAuHPe1HNqDqCRTxudKkLhGhgI83JE/WOp0oDKNOZ23p+Z/g/MJO79y53s7CPL6vG4ZRJ1ldTfaTnxsZX8iyxYWFxSy78FDw3d7dGBZhkydImQNRxQf0ZBZnbrsNqcLIaztsqZXBcDgMptghUZiBYYZh62QyONykneLP4xf6WTIAKOLD95J5ES8gu/dMalJjKA6C5RFpUqkg8/GkA7KxcbAe32QhOrYQ7MbFSrwN1noH/wQIW73t7f3mZNNLB/c7QjAL0blvtXAfzvxse0/ibvf+C3v25k171+Ycw/dvDc6xzYBiCpp0qHIpco8/+skBXK4R697lWhXJ8sqFZ03WtWWEGMk2GYUTYA1/eSBP8yJvKd68sLJMTsYYyXZbRhj3yP45HuA74Ke4CRGrRG6rSCgZ7hlR0eMwjjZCCQ9Gkf222gKRySWp0nh+kcFqS9JCUZXQH13QNUMX87sEa426rLrCdPvFVb9aCwydoAiOfEwcQRli4Adir7nPv3huNt1+cdUJIy6oqemOI+wgsA1jr4kPiEbAbFZxkTK7VJ5fWBpUI65ZlBJEgztCmIZONDSpSSz3I28YAyk5GvqRn7egpqZpOllctEq8uHXMSUG+5FQsJGJA2K0x5h6xlMMxUzzH6GrsvxC3LHDOEB5aabqMaXkevugC4Izhie9g5JPxOcIT//CXneCr8U0H8kO+8nMyWU2ZNEm1qN2xAefcfPVrRPyejVkYWmNDNwT+nqEbYvo13BOGbhic8+nIR/RxxDk34lldso9vQpjieYaf75Z4VVMmbZ+3PBQON55xnyWldd8z7Dhvw9CvsUjSu+6yoohd0w1D4O/rhiGmf4lLEWI0/WtMhGHoBnfEdBSSEOX0X0MS4kg43NDm2dnsO/gqfGPceiBS5dLo371NKf2bIfzqX2xFpx5DsMcfZ0LYDqL1xBMAgnJEI1aeeAKfiiKXfNObHESLCeG8+z1w0X7zm+3nc+33vNsW2okjt5SqyxCmx6hjfcf0LcG5rRHrt40/7W9bRLM5F9bxMf6KrRHLEpz/2a9/jP31P+NcWBbR7M98xj95/74/O8HX4RiS+NfWGDXehHGwdYOAWXz67z/oUHecTgJmcQx/EH1d9fzy9KMU2fP8Et4WECsjwGdfxlP8DGjZre62Usb3ciS3Q5yJi52YAjm9iAxkkEVZN8si+0mSJjRDInswX2V3SqTcmxS1ziu2qTm1Ia65PO816456NQ6ZcEWgc6/s16RAjMPQrEmCiDjz5QlW61v1umWXS5V1as01LmzUGxqWSxm1HXQc12WItq5rlpWEFAnqGgpHlD2mI8FmqygOHr2yX6IW03GwEXgVutrExSgKGnFEMGy32+ggIYQgooMkkmXL0EltYyPpoDY3t6hVfIKObaBpUMsiaOuELCz4dScMGCHIHFGrJeVSiR4URbOFZG/3wV4cWwgMmrMTsoxj4ODDEtwER/AMGME1+A0ArBf6XqdlcdZTcdHf2rEKESxTyF7Yy0rgj9h4bSeS5nareZH3YqqKQlUu8yUylWmsqIpVSCCTtlotT+l0YQvnuZm264z72M/N/sgkfUXTdSK5ME/QdYPlO++8887fRMOkrktNA78h2+b8wtraxpG7jLjsHj11Y/1te3t7RXNhoX2LYRgLRnWuOTeaPol8+iTylwwGiJVKXjz19PT09KkXLiCe6z/rXsuyyhQbZH5BRo67GLouTr//Cze6ho6bulHafOSRR65ebLU4v4esbeDbcGPj1kekLUXkeZ73yCP/MB30956xtpMlHTK9D3+9q37yx7MdZPV6vQ4AQIDMTvBzOIY5uAGgk+sVxI7Inb7Y4dF2Sgu5EqVpRo/ZvAlFnhWqUHnWlVJJr/CfyvjEJpJLF4+OLl4i5NLFo5XE0Oe7OkEfMbyh3++HqOn6uXO6rmHY15DoN1XR0En1Jp2gdn/v5vv7fUL6/fsf6PeJi3rCdYK1xcXqr6+vr1/VNUJWVgjR9KvrxNDJga4fEN0gAADEd8370AcoaEGJYbFoDVLFaOUoHbUy1dbG0U7v8SOg2Ww2EdutDG+88coVlXWWOjgmnaX1tapjMYcHzWXPq9RrZbw5a7Vx/vz583hTt91Gub6xd67bPYevCcNO0q3PLTQaYb1ELbtSCbDd7mpq+/JAbWt+a+kEJziBfQBfprcTIFk+sShUT1EVqkL1VC4lubL5u1IVygwSlHwOyFBJ1VOpCp88PDzU9SNDH+r64bfvIMaRgebhHd/+9h2HJhpHBrnj2/hjm5ubur5LyK6ubz76wv/efMwku8R4loFbmy984eYWGs8yyC4xH9v87xc+CgAawKxd11WgBjlAJ19qlGHpTpqkHc/z8HC/9KkWtFlSbzA5Mv95WcG6aUeObdtRbDtCmMvvw5Wz8/kcvJVmElumacVJw3Nsa+erwrajxHYcJ7ZMU/zNcheu/D/Fm2tNx07SVitJbZtz6zrrDmCx+6NY5AJ5kLyafIh8h5CKC8E+kOHvLZeDbJANstzw3XQcR1NSJx9/ajWZwjXloy26RrQo0iFOinaoy0Z1E0KYRuvWCSmyshwUSGWLDqh+Hok9bTafikxkg2xQDIp8ns9n81k1qxbTxXQyncRsxydxJCP57RrQRqsxV/XtynRq9YhSilzEtZpjKsU4TN4KztQW/cdHwFfXVp6edJsjAjAmuOCUAgBQShkV/F0QBM3llWiiQszxW+NCq3AajUbDKVoNgEbJC/hbv9txLM/vdB3LO3nWfmU6tVoElbp7iOr869Xi/s3m1nYS1ueuGCnnQjAGgMg5Z4xSCsjuiHQO1PRuln9QuctsFen6elq0CJLu3k/gT+ANpEZm2e5T6KUHWRRpkRZqZZtIo8M3j+fbUeTaAMadd5oAjhtF1isZ+7M777zzTgPAdqPIvsTYK60o8mwAEx7xEB0r8N2XPer6geUgep+V6jWPPvroy1w/sBxE7zNSfs5DdKzAd4kgfO9x+EX4BknIIXIVuZW8jbyHEJgVgyzP8iIv/LIq8yKPtYHkeoNsXIyln0xdtLyel345yMZSuuZIUXVkMemdvUW1qKSv6sp8UXZQ5PNxWWW6kkW1mA8YuUtjOYlleapuWi2KePRXlPAaxlwPwTTlK0Apw1QKnkK510IEsIK8E/NNaiAFIaQUHGAbqbNjOZalfGkY2JPS0KlKIhnH7W2aeK6LGATdURiZ4Lq+wRmLLdNEWksnkWF4puEljMPdoByp0HDgNgoAhqGW13fpYnHmzKJiA626ADbgdpbZiJQaYmN9Z2dtjc7gayxgjNFOJEU93WVctwopet0e/SPH1K7bHCYJtSzcAK1BChGbyrKTUavFgSLsowzQ0PznoxozLYMyQgxCCOAuvISIe+V2GJBVMiYVOUxOEjISKmvn8TyelnPZYvnsrzS9tbhV3jo/BL/26OQRl4ceffTRR9/96KOPPvqef4WiHR999NFH/8fZB86cOXNm+X/Pfu7sk7Y+mdec0Nj7FvwIvk44qQip8rHKlXmYdQzex6MZZRrvWpO7TxiguK775bwB38NudzrbffqB/Wav2rmW1hv1Gv0C18ra1+sB9PvzYydO5OtHjkxKBvv/0Du2r2q36e7u7ePhiAFnaTJrBaHT2No+WY23k8Qw0qe3parVjswIIUTs/RM5gpfgKNkk58i95MXk9eS9hFSNGUSZkBDoW0wXaVVewjaROp5+VnBUKy2jnQOMRZV4wrycFVJk4pa7w5M0kqqREfVoMk/o4eYFN5d/5ZGsZCWzsiizMr2l4bVJ9dA+5rtx7HlSCOl5cep32qvdet1JEqde7643O4AwcBsDP7ZC2zCcuO64jhPXXEjc0PQMpQztRqZ1l58eqRU1DwBcAM8znKKwDQ36J8PhEEaNWbt2/V+trq7GlmHZYRxFlgV+twWu1xyPoem5APX2xDSZU7d9rWyhLDMKLTsJrq87t5sghTal1K75Nu8Xr/EAwEsS74g+qg3bNsI777zzzhfvfp0Qg5C9POKu4G54DD4AH4Ovw3fhf6OBMQ4IGRVpkc9dul5RzsoZaK7JinJQ5suhfLtVvm52W2EzlzWV5aAoDNSVpchuD1yW5SBbXhjLMiqF/AVpOY7jNC1vM5CfdJzJcrAmieQ4vt0SyyqDHd20TGKneDkto/jJTm8/5GNYvd1avS7qjOP0sTtJJ9M04RRVOUnHZVom00lVlYtpWrrazcn0aeG8KmfTRdUsyrdbi9dNlmbTykMvnRuUo6IwLR8znxUylwiyy4tu3bSczOflTCoogmNhLpmWQgIr/YuqLJM0W8xOyyQtKtlyuULfyeVVMasW01Il6uVFWklyDhQaTavVUjEuAFJqULgUXGyUpMWUS8tEZuUg5mo6eToc89CgyE/xb/XhP5MkgZACsBq4CMjqAGAgImsgCqCU1RGBUZZS5IzRmFINjFGfUgcZQ4dSnzIGGgAxpoxxpCmjDBDrjFIQiHWOiAYA1BkCulBjADSEhNLk7L8hXv9xSP+uIAJ8vy9A/Pobb7B5xIy922ZqtLqSK+BM9JR6H6WbMGaGIQApRSWN65WW4DgAjgN/ggv/dibYeFuv1xOIVDTmBrM4kw6gY+MHAOAINTSA0sZP+ZxJZYJrmQDaMGzTYv91/XCNccGaq/1+HDAzAwiplOrD4IAN4DjwXc0YY9oBcH7dcRxKfcoYaEAaU8YKd3Pj8jb063dMWR3gtr5ZSF9vIvrlTRA/UW8REb7W90q0Mz/IBKUgtYELChljAVe+obQGw2g6iI4DaN+ZaRCdLzuOQ7ng7ouz0VBwtnUe9eFwyJipGbvJSA1DgbbtILRsoZBuW3XG6qqWjlYs4Xke1a7g8C93MgvgvF9JdeeB48X/sfcNna9vQshoUNSnIjoUpTGKRksLWEfLfjkteUjP3BSunKjarXE5Hmd9wWv1jc1pLUlcx3HTpJY6zm1orneH/6/40mx1NfQtqygm5dZmmog7pJJRVEvjUCqlwrAOF01z2o6AECRkT4dqOyS2nmq/3UOT+ATm2TSLyylcWe6+9WMf+9jHPvb7//Zv//Zvjz7664/ypcaQXbwEzyb7yFPbCAoEUGX6q6qczWdz+M/muleY0ma0Tw2DNO0rykOSFu243w12eCqj0Iy58/2UqkAGGZcs6hb901dh/M1//ud/JgQR9X+NfN9yvfMXLw+qlTD0K9Qylht1RNTw3Tpqps38n9F0gsy07UqXIBI9C32f6Ug+oKGBS0u9kaZphBBdI64btgkiXmkv1uqXBXLhBxFpNJYp1XUndAX+KJLF0BWoEUJ0DUtuyAii5nl5vIQACMZshp/BEawBYKvVCmQkIxmZHoBFUHjTKKtJ5/sjsKXyFD89vQU/Nr1FCK+1srKwQO7bDSoVe/oDq/OQG4a1ar0WBrqOd5mIozt2d5uDOHZL2LyxniTru4thxXfsWjVdXVwka+sAOsDshACOIYRlOICHATqpTJO4HVIVhOK9Yp4WUZapbrHTS1USx6odmtJI/HNj1aZdqoIwXb5QOz0aZ3G7KXXB+lnzNIlRH41GiGT0KkTEVyKmiFcQn4m4X6LxK1/5yn9m9vH+8v7+Pnk6ItlHfDoi4heuX7+O+K6sjoj4RUTEv96YQfybv0H8nlnAzyPijPAVS6BJRjgEH+bKvet5Xre8SdfLpklsyFSiJuaO2MxZpQoOmvMLkeSccxktzDenk/GkiScrL7q/tYk4nE5wMJ2kk73s+LOs6cMBbm7t8yfX0tkJfhfHPjR5kFmcFcrowIxWwmi1+Hz4+/76r//6keX3YfOFL3zhX37vb1/wghc88rTe9/ZdfOKJJ/72D37rt37rN6DgNDy6tfeL8PfwPXIfIaN8XpYz6xU1Mpfw7kfFI2bFVlljYAmkeJv5bJ6vhdzhMvHoLwvg8b7vm2anu3Hm6NGWjdRmzKyl3QFiMugimrbNEA2tDMPzHJcjNX3fMSlGnmUKAQBSeFK7QRhHlu1KZLZlWWAYpmRPaXe7o42Njf7AidqdU8O82zTNvNMNE60BfQAulWAsbjRi39CBrykPozCMG/26J4XvOZQ7QaCVK43Q84AnaaAolRLRMgytGCOEcEL2ZNlYl3TJPnIDuYeQkQgLjFxbFeveftXv9wEaUN5saE1oDHgC2rcxbCUPcmNQ7t+/f3/dsR2n9sHFx/795Z9CZ/mn/VoKkNb60PnyIhwJwsbyTxthEIQN6DTC4NFjfNv8yH22k8aO/cH7bCdJHPteSGv9A21fvuPfchA2vB1yxCDW3pPwFXvcFZ0nd5IHyLPJS8hryNvJe8nPEVJxWKOi7HD6ovwax3HZWRYr78S0TKbpQMpyXuZSFDlvRgtdq5A4qkqnhCuhiyovhEzSSsgkXVR5ka69tejNiryQ38+P0mS6GOwWxvs/3Z+hSC3AF1zNecL5/ZwnFBmljwC8B+lVwF2HIl6FVAN/AJHiAwxQj2LEOEaMdxde35HDUurdr687vCSMX05qdqnpd6hrAkU4uU65oBal+1E8X6ANSNnNx+EdsP46ARyTupLXrSPoBqf7AfZT3lAAG8cKjYWtblq7rKWA74e1lMOl8Fza8MwveG1+Y97eE/Bj+AJpkQm5nTyX02nYWGIbkl67Upo23Cg0FtsXieIoTatKVhO5YcfWOSuVICtt3oBnIxmCX0A5fVE+Bhrzsp8fOb5Y9HoAvd5icXz588jrVpJUP83h+jqtNQAy6bkoNLqeZICg4Wxne3tnvL7W+/ag3+9r7vydwIOHLsAXjsdjPzOWT+lsbs773cBEEFIIJq9TSlFKueOg1ug4nFKqWLheb4TRcLT85r//+79LJoQUgGavXr/z0GEWmWOmB/ESpKRDSnKCXCQPkzeTnyakyqZZUZaWnlsKX5ZKlaaufH6aUoRcijLALS+JJ1WpmJHWy7KzpScTWP+dSVp2lXxWkGCQzqDim1I43FaWp+e0mCbFvJym02wal9mXRqNRu51v5s1O1obWcLvj+wC+32n7vu+3AyGlCCLOAaTwP2rXW45tO82aPeh1PCkBlHR9IaXwf6nX64GbNgwDBpA2YaDzPM+f+YIXfPqRR174wo3A73T8YO6/yu9By3I90wKwTM+1LBkBhFGjEQYQHP70U8G0PNeyLMv1LBOeGsSOk15zqgPDo7eOiH/oWkqme0/Cb7bBt/ba81Lib5nCj+dxQUmLs9InoO0zf3r+/PnzcPbcuXPnXv6Sm37jN3sPbx89ug03/OEf/uHZs3+4fM/LXgZPJ0QRQq7BS/AQGZBNskPuIM8iLyZfJH9NSDWQ8zIvslLImC3DBmdxXj4PaSbzYu7m1RRSWKL5WZrHc9I4ORIjgl2Fess/wL2CCkshWlaWSToalGWZz20sUTU2tAPuMnQY9r1tRAsIpx3oEwZzmWciy7mjzD85emQptsrSE65blnHpTYRD/BdMxS11D2RbAlLapkiDtOkHgd90fMPwW5S2Pugheh5wLrc0UMNENLJmwzBMs9Ue9Nst09RGs5HdAo16UTTqAPVGUdQbMPEAPA/RAxcS8ENPcE1FrdVxXQjCMEGIkohShgYVtazr+RCGIdxDJaIVSQAZUWQtStGlFEG6sB4YHP4tOiwB5JcoUopUR2E4HEThM8FatwB7fTwAngfgSc7v2Nzc5IYBYBh8E+NoMOj24iiKe93BIIrxGTXX89xa6nmel/rgeQCeB12UhkGFK5nj2GFDa0RtAFoIgOBJ7tl21DQ0wiEB4ExVKqFDKSKlHYo0VburnApCCJF7/0YsvASPkDE5Rs6S+8gryPvJ1wmpZkWeZeWgyKuqXFTTclFV5aIYZ+MyK4WdIk7SCdsgU5WzeTimkurY1waOdCq7oHE2yn1q8wNJy3EcpWObeDYsZyXNprqXDjBSbqNSFo9L2G72KnzP59m45JWsFks8Gf2kNDrKM2xS/SkCvMsQgjVl/V0MTWDwrkGjaTS1F7QR3sXBvBEAVzkk06fPZrPuFDaArnK8wFY53PmLq6urHA0AwFU+n4NqdXWVw51p6ge6/IlhGAB0jaHJVjkeRACljKfWEPgqRYzj/oOtWg2ArQLAlB8xJbvxN1/6McaXPw8UgMFdsHwC+OpmXVUoz5kB+59l71pdXQV2lDblJJLChL0fI8IVMifXkqeQl3jesPZStunc3LwyLYsSXGYTw+pLz8Z8kpYyL/Ksz6wHv066ns059wIV1iL5umcpp1tuXewS/qqO0KivLL++Um8ANOor7brW2rb12duu1nSd+lS9vVIvwNDO8opjaG04sOsYGpY/0QBau442DO04xq+u2slxtQHacBwNtzWL/37oPW6s/3rRrENDObbS+uRJrZXtqAbUT7laa+1+2zE0gDacb69rp3/QU82+WITv7ZFr8PVwhtxBHiIvJW8iHyFkZIm3WdtaxD4uVpZluajG86wc6Df0ujTexlmRjUuRjb0zQ4GjBJYMzwcobTItJzHCvEmu64uyLBWpANSZ4DtGjmbzskQrjFI1+6yczeExzg3NuZDAmNCdRs8yg35MKcBBDWbNC8QD0u1V49WRVJudDaU4W++niuvezlY+4Lw7WGzkdZOK5WUECfgwCMDnbi9/0XwbUnzn1YAnAOAIAoN/4kGQbphMKb9RH+F/AiBFQEQhmRPEeWTblNUYQwCtDEMwjKJ1bTTqm4fXewqhGbVNY1PJZmN9trJhGA2vxYCDBlQIbdAACpsAqBBVAIC0Zppcbwa+p0w7WgEAQighe9+CPbhCYrJOLhBSLXw0DT4NREArn/5mlj3jmsqYWBaT9G5R5Nm0TOJISv/YAPCHGYU+v8/p6d8b5rVJ17231u3W7jM66TWxaVyTdI37at1u7V63m1z77ti7xnId61o3GR1IkgOjxL3Wcl3zGi/u7U/T/b0PaH1tDPcmyX3JNVcpdW1yb5rem1x7jXutAWBc6+6vdbu1/e61pnmNC/tr3W5tP6GE7HEvYpt0+Ny+LLtprI5RWkJuJgxBa0q7M1XiclqWv/23y0t0c7OqV5sb9LMz1aHa3KTLS38LVy4thkO8gsPhAofDxXIpvORbSB8trZ/1XiIulSpqZb1sICUnEBg5cukkjmSWZW8YjcejN8y/YKg3BoN6vV4fDBq1GsQJLpBlb3hHrZaIfp2T/gYvwbvJlFxNLhIyiroXIB6HJUdZxw6M3UGRz2udm/ifk1+7VI5yjl/gCtY3qxZVmWoZ0UD68v7PDElV4qV2a745GGz0pGDMc10osyyvOl2o1VZX56Msy5u9XjFZXa3VYPnhbq1e6zYargs4juOk8IPOP44BssF8e+y4+VoUx686WaxAt3v13DSlaDabeEu7TYvi+NkjR4oC43hc1OsA+ejw4WteseUHAJ3OeDy/CjCJD0Ozuf0beOae3SP0urh++GRaQ0II4XvLvV/BV8EVkpN95AS5ntxJCJRlmaRhWZZxKUtZCspTpijKopyTQJOSpgX/Xyu1IkNLWhYjy0pOllVZVGnB+csWZcXTIqWFftFM01LCmiVeQ9epYVgnT9iGQdfpa4T1ple/+tVSvfrVmr8GjLvuuuuqD/XWP7O6uko5E9vBcrXX632IcaHfswZXwFx+D4yftYSkrkulsH7WAJiZsPyVoihe9tKiDrvLK42nrK6u/suz7l279tprBWOYHnvTc57zHAi14PTme4jY+8neFZRwhZwnryTfhTocgLsJSRMppCiw6LHVJJ2UkzSZJmkU5QGdUNigGrGzq8t844MWz85lukufmm1U4Nm9NJJR9tRhH634LnZ61F4iI1n64OvcwAtmUTIu8jnHEqazI7PpYrrIBVqO8kE2KPIsnw/meTFGuH5cSUOZv+V8PisjUHAPqMnMr3iu+SyPVoF2plvkxUBf9lX+fKeLajItVUNc622VWMvEct4sZTc9TI8djWNpKdefSiHL32bd5Nnd+3YM88xV9/ZLxgAg1AGRIq+yHHADkFJAChvUVFJP/dbdw0pOa8NsjdFVwK4fBH6XAQBlnA7jKIqHwOK5AkQEBMBPAfQC3w96MLF4kveexWEYZ4iUMjoBoH3rzpbWvd7hI1dhTibUkQEwRukGZYJ+nQjAsH7r7mEtprObESG/aJpKEVdhzBijpxiYdioe6QEUDIBSxtkY3sBZCVCmcvSLfNNVI9QJkF53w733Htu9ijY+0MggSiVG3CY4zQG2GeOU0sbt/OChW289PUhTAxg8AyHp9/O8N0iQUwYMaS0v1teLvJZPlOwOyyUAQNwfjPL+ID5TAkDhQhT36eZFDSYoxnIK8NL4xP6zZ48fXyk6oLsHxKc0EBhyTrcp3aacIwNs3MoPHr7l1tOnouKQG/mB+rcyQ6AnGeOUscON/qhFGWcUgGbjWzArxxkFeopyRoHSI43+sE05Y8z//E9kuPdD7MHPkYJcTwgsnnjWNlEGl9JywSLGk1+sWYxRIV6ZvigBN/Mc1gtvtPSRQb8/OKIMU/0XDaCVbamPnYdmc2IgSmn9pmUc6ff7/SM6ValWtqV/4Tw0GxPzW01wGcTmzs6hIzs7mwJAfU1bltb6oydv3dpYH0rLMgy63P37GzxyqKabxxsbmbQsU1NCFHH3vgd/B1eIIk2yQ46Sq8g95BXknf48Yq5mUzXQILbTRWVECep5u8gL95P2ohoZwpeSlB8lcG+2UTCV3DxJhSylSBmA5TgQGrueFLLsG+TgeQsIvT9JRVH+NYB16+B6z6/VfG/ui0NtIF5Mo3AwWFvb3l5b7w/CiL5YDLKtrWz5E4gjCnGM8GyMYsQ4wpc0s6zZEEndsaPIseuJaPxNv0+V0obWUjEOSFEI5UVNKfygD3f0/UDIZuT5nBtGGPiK9vvwqQgxihHj/1vzPc/P0l5c6G5tra32er7v+73e6trWVrcD0PlfMcUoRogghuuwW+43LYNjKaXcGKRvMK1ayhDyIHl6Yjxw08Gg27GsTncwSN3QCELf51ynNdvSi9iv2Skiq+Qqcp6QappN/ZI5E7xPeTyPM3/HkfjVoKk1gx1Cfw+T1ODtlzG/p9frXer1enD5Uq/X613prZtxt9fb3d3dvbJHLvd6vXsuX74MpNfrQW95qdeD9PHu7m7/axzs/RC+BR8mdXKvdS7wAR1A/qOMoqzNsvSY72YDOWcTnZ9OqvkWFdqfAXcaMaIKpL1bxfBK09HxrSAIghb4bk8/VsLThumZpmm6rmG4ieumjuM4a1+uxNUmOi6A66Cp3SRx3dQ0tCcUfDgIWuzMyq0gWP4IUVAKjFHGekxK5PfwNU9CMvp+B9G54gK4gjIpJVIqEC/7zn10r8BlUicPEBL6vm//IGlVeUcHwmN9KUtZjuW4bAzDIkBXs6q6B7pwxPKTFAgA50YCmUnRWJLxYQTOJ3RuY2MDtFTJyQUwyml1HBIlNWwCpa1iFgCh/bJOQ3aEIqVolCswQE35Pm77kUcegUaz4U9XAQFXp36j2YBH2MESeuedVPQfh4wQYvfJKX8u7wXkFeTt5Hvk++SPyV+SfwMDMkLc9oy4EGnqCiJxmG7rLvDwqTvJax0eq+z93HenaSTMr5/ayu7742yc/YWp6Q9VNBTTXYqaNkZKthkrO8Te58H3HekstbGPfX9zpY1t/4z6KvpzjanVaj/E/WHoXQU9sI7avX5tevS9pjWdPXh0O/mklM22GpvTdNjXY/8rbGN5lWrf9e14GO9PU7+jt5V1v9t3p86hLlM3djgM0M9//ofvecuHfeib37wTOb9Nsu0VsqxMy9ICWpZpqv7s7OKyqaziMksZajbOfQITCyB/yWAixse8llarm2VSNyXgwnK9FklTBfAGGAMYgzeEEFizlE326lStwGWpB6DMxfrR7aOeOQPsCut627SOsN+/9jXvfr83vvw5ZiFmIaTCJMzE/04M5g9dLvk6z6z37vKqLOkjARg2JIaYTCIAwMxCBDIoBuDF8/dhcreJXSVo6qvLNAOIQjjfqTpXFLtd24Kbem39Ms9BGwgTCz4ewmDG+77jE8anzw63N2XblkDm06qqt5uzhIR/0gDGAOYNqpoGNlng77LlsgYAbFUJq+WLF0C7vXvSMatqyNerdFm++zWv3e+BV32XEAsT85cTGyJhfhWDma7TgJCmmzbNQpqll4VJEgEZ6wweM6HP9yDCEIb//7FvXSzmtm/FGw3GBvTS+cEsvCfUH8BVEJVPsLNq4ze/9rWvtVnWLPMsL6vq4uwS19cvXv783eSC+IAX19dI9UR2F4d9+f1t2+7KpXMhDwEo3jhcXePVrxTX1y/GFHAO3/OqetNisQiL6pXfwi/g1+gd9D70qfTZ9B30g/SL9Bv0e/TP9G+Lxe10snHquzlK0cW6vrPTHON9nDRgH6MWnJmHGOOEMiH+RWybed2yVdvWq3xVx1jVQ13v9X5UrY1NW8VJ3LQHVnU+xqlt2n3fpHTDdu0KdWCP7hyrloettkfT7CNLu7QdxiEOY9N2NiKwQyZ2sEvt2HdzN0/9HKc5xlOsYhb5eIy656Y5bZcmDWOM06zzNNqodsKE882s9n4e43TuAy3XoaInYxWjdMtP/T4OcTjte10ndrW2zaFpe7BE/G8fwWrbnGIc4vE6T6riEOs41D5xqcaurowXk2KcRrXadv2xj3EIFjW+O2lbxaFu7HQ6YoRx20eqb2yn/t6Q79Dqj/3gJMZ4OlsBvzAyMTqO9zca4nw6nZq2KQ+WYTrNlVVfOzusXRqP4zJiqwGjyUynY5yiJTGOMVpdx2rd9U3b9UM8xYYi1n4ujpJpvq+1t2qPOS4Z4v50nNUO9d8kqq3uTBJtM3dSdaTlHxjMMbNzjHPTtiETS9tYz2qneb4dxsvo2X0c7OGqTCer9niKsZsrO8SILzPOHzUSN+12s7tYssBQrmpMwd45FbU2kIiWbePEGEuZUqfsVGTDwixiWZEyG5BTdSpftcyRWiMJozBGbJY7wJrIc00dH99tNnSsrl0yic/5Gob3AV6QrVYlrHLmnIgkBpIkCAqbIrGw1qWGIAFMHgqcNY0/TM4yyBgHFSoS0ce6BBF1rQuQqrT7AhBmWCjUMykBzFbta9/GF3muTBK0KNfronRFUzd1SAmgR486lMJKhsU5Z2zYJQgQCwBXnxoEq9wmIVheHg7nm/P3V32vCYQckwMzHIReHRI23hj9GMNgsUpMloRgGP/HWRC8/EpyZqkkAUSKP0kKX1XeH64us4DPdkFgZmpFNsQcQOLQNDlSn3rrMJlPXddJRoBwyQKRpfVLNgKSxCcEhvgSRlWFWJ0RZw1wOyZr1nen0+vKolE+vwXU82eaxMEm3sMZCd5bZiOqLLThmFnw54Qt+AJmZkOK/Ozs0hGMW63Z53lqCESJsEn0USoTsKElAE2KM5VQCJtxvsJRATQLVqXMEm9zAJ5h4NQ8PQdXm/YxORQ+SxI4H3LmJKnqDcAvzs4KMsqGICC1FiBAAc9EAPB3L/9ODeDL4DWDw64oPLkvIhgkRts0ITAFFhgiQ2r3YBEiCl5hrHVgVm/EknPA3fmmOeMv4gCQ6mN1TOKJFnZx/cpv4X/xW4tvW3zP4kcXv7z4/cVfLP5jsbid5jlK2b7xvp3jJPez1sahHuoAD/Qq6rdq9/X+sA76BK060shqKwCo6xtveW5jhBF6XupIGQejKzxFVhE9f7ftNPfVOMzTfLRat8fD3u7tvq7GMU6n+XjqyXUbh3gfh3k6tXa2TXvAtO8P48G/sGGz0Tocgn4wAN60M76L2YOJYJTlCjBi5KbupKAV0+2u3Xupz58/Oz08O1HbPG3a9uzsampX0m4etdflnen3w6OLC0aRp0R759y1myuYerW67s/O6+rJ6692wvyZtAXKwuEy0xFLa5ghBkj8j1xeXjIu4a8Zt3T+eWlo97ebdbU28fys6956fPRoXcjnEwk6VmJoB2Z2O6gXKQDKEJ99L7i96qsK17dvNHfdba7O148Kc7vdZi6Ei3sfry/qukt2VYVro2KAS2KV9WazrA+9tNZvxonlrw63EN4LNQDmOCAAAAAwYgxZnkuUhhc3m03EZl2unGDtBsp1WneVxEF3fbvZDMJOrR5v71H2noDPwRfI7eRZhIwmvQA8Rzbru5h2jrhHQyL4YaKByrqGsIqFuX2/KYsoKTbzAgMvjBrtq7pIS7gGEHAjsBjLphfg6VUJUFZPh4d2WvaqkWzccst6AVCs33JVUaNUGYkIG9vDVpdCvbHZazHT7YLtOmbW2Q/3KPgAeH4UBT6PalL2bBt/GwDilVZRjOZw8vAzn3n4JMDJwdjImwuAxeTixckCVuuNRpjYK/U+YpCMRmnKgCV2wIVX2wD69JOB1uA4mxzQsh1CCdl7Er4dehZ5ZYysU1D6Gv2SvF3pp6V7T/BCbdrY63CRlfm3JElLyROKqzyr12Bb3k22q5z+S9nllb/omJrSdHDo9LAH0BudOj0KVVM67f37Ws1ma1/ZdCkK4TLb79bCGCHwO3GA0owg9NIoh12OeMYxLWp7nCVKA5imA3DZZ/NfYH/bbYSNRj2DrdUzZ1a3t9KebAQZQDY4fLg/hJYX+Lajm16CYLn1muciUFebgJHXBjwFcEIbHYpKa1sIKOfRSXSYU72Uc1w181DWTDPQqcdyNJUc2LdYTndL6DsKWH3wwQdfevfVt2w/5wX3Hb9+O//Upz7V+kzjCj9L3fSiF73o5+6776fed8cd//Enf/Inf0KQNPd+DH8Jj5Ea6RMC02wqy5zsOZ1mU1pmZQivPX369Pu/+rbn/NTpX/jcOx54pL6ysvKfa3vw2Bd+/I53/NKfv/a1yzfBdcsv2f2nQNLGl8NTyIfIp8h/Ib9GCPT/C7y6aBDLeFHnCSi6rFZCeNL9mKpRo4xTIk8XpPfStMwRBlluLFh+mcV8Mp9lNm+Jo/KI4zIq8iKpFtV47reTFnk2lvYKYwu3sfquKQ0wylIW8fySOJIl/I4uVsbForoa/G4n4pRybrUmJ2MhZS0KQisGcGxHKRNBcA6IEmXZVZRGXWnH6/XCsFbf1+h0vC0hxGjguoqyMkZmO7Hjl80GmCRuNtJxvLjZFIhyt9cNKBhK6ajdrtUovAGDMAwAgigIRq5WUrmeVlJ5zDQtC24HpSg1DMq02gDdbGwbUZiEfsHZvqhWc01Qbj02TKSWphSQUqUZBxbHUUBpv+j3JavVp16tTsHzIiVbzRB4eMaDZVEUggIFJjigaTFgLFgF9ABY5rrclIpxuDo2tWHFiWGYVtwC23ZssBzbaYOUAFICIZQQch4vwS5pkqPkLkIgSUsyodiFunlRlu18c5oRDbtxlJZjAUgs5NXFfFaUkFmQEkrBWeIyqm6KetofhCZ4GXqNhucD+F6j3sX/1ms0vSAAr46Hzq9oefMfJzX77xZvxv5mvL/ZoyjOt4fDDmdFjqI43x0OW9q8nXrbSdjf3I83e3BijGw4d1g8lMAg3w9/Dt0YZa9KFPg1p+Pc9WNYxfuuK7vRWQYB2a5gqZ/lq7YYIgTDi//yPy7XFVCtL/sKSELdf2FfJaHuV3GbSbsB4fKdwQ9gXV1eVmvQJVBWdXlFS2YfjmAmWHh8vXgsKe/w9sWiPdWnG1TbIN1EuxGYxM5k0MV4WjCRTBqHtSc94Pbh4V+/42Fyy3tkRfmbHx4eHr7jXx8eXv7rw78muAX38e0PD5yDtZeLYbG4Hai9Sdd3PeJXQDXjtmkfVnYm9m0fb6OJFt+Y4+7Jm9705A45s/on7xr7LHWW+Ly9e3I6PblrPx4LLD7+uy4Ob7q7I7q7e9PhQk1IRsZFyJJgdP3sfAtsz5+975/+6ftyNK9IX/kt/Ap+a/GexdfijxaL9XgY29BNfhwiXECgFqe6pz4TZBjy1p5jH6olbZt2Xuv/6RCHeQj2NjIlbx4imjOq0joeYhPbG9BBPM33rOD21A9coLgfeu+lvnmIxzjAqCtjjJMhWmOUCAh/auJ2T6Fo26oFS6TjBnNCa6gBWVPkbCoYVp4wCNSII6cYh9EVMx7i3vgMyAMxLARgsRascvumhuLCV+PAGu36Pg5RghzRqR9TOHp0DsdDKWJ9+z5O12tjqAEBxxADAyXrxya4WlrFoR4i1bWrWq80iVWsHEM1wlPXYfz293u/H3pKVVXmiUdaIIQ0ZeuTenNx6YkR0jQw+4vLTZ14y2kaAooUPsnLqqJn76cWMHVlVExJxJSFwBxCSsRcirFSVwqrvgQlDGYC9WOyzq+wB3JZyhacIVNy3jtDnDhPKQgGAKy1quj+sN4DaWptGlxZKJOAmRl4AgAeyPMsBzet9UsCUw3UIktv24aRZ3kOJNhjGs8QIlOULg3WpikSfxqvDkPIGSIE8o7EePnGgnhlNAMBPss8gch7RxdTD4MTQunxWyOI0iJJLp/S3d3zZ/nFsiyWVWWI/Lt6TFUti3J5kT97fndHTy+TpEiJML78DLIwZSFGyGelJhERBQiexEhRGlj6UQgoAKYocgCOkwgg1IpGoftXEDE2WwLMnplZjRApK1s1NgQjqsAmJMGxVcN4DjRcs6WrquUKRqAADGAICjFYrqrKLRWg59CSfJKEDamKCUFV7eGv0BhhZi+yzKwRATFgKXeWYpWUJOwA5EVhPIurQbCQhXvlt/BL+K3Fly7+G2v8f/TTuI0T9iqVrlk3bUpjCJUxZHpobxW+BrMkOhwrRCB0ELrenzqHbfBBmuPElcpO89QO9T0bzo9Wl1al6o7sXS8Q6fE4G5t6qOVA8D6sQhiKrt2Z5kFEB9P26ThGBpJMQeYct4/a96woyl9Vd3DB4c0x7Gijsu0JuEuhHLSKXRb0TEf6QJXMkj1irRCFkk3txQZOuKJ2qI1Zvapu7D4T8aGbI9tccJ5OU99lPtof9hBOkWuDl7BwthrzBw3sbY6nqY+axpwVRmYAjn1R3BnukOerkAbFP0oyK+IM5BxTyTZJ6nq3S0AgWGOttQDoZICS3a6uk8RySexcYJw4Swj7uhqEkIZVnqNj853mW77lW3qjYAohmDQQOUJ+nr+iSMbWuWW1DkRkhMn4epMh8rtdvXTOytp5JiAHPHGSmhACE9T07+AkBOGlETXrtQFUVQGzXhvDEtSFkDCtWUpv65qQ5VkGJCCTOmsJniFEJi9sGtSGQPDOMsBWLWCIAjnnmayXRmvZp5kjlkQgB+XYA0XiSwmnTB2aDXDOC7s080Sp4TRNQETeOUoY7O1zVokgjueUBqsh2DI3xCIJwC4NCvJAlmUZuK6tK0XWAH5LnoJAIU1hmpqgetYxE4mI2uurxL8+vV4u82JdKQgwzMwGTay6rop8ubxO3+D91XXqhYi5O1PgexIR0jQQCE+lfmaIUbNpGpgakR4EMao3V2U2hos8S4v1GrIBVBRD6AxV10WaZxfF+1zdhISAXqQhDqk8rY3Ms5f/LKJEjo1wURhYwMIUBRshZVGRf4NilJOFgeVyvXalEjRzLqznFRWAS5JkA6iKhMSKVTGo7OlU3j80ADDPlowxoEwgfWCVUrdKDGbajs0BtQG1hGoEbju2yZ44pVAysOByzgAoZ9L2GFNlB6wcIvynGybLGIahAKTpBKZsSwAKT4Wh70O57xMEIAdCMIC35gS5GWeh/kKuBAKzeJnpt/l5KWQiRVlYpZYWlezYk07xjpJ0t4kOfM7zmcNFAbi6cqBfr4Hggh/gnMu2oIzFabKyumBbrSZAo1HGSey1p7DBZxoYZItFvwdSwgwpE4JR/IPUdSj2MYqiCH8Irdb6RrsDQpi/4OIeb+0WecF1N0o3U5tHyNDSGGfi96NFaJaDnizjDbKYXOQP/q7zclrKcLsbKZfpfovZdhxZtm1FoWPzpgjDQRZQd9YMAJJQCnsUulrTOOoP4ghGYBphaOgjDK5TaT9P498rwwTHThPbAc8t1tIgAEjT4TBJASwmrn9OkiTOfJQkAGmaXXddYjuOnVzXqcdeT/8OL8GluOMZGtKsrHxQYiHnUVIOLaqM1zNSzX944KXvfe97V25h8xtufBgajSxrv/fT7NQr2dlfhkvL58Lbl8/9hZPra+ZHgDPHaX/6rW99y1uIv/efe7+MFH6NaBKSJsnJmBwgJ8m15GZykTxAnkNeRN5C3kc+Qb5LSJgWKewpWPf0ecGFTMtFVchZVZQircp8zou02PKIVSTTclHIMonTLydKUcgyqYpqb0sP9giSL6qiFDLlx79osUirMpcplZWM0seWOa2qsigc0XN5IcsklSlWFlXlvlEcgrDtJJWBuNgPYHM3Ifs1zvmgY/XzlwkhFnax/FGkUxVENq0JUaPwTMuyOgMx6t+/ctd+rVZTQRQZP8gymuf0vXHL6aZh2YrDtOssf/HbOHh3FEWBqhnRMmmFN08mE6tmIiJjQsiS7zvW06NS6YmHB4MBb7R6ot950b5y3GoCdqKb18rx1la/79hKd9obGyV8PU1TFUSRnn/sR/o5H3Ss1/gBzXPqB39wXvsHa5cC/9Al5j4hRE2I2oWc3tuFExkPxWXae1OOW562LGvCJ0IIY46v7R7r07nPe+36XCmVCk/VVADw3nZ7Uu7bN745anAe+MPh9ng8Look4UKd9vla3uVlWXZTsnkxmU6qAQBHAw6MNnZOkyeMpwtb7ddbyCgel3Ltcw3oxsnq2sF9G0ptDxLPF46buK7tO0qBqmeDVR6GvXaQhiqOAiestjV/fHNtvdUCaLVsK0LKA78OCrTr+IHbCQKaJSlAxM3URhU5PvIFbsdWh66YAAWBCs1Z1iZylsaCKYiiamR9cEVXcN98Dq+wfc8woq5j3+SefGVWz1heyfyf0E9fN3glIuJpsJ1O67qflmtDsKR3NyBzchtHTwYVUt9N0UG08U5cDLyeaT5LhRQZj0RecKtsZJLnG1tUi2mSJjKGy8tLcCnQvozekF3+5bFjx44PiHnPeM83TADT8KFx7NgxELxeVxKO74LwvHrpeQiXtWEvL9mG1oYNl2xDLy/94Af/YJqeb5qm6Xum+Q8PRoGP4HnJQz9o24YJrfbGC4gmZO9JuNbVR8ij5HXe+Yc+Rb48ztYpo0UyjApxMNBVwVdp59nAybOdJmnvOSDfRJnoSadxMk2qAJdH4iiNMhxR0k8nB1Uxm07iSA4KOSgW1SQVGXOtHYsCnT4NuQB22zuMCrjydO6Lr4HRThMEDxCE5XkYxUmEnmcJQPQgSdqSKtexpFZgMoaKcyNJEKxJtwOwuXn61Pb2WB8VLLhAGaWgKQClANShUbWpjY5RLarM1SoM821AWHA4xMuwqlPn8nGqw3oq0bK36g6zLB+1Bs5Ba/Qtizn1LctG4bHANDWmXGuIu7YzSEYRVLC2vnNqcxNgc/PUzvpaoCqK2QFjXWEWpIUMUkA0zJZdANTbY0SpjTRgvJJv7MdI4DGynxBI4rIcixmXgEDdZDqpOgdRkhKboyTl8xUEzTWD/wHZ4Pixe+84bdlX7wwbDUMbrj1KU4gbGxScYqc6htDubGx3hl27320nXViR4vQIK/VtAWxAFHWBqlarQAu7+9q1cbvNLGuj0wHoyWAUM7uXtvP6bYyzfYAQX6CwgAxpfXwDpciDLapFVSIZJ+rt4nxx8+td7j1yBK8MKfVu7jx+PP30n+QLzqlTH37ErIqQvd+GH8PXiSI+aZCfIm8g7yDvJx8hpBLZwEG6QKg8QcTJdDHPsw4d9GZEd9UBxV6UTJpljPEmKmYANHBGHdOBhWrPiw/jYrhAFEexqAKphfTUzSLKQyNda3IVfwwYRmK75L9qHDY4cA782DNOnEDY2ro2AMRP9plSFgrpg22bQZxYzNro91FwCxF1UKtjp9/r2pbnWRqRWlKC5zcabQ8guGZrE6A/2Nl36p1IKSJFataoMop9pIwCZQi09RApnXIBFUkf1w9FYBQphZ/CEyceunl3twE2M9MUgYsEHVuBFACcBU1RMzAKT0W2bYkgaFDHplqDUkLSRhAIy7ajcZoohWY2atvchsbu7s2nqqrXheXHkZ7eo6ooKQJmlDc5jqKDjAIyhu2XPn6vGw/7jgJ4DZAKjNIYDPIxGEWLFH+M1GjkXwCOQAUhBVdQB7LUBGUgtFIP/Bj6/Z2dk3mmtGZUCBCeG+3LMoD19WM3rK3adk0W2u6ASsE77flWuwWQJP3QNBnjBkAvtC1RNlYIKZEBnl5fh0P3n9zZ6ffhyuwHrWkHvm8mCbOUgo31Y0eKFcCN9UPtZsuigpmKM2q4nrfe7SG0mpvTbhfAskPPa8c96ntNXxsAjUa7bXlR5LYOH7rh5M5Ov3++wb6AfVZrW4iBE7gvA4OyM9BHiu0uRRHzdcqXiIdzhZx2Hs4Cl/jbNZ2lyLgWilEIgjAAMDhjphkM4gSg1dqat9tcSJ+oagAytZ211euPra0hZNm+0HUlFeWwUuovmqGBDtOzNPW8OB7VBmBoP3MdIRtx2/NCy4ZOd7LZbAJ2u+ue6xqUKVOgpFar2Tq0vo5QrBw+ur6OoJRFk9R0Xc+GIGjCbjMIYk8F/Zb7fYxcaMMtdx8lz0DMACNTxahgl6GfREGWUmm6H3GZtbUzLi9Bq7W+2mia7UbgA/hBo23buO8uhHpjo4Pos/ZkA02iXk7WV2/YCP4IcI/qutZA6o1mA6DVWg/an+m/+idgE4LPh0ukILuEjKxJZJeDQ2Hs3o1U7eum83ju32FcP8Qadiy8ikI5uWlcj2Ovm8yMMGzZKK9op16nz/rqN3aqamdn5w+d4KbpDMYIuTwcTwxDw2Awmw0GgO1WelzuTODrWkIIfBv+KxEkjQKvWfh+W9yiwhPNvuRAf/Fr+Aeqfx2+/+LFixe3UtcFaDSbDQDXTeFNFy9eRKUGmWnCxTtAJ+ngRJoggfVVcN206zmO101dF5af+elmvY6Qpp13wvpq6LiAxcrhjxLC9vb29uBP4RIJyHHyIHkZIVUky1LIqtSKR/WrPcgG9P5ekVezqq7BObcznaR92wvGkUykbJXpG1moqs1qqowzWA0oY8bR8jn+Ta2iUCulw0hpyDGMsuHaak6RsXx9fTSKYliVlMlBvV7f2Fwt6vV6XzKmVmAXgnCYJEIkaZoInqRZGKbpYDAcDwdZksL5UGutw1BrrcMX+UGAGAS+HwYAQehPJ5sjz8OyZve80eZkt6zVPdN0lIoMHUnlmKZXTye700Gt5rX3MlAKDKBWG6wniVQASibJegVB6B8fHylcP0cNLyODGGCMjuKzkgASlvPCWr/aUsJv3HvvvTOqlFcevPfA+YP3HtyERw6NhtaY/4Nn6OVfQ7L8a0jugY2tgz+0rXLcm8kG2SYkDGmYllUZln0e+0anDjNaklBIP6G3MIMP/WMlSZZlH/pQtrwEs69//ev88/Z98BQxpou5+Lj1dxwuLx+Btywfmc3gLZfKdzWb1+Sue/inxzpc/CRc/vjnEhpSyb7Xqd30XaqyKvvv9xCe3N3d/eG3onPqkdeFyy97cK25/JIP74HLy8fg4eVjN9xw9+rGxr3n5udi5+zI9q7AT8EVcobcQx4hZBRtju5Z0UC6acFj9pgsLifTBd1/XTHIZDmZTny1MOo/l9jCxnlR0KQEJpPWxBeD8Nh2fqzChh9mYbHJWK+7XYZhabhu0/YZq9sORcOIOTd2Ax/LKCgP5SNJwzD7MONBrRaEAGFYq/ucchG32nECkCatdszZb0SH14KAXX8tXHc9wAwo9X/Pogj7Txw/fgKTeGcrrclnAiAaZr1uGIhwz78/9NBDgGhazaZlIgIhSFxCsIRLZD85SgjkRV7kxSDjcsI0OhqZdo5OpuNyYnzluBKQ8tXn8TwtJebWqDaZrK9Tur4+mdRGFodv7xHl2x5k+e23vx1OpH2MtNOtpYBprdNNR+anmcxR2u3UUoS01u2kP/jIRz5y4zmCe/+59yS8GuvoTAkZXR6MwlxVlZOsKPOQwGvTSlayLEP9yhBf/7y7mE7LRH4Ea35TGUdtdhJggztHTbn5h4899tgFbh+1xEX0+xelccxm/4+ut0sLrZdeY6F97Uf/8z//8+MWWp+k7QMftdAihFB9//5vk6vazuPyqirHZQ6Z77NXZS7l++nIpvJzgp/VtOwyY0vxHo652vrIMaq3FT9GDxmmNrjc1vRpreSTehL0rQsNuqI36/6LNOgX84eCyPM16K9eTw49uEw8Usc/wYBjzcwXZVWmtJLVSkbK0ipyOFLdX1CvmUyCa26++eabbrr5pptuumn5o5tX3PIw1uvNH/XOKt17Eh6NdcUY9LaMwdqVZVrN3iqVZs1VDpXdtN/v12jtN8bPsOw73/mO+s6B97///fX38a997WveV3u9Xu9Fvfsef/zxx4vlX0G6/KsVeNrKG1dXV4vVV1y6dKl7Sd98882jm8Cq1WqXa59YWXnx5cuEEE7IHpaTDciITMgFb15i56ZnAMtA0B4HfUb4QRg4R1Mg3WcDAnMsUgFhqPDEzUymiyqp3DHa81nRZ8ewHuJ0pMVoGhx6BJbBIMoAeLSoqZeUQj5Z9voA/V4573uxd2zYe831Z2itjkpappJwzahYRKPhcBQuVkaACKOiCkfD4ShaFCOAsd2JBoOWllK3Bv24Y9sUj0i7E/e3/NhBBAPNvSRMz/0uZa8Pv/L18npxDL9WR6ybSkpltqpiBJAJP4zWfJIDAIyKKhoOh6PoT855BsgMnmUQ2XPuc4Mc0QEGft8FvVV3Mb17J8Fjy8twz/JyULYfBWP2Wn4AEPit5vxZmx9e6eFyGLdh+z/E5Z9A4DfTD7xEllAn7AmSkcn4OZ2srEajlA7VMFWOdYJ2iOeRltOfHD169FVHf6KHDSx/Yu5/5zvf+c7O4BODDtTuu+++p9yejLtPOv/DH/7wh7MZQSL2fgj/FndXO2Nm9ok4isPSvTYXlotikPUhFuEcpqVMBOcnmA+nbHoCHITlJnQefPDB1ofqcJkzCbi83wew4OdctvzBz/xMHyCv9q7AfrhC9vumBhfq5/MYO25uXYNIbKdxOSdjYXbSpIoO8OyVsDDrjeGBXs+ytjWYW2GA4J7WcF4D6Jv8oC8Fx4SxnmVogFqt128+ZpwwuT/o9z3Qzwd9TsNrG6ZpUQBxVAlCCBKyh+Oe9jmNiMEq76rK9YEYEeaHvu6PkEIR+lzkV6swhA4H2TYtAL0hZkLMTDNmjIKDKD0vAQT36Ap22s07xLqkZhxHBvAzwGcczntSKgRgK5xJKfSfR2V7T8LL4TLZIkcJGeVVFN5QqroFDww+bkQlSCCjNdAV7oUYzOy5DEdg2t7xfd/2lOnX6huDDB3peUlS97ygXvO9qBbHris2tcZ9IaMYhIHdxKLz5aqzwoFzLgCkgdDvHy/Wwk47TQGkBlAKME6arbDe7YiP1qNQg2E4nTXICCGMkD2snXhZNiMkrGTFPYz9tEDxWnG6YP3xS5ZLSb4++XHf+8dZ4L5Go/Gl9y5/qdFofOHdrcFg8Ntfgpd/5Stf+cEg1lCG7OIuvBaT0314IYMfhv2FeFRJTrIOPMu7eTaQoY86Ii35fwyo9kqCX0gQk5jSePnPMaVxgphAMB6PKVIhaHlgd/dASYWgSMdH8kLirizyIz+NSYLvn/g7zp8/zznnNzebN3PO+fnswP6rr95/ICMG0Xu/Al+JX1DtMfJp8h3ylxDA8+H98C1Cwmhaxmci1zsziJPpZEr6nziuJuVkvshyOS5FnEzHPjSMIUZpduP2iGvk5gtcyDDopOrAwaYVJ/xxY/5Lq0maTOO+y7q+RbUo6MJhIZF5Mf4Nc3MmzYu8KmhAiRRyoYn3R2lULmRuadcygA55kgFqU2g0bWXdltFSk7JcFN5FhSklB3hUsH0BUNOMEMXM4QLNLkgcXIqsidJJmCgynTAg4uogG2eLqoRONMJPFaLCjRT5cBOzqNEYkkTCeMCJKEmxKgJ5nApZ68HmeSHSPwL2WAQJHUjB5cj+EaeuGqLlKdu2wDY0UOZ5+brvE1ImJ47vG5pyTqnQAKYKG1O7EsJRRhJ264HShuWbthOg02ikbqykBeB9Rzm2VjYagEApNVHuAymQryohgHOglAsQqCxKHYdSiSBD0+WCS4exQHDDF0xwxm1EwVhaqydJXbJxXV/tuIGoJGOUCdMyImEaUqJQFqemadsQccaYUpLbinMXbMoMw0BKGUMaJZQK5kppGgaXknGhTdOQzDAMzpltmJQC8KZnmOgzBsDrnW4bkMZxkCSJxQUiB6DMAAgM0xQAlpYI0oU9ApQZge9oKt8YBBTc8j3N3bY8nLwRNNEgzs+sgLD8K2mBrREA1kZpGDrg+n6CtN5uxx+jx5SNZmLJfs+vN9rNBpeccgRqMaJiU8XMnCwqjzMPDC6vARmtIzY8xZi0zAAOeV7NAwaAhtIgpcHANE1tOEilkGgYAkDYYYCHKHIAg4JBESi3LYFMI+WMSqX48ot1ipYJhowME8FSGgFQcM6YRnSGpm2ZltEwNRiG62ht+34QuJ7J6nYtTXsdqeNGo4YUGaJjI1LkRq3Z8pXvJ9iq1bTUnhsGAdfKdiyJ6KrISy0PAsYCy1IqTBFjP5TCtVPPFYlEwSVKaVuGL6FFmQbQXHBA4EhlFIJmtLR/ABGESKL2HoefwNdJi6ySHXKa3EIeII9Ek9bUDdFKoyNjGwOhPLpIk7TQ42GSXJWzeVKFylEZ/jssPUzihZQhIDAapdtpERnqX3b66BbK9fVKGfvbLVrDRnOnmaZiOpkUf8HTtHlNVWmj2918qXHkyDmt9o/HjTme89fXjyaGibN9O+OfgKHj6WgkZa02hK8LdbU9b+ca5FxESaNRlzVRqyXjbCAt28r6YjAYh4zBJC/iX40zfCqSIPBXVjb33/TxbDRKD6yvu4mQI22uru6XUtCN0bDuZ0/7ddwj96IMEA2P5b6xzrYmVQtIpeUaGXnM6V/MC3/NAOnXOFEdyrNcwOCcbxw+yXD//luTpF2Muz2AZNKP3e798+uvTbIBSOmGlrbtZBXBMAIErdZbbcD+YGW930eQyvUNZZjhCtp2U6l+q4XYH6y/M05v3b8fWQLQ646L9oens7ddtC+EQcvSGj2tFWDdEpwBovK89Y0wcN26bWiwpRCQ2lwIQOH7+UYcxyPc8ZfhUfhlskpubXncGgd+6mvkuFykEz2sTnJNxVJWQTD0EyuQTgAxm1gKWQMhyf58pmUi4fjy/4O//P8t0wQhODcMdaTVEhIohfN1rRDG3n7PsixqPyMECC88jdkYA3TPGlwI9L39CO4fuAC/DK7nLK9z/Rv/jFRne32pgAHYtgX/sAtXHTx40EQI7RC5kDqJpUGRKhpHpwDgvEPR852Lu2SO6CXtrZVxOYuVRoOtLsM2h0ivSDzWjuMKrbE4lxGIVxTH8IblF+CG5RdqngvgejW4YezKfg3r500lAaQyz1tSfUtJ68aJE2+0pILL4Ho16npnTv/CJn6s56auB8vPtn4fc2kqpZS5fNiSSknrbb/s215P2uMOtcjCd2YjJcpRWcmiNKwyD8HDlCYykj8pEr7DfP5zn/vc5yqAWhwEph0EthEGcQrq5p7pT9/3vve9z0iSwBLcdsC2ubCCJDEIIZg3+9hvwc+RNXKTn89iGjtnGd14tCicR9p5kScYa8qUfAed13jmjb2boRLIrtUr8qKbGHA/ykm6vn51cPX6ejrxc8DN6XSKSVwbp1GkxsL3660oUnMZxy1x7eoawivXN3uY6em7nQ5/5VU0jtvtes116rVuMwjYcSjL27DvrwRQwcdJQCpyFbmXPEJeTd6SK5wyFVw52nlFyyHTmsesdDqpJuWY3GMMCTLxMjhLERVCKW1/tGu3i1yiZpmwEuhaEK3C9s6RRbUoKuihrzLhPdyyAp9Sr0hrhnQcemVRlt0u4FXTzc00tZFzCoezLGDWcc4PHX7aY2Jr69jRlVXKt7eOHl1dQTNkLBy1O7ZjUs9Tbhisrc6ud7rdftc0bafd7vYc277FMA1pxYZpSjPua8GUFkyBE9o2BccRotnIXca95T/4XrezfuLqie+77lhh3bamFqbT6foG/Zm1Wl3Ifn99rV4Tst9fBy09H4XndbvDUPBgur6e1ozlf+vYtmE06q2mbStdr3U6jFEjsRhlRmLZKDWjSjNCidp7HH4CXyY2aZBV4odF/55z4zBXrkhEls6F730m5A9gZfXYDuK+fXesHp2v97qW1etuzI/96rHVFbhj3z7EHUhvOnqsf/ziXcePex9cfhHarWJlPF4pWm24tX/s6E0f9I4fv+vicULs6X/J/wGX4KvkzrC4KIgZRV0CjbtucV8T/Qx3ciPOEyqged0ojuIrgBiyTDT6mmCRwqW42+124wi64+0DllWurDbjdqfdSRbDYRJrV9LBYJipA4O+YwMApolpdg+alqERPLfT2eKDQb9PpQ21WlFsvn7ieYwZGg4PMwDTQGi3pxogCheJ4GEYDNcBouhAHEWtJnXCACFJRqOtNM87XUTLVBhFjuscTRLA1RENQikHhJFg7wp8Dq6QhHTJCtlPSNXv9+MykoK6ElUsST6fz/Wnh/plPOJGlVlALWTnIoAPLu+HD4ZBK7z1C60gnFT8N3th+RfQWP7F7JcrDFqPJO0wuuOOKGwn6c03P/vmm/8rhGE7SdphCDLG/a6TU5Zm8f9yYxmEGT50Nr+xuIujXLqubECf8jnDK49ttkLBbcOwWewaGiAJQ3ukHdtuRoCe69WOTSgeUao8RT+4aRoHMG01wQ21AohcF1h1TxRu9rwaRXkdhSNb5/x2+LweyycF2UeuJ/eSF5E3kg/bQl2GqNqppiU22eaKIdeh+bxyAJS5rSyOnC1GzMbTaYpsZsSqNTIr51l035n6FF9UbmE0dse2c2EtqHHhZPgnmt3l2FFk2wC2HW3XJqyNbGc7sp1Fwu3lGi8cGf3lFe7Etf9cfO22N3xUi0S0H2JNbsis3X4t+Xl7J0+w5UIrsH+b00npoROWOOm4nKRR0BNCel2RpmL4fDQj2rKSepaoqOK0KCtvXJd7ZpaXWUNaMv+S7/ADDzyw6PUBAjhHXQAfDcMDgAM372xtt5UIghAVKBpfu92PqAINYRAEQQgaFI2vSQBseMvu7m67OxoAHP0vAP7RcbsFUD8E/f7Ojgzy/E3odRfzY8fmi24Pxm1qQK7cmE52t1euySPENPVMc4FQb2wAhIRk/vItFwAAgYgTv0/8n9OM5rXON77xDW0hfPklhtXd/KXWeHxwZ+upAhBV2KfaP47LyN+ZH8MVeIzUPNFIorzgR1iKNRm/rEq/SgbEqud6rMoUvBMnTty+sw9xPr+pGgwA8tGBE1989atfPeqsnJpk2uv1enplZd9ipTDXjWZzVLRaCm7qLy+9tdVqxYFc153wXkIIocTdexL+AS4ThzTJgJBQVrIoszItZTktw1RIkeLud4s8q6jvfaCe3Ldv3849DxV3vdXKPbvRyjLw/dqxixcvPngRpm9/+9vf/q93wPk34CBrNWwvr/n+P/3whz/8ob/Yn/cj+DrZGnIhWSndjMgrx/jjPAj8CHePPkskfTkeOHp8e//+jXWK6xtHy07Hdehb/5Z985nHjqH1oByPHF1jdHXt1PGNDbRJnx/eEtRiwy85IHeTh8kryTsJqQJEzEVtGjXkktbNi3yePmf7fOZLxaeylbjkCV0CJaSrYk7ctEQL0NyXp2kiAd+ljTkqby9OPlMS/k5g3fRvof7AYEyWWRTBXYFlWVbgWSZt+j7sW3Pjuu8D9ul4fPrMeEx7CL5fj931fZYVMtP0PmsrxZq2VqC1/Sugtd2koJRtaw1j5XtJ4vkKeKvbbXG4wiBqotKqzLa2508FywoCy8pa8S80LAxatGEB+H499xZZhphlCy+v+z6A1aCRY1NH67tMy+uCVJ5nmrmnJHR90zQNf19omgCmGXJERE7sllrPOf2xfDZ5GSFhv99PUiiDVjp5abbKvtwufv2z4Au1J4dTUQibJyseeSl6u7C7vFInDzFb/IvVv/cM0zS8tkpdFyZDJ0hcF9p0de3IkbVV2gbXTQJnNDFMT7XfY0pJ0zqCUubHoF6jUpqWkrDmrhQesHqzVWMAlyEImrEF++p1puF5hokt6vk1TA0A10n7zna3g9jpbjv91HEBjBR9y6JNvNEw3CZC09UaBk3AlmMYhnbLDDFjTjsNIvu+Z75OWuQ0eWo2MxuD6waVMUg3LS6qCtunsZV9cV5WFAygOpSW1eIP47SM4miudWp5aHe9gv3g+QBx0u0mMQxS9D5hkX040wH4HuxvefZ9Cbxn9CLTbf/WlgfgPYva3YlxNzWM2IOXGXYndLdNY9sD8MZ9qVAfMoYQ+Be4RFrk6pyrhedceCqIA2PkEDl4jQrc4bvPSqYtTwn8C/R62+NeDwYzrFlS3fInWZZNsdfd3u71EGt1vGWpf+iVtEypvnbq1KntXg+g29s+5XmnaxSkMs/s9zzPHW53ugDdztZHaoi1k8vay/qBRtcfqncFLpOZjOrnpQKer6dwdFzK8szHI1BoFQM7oPqgCznEPl9O83zGiDT3MjI4RUKYiishVYDKEgLuiRwHuuB+4cq/+nIYQPFgpuqfBuaqQlgKUVFwnAjuEWL5TheufMFFHgf/+SuDe4hFYpKTbbJLzpJz5AIhIfj0apmVcUxwx8ejTPTGo3FxXlLfacYSwyNYL/gRFiO3xRXPnTt37rXTbrfbhdVz51772nPdbrf7t3P4ufmy2cPLDtHn//2a1128+LrPf/7zrdV/fN3Fi6ut1X/8/OsuXnzBdHrN5z9fhjkv72X36YSEcm5zUKBXHxenAxmXHrzvPqt83wdpgaAr/qpsR7iMgEacTFOSjLYArzMzKi6qxfw3tLZNKU1b67kphGnrdEKR/Svnf5hx3/7rLfM5V9QL/M2Z5f1sHHc5F3bSmdluL47B90wD2Almmt5xdoKBaXi+Yf68k8EH8vOQpP1BmoD+TWPK6/00gdBN8YPGlEOSDogicu8buA+uEElq5GpyjvwV+TH5F9CE4J5FacoHpJOWSQlkqZZbPKBF8owWFXwfK+rFeZl2KJGL6cJzqh2X8yyMcTYv7W22gmbL5nIgE5laCl1iBKS+F8Ro7DwCtiWy4ROEFKksRQzmJiJCQECPwgKgU6PFtJQo3GyHJvPJOoUi9bCM53EE4nKRpsXWb8azeT4XUsh/5JxzzuCjXr3uyPkcUGgtCmkB5cgFmo4QT900ERlzHbtX7pM+p0LwoBOoVq+rfgcADtSybMeUSoEjKDd0P46EHyL4WioIQ4/ZtmnCXIPJHMfkSA1KEZEpIcVbNJii1+sPDABkTmiblgzjyOSKehYC1GqOiyBBCgeLeT8AHbmO5Er7nj/qI0a+737HotfVarWkdxoRkTtBAFBztfnfKQLwK0KoTSNC5vg+gEkdrM0auFACANK7wphK0fKD2iBKLMGFqDvCs4B+0W6YLl+9mWX5n/bKlY4OpQDWjgXnFjBmeXGMtuU6gllUa6CUgolIWsaY0UVtgJTKoWBWarV8x7FtV4HlGkI7tuACpazXdWoYZhxRbYCj4fag03aldEKEwA9qW81mk9befejQIWf6YcuyACnlkKdlFJAw0tm7Aj8vXx49Qy6Q13qiU9HMqAaDaSfANq68kuNBkQPiGhwaQgJp6gEYy7K0LAetLlB80wrpxmXKIlc07+K8mG+DgMZcfiYYt5JEqSRprWUZLubnz+3sMMyytc9pWbTfXCgCKIqgXMPS65Ru3rAWug3TttxuhGCFUesVwIFhkAQHAh8oohl4foCQd5sCbmo0G+1Ws9FcKcvj53d22GJxjvHjZbnyQ9NGYIwyjKIIm6lj6w1GJz+No5Webdv+oIbUj5tR+BADYI00POSHgFHy/E0/CH3A4fpoKwrxrY5dI7eR15KvMsSk+7VPZVJc0kyQ252PCA09nKZFCuIBDQSDi01um5WBFBIapCMkp28pjwb6KhZyEDDcSqoGbjor8qIIWJYSCbkxNA9mNmKon1RecsHjVy7g+/XU89lka8NzXcMw7t/IbZtTKdxICBnZ9is3NjZknCSJMF3XNMDZ2PRTx/X9es3zWKPRiOx6LVUSDClliICcR+Hm5v2mabiuuxE3Ww3ueUnD88F10ps2NjYK2+JMCsd0HcsAd2PDiWwbfK+ReC6v1+uR5oJJ1xvB/Q3PB8dJ7PVNFwzTdc37N3Lb4kwKN2o0G8zzkhdsbGyIJEkSYZqG67qb5Yx5frrPK1dCRnatnir53nq9HiIi52G0uXH/E8omUqrYtpsNj5r6Hp1vbm4WtiWolPZGu9sz7j6JSbYdCyFDLTgXnjdktL0jMXEXXkgC0ifbZIfcnBXNzq0FwuDthGpWFNNsurhdlrJyzooL5XYzG01xcW1auDkRK5/N8mJaLubeMl8Ssh+Nodff/vhnJsMRHn3/2bNnE9ez7fj68+fPn795geB5dXjaY4899thOr3fowDCDLDt0Z+uw8Hz/MHwDvinmM/b8/x3PZ0EIyw/Va4uT8QOgVS01jPN/fR/OG6bxd1n2hf0rBUKeHzg0HMGtvtK4K2R3jjgnkvgKxZqkkkXZMXIzeTEhVVLlHmUj00zaoID2cE6zaV4ImU+7IYUl1INDeHWg8EjiKB4/xlkZlVlumoVj8qJaVB9oU2xvbfKVlZX1WmTO76tXHjlyhLba9On5ID5/Dq677rrrPphBFDUvXqgHPjRe2A/8+wdaazrwJv0wAAjD3quw2YLZKzdTm7Or2wDtH3maVXpfGB6wirZjXzGMVtMoIE56qEmPMgDO9DZEYb8XR1B2MFbtwXfIOfIAeXHEGpg0urJKPzyvykkjPhYyZhtGt2ZW5Id5kRba28NFLlN2l41KQRlOaSmNzKU3E6BlItfKbz26m97Nw7DRiaKbqMLu1GgWK80GHKhFrzVOnnigfbOr5We63a4O4ijUWukoCnuu4Fy6jvu5ZoxR2Iw1CrSFq47t2FHw2mQsJ9cXNc+L4+7BZmN1pZFD8sQVuAXs6r7dXY1JXZcsywqkViqOokgrZQvXcV0hxKsCv9kIgiBoNP3A3YPZ033aNmAOHrmZ3Eeew7kNEQRnFuX5kjhVtj3SuEzLRVuq6L7qM7k2MZc3xd7nQnOS1BU601l1a3+PFPn8Yw4XQji201ZBGIRKKRWEQQcaLobfAy8Ikh2o1Uejeh2gUc+vhzBs1f2A397Qnvib0Gp3WgCtTrsFbpw8XHn8ZuHYrsOFsHyplAzDMNBSWt+/wL9H3jG28UYY1WsAtfoor9d3OmEI4Ljp6N5rdpr7+4HrBv2+73l+v25bll0fGiHXZ6dFpq0FXpsbsN82w4EU2xFZHgvYTWIhL8BGNhtBsmyDYgEDeFq4Ru9nkgqT779c+IDg2/P5AkAwF6zDhw4uDLSbkgGMj+weQWQsQC+qpd37rzXR70qx74brjwJwkQC686PVYr5uAY0sxNnlz7AmZxZy2FOPDuNdZjtwjEJLax8AAo8LRjelHcA1rCdVgBjH1LOsmvAT4JaYXoFduMKJEg71bAlKjkC0XuOqLIab0zIrTr3ltIxh97777pMXfs7eoBwuXpS3fNBZpxzug6d8+ctfNi7pm1DAxa/onzJ+ViGEEIcQMsdLcDXxyYBMMXd2fip5EXmMfJF8m/wB+Vvyn+Bk5rhCWUbZYF6UVTmrkrgaxLJMywhIM8wmIsHkuy3KPJNvrqJsbN5GitVumd/NLHtjCaNx2BF4A3BmVMiA7zWylOUsRkEMpwTQlosyL47gRyXCh4+8HAcI4IYjJsm62HE3Lwqxunl691Gkg4lx9hyBBdITgrGkSZNyDqzevEFM9ezvQc4RgXPAGoIQgAhSAtapEJRKSUfyTEr294gMs74gW4E2g6YTQAqByWsoBfocseFZOHB4seeIIq9aqQL1+4MkAUiSwfJ3nU6qSMkYiIVgDLgAxkA0p3L81fPK0aNHTzJ28igFoJv86ScZADv5dF7jrzrB+YlX8XtollGaZTQB3LdDcd8+BJOeOEbpsRMU6akTjJ04RZ8DAEAZfLHXU2r3SxxdAOR4GU1jmyJFSuX+j3BMxVtOcH7iLeIwiCobgoHyXxVCkgz6SQoHQb7xqASQR98oQYF4x3EBII6/QwCTb/3g3yrvhbV/DK+CD5C55oqKUJFeaSqDKs/EA6Nw9oMCJBvcUf8bIVxq1Tp5Hkap2+v1B8HVTrebr/fzOG42yp0kRrRpmroSoNlGHI0W35rNZuLA+rppO3I4vPa6V7/g1KnNjSNRXpSTXg+w319fayHEUXtrcrDZtAghRBGy90tI4DukTgZknUzIAXKCXEtuIgSKtCC+gOQe8bycNZKhW0yyeB6H8aic6ucpQYLltIyrkV8m03k85/u4GP75r//6ry3rrw3jz8QnP/OZz1x798bd137mV6qqqn7lj0+uewiTOXsIvQ9+8INKfVBYHzTlB5X6oDQ/aIl7n//850+PPO1pT3vakenzPzgajUZX/cU3/9bZ+6a3zmZMVSkhuAuvIWNykXyUK0bALk4Ui3Euhd1N/IyZeZNNBOaZj0QBUI1QGoocRRwEOgHASdlKrgPcsmxd7MvEBxEEQbNioU6Wi0V8RF5jwJ4EFOHKajkZr9YQKG4VheAd0zTNdmuUDUxzMLjzzpVOW2vXG8StjYOH6jVarBQr9HjLMXTbYXIwyBE5YzxemcxmoyEFc90w27fxMKjXQy/2PNfqtmtK1mtNioxJLrgTx2li24CDrJfX0iQMQ8s2zbSWIlKmKaO9ac0y2f+mUvAomLbbnDXSVQCAsNUec5b2+8MsSRAAamkx6vejD2UOxvv+YK/Xi6S3kqYRIFUrSUProjhi8mRtLb+h5roAvpv4rquTRtpomFZMKaOMUh1JJWQYNLI4SrrthmtxHjaSRMgIkVHOOd/0dcz9uGftPQ7/gINguc+GLXlJd6tZOQGjsKmfVTj2aIK7Nnj8+Hjso2ArR3tpo9qx273GCAh8NXU+F8i5jbwKrygkwOlqp9cF7HQqEEnC+VadidJNKgCUCrQfYDu0LMOAjQ2HMTBdD9qxZduURn4UuW7OuG27LjBEWBkOGRw7/swdGGT79p06OJsNAdhwOJlOUtAaG+12FENomD3DcSANA5hO0jDEwDSgpx0X09GoEyMYGoZ5McjihEF9a/P255w4gUQTsvc4Lgh9DHa8ltxLXkE+QL5I/ooQyDPHmkSWeUFSaQytZJUXs6ooQb2I52XTJZiNKTMvB0VFs2F1i3IxTXS7mpaLCuDDIpG5ifmijGcbkPnvLPO1FmhiKqGaNVVNwm2UmZu04JJJFDEMg+eUFxKHDMweVeaRwkaeznRRFdDz/QPjccfTZrBymP9NmqYajFQorwHQ8JS4fHglMLXXGY8P+D5/cRAEK4eZt56HxcQG39BpXTSGjLGg25vPjx2bz2mmB+OXKDzPUyI1QO/5qvyXujcN9C4FoLs6mHp123Yc2667s0DvUrqrg5k7/QMHb6IhbbXG2rG9Lbu2/EcpZavbbUnfMcr9+0vt+g/bW57t6O12i4a0Bvtc1920a6uuc63l33uet/XnYWpva8d+vRx6isPn0+p7hmEYjr/rmTxXbx/YX36JBxtRIzUty0oa0UbAj1N6fPqCxLIsM00RAI/zOwjwrVzUmk4fJo+RX9FCx2U5IEoipu9P0mJcViIuS5Eu5rOiPZ0dFIvpJBWEwTpxKTEXe6KQ5Zh4aSyFhAvw1SzbF8vkTpoWsFjxYjrxeCQHToLyJWJapdXB+mpezuazbJAZZNZGcVSNp2OhN47LMfBzmlQv4TwQ6ZPJ8zwXlUpVHeq1dC87o75FOJoDQHJXWZapAnBcP9AKpFgLI4CTx6hjQQIR0nYreYlt22cZtRCtzI+fB+fAH5JSBukGGkz0sAYwzEHw1sMAQmlKKTMEILwQo5DSMMJvtuNrfkuaJGmagPZrhgFoAwhZ2wTouqYwrNBo5UqKZyJiFIG4WtNaGj2dG0mSaIC1Y5lb8iuu8qF+CART4bzY29v7eyTwtmjK/hvIs8gLyUfsR6z0fJIif6+mIhUxggqkJVcBMrTzorLtQwcoxYSVcBXGQ8BLIXMYlb+bbYSvWy8t4yK/IrxMrQvr5/NyVi6yXNpMYQw9lEbVSyiQEF/N/e71118fdzu1FLAPgTYAwwRqtepZCN3ucdOy3VYrTRHt0RGsN+p1BCNwRrYN04ZWWjfqWmnVeK1kFlJKDS75TaCiI0OA4RBg+GR7NPRc4DxtWjbNge47hNS2OzDgiEGwsuX6pmEG2q/XbBvOFIaBADEDdL28ZdPf8gTnzLUMAKRUvw593/cBfN/38f5erweAyF/EERnQ/icV7f0jDLNsCH/uoudmDwEFGFLP7adWzCis3gvCMDkzCCGEEj1CrEjAqZjkBX3ZBzPHo6b5anWeOmSgiJ44LSWBK8vd+Pe7N4w6pkGbL0cNs53dCJcpClbdhSvfXTzwwANPe99OmhpCGUonSfUBH/jx/t6vwtPgCmmQ04RwSAe68UiulQAbkIJLNQGjNlURt1aIXUFD/WZ4xrapajUXpuv2Us8FbDU7k1pNvnh3fd22msq0eGKa2XC6v8gR6rW8WHWROjtbW80W4Pb26bEL4Nx3ww1Vq1ZD8NzawHGD+dkzt8OPcTTaqSpbCGd7a7PTASiK/Vv9gesaaNvcjKLVldnp7W0kQNTer8LX4Qq5hpDRoCjLvCjLfF6W4zKS2gUevi2G8MzjIp/LpYvZIOJMTAmijfjil8gogy9Jw9DathquHzDR7Q2HYTgc9rqCBb7bsGytDUNy8IRUBuO0yG+5uSgoZ4aSwgPesi3bhlqzlXCtLQGIgAiIICytedJq1sC2LTutzaIoqhnWHYcOIx46dMEyalEUzWopEcTeexKncJm0yCrZIefJfeS5hMAkzXV3AXBnO51UCG1RkdyP4G0yIqEKH5CkQnJXW9Hsuyn92LNUxdJbTCf98xW80tBOtTh7vqoQrwlPcNFqay1wa+v0gylAaikNoJX1RlNrrc0aQA0+guPx8TNbW4hbW2eaLcCF2wkD+APFheAqBUifMToJanAwzwG3tk7fOD0wgDCeIoyPrW/AHNIUhDRNKcaDnxqQpvDBg8UK4kpx8ODKCoKC9jhttfs1IZQUAv0AvzOXTmbvG7CEK/gAh55G3sgpWAwcQM/dPJ1M/XJbVtIFAm4E58Rx2fgwDRDycyRdAQHjgOIUytOGLGaXB9kgzsbjigxrx6b9ciHjX8JQOr7hB4HfePskmVX6ISEE2Ha4fF9kJw6bYAoumjdEvt/vNZuQJX9Pm81e3/fD65uCc6s7XikajA58qiLG6kW+rVUNDm1QyH2vVieR8nbqNc+f0ncHY+zXY4poPv710P55CGmOsjNr645rW0NAo9VqAUCr2dQIQ9tynbX108OhJYUM64xi3WEqWdq6b9VNA3D7V3WnfbW9K/Aj6NdHX4dsEgLEvlwx2JaVREDSSoflfUl1z1ClmU8fXp/nef5QURTFR++9995H7r32c8W111577YlbYQ63P/vZz/7+hQsXll+7cOEXgPy/s2fP7u5CwLFh5//c+1V4JXyLhCQn+8m15J6csuwshCkOmovUR9lVvOcSkSbpovJSgn1BR4o09BoLgYVSe1GMKN+RqaDO2po33/X777/fQfCeYSqF3GHa0BvDdUNLYGA71lUSUL3jwIEDwjDUIGSMGU/3tJbvCvrKMMRhpZX3DINxtvyWppQ/aLouSmXsXzxRlqVyHdGgQhgbqwZj7Mc1BUIaz/EEN88pwxTPvuuuuxSibBWGNuiAmZb72pW2RNAXXMtiHWpo47e4NtRXHcaCJwwpgdd9NO/4R/Aq+AhZITdjtCBPaEmWlfk8LBfVxPYopamVGahd1bRGGx4+BL4SujQ/K2OEAYFhTuNN+TnIGGdIr7YOMG+9c6hWjzeU9v3hcGqZiWOzf0agIhxko7wtuQE+FwDmrkORGlRIjbjIc5szFr/XbLZaDQfBgkc8AAQd5PnWdhIDMhY8Rpnvz5KEM9BPywZoATjg2EdcSgEajUPNet0jhDDC956Er8NlYpEWWSMHCAmTVMi8yItFMZvLbJoJUDoomGxmKJJJPqs6JGCq51eLeV58qGpboWHZMcfxxYsXTX64/aAVhn2uxvOikM8z8nzfs/6DmbcriMTZwBISOnD09rPT8cpolI2KIDiL5rmnz8blhrztxot33f/gxYvXnTAB9KlrXv2Wrdls/pynEkHI3pO4C5eJT9bJMXI1eYS8lZBRkpZlkmZt6ne2WlSpj01SySpDidGCwKzKdLvN6XSWTtsC8aya8MuggjSA2gOjA7bv0kWVFmk+uliWU+dPN23lr5/CD4Ay6FM9p6cPOeP8qN6BJ//lqtuPHDmyXjCHO7tQC4brd9Xr9ZX6ylsGCaSRwbhV6wShaVkJgJQ69rnw2r0wgLf2er2uKw6uMQozQBz9Hga+Ur6HnHP7Pc46++rfP/CBDzwUn3GACvP1H/jABz4wafjasEBAX4Dj1DzDEIZWjCqaKQDHqU0+8IEPgPM20JpxrYCQlJC9H+IufBjrs74a6ZNbyCPkbeTnyGfI/yL/BxjksANXwb3wCLwJPgSfgz+Af0YTL5LidTISccQ066RKyGmZZ+k0ZGWOJnFC84pROSjFfFyK+aAcl3k5K2flbJoGSKeP68pJPC7HsczEq7OUxY2BV9jvw7JMy2lZhBcBr2WdUMyg8c+mbMnRikf0bZhBbk2elrN5Pp3IKJ6W+TyfLsb8vGJll8szIZN0Uu3cpi1KZiAFUX+0EuFEIFfMisgGRSqqM+YlMN9JyTSpqmk2JfivRUTXYpUfCatLWwVUmJ2Yhc0hyQZwLnT6PnQbp1rYVUATbnpYY6bpbD4uxuVgjpnfG2dRJggG9cXRNJpOXgg/n7w4WmVb0WJtLblr6dSD8tC0nGe04g3EKNM2/BngO0+G5X8zTQPAeKGGENQzjFnbH4IHhzHrd331TTRXAivFgdWsgkW2eqBYgSfn8/n8beBIQbXgSlHLRAXUNlBtKqWY8gF8xdQK2jKzRzWqTAPQUgBSCqpNE4aUChPltq2UAqWZ02w2PVRj09Kh67s9oKTWnCM1hZTMME0Ay9RMSnFMKSXdmydINUDOqVKcMVyZ9wINRNMUSgFyFPBgWaY+5kKtslLsX8uGlm1Zo2xtf7ECuXnClsAwzx2ymZoJZ23AA7L0nNbtPns/7L1l/0oB6fj4ie0UsCgOPHNjd3dzc3d341oHQEnORpzFMeOcxZAwnjqMQxCg4KOGxRgVHNAwGWdCIBhaSonCl6YpfRuoXQMIXEaV4AAyYYqNYgWAKlAUuRSUOS6jUnCKOmCKMcdlVPERcDaKFQAqN5zjZ1cbj+hXWjhnT/JRxjhjjPEbDhQFQtJdW19b66ZQrOwnFqkfdmWQITlIzpN7yPPJG8knyNfJr5L/Tn6PkNEsKyru6WTuLNGaTBHzokjmsQSG5mjhZFocpmsfQZZtAQQi5D/Y7DhPxvP47kRIX7tapJlLRQBDPEQUi3rmSFGVydRhg75LbSGnDhwhsCReWVSj/OlAeP9oonI5d9WyB0/eLfMA24k2GPMcB8JGlKC3s7m52W612psnkyRJgqHKitC2bTsMLdu2wtJz45m9m3bD6F9khLV7DaRBAuh5ntJKgd1AjCLXENZT0zRNI8sC00xPeJ7nwS+As3zOPbffdvhIsFyTLmOu1Po/rLr9UbCdaHn5snzcbwbKgpBl/f45J3AS51xVVdVNN9HjeRaGti3CMHSkDCMhndAwrXrNsoxjSkvp+ZzbpgKUgis/ZSw0DPucZQauZcO55b85EA763a51j1wIbVmKEMLJdXLHijyVPIu8m3yINTyvg8Y8cWk4JySNAhJpVEfLplAs/RG8nE75F1Cq0IyXKn2pN0+HfVxq+JJ5KQvMH5a4pvTUYhsBMhbLUi12sS0jr+bzOdzrfu/Yueta9/l+ufiPwdfX19fXpidOTNdWp8ePn7/xxvMv/fS9RVEUo9FoVBzs9Q7tTg+vW8esc6PB70dRFBb8zS4BWfbRb+zujsdYwv5DvbycbG1tbZ05s7199nQ/6aX9t59ZW1s7v3rn/ffff//bb7/97W9/e6t1//2Htra2toh531VTpEZWyDFykbyMfIT8Cvlj8vfk36VpYtu7grkikFDPL3LZn/bO5kUuhTZ4P7uM6JaQ7dIFFt0xaTbNREytDmGyYbyUzniWJrP5rGAYBSt4I3O0YNJYH6XLD93Jr+rk6CCOYvHVV7PtrsgyLvftyoU/W+fZNyF2ASMXns45p1z7DDhX0OKcU6YiBC7kb9dvz5pdw3BWOHg05MCYibAJN4dhyLUTWhZgx7WA+gwNurK7u0tDig0TWUABGGcCgUkFNKT44U39+jH98cpNPROAff7capuGCB71GXh3RAheiOD+SoRuhO4Ym+gZlAI2MVKI8CqH8Pm+3hUS2FMZsKZE2NQoTADbDjsIJqUM+C6F++68804ACrTIKQAF23Z8Btw0wWvcM7Zydtr+1AaKb9P0KQA+CBT4AzOIHcDI5U3Le1tF66DSNeQB8jLyKvJGcpl8k5BRLqelKoLRLKeb6/cTLqTA/IdzHUIfdYKm7/IYIwpcq8l0UsWxsnYu9oAfRGcg4yKAaTVdyc1f54qUtErzIu6PA5dxE1+oC1TZNEuqrRqPnu+Iohj+1sMhei+wOLdigPh9xfwHcvkQ3Q7iKLQBfcs0AbcC3w8s8C3LhJPNZhNMg8vAMwzImlcxpeSwi1IbbGP4sP6qQGZdlFGkAvlsFf3cqVOneBq5br3heQCO06jb9p9BrQYIYi4Au136qxBpsK//tQDQAxO0ZkwpvwAx0KA0ZUqFOxMX28wwvOepbh9B3fyoaQLgo48GUsqW+hyoVfkxrdHzu33Pm6ao2trzeq0gDIOWFASHdwdSIoEbyY2EVEVa+OrSR0qa6aLSoGeE5vxYzqvKXNIzIUaOeSRrOxpf/5vKn4ZhGEdZNwwhTlprYeBQbg2yq6p+H7DbK7gYUlhZYweMC2udLuIpLdu+D3BwI0kMRv1O+7qj/QG+oqzXbpxOp+i6WK+tLZIU2u2p5ay32wBhuFH6vkBQjS4M5bUUwmB8IAAUSkU9gCjqm+ZunkORn3o9ou0gifW533XyPMRzIlHrPF9ilOXsBCCAuzTZFRXayMrYTpNp7AWsUZrJJHb6VQdcFUX1DfSBDWAA6v9lFn8trUZgO5YVJpYNput2r0M4VwaBCQjSdlojANMIABjbAIjCxj4xwmYdIKGsFrX1OzHYjmMFFljpG4JT7AUBOM6g4blgaOhJwlf75tsppLVVxhEj24bIEpwCmKOOZcKYpRB5HJhpdlqmBUHQxK3M4SX4OlklN2RMPiebZmj5UZTWEsaXhsGEdmoHLvheaL9PEVG/1Dfz7OeFTNJ+mcQj3BJGk45bVPjg8ePHOwcPXed+95D5PEFMJl7GPbhv5+Z9W1sNSBPEZPkD8eGnNpc/KoU1sXziiSeeSBCTgVXonVhdw2t5iPUUkwSnfWvcc/POPoRWaxuTBNP6l7AGzjc1EWRj7wr8DFwhu+Qm8izyGvJ75C8ICX8d8GjFo7lpCtz4jSp9MYrVQdQY0h2W6rJ+IUVclFXSY4hb69Iyz3I5yzZKLgSMmeV+kMwADWiaK+SuldidYHe9YjKdTLHUz5iV8UKIleIdDm483EaSSCEhtKJJ+nx6cEGYZi7/+cRh4DuO4ggoXDcMwpppguNaFA0jdFxAMUfY3Lzq9ukEwDCzjJqGHRT7/6lkmhwG/U9xbpjeAGlkgDANrQBd1zNM0FYQOK6U4usbRzcHfd/S2pGWbZpAtZbSUIYjVRhEkWkyAM61TgE4A7DswHJdCzxKg2YjjgEotfxWq9GwDYraaN6nTcZNTRnAX/ndbrfjR44DWG/0B3VLUpYURa+H4LhJY3NjIAUD8L3QcQDcnX2bGxT37dzWb9SNZ1j1GkXHaHc6XRdB3HVQCmmamw8A5eC32+2W9x1M00ZdGQhRmKaWkBK+WabpWj/wAVzP96UCKV3teFHkugC27cZhQIGhbVl2EoaWZtwMERC0igRlQKkUpm53RqPeKyiCNrRBKSGUkL0n4QpcJoL0yDYhYVqkWVlVvu8LKSREpQnvlArQH8O0nD65vr5+y/qTNdMn19G777770t0XHq5dgNXLly9fPh3YVrr8RVhb/gDWlj+4cKEXqXNy9p7ACXyBnCd3kAfIy8kbyWPkA+TnyafJ18h3yG+Q3yN/Tv4/+WcAsKEJOWxCBVcTNOjVxTwvikgzzXA2NeNymotSWQo5jvnxgbhbS8RD8aSakpLTacwgOF7Lx/F5wYu0mJbxPJtmnNFz8VxWclwM9hSPy5lbe5KW8fwARsbLLVdlzJ3sulUZS7zeRuFUJ1DZq1lZhEn3IbC4FghSaVVOs4T5VU6WRTmVlbScLctyHq/cLcp57LFnpmazcp7mRaFeimWZhSiYVhUwBryQgPxa0aEGac1jqjItIzkfrlJIn/WpMy6xmE6nCPYOgCP5Q1xK/hCTDsKOAliYAGYFYM6WmOIZTDoAMxOgMgGM5fM3HqaAzel0CoA7MGN0urW1hbPmcwoAst37fsk0zcSE8+fP33D+BnH99defEC/3n4u4H+87/wL93Oc+d9/H2MuYEOzqd04ffEQvUet0cfDgwYPXrw6Hw+Ha2to5/xmSUnjKBXglE4Lde2d+59NfzBhDuOP5QVe0dpllURQxH45VVYUYZ1vwW7feeitlNt6D1Ek6W9WheC8zAO6klsnuRmrR2yl1IFbwywoH8Q5qIb2bWhb9X9dcc801NyGMp0cWiwXAPYiId+Dszqdub28zBt6ZG1zXvfpgAQAfP/5U+LZlWZZ5yy233HTbOXHu3LnTLR8mAPcDYw/c9nJ8yUtecuggA2CLhUBEWESnr0+S5MjN6+cv5nmeX3Pb5ubmLcGBn6cAd9zNANjdd1tSSoA7zyeHDh06dDIOAJ957733AiQfvR4AEJAQJOHeFfgsXCEJ2SIEsmkmpJBxSb6BChgnIa+N7wRBZ/JpmcHp3/u93ysIMebrxZ8X9QY89bP9BqyitfNWW2uYPgm3QbNZ/J887X3cpXL49IPL/wrasN++bOtl8xiGsj+CK/Ah4pAmWWFQ2sjZ9h0RUsiRdRhCE1CY3odcVEmaF9Xc55IQ0O5MpofrtYsnT2bwxrj5vBtvHISNwblzz3dr4uB4u79VzBdO1GHWg9dckzU72dHdW97UaByeTDttEMOTp+765WaYnbvxea34+efPD/4j3+yX5UFZj5ydxTs6zey6a59usluOHcv8JiZKQnAfvIrEZJucJQTwtqmtVtHHhmSSLqqQAT+QmWCaWdZHkstYpEkaFjSkeZbLXA4kJTHJ6IAvffBq13XNne3tnX6n0+lubh9aWznwtVF/tnNwff3gzqw3grXDp/eV5b7Th9fWB4NBOTuwsXFgVg6ybjff2d7eybvdDG7813/9V2i3lLQBA1hfg+XnvRqsrkLNg4sDwG4XYbD8yCbUlj+CWgxFAfHyR67W7bbWLiGEcCL2nsSXwmUyJDNygtxE7idktJjH3vMlaEWp8Z4SrzTbXHbtAHr7TTmdNidsMdwenz6wsenWusO0BrQfhICDbAavmGUDhEZ9bfkZtLsOotO18XZwug4MjNwx5+feinY737bxfwfh6fF2mqRnWQRQq2Wm5XY6w1mWAWTZbL3fN3/BRrSf4yA6z7ER7dc4AM5rbET7Iw6A8xEb0f4TB9H5E1IQsvcduAK/RATJNdBY5bqv19RM1+Je8iB5DnkheZS8gXyA/Db5A/Kn5K/I35P/BAE2RNCEAazCGCo4DCfhGrgV7rIFS1CykCbsVmUhBzcX82WGLHYmzazXnHKX1eCQ+bcHm3HtR+N5MHgKoTAUIiG6WYnz57JMYW6aEMsWVI9McDYwQTpFPieYTMKxLqOfXEJ930/LqvRpjXaMX/ZL3wcTs/zQNsdHuDntCcDmYsbt4yErFaPzqt/f7XZZN+t2u6zzCcZYl3+k0+nwzsunHvitiqc45x12G2Osy3673+/3tweDwWDguLf2+/3+3X9uufuWt13B8sOmaZqnBoPB4FSapgPzk8WjLWK+Jhdj8DwvCRAVCMPUqq8x5dIKPA/Q871GrGddJcsCrW3fcV9imqYJt5imaS4/ZZqmOf/jP21/97vf/Ra8bvnSf5s/bX77i7+g3+/3/8T8i3+p3+/3v2TW9up+v98fDwaDwXnTNPvJcDAYDHLHcQynZdu2YTPDMBxjc2r5mm3b2hkbhmEb3XnvT661tg24wXg/afn7g38zzcFv0JXl083U4TmBlJQRPhI9SSmlWiAAZ3EoJIAdaEopGgoRGA9uHnx2sN6HG5cPwbuXD913H7x7+egtt9xyCzjLv4f1Awde1Tf6HzHf2zf6t5rH+h8ZfNY0zXRgmiYhhBJGCPwHXCJ9MiOnCYFsmnXfkH3Zclni2qhfapIkG5m4joE/IHM3DGZpmwX+5KGHHjKV/KaS5kM1inX4dh1pbfnVVphTZ12rFYZh2PrtQTNjd3BJSXNlxZQKa8uv1BBrcE0Nl38IYdBu5XbyrXZSniHToDs5nuEleDl5MIff0FYdYA5wmM1I8tEMJXITVSdo5/FmZYhZcOtSuyCpXttpJIevPV6Cfn9yeG1tmK2tHqxaTWi19/X7/SYyrTQIIXqrK2u7GxuIa+vHzpbjoj8cjkvP87wt1zaV4zP2JabXn7SD0FTMABBRs9k+VOQAQbDd68GLpt0eYD4qx6MRYre3utbtgWWGSA0EQ0jBW54PsFIcPba6Cri6Otvo9ZAO+oMBAufgaK2NSa8LoA0tAUwlEtPEfHTIMDm0O9uEACF734VL8A1yEyHhwE0qnEaUF88SzoaopMRlhvUW8hQgJ2y4cCpkjqJrNc+LPPveDQcPUYzjSDImBBeARXFo1u8BaBVFg9B20LQA0jRJ0eDS1Jp25HOI9UzToNyIwmg+GPgezmdn4Rvj7ZvmrTY4tuRK2054eJQDtFrzVjZsNMGyolar1e4r6XurjVrSWF1bz+JYKqB0rdncdIJAa2i3Nze3r9nYIIQQSsieH3XaInPy8nx75nnB/y6c8hmxMzbUtmDiKTeCqDoNrCZV9kEjndEODFxcLgdZ3pEOMi8L4Jd55uCNsg/g0WMXDk8mnTa0uy8s9x2eTDsdCPzeh6br8lTIWoDz2XXXLCqk8/l1D3DH4ZIzLihTtSBwmeSKftweMIaCAxdCAxcCQGsKwOu1ouG4lrYsJpls7XD3LkC7M5kcPjh9frc5+iG7ubLSW34K6iw4ITfn183msFhcc918hm+iUiCXXEoquOk4TSGYwzloZShuUZAAzDTDyPcYgG42Q5MiopRGwikCwfTpvwSXyRaZ+4o5aYl0qemxMEzD1Ej2prSRWLeES7u7uzfedePueHzSPve0229/2jnnxHh8pdlsLppw+cqVh8e98RNPjHvjh5dP7JI0zFJCiIGXYu3vquh3nCjIR8r8dbbCTdiczkB/ZMZ89drpFHE6vfaa4bJroFfUG416kTdoJ6/N32xrrXWHBC8BL8Tp7NprZ1N8/2uaOB6fPTse418zgI31o0fXN2BAJ9pWpMs8Hp7EjnrzdIQsThycQ9iFmRv77euuu66/JYW1mV3bdhv+0N4jP/3TP33BsZsXHrvrTkJIbe/f9n4LT8HXyGXyafJL5H+Q3yV/Sf4ZNNRgHXbhWngNvA++AL8Gvwt/Az9BE3tY4gm8mZDRQubFQubFLBvIXM7mk6scbLBuoMizRbVI5+XkqmZJ0ZLRfRHKasIJkBv47zKyLIgkGxfFkzRJB3Igc6kfQDUaNwz68ljIPP1XENBtpQfuzopiQUWjIbVv6IEIyjHSkoLKtzeZjkvuB88UpGFa0JEsHHodEcVllyu8kHS8eeAC9WenXtbwPO6fTCdpkcTbp2ZvuSwn027aCK/TddOyTOJEFg0v+icigUY0mZcCmnQN58SkSqrFNKkSR1M7yR67LY0OQBS2LoPI5ClryuIZIcCuNZ4y1Fzmoog4yLCoARkbTBDN5ppITkshcxsJ1VREpbPRilnNRUoQvVhcLWaVcKuyEIT6kueZBRqqhmg0cDcvGi5aMp8scHa7w0Pa5YK5UgvBXct0XU6pDKhlUo87RlyP2nddV2uKiFyYUioAIRpuc3Hs2AHBG+nKMDEthchoGDiWzziAVCKh1NWu5/qKMcY4kw5aFu0r7rqmDrgQWrpMcFcDYK1Wa7mf+pTbqtVqAFchEj/aZ7zOXSkBqfYppYYSNZNRJji1hFjeAZQqGwDrXFMEqRyhDEqpr8dCCssCKT329V4SA8RJr5fEw7U+IrhlAHDBXWcBwAzP0xQAWu2zhu8bHDAITBOAPRSE/FT+c2rlcc6GlgnIte9REYQWQMziFNAVAFS7rhJCSgCZFcVkO8/7No+ZaTqu7xu1NDS15qABGDMZcgrAcG1nZ0IdOPeBD8wP+gFiHB+qjPmBfduUgUJmMgbg4kOG77uubQHX2gxr6S+yer3ddk7tLH/g+D6CNmxtmowLYf5u4riAadLwAD3fYq5X+yEIqUyBFKUyDIAvmkIwbpqGZWhA33cSiRS5LaUA01BNlynhSc5MTrVhaB0YViRMbmgAihZQzrTpuo5j24pTqii1OKfD2jpjDgDXPLC0oRCBgbKAMxupopQF/X6kGQMACymAAQY33X6gdaSQg8W48oViLhf1MMRUiBTDsM7FkmtDG56nU1tyx/EYU8z3fQu41EEQQL+baM8zDFNzO20x5jkO52D5vk+1A+0acKDQ6f98Evf6cQKQxP1enHzOCQIpU6cFKDyfUsY8VywoZ2GoQUcxmwLYnqc0V57ndgHAUI4UkQmA4HIE0IBSeKbRYHZTDx22Wq7XbGVCftZWCkzDrfk+5a4XcHYsjpBRydl7zLDZ8zut2q4QAH1fCgBhRH2rE3Q3WWr/N0whkWMcNevCNUwwdBC6HmO+X4OXDR1XytbwwPIr6NiO5oxSpZRhGl8A24latq2FFzDmNnwP/oFThsLkUgIqJY8bpqGUopRx7dgOroEUwhTIKJdKISGUkL3fx8fgYyQgI3KGkFEky1KQch0pun9qelrQgkGEaqtIyheRUE0RtRN83LbDyLZtOwpte+kIxGkvHwzfdestk0nBhd3tXHX2rS/Jc8fJRo210elud5C9Qq5gtzbCDTxBcKSMkzWlW51OFAE6bqMxyFbz7v7R0Pdj8oiD8bEPyIKcIreR55C3kE/KHKgC2GpiYjLgXaHKZGq1t5cX81QDpEVofJyVg/6iptMySVPgRqRw2DYvT1yBa+qp0Dca/ilszAE2DPHhS2Q/uePgQUoPHrxjuMq90GytrraaoAIF2Ol0Ovg982P0fuLhn9KfANOMaQZvBW/R30e+YbiuYWRRkTewO5t1u93ubLY7dga8a8+/9I6DB+lrHw2ardWmAlDNVdtx7N+fLb7nIXpv8wC8t73xta99LWOvZQBsHBtdrbtG7BqGYbjQ3DvfzrYc/MVB4X8YQPwtJoRkjZwgd5GXkncQMkooG0+ysSSg47SQ9IvFvxoTdtIJt4KN+vv0smkWpUIIMGHcNBrazR0sTC0LMrCsjeN0nl4ByTwvFskoTX8jPgvCF9qcgwVgMWZLYw0oc5RlS4dRsAHsp4Jv6b989MJ9+/YBCt5qt2pxAodsi8KX+3neagK0W3nRyQcDxEG/+C8062CGnDXqh18WWNb3er0etR2MIaOOQ7+Bm/gKedh3R1EMTksAQqNeOj7X4HrD3HVBtUIuikLwsHVHm4KotREuae0S4r8WB6Rz9u/6zvtmhCogjsTTeTxXOZxeCA/lqCG8oHonR6Npfnz1pEQsJ1dfNZkgTiZXrfS6O9vu3dAduUfdn7ikvGS/fuHChRurCrGqbrxw4/4D2Gptbc7h4U1+n7x6UuLyR3arORy2WtYTTzzxhNVqDYfNlg1nfEtekuU9uFjccNtsDjCf3TZfX6/XAfMp1yVHyV3kuaTfaVAbomESTaq8dsb/8r4n6XSZrcZftyzKh9tNBlU8OMEv8z/3+32lNfaVDBLdYZ7bCRsNimmtthW9fYFqXXS9XtRoINTS2lb01jM7O70uR4RX7s6JYzs7gwyg19vZOX3L/n0IOzt33LpvH9IDB2/8K9/3HUo3AtuC2N0eRtZ1wIaRT5UsaP/5RdQ0cX2fh1Zrbm51bW6u2YBGvZg7sDZXNJuwvSTMLzzivF27BDw/f/7xcdF/3TFIwwhuQ2WURwrRYMicuqbfa1FR5LM9xey5ntzc3Nw8eXI6tLe2hoeDl29ubm4Gh4dbW3Y4ffLktzY3N68+eXI6sLe2BofDl1199dWb4aHh1pYdTJ88iVGeSjufgH/my3qrRuisHlcYOJCBwyuggnCi4weJmfcIoLS9nPzEiRMn4rJ6+HA0Kp918Ip2uz3hnTx88DGPgSC+nO2nnThx4kS7rBw+HI6Csw7idvstLR8+eOLE8yqDnQdhD5xGu9G5Ng3WcwR65EW3vZcHYzEKy0wxz1wabSHjtWO0iMB9gfeEG2CZQVP+tIPtBoHtHtIYMw2jPnPIMA3GdUkO664TBG4gyTI1dAeCoNsNA8fQmSRLwV9xOymKpI2Hz7YC/XV+tFs1xrB7yDBMxtT6zE6umaSEdQczphmaZqmEGlhTMVY1bFCiWppmfKZIEoAkKYp2ApC0i8iyLCviZlzkn5JVUYoG6Pa+jkqXGTbeRRSJLuDps36Sc+N2ImcZ3k1geyfneOhXo7lY38t/4GuqqvlDp3VfKH3/fTNlzyvPvH2e3aVJksAYMzTTULVZVVMNu9ozVFVhnFJV01TT1AzGmCBJmmlUKoYJhe06juO49jVh8nNchmyi0wHodCYyeIskYFERRVkkBLRZQ1MVp9JTVM2gnDJV1YAQURZFRcSClMLAi+K9jHwDvS0UoZWsVwblqXAjsQ+2TmA6b67AbYPxYuwFHXSXO8BLt58HN20/r6SqUK31fXRSrQqqUnqdrKpS2+tIvWTalSbKcs2qVqyGLEmaKGFJzvwYtlS19JTVuInyp1iKuv1nUYzdVFYWviKR16xKVGpwEUuiJilK4sZ9yr3IH/EWPBvdixAgdRMH2GWldrMVv6ToIx7AFERJMrTYSNIs5UDSwVK4KHrxeDQcCSjscjTPVdfz7Xytry78PMdbE4ZkRu12XT/Pshs14AzidhLLnu++ziyZlKuKUfZ9hWuqZiuSo6kqE0um8WxDlpmmKBo1TUUbQr3lmgZL3F2CrhsiZ/hebhrSFjxLVVUhdZLlI0fWH4rbuxcBzjv3yBHP90EQqKCBJJl6FDXnxqOy7vth7DnT1SjUVEJA14AxreoHFbnZCKsCIYKGa4+S6vWmbegEwhJjoANCCJUQFnxKUBMVXPQn3Yi20PPRW9CD6DPo2+j3/0Mb7QrM+LDcY24XxLFfcFw6Jj9VHuYbp0U2hyzoiK0Qp0VGsVddsDta+R3PbIqKN5flacHzPO9oIWLzg6kQ7A30bezzoqLWvC/wUZHvitC4XM9sR5ZmoGrkexoc7p1eaEyaNbBaq8h3bg5GM9+ZMwp/pitWgNw0cIwPF9hpmq5fKNInrzQMg+hcdQDB4ILAL+ecC5xhJnABAyxwTosJ8IMCk9rqWKAEM8yWGVMoZVQlZB64yWFgy84WQaMubzAscIMLF29+DBcYJlTAsPIl5rD6pnjuwK/sDffff//t98fry7aWuGnu7/cG+DvTNL0BzntirBeTdzPGiMuZPSxtGMbhHAeCILTg2NU4BdMRQgCIwYVJQlTKKFUYe8Zh3ifw/Vs88lQBA5yu8IebB0v6RRIeZ0M6HUO2ffwNt99++/23f/dcH+YCXyUQWeBPnjVRAw3QWnYQ51uWiSwc0/EIXU3KH8TRkaahsfvcTU6r5ikRNG8sVauJ6xy6dGk3hhtsPPFSuyvdl3nDLd/73vd6rZZ0uD0c7t63sNDa/hQEmJUy/Gl0en3hwzXL4k8y1tauWKm1dyXTg/WFhVYLPvT/UKlOP2k6DAFa8cLWml0IgqQvzifinU/CP+D9IPZdSUcEDuNelmFsVB6O0lEv743SUW/Ui4fZKB/Gw1Ga/9uf9/J0NMw6Cj99ng/jYdYb9fJ01Mt6o142zHqj1mjIxS7N07yXDVXK01E6yvJh1suGcW/Uy7K85Ycc4KHR0xi85YAGEOasWOMW75E4JBtk8jXWMfuEpDfoF2weDJe8gIs9c60z+MM5cNkMBREV8vm+43p2zffey4cj+AdgGoB3H1iAhwYeu6iiiTJjqkaEqDprvG0rvjesA0AQsBWuRT47mxiqZ1VmZ9IAGGaMKoapKcAlgdfqHW9qcmK6hMu6rotlEUqrqxdLkus+jzF1HSCHAgaFAw9bsTjBwZFN+MtHnK5JIiUSw1jjQKhSAdApBknXYt1KJzrVCUlqBS3TILIMmDHL8n3HdvfMzOoWFiqt+VafW5azsCJgAV84vwDN1tzcmZwjhDBCO1+Af8JplKI9CAHjec601UcG/YLx6pey1bGD3PPT2EbToXHUpCS8fMZh4dhgSOmgkibTRfeMyxhbGY/qdaF6j+Gy1W5xdaMV16eiKIqmGq24MSpZljWC1wiLi+eed2bLdWpLmLSaRbEqjj8ZYbG2fZsN4JV6s3v3zvZKLgZ7sLKyd6Xv77X+ASzAp9AQ7UU/aME4fwzCASTLHn1LaMNFhkwXWy602TUyiRmmmD5S3O2j8bghkfZqCj+WGJsrLj+ysur6zUbryMjUNYAwmpjolsMgOrBrIbynOj2TJhj2U87s7Yu1MIxn2m1Jat+Oa7XJiVoNf/4Dpm3bZUMHSphTqcbQsMtld07TpoTB8PxKtWocvLza6bR7pslFX8ECpOlal9EwGDSTpPVAVm+4AeA4PnjDZBgChOHkgyLjALpRNi3baESRHlOAPoodaqBDfWcmb+5Cr6vCgcC06kI8iPnuFnrIhnPXNy6K3OOdvCJNrGsyDSDpeu0cXZZlWV9wzToWDID/vfDCCxvu02XHbiYqNw1FVZy0qarwNGFxuPycnkOEfGqyJcs6PFqXZTvozxWLhECpMax6us7kQK1E+/eHgWhx7jpB7bp5WTI+wMfvG2rsfBJeB+9D16MnoVejL34ICzvWfXh+jkHMrJzF1hNYGJrOi3EqqVwKYgmiMq2Lq0NzLLdNcTRKs27yyw6d5y7RSTkTpcLMAi5XW5SlTulrvdwbDN3+wRGpCt3Ekr4bCg4welyYYf4mBYA/irGHVY+vkSuAk2TEBSJ1ymUAx40iV8cCQNbtNtM0K4oURJEAtlQs/4liAEx/AOO9e3s9DGkyHvf74TIQwkcTnUqkckxETnvjcScTfjS/vrYwb2NNA2Pv8tEj60SS+EkQgBIsCDolHAtAGaUlS+CcWowwjDFhjFiMqPh/ZEoFAWNRi45nYQRQiSbyalUnmgqgaZ2aZXm648z6TZ+yRjYeZ2kKosRAxIL0gASMEoFReNIYYKp7YLXTkWXf3wWESBK2GTMNhQKIIuvKMheV7feOCZmcPE/CIF3QH8AqlyR6PcVAAQThgJ8ABkZ5yWKcE4sRDhgYoxYTVIyJkT8F96EeWkYXtTo2tbQQ8hKxDRkQHbMufdIL9X2PO677Uq+Oi/HA5UMRNDqldZH0izFHe6MuXhk7XcuQmEyROVcIs069AThuT00GzDSkOazrGMrB8krcOqDbNg4pw+A6joNxVImeyqanzxpNTlVrKuVMXy0ZDNbOvEiXOqokC4RxwnRd4c59UwBN01RDpxhjClVRCoJ+4bqS1JYMQ5wDw/Be4FarAm7UMx6LIjaNkLHzM1WV5TBW1InXK2EkgG2VfZNhjAHKngcTxMRlzhVuOxIFAMCUMgwAlGqqhhACVNr5AdwP9yELocSrjgD+07s5zUt5DM4111zz8hshf+UdL4LT1zxie5tzTfY/8DA8AaW1kBiQYU8P6KeYkkjyaz7r4LSwcdGerMK5ZegWrbmGXg8je6g6lpVWMPZcr3n8TALp3lvv2l8N9mUZuJGmVVwX00NPiSp7uuUmIfL1Ar4AYYR28MpG/S8OPOPBKMfnPi7ZjcDS8ePHH7m8/IHlvXhkN7j9wMbGxsYHjh37AM+24xnaix6J7tmmUgsOrBwRG0STJ27uuABzgm690s9Geffy3aijAB2ej8Fw0UVJlBojg7Wd4PFPr38uINQ7eNTxvzWBV/ifAWcoc5h2n+CKANSrwKHIsmEApQMuZwE/B1PTkySJ1xtc8kjFkMyKgLf2dD+Lc60MgJNbMBZoEGLxJiFx92FQ5CYLhT8FQSDw6xlmtZdiLAgBoGazKZZKYrMsVyqyXzbrouOX0bnocnQbmye07Hpunnu+Pxk108EtZUee25S/8RgOpEQJ2FInxG1knA0fvm5rin4xHvHeWgU4u18uwB22rlPfMPeN7LDhuqAqDllc3NhYXCS2qoLrNkJ7tA6u1yS67viGYRj+10uKghXFbBGQ5dLvQFVMU5ZJy1SURWBxlsUMy44bRa4rwwgUxRKsUpk0TXDdhmdZ0mq3i3G3uypZJb/humA2SavsU0tVwTA83zDgdtA015EknDm6Dj1X0wB0zc2wJDnrHAgB7hu6bvgIISSgPu5kH0ITaA+6vN/clJ3FP8IXw44NI3+Gz1r9Ts338nHcy3ObxXS51MGBKZeaOW3wIEN+sxiKSfgP5/C8Ryr/S11+9559R+cXqlWI24PCtoCCiYfDs+YHfq0mAZjYctsX7VoAnGbzczOkU6kCnAUAVnl2dyXMPE8w3JnZYnYKM0oZvCIFiFv9fr+fxBhURaQUwCovdTo4mqpEDLYfmp7sVO21fcc7YQTQBHN6etSteJOiWmonk/XKoFYDFwjhHBDiqnKRb8AHkI2m0RGEGASJ1sU32eZBYc2yhSi1YK3CmXTzaxQOyUYMArbJC3mzwSilJSVM88b8wmGFcZ3754rWqdPp0tLS5DnLk5MAk5PLB6Z21Wdm5pb6ea1areX9pcVer/ZXAMx7CN3LXnzmREeNMKmdLN9wuVqv188U8OTknk2lu1u9MNwA3lKAanUoB0XiDrZTwDNEE/BRn+XtVyjzU57QxB2R/+OSeXG4MkmSJ1169Gtf+5r/8iMb29+AzvY3Zv61vbGx8bXH/Otz5XL5a0df/ub00ic/59SpU1+vLhx6znOe84l53X1k7fByzzwNvQy9FZXvJhQaxMeNt2xx3Kcc4hSJaQU+LIpbRTy7/GFHmOXqOgUWt3Gq8delKB1Rz/J9NY0TJ7YFo+tR93IHbFpV34VfRlFEoA0kogmpkASLAAgwuxaJogAhlItclCRVlUDXMYgAIm7TiMBA7UAiAu/HURhG+P1Atn9AKoRUyAuARJRGBO6jjZOENBqENBoMp4Q0v2eLLO/HCZRKpinRmzFbaGpCTjYo/falbVVV1fal36aU0mVCloekPuzhx8MTEQe3Bo9Ad7F6lyehMeAdw0yFvK4JgMAs1cakLfBkACoLxxoMjf//N6DucE3ooJn83PPx44FsYAFjAr9TFVlR9AjEDREGdorqtqXKsqJdxWwrrP3velSphZbNOHMU1Q5dt0aZlpD5uiqG4SdaTVcUWdGgIJRsEDhNhREApm03KFsWRNt+pYAYQRTWy6YJvmG4Tq3muIbhC5LcXVQ1oYXBMHzPMHHTssqBG1MB4zGmOS+PMdE0WkF+E6xE0Y0Z3vSnvPGbnk9XjA6XbkRK7OMJ1hTZXFszZeX/lGHfPrYgKCd399eScgA/NWXlgCKbyaIcL0uSoAz/OABBOfG/zF6FtyBC7b6QoL98boQtYvw/pbhCJY7a3ia4AugWE2cwMwRARTTbymyD3P1qs9lkSrqUKqy50pbaK3Dw2LFj+/cfkwcu+9b3ve9977vqpd673uW99H3vfOf79uzevTsdDtPPHbXZ9Es9+cvwRHgHaqPDcVOol50XVcg2VOBn0s3SjFIxJfUdNpKNXc55dz4Et1e7bLIMvdn1tW7XFXA/jeZWO3FLwFHs2gCW32qVYXeQ1hwHbDeOMI4uPme5GS8ZnTwfZY1mrSLLjJY+Uh0cSjPwfQfDvnLWdpwkkLnrhJHtYRyyKth2LbRdLoeM7cEwm0XremxbIMtBmLTjlosQQgQ1dj4M98FHEEMa6qC9CIl73ucUoixnA4H2HP01kX0FIpnGSzVc0+MBP1/kGSRTU1MQgVjXFLzZ9yYn5uenp8MAwqA7PX+s34dXn3322Y85EB0/Hh3Ajz0CbiDrmO9MTU1NHXvi1UVBTumpLIqrr5qf93wQ5oqXXHDBBU++f390/Hi4/21bG0hA4c5pSOE0KqM6SvsFeKoD0gKLwvnZFR7z4ePHjz//WP366+vHhBdePtF/qOfBzc3NV33uWOP66xvHPvaizc1+v39l/5X9fr9/JYKdf+58EnN4f0+bm5n/w3IVoACO2sph2mqFdxRlxZO6QMzUp3IkHhc9xGS2wIa5LoN/AMAadu+UFzCe/dAsxoJm42wUr5mq2oJrRw3GOWuMroWWohl/xhi/j+LFzQqEPPe5hOC0rYvQ9+HO5EQIZ3fKBICUO+eEE5MdRJCy8wP4K9yHOihHezSpGl4hAMs5YsinVAtegaVAaPHEumeNP3JHLFNOaRWZ0c/1CZ+PKK3V8loUmUySmBlFtV69RmmUWqWlxY2NxaWSlW6/Y3JycvKbM3l/sjMcTr34TW9605tOtNrtIARNK5c1DcKg3W6trq50uxh3u6srq0cWFo75vm+IUiNoSaJ9bGEBIYQkhHZ+0Ge6c4BGaDdaR2eh89GlaBPdnH/pXTuJc/YJpVIpzXwV0V8Ru1VXm/m4SFwutwbuiBaK1Gf3/ZmvL3vWwGlNtbZfbKmaqtpwraVqCVDppqWlG2UKQOFaCtv/3r9//35lPB7fufylhx9++OGjy8vLd46PXnEF3LH9Yrh2+8W2qr5CW1Xt6ZPhWgoH+/2DQLdfTAHov2NufBTSNE1f0O12u/sn3fK9AT8Z2uYTJJBrOTcGmHWB6VNiw0fvp4mgNfK+Pww3B/1F+M/80KvOPa9aBS6cG65JamswWOi5Tkm1zylLIq47tomx327nsYB1SfHCwALs1mu74L6a7ytwbq5tieetAxaxMJUNBodGazOKIHAGfrXaFITZPPcNmYlWlsYYT3c6VaxmsYNmmM8pdnqKYtrper6T6ApE7Oro45jCO+D4gtAK1z2XQwcMXIWgMxgOTyf1i/+CIEqCCLjEmYQK727xR9RzSpZBlgmlVV9IwSMHsDqOIuEoBugvkDxXAEniGHSdm5Ko60FSDiSCMYnqikZFAWBK0yYnGWBdN/1yWSVQOjPs7GwPMMMQMGATYzDNqLIXC1k2dQSDsEuSYfdWwYxRKJWMwDBwpdp0JM2Erwc/4K6R7318HroGSSdbldxEQVxxbA6zoSDOEUsdU/FnhUEeWZ+SbtFGtptuLSAcei3A4SVcDBzHphQIV3ClMprPUsdO2isCFrHsepYNYBgywb6nBrrm+52FTqaLWABMfM8LS66kMgBRlGXybl2nGsYVRQHdaCqKLhCgvxUAREnFAoRBd3pc9qFRn56ZWo1joHuiCLDjGzoVQJIkHEV+p+yD0J0eNXWVCFgVOQVMqaHrmnB0dVURsO8HSZo5TJQUz0UI6bPkT8GDcBpJaHcWT2GuYCowPPuLfJwNMy87+6DZ1Or7fTXbmK8gv4n1LvMIHBDJ0yX1D8PgRN2mVRKaCqTpErkRbAwgSUHY69drgJNkMSgLcq1xXq8nCON4tjfbiyc4t23/Bt227bIrMaq2m00T01KlEvmNjueFMHH2vvJUt3NPpbrYyQD2PWm+sKzZ+YVe7sppMlqYmMCy7yqAR8P9+5YSTVW1ZHZcTKsUSFVVKCtJ9aHj2Imva7WBqZtx4qaI2XA8LgiV8zysdXIHeZTgkrTQo8yYplZYcTTk8WWLdAip/LqapJHM4lyKY5VONii6I7jd6Prcz6bBY2wlCNmQ055/uWX5tT5CpzOLQomum6cphGG367lCQNCITBNNOIl5LQXpWiZjjcH2ePAh3w8MCkYUJwosywXLMrVnO/XIAfi17/4s39zq9VHajoBGfdRPa8LudobDtmlONt1msw6D4bmten0U+lS2BoN2ln1EO44nROy63LQDx6BApQzrnU6SAnIjU45E7/1P+Bf4PHkNwDm8mGdFtTknYXFzeCAHMhJTI8Oe72LQ9gPFPeduJee00sTns0slJReoFtNJmawJXq+NvYmXIkqvHOwiTNDcN9Wm2VtsFROgM0av+Jh0Mk3ms2WCdggFN8tRGVVQBhtT7D2ddDx9u6mEvxMmutkUB4Fg6Odn5JI5QkuzLQQgUK0tJxysrQ1Cx9KaSr3L2qbUwqEcgUEHn0hF0KfoKeFy6XgMs71Zx93Aj7Rh2Z/uN8vQkQeBKxgCUKSeK4UjBr6lpWTc8ZuWZTlumriuadlN3+FMSm35GpFVvo+AUvmSeYwblJpa1A8Ujd8uyuNkdTWJuSElwpbfhdAmpQZnHpO+kgjo+xVD1DfaDlR7QVMpnkv4XlDDDII6APhBJwgtzwxD07ODoBP4AFAPAtP4SBUAkSvVCBCE53mCKQZcaj0XVIOgUgHsWackFaC4zDpqnkwxAa4XKIqMK0kpKC6VEABCKMkVUCoVZ0iVoBQ7na6QUhocTUeHoy4FgZgOa65jSifP7XJpuE7d9z0TJEBa1C/cMZGZUkre7XaAUUHKkXM+AI4W1ynQGFuq/IIDmJ3jOk6zoDFu7uPChVMkOCHkSOOpUsQpf8HpJJ1MZ5e1CyZpEk+mx17hNImmibc1Ey3FjeNgIQVWCg1XS1GN54e72AijX95neTIF4UAAC2GiObi5YiQ800gVjmjWELxtByBW1zXCMAwbsDucMsa1iV+2KjLTMhwhlW2FoWUrKRzDMinE9vFoas404yZgYuMSU2bwU1EzwVTIGABwX9tpq5Xa2odmnmehYoJpynPXSIFSO+2Mz6CiTPuGRxOYMDlalEpEJRhMzlJgNnXdZtN1qT3pFQ6UCYUoKbWQm4IhmNaQAkpTCc4o1VagpdNuO0oFlqaUcaEsgUDhchg2PnK8/BZPsWgiIlJGBTDknAvB0+JTkWFXFQRAgcw0TQpgBVxQAEg7E6JQpu2DaeWuKW1bmm5uWuDbphKhFrMAVPDAcic8WZtGEMUR44xLilILHLAVOLj1rsW1AWBobnVrLnr3mSkKLZFKzjiL4giQUgFIKeeInHILvPxYjsgEpYCCUmyXZb29J+H78CmyQQ718vBaaJTNmMsyhdA4Bsz3dpFLyK8jc/ctzwJ4fP3M9uK2AwcQDxy47bYDBxD2lweZdwH3+wdnJ8qeZzeCwMRhuI8JAt9+b800cb9/sJP0Z2d78FZ5IXpuzXjXrguOLmlGf/Vgv4/9mmHIWq36iGBqsk8Zg+3HBXGcHez3sTWzvn4NA2Yp3TkND9SPym5Fj0XPRC9D70AotYh8L+/ledHifttj+FDiOn7hiH74VzLoF5mnyOFfyWiYcT4Shn+ti/1SqcTzLL1eIpCErDfOR5kgmOAtbNFZOWhv88zSvqzIgufatWlLGywpbPkMgDOWmbI00Kzpmu16RFEUhXieVZ0uaf0lhS2vApyxTJWlvlaarlqeRxTl29/+9re/XfrUw4EHT1qfncV4dnZ92H/7ic90u1/7Nl/W/mNV+hPO3Ctfw5d6yuo7CNAO2toCtLUl33HHHXf8+s47f33VjTfe+K0bb/zWjQM821tf783iYZSt474CD8E7UB0to/Ny31DeFhaSeUIfUhTRbnSLQTwoX4mlHWFSJARUySD3c9svlUqx6ZGWYsJN9vhFp06d4idrrgOO01VTnxz7Nch+urq6OlVJbFtVjeZ029CJYJUmdvev3vqajN8PPb4b4HYbHLv2uch1wYYgTD6XBgHM3Xzw8jx3Xb0BA14uO8A1tdvdfBX4z952UvZoBgG/Z1jeLoSQvLODdeXx6OgO9FT0KvRW9F70EPos+gso7CqRLZxOOqIGuqLMQPEHHe34NOvzsSOnDjbFWm7aNPA1NPAovoRC99RdYdyJO+3anps0rkfGGupHXH9YsAJeR5L/OEtHHn7ooPXNHQ3GFwvWZ9MaFu2yod+Ne1+bXV5Ap8aXTD4uxqMvUCKJlJQs6EmS5SRJBCCKqilJpimJpilJ3UPzHKnqvUHDc3rRoO/HkaFAqTDs+UIIBIqMcl3PshWt/XrqA2oAJjgAhW1DmJ7lcb78Ja1cVysApV1X6YmqI9bqq/0mi6UYtzurGAaIQYglBiFiGGAJYQgQhjAZmXhtbW11dnZ9HUQnCDLtv88fp/S18FU/CKhRq21s93zGS8NuxBGPLQseVEJKoUJKw8vtokijONY9W2uAIYTv9RiGHQIkwHVTBkGtliS1xmjUbqOrJAJFyQ2r51Qk9RCFSvFrIqMUNnYV2E6SRh92TZ/3V8d1TNM0nad3Wqtra+02QGiaCZq2NdkLEcNeSDHqjb1FGvamT/7IZqsNdDo7Xa/PDm6trXV9zha+T3JbebF+/1q3CziYr65m6vUQRlGr2SH4VvSsplco5LQ4KIfZjtC2r/CbQEkIpQsUSLpE49NVki9Op/74/ZyWMZa6KU732y3f9/1Wuz/O+nG7H9u2fvI2ooidegFCr1v95TDLhplhydV7i++12/1+u+35vX4ISdLvJwk4Tn3dMBf9PjyUZVk2zLKhjjztJ+y18j9UpWDQxVKLn8wkzsim0ABJNcaIlPEzeebS3GkP4Ipl9OMo3ex0NttJ0t7sdDZbzWZrs9PZTIPADRPiWEgfS5qEbhAsvy6N4r5hwWPY2FLGbC6UV15quSsBHQf1ExodBzkXii9/wwECX93mSnCOjoOC24wRAsTcuwJfhdhmDpIx7JNlEieFM8OCigNDYg8MJXmRx4mB+Ww8X+cofWnL9GFZwbMPHDgAnQIB7nWfuXJ1/Mo7H22u9eJO7B9TiNdZiAD9rSbW5X7go9FoFNVXDAOOPni4kb+93Che33cfaNnXnVrYDlYaoNa+dhAM/as2CCEEidx7Er4Jl8mI7BIyyqaZkE5yNs19XcGxAUvVVlHoKURpuTMyIsurvBIh7ddvdDodkMpvR/04wgP7r79u/wGKo9HOvoNukoxWwogLeMyJ42w7sbTZ8DzTDZ5N6bMfpv4hwzAAB42iKO+YzwHmi9uPl+Mochs+CoPKSWLsT1wHMK4xCMKUwwc/BPChIzmHp5QQPISV5ga7ZEQeIq8nJNSQoy9YY3h80WJWhUk5ncfzqNS9i8oSvIqd5GEGMWuhIYJmLU4+N2kHUIjBjADboqguGzbCeT4SZ0L2v4TMiry412OU22nXc8G2m22XU2Yfh6Nvg4uUcwauuw5g23mmVJoorhVikwsnBC44MwzXkdTgXBtU1OparyBlQujPpzanzDsKx21Gudtu2ja4XhfucSWjtDHI88m0KPpDxpiyjzz1zsPLXwIAgA+D59Rr3W7m+9mwmuV5klC0rVZzW+lgFPjDnmUCOr5v24i1dG11hwotJX6mQSmT7uE7n3rEVoyxYb8oppM8HxCC8+5X60JhgYZAM1hs7bnK3wSRDhJPQNDWu4dRDAZvFuRcCCZMz2XMtyzXpWhQCoYXRjDwv6NkD7iWNE1NaQz+s4aTIOScUyjiZvlkNOgPBmkDLEpNrbQplaIUlRsGZG+04aTh7n28IeW2GwtJKeNc/lPAMfTGZCU9aWQ6zSnoxYdx/NWvfvXmr77V9vKbH4wfa9arbnZburAy1f/bg1QgCiVZpGmxkZfSpEJmJxDiArU/lxzTVKJ+M6oFxK6mnMnvfS6Bd64tFkVeDsp2eyjVdSSUIwnkaMbjDNTdLK9N1vB44lnx3iBEbC/SSZhpVygHhRk2VgJn4tLFt/QEKtiU0lDKFMJQ2ugwxgVjgjf4w/dPZ1whPM9xHQQthTTDyBtLKbjUhvnmo+G/yz3mKGrYVqSlBLQoANQ5Ok5tGHiG6VumxTnjHAUoqbVSwLhhSMaYzZUfBpjW6wjImObcr5ueIUNDAIBlaA1SAKJpWpIzcC3LdRrNWt1oeK60kjSK2N8qZUhpaGUIYUacc84554Jzxjjn3DHDMAwoOgDKNL1ACHNDKqkkZ84jJ3d2+pf//bTuMMoDrbgA5RlCOu1aEFBsdZJYgVJ+5HmaCgBgJiKYprbAbDRqTJhpjepaLeGUcsvQwg6gaj6V4Hk0DbTrxTbnlPnNZguUlF4YGaJey4YtLwjsJIqk8OoC9hKm+AHEG0Eo2ngxXwTEoCioOy8nU61W7Hzg/mAdKc7KQTattHk+aVqKWMgoxlyY5MWkYE2CWdZnq0U1hUtQNax+6y23PFvJumkAoKGbUiFd2d09cWKBraZKiiBNo/ZGm94KoRACaMPsYQ4NBCZFBFE42bx91fM8zpP7ZbPZbtsUWB2BCeHnBw8ePrQacMEA64YabRF1QNfujeykKRgfBdS6rYy6W7NM31tRMjUtAHhz4QfrhoVJIPsk/Cr8HFEI2k8+T15KHiNfIY9rW7SnZeyLmIoWdLpllC56UZqkKcE1EmNASNggJOp2PI/ZGXKLvmRbLr8Yl9I0jRWEm2WUSrAd5KBiQgqLR0Hm+WdLguN87Oe8MWYsx2W/HJd53MH3PvrlOB6XJe9QgNr9TEX/juFwODymtd7uOrHd3UIAdqJRV5rnZXMy40Ja65lCs5MxbP+AcSEl5wBdxwqppOAMe5sAiQTeZIBSumNppZQFy5dDnbEGvGb58oCCEApeE6IQevnyl7/pTWePHj36posXL1x4k9JCZmff9KY3URRMiWgcSEEZ4PNuv/12pM5cU4rPe9Ob3rTBkCJllCFnIkfUQlABSLmOqZFppEj10EBKwQWt7eUlWyN0q8wa8JoGB02D5cuVEMBCuKSlgGvEN2LvPQH/AF8gzySvJmRUjBYfM4NsVg7K/n5UyhrC0+GIqNEEj8kknUxjwrSmi87Rwe/JbD6uUsW08+CxRc+QOALiFP7ed0wNRqyNuNHseL6UlIHnAVAMvDiMAkN5TuTYGfzsFeOWdk03TBudKBKSUugBIq2ljdR1pEAQIrBduXtm+jnQWkdSnj1rTn/AuWEGQa9hmrHrKb5Ld4lcmIYjpeNGtTj1g8CPo2YjDjzbtz2jv6Ci1q42uQQQIkxqTc/jAimAnH7faBj+Xb/ay1Emraeyrt+gM4lQaMdQTTQq8stJX5EXeTqmJoNzzkiTQP09UeRpUksBWl1NMrfFdPaNaEpx3BgJ9y6XgMvlCpVu3RXA1fzG/jFanSRFkYeupzwzsChacZrYlhCxAYDS10ZkIpojw4wTTgUiGJ6FdMmLgFLoayOy6C8voChybnu+hsvQbK6sdC9Wmk1YfmdkmFHTNMOmpySgtISIkyS1BQCz/enPL1kpRk9obiIFU/60yPlvN1ysjEaGGWtfG5H+wqE2GbdkndgwROaHx5EicLnZRGBg6HFcOXzkyOFT21sCXbdz6+Ejh49M+FS4ga9vHDqUF8g31g8dKnKEy0orZZbl6bW8aN+qlP6R/9GhPEe+tn5ouL2+dsjvC3HUaQuPzru5ndxHnnG12bKox2wca0E4ckevKXBsRt0q+pXYVCwDv/XMXCPaf9oQcmDc9uh0Gnt4Oul0ADqdyfTw12eH5bduvfXW0a2jZ29vb7uT0pkm4oTwrJMnT3ZOtG+oqiqt0iuvya9T/MWXn/3Vo9Ho1tGtn7zrrrvuv/8ZhtNx5As6nc6J9sn1NE2rtCJb8w57/7b3S+jDt/Rw3Ya+zsVuII+S/0f+hZAqQQUapKXRoPVIVicPLYrRVDM75E8Iq+WC9DqaMmkDXEhIUUSZUHOR4N6irAbPCUsyzzBnymxbyOg0SmoLe5TlokGRxlKSp+kAxCWgSTXzbl00p4u0PIyx/WIyT75Dn+Jr83rWmr7dENo0hLJuMYCaBlDzpb5teL5teOD52go8bQa/aknDMaVhwwtsZJYFzCrQ0EANjTfYynRtZboilLLX6Fi9fhsAuv1B4kDfDwBrkeevxuV4c76ygl0paqe4p7vwSqVWQgA1DNNn+abOLg3PBKCccyqltB1HasuUCMK0ItdAKeNqv7ZlhkLOhYngugYapmWhEBI4F0oIpFI6VlrjnmmHnuGEA4OCNijoM8oypLIMCb9FTQOYYeL/MLzANtzQ/rQVeMoKPb3fsC1p2pb6ILMtYLYFOxrQ0ED1VaZrK9N19JsHw2EaQmYYKQBEQnSSuqzVO53aKMvU1Pe7bqdbWZ1OerUNFLUVBGHoeqYvBAMuABRFC4BSisAo5UJa/miUKhrbDkDA/CCOXJdKFJrbttOQPqLPo6SWcoU2M03HtR3hObbiAMGdTuCbduibhBKy9+R14ugN5CHymharzu0uUPlB7rmoh5qcS8NK7NaIRVRnxKUYSrKZx/wNglsi3LZTab19IeX/99QxTHBdYJbFBOfcSWu+HdkmouMkrpu4punWfDsyDcMVSgnXMMzEdZOvwVrSHnlNIriauOtoDSsgGQoXwL1iO4xv1QHeDwgoAZQACnAPBymB9di0FAXSy///jkFKeLGaxuil9WC95YRQUtv7JnwSrpCj8XqAJBKmhzrvPgJDM9KvC6UmSsbEdtUYUeNyEcuyQvIrLmUGnK9LHAb4cjDihmtcFaXI4BO2bVPXdRxj1YPVlTbFZmOzaBWD7WvWp57rcuac8EMc9Ad9alE09z/kaAOOJrLcMBn+0PvyarPBRbLSA1xd3bd/VtS7Vz70oQ9FgisVvRS7+ZH1ol/krRY0VnrqltqWJaTrOYdsA6IwClF5rnNMaMN5PzhOkjjOGqosP4S1+nA4KFaq46urQhYrvl1MZm+59//xNVwDtu8jH/ZWdmZRUv3kpkoeUPZwYyN5O4tyfqFqUaXJtNT+YAlphmxWo1waZ3mfdidNUpMjUT2R1OGDaVYSURYQcMh9E6yiTjg2VdLg/f76JC+QM27SZrPVpCAvYr0ee3DZkFKyZqvVyly+Ptrprqx0O1RI5ctGvdGQ4EiheX+wsT0asvdR19TYarVaWebeNPepekMKxQdZNuSAigLb2Dx4YHOLU2batkE7nU6bSf0dADhG0eD93nqZ51QCA6W1BmEplDjANI0ceLEFDCzTMoFJKehwNB6PhlQjAlC0+fr6vgPb2xyBItiWZQPnXF+FjAJFy7ZtBGQUwDBs2zQAABE4hkEYoOCTqSHslD+e6+Qm8gLyYfIF8t+0Ipo8vxAujjNJI2pIPoo9uhYujBzjZsc1kL1iqMuDHAiGomIKA4AWhkzNVc6VPWuurH5eKkFg+ZWFjMosV3HZTZNYSO4IzxW2oWm1qBYyFYIaM/jT5QH47vKAL4QQPnw3EEKIYPlEUm+Y3ARX2ZSZpj58xOAzpSblyjfHBAAut7a2FZpG3B7hIogd6GpQt5cvQG3qHwkyir/+X4EyxhhoLlxDMMC1jXVX13ngt1orwFgISKkLM6/dcdOaU6sHLojl7wMo0wII6w3TNBDCoAuXhfCXL/WFECKA1wRC/JIrZd3mSKXt2DbvNsxGY9WyLafbE4wjlQiAXDRNc5yGoWFTpFR61h9rQAAABEMiACAouGn5R5At/8ikwEzFAdIoOjEtbc+jLD4dMgbgwo8yaE+mDYC01u05meBewgRHBAVY9z1CcO9f955EAm8kAVknpBKyLD0/QQbnRpNNgScNu0vNissrq2tpbJrF8N97uHv/1VftH1n19bVFPl8cvubQ4eEQ4H9X9bobjLerxY/pt7erfXetrnRrkzIbuJuNBoyGhw9fa1v2OvordebNt/dJEUw26eeRoxCyv/OmpV9ObeSyQBLYY+pgxmGdJof8q29eZEBO79uXDXDQ37//zLF9nNWUUWzetn8/sP0Hbn3ihVJ0FsN6nWKztV40mgx4V1IKPB/tHNlYZ6srhyb5+7kQoP8ZrkB/sG/fqTP792cZdpmIJfOBHjxw+y379+Py7Q9yUQCt14cb7Q5AvZZL3mTKD3dGI44rK0cOra2x1hs4RQl/q4EQQpC4e0/CF+EyOUVuJSQcnJ0uzdQjrPoAFuOyMN6eRmZ1EIrIKZhOpovCl7Fo2NwYqUDSZ368PS5XdHryc9FmY211Y9XQuDmZrK74KWegdLO5GK2v9QRPUgOYG8dMAGxv3T/pbeemaR1+PYf9/gAu206Lu4DSMJUjA9eBKBzkQmulpZNlCaVmrR4nAJbl1wUFoAJWD41GsPxoguB7BqLlOsrUBiPm3h4p8RJcR4Zkk7yGvIdcJh8nnwMX6jCDA4SMZCVlKcsqs3snh/kbG0LZqqxkJauZyjNnaMuyktWKviC9krqKAretqtfj766y/eCYk4+2+PKFbG6Esv6ercqqWkipbZpLK1kJmVZrR6ww82blDcrQNlmiHI6i6RsaLZbg844WZSLTlctHOSRF8YZ0dAHsFbmU8mLIN20rdH+U1xg7nP9MEC9RSjPMaIYDumtt92pdu3fx+61Wy27Zy38Jw5C1qHadsOF5gIHfrZsmBVq4lkXpUTrEIY5whFXa0wm9mtaM/WxFvWKj2Wxq39UaQUovMJt0B1vUVApjIYSKktcrpdz0U4yxFdXbV+sazVy0mXCcdtOyEGiROKxnp9113uYeDhqjkLUoALft5orL6rnYB7ErJADjAX2WsqXQYkCPQFdwIS3DRND/vVarKe9/tVotGmALI2yw5z4fX4g3nBevQ8QX44u94XCYQ9sxDATXa6VRRA2tALoInLtN1sIAWxjR+AX4nFuwxVt4J3XRU6cQMUAwDMvWBqAPHeXzFqXG6YMHD4aqv5nn+Qpe7fs+DfCl+NQH8cgxXAXLcylYloAepbaF61t4/QZurmdugaMCewiGaVK6toJHjtFzQJlSlEI70wCUG7TGLBRIQRmuoxUA5AUhhBO193iffa9HNsgZlHYWvImByE1JWhBkGgG9GKjYLPj0WkyrOJvGz1+h3Ny4Y9+iSwbT3/KFHxCttem76tYjnpTyGyFiODsWKdc39fVhGJq+p9ya98n5fB4ihu1Iur7ZiHzLYtwIh0idfp38u3jo0J0XDh/C4c8rcNrzPFeZ/nvAth0MQnz+0DeV6/3+YDBwleE3ZHgYwwAHgaHcrUEnTqJQ9Y4wDvYquLpNP/n3gXjo0J3E10BaJxk5qa2/sQZUCNtVnJoNbneWLsF+0Wl6PUM3OllI2mAeIpWW/9/0XOnW3PDNX/va1wLEYHp0E6va9N9/3HLYE1Lc1263I+l6ZuLHjsWZwVjYmwWIASQpMvcPO9L06iocLDAI4XmZbyjXdV1l+O8Cy3YGnimdvDOqJWGghOpXEAZICNF7S3IrXgLAmxrfQJ5SPq/9Ovk2+TNCwhggX+Aky+MMNgNNiiWlwvJCVHmaJsVC5qkA7eBkdnN2UtFER19TFKblxG0KiY5hgIXP+xrlr1pserzdnPUKTcTLJ0TxuBRVUrgypLx1zWy+kHma0S7eFjlHTOOsnM2TlZckm2qfr3lSUQi8XKh8S1EoEERnHWHdDwDjEGh6XZ7nAEJJLzEkFxafEaSutTkUNzJmW4wDMG5bjO3P8xykVF5sKKRL7o4zxi2bsblt9bu2dQ0mIeQg9LAwLZhSb1UUBYKKfSkzMA2KUPxPSnXqgRMIGyDS7jVhgliMYAz7v7KLd8c2Y1qYZpRYljQBklOfPBQ5a//9KfxYSCGCQ4tdfTY0TMvqmRRTABddwwGwjVWTgo/gsa0oBq0aVFJI0EDjxIvisuT/CXfhnWSXXJdnwOKs6HyVVsZRIYuSytRoLcTA/nFSSagAbgEZIFpUypkqnNV+ERcSxf71jXNPedYzL1x/586+ndnzW60zXvieX5kIsd7bbvfvP7R2YvBAMsjSN/Rbzc2nnm3Fv1Sv1/vZ4KnXN1pvPlRNhkPbSdPpmu8yqqKjx27w3D9b/mm6uro1qIVW79D6yqI9HQAbzZVx+tlBcuPq6upcwOWXm4owQvb+DS/B64hFemSTnCJkFM9jXo7KecnLkaxklRd5NpBCTstFtUiTVC6mSVpdniVeG10rwkUCJApfXBYVXlpeWV6BXdj99vb2dntzc1FtbLaBstM3ntv3R43evL/l1evtQ4OXHL/2ujNnplCuHj12/fVHj6554U8Wi8Xjjy8ef/xMu91er9fr9TVKdwzzdBjiVju1bdx+1Uzrbu8kdA6PhgDD4ZHAJYQQ3PuPvSeRwWVSJ1cRAv1+X0haNqX807A6yYBwTlROWHGJFtWYVlpDqNo05dil7OOS8N3l47CzfLyT1sQ+7nsd2Bndw/29Xu/5aZgEqzNvvxPGJ0P9NN6ljueYqGvsbgGXIYw6y+913Gg/3R2YdaIQlr/gOM6zXWvXPjT2ul7Qub/Nn8s6qP3ARhHIFyki9pZ7e/gaeBXZR64j7yV/Awhdn10aU21lMw4KVETB01zUix5JlZKJbcVY6WM5TWTsWB+ZhtB0N0mTKiUIJZ7nleO9NdMkTsvKCRiddRandOJxnMs8Eybw87EQH3CTOkXGtewAf7exkG8gBxJePdAH2pjVYqO4TI5QkFKEaXq0YvHSLgaligvT8EJtk5+GGhXHybIclPmJGItqoSux26+ApMxGClzoWu7GCSRxyxihZSUgCm1sMlMYpt16iLfULBMpuDXbcQCUdj5t4kTnsYJnDfuUSh85w/6Iogr5cqhomg2wAkWx30eqAvC57wcyq7vXkoiG23BsChpQCik9aYggwCDom2GgkFNhtaTrAVoWkyI0TW0hUr9WY7C6OHny+G3nbjzGKRU/86lXPN9gXLV1sxGCqfvDoRZat0wEqRT/p0RzylAjMBa00bIGbc8DkF5kW0htCmBoxoUADNPOyR4YhrZMRI5SRrbWkBq/wBgD0G99K2UUENTb346MAaAAVGo4PG8A5/DGNwLnIBAVU6YAAOCUM4ogTENxihyZZbYT3wNGNWWGBJQAjAWOEJC8+J8NjMDzRIMzeHoRRdDtHmSM0fMAYyaF7CsACjoCUEaWNYUBQaNu2MHokXb0Br/Y9QGI+OZCKsqanUW1SFkCgSE0SeE+FOTOSDYTbwkuL1OS3N0uhtFxv+f5HHZ3gUdxzT8ehbgLUta3yHJLt+pSAgeqgy+wV8u9PEnAMIPsR1enSkOajLJWkiS+0qBkEsZSgdKerxaju/q78hzyKvKuPjVb4JSlvmNh+EDJftNVWSbTMVEB4QDLLF3ZACSVDIv9D3IrlcwDoqzicHBRVpNvK04PcjSq+jbqeg2zaZqm2TS1HknQClxMsvkLKwjABK3BzoRg1Gxahmk2raxes5RUQUscVo1GQKlLWZSmTMskcSk6SP0wpFfq1bNmddfRm2Kd4obcRNRtRGFMAc5IQIRuSiszb8oNpJtiU0nZqXue5tmtCaKAg8AMM70tMjN7EgugWseE7/1k73dhCY+ThKyTw+Qa8lwmE3FNA2t8VFP3VUhDBJsbYSHwpU9IdtBJaXpeMY/n2uqdMIodDgHdYTSrmFxySUeaziXF1+y68tChw4cmWhv2sZtuOmprrZ/icubdvLoaoWNzz/c21o++8+LWVsQdG/2VlRs8ztzD3GhVtvE0s+3dI7bDgDoO4jDb3MyG6DPuGf/ohud63rZlGMbh/YZhWMuLaNuiddXZW1xG3d1Dh7a2IuzfeOM9LqX++VOn29K26fVnzpxxAO0zNqINNtKj3W6nc1AID9zTsygCiKLZaRc8wsRzaiPA8/3oxmOyy/zTysOEhGenqxp29EAEqJnNYgFLVqZBg3Sr6ddGnwOTtqGv8Ur8GHje6un4RNey4BUnTpwIThWeB2BZ3f9x4sSJ+NSq51lm9ysnTpwITxeea1rdX15SW89bXnVdmP0PVXhqzXEtswtXB64Lt4Nt2yu3g+sGtm3Dq28Hx4ls24aRxmLypjf9Kk/aRNpn+RqZkmeSnyOEA4FDi+nEf5lk09WsUnG2jZVRXJUdOeC1AnGeZN4lpn6Gxzr+7qtJEuE4rxHdE1mIOnkFxtHITl/TT9GNRRylII2sw0XpZf7zxTyf/zwVIgkFRyWR86jBFSI/XBgGCFRgWd2xdkzURvFDuYGGHg5vuHY4NA20DENm5F0K5gqfTI4enUx4zxy/doCbUVBLU4Ya6kGKWkVd29FrFgBQFQSx6HQ6HdWOPYEA/2FT5w2VX3JlrcTdAECFUgwATIcCwKs2bAA8qVTKsN7HLDfeMBxqAwsTQHYAqWEMh+duWV1h31R0OPSY020EwvRyf5Na9nDL9VTquat7fxIvFUkcxQyzXGdGrvUcIJbHIloINuQ5MpLpwoQTlJe9+WI+K2A1FHY1EF/iC5rthXb14cV0XDqCrP6rTPPI4Zw7CCvtEbOd3iSJveOhO+D9wK12e2CMx2VpbWd1gwIsf4UZOuspTR0btequK5tSdcV13WsnUYgWBU0978iu61INaP6J7aUxgzKdrHb6LmdF2TrLo+jA2Ubdyut1CYBiWB8Z2aDfF7tiqcR1FMq2vPF43tDgN8LbhgXyHUBo05LE7xM+hQ6E3q4/UsjAtUlCFEoFPOdvbDX1z3H+zPePXLr04ocffvjhleGvq+WZmSTp9+29+OGHX/zTm2xlHnwwZHHvu/Cv8F3kfOFujcEcOuzcLfTghosZ4pSpVS1mB2q+l4CzNIqaTc/D4afylquqnVZL6dFo5/wNN8wXHLLs4MEzXzHX1w8eWl3XqjE/dfraLzc9jz7t05hFYetv+Epx+PCZo5NJcxRGhw9fuOrAgX6ffuXg9rjXd9YvXHiR2W4fKQPTEdkiV3MWgHg8dOXNHDYJiUj0/V3hCZf6MgEE0g3EJDhVcJ4sHNZaZ2X0ke+vms1i1GjYhlLatJSB1zDG+U2GoZRhaG1o/RjePQ3/np9dIFdK9RBHeWUY680mQC0CrU1LK2XatwnG2MNKmYZShvnXL8nxM5aXXtaeoLx0O0Gf9HadCzTGf7Vz952WE94ggYeJaYXdJi/OFMmf7/z5n+/7sz0y6vbCIAh73dHYFH+4b9++P/vznT//85/3/V5vOOz1IB2af8ni9kRC8DnwajInzyOvIe8kH2PBCb6hw8r4Qnqk2A0KagDYi8MAa3TG103SacoXLI9QsguCRzlaRV9MDtFjFtWiSMsmH6mwOCMv/NltUUwid1OD3u5UBggZCAb3Wv9dslg5uDJfFLNsYBppbcfvD0aj1nqaGuC2PcAgCmBbUTDLP5NB0FgMR7Yd1DhjSF3fZ+B6zcbqWt1sNkdpszkatpqM9xqmBUagVBx3Gu22+snKyooL4K64AO4LNYBuaQDd+llQiQJQiYKHwWgYAEbDgMdm3S7t59BqrY83NsKNOGZM283mOo3RjwPwpLVighrEsel6XrfXDVrtAEEHQa9TrzuW0sNhENDUtjhPk35/YKdpEA3ydhwJYVsrD4K74gK4Ky6sgG5pAN3SUE+SRAGoRAGoi/V63QAw6iaAScTef5BL+EqwSU6OkUfIa8gnyA8IqfKidDlLzpxai6oWNyqmp4tCTjPwwuC2Aj4ItXLUCJZ/UF9LRTotEwqsbBTCrzmfQTRymW9xAifqLoq8cB3JHiiknoQcLvk6jcm7KEyja9cir0yFNyiLyLRgVV+2/i/mOOHIpFndpI3I5ii4Nk0qei3H4R8MgsBkYmXkCNdtWEqaYfgv1113HUVvP0PNM8Zik9FxpKSQ8b5AOFQrF64Jw1Dh0LMt1gT1t+MmqFBSPzI4RwNVqFAL123cJ0Ch6DMAmpiUzn3BqFbudtswmFLecYPxPw9NE4xXgXEPOFpKMFKI4rRlpquNMISGop5HM8dDpNAFBkAZGDa4nusi+DPXMGGgXqsN9ykSsvskqF2QUq9IUP1GGMJVwDuCIwXDDizHNKG14pgmgBETUvbQhuA+DFLl1AnDO1f+OySjTpB4ISKzB2RlUU5z63yJ9nHOn/8c+76niJLOF+xj7GH5MvH3v1/GDdvb25Ofbrevyh3vEGxt022bxmMfh8/D18laizjMdEvJhpLhdsJcAojhOwO3OY1Gp3v6+XXaG51Gw4mOD7a3q2bry1Btbw+OR2+ruS502hsb7Q64bv36Io+TZu1VSeK8uI4Ikuz9Eq7Bt8lB8mHy13Av1rBNSJhXUbqo0m2Tihrrge08mzUOxV375CgW6SQel4N4XOaFSPOUXagBhMK0f1Jl5Tgbd28KlUuXnMzH5bgQclxOYhSB3cl0MlVYT8bxOEuVl7z1QTDA5aCFck42LqoAUTFWcjKQghEvI51VQs7YAJBIGVJbRbQP0dwVVaSVospl7UHcL6AQjwaF7kozLx4l+UfA2weZR4UX5jC+1skojtLJdJKjdwEj5B2qRSWKRTqWSxwd5cUifT/IuBn5TMA/ejIrF1UqkoVHYWyEy7go6oesFpkSLSdSSF8kcTbIVtSRQpKxyE+cnYpYTJOKBZdOsaiiu0AoycoFIDRDQOkn6VaUfe3H5avu12pRpEmVF+epy/SAAYDRS8N9tnCUjQCohQcc0UI0TM81fcERoGfaMgX4vp+GseswphgqpAAUIA4Y9xgYZtQLKz6AGzd7nCFSbNU2uuCYXELQro8kpxQos5wkBfibGs3ieHav5YY931fSNBVAMzSHLaTARqFpS86UCNzhgO6jamFrtLraaoWAn/EtW2hAy49JZEmppGj6zqlBSdtUho4ibXJGUSEAtRhHDJlwKGVU+juZv1aebyJAHwDAQlSg0lqnHiACtBOAXt3lTNjd5UuVE4cGV55puAajgADKpZzlcF0KjNqOQymCrTOMixwXM92eMMMMKXUNhWCYnCrlAKIjFGMMUIa+z20zuTmlbDMAJeYeAVDHtU1uaJBMKOk5lk4ZckSd1ESaBlpRmlFCcl1Tz7IAXd80tHilCKQPFxuJaazWtAawFePO/qwX+AgIWrggEKOaa1pghnXEKAHwho1W2nuZrzUgB5CMIQL3GdMGYwCIAK0tAAgsjwFzWusgDM4BVwetfX89A6KgnAF8IaIUUdB2aDY7/dRzFYCMY99riSBAToelll6tPmzVGEUwTUCKNcuTqtnIKWxz5NKybG1RAGTUcT2TIgDYhgaplOdLAE0ZgoWAYWBRpNao19DTUtm2YZkOZyMXXNeTABT7rsOZhwgofQAa234QtI3P2Ap4EPuGFErzs1MC6GmkQagkWTAVhWU5jk0poGkBYug6NhceoIfdUuZZtk+pHTgeADWZ4fmBBKE0RSUkzUAZSqXgjLmWjKDapJBJXrkJCFx5poko0zbrk6c2UEoDQDDrFDmXwkWgthJS6GYdfFm3nUjgEqmRdXKC3EqeS95MeAqhwJjhO9ysIaVzBinCJJYy4Ny/qYrlyRkKTbiGKCaf5rwnfspXzGazmRvH/io1zdiLY39Xa5fjr5fI1fqV0+l06sWxt0ZNM/GiODi6SAInbINWU3tpOIJLYu1Ar7gwVnXnx3GAKKNZGoaGBPQf/HlHGwYH2e8hAG3YP7/Qmv+utbNHVvZIxDZ0D4KguUdWgzFPSJ7F+SvwJHybtMkqNwBdklbSuFA8UrlpXvdwTh1lVQMHcOi08Dkq8E+Wi7zKDbSEqDChmrs9LcdhC/10gtUKFzHgG2JRvw9+s9vthkFTCEA0hL6eMVS1eq4c13m87fvm54MXrV/VFw3LZgxQaxDCvuA0GnEMgrNzwGP3lXMB76ZFs6X1a3d3d4VlBr61m+e59JKEIWWmMEe+z8MklvAJrZzuk5/85CcrriquJjUADMvzbDCNemP9+xZSlKJvGE0f4rjVinc6nU7NcQCiPoEEOXwXJ+rSDjnOnluUFcINwdRPa4zGVPNKLtWIoiWuHJqFTPz5OTkty1uvuuqqqw4fhncFq2s7t1x11dYW3APt9vZ21UlSM3DdopidP3yk0az/7d13D646dOjQoUOf2lldC+rNxpHD52dF4bqBmSadxfZ2pw33wNbWVVfd8pd333333YRQEu09ic+Hy+QMuUCeTQjkpeqz5kF220KOJeOAttRbVOP5zIPpgem66aSaxEk6ln1eVEbTJI2mi2o2X8AoMZhJRuKvwRb+7GjD/sMASh4/LhXA4f2wE4UKjt8A4NtQSwBO1fRnr77mDHAOSQoAto/Xn/CeuvyfieuGWci6bvqdxHWh/Mep66Tcs1t4KTRMcD3T9FwwG3DzTefPAZR1SBsA2vYd5vt9Zm5wwZq6kUK9BPjldyz/EXy/Xvc9AN+r15ETD04LcF6kV+AyGdS5i1qiNn5sjsu9LOKNiA6cPG2ab4J1f3p4Ou124E8BcRCoxrHYrt+YuEDS8vTD0QIuQ7s9mRyig8HGRr9PodOZTg8h5zh2edmKrm4OSGI+tBgNcWjEV+AxzLI2wyt70rxMZTyPE86Ebep8H+M1zudlBm9729ve9ra74Hl33x24fvDLv/y/74HeW97Se9WrXnU/3Ig30SX59iuIr6J3/Y+9J/GSfDB7E7lInkqek6+DEeAJ84nM5QIe/sNi6m1T4vm1EnMIaMJblP0gZSYTDz+r2pdDnr319IU7cNexh+OuO3bs2LEPjv1DBLEVRxEfOoaD6DrZ8lphmq2dZ7/opptWg2YzpBzsJTy5MFD7bx848L1Dh95x4MCZgwcPHrxfIdKsZThJu13TWGxsZMfms6egkj1uAOjWgZ+Xzhw8KCvLPwm/QA6T4+QaybMv0pT3CvVx06YAfMgAfke4KBo4H8XDyf0yrtIilRQBnFEDQL0b3m+Kz3q64cnHHnvsQq3Xq9WVTGkYDYezjXrdDKjntmueb9sJaqW6tZSzKKpztrO27iPADYPt7e3tv6XaavI03lhfawihbWsQhiaoOkKlRjNNjcm5c+eOtlZWV8erqylzLjJ7G4bhwGlEEYDn1WLPY0Ipallm2ul0G5wf2doMEHaf1Ww2m6DW8j2L0R+m43LSb7fSlqKWZTluvdHvZ1mjaZI812KHtDFiH38VuZ08n7zNn4bhNFbCn9nFpEiGZY34opOcvW2BbJjL2XRh9szi+eYpGzRVGu58KOBR7F+CZh9rR5EUw2wSuC5tMNcJhr6PjV6vfzNI6ay2WmZ3OOqX89UViQO/28m5ODM2Wa3Wt4WAQdZscWxjEI6EeOHyCuyaL93d5XUmiK8mHLDr9R5QtLpJwgyeJF3Hc1milFz+p9Fq5W6tltYYc97lZHH6/cci79QbpmW+sX8AGWN5oylfxCjFcsg833es3zdpOiWvxIEPI71cFgZ9AbyWu8g7mRSFSOD6A5qR3Wfcsr0Nmxt3fvrTNy6qZgsOnXzep+Hyi170oopujw8fHJd0F3r9yXTfhSMngai9/9h7HP4cvkE8O8xj/xf5GyDQjweI2F3ZXIpiMJdqTAgSGMRcMxwZ3pY1uTg+4nEpKGq1k2LZ6KWcl0Zy4ay1WQwiUVPfuSuyQWGyhfiJq/NZlUwPn0JLPZ7nBY0BtDt3U/NNWYefxCactE8HfQIF49pzEjnSOZTJ0qCXCEi04zTpDImgD+QohaWJwaAt0m73oWlZaBg0dA0h/lvsm0KAbTnUNNlvOUiUlv0wW1p1ogOHVRiEyYPAmD8egw0UpBTKMBBBS2SMG5at7RNjBmhq5GDZCGjZIA0DNxwKnoeu3747isJIC8dtSwVgA9Z6pmalIBrNXmtuUopoGJxJCQjqUNZKEo7oPVZrGJDqBCVrtiOWf5emvYHFkUqlRBCEgRKMwwyQai40Repw4gMqmW/glu1BN02AUSmDMAgEJousgMcMBIbfchoKhqCCApgGIhecPwThTILvs33EZ8x4MALQpm0hUFQGUkDTNJGLpHtSGyyHspmZ9bnjGIzy7rFfHQcBIL3bZCzwHSfgQhtxrA2o2YiQcjG0XcsC4NwRFEErpddAyAgQ7Rpo7bp+KJjr2O5HelxQdK0kiSJBmlkdUieJu5/zgAEwXykQSCW7SVOkgvfcJNEy8aFjeBQliYWRbPw/4SV4EzFJjbTJFE977JfTypfoUBMGMuh56pWJjOLLLlEmPvOFnJb+rbfeeuv91yDs/r+sXmefgiQZ/mWJyzdDv3/VNB817mn0boQ3LZ9x42seuUZDko5GaQJ69z7l3byoELvdtfFWBu8iBIizdwUm8G0yJKSK5/G0zPEDMYGgGgt02p0sT+G51nPDI7cGT/f9om5Zcez9LB479q7vf//7379vkPs+3k4p4s+t3+tP6MCv6zBvLql/8SQYTUVUckpAgVxMLoW3R+qjMyI0TSxLJMAzT57COBox3vLpqLThGpEU/LqzZ7a3EU+efMa7zp49qz3P3q/19UoKNuFpga/jseMPLTa3+lTKUNuG4ExwjYhRmhw4cNtDx4/hNx555BGbUr0hxEEuhP6xekAIofchOUI8tkY2yX5yNdbsgnJU4M1OZVgHzn7dtJHVt1ArWvJ9f246LedlH1lQ1UtXPnbpjsalj1251Gjccccdjd3lpUuXLi19cU7RuHSpkV+6dOlS49L7r9yx24CPtUbjS5cu2QmP+yO4BG8lB8ht5EVMlZ2WjHf3eqUQWC2R8lgrZfS72+W/WunMpXzexYsX3WtRHvhy2wCQnRyePqo34CQXVsC4KOn6cd761re2TNB9/WwUSceyLGNt3bA6PI/tOOedJ6c/S5GLQUbNDzKYtp9CwXE3VSikYQQ9RFz+54AZ71RUrzzBkAIbwIXNzU0jSYzNkZHnTp8QRtTe474L+32SIcG3s+RIbzBuyvCkTr3HSYYmIIJcvFxJ0rIF7+aLcmx3j+oKeadAayITlVEZpWOgWjeOymRIU4cyXDo7icdxFCeA9eNxHBHlgjFNoR834+SxfxJHZVomr/MXmcblJE5+3Dj1ZcJvoR+XpNWk6TiN0vWMS6MyKcdxUiYx6zeG0/d0Uk6mkyEd54rux9OpOh2+JcU8O83pXh61XA7Ps4vl8a8uxo6Mp5NysQS8t+9yUs6qWTWuxuWsGlezcjKfVZP5eD6ezqrZlF4cHfOSFS3mS1adlYtyVi7ms2lVzqrxfDKvynE1G4c3pUw1Lsfz2bPS2XQ2Hw9xGZ29hp/NIRlmyqocz8fjmIvU2Xcal7P5eD6eR/PxfDIfa+4gR31Ld2MB5wp3twGzwrNzQ+PHLNLJdF4mJODiCGvHTqrFdBLHXsERnW1pMl08L6xS/x42Dq4GJzyRJAljCQWgL0y+hyqHS0oG9FZiUSp88nzbOFy3Op3W+oBQSsYZU4rYcUDrYUPbiM06DvsHBw38VBgefDQQmYuhsk/5nPOXBwe9SRZ85Wzse+bEhPlwXzUY+sHvbX+Yh6wk6A9MRAEgAa1FkMZImebMi0MMtCYphLQGQGAfqGRff7N+EWhNUOkrOMtiLgBgYDm3A0AhGMS6sNacXXsYP/tmjAgOWl6GfYLi8kO+sZI+5JNvLV6hh3Wno5f6HehO9wAehkUgH6HXV0z32ax82MPbRQTx/hu452pAwIevnf1LlQ0TzR8caGNM/0Guk2HWuocAqPP1Q7d2+jm8kEnvJekJAjUKRis0AL5UVQKgr+8QBQHd/qfbvwdPwweDVjDLgg/qVrBLMHVx6h8wtBu6q8/d7jgj0Kjem9o0vDtNrIWEhez1h4PQWJskqIauRiqF+i/94dA7Z5PeAg64smVRljbkLFf2ZPuiKwZZz4ErV7ArODwuk8Q664fDXl8qIdM0TXUvMdaGo2G/Gbw20UabLC/bPiQuWkBXLr/oRZevEF25/KKLC6uCIAgoULefxnvhPwXvDN4bfHsQwFyKykltd9Nsd+5bRSQQVuKh5qbhK0QUTdGBJ72nBg6GF5InDiM4KLQRlqpNM9euf5O+tc6mKdeZbHfrGtgUoGOZLNOfm7jlVlOC12+83NmH1yuEyeSCEUyvhkOAen61Qki40doCVNVgUDJW9gdVC8Bqo3kCWF2d1wDD4UozYS5MJoCr9cPWvfzGdUxIW57C3uzqtWdY/4xrV2d7kP7XEhGthl89ci3gfsOYOW6evPfe6MuRPVlcv/78u05PR0wb3l8tr92z27VfpNu5mfmQMRcV83kQxg+1+byIHGOhn5m8rV/U3m3vub5c9bnRbHR6evfzrl8vnmT0ZdG99756eWwYM4vtQ9ev1TV7H8D7WF1fu/7QdvHdUJaIZYHngbaKbs/6T8PXw/uDg+CCnGtz0b3tdkIH06Bzy91qxF6urOu+8uFO7/18fTqfAczmp9v9qzceu7pc9vsA/f6yubY4Ot6D0O+71772tV+4bkG7PXtqOoX5/MKF+RzqazcUkV5Inh9W3Q5+/gvgYNi0O7r3R8tgEXwRr/kmCKxgA9koxHovcyYf46ZZC6HdxIUQPp+xBoGdiVRI5BRdWstFKEs4LHyZ4ZgpXSV5HnatRV6W3WmW8W+EKG6dfbSVcPPsX9gHkFk+qNsdIwEHg9VJC0C6cac7VtgFyR7BxCgC6Hd7iQURdruDE5uQezR9dQbP1+J3IE7OL164D3EUAhT5Xlld6veBjgCY96wqRlJINUGI/UApZfr9el+P693+SXg53AruCF7IxR4qL+az2ZpmxrfJpSi8SOAEs6sUSLt5kW8St6BeqMu8WuBlwqUAcMfpESJmOYJbHeyvElfsXuu9ux86OUdgov368rn+wAIcQ9U63Z3uBg7edzCZCJbEh+Vg0J16L1S/vz2hlXPGNuOJyHMmdnI3GB6fvGBvQhHp1SvLNl551733djpw+eg48s6dy9vwOTAa33Xu4KAwkHYOD4+3o/HxA38dlO2WBzPKaNVkzVTKHWFx+2NMlFHVZE0Nj374wx/+4Ic+8K6HH34Ytg+f/ffFt3/7tz/8nY++DbpnfwDdsz9ofc3XfM3XQHz2GYjPPvM1EH1tELCgffsW/JFcuhcHg2AmF+3yRs6sW9vQgLE8jFf3bLOuYcZndSPhrt/6rd+C1uWzPy0ACoCz2/D9ly5dunHjchidvReU5t5c/q1f+e3f/u0PXP5T2zq7u2UhgOB3J5PJ9RtTm2X27K8+8IEPXP7tGGKX/q9wHX4i2AafGwS79dUm3IGYbOQ18ZGyf+aMYouEwqCj14ZXNiN5RTErinYs4JtCVpPtrjJb17r+/CjKiyQGjGMOedYdtloAWd49H8cAiCk4G1Okkz71v2SW58i+kix1XCBTQujD0KMG4xX6OgwjhgD9LAX8hk6rVVWdznCv0ybOR/1+f7Q3O9nrtItpnjslGGuXeZ4VRERRFGX1uN/LUpLS9IejWKJUsfdRlOdJEhdlFUVg8xxxMJnUzgdBGuDtW/CVOXzVsgteFbwheAfcDy+Fz4G3wPvwAj6Ij+KT+Ln4FL4Pvy8IspB8a5qmWTZbHqkhotZCg8XtTg/Q7uSFvPiwZ1Cr57rqzlSYVPySTVkthIjYTzy51mwWTVntCjhIzlWqoI2IvJu0TtELmvWQzmEG9jPQcTSm8lzolyyvN4tpmAS7ysnLuABi2Un+V0UjUiVhI7pRvY+m4gotaj5WcriNiOe68MAq5z/tA2wBXlykfrDz9UL2unEacC7wGs2P4WmbvwgzlDBu+nAPEQwe6PZ2NQO6baoPeEM6vbwzgFW4jCioi8OYdKs1hdxStibjqzH3Ia8lS8e23hEBc6Y8ppdls2vcfHOtuO5hc6AcXJ3XZVNGCuWzQA0TlqCjMPZZkCzTQtQ4hIgBeLp41zShysFgViKqSf3Zgijw4RznFC642K0ZIXdiuk2mkTAc2rmszbT9ZiG3hQ/Y4iEiNSZfX9GSyYAXSRJFGJpRiozAWq+KciSkgP4w5NY4BUBfKyQjSVnAKEmEx5xWk5BiVBbKW4vZVQJQzhrmh2/v9/sKCZXgUnAboyv7H3lGwDmXAmnkPABC/lICAhSSyCqnwD/ZWHDKudK5zHvOONHyVoOOCJAVWgEHkMYSAvc+c65wDpQDa2So3qm4lIovzZXU7l3EGDEOlHF0lpmZjON+fnRU9JJYzDWzDo+UThTnJGKXchc1N65NWCAwJjlJcNqe/RHnKtEqNJojMaLUxYKOJXHJGKDVDkbE4EY8WNXq80JQzgamInMAgpvcZ2LcWcGHbcxHh4ejHNuhByZUmmU+N1wAENspHiH/CgjicLsWsOXQjJgpy4nAaMGk5Fx8geRcSia0AaIcTl6ORZUGpkvR8mt/K2fFOWW4LPTnHmcp44LKLyxJcJZmxw9Lro0pHixm0gKxoiw1A/1dRunQ+1Arc3UwGAhCQMuF5EIhoQRSglueJJILx7hSCsAYBykgeBOGApEpSDMCVNJYeeKMAVBKM+YEl0nCLRdKMUTuQ+MBIYUTaY1UgJSlf4QkQsZYKIjhq3pxmmXCCQmIII1JnBAMCJX3BM6FjnMixiQzjKEBJYEJ7xSCdw4A0HNjnLLGkpICAXyYAyjnBQMlATQyZphkjAgYd6FzwJzXQAAkpE2MkW7u6rMiy9K4lyZ7Ry6KYpYCpCyOIne0l6RQETAkFWpEppUn8hRQGSMBuTROWoawlDs6ySPqUMO+5J9onylA6cyPIoKQ0kQEAI6sLXXopZQApJQUSMCl84IJimLPbBRZ5uOIBBPeSQ6EQipFAI4fU11aS3ZI7cjIzPNvMh1XlrkUkrVadtBqOQDXag1c1WJSyLwsXUe9N8lS3jZGMHB5/wjBWRMvsariWAkAoeK4qrBlHWBs7urnFoAJY9o8S5NfB6VAKVAS/5AY8ZADo4gTQsACd/tW8P/gp4MC2nAdHg2CXRQMkeaAD08EitpW1UqpOgVaw2qIxHSNd802BrcXuxJVwDOw5CS1DASfBU3TZj0xF5fXYYXGFXVWE4rNF4vl+9fNZCPqyUUZZKgtbaulMr/EEpHSXl5Py8sh9K0Y0zAQXIaCxYakWTRboR3iHraKnBxtXASRkQbyyYCGLLrTkC4HpPiDjtaay8o9EnJ7ZCZhTbnuiovXzQpvdf929wthGHIKXmZLQESTZTP+Ge89NzY0WgNwjtJYoZikKtNScS6JEWl2tUCKSnVi2nFS2GrNZ+0WWgBlmJCo6dLrGU6ClC6VZV8KHELVGIDmhoGWAmUkCCUxYrs7RUbIGIQE1yTkg4/8TKWMGEvNzBMAIHAlnojcLti1ofhDnLoYraRwywEJDK9aUkGULhaLRfqHOJ2cnEwniKNx472/QlLiBTPIUrgbAYwBIHAeLrTb7WdJxjmTz+x4/69f8RVfEcexZFwIDcIq5cLIGEKlVGSMUsL1UCASkdFEZBCfyYUAEIK/BJRAkNIgEWeSCS0EEqI0GJYO0qOcl4qBRn4ZmDEKAYQOQRgOxBGllohCcYnEAL3agUSoLBAac45/8h1RWsMFk4oYgpAkjvKcExOowAMQrqkeGEVTqRAA76RmyisNf3KSEpwBNNeRC4LLB7m/GQEWIggP2KXrGF0XaxVnHzfudSK+iPxGszJX92ofXjRlwZnEw7JbNbIpgrTe2HN+YzgcPms2MJYAs5w6deLvJW/7jld/22lVWoAIDQ8sy913vNKW6J1tBz8X+ABq02TaEWwnGRp1pJie6Lo5yVAz8tMmxCR0rl1eH4U4uTcV04nkmUtOeLkzFzrni0LLsJJ2WTW0Ut09zOkkgVkGGsWkKFprRw7xblk9z6+26I9MXc0W60Y1cc/LopTwU2dfA284+xqWZ/1ennF4I2VZt5elbOYFZ8SFbzFeMRYxzj9ZG9znNZQvxYGziLGKs9bieQEcwWgOjONMLQCZF4KYEL5gVBACR6G1brT/HKkMsQ+0FsgBKWfIufdCMBLCMwThlAIELhgJBA4CbvWznJ19DcvSXi/LGLye51nv7HVvaGpiyAkRTLfb8cYgGuM73a5he9BIscEm4lin+v0rr4qlIOTYkUqBMQSpKiMr65sYBVZeGVtJUylJrAKXLeVIQsavvNrvK8nlTsw4tGff9y34E7gVDIOLkbOcgMQnCkfYu0LBq92wcIAiOyyWmQ1eC1U5Gg3hoNWCl0FZjsaDw1YLXnb5sNWatm00HPsehVs3DvZbrQiKdmt9Y/+gasV5u705+/mi3f7igpCrmLY/bAbtDEA7OgSDoEC6zpzEtNE2b/zajhQeygfDL7W2O1etJvYKAkn+fbU1dJZSJtY5FyfOAi7H53azGcBwsOhCZqSTulWW1b3BoEKIwqrUh+gPy8h96IV9Ly9hf3jMn88unIyXaF3ywo8lxLIDs73T5XSqrvqBd6tqA3+FbNjPyzKVsoxCgDAqdROPlW/4EGTZ4LXvY5Bl9uQXSoMXB18UvFu3SXrk0XPN6zPo21i7WzTLzXrDQ6Gd4mtH7UDa0Ig0DGmD0CGPa7JbLntXGXJznvJ3QdvyA/Dp+xYNQLO4795mgbho7n2mKNIwjV0FyAkVK8uiQAnkhNEiYczMRT6V42mQ73un4fBv/uZvjgWcjeORMV/yyG6LuN098vAvxz0Mn4eLZmXV7msW+JmccZNmmoC8O1UIjlA/reV+NVOKvGCAwMLQGgTGer3BTDAizhSivjk9rzXAaK1Y/YOcvQK3u4d/zQYB3P6n279hO8WjsyHsUai/g+J+eTPfbDe7z5s4uA0pKQrEgKYMba/rdbxbswPEen+qXMJXuqM0jqMUEpsmLSJtYJ9L5fHR0RGPSrgpZBWmmR9rVbgkaTHSory45kLxh87fLIoEAC4fSAZo46KILecMQKJSk/FDMQOllQKIHjm/LEoheddJIlS9XrXwjIL3+wf7+5NWiykuQu2JpV925z2DgZAUVHluPQ1/BB8PHg++LHhf8FcQQh8O4QI8E54PL4Ovg4/AR+EX4Q/hnzHHe/Bx/Gz8cvyGgM8mPtr1tijIzLj1zM+uCgcW2C+Z1nzx57DS42BOFKvbDWwrSQJ/lnytkFk2YqrzWUj/iM5FiXcXpv2SkyVXCEkc6tA44GVOWs2lqJY6t8iLt8QP4eqfjLEYidpYXq7m8uW4gscsSjmvt/V6V4t62yw3AXoYDirckUAF+25frmgc2FZI4Y08douymKZS11k3hVJ9p6ym8TYkPiAuuSBsVjYjuHMKJYtOfdV0NV3XBrU4rUXwL7nY4hV1oo3KglXXxlIiycbGjHJ5xYBmGj5+/269q7arJmPh1maRWoZYrY3u9qbW1mh2hyzPqOLI1gMFbkZJxzwtkKYLchNa4InhwBG5rUpJ1gtOM4HgC+mZlJHB3hKOTGrcLVfwRyzmhFwqCYpQsghyHSfReNHsI6WJkmWSyFSwEwMhhZPTuy5IIE0ghWSoVFZwoQQHuu7mvk9KQHH2R3UKDyzilJfKsGqCFNJ2Op3XFBMpBCOq5iaFWVYigJkhIFdMcSZz5wGsTRwXKJUixoBpbdutqj/b67UTosgY9HEsNWpTIimXd7qdUZYlAKxMS2MtK9PUKinZJ7lC1AaBK22M5ITAexUAJFUMkBVGS8GZBwQnOKPwSRvH3MQuST8i1bnT4HBlWHWJgQT4d59popch6EgKbYW1QafJDFZF38oJheVSsFBvwjAUHBIGRctLEWB6ggYN1mi+9ygJ6LVbakOhZERCcqOFQvJE8Lfc+1AyzkrvpAD8CaGM8FlVQlKLJMXHhWDqRJWZU1Xl4khyHpseAGjrnBWCI3LlZn3SMYkMvbcam8QwzvKOABT/nREJbFi1AjDBAGWWERxL70qAKpHya6OyLKDTqtSLUNosC51EbN9dh8a02z1GlXeMkAkpmfKMJdH64qXDJElti1gIIAxjNgxbush7jEtBDKGsqjgTUUTMGmKMEDmzIREJbqNESgDEqsVYEsE7gDgAJ8aZCpm8nR2qOJEvLlmr26qIpBBQGuMAkjT1/01LxozNcnmWxdYAzk6RO+tASZZVaWq9FHHcZZXemq2UvhxyfnRwMCIW6khpZfO8DdjLS0sAChgPXZLEX0HAnIZNQ1xyRsw5HSkQjHHK03usHYFxxsacuFRSakUdUFIJYIzxi1k6b3MhFcQO0FUAhJy95REQ21woKU0sByTmEwjDELg9d6jlMAGBIxG2OQCXXLSaZQRMgAvklqhZkge5eC0gXFFGoeCMCaWlRFRWOUK4zxuLwLhkxsYoBL9ORMylnCehI5agCr0R0moAHgpijHkAru5mzBAwxhlqITgiYpimBTEihChJPSFDJTmzSiHXWmmSBrSxhMJ5jRyhrVWvHzkPTpFl5BQgKI0AUqTnJWMAQjkiQGJUMoaBLdU3+gn4a/iJoBWsghcGbwkC0P1i2RkUlGJMErgF4syV1XIl8pqUpeVyGM5FR1YyuezmUQqXpajneCLk5U3ILJ0KVqat5zV86dU7r52e7u0BDAaXLt24cfHCbDy3Hi6arTGqIb7PFMJ8utvtR1qo/3aYxMmox1mEsHd9NksTHh4uH330oQvtjg5PTpqm9xNpVVUFF4B5ZpA055bzciRUK8/hB85RGPYu3zAbDC+slG9gHmf/cdlpA1jnFKJLk9gSef9c8L6YeERjLfJOezgsn3Hvg3l+bu/ChWvVptId08ZZAPShKJvHS8QWZ7FSWAGPP1lo/8cqGKBLIXqvqBmb76B3Amkogv6CqKimMFYp4z+wziDUNwBWEeMvIqfJPyP+FpKk144jOVFZCYcvv5hO3KALSkWmCj1AnPT287FJMoCu6UYhZNkQiNesZx8axxEYm+QZUv/rvu467ectxMxyIbgOOab0AJh6PhpJbJiNwk4/ivKxjNvBgn/jjck1hGGr4geFWtnfDbud3H3YjUHSGPl/H/49CUnSe+5ksgHuycUUesboh7bFe3QcR0d5/meT9uNNlP03DOAngnFwI3icKwj7/6HpkU5I4ABkm2mkBHq/VM3KViUFlXD2RsSLSN5EZxQE8BTylZR0MHU3Ii2VBPYokyXEPq0jtridDVxDdpYFpzXylKVbWZM5w7P4+uXLl889fG5faA7NpZtrbbQG4cNO7kPI8ha8vA90AtZgZJU2zmlDmXdwHYry7GmD5wCUrxGKsg900omsAq2d0/AaYjLqtPza8hnn9ovm0s31AYZh/nNKXZ5OhT45uXx5OhVqvz69BEN7vx2m1Pilrh3HUF+6dOkGQUtoASOgQ9Baa6iyDEJfdEIv/2VxetcarQWw2jmttI0K72F79/G8eNJGCwAeHV86npfN6V3rLlrtnNagT8CHeR56wMs3EKpyCHhUS5WHHl6D+vjkyqXpVOiTk8u7yQS/eJqs18m0HccAUdwJggCD4LY876HeFwR8PB4rs5AwcbZuAZEmLJKqtjuW1tkgcHWRyNQYT3PjC3uW/wrWJrkxxuSJtXDZxIm3oJp9BaSD3Vd4PHKeTYfatZxUzoLz2Xdk3ltbHT5owbkwtNcuWh9aD5Ben8cATT8Fb4L3M2LVWL9vwMZAyFf8RAWboV/X/BuKYriXZVk2G+bF52WDQTsHiB57wAPmrfGo/Sg8dJjnUFWTsz+YVRXk+fGD7y4AqqLTyd7wujwyQsXxF94TBDqQt2/BP8JPB18evC34ej4EvZgjTfm30F+h/4oQjIvBpJNgXjwo+jEvsqIoioEYkLHb5MUQ8tvOTIrxZJBpy/qigzXzUGdSPK8kyAZhJxwUg8wnNuBxpHExGAXawdDntaPUojkUj/NecoCJKPLYr1KJKCZF6edx7no00ZAp1LQoBuFAgyAbFUUxCIeEwNqC0CcGPwC2VAQT707yOGdrXRbxsUhMOi2LsChALU2+i9LLAABnAAAuU3pXEEv7ZT3Ja3aN3kFh721nzpz9ieX2UudLX/pSZxkA4KI8c+bM+Ytn1g88//zz715st9vLnSV55syZM2ePLXfg5GWrS0gJDz//oaVvwFKJ8Yy92vtlhh8FeBSzhyaEPgJwz9LysvW7v/u7afD16t5b77vvPlgJqt987h7B2FpcXCwmS50j999//8UTac33/ertftVaWlpaWvrY7bffXvVvLyMZB3BcD5XoLHoaPYde4KsfUMt4w6kGQZY1Ym1ipoAmwWORSC1z0ndjXGgk7py7KyyXvy2m9QKWGM3GNwomW7yhDFhIeR6GRmZ9aS/K6QRKamLoUZMQE0MPiEnvNE2TEJPSZrfbxe6xw4SQr0wmE0ImhHS737PvgbSa7/1qivWVq2kOh2fSFA7jyeSGGyZjDPPzh2zcLXE5YOnVarMRzvzL2bNnKR4OKB0sp/QspWcJHNyi9Kzcq4JJ4CA9S4CaBEwgJjWnv9t7934VDq+vKlTT/Hu25+Yxnp/bXp2dVURKH+NIxlnXjeN4odDJGosERvBm5KAt9CbME9jalAvGkwkLa2twool4D1zMcA6ZNyZ44O6k6OdJh9PXl3A4Qz0JXJ3wfGQCelPIihCdPn1ak0qP4ziB/1hJtWq1P1+vQ5KmkOckjgnU6wsVvPfnWOlwCpRWrdk2bRqGKfsz3SCAU/DoHyW2zTVM3Er2ys9GUXSqG0UA9frCLzC/kolTcZqeWqjX4SSJ73n88cd1/fH3+J4vuZAQYqI94bAhRLU68/N2zav4+jX4Tb6RgJhARegdFWyEgY92kyNKLArXbe70bpEXIfzm1mc/B1vf/vZvtlqt1v5Ll/bDFgCNtAfo4sXBSbu7e3/heZ4HqHsdleWPwCbn+WzBNbSJTqDb0OfZBwlHsloRn0AJ7IxAME1qnEPaga/PZllmK6kZ4PczR2KKvDp95RQqB5sihzwD0rVwIrgRMTDzEIzKt2BLSTgljFTpSZRzTkB5PjYtEwNJtonQCHNlMwO1LKXz5iOO8wHH+UDFcW51nFs7AFiqoRTung10TkDGwzxsC4DopuEaBnS702m3C4bhGqZOACyLvUqZJiSxlGaGge0AriRen+FEBphzC2PXdna4rtvs93QJexXDq2nhrZGr+z2MVpzIh3qj3tuZX8B4YX6n16g3/MhJKLUxsRmtxnFQTZPmOC2bCc0krQZxnDLqEGzjdRz3Mp6DF1CKCnSUfQNW1Wy2BbnvCD5FDENlI6MxhpAAbB64qbCKrTTfF4jVCcmOUO2MjU8UxcNk24NfN9LPsyfwZHq+1jgc/2PGw43a+ekEw+zGzoFlaRanTh7cMc1Fy6153vpf2EP8fRgM2lXOrTkhOjP79q8+KADEQACImYHipAe5dsfOjiNcLj/VwtnZuePeOUaXQ/+AaS4Vp04dCux9W9vz/x8ATMee787O5Qsr5XLB2cxjL7aBVY0i/JPG7l9KpJWsmIyY2dhaTH0I6Jvf/OY3/8vAInx+lD7D0v8H12D3Tn6RSWdXshVi4226gWm7aCMchmGIWRgGAeA4jmNMwzAIYd7e7m3B7t4PwR17P1RTSmn1/5VKqVT95+pK01T9qaomlapVGppSeu33be8MXoMHmUNr6Cjy60DRKI8aHkHnES5c/BW2xD0YTMNRYv45PRegwaOcGbQM3XV1421+GPr/Ra3BbxuFN7Dj550WOK5uGLr7hiLkT//95X+61nLeaO39b711fq52gIp76mGKpuaoYEpEe4yaMelP9rDxWoL0Cl9auHzlypV2uXLw4ErZvvLgg3v/+LkvnIhm0zVPbJUE97+Acvehh3YHr7zyyuc+90p/7o035/p5A2S/Dv8bfhwxFl3WnkCX0XehZ/NLtaM4ojRyAl9/6XQ0jHOZM+BVJR3Rz1MDEH+ZrMj3ppNxPglfDAm9+slfUsMvmYwnnXr99jxAiAajNBhTL3Wy+PYM6ACB+c13UIxzmAvr9fDehWZOBsXWVlHgvLEwGs3/0Whra6jUYlEsKv22hQVjff348fU1c2EhrcytrKyU85X0m9gPQle6jHI2ikL5fspc6YZ+gGUUjhj/CQ55DxiN0jQixwOlgpdT9YVzs7Ozs+e+oNJGY21pkfM45iw+fPhwY1A0Ly4uLi1egOagaB4CsWQ7jr0kYO/fADPdNKVexGxytgSQpqkzDLNSI09LUAqExKaJxXGgkH9S/5fRefQ9CAWKwLFctH5FxW3Y3SzAiWcM12hBEOWF831gZhBnnkdFwbMyWDug10EXlRADRieW6U0RGT0ah5NfjU3LN5S2TwAQjTENk2VCXsTkBUJeIGQYGjqwmAGeCE3zBr7/ou+/6AP4L2rquSCcnzV0AE1r1gyTAqtgwOyWcziM+guGDrDaNQ0MtMIAgmD9At5gPQoYCMYMoIbxm4C+RvDDGD+MyZ8SaGhCmq8yAPbqCsZY1vT4tUh/k1Jv0qM/DY03sVfrhsEYY0qTEoT0KQayDbDWMAxChdAaoGk+ZUkYAuxDDCG0hbeghSRK0Bwq0RmEetkom5BgcqDNVDO3t5nV7ubQzcnQCYNLemjdYZlnamvvjd3P4629y7u7u1ut1ud3d3e3tt64du3aVqvVan1+a2v32rVrrda11u7ly7ufb+3uXr58+fIuUgihfXgXdhBHdbSK3oR+HP0c+gP0LfS36O8RKhNiWhlNwok5Y6coRmmWuNC9A28EEk4u2eXdSZGJQjrMYKrAr2yhSHcjln9EBtoLw2LUy9aX0YbRWT0S1nrY/0+AKMCRg2X52JsU05HI3MkyxWaXRyzWUCQTPM/mNeGEZ508Lz0S0k1KdTX8aBpv3ZqzB9M0TSfgB4EHKdYNuKGa9qFXTSGFdjaAotNJPwOtVruJqzpTjdchpLjZbjchNYwoTCphZBgpfDHUILZmepYMlZJSI9yPNYjBmu1bMtQ1KRTh3i+naZrCZaZrFMDMOhaTOgWwuj3rGHccIRyHLwvP49zzxP9cX1+vp/uT9BeeuQeRoXQjMgCMNO1VU4C02htknU42SNOe73l+j4vHmtJqz3e9oJumlTA0DcMMw0q66IEOTcBVjUkAcCQ5xDsLpQN42IAmQDUFV8yZszQeP2hrkmsJJBgnCWhcanVIAJL6WClLqTVdd5QiFy5cmL3z/QghZF+/fv1l+H54EQ21PvTxOF3Zn0S/gV5Bf5uHTVqDZdjBtyqolemXkYqO0ousfe6fXV+DXbwR+xxEabhUiMK+VL8l0dCiXsmbNZlMRsY7/wEZP1lLdmCCq3R90zKKbyXNVr1BpRZFc0L6fsa5ZSdQqbSlDIMe9jzfIynI/8ABsALt1sLCYLCw0GqDobtbly9vubqx95+lNAwph96Io4vwl3+fLLgvKsDU5o03bioKsHPnnTvwAhASRSvYdXTdAde1LAGmZVoYMzqH4ziuME1W4gWgNEn37b10fC3OCOCFrB3vtTu1ZQyDWqfde3Dld7djTCAvfv/hNN5jLDx5hpC00gRoxgmlJsam362gjqqx9VS8gEreDNc+jJ5Gn0DIPsLo8aTTchiDG67SSTgRxSgOJ+G0zNsvjotJODnYjPflZSCyQrEwgERpi6tTMEzX+s1p/kyd0PXC2+Vz7qQoHXv5YuQGHL35xqnI5hydTE3Nxt53vvHcc5cPzz66GoZhGGjggPZk/K6Ds3PwgUOHDlmWZVr5jlaKIjh06NChQ7bNut2upXPGbEWj92UwVk+l0FfqoteL3PvAY9/32muvvda64447Gvs/JKXU3CnWpVIwXhnAqcbG5unHBu1Goz14Ua8AJIn9QKPRMBouT7l7qGoYug5gmrqy45jgIKggRJC4/ld4Fb6ALHQEPYtQbyujpQ1SY1qDUZ6URi+bOhYB44ua1z1Fsag7LqcTJUqb34u1eBQPN5XvFR0H9YGPbOkJNNdXXi91an0kd1aPPAftmRQS3oTDwYgw6Xc6+HFgMiPWjY2FXu/YaK3pdF6j0h7v6tb+IARM8hw+BkJ0BxVKOYYR5RlVA0wSBCG6Q+q0b/QY888FbaCHnU6vb/qYJHg2YcxdvsxvgN4+uxeBshydzUfTaSvTkphN0nSzPxlnmby8L51m1Gotl02Tu7IoCJ6DSUy/jnlGIOXw10HwHiYxlu02ZbkvlBP5jLE4nqLgPV/Sdyxu34I/hY8Hk34t0SaCwzRXtsjM4/6DP8Xh6NyFmzd21zptkKLd3hyUZeTjvNMe7UZjgPlythdlRO3RpUt31levLhsGg/5sVHWcleF+fSGgILt9C34EbgWDYMd2BeVqgfbq4HqDXE2GKiEG4BhZLWbjg61H3Em4m+/rLz/6gouXMIryzPen027R7RQF91kWRQCXvq51cjyfIW42jzxjs0aczY6Pis+F0ejcajDkrAfOZ5l3gO1L+/sIT10DvHL5sXo2Hw6T+XiEWFXttkyGw/l8/rxrZ4/guZPr1y8+enqKeHr66MXr10/OIQxPRkPE/uDgcJ45D+Bd1nduMrkQsCAIAvgMPBW8Jvjy4IeC/xwEM3f9fru7uQLJdNHU4BaZwQOBxYBxG19IFWSq6ttFB6NKwjraq0Vz92hInji6MrRi7wY3zaezXJVpXdgan+tAgLmlXV1dHc3jSLFP5B5RmGNhebOu+W0ecaubqvYpW09quAOMBk3OowbIUSsIQWvMATR6jwq0xsUeSoFKg8dfYgMnt2zqmaBBKx9qDf/tiSeeuPTgg5c4S5W0bpAkiUmlUjq/9OCDlwqlpXC2SJKzHz4+Pn/lyvmTk/NXrpz/Se/9+r3GFeKuR3wjGhR6hxoyUhoWSsKQFElXKRgLCn4VPkNegw61BqXJQLr6SvnZE088sTvlPJXK2mFSVWlsEyW1KmB3WiithLVFWlXJN56/cuX8e2rBMR7V6n+AT8F3Ba8IPj/4YPCJ4G+gDZfhBfCFQeDTtbncoXQ02gYiKAN5ugOhb4K5d9juJs2kmU9jG8nZi9vV0mhYiOO5HO2I6AIahgoA/aBD/l5VuaPPkmaOK4tmUbyyUHEu6mpJMWkW/t9UiF3t3C5ygNQ+UL0y2hw3EAyQhvfVRTOf1mSTj04Pu6Se1/NFxIQ73m0rlg46i83iXdG6G35uwil4DxK2LJtgadKsP/rFdsvVopDltGnyT/uASbNo1q9WpfplpjUDZrIsUkBJEhX4vGbpDwYZQHc+H/WcB7LOeCdUq2eddb49QYi626s6w+H56d6s36s0k9ZZFAsCkewfDN4NaYbO2qfH43GLSQyCe+3ns2niHHrGUcdxFsVxJBig7uVFXPwouDTJKs2BpWlvf7kEF7PfuuPjvVdnoU7ifug9B1SZNQBhlg26AtBaD5hHcUhkvc/yOIogdc4L3pod9s7+FgBl6JMsVDrJiZH7lLm4sJ70S3gDORdbzUXkAMq2t8RCCfBLCL0s8k4CZHmsNQfg6km+iedl+i7KGFNRJ09iRj4sQROlaVn6iBExK3kskHMEkK1qMG53OGmdG9zMliT7RVz0LrQ7CBUAA4dkzj4IadJlyiondd6G4u7G5ICkEYycI5g9YgwYwr8wImnaYQiJtToy5ggQcqnCL8TMOS/MemoKrQGIvUNSANRiClFyQYQogUARS6So3o/hZ87aCWEJQAClUeuviIgxw7kGDBV3xCzAuwCgSIQAYNxohShZQLf/+fbv4Z28Ri5dDh6LvYBbkAJ1HyvHg/M0kfWmcDcaz2XSeeLKeV0hRc2wArTJ3QKUMjvebua7pmhEjZdMGML/+pZObuM4fMXkcDiZDkZK6k8zZlN4yWhv1r7YbgH0B8dnPzeRMo6TBN/+RKewURyee/ChB60UcN92axUD4NNTx4mYtaG3L3rPe97jjWbUPfvwAL5HWKPy4fD0NM+LN5s49kbKxXZqFQPgSRO1gyAI+O2z25+EfwcfDPrBLDgJLgd3BwHUVb1rtvVc8kZIUWWSY6P75OstELV4x+dJsB5TZ6KmRscjXjSQbit4HvzS8i0ve9nLQmFsePbXTgp6jYhjM/0zJ0Ty2YqSH/uPZ39B+h+f+O7PF/ToVzGlpARIPvGJT7zwtZLBs7TW48xYOkZjorMPx4j+4T8KwwgvgtqPh1td/eHfnn1YSMie1mkWxwAXP/7xj/+yJhEEQcCC4PavwX+FDwfngl3w6uDzAk1rN728skYYFiWl3fXd4VYbQZ8s8O+idaCXwJEMilNJf52VSl5U7cqL1NJ2V/uDGQs/IZyv9iHLuq8Dfz05LheX8jiG172/clbF8bdnqphDTL/wda97XbnYDFF5YTm2Fl73DVWWCqV4GFYzyLKeZBjzqUBM/74VRbDoZTnEUfWqIvQijoX35UEYhe3zV/8nnL4n/51xVL2qjCKmlAh9deDDsNtvtYatKFr0sgy+FoDfUF0obXIs3WDiOQg2FImpz6ww35yuMBK3hTC6sITBLWTQChW+XqSfAx8WWH57GBanRsqPnp6eGilnPER4P3Q7B89+cb//9PS0CMNvL7EIPUhp7pXS/FeU3b81veAdfRGgrgN35YrXqwKVj6ZihOTsRM0edNE7Mf3QcrX8vbA0aLckJZDF6fdzuVoSDjfTD5YV09ZWLUXGCI7izrs4WSMFI0t80oQ4QlEWhopcK2TswnxhWCAPI6U0MaYVcUEghVJIKs2KQgPIQV8rzRCFJGG0zluXNOsWqfl7VmslWy3rOLNOSsbbbc6Mnk4EmHPn8kwicrSmYVrpPIsfXBLHSSIkCKGTVHMar4gcR6Wr4HnBy4I3BG8NAh5bnzGsxP2ArWq4IslkeofSrEY3kN3tGnS2gPd67pYB4VBnV9f3CqqzWlayp8Z6sS2LiX1w/datW9sMjBrbkdm+SkurFAfW20Mp8JASGn2KaZrhSQk34luE9emhlGp5ru10HMvSjIjBCISwDH6GKyU4F0pxzv/f3FoJVlv/HxLOdP+ZC5Ix0nmQUKJprhCCuUoXnBDf63X8gFERH5G2JTVJXrUK45wpxe/lnGuKM8aVwnZuZBmxi3byYUO/N7UPwTC0KzM7c+U1y8QWMxABXU8aTC9Wrp9N1J5GMSQdKZhOLbv/67WvtS5s74TfTl3PGyvd6FqmGd7xl2qw99fxypFjGUKJzzB/3O/3ofeTmlJW7lBmTO9eBQuPx+e3JAaslnqzbVMIXq12zN6ZTk/cmne/5z3vObbOIVX6m3gffCXHt9wKuoo+hFAvLYTtYbR7bTb5awa3H5G8MXO4BI1esZSwwUVaqpwj06Bumck4Z53chXpTTO+71ECjdEeoWUqBpixbU0qzHxlkxh7J67bSJvxLXg2Usj4Rz86MhmW3G9WGs7OxwJi7rktHI+q6LsdYxLOzw1rU7Zaj4cxsnKZ7/7S4EDphUgWAhjXCZHvnnnt2tgnZ3rnnr5SybE0pZdmaUkNztJRa6VZTy+KhXcFYI1Jwt1ZrjHd2xo1azeVCEg3jih1yy0qr3dmlpdn/YwSObnoU/FZZWZhZ2Zqbw3hubmtrfg73e741NbTdj6v+La2hTxGyBqAl122IZkf72HtWxCXf96+fuXDhwmOmJuMT52+68BHdcfTPmpoWkzS16X0duD+QXXyP6/n4nnt+xjRf9D0f3oochK7/d7gGb423KbUbGxMRAI24hhg5xWwzdZN4QhIWoohbCqAfYTlSmGowW2msIzfAwmcYv3pYjnz1A5fKsjx++q7PLS0tdcpku9VquT0j1jStbnWiSqWipSKmlMY8aYZhSCJcDYIghI16vQ4J6zebTVbVKrOzszKz6mEYLln5TYcPH07KmfNzc3O1kT+7ubk5OdMZHThwYOe2BegsLS3lC7PdWq2W1bsiiqJaXL81yzIv8857nlfxKsfr9bpdcxzTNDtGe1Ep1dd665qmLevFlmmas9bcE5zzLXXw2dXVVWvq/idK6SXtClSiKFqMFi/5vn+LfsPN9Xp9J417Gb8Cr+S4FXfRpTunh4TwVYC2B+0wPAOZ6p5RGA/Bhsw8al60NcoYkCRSBvRpbY4fVWh0zTeKp+XrBw8enE4PngcAu+l7AFHcW+/3APL+Oqz4ikWWHwpBMRa2HWr9Bex0ozhNF3JVyNdsYVsOozrOzzUuZraCbJI+eGFfvV5/6reSd796mVI6MarVbKZWl1O1ML9v38K8trdtM+zqlq0rgzLHsqSdElGoWq0/12ywMV9Y2BnlKrBtgTEVMvCtiCnfE4kg8XwUedIhD2U6OItFYdvXykuH6EJTxisqv3V+e3t1xdt726jXp2y5NcDzRZHPWJfjw4fOnJn+Z95oDEfbrN8bjYuPr5x2O9lwuHX1xvPDodQLzkVoFiGWxwhYqRzHAuAdxEXZk9pdCq794A/+YBPw8vJhmLM7bSz+QGPvP5XdLsbdbjkd/oam8Nxzz82vHF0eYDxYPvqjB72PNN+SeplkSRb1uvne59n1b8Ovww+jmi+5Yh4zhYJcBAytsry9asFc2knaHBkCvF9IOIxweliFE+T6N52tdcoOHLr55v3rlB3gmmYanIu5rf1b24PX8jwXnt+arVYxMBoGoW+aYJmK2rY1E0aRz+M4CjEw5oehZ5jYtgRYpr5y+Kab929QtnPo5pv3CymlYJx4BAfB8E9mZ2eF0gDCMNcc29Y5F8K2OQOg1J0LBDbmSq43Y9iOaTAmhOVSBkCIj/Lx+Pq/Xf8N+DX4MlpEl3KbEOUD0BBiksgSeI4yTwctuHSal3m8qfgMKjCQc3SbJ/JZgPSI+TfNaQ7vxBj/JBdrnB0UQvLznN8pxMe5XBTsjxgTX+NMvfrqq5hS8Q3B5n9KyKEQfFUIyS8xflHyL3C5KPinMMY/xugC59uMMXaO8+OMfYSxDhcvYcx+mPPv/sY3voEB2Bc5n/sRxnLOeckYYxc5P8r45xjrco4QQhQhhOAa7CIPTdB59ABCwOv3I/371RLFoyo/CxaWHn2TIi6mMaapgo4sKv/b4uJ4ivr5dc6ViwTm8iXTEp4F10tS767LPd2eC2NotYqrNK60m3HM1+6K60dwqzUoWi34DrheSgklqS+l0Dwv4ELTvH7qufAKRGE7509AZI2shP4Tef2pBq0WvqEdhQCeX4/flFvk/oGe0Pds8WLV9UCXnhf4UgpSHojYCCFNuv//uChfWXhHjG/h9TvrfSQKgtnkhzKQa6oI2eYSbp13EzAUxGDDSdmJdhqDhSOv+GLRiKB5k2ySr5aV8W0cfQMKYlU+QrUy6BofNAA4eH3FcTh8tCpBEHFX9jK3Cghc9sXWXviElELI4NSkRbv4tTA/6WrRbIshxNzGOFwCCA6AwFJGEEvJ0U/2uABELrw9cXDbu0iSXpjnScykDat2O01x2+/HcRRyHNIeBCtksEeTAgBXds7KuTSaAFAJwdnLHlkiL6ZjpI3SQEopZCIM2912O2X2G189MpXMPEOBQMx7i2QRypQztImhvl9CqNAaTI2IYQoQeucBmeXcWo/MhowAOBBz//CQQ2TMGyOwmjXWWFA8IQrVGZMewVoCRExkHHkPBKRD9o0neQQpQ28tQdkyyn7vxAMAgyC1jGI9UIqsgiizUQXr1P0IRBJERhzKmZQQpWls8iJNNRYzwLhSPF8LuwKlC0+EoIRyBdeJQ5QE6IjzhOOkJEipaVcxRaGEMKbvQwdMKMla+8fEJEY0ApHpkCNqMpazjitCFHqYj8uS7PYt+Au4Fbw2iBmdppAKt9xWiC/APF+AeETcSMwtxlbVV/NodIeXROWPibKp4NOc8059+qxEGdCX/IChVnDHi09LWcj8BafRV0Q//Mj3veFV/zr88q9Lm3MfP/osV7B530nljQHW6/V6xw/dOWs75uC2rrq718P7uT+3uquVbs2XpZ/1VfP7Xz5Pn/2lp0/oZGbbTDiVt7D35YIguAufgsc5JX08zws+K/iq4N3BdwUfCf5r8A+gYa+GszOplzZDlvVhFEcx6QXRMNZ1hJVBl1uUNGV+cgEhUkhh5jECh494MijwApPkEZJDh0o1OnHTkX1QXuf7sMSSicQIbnCI/jAQWcxH+hKbMt0KQ2LHOwrDUTCMEd4vWHM3YwUu8jnYUliMnjThg/BFcJlxbfEuOXjogX7HMB44dAjDcClN4d+ex4cOPWDond4Dhw4SSKuLQ9iQwqoBSKFZGAwFliZl9andYV1jXPsucF1wcKsFdsdxHDvFOM2lo1Wmq///eIBKlrEKWl/a2Meazch+mUuLTKJSn1hyLNcxFoTvFq9SBGP8YtFuYQbd7nSx7VSSejbtdjEwaLeH9UrFaS/OAOOAY4NzwqQEQaVGKY50zinVFFAK+vGyLF23LBsYN8qbG1BNsXV0vtFogGXBfAOqKbaOzjcaDbAs6GiayTHeJy28qWkmxzg0Y8DMlObWSc45J7k+ZYwxoTg6oGd2+jsoRihCrqNNJxD9tkW7fSCmNE5wAZ/dew+8Y+890XIh7q0JSlnPr83NiTuBH+Rw5yW8k/d702mvz2mnswqfV8oaa+3eJ2insxqM0AUeTqn/OzJdnZsTsr96LdYD5vNAQIXrJAoVoAknXpowt7d7GfDrf/Pnt773A/fdct/7b7rppttuvhVUJCbv7v7p4ptPnPjY2mTthqIoyuU4/Fsx8jc9iaMANdAMWkZTtIkOckRXdhu6Bz2MHkdvQ+/k2uByPoZ+CP0c+jX0FYTiaZkVUZz7N0yDcFSMHcSRmJjN+aO3DYvR5I/bh0Ne0Dg3mb2s4KIUZbGhRIub3OXeozDkX79dRLG/ItrttglsLf+R6d0xCEfFoBhPJr99/3ptY/lPlzdue+CB4IknniD8Q77lPvTQQxg/wgl54OZ5/ugjjzyC8UOEGz8vufeNv/u7v/Osvb+wvd+bwG7+LxR7fwiFkns/gzETv/HMM89QAvCk5U/GzbSg2YQv5+L12U8IXTUNzckMpYxD7m+yGXxAXrbPq8T4iDIM9aJaNvbJQxhjvHef6bomPMk+YX/dtAjRVU9phDjaOUooMTwXESSv/yZ+G3wFHUaPoucQAi7aTk2RtAB2olUWWbtAASadTMvBSMmLjZ0ovpcMwkB0RB6JIkFO4bC0JD6nVzt5Jx+Yru8Fo8EIyviFW1OSM2DacBGUge9vup6EwjaJ6B8xw2aSWJrxnO7UCQstS5MCCDAiPNfOXgYYwE9R3CglhgLsVjA2rCR14EQ/i+8CB3jfc889J5VyOBeUCcIwNDVmEa9W/TkjbKSpqRnw4X2ttmUxLtqe/YqLqe/VfPcVW7MJo7pRqxZvlKGUYsOSoIRJQGvdHVMJMPYqBBvWkJ+KwAEblmB73/PKK68YXEhCKKWSMozXbY1S6ljvBAy06Vfhb+BHcgn6SGfQN9C30X9D/wjsnCiCkVRVlxZl2076rNQWAoYJrwvaPGZkJ3Wm+RCrG1vYk2HBs0SyQVpbs3pppPzH5WULUjano2TV0WG3JN7IThyvgMURKI7HwWjk0URL1z13kT9iHSa0Bs2MJFxkObFFmE5SFMORy5xkMi4D9exN2RO3i8fB30Cztbq6f2tllYqoqVZX92+trrSasFdCrTYar62NR4SfFx6Pe5cvNHBUIJhlaq0OwN5fYOqDlFyeZQTzQDhCEulqkikgFGOMy2cmITCTGMCVhNmmyTF3XMtoD4c8qkxsy/FqhCpF1EK3f59xRCG5DrnkIWeixxQPOZfPu7/Tv7u5241Ho8lud+PGbjf5/QYuL1eDwWCwWl7+VnpNiOQJM+x+Y6wlmJJZGBOltk4RCSms6iR5Yo0SxQH4rT9PxMiEMTexhVYVgvtCEBBn+SgWlJ/0BcsvGcb7dHiJGXY/ZBknBSeGoyBkPCzuVYwYi4TgnPzj8V3JiLNQcM6Zu17L/gP8NLw/uBK1Fus7mB4ov90p7jAqJXgxAlPFrBPf1oihwLlvtyyapGDL3b05r8k/GRb1xavw74DWo5cPAfMM4c5XlEIAFTkJUbzyTsA8Bxi+fKR1qiCMsiyMQCmdFvqOO3SRaqUwi5LUe1AprKI0xdLliPnsGmhlEArEAtAoDddmOWLuSkzT6OxpiLDTHo/bHYzCEPIv/MIcwjCiSWcwrCqMIBCBu/2f4B/hVrAO3hC8Ofim4CPB7wcBzOumiR+dZEYxlr1ABxOHtpHSihg0zYoAo20j+ieCv5Go3Q2Fi+Q9hzs0faNL7E2NOjbUNZvtqqyqZHeSZ3cnheFlqGQ636z3fycj8SxI2TfnFbV9ZunjPGDzY0ZcLXdQHfDa/6MC/oM+PHoOTvfOnZ+uADlrdy4BojFKKcbC+OrhoUAWtdutStkwGoUyzYrcMRR7exvwYRwrA4siZwRw3N+vB0O4dz6TPWv1e4ALgJEAcUg5ZPlcgDguKwAu4DxwATCdrIS4MJ+hVWEYJ4NBu51GcQ+ZdVFoQAiupLSOgZRZOgbGmVFpu7ASvtamKYG1g9NXTs6d299P12AMIyEM43HCpCAg6/qD08evXO3+xblWS2sEFIIgjrNU65AXeZZDNBrP5n2iZ59vaw0AUair7ebhh6UYAwhBR25cFgwEB9bpzIQMhbgyHoEQs72bL4usY8DjOMurrHsB4tBraUEq4W2qNeMckiTPDXBnlc9MGJRNf5Wvj8gzg85pApZtrHAqhoWtdfANZ98Orzr79iiwI3jV/b8PHbx+81wv59xb41kRW1PmWTjTYchm6Pu8Y0nwfu+z0Wf/pvOPPHddpJteL8q1LqII2ekTeX5uFLeI5EMIqZh/LLp9O3gc3wRBsApeHXwPag3dtQVKQ2u7ahYt3s1mkQofChnHi0YKG0fT8XjvuGkWzbibpr9Z2dzPkA3BF3ujAqsXz+vaPD6tZ7I+X6cWTe0COtesu9Vr2tbCKQKEY8sB9zi3jvM9BObGISUZX29r21N4z6AZmCFw+2vdO2vb0w+2rTkFhHDsOMCMcecYnwFwN4oQ4NTY9t7j6D1+XmC4qUd8QKBgSx5A9IHi/i5+HnqPQ72R7/+VfgcpP5F2gs8O3sGqDXkZhCyM+CQwXg5GKjE9nVuqMwUPv9i4c/PNAmWYKw8aiGekUE8mNVu6zLOEVF0K2vJT260B9x2UrzYytjVM6hfl5Jd8uHc6nwPU9fZ0NsMf18Zk3TRhQAKmoWeCbB4aEq4GiJwJcs4ngpAxZJyZDMn83jNAxpQWP2zdZrZfevazn12VeHJyx43z5xBPzt1xMP3p+YgvPKVA8NXs8xpm89MHEFH5LJMA6FzklSLgoAA4x9xeQoYYz4xRlAMn5e4APsYAyCIpOPypMZwX9VfKsnxkdnTHyTHCuXM37zg5xkzWJfd48IbgX4IA8LAygzyj8r7WtQEE7Tha/WBEGY0qxC3zgyGIsZw3Wv9Y3Emj3DhRHBVSTKv6qK2qdyHXBUPmRnf43Ijff6v6XejYkWNxmq2qqeminAVPNivb3Wo1hqnhujZ1U8OtHuWmL2VWWFlKl+VK9WxOvR7lZiBVnjlRSVvkSvZtgf0vapFFFbbu/4jl3vPnz+9YnW/DpK4Lf+jLvVkU7vI5325FXWyiaLZXuUNXCWaJJy0Be1UFMBiczHs97SVyTLjIBUoYFkWhbZ4r1bMF63RYYbtaZYVVhXJ5KlXXFdTvU+F6SueZkydx3G7FcRy32nGchGG476vpPI7W1b7YbkVdLpNoOi/Dgyiv98J4nddifU6gyARLQaDwuterT/oDqKo92Uo4OSaKIAgCHqiYGt4zs2ARvDF4c1wNP1eud1m3rib1ft8W08xvs51cXNCsAQ6wKsHwtbf1+nU73T8PzZtJ7Rv21bSQTZ1R1dxc101tG4u84ep9KnvdhckEPjUe3HEnwLQeVqhBY5ZnaZaDBtBUTBaPVPTKrEINmsWlF1wFgMQYwAQhJoigetbDd955Z5oAwfs56K9khir+Q3N49lu9zeaOT+n/8lMIHu5BQOXkA3E4HwF86fv++uk9OtftAl4AsC5utRCLg84B0v2fOfuVp59++vzY2cWlq6vlAANC2SfgH+A/BJPgnuC1OMap4eZE8S2cK4OwyQDlKglXbrFpWikK3pyD1gbLBzJiyVKnxIOqiIFIqmPCRiw+qpbp+6lpB68fR6GS/V6v6nbal1a5lFXrsNNuC14WrXb074mKPJe2X5moKo4FA2BGp54RkrSDwRJ2UacjhTV60Cea7O0llohxpZjgnIidfdtwMIgkUnrcalvE5uqVq+PqzQfDUeSSxEhCFGOvlS1ns3PdssIsb7fTHyHK4lgyBFONx+O2c3be63dKp5OkGKxWV69dnk6AMZH3kA5OT5tx5qT0oXFxHGa9XvZh6zTpgghgyHgvpAADvH0rOINbQSuog2And3La7Mq+bptC4qVNMyUYjfz1Vt582/Oe97zrj0+KHI4Orz2yO3eu3+9PO52wfJ9M/60/8zM/8wvxZHLhWQf7Z8HPgIdO59qVVhs+VUev5zj5ygTVptjQMWq2rFk11BTN9M2fu3vkJesvWV3/vu/7Pjj8QyjPPvxhTttmuf0vwWV8Cu4IVHAleFbwWPCVwXuCHwiCTExJoI9kFSu9GHZh8dutzoO4T7ZzgrOvrii+khrhxkrGAMQy4sK602wqakAbDWh54EHUZcMCvCdHq50iLXz0+mnVIAusPwUCIwhNLl80y9UXuNx5l1WzO8W5MrYfeSFCqZTVQjonhbFSSUmMaWvvV8XAOCteMTgcJGmS9u8bTKfTA4CD6YcGIfTiqNOOYujyVg/mG/C+VG2E3sSY+FWld3oznMLecEUi44wLGIeZjyALUySvZRyw3R4MCqtUon0yjIFUhtCxeRhTZtpgyGj28Y9//CYkab+XJtCB+Qye8YPQqp4onHcuz6Blkc0z6yqh1suwXuv7wZr2N73hDV+rC4AW77ZP4nfwOnwgMEERnA9Og9cFTwXfHfz/QTDLZcW9r3JV5XdWNqIIld8uFcK0Is+KOzgw5ATxSQ6sfzn/gsK25qJp3nXTNUqZX1sdILBaby20NFWM1U7sboNrEjH9f2LL3Q7O9Vut/iJtQZX/LnA1Vem618prDZdJKpACQSpNo/6/6GdcqtxqxqwOBedKMy5DZd4JzuWrol84By/EeWItZJTknRngqDD5q4qiaEO73EMWEjHWN7M/7MIOOtc8YK4Q/H8/ez88fvb+3ApblS80JgRj/AMgZRRKAYbaO8uQANK0KMIEOUOYRFHCtrlz7zzvXNEaastMC4lC7PYA4vjO4cMPv1xEkODkSb/p47q3b8Gr4KeDTnBHpO8ir9JeFAtWc8KdZZ5Dyyo7VhcrJny+Smn0ps1lvICxpjCuS4w4mwHqLatS/qyxFsQ4MxbQWIPE6O3t+cHeIM8VwkFRAm93ppMhhHZ0U8DueNztas5Y+t6qKBhyEcX9r42me+OyKAit7d2sKpfrMAwBBgDGRC70ChAIXrMXxwBcMCgmk83B0dG87gMhQGc22z+Y9rvdwdnv7a/XJ+3BsGqxs5/8oePz58b7m825vdmsiM+fOw6CIAz6aMTs8LbgweBLgjcH7wm+P/h3wR+CghE8C56Et8J74H1BwMFIjqxsTPxKl4W4LuMmnwpvQMhWBDjAYrjYlwA4umi3TZgkYstsiyIHXNeeTjZxZbKF3e6CNAFLfMR8oJJqG7a7cSftbisxJaFrOS/qNUiFeFnPZhIxapoZDcxjFBOe1iya2mi/2djTclJYxQyKqmqTbtp1ct7UzWQqbaTZ1QJpLzabqvKhC8XtZFkGJndsUTTlbien0Vw2C/QRpnWzmEq5KTaTCuXsgXAcv6lRP/lphTujbwWXibJEpCUhwMUveiFHXrNITJiOOQC/KMRFIS4iO9/xjCiNE65Qgt1OOySW5sBIRZL1YMdjlhpgCIiOR6FZPwEkjoQHTfIpnP01XRUJKLvCEHGPUYxYUFOigL3vWUBXGPuyPiIANqMTcPCYLwCKX2DsCg1SkdiM6Cpihpgh8L1nADhwd+zZv+UAdJXYFYIHAJ5Rk6sYSlYWFMAYb6Ia2sUY4CaAZuYmwM0UmGbypmRjovEDjzdR8lQngeAAIIc0QUTSDlBKmS8/NNK9BP62clogAndgObgGRUDwdQz3APaQvRQBoEB2zFEDaOTHDJOmduSlT/7Yj/3YkNPdw3APUQO9hGOO7E3gPbQ/WtImlgzBQcdNEQuiKWKJ8NTLMGVQEIQg5Z328T33/Ain45RMkQC+/M0AEKPVI6nb/wsRPhasg1fbLzPiJVIulePSyFzgODB/n87r9WaHgrFRXMcbGRgzeOE1M6Gv6qRily+/8O5LF/drFx4ePuJ5t8PdTLA0HwzKgjNnq1B0u8zuTydlwjgUwMejKxzKCvl5xLIaDgct54jvM6gqYNvJxqjpZLe765HTU/rYq2/e9KrVXjTXHrv/gYnwd9/leLw/aLcIk6TXLnLLw7vvNiwaDI7H3U7MCIhJtVs0Q+QXLzHqXxi12ownYavVO9dCdukix/b5+55/eXG+01b28pWXBEEUBLd/EwP43uDB4KXBk8HnB+8OviH4zuBDwU8E/y34jeD3gr8FDq0ggHm93S1W23pez6WZJbNEi6X20WqBiSiXWXh8FoKiQaWrTAzEfvDYZmuvAqCKu9DSwxMSW4AQSJMXUghM59dea+uymsvtDuqIGYeCTJZWs5klFdgURd+T82x3aZQovOrquW/IA66ZLGd+007o0sMHk0I1sxaiyPuDsRSMTYfDIhdCA2p90G4DdLqHtr3/c1kh8mI4HBMhSTnqD/JcSA3I+XG3C9DuHL6j16q8Y0wBjCd5JcQblaoqYaQclC2lpDSia5z1VVVV3jpjnPVlq1V668y/l0rLqqVUKKWSrULqV8fhYBBFb/TtzgAJoMonYwRJzLWkmPQjBkUxVdpEkXlje5gmnphAHE/zivN2HEVRFPn4LRi5qupJUWXTMYJkKeMmCo2Se0UJUFXzb868B/A+y7wH8D6DCImLk/HYWWP6QjA2tNa64fBIaaIwL6qqLCJErY8GA2eN7SMhSdE1xrrR6FhKwLAsWlWRR89paS1Ut1tzrqjX5uLXvENeVqH/Ek7ee18VdxVZniFmWV7kRZYDZHlerLwvKk7eP+i998Sr4vOTDCBLrkhjOkgA7R4ppWbttjz7B0SbuzSKYkc4Go7GLyu9krLV3lNaYa/DeDvOAbJkkHmhdIuLdp+kEOPx6wBGw+EI0cdRGMeJj8D7LPMewPss8x4wT+R/Dp+CjwZhUOX+xwfgeVg4po8boshOkqqZcpn0pGp2s1CS9qpqdnD1Ax/4wEPtL24/9L37BwcHePBseK0x5iP5d58tP/KRj5jvyeCjjFtVfvhh+PTZD7z5zW9+8/nhcBhfMOfjOB7qU9x8ldb4FDwYnAavDn4o+M3gH4KzIJhRtdbabEGsCMTKZtEArQxrLsk6Zb3GLwYVO7cDcRatV17Bi9mEhJMSOxHoDZLE67nA3decVyy2U6cP4oNRvhPp8WKHO8HWJs+S9WZehQkNkeaVuhH1RcHA+/4o+SspmGtL0U7RGpmtrlA0MNWc1VelnOIrAeEwFzkCtFoAkIn8MBtJFUQUCQmvJVZgGidFttdlfRUSQy+RgiIrChfH0SiJwfv47NskPDDujIAHucgQqgowC41uRVow/GNGJaZJPMU/UgzgfQTolP52iwexrP8dfPwdg7KEspwMOlGajNVLAZJkPJBVDy78QWRdsqAWtq3z0YSQJpFzvoXQpkXibKSkhB4IqUeAwnrfSzH0ZWYtB2CMSw/J0AgBYViWxvJLEP4bWiTehkpK7IKQ2juXLKgFLW99NCFgk9A718JvbochAE0ALgFy530vxdCXmbV88pXvgrKo66JMuwb2QLhxUcDNIfZzt1v9X2//D3wT/ESAcA2eD58Pb4f3BsFM7HYaQVG9VsSHJqupDpISslz1nynkrW9yfuW2icaDCmMHys/lpBByu1mPJTjmYjlvAD4VqqlMgYCHf5Beia254MrcvJts5U5MrXCq0zX9ADzpDZ4CA0tw/dtd0Sx2W6e9jd1ZJWwIuMWY/K23mdfrzaORxQmtWS3frTjP5p1GamV8TgZv/8DtarEriaYcCDeAzRzt9W6hS+t3i3ZrL6R9O7ovWgvnAP5x2EUuo5jqjfWmYAzIe+tUJsMASZd+DHOotNZcMHzBaIDwRIQt7lfAIoxjC2GPmBQASdlKUym7vYsPrNfWxNHedNWPYyaQCI2Oo+HwcNHr6/D0wl0H9f5wz1imur1+7gEQotEodEq5US0HclZT7q0gENwomSnhEHEfMHJSCgIQmdcakJFAFEwQZZxJYRJhTQYCITIGGRMAPaFTpZ0pkFf1gffc4SNtHVWcQ6iq47NHozjSmlhS5SQi1AsAdvB2RC4lFwCSCckTgVKyz2UIICTnApSWz2WaYlA0u7oL4HmemDeI2nnDgBCENqbVStzzVqfTY0bgxITgWV4UJpQAIDlA5qLQGuAilzpllKUEzkYqQkTE+yyJ0zzrmCzttAdTolbZ61ctiVJyRUxIpQSHODs8ODpyrgrLsj/p9vyo3c68BQBRFJ1BlpHyrtvt9eIUC1aRIuolaaIlYuWt9d55TuoqA6LZ65Qlem8sZ0pIxgqleTNTV4SdiKLvJ5Rm4L1xiK18QIxJ33HOMpGl3oowDitonXeLEt4bccFFmiS58yFaHeDc+EVMRGGEWVo5Z0UiZVHqDQTky5JCKAi1pgxyE3KeKEl6OP234KkgDLq8FZLrtnbWZBk1Jg059VFD8MpnPOMZp4uPfvrTj5394mazecPrtx/5CDz1ghecPQVPjT7xibNPwTigfO/rR+X/2kkwyFafrxvapzQTEvIZqdYxH9h1Zj/54IMPzufzn/u5nxt99KOjh5qm6XxOd/Hmf/fYY39+//33n/35y14G+dnf3rwJe/ZIcsHz8SnYD8KeezDuKLgcPBG8Ge6F53BFZnKMnVTNtI58GylnNvS+WSl+ex9FM438balopkaSTYO4BCTplnVrOH41i6mgv1GnNrZmwpVsBk3Eq9Tq1R12fpgThVkctxJ0UtmU5ldNUoUTOSkWgtdpXuVV3bxloCjZzTPQ9XXr75QiLhh7bE4bu/8beZ1YKzcwrtu934HlrTsg5aCKoKSYa56vy7JsnSVXryYnWZbV+edfvXo1OTlJrj4cRT+fHrzi4Ec519q5MHROa84518oAujB0YjKTOY8Yk1IbY7WWkrFnfq62xlQkeOkL/i/AjRvMWIBWlly9lmYV/wE1wvXrAP/3BRrAOgDzLA3WgukLwYWYSyE444yDEGL+tOsP/FP1s8ynEuj/lud5lgKmHz48PDx861tffnR0dPTqt771rY8//lb21FNPPfXGN77xjW90bjXz5qNYyW7rSVI7F1pt5rzfaGu1EZ9jz4TR9gkppQkZI1IIXvDOwVvectDhwgMqYsRCI5HWvRiFpnRmeoOcWqGUYcU0knScO0moWfX8pThpA1YT12Lk7POPjo6O9vdtWUwKvhKfgjfCKdwHj8MXgM0x0ABoG3De8O0aL5o1AwqRmNrhREqt5cQrsCNYEUlTOJFcvArZK9RAaj0FPJILdnOi9cXCxpjOMdIg40h4noFBU34EzX4yPTy7Ws+n80a6CbekxRjSTIS4qkXyPfhOkDRkRYLdyRHxnAy8bGYYm5+n492iMcFghot2+Rgm5X/Lu+1mUinhdlFe0TLR6mK33fDraM7W4WbRzLA+yAt8FwhCtef1IlYQrbBetOVuYUYKjJ+K8+tK00WDTwFnoLU1IITgIHVwJqCUhIJj6OOI8xQdlaOxzhII5wTYMSpDrqTkLoo4U0p7LsBYzhjL7jTS8rHOSi7QOio+tJWXhqmQ75Qs48AFElugE6PII2IUOyddXqXqjJpFAiKp+2FDeZLnECMqJVWo8qmSMmRSpjyB/u5qF8paACnJu/woTcHoqhuGgKi14JAjsSiOIiD81/+ExkiO2Ko6h4RzLhCNMRZQSqhsHKFU6Kb6hHq20tyVW1cr+GnZhzQMAX1mwCqA0iGGkSDgoipj0Ho3zHDhfVnYw8kAhb7PYE7MBGGUZiFD4uFgMEo4I8EFFMVsNh5hbEQSlCbmyjLgDDBNJSI421r1KMQw4kBpqiUAV+1WCFoDF0pFcRUDTjMPsCVV5kV7kk8M56BBCiKlpuAq46r0zoLHYpJFEWCrigwuyiwICUYpraNJWoOUDK3Fi5QkUt1nZlK8ZQwXWksJXw7WSmF9WaUZRJ0uvaf0MVdWARrbjpSKQgptY2fRv8F7Y0F8+xZ8HtyysS6ZN1lskge3W+F4X3JzuVwuX7larVZ3rsYrlsvl8ivgjrP/+PdnD8K/O3sQ/t3f/31gbp8Fz8Cn4CDgQWRBMn1B8Nrg5/nQBVcs0bz2rNItd6JWp5EQ7jtlJeXkIQMvSTJxsuxP35NyqjSFZub6G3geGNyPSBs3q21o7jIFnWdpjz61CH6GpzDa2wjLru3gd2X1Ns0hNoXUmx5896G/JbNiU5Tqz1pVc7E3753P53l6ITuthyfwbU4r7HYIlHL9ixcvXrz/4sWLF4cRWaI+8hAWLoA+SmJ87jHI1UhCIpJS9Lrh947owkl50G5LQPTu8KLRZZJPGKJ00B0Yk7fDUa/rHU10yJtc9OzvJkS8PPxZRDlxbw93GcA+7IIxBp6O7SdBSiNJDCnhbY888tVqYTqYn2AahmFgjLGpG6b54KeZhp4xDMM4SpKCdcysAWA0R5sF0zk/VA6ADYaeVPLjdS5cuxnVSb0gm5qFZ9wZHeZJ4dRxXC0IJnkfJsFve8NGsX///hnfw7b7/reDHkpWXL8Gb4Nr7aVN5NfrILknhrj0J1x+9mMf+9ht+/bdtrCwsHjw8Ufh2t5fQnfvL5966tZbb731L/8yXnK0l8cHUYVRp3EX0FvRLvoY+lH0M5r4pjpk+6Qg6LERm3cmjH2d4Pcg0djdko1j/IOFVM9azljOYhnZh6BJ4Z+Qc77HIs95ZgYc7DjO+cfRUL4pwH2jmdXqcGqG0Im9aG4/Mj8/bxphpHHTxJ3ObYSQ/oKmFGOGrl1cWFhY2PtjO4qiqOq4YFl2SMBJKkmF/6o6bcsJML7RcVotzwuCdsvzUlMpuBluBSE0n3wu1XC+ADJOEr0xyasom4OwDSGFNN7JktozY1nTtA8Hhg7AOsTf3zdN0/zEAwrwLAYwj2qa1lMHFehz0rTiSGmMGTpYMzqAYVQqSjGmOhlHZ1e9M+MHoLc14NwWmmsLUd8muv4H2kgjvj+XB+HTIHekoXueoUP7E7Fgxm+GL+eaAxFOyJopVli52MXttjzkREZuyz+Fl9v9XufIkVvHY3BFXqHdjEIA265052Z7J85eKKcz59ttBgOubq+NNeW+rwowN3dyuV5zHF0ZRuBLCYYZvKvVz0+NGw3HVZquu9ts9g14Ab6AOr0BgmWGzXweUY0hkHiMr0UxSNmYFruu9S8QKqbDYSwBXLdWa7XqtdmZvtLq7VYcwdOx0hw7jhPT9ywLz8yW8IQnJROuVzHSmZUVWwL15v1NAmQ03LevtwRSRNnSUpZhqNXmZucbugEICWQhwI/DO9GALY2Tv4W+Az14GKH2HdMwI9UaUkLzWZaoMvM5ev18nPvI2LqCi06AtLksK/pxWAzSRqJDRJdL42LizvfAxGbmQFXETaRx0OC8tpJbX3byhQaZJeOqnF6xWTGpIVvRnBfT8oQwE2ykLN0bDcvx5LCv/Tx5uc513KAxSjc0Gb8ShKxfoqWtSB1J1PP9wK//Ig8lprqT6WRytUcAvCZvX7zFp9N+ykzCiO0tNzGKtSwCESjmf6AGRX9iEUGZrm/utFrLgzQ9fwNluqBsedLrV1MMIQBnaTKbn90GDJ+llIZurg2nEroGTOkUAKqdhqWwMlqJ26q8DDhMYsUBmN4MXfgDALAsyY1hpVhTns/Xarnjur4ShPieH3vqK5U0SQGwqwyCCeE8AzeUZD31qGkYUm06R7FQeuBHwG4jwOnxqui6QkgiNABGMOc+B3iPH6hEr6OGTgHXG/kvjZkuEoZUwqTUEovRbqYonSWEY4BO1o7yT3OKCecNp/anlKg2BqZR0nSN8LZTKqz62vsDizojDcgCJQK0V6NsRuzNMxwDiASvhZWk0hAAcxhsnLiOYzdh+JZYlhBCWNYcMLLgOUkWYh4IpgSE1DLkPoECMO7bdqQ0Smx1mYmMATwseKAzDLsYDOQXHaUMRGOK4bmkmNF3CSAWLWqkaR/ZK02kYUS5L52ZAWAukiahGLynpxPOCWaMkKPHOGeMcyDtkxhjEjBEmrrtAiE0fWq9eymRIufSwDYJLoi0kteGsR9F/wl6cBG+B6EyjbaBJp0LWcXSyS7SGO5jOs42m9l9TrPnSY3aGhvfwn9uOS3HmawjBiFPAfnieHKUwF4Sil0UKPPfzWg4Gk6+F9EwbyF2+dcNka3NYL7X5uEkDMJgZ38vg2JSDMPB6CATd/LOdI3QYzIuBkUDCA5Qju3trLPB3q9h+t54S4xxOmIclJ8SoC0EfB3mU4NkhIRlqC0w/ugDAV81GK3SePLd4IaBZFSruhZ8SgjXUrz6WHJd6QRjImFGaKrvD0HTHCedqZ5qF15wKF0W6YwkFcYA6DVdVQx1QjUpJSZAlSLwTmLbrg8FoDIRggJYmsKYYAVgGoxjTDmJ99ZBUpOzLEdy/L2U+bBSiOqJrmFNpYTErhaDZ6WztSpwTQI8Q+nOkSicmammKyNNozS7HCXTg60sDBkFMC40udVcyBnh2hBzqbmOZzMeUQK+bXHOMZc7XR2MOgzg7w2Dsy42AULLMo0UgwJsEcA6phRJCLMK+fuGECWlJB/Yiy+ntIJJFPdzxijlXAJMBkapAABfyP37TIPgPajCeU0DiCthKAWl93uaIEBflEq1JLcx5pIWAqxry8AwSWiUkhA+vKCIeNZTbpvmPT/3cz+XropJG+BzHnt+FCQcAFfJwwd6loP8z4BrIPmzlJspY3h9ZTAeJDrPckdeWSkhktYYneqeqPR8oLq/JzTl+0eyfsbClDLRDxRW5fVrsHJ9h/wBlOSFX/gij/OYvYszVj5+8yf0a3fccccdwPb+5e0XL158/fWLvn5/X/8mfBYlaAaVNi6VeeJiReRyVkx86KkkH2KqDN699yIc2XsxdR0Ax03hSPLoSSR7f3L58uV9j5799S/u7OxcvnbrW+Cz4Ljp3osDVYEjqevALU899Z737P3vJ5544ol3v5vXpvTLcB1+U9783CVU9uIEA8vUlOV4iDAVtI2Ro7CAjoRQ+BB7MASdzuraEVb7b/TI2mqnA9fm5+d2b+y1lzhK68jq49LVIw+/9tprr83P3zQ/f6eoO3GEoxa6CZHraZaR6RHDQCN0r4fc9wcHnXMmg8JmC4J1wAHo4YL00qVLl+6HcaoWSK9PDi4Sp92p1TGu1zptJxGvPNRr0+n0yvQN3ZAdqp4HH6g0G4Q0G5Uk9XPPCzAVlaTRJKTRfH40sYt1rkQJW790PETRuNQt2kXoyfoR4P7bbrvtwm1gAB+/mV+4cBsYt+HLvzKJ3w1vRRbaRE+hH0Q/jH4FIX/sAhTmLFzuCw1pbnfuC3YS4QtAYLmBmQRyXtJifY9U8Eq9dpz1s44Y1AbSEp8c3yHiZwfC7Ut5r992NyL8jDIeNFxAGIcMcg5dFDnzVIHtxfJ/JbOEzJJLSbca44fPVADBOx0hMDhVUoNvq2TNULwSNwngai0PiK4T1pq4lLZ7IQU7TgIHqONKJvf+za1UfB/ILE7ay40mQLOxnHoeuF6a4Of4I4bk92gGw5RSShM6hHydkN/y9LME8N5/IeQD1lKfYbpOnraBfCALHon1RGgcwMJ0ESsbLCup27E0Lexi2nGYpEqlgb8LmhbFsy9gILf50GwsLzUb8FOen1Q9l3HyrOvBP0ppBILaNQ0pOdzKoArehQfjwYxPort89IQ/3d8hwphVNIogiYjQ244mHaFEIjUvOK+6LKLNXlF0stLKO658D5XFsIIm6WdZYaEB6S4KWmsDTLxedMSUJQM5b+DkXgBs3XLw4EwOkM8cPHjL4+d129Fjc/MA83PHjt72rc77uePElFmMJabJvqvX62mCJ55vB5RaVutI+1d7vZ7Geeg4SYP/xFDaY4QDpqzOhd9rf3savy3n6Ri4JQw72cxM1slGj/l5I24c9fvLy/1+FP/26fSplDM4AowlVxYItv008Zwff20BsJSO3XeCyGkqRTi+/OMPD/3jiQX/7zdmXH8JvgMvoAKN0HFrtaaNy5BBjKvT4CDMoxUpb0Bs82FR/86rRtgrrQXWAGC+2wvDMOx1548tLnLAlAbQapflwUNl2W7B40+/Q1nGKYbTzUpi6JxFUb1WrzluvT5bhTDo9Wfn+r0gBDIaHcWY8cXx+Hrw+5SKMgw/4bi1Wr0ehZwbRiVpzOZNqppA6Pp/x1vw/WgZ7Uc3oEvoUfROa5i02NwQXuUoPsOkj/DD0DEZhXPOlgGbJHYS0cDGnmuwcQis8o2ZTOMxsPPMM8/0alVNq1Z7z5Z2xl440WxphGit5okLJaCHZoZ7f0O+QL48OBDyeUo//+flwvdHUbcbRZYZfic0Ld/rM9b3/Kdye/9ASExILAQ7+CB5OyHxn1ttDoXrjyu+/s/XfxPeA9dQF22j+9F3oY+jn0EvoW9a43WTHK6ywRSmzQSSFLaQgsaS7I3MaiEG0Tjvq4VDBXhxGxFQ0yhoYUlTlPyGi++AhKbgEn8kfFcESSraTQT6iEmh+ebcTj5oS2oM3bbizdhU9H/z7OcQSSEhjhvdTjuoKS3wCcRxJ+719m2ObhYqoHRxqCkpsRYGjYbv+EHvSVpJ0lTKuqM0ApalaSbGJqWeP+YA+yzT91qMcuaaptSWljHgsLm+vrpWNSxLeWa1ZujZA+fO5nnyRs/3BoOJbbWiuB5Tgn9xc//Wom3PDabTPCfYtEbzC81mM6YMzwZ+Od1vaO9nlAAQSgimQnAOmNimEBiMlm1VatX+bKPpuHNpNQzTtFFvP69Jz03TbmQ7oJTjBgS7tu0Hjb3/i8FPq66nYYaBGGYUJftAcCkpxUTnXGACXEjDEA5njm3OGpZJSMAlB6CEM7hLF8AooYQYeqgp9awEIFQKsA0TsEs1hBBcv379z/Au/Bi6iBBwURRcFAUXXPCvrKFpTnNgElADprFHvorAAE0LoOQ1cGVaTkVBa99My0GBd0e+TzEwypR0XEtQTdf1I5PJqmEuQOQX4/GtAJxMmLY5mQ4mRRlFgKvVohyNJtjzwlB3F+lcZRC2+416BD+WJYlJsYoakaXrghLh+QGOoq6UDkgZ6boOlF+WWFGqKQyOTVJh+mI/uDAPhJhmo650wNzrdeeWfU/6ku1PUAftR+fygW90EMCEC49OSRyFefrYzs06E/Oow0++p2R74JrAeu1UnVFxP2fs/qzTybIjKyutFkDWWVnZObiy0mkDNFsrK0cvrKwAXl27+ewGWWC5vfvvv/9tb7ufmwt8qvdnWafzNLTb5crh4ytlswnQbq2sHD6wstLpwCJZXz9309oqgXJ6xy2rq5ijGmOfXo+xvXUPo3j2pZLdrEL6DeLS0A7oo0NROQ6BR8BrwFGQHUk0gGVwJ85PUEDlv/YfKRE7xUd+9lzT8drqzZt57gdwhwiCqD7b6VRrdSIwJpa5uHD5WmN5sHhJ+p5f69RanSiSnAVK01X0Tr6+fhO8AK12uXJkkfz89srKoRl+qdm9aW0VQyWpJGy2alrQ7zc6ESRKsf6pCIL5D2LX3ZyPdZXnELVDKR2CNUoZ01bT6s1rGxiNzTK0N+IB2bivYQmKpTUu2QPUIDA4osqMolEK9SjbEo+KuMcPQB57TTbKRkVhEIst+AQlMZIz5uGmQYyeFIj8H4+tlK3P3LezspJ1YFnMfvPqGta3aRxXVZYtzMVKmKYV+b68fZcEQd5fN3lTyylK6ZEaYWGz5ulxvtGV/Gyrm9VrGtyyuor5B+AFoLJMlIB9s/n3z1hpt17RWbPeIIDNxjBJsbVECdVVfQVEUolj/Ft+w9B4DKAtGwCzSu8tBQGlgFdXb6klG/6b9USkoXfmci0I4BhhmpVJERfCEYwxOymLuLRdZujCpT4dlu5pl0vyx7dW/mRKe2dtjW9tbW6fBRwE/f7qrWtra6Tk/f078/HMTu1cMD938JbVVSzvW2LZVm0lN7wcv8n3VlaJowh/yOOVked5T11WN4+6WbOB8erqLa3q4nYXL6MV2+g84Nw5B52AMZSASpSvi388ctRJ7/zFX/zFX9TGvhOONB/F75ufn58/Mzc3N3fM0RM4CN5Ivsd0i6JfcjJqrlV49On28/5kN9PoOS2tRLspKzxm1xBp7ftXDIoU23yBe2Q4CoLoBgpBUKtV3DAMulTTrJppnlgYByEh1aWlta+88cYbdhQ5M0EYOkfqJ6oLC5ObV1eICLB+7nv7cJ5vbu5ktldUa4YuuLvAOAMcxUk7iDUNw3K9Bh+99957EwBnzuWMFO25pAJkZfXmauLHorC+/56wH92A7kJXl5z5/PBiR3t7rmgUDUV4RRKxwSbh9xGt72GWoQKkJudOYcXtKT00mUwmXlIhpJJ4EASBD8wyMWRPHDx4sFPNlcJDVq/XazGEh5G/zuGVldZdl3S4fe8D94PYMJaWDBNfPYO5qPfx1Q8uYM+Tywdmse/hZZXejB5Aj3F6xBPxnbRvwDLrwMlPKJrIFIMimIxprm+HRRzRATqYRFrERVEw9AKrHBo76fztExblPvWnpr7IGGO2bVuEVSr13N3av37g48VhePxxEDMzM728O1lc3Of+bPSHhJDDmAvOAZQyHFGtbVWwro/q+zeDcwsLC3hpcXnNcRzHtfvz8/P+vF8W+O28jO5aehLHnkHSYMJvBFlfjVH776roFB3BW+qds5T+lNUjIgjj2C5qNd2AZmun2emofWTs+x4GwzBNBkPuD4vgwPQZ+Mdnw1BwiKNmszqcmcE4DFeXPG95xnUphYWiQMvl1/DLYUywLPvxSxwU4/O2G/NZrdNM0oMdR2TTG1aNknxcRJseCATxk2AzbAei46QxDoPJa0vFeBJOcpwXnViLCMWcXla0zPvotmkcOKAbvsaqzjtn8aNWvscZKC129p0l0RmRayOfSAlUKlE9rhj9WEq5rkHGAWfVBOWMSA10AG28aFEhMJGggDImGEUG/7uLccDiXDLfCRAsrmxoABpg01jbEkS7yxTRggCtdQcnoAAbRnlUAigglrn/kg7GLQ23QRlogUBXuG1VAciTwCGsCQAZ3J0q0UQ7dFHiBX2IZ+7GlMI59q/tL6CvUs6y2c/ILj6L6Dw39D785bDY0hj2M4Y39CdcocFUsAqLqhEXye+K+/nUB5iODfLpCHnBnbPP1fAmQahONA0zhjWFKcNKYUax0jCnWFNYpnYzteZHggz7Eyk342GMWQgnWErqjdZPh2EIQkQCQERCQJghzDupHDHfPwCh3aH00SEd1OKdun7+gK6fWVXqgqEByGrMjyl9/rSuHz6m62eP6vralq7fGEsMciHmbzg4C+Lnp7Cef3efQBfQPb+TRLcCt0cm2ikbtn8QxTccMQsjp183xeTI94Os+0wA8/0GTE3A6oMGTH9jdnYW9PLK81euXLmyAL8XvwfMXzYBzCkYv2JgMKdP3mfgmU/d+ulPL4t4B92Q7ZM78ztPpi7GnQ/TpD4cGhhkKEAUKlGBmeTOOfLrBnTnONrY4Mn+u1zRBqNKTDEI2ZilAEI2dE3KzWVx8gZZWBiPFxbI/YpTkNa9vl1pNslS4iWNJuHCfHi5oA8vjNtCp9Fd6Ar6EPoI3xU0uQH2vyT4Tg395EJaKMz44cbrdtKGITJF3TKIRxWSUR5zC00jQG6SFwSg6YTFg9X+ZBpPCVOlZXNOZtuwZMKsW2aj7BrwizC+syzLsqcHC0kY0g5tzkAYbhsYx3GtnbQAWhD1ar4vwLEbeQwNYJu17j17T8WmZZlxZFmWFX0dRr6UeDH09+7d3d2NwmwuDIJgvhJFvC3CMPDJpUuXLrEoikIC+OrVq1eDKmhaEgJ0aCa13PNxeuYnXEdTCVh2hTLPNAHXlDKsHUs9Nf3KO8CyksSyAO7XvryEQUiVAjCZez4EYbcVBqD0xGNM6fWwrmlKqyHEkHH9L+Hn27zSh9B70fMWWkwAEKItKUkGg1YcTo1t0c8y5gaQen4iRMrFLST8GYclmjkgxVKxPiEVEZeDUnkTQunNfp4/uG4RxHkXrMGa14GLyTBOhDwdlYzm4Z3j2OEmVjNWRCBExBIpNByM84/7JeExEUVdTZmW3fQtACxjbuqUmsImBFpKA2JaoZYGi0rhmCmlCCbMIEuVxe3tzTSOLAAMDtYNbkN2Hdm2jU2IGaGAgTOoU/KcFFrGmUNYx3I5xZgyF6TEGIjk5zCQB+cnrmOnowpUxB8xosiltNls6hywlK4lPQepbU0+B+iGtoXBCgdFMd+u+57JgTKV1DZOtHXDFZz7Ak7Ve4sGBSMfrI8/DAAhKIUpYT2JIY2W/zQTepUyn9Oqa9rTvQJmgtIwoRQzfplQSt4yS5A9zVvXX4cvwRfRwciEw/5Foct6O08owAQGIsSiWdDMC3NnPu/D9xPibtrldHJ5w/FZlVd4LKFMh3EpjWqIOwYhfAkc23agvbKystL+ubfAaByPN+f6YQAQR81WmnLYXFoOCJ5vNrkAOLG8vAy2YzuwNInKy0CIFTZbvmEEzWZoYwJgDmrVSI+eYZRZulGtDTRtbWV1bt62CRGyx5imdYUwASiPwspsnpPvfiKRmlL1/fvrSmkyeaJZKZPEjqAaBFWI7CQp41b9VPwGPtQ3SB6GG9Al9DDKVCRFtQvx0BqdC6BQlhOhy6LCkqJ8lBWusY7Ek3AyxAPr875kOcb8r8/ZBB+CvL+zffbc9k4/B3xg58F7u+2Zxw7MxpW9RbJv3513rK9hfJASqSnAYRgGGIdRFOHfWel04K8tvek4nlczDKhWq5JzWqm+Xi7MpylAms4vlMfGE3PfJtNOPFHNurPWSr+HW61DJ1oEKKHAWRDMzfseo/CK22zN9MuyBKA0jCjDcExwTiKEEKJt6vFR9NZo+U27egjWMaNObuDXD0fHfAhYxZNiSF0YJadWO/mkiKwqhsGiZWI4YE4GZIgh9DYDRZr0qrDoDpyKUSbAbBBsM5vwq3Ju25ZdNTRgVCeEKaVsg5KqyDoo1TBJK4ZWcWzQdTcKDDt2pRDS9wQHxZi6DnwR3BC8BuYsecoUyugC9AUCpt77eQJgu0uwZFMKUgKl9lWbUOTHVQw9diyT9UILxPuVZraUwiUcgwCqVi9Hq4YYUoWpbVmLcAig06lXLneu/yoewVfRFF1Cv1bPIwrAm8KiQ2ta7mPkC7BwWOb+OeKjmoY5HGTZihl5kY71I4F+BlkhCbB0oe7LTcG+wY24KFXHfSEaFY39DExGqHyD0yBMHL/Dsez/jSD/RBE2PB+ajaWlRhMgSfLKgNCVtYvDkW6eOHGp4vub6x8ORb+7uXHkyAGKPw3m7OJic32nvA8T1hXU41g0pE25T6igQGyK35vU+gJ0Q1OWRjEQjJWpMeoAACjGTEm0OaEywICViHRFsGYyqbnK8AQAlQajQtPB47wDn1o7ZqbVzlKjCdBsLM3W62JrmXhmePToHXeurTKgWAaTj545utPrEZJhsveka8Xx6KEHzjJC+GCj4lHuTR2DEmlpknJXEko8KXomY5qkRKNMJwRTSXgDA2BwAktx3bZXckFMAGAiSJO6JaUZ+HWdYh8AQBBCmSDc8DhghBgqc/8BsopuRg+hP0L1f3KpxcF46Hpj3bEH6sAQRxqzAxHc81nn9H8X/e/tybhMQsDw783RMLsBw7+/s2Egcg+TWx/o4A3s+A2GLLK3aRTDzccnXdhYJ2R948L9T4Vf5dbxTScsu3FSY6ZpGbSaxt1p5Ow7bvFT5zC+8fRQ3+FWqWGZJqulUbcMnc3jpjh9I8C5UwyLnFalHzrcDfz+DJLhsjP2zsxk/4WNdfJDSfymyxY/feNsLe5zZ/ynmhb7SWX4DZ47xa3j+5xomkVplZrmN4Mt/kBuw15Mwew4ge1KGpaF25ORkhBh1LvRkOzMl7vdbpadD4JgNApmZ89kWdbtnp+bm5sLR6MQatRvlX3X1772tbW1r/3x4uIyFVwv4MLi4uLiH39tbe1rCOloe/3EHUCn0IfRx9Hn0Y+j59GvopcQegxunoFsDZWOKenCA1Avi8NJ2HSTZFzEZhIgMhdxYdPXRNkTRIdbPEEfKA1EMNoIxsUnk9bdGxX9vH1t0szF+9h2Gl9tlpJXhDCCWDTuZ5kXFeLhNsGhI9uPXu7aUs9bWF1ZXfC6y6ZjrEfrkp47R+V6tG7aTfvJb6lhN3/F87yaSGRn7/mOTETNm5Odb99hwTOi5nVksvctz/MWVpe73+4u58MvHKenm+bZ4FPzgrlKina7Pa076HHak+3VI2++1WhuGvHsTRikaTo7d+H4+ML5vfS7Pkv+/F56fOFL0zSdTcyypvLc6e9hAN+jO6LPsvsf/1TwvznbQVCTTSETjCQ2lGHeDgFVtjfNFItgWN8z7OyIQGG8Xc3Z2DA/IWhFy8hMYADLBTxyAaMCoCw1Fi0ZYphGqB4kiYgjxbW6uU4vdj0f44maQ7oCDyGBDK5O5KLJyZxjiYRUQPhlZY8UEuDgHN83iwMmYTXopOyX+ScrJGQ+4gDH4HqmDKSwrhP50EVJ4iuuO5oi2/NmD+g6wZ7xPRuR7mhe+SSJXOijEQfs9adE+4eHnTAzvd7htGpp55zTrWp62OuZLOwcHu4TTfs9BJ44C2BdkjgLYF0SamN0wFKRDlOwxHv1vyEOZehHeSGiJIlEkY9CL8O4V2QDUEopGGR5H76n2+0mFy8+0q6SjjXxHCQipZKq/cjFi0n3G0n0DG/7NAmty0sBdJDNJ5N5dkAgytzZMEl9m5ueIA1ZMh4MEBgvsFPGzgE4FxPFzgE4F5cdLDgDHAzGSQaPg3VJ4iyA/behPscxoTYC5O/jrZJwB9qUYVEMeQK8gmFRIEstgu5IANnR0M9zjv8k/DR8X/B+H9zdpplPhfJEWsdNy1ryyqqYLpqc0yoaHOf5UOfale2i2ZiOtfKsSXPja3aNKMSmiR9Jn23Nd3pVSLtfu57vUNnHop7jtC9AExYWaebSLBr4uhOEMMLc2izDOVFVViVOGXMuDGHAeVkVBQLwMITWtWv5MEsRkOe++Q7za9daEwAoi7LifIhh6BxjU6jKqiKaY5ZZW1AYIZyDKMqELMqTkwfZM05OilIKSKP4/qubzWh8VNetFlxfLafTNO2Ox/1Bll0+Our3Qg9puuRhhAutd+fO33vP6QVGAEQXLtxzz+LcTuvF3jJNwYe9/tHR5SwbDEbjHqTpdLpcXYdWe14fjUebzVVIkhMg07S8S9Tt7e11e3CSxDgXpgrK27fge+EW/Cz8ETqc4tUgyEY39fXJDQv5YUFiksTKdHu3rdeLEyXn9qIRF18s5d66U4HpBmsgKfKqjAcpzC1R2aIuDgcxgTljN7XQoKyvf71Zb+qmht6BueA6d+t6DtSKBnQfhFtn5sEtjYkfXW/mm7mANQ8bOgdoCLSLPHzSyoEWc4ps89otOhHY9HFLlRPEQW1XNd30UWIuBlxpZUscg4Jl32G3+OShmM+ijszI1kWnLDGt7HDR2C6pU0MrjPl8rlj2WgjHgUg1uBzVonfL2AolIwCZRuv6VhYV4E8Jol8cgrFczEB0yBRtK/shmrebHcmn64YuUiCLF+5E6WjHGWtFyh3NIpe1a/4x3Ch2ywOkrBWhK1r3SuGO5yz96kzVbMS40V3C+08RkDSQdo7QRbS2X7TkAUAJxrXxwiCmQZUM9AJPe46YRUyE+j0hQLD7AxqjoAc2RhOClIyUBYKeQcUEs2HhxJJTTqTRUUZi4nAwziIxbhRGMIC5BKB25Ql4XRGOsdweKym/8EN0ENnRAnHyZwXjXAujvBIziR6hLiYcJ2AcpcSPamFqfyUAEgkDhoAF3CDKnRgEXz74ffs9cKMUAvNcAOB5njGZ8hu2SuK1n4zTwporv3AcRh1I0h70j/KccyjyTju6TlLJCmptdfSei8hxRmiELK1CFcVcSQ83NtKMOvw2cU6W1dREKhKEJBUJxlJHJAWpOLdMVhPnXgp7GVnSJs0EaWMVC4uIWJQw5gyR9VkKRSURPDXrP6MNASjE49U4R0QmtVbEjXCCcxIs++Pqo/geR1oTEsXchum4LwEALrn3QmZHOAUERXxSxeQpuwYI4NCsPCxpuGVV7LYK2DhLgDMETYRCV0fpvcz67hKRiJhhDRNIGJ6jJyKTtmKMmCKZSikBR6xDaY1A6UkfQfaDrx9ApbhBzBjnNhE6JMGYFTKsOTFiLMuIODtBXzruCgFKMc44I2kZMUaoZTE0fM4F54w441IiCmEMghJCKsWY6xMAGB8gNblNetDt6RKgPVytN/+WOt39LBuUw+F4VLU4TLMUMbSJNMPtn4XPwMeC7wYOL4Ifw3+hR+nD9NfsahDgndNlj3JoLVdp5h64hVVBYM8+Jy9yzNpQZuH9SEwDmWbiagoKLo31I3C+qZuzCs4s4fqrHBGDcw3rTEdWP8PKXcFgh7wxB8nRYmYx8wh32++WQGqK1a8DtzxVhPV3Js+6IcsU5hheWA6RzIOUsQV7HObxeYsiLz5va75JWy7PoHxbuKvfYrlYzWEdX+PFdGJxgiFBDbktznkwz3Yi9TAiFgN0FcWUtcyZkAqCxqDRdWRRG3grPuInDL7i/GK2BPR5geZujShSLkJ0danQWM3mwDI0WpV2WtajYQ8V6SOnCtRtk3B6NVsck1tMox5fsOAj7qvF3ZJOAK6nZNGUVSxWXGTYvvjcwKccmS/Ec6aL+tMg5RS6lYfMFU3e5MViujJ7m3U9mbLXqxO8Sum62a6Wltlzi9V2td7MpwUMtPjoOiSt9rZaImtPd9vdbum0GxqyukPA71cLy0h2UgpGGYp9OMIvqlflzeJJMwHkXiYKIRfT9Wax2ZSOAPESqz5YMW55j7+jWGCaHuQWxamResfT7fz57S5PGt18lTejbl5slEiBV1zPpzFuyRof3a5pwZXJjba8ntd/zoXggguOp8d+59J0fzhUJ2+SgKg/EVC41lFnaDQAZ8Zg4PbSJD2SORv+xjkXwvsoAqI4Xrc4HcUnADeA4NLBkXWtdn8TAC5mRbtGeeVDa4ssjjq6zrGICEchaVz36cInraGlonycIiLlBapSlzKGwPn+uJVyUhdtk+ZJ7aputc879XnniCFa95q8hUiUeMsyyIlWe0aMMTrL5BCSSCst0x4DN+gIVbWfm0Tbj5IRPh/HgVZ5A97UV4WN4uz0niFplHRJFy8nYkJFOQDCK6GwwgAhoOiurCxk8ZqEN4rmmhiNoRdyGsrjlOgXgnunJHdjNPg3ThqhjPNecPrAMZPyHJoBCOPRBGlDRiRxHIbR01rTAQVKhZBaOytEaEWZI49A5GMbUhFM4fwF+X6nYmvAGVfoI8NNhkhwydvg+okhCTl8Df2GwNHn8kBTtDgJRuW+zIhREcmJsbqIUg2JMz/crHvGS0sdIh7MbgfgJ1d/qeNCW6kAGFNsR+cUl4RgjBHZtdxZxkKlX8w7CVfwWcEdPKpFQhDOZ1prbYwLKdczSuN5H6KxkVP2j6xYKzHCxz7alZJQ6XBYAyIak2WcCeG8VNv5RaTodpbT0jNW8jA3E5G4UABo3PENH2qdU+WYIbrXZ+kWJZ7x7YoIsF3O24KbcuC4NiJyIw0w5nI+d3LZex8aG6Jglk+HWVLFiwhlLvzVs+20Eox5VpFpFkd5QQyx363yfjFwe5BvQo3zUhPa0DgpizR25eI1jAvGwP4oOsSG59yhKXzf9wsmhLJ+lXnE1so6RKtyrki0LACJmyjKEIjKtpRJYq3RsXXr3SNsDJ6LYqEHtt1niREzSnDyNUFKZ5WyOrYAcEnLeq3knDFrYuQ4hsRutzudAW6P6E05nrF8pkOh/DAjwR8rs9eAAiOjM8R4iDVmjfNSOmvXIXJ2stQsj2y8BSCcGO8VrnJ+hoQYE0evFI3wBC4g5gr03REtCC5/+iXncWr0xtMjDK1aBjFJtq1gw4yQC1J6SzyuxUR+yWLGS4lxImO0tkbBK48JHCdPnOzyHBCPHQPbWfBIKZ7eUdpVC3fMiJiTHMIcAPHkkqzMWTfoaWWN4Es3A0BCGaukQGF+MaEYizKlgYtgRRLQShNy4pWG/VIBQMjeEBHCUPAyz5xIEJyyQ0KslLwmiJHL/SsjRJSCIrkI+6E6XB76NC7rQ18YfBU7B9GyUgGDUmejOpNRzALGvMB9xDlS1NfhxfMdr+iDgqG0CsLCoZxUA/sQZCsHdat1iamQj0+PDk+OD/dmN89JgdDrDwZcxPFmUhCWSV4VSdRTCupIsuEwT8tciMPz9ZGSSVRkTCBO0ohhllfL4bAzPMzGkBCGSpVDztsHD16+efP08qgk6rQPP6lSlzbZOXhTNwwhklwvkcCl/HwCiuRkMOvFljFnQoRaH6pguDWkXML5qMqZEGFUtDgBVLPhuPRW+KOjDWNSDYZloZVS03O7ZXMxy9cn9017jE1mV4+b4eb8ufHDSKRAqiAIAtJ9jy8GD3DO7KvaHGlLVByjoGFq0w4hwrZt/arJMOp5VVNXHRUK0khnrAoYiy/2up5Pg7vvvvvS3ZzffenuL3KPdTqPuS96bgfvvX/MfdGnl/O9vfnyXjLtdjo9uiLudKeRgJ5iVPPccUR3X7r7Ff8fXs739n5tT7ud/iix+gn4DPx4u2EBe+QfbL8R/D8QcARX2xEbWS6OX08F8wWDil6N2iZrPG0KOoyCalGt8jKATPEO1JYKBpvBYe9i97St534DbZmnW80HK4k4l7BzwE97d+vd54HBJ1TnnmLuN9YS1L65WacA6ZZ14XG93/FfvmP2hYtnP/t99z3a/fL863/ovc90zmFVoSujeK219grDEKT/Tu99366ZRnr9xqIoHFUl2CL6xmvrVfj991qtr/34QuSlz15/wf53/ez77Lm6Hnziu8vd9t7HLl8mffyG689+9L0LwMuXH7vLWoutFvNFlMCPQ9ORP+tnYOmX3ri52Qx/2XCzuXnjVRzuO3/+/CPnnv6Z89OTVqv19NOtZ7VO7yqKoiV4K9dpaq21woeMIi/ewTl3IaPQcfMCY0xecV7lOvlRGAxWq+vXVqvhAGAwXK2uXV+tBgP4vtVq9TNPLx9ZDb8NkmTwyI39Azh7Dl6+/Niof/r0z1zLVhee9djly/jxoihaTLQKmyVBENigd/sW/D7cCj4d/Gnwf4N/AIAQWjCGOZyHy0HAq7rSPuCWzApMBokey6ZsP6THUMMsZVQ1tne0IgExqpqrEZpSMKKapqqTnkONz096/6SfT4YYz62F4hRGzJNKUjyEZ3ZNLkUV+w8YkDHsVjo5FZWugNEivyjLi8ZOWW38hrarZqe8k8mLXO7y8PX8YhPEbbwrq8tTu6Er3RZCp+RApJcXeVVnLCa32Mj1rqxqetaj3dzJTSQKOZP14IwxgjtW61cxDNeRK9JEDlLeFZnKu6otO0no32cdMlBCmraSLAXrsoGxISfmRr0+u8g+S6bHcY+K8ahgvfg4ka+ji7zXHznGWGTsILMWsyxupymUYFjniqNiR7Z1J9Op6LFkoJKk8NE69Gf4/508zh3n1rpnxnFsFfXQaWfbwJXp9hAgTSQCZF6IpP9ncRw7xXrglbVtrmyvhwhJIhEzz2XSb0VR5ORAlGXbGaE6e3uz6QlYM1KTuZzIsSx6fBoKFWdZzAcVosnTlCCKiigMRS/PudmbnU8m06v1iy9LNufNF8dxHH9xw+dMXn5xfXU6jc/P9gzP854Iw6iIIqA0zQ1iNeBxlsVKhFPeK+RYTuR8okbGwsl0trfXUcK4dlmKgXRRUbzUWis5orLLJCLmHIg8DP39+R5ISrvniKWJIsAO/qC1VnIc+mcwllQL2O1/vv2fEODjwTx4NHhr8G+DYGfErr3bVrVABngCLtsBjEyLCAvOyba15S0tiyW6CgeTZwyjvMymFfJKHNYjNed15pcLtXXQezGGLaJyF3bH0mbaRPTBwkw4aSBr7MwmA8vBf4HwIFXtLDG+sxdF3R4xxBFjRVnE070TQID7z52rPgu5dD4MpSSyNkqTBEqoWvtM6ygqodebtFqHh6fQeC449y4KlcLWycndCETHk2lSFAWjISLHNE0zpKExb0jCMINW+4BrHUU59rqTVvvo6AJJ50OvJJIx0UMdb9O8VdHp0VGrBZNeD/Mo0podtttZkqRwj7WeC86dCyOloTx3/gEAOJ5OkqKqBB8jcup1o2jydul9GErJmHVREkcVQKs64FpHYQG93iQKO53p3hGws39tHR/fAYB4Mp3GRVkwNkJk1OuF0UxKJzhjzkah1kEQ2ABv/zL8W/jBwAR9RKU7vSb4aPDTwW/Bw/DFQTDbhiGeqcpKLhoCkWAUG7bYtMr/luZZ8++Wm23tYx+FWKSgSvPgETAuNi0Bi+ZybxVsCmPHsYmW08B/3UZCBGURQ/EFROZV9h8iyYs9w09AGVisabtt+YtS4kKxiS3NIbh5u6vdvmArK99eSB+jnUm9rXBslZW97KAasCCHworReFU1lV+669hBbE4ymHlY/QwD4OGaSCVpLmOlIor2aV1vd8tuCITlluy2u6Vl8mRRLFbxu9QphVzUiw08wDgRas2RbSVgGIcCpNBG6gi5NgzirUHESlJQLAQH8ZvEiQmmrBGJaq0ASJxzzRGVYoAcjtHd9BM55Zys5XjNFI8BBsMTL7jg0D0+PjhMs1YkgOVZe3Tj5vUbAyTGBT/7mTSKELO0KAVTqswqzzhH5X00Pznpcq0B8rx1Y/BXUBQdSm2a9todjoxx4EWYGHswnUYIgvOQEJmSEsn7iAsuRJwCV1JIQgBNDCGTDKie9noaYiG0GwyHwxhwtLfXYoLDOEsB8Fu7fSAE7UMPnKDIYbO3Z+B/AkibACZaKAKuhGGEmMp+K/L/PVZAwolxQcRzoFYTJTwTOZfGe6mkAnEdnSFpBPfVOKUJgESS5F2kqkCuQxkVRTweDaRKueBc5FXr3LmTcxUfYrhu6roHoiiMtqlhWCbnAzBNv2laUjRj14UnmEcYJUG9Ho2bLY6Vhk0jGJ+9D6RBMQjhGyYQbNUjS2PUMIwmY2EUOZe9KZWmGZBGHwO2AnDJM6U0rmnU7LtJfYJyL7BO2ZNtB2NdhRgiLjSgVKb6PwdfbtrAJPTGBjRSJgpAdeenou5eT6EcXYxVWLCy3M8JF8KDlDTTSdnFZFVy4HGj/Er0Lfj+Dr7ZbreLoSye9n9/mqZpu/PjE7G+kaYb6/9zZ2en3d7p/HixWwqwJ98dBEGw3W5v3xt7y/qt6yd9/+T6reu3yC2vWtevwRM26OIZtI7HS4L/dNOHYgvIIII06jqnko8s/YcE4yTFOH0fTmAhPyX4hno+kyzi4fDkieEI4+HoxGqvh3Gvt7rS6wP0eyvPDW6rd58IpD/mON2/3fvSyWKI8bA4eaIY4r3fh16/jI4Tf+cRwsi//gb8DK6vxiH8P8UDFWZNS/Em5oafbnoC+SY4ni+4k9ciWPR90AGl+77vWxalUrhOUPV9eAb8oLPU8X1YXDhwYGEBw+zM5tWr56YTjFdWb3r1ZwLHFZJSy/J9H/XmpX2/yhZn8noaZZ1ZMngfff/8gpjZv78vV1dvvHl1jb7Kfd3F/hVeQH10CCHGW9uCy0wNbXPKXOJrOwyE91M21wmrMhJ2L8hHfhv4yM65DaKmS0cA41r9ns0NDGk6M7MwzgDugX7W6c+4LiUA7dbSoHDwtiETxRZVYT8QTPOZk9NOOwwdrwK4q/jELdvSmb0kafqe48YAeLouBz/+/2MEz6I22kD3onf0FSfpFypktQZkuCF+BwIb7Iiy3zOLbAHXS5yVJ2UxzfvCzGg+jJ+MxzcpTjb1DGH+NnJGhmLkFyQ8Ln7Vsjz3M3YQ2Lb9STsI7LfW642ZvPmZ73juZxw/sD3XthszeeOzlrX3z5/5zGfGuYtbf5n6Ic+17c9Ylh0E9idt+63NPG/W65958IWPue169fpnXfeWz3zmMwNvMflFbFrptf4rpBGfBdnT6Fb0EHq7XewirvIw94nbjDsEzNM2BQsJGl8CGcLizOtxXIyyNAB31IVHdD6MKgAWMSgFiD2eUlk1/Z7n/ZYL2Pktz3vRwdh5k24Yhl+vaFJqlWebzabHmSa7+c88fK8Rz3le/YDjtP66Yxi6kWW6YehZJIUQcSSFkBG8IOUVPfizQL8q5dUHdV28vwGe67r4vizLmO1YFr6/0zmPLRu3Absu7vs4TdKjSzdJsZerMMV5CwO37QocIOgUDVXgIB3OBMyOYi4VqawVlI8CgVpGgB31c/dEfMSqrDDqZTSbyh9ALVDfTzTiSLOrqetUU0dGcaOfVAATTfOt0KtVg4002QyqVT+uSK0LVyp5ur29rbqZNgO56nTVttSVWxcLsChaLbEIC6Le7YQbH4bw7zy3PmcYGBvGXN31IIzaum4k6bi/vmCaAJMJgGkubM+M4orUZC+O4Mnnn38+w9B+85vbgLOfCy1TSqg9+8EmQPODz9YAOpqiDFGE0AG8C/tQhE6jh9FPIARBWKz3FhfmK3WIDnCIZvFIbGpPLmpGoluYzUVud4MSI8SZjHHGO06KopjEpSj9KMG0rqmPpYXHc+JCgKkVTyvmPf4XpqjM4YNAaWgDpZrU1JNZltW0mb6qZcx2/B3QdU0JLpjGGQMpgFGuGBdc13QddnzHoU+CxTkhCmPQNE1RCj984403Ys+zNE2zuaCUCWYrTdqeBzfeiD3f5lI6XDJKBbelJm3fwzfCBoAydE3gWOmMQPbe97736mBw9b2BJvE/Uia1JOpVfJ9EEfH8OI8STTL6j1iTAcOKEMCUc4PQj1OqadHHtJve8Y53gC4MM5IKYyKUjExD6PCOpwF0rvSKpguCsZKRbkgd4GmE8Cz+apUcQE6NhX/vYRwlCvg73u+z8nw8znMLGyY1Ws25uWbLoKaBZf/jvx02bFxmhybFxkySSsN0xiTU1L9zlTx5nT9Fz6DvI7kO2WYuBVEoVDWmgu/ksCyeTEcCJ1E+viaO4oDkW4oKHJdPik4+PoH2hQUPeQgpKjvO+6PhaPhcN4iDMF2ytcC3RaOR99ttw2i38rzR4BwTgjlvNPK81TaMdrv/SiWCMWFfZI4LLsAZzAXXNOJcdu9g12XMdbANcAaAuQ7DYBPXYbClwiCKo9D9+IqjIFR6t7u42O3qr5Xt/Q12HIrDNLEbb3bE/lAACEory0u3Ekw1LKtSTOwwDFwDwD7A2JF+7npS0wcJYmtvX0PzaAeBb1Z8mFuXbeOiFVYaBrg2o2JYwuAHfuAHnsUA7BBn75EjKUey+QjjBxhMf/mXf/n9mFL2PhhKuWcLcbXxPSx2Qv0X3+/nJWiIch4uAcrAcC4ZHPM5sQQzKuj3o382GzprEz9ls+Bz//aXuPtvf+mblmX6uBuYpmX61/ft27f5tWTzAxcvXtzctwnvzRpZ81Xfj+7jhiXfNGHv1bedOvW2V0+depVcuXLloYcQqxNdn6J5tIIOodPITTUvmbOn+rgRh5Alo8IF13XLYgLWIVcWWQF+KQRb14eFKEYEAOBC5NyCxHEeu7Eevip87tKlS1duvnvm6tO33LV34Og3bxqf3ntpfObMmRuOHZ2B6d7vwvTGM3/17NGjR49uferifvibxvOP798bwk/tjeAP9kaTf9r7/Ry+shevr6/f98TrE/hve4fhV/cOw6/ufRU2f+n++++HaPI0QhwhtIx34SyyUB09hnbRx9F/RMgPJ+GoWJ52wogMU9aEpZrJs1E2nWQ762ieFdPyAEyrqSBbJQ5EEK2G4w63XJTnTI07xRHlTlTYIEAfvZIk8kiNV1PEGSluFYXvTVLFZIvaBJd9bRTwmsO8Y0OgYAuBFBAgBaJRNIQS4Tu5OAuAY6F0U8ek+KlYzhVvv6tWq9WYcewt4/EYj0DeyiQYhgAsg/TsVAaM6wBjjdAdseWYlgTD0KcY51btf3G1Od4EDAw+7VgWgNIkt2zwPyo1CaAppWEfTEP+nV6tVasaFs5mFQiRRGlA5uemZZeYZiC0vv8+Rt0rODZNIbFrmotvFwCw8Od//udp+udf8byf/Mk7Z9ugFAQhIQ7hyQKlFsFE6NWaBKXDiSElVIDrdrfBsnQQpimNMABdAQ58DzCjXPM9Yq0zQgBMyzKJhT1PHoH7gAKYJgeCgVJKwWYEgNyLlYaPRAAAmiHwwjHQFcaqpjdlB/ZU1sGNBVhz6YTyYDhp8TEtP7SBZuyhueCiBOrPrRzw1Em03XeM4e17vw/jvd/vExpzHteDALLFxeVKvz8YRxGwMNxXHjWF+PmLjzwyunr1VqW8ft7tQuA39n7JtObzRsM/NDO0HQyff4ETvI78oOFX4qgTx4CTStJMKhjHseeB2/RHI7+Jq9XMtEzzvzX8APZed10P4yhOGxi7ro0QshG+fg3+Da6hZ9Afob+Bj2OBv4Z/D/8N/h9EkTqZI3eQt5CfQKjn/Qr9bqqoSmr70lc4YfHS0vVbRWDDoi3KwrxONAhTFg7qrX3WJ7SLuqZo3+C+gzDtKQquZRj3qCGjcBY4QnEx6VLgOCmJo3KIk0bY/ZU4oh5tGEZxWQyLqQhEX3TeY10/5wWPg1jDCyng8HHOddxyHGXBYEj2Tlg255KHwEgUCeLQYdjS5CeVt2zkSeJiGvvkUyHtnxWdrJ+JAjMG+MnqioLH5B8DgzmvXCEiCZDnPh4qpFkRVAsiF+fV95GwGBTDDTFoaGqVxWKNO+HYhFY0LQHLPCArCl4M3ImL/PhDUUV0oJWkzIvolbif8ytkEUKE1J+hAdeWY2v5uh09p1M3MXK5je5WVOg6YtEgRMwT5YWzTI1bp6K4EEnsiwuedyZadS42q2TwGPLj4THyWpSJJlEc5Uc4O6LFjIuYnZNF+MhGgjyivrAtEU2K+zqletvlZ1G21qnYR6NhjJYnimIqZntxLkoB+floXESl4P/xcD/vF0wDJv1cRNBEtE/fMqQ1nUivR1d08pw7h3ZR9AvwQaqk/DBuvJBkgyRFEcWW8pbzshifH9ZxwcO+4BmManqCg01P2YwlIygndvK8yIvxZArJXAtjwy5XFfFicIBp8djFIyA42ditap4L+M9hGDpWlWRNRAFlmu5bBuDINC3O25k0CK4wXRehSdlk0cBRlihBCuU1NHTdpu2GCyAZdnTfpoTUQVoWCQDramnnYnuIl1y7RkSoPJFA/kImJAMqQ49+FBgYJwNxQOD9GNLU2ggikbVJKLlDcCrfB5BGSMrHNvn7pHZURs8Ny8JQyFghREIp5TmQdGT8aARAo7pIh9aRlCgnWBMiswI56thow4wpdEjcovdeAcoKVRsxRzwL8Od40yRz0uvlxjgphCNufSQhJfDg0UIxcI7wJBsASKW8TRhT3rUvHR932ghJxnkM3Lr9633wspfEptPtZjlAu9cbMaU5I6WNclJwAKrAIAJRAUDsDUREQEkyHpSVUBBKhqXJQAL3vj0+fw6EhOPOyXTqsPRax7AvTxS8BLRx1BNZAk2WpcB5qYmFoW71O5VIiULqdjdJel736rtalVWhMIKYPwjTJG5BN/QIgkj6iDEW/gXKeAjOSWlRjTwTITBDyl6ZimuuSbEAmicTjRbkrDxBYoIjSR8t89xHxNChkP5OzYQQMXlE60EKozUQobAI0gkORFgCIGTIlBKMgZhYzUJIDnjYEiJCAgE9Blxo4sB5moy0hCREJ7X531LKkQ2y44/gmdYKYiPNt1lZFgFoRhatQZSMM5QJZ1H3GBLnmHenatx5JwlY2J9rYIlOS1LoLykDvCjHVcXeDAeH5y/jhYsv4YzCCJJEireUZemRoA9zzCAEoXKxUNLo2AJRZDAWjEnNvcsk7Q0zTlvuDZC3Ynyz5XaAiMyS4wZmPhQoERD2+lIa0w0g+73kmGOuH0OqARLLGTlLLBMqyruDMGyV4Dwxx9NhahBTmzITJAKx2IShlwIdVKublOLCouAgyy6fz84+FjEG6UECyLXOWkrKKI68SZKq5KElLAA5j4d9Y+OwKLpdqRDQM9LWJlRJIQQTIgahIAIAqWQSx+1fMaDKslNoDaAoZizs9qgPqJwVhfQASFUlquo4LmtnBQB8LmD7QxODOhWU6xkQKBSKgJihNM8d9DQCj2IDeVFGLaC42xp1u8g5xlnuiSFVUQIAo2d7762IhGMIzJMDQpJawat5qxWH1u1pfp7HHBgCAuiCMaXaOcQCiAwR64Uf+SUJxjmtJB27M3CbtBIFgExIBWSd0wgSpEDo8+UEqRMayTkfainWPAlEr08N5vkBBeZXuDaQJKCVYLqUoVCAIgjiAG7fgv8Mt4JTiOFL4EcQ8eX4E/hH1KG76CvpvfRD9OP0s/Q/LUASHOBoLqHemIqUBBoM5qofeUNgdADtqhFZn2/UoiuNCqY4wl/WFXKYpUWz7tAHKv1ZUbsjWS1WpZ5CZ75Zu5aCxLtKr1eS+3gEodws8qIERPLXbjbNuip3DDqgp7f05vWymdhElFvplUFH5KRe106iWCwpZGuYQ6HRXqeJTgahDlYGqglyOanjT/wyrEUTtVi/rNUrdeOKi+2wyWa7W/cekc5ytQyz126JIIOaYndd5JUHLWL70FVUqmuKXE52awtF4jO5vVvvCL7dljdvCrjr3Xq7KiferCdWH6EnyqJod7NuFm/c3a2abffL4LJeLhaNWN6YZk6WhdiVchZrUWY6n05Wi8WOLreWTCdT0Vln7JIXugLQvWi1fttcVe4Wq+VmbTMVS8HtWCyL5KQmJ1+Uq7LeFnLubAckDaaFKES9fjNV0YjdAs+QLvpaTUcUQhkkO6/yQuxKr3/JtsrlNqIrsgfRcp/O5aKp2e2JGuEaW2Qs/HrTuI8STSDxiDaYjCzlpJlvL728yFclt8XQq9VFP/HSxdbXt97M5Xw6zyhdJcumlJti3JQbTRSdDo5Pqouq0d66yAtaazSYbpd+2cDkBLS4WEjl3nTcbr3byum27OtchwrXMX46Tyd4b5dXTRMl6fJ6t958vDWbeb1oalrmj2zWtRSjQj8Kec6rUf4ujkaHR6MRMqYn4/39QY/TwWo5myGSHvRnh5Ox0E88MdRxcvYhpmlkcLbtFkLllUoAfwqJvDXWgkGGoIEzCkM9UmoIlCAwIcXYWBBx2hNCoohzA+gsAv7k/gGARCBjfOwcUKvd7mid7rqq2m3+/Ocb8zwHYVqUgrRyWZwgEeDR0VoYG9qYTmTY7lEZN4hSFMx5TkJqbYcuZ6lQAkFw095zekURmIVXRsR9HTinP1GmwnRpOVCaJgl63/OMkeowkQCLoiw5GlM+K8uys4MCDRklqZPEBBGF2pmJEBmdtisLzpVS0mlAQQBMCsj40JjPR/0P+AHOSiLOOwx2ZFMy7dEMSs0ZNmFXQiSKhUQASoCelCIVQrAc6gKUSO8icvkR1zHSBNzQ+3jRKiFDo6GcgAGizIVg3DjyRm9Iq0BGm0jZ0LMe58CYwxUY45zii4eLikdBpfgIGDBmHOdlgJQBl0LfpwLMEEW7NZqPRgq1qucv/IhqunENZnZ6+nFsVePx4MA8RoiRZIQOhYTXOvzf2QLEXjPQToGU8lngbm3eQvySEIIIbkGWttppBsi+4isZiCyrqiSiVr9fFAiIk8m583XtCHmS5K08o/x05xQQi8nwhzQadlJAgFZY+bCvewQRAqWeX9JzxBhPjX4WQDi3CEFILAvpMzWdMiJGKSMAi1cDUwspAO6+BwB5mlTdsoA/BG20ceReh1ZG42opxLcAYTWczyyPomzS6yHA/Q+8GRAVDYbAMbFbwP6g3ydAlN44j8AoDY0mYp1ut6c9VkrKg6oCJowhIHLtiMnQIAFR24VRRQDiWiGAAMeZVv0sTgDSkJUAYNibayYZM8yTlD8PEMRIQPNUCYAUihGwyEKgF72eDpfwnpRQiTUmULifHCIYyohfSpwj5O8MfqYTzhKdyeOEJaXW6m5L0eeLqAxYnDACLsQNrMlQGVFeyY6No8U5HOO2Jlzc1FoWNYfsTCn8HGC6ICpDYQ1tJOXAdlAGTIehMgDwWo9+K8I7rYpFaiNTJB9Hu5GHi9pIqwhSjrFkXd9K9c7+AoCFYVqmKQeUaSoYAeclEefWCI7nCCD0WZa0xH8k7pyzDICEUWnE4pgkoKQ4ZjJJFHfSOfWzICSAFPAkghCoAJBxwUQcx0oFQREEwQvxKZj1xQ99PfvMs34s+D+wBwdwB3wOfAV8HfwI/Gf4OfgzLLHGB/FtHntYscdeUiD8MOnm/0QKuSiCoFfw+M3acSdcbGQXTSmXu8rexy+ot3WOkhPv29q2GYor4A4WosPpTtTlTpAcmcdKi0WzrSirg/HoVEgxXd/32xVaIAL5Y0UjwEj6TXEWzol6Nt+V1ZoYX0jU2A2shKhc+YuvILdVXohiu5tPt9VEliuBUlKXvTUDJ86JjdhNpttKFFu53Qi5Rm6BMxxYymqI+7nltKyqSV2e2OjwOyOaoilr8Jqr1aYRUylNsQ4ZTmma5ycQl2N+s65e0zqvgOhcBwBQZjrfAxj3SEU9me4SxOd2UvSH6qaZGBhPGd4SL7ETM6ouGKbTHWnrzUayMlWYRFTXlMUS5FlfuZvvJnK957a77Wpez6uy7wXqRSOqKv+BLI4ybaUUkSlOFinFoMmVlU2zq2vxOaGdS7kotjsht9VELprFauPWDTCQdNGUbBDFJnAx50zyXsIoRI0CJdP2Ww+ggBhTa97xMwacQAjvkJozsnsTjG3MFBwQlGWsMWEeajB+GSmFYpp5fShpzaJQ20T+33GqVDoZhmEc96ITCH129o9X4DFIc+COeRJqQyWMSFp0GINCckbIkCuPeRQHpBwjJMVAFmCsvLrLckQmgVBvK+fWbi2DDgGrT6YeoDdzQBPKn/1Ozn1e43hnT5W1KrJ956QBovAAsa2kJkQySgO0ib2yqqpwtg7vk/Lh8PKvzr33bl477/0MUimkSDMhhcgfOz4+PhR5IU6O5aHsIQIRTEMHCAgWJRID5UMiSoVg6AoAriSAVBzgD6SUMovZUMpasjQXpXwfYi4EA8sAGSI5IgkgpAJQkinRFhJA8Nb/ZiEgokZQyiBjSJwhAqstiZVSWrw7ExUcBHFhkXMQQgH5lgO0VAYohXyInrmhJqKVHNgMEBNYT6BzHT1yaneauTWAekgBgPdl6cMHt9utGKdC0LcnxijS0Ns2TpAyRKVIGoBAJ/PB+gLocGUYvoFaEF1dJxEkIT5llSHnZwUjIZnkVhu6eU7SvA1mROqIQQECpPDZTAqKONf9aKQBmHDApeQ9dDxJldVVVQGCZA5DiNmhiAr1kCoexFar1cJ76UMQek/r3DQ+BH3z5k05n8ubmdY/AKI+u5UbxcgYQEJKqSw1qxWA5D0hnGitD30SSv0MpRY6ztxz9OMGU5wsYIGsbe9DAGbr0HvBvSc7QcbH6SXj4DC4HLwgeF0Q7JDiGeOjdka9J0PJJ1xUOo5tTInYEwZ3GtIKecE9TsFquSuAgJoq6tyqkV8sRJIgqV7XO/tWePLsWzPbVksZPPnoGvwTWNs9v+hYC6/cbDaj0eZqhpBde9KGoZ6PBv3x/DPsScb03Yp/1Lvs7FvziHh14MnM+bN/jeIIvhfiKLrn+fPBfIDpV2Q4eEMJmL339a9/r31y8hwbq+CCzqF9J+/MsIfXJ5ebpllAIBMpCco9b5vX3rSNDVuCHW3IIH4CIUhXVqjTyhEq/qUfVg6ISVrBnNzRBhqgcBl88Kmb8o9All0cjoadPM+xy6TVTm1tuI9jR8Scl2lqjFZVqfR/6fb7ZRRFJZHgzgseS8GGfV/jWUOolZLd2GpHm2bOWauNzfM8N3cAuFa4Zz9z89Phez5VGfLs4pBYHhUFIkQhUUtpMqicWJ/zMkmt0aoslb7cZSzUUVgRceGd4LHgrGwRE8L0S5YSrSQobU2azsF6bfMiyw288tchv38wBEEQdG7fDgifgq8IwqAJrgfvDT4c/Nvgr2EGXw634J+xhw/h8/Dd+G/xF/GfaZ/+jP4f3WZ7bMWus4eC4DQqa8FLLmHP9ma03YXy7OSqVaEFfDG/3aAtDPwDjkiXlzQ3xhoZxsYi1ottcXKF5KUvSiuIBGHm850TO9GREuzfFLqBmCbyIecqtaj+qqmr6Wpqb5xkn1ALi3Ri4BlbmDzTlUGpZDGdS1tOflfAcRG5XHITHK1rMMA6LWBw66P7qmQuxXTy6W7RFLtF42VjqVrrRknAd9OV/JdO+yeDrT8CetwKYCICfTHajgjWGSd9t1vigPehO4bWXMMQo66btcYVTVksm2mzlQ3pNSWrxW7V5I0omkxwIYnJtngnXSV2N5ouYAcboR9ES4zWTVkP4FaELup11wFGYNujJSSderBqFedSiBHAYougVejuNsUGx7CuX4nKJlhnt1jhzDG33XVPG/TZn7AKy91XE9+1dmPRzBfz+r5YNoVPYvYqHbvBwKCrNGq2ZB6dZLprtvXE8qbs+sFbuQWuKAQXD9tjKKNhGZFKWzgEiGU10f3A57NF2U93WGWiefP+rFVFXnzswnwH+JTWPChHXWjF2ZxpX1tHPNVaNJBqJZx2tC3SOG263clm65dIRUu2q0y/uTzHQugLONxAoG/HNk8n2yC5GJHLEJhMN5QB8djJjb6A8nVUPoYIpkzJbscE3Gw8B+qMnHOE0+hQtct6ltahzlzW736nanYfYeJsLxi6hFHNQGHFVVEhiAm3Ebnt+O20f6zl3LK8kMVvIqFk4cpktYeHASnJgtUOmqYBDs3i/MFxrwuA8GGUhq3mwAUJWL7q/gcODwXS4sLFMRxeuXLflckEoAJoE3AOlhuDAgRj4MO+E4Q3FbU6OLh27YGXa6W5ja1SDAgtopq2a4dmkPtJcoVkqQCIgTEjHBaNj3mSliISYLRDiRMjaKsaFQCEUhyAmADUSHAS7ZSKmAwstoJ1BXa2lUu+IMNx2AKxD8QjHf4fERg+6SYAvJOkQCIfYkWIrWQ1oQDWLcZqxo31xCHzvnGKDAyNlJaAmHElEZTCLHB5GlApK8BoCYIzzrnVvC+4ToETwoMu/pMSG5J0IWPhYW47oK6DuoVSOWB3dQC4tpYUcEDNGdfcEDIUAhmSiJBMH3mol8qN2q1HIIZSUSlosELmkGUkBXSpbvbyxLyUAjiVCNJ8GJI3QoCa8jw/2L+xPxr3nvNYm8ksK8uMwzjxV9AIIdGBU8oSgCQiTvYBTgAYLw/5Xs8dVGMpiXHGC21ShoIJ0XZJtt9h3AN7qQuTQR+AEn6pSiRjpBgJGOabn9CTYjQczbaXLncBz54EpsHQ16PzorT949FQOQOiPzh57M475nOA8eSeez7/F8lIsQ4MxSTiCrKw9LscZbUl1EuvAi4sJ2IqCuWDiCIcFCXnPpyjiI6ShFiWdZwA/JiV2L4qECNuvoXGk72ZBnDN8rH4gz7Y2q1BLwNIhomxngZxHKN0ziQRyGEbFBMa0Qi+OznudODskwJRJLFkJEAb+840Te8R/S5XX0BahATwAeGmpjTsJYJS9cYwYsJRtzlmPBPhqLBAQ0M8+ZIzgASQHxbAugfFODEywRwHC0gHUk8KffuRmDScKYHFnMsNywJoUF6hMDwG8Wb3mACwm1Uk4poxSzESeiGYlsSUtB9IJOalyAqFaByhBMYqU+4VYweU+vzc6nhKP33ljFmGCEYmXIC4rAJHTq2KszfwOGTCh6jji1Buegas7XRRW9wjTJMivCA0HY1MMcarqKs1ORZ5SZjEyTM1KzutWDAI2gGbYKoMkJccw7Ki1yrHmJ4dD+GXkAIUJI2M0+jm0aeL+LWJcpZJhcYkg0G7TcYmushiJIJnQYFdzo9misd5TgI5I+Ic0MytROB3IqK1q+f7o5eoWTEQApFELKWXyLlSbZdeMkPfYmT6/FDveUQtQzxyAgGs4gyv9FEBFDeuZFrDeHw/0etBAekakdJk/uXABQIa5AJwPF4td4aI4uPNup7jD1h0XnHOQfD2EQAqRywKCyAJwPmSmFDdvoUHcCsIg3YQzAQuLDyvpGoy8lc/n6xZNQQ///znP390+r//fPQ/v2k0Gn3h/xj/ef3N3/zNL4WXnb0G4PGz//Hfzz4E3xR0Arr9k3gn8GG/k4/dvb8RfTf6NPox9LvoD9H/gBxW4SA8BG+F5+Dz8AtY4RwfxF/Cf4b/O75OVslJhLqKFPUw/KC7iePFYLUlEwdhkPOhyngaBunrLBvm40lfFEVfhHGzHI3K8WTqhZEoQXk0Zy4PRm/tsxyx4BbiqnA0TXg5z3l+D3Fcjh14aD813Xh40PZhR10P3mKpFCW/1sMe0Txuo3x2bBU8Q8w6isf5AJpMP4/DohMPkZ6ioNLOPsgiz96WxSukJaavUDNNhJHw9sUXZNYMwKamZTbKBiwtRYMYJghvIfcfRk/OCo5Ht2eF4Y6wdB1EOrEK/X7XvwZ91JHYzT5t2mB0OM77OQASWn/nKDInFQrkJsjYXL/Q3zwXc3Jbk/FkOOWFgyGPDZTAngswuPA2gulfsG2AnhyHCSOeFb3LCYOM5zzjAoVDOxwUrUemd4lDWwbToQMnCSNFBytACLiaZ6OsL0XN8MmkGEw2Diw179BbHOT9lcfFQ4ygmO1VS3N5jaLwKv1ofP8Aq/N+FLwIi0E82CqA7Lh4d2uL7F8YY1wtONrkeEVyGAt2ByEER1rKgRFWc2r4tio7a1mWTqluURoRElE6JwAcRLpIC8EUDOvAGeNwA2AQGEAX+TWxYeG2UkwpZWckISmlghL6j77vY/9fdPxCyQgqJuMy7gAA2wbbVkrX1ZJmW03UGA7Lg6uUUrp+M3ZbdMXKlW0r0JXS4euEKDtfQ84x/0vXszhL0253hrGZtGqa2OPcmpsvlwetWNeJCVhNW23AaVKv67VhmGUD3roEwOXC9nemg1+vBjYB9Ce4uGPvC1hKtzY/XywvBxFj1Xh+DjOqoLhuDsPlZT9mrBZ344jajFGNC04J0Xi3KxJCQGnJyopZAQy6Vul2uSSavh7B38L4w0xYGDRubFQ0iilXycpqzJmkXEs2DC7JWtiJee7Qdggm4LY74ZNrx+tqyFPtjCNZcz1cEDOOef/y28VBEKx4JHdAJZkzuI0X/x2W3FEqBBWX/KqGksWLrmfBVZAaYN4NJ4NNsOYFhBCfEEI2yM+XoRk20HVC4pjQvoCQGyb9UrxOATDJlQIN6vV6PZxOp+SkOyUEatVJxqHt/nPVrBnLmrHGBoDRNQCMiOia1WJMtQq4WdeF3l40xlJWrDf0w0K8gFeKoB8QdH1mxrZsO2esr+sEY9XubGr0RKcDoHRe6Xb7diVp1oNA6fi766ZuLLb+jMrFiXYHdMWTrNvPxuPe+5mQ0GxuE1pLGGt0qI55GKVpsHf82g9vxmBfvUY/5PkcMESBRtUCYAJej1F3BoB4PSrDCDAEQTYoWp4HFCAKmex5hHHs9xnt6Jpi2OtLGkWYMAh8KgI/sCySOjZ/AgCGBoAxBAAAGFvWGABuEkKsBHD49D6ACsYEba5h3fqlcW9j8i0Zv4Ex9pF2ippIxyZGcbvIS+KTfp4VUJTIN3WaEv55Cjw/P283ob7+4o/+6I86jVsBZiljxt8++eSTTx05ceJEFR6oQrb3OmQp7G0dAeq44eLLL7/8MqqRTr1W12zeQTmJhGqq1LhmQG9L4C5SAibmcTtPP4yyjvi4pX83pVT7OY3WLHt4cQy4VuvaJtN+VqOUQlzJOt0sqRAqJf8Tw/4XKTjIfSdOrPzdTSdPHjq8XatKISReXj58+MiRYsikRAghQPH1a/Bf4Br6aYR60xIJnSv1H7co7bjKFxHYQ4EsZWRyfTDLCZc5nakR/Tw6+PIDSSlcOkJmGsazi5q8mACEuVhURsGRu5uIZKPRwNoF7NXOArskSZIEu5IAY5QCiWKlCOYcIL95IitAoIQLsG1NCaoIfynTNKUo1zXbBouZq5xJbIF0zGCiVBxRAFHCMNc9nCRJMiABEtSzOK4kibB39to4nMg4PEniOJYKVFBM5jKJ4jCaqLmHjDqObQNQRkBjpoHBsm0bM0KlaDbrdQKaZJrFfB+8y6y+zyyNSQ1Ivd5sCkkJw7Zt2QCmyTQAN1fFthyHKSlwFMYRAUKpItK9AuOALVFNkxTjJKlWhVVUTjlm6IailMRHnzoIXf/rMYDJHJmohhbRGB1C59E96Eo8EozGpf2j6JeiCUpEMRGDlj4rcdcwMhg7iiSNHKprvBCJDbYTsI30P0wDaL7sdVndKJ4Yn7Urlo6T1H1ZOL1Gc5vXNZ0y3DuaWUGwIqoXG3cOwjArJRJrLm0o+KyowUET0s5rn7AYQafZbJ58y6lTpxbVwsKCri+u1HVd311Z2dVvuHLlSvOulZWVXV3fXdl7V7vdvuDc3joDm6dPn25esG9v/vyp1uIzV69ePdmGzWazebt9oXn6ypUrp5qbJ0+eXLx28uTJq99cXFzU9YXy0dtvv9250D4DdzabzVNXmqdOnbqidpXaXXlD1/XFlXJBDxebd62srCzq+kJ5ptlsXrBvbzZvty80/+eVK1dOtn7hZPP7W63W7c6F1odOtTZPnjx5ZfPUqVOLD+zq+m5514ULF5zbWzcghK//6/WvYQq/ivp5eWEYXI2BGDuKygyAiliOn8BIQMRbI9wUAoIr5W6noPo8O+bGw6bWSCrzc2dd35JDZrr1evOpo8dm50JK4V/bTAX1JJmbO+MGlhxRw6vXG08d+3X+XVPb4cbYdS1rRmrchCcsIS3LmprmwmLOOayY2rbQYey6ljkjFTOfsKS0THtqmQsLM5zb5MugH8S76H/YnkgX0RTtr6q9cU+id6D3og+jz6GfqnayXllkheDJLy2LrOxgMHSFMxs3rXxUVBmEOXZrjtgIlSuBnOqAWUo36FvzVm6IQ2Y5K8L2BWop2FGcOESuCdN3oVjKLiaeFDUE6VaB9QVb/j/X19ej9eh/nmO3/AwXsc3A5Gj23sSy6EHYnJmZ2Tezb+/Nly5dup0+iiirolpklHHBo7eEjwn2jWPHjrHTcOCeagal4W9funTpAosopaeOmTfffPNZ9sNxHKfR2sz35WttTDnj3p3x+36w0WCWWo1ZWFU4YyXouhCTyWQiOK8S5sSwCufKMKDGVjlvYNPEnDfoqH5ynJ9uNBqNyWQDC8lFAyFAyfU34D/B59FTIyvmW7EDf8a4VGnhEpmw2YyHhs+j6SRkyDAIBcaWp2i5OUSrH/i74iPU1s//FbtuYGka4DAMQmzotmfbQNrtdoNLISXgRrMdljSGQgDTxoZyxnaiZpoaH81JME2/3aiDRsxbSgEOgzBMK+hMgefhOyCuVD3TBMu2LQyOE6dRiLFuZXd+SSWpYKV0zihgcN1Ku1rDgF0v7dTrGBgTuiaBVJJKghkVulIYojANbQ4iymwbwDD9WpoANqI/sYt4F5roArobPYmeRZ9CvyhjMGqaJrjmsL8qwBPZwPXEHkHLUIhmiO7wsXLD0a61V4yKvFcoiDYL+7k4iSQgxVTuM8A14XKmECS9wS7ezIsDuNR1uunh45PJZF8UvXXlY2CFkWVzVUmSxCw3rhYFhjRtNpw503HgJuo4SWTAn0Tx1nRvW7guX/6kxzjnrsM5Z+6PX7p06dLKyurq0spwuPKhNE37S0szadpfXJpNf2hjY6NScQYnHADD9Ou6EiKqpLMvnJKq57hcdGzGvdh1ADwjSTbcAPwCbMdOP8/L49jg/1izU1tozFQqlYXV1SXVaDRG40ZjPGrEgadtltoKvZ6BbZF86KPewUZ6Gur0EeADgUfAZWE9+1Hx5ZG7D2MECOY4kJxgsdBP75SEpXjHcjopEDQaw9IoBcPt+jMciudvgShspEFAsSJ+ugS+aYJpBdVqt1LBUImzdhzTtu+3QVOmpevguhSu1ZynVFtp1rKin9nf9Ejh0DR3NjXxtDrTC0zDNP3QNKAHcaWbxRWAKGxNsetgxijzod+Ok8Kl2KPgccbTt7NsBOXn0CY6jx5Gb88vOHuMjKtE6pYVeTyjGzIqRbLuTiV8UsJsQsWy2gmbUwLDJwj9XkO7aJs6K3R5MikyF43sH9tJiT/KbXebZ0VoQbU6+8Oz1Srg2VkM1eos7qdQq83O1BafjGdn8Rd3dnZqSKnW7LR8r4oX9ddw1fPvhvA6jvjVmu83Pq+2s3P3TVdqO3C5eEGTca02vhxVbs3RHxdPM67Vxpc9v1r1/N2tqu95fvWcXs6y3BPxPQDfq+2HbfC8WtXz3/Uu36vWPA/eZf/FxO6Sz9EEHUBn0cOeijeG50sF7S4Sv/yZk3zJr6qQAIQLI9SYXQ6GeEEXEKOg32gBjDSv4BhTtj5x4bbjjxcO9DfWNzdmlNSMbDKZTNqGJhVrghIZGfoAO52z7Zct62Vh29+y7W+JJbtr2Pb7bPt9f9fUdaW3dKVkTdOUVpVK6XdeP2jP+Hc6QTPo6ai8mNYV+Kw4f1oO4/0l5FsyZ0AzbVs56LBlemPxxQqW/qKyWMqxSc4XYQKipooLnsPH9n4AHtn7AU83DN2DR85P/k+gdGpIATSO6WfqQhQ6Uyk3DNeV6aJM223ICzNQ0dJO6ULHGAehFbS0Q1pUr7meQVUNn69Suud24fOG7j3IP0894TImhZFC9T+B7UShL3islJD1B1p9gntCqbZb7S4ki0pRh/PqDd2ZHuNROO8ojzNqQl1MMUL4+j9fvwZ/D9dQFy0itBc03UgX7+u0YD4H/aogwsxa4L9ONg+tvWNj3TB6gW+Yll2vrTyYz4ApMXbdgWH8n5MnF/nGZPPQ+tMb65bVNlerlw/O5GDkxjEZWNaFv/RkvH8liON3wRPoVvRIvo/hLa5w1Bn4HnHcia/ry1tlNB1btykGtnhaTt0PiikU07ZbTvMeRCrs2cEsMei+mYwfD+otIZVTScqm75l6DQfuC11Znt8qKxVHSdFqRjqAYTZ6vm/ZlUq/l6am7/kzs57vm2nS71cqjsC8kzVMDM7eKwDQcuwSnamYeh44dutpH0OSDJZmZwm2bDeksz0wPdvCZHZ2aZAkgBMVx0HISK3azf0AwPV6Ge2wU2c9zwUI/NxxZw29btZqvg9hEFZ7wl6GQQgIWdf/KR66/Z/hu+HjwbcFHwl+CkbQwDfD98K/gafh1+DPEDDHKQ+NKAw7IALH4Ub/Zltv622NDBtF0IVMw7r5qtZ5/n9NBw7zAJz81k8nbXUyNUXnlsoSUYmK5h1bZTlGl5MbGnLWjZwWysaEPwKZuJm4ALqgGnIHZt7KSFI/k5WGpqKmGZPtLp8ukeV+W1kfy64WhZDl7glYaaoVEvT2arFamiwbIWcYA+cqU0tIMTnrTKNViajeo1XtaS5cZtp4cbVMqgiX8lq/nipk9TfbaluXlRvqMdt6UZfVYrXYLYe1elt12YjPXsUjRJO6vjgMeqlmJWtVETIWE3OP6CEV8/ZSWD0ykQXa52Gl7CYQtyWp+dI7X2yqhwrug6wh6wYgb51FLuGNjDEfZuBYyjgzaJhWnHEnpGSAobVWITqWncupZKgkklShABAhAbeIitc+RFbhM44zrvQ9AWzgvmAOMh+yyugecQSRZ7ocDscwGQwLk+UCkFNP61ZJVZXnclq1jrKqjELCLCurKCRK7ywMKlXJOaiJCKQDzkQCIMg4STYS6DkThBKYIGCSSe4NMxYlKON5pF7pCJFrLQh5WJaqvPficUvJaJIlMdKqHUYQR+WXcUT0am7rejIKBFmlZo54DloJs0hkHIhiFJEj6QxygEQQBy/wD8acATk7EzBUsjq+eG8hq9JzqLxzuiLyvKoQWtXek9nIg1L2MZtnmdUuSSLPyHQypDAqyzwlCuOyzF5VJfuCZ2qeJSmkSXkJ4qTdTpIkbnfiBB7Ji8IYwcM4ip1C8JVVEtwo+1Up5SRNDThukXMprVOh1EKCABCouOAAxLVgcqC9N8b7i0DdjfAerCL4JpVCy7Bcs+bMORrhwKTpRIaTyTR2jI2TBFLXB+i7FJJkzJiLp5NJJGUc5zmJNJu92ApZlBUJPGVlWVYexhKQgtqGVM+DXL+YqpEy4Iw/eGwBvMqVkhSICEqiZAPuCQPG/FlUFFV7lk59VYZvsCZsodbWWBsVpIqZBbFECd3EC+lMJNEAdhV4zjyKWHjkLJeAgivewiYKQpBhWflpOmtXgo/3z6FFeR4napam/Kfi4TDHTqfdxpdJwVtFmkipZBrnuf4iX5VlKaRz1R6tz/6o89LMtn4Mrb2Dr6iiCKK4hLRaVThqc6ZsWSap0lqXZXafPbweFMNhfGwz9gwR3hwcBo8GwYxt0TPWjSjZ7KgRKU5jZaynUQY9RVdRPMhvTIYq6V9t9nkNz+12ugiMIpKqVY6GkZUy9M66ymWMpX+w/vXN5xEAdHuH1zfb0QjY3niMeHr6yCMPv3A0xqLc/6DWfYAovOmNdtaVHQj8HdU52XgXttt5AYOYc+hFMeR5r9cx2rn50dFRv484HE47nU6KkzPVtz8Nf49dMI2CMuj3V3RdeU+A/53sGjlzruBrjg58Ykbj8bhu6ooyyprp7vqkalaz7Bn/twKSj8fjqqmarJdl2WPiIfi8p5566h3y7PettY/9zpdA7+z3offwle98+9vf/ukXktYaxAvPvoxz/s43Qf/skzA5++TRq94Lg3a7/ZbXvjEMw2942w+VZXn2TxA9/+aHzv4JxNk/gfgq7336+S9+znOe8w3hNz/636AXYFDcvgU/CLeCXn8LNgsLMSOm2912MxbRy9egOkU9r+EH8cLF5z73wkWs62vgH/d4ta7P/hrH4/GYaDwej/H/PffiBbxP6c3NpnhVYiwnFpvNzZM4iuKTkyiKopN4u8p6+BS8IlBBEfyGfWvaPG/IjhJshBRcSeM4zi3rqMl0kpEOexqChjfUaDIlqlp6W/ABGC9XZaYywvkpjqyb8/pHdqRND076ZsF2G1YJMx2d6ySPiEfhuAOUhu2KAxmMq4tmMNrsjA9rwaQWTJ5nUVLk4pz/PC7ZKVNd0hqYYywkON8z8cnOcaI46rQTmfykPM8SbxAZ5f0o5ikTuikIptQwyfMkNhrClKioTs5t10f7++PcewRjsslqNfCIWqdpmUSxMJk0EjiAtib0JmIsTnr9qsdoOByPq73MKBDeelhqoT1iBMAcF45zq7SNzG2ulGBSCVdGkZBFeS56q4xQ9L1YBiRDJrVDU9Dc6qBEM4YIMdHJmCvAaNCPldZKcdTGhZGTgEaETFidF4O03e7OWq18AlinZZnnzoNSUafQgMYt4CzJJx17nNVbs71OCeCLvSQDSEKJICWC8KI6z2SeM8tEQLc/hl34H4E7Uks3wc3gOfYAC7U2fDuO5WYbOVPU1zOeWbpIPyRnpblAkICbWy0r+GWYyUPPZHBfr9+Dvd8+/1JBr9/rwV31re1TESg10277rQyeafCUy5o2omTRasSA072f8J00zxcBuHNse6tLqa7Dm+fjIIjn56MwjOZ/dMFLEgTR/ENH5+eh3sVYS5KeLS40nvV8nG2dPXew7S8UxfyfUb0XhqBpScA72X6MeB305J+GH0YhWkT76mtS31tnTzwsl5oUQTwRLrMJFQhXDQgRSf0NfW+DlCAJBNTAtZJ6N6C8CzOPi8EXH8dFJw+LjxrCIiUU4zk+wEwT2hAElVi174FhcRNgjM8XBawfOrS9PYD7Z+duuXVu9vSFCzf+USusJBjCIKmYLZk4kpud1DRyA2hK9wm4rlNPUqJ0wwdwHLtSreLvp/GDD3SVRpn48EOvv/768X6vDQDQ7veOv96UUteT1/e1O91up73vnQcdW1157bXXDgnbLgeOQ4h8y3333ccYW2zpCuCWQCkuXRfMhqNprUjXubRtsOqOJpsIEVRFLdyDy6iF9qN7EOpNLQ+3s2JwVOtF4DPaMP3ZCkpSzTnbBXxpEpMkt7pGvhJHwvHM0YFX1Untwoff9xkLqmAYll4ckLFpCfW4uoA8dijSsGjPjkf1xkv0yJHH+nPjQf/yaNz9t53hW4tBqutUse84zezsxsbGxswMhh87+I2GUkB0YyAgdvHPVMkZY1GIMXDqedYdLiXw9xV/UKmYP26pxDB1AKYcxzABHDeuxBXbAdjCa3X0fvRu9CeWtOmUhXvcYBYTmIqJp+UgMh9D6wi8t0f5kGqxSkaqUSpjQyrYq9NLN4833oBCbhDaoJcXhZDEp2IvgMNQHsOHU9qvjNKG8cyBHFYYdwrm251reHcnyQ+Mb7dFRkwIx44KTisrK0kMGDEBkJPgI1CKC9SSH8JYSn0TLzHZsJkQEZhBa/pxgtOs4wD0q8AkaukzWSvx3khunUDncS0VcG4kEZLzofbeMWEFJxKhtRXnEnxZykp12qHhMk1yL5Uu4NXSR16rMAFluZe1EuJWCeBMysB8K6dJpjudNngfx0giRgCKYmJ0hVYl9Fka7YWMAfFR7LziwNMwURen9QILsNEDZeAKV5vhuMh5PEuKMiIiDDkDggHnnpBl3jnl8mzUq0qRSKd13pK8lARwe1HK5sr57U/CT8EHAxNcCz4rnj/hPMvJiPHwFjemb6U5BDWn4WqAiWZICkoMLSl+DhtZDnVdTMe1zvnm03OpOt1uR6nZu0eDQXcpeFVNDvNcm+PFrC5Lx6MoS+OWH8jYleVnpfb+eJwbY7rnrw1HaVqNsyxct9tKJv3eMu736uN+3yx7/YQzxh44v3dcgr3/erZ3/j4fx8MbJ8dVBf3+wfHpBlmvV4ej0Xw+WijO8jCMohbR7s47mna75d759suXQo+Q56PXrDdJupnPEKzbP9EGcTbfkDFaQhAEKghu/2cUcCt4UfDK4HOCLwp+NvjF4HeDvwiC2XbXNHMGA7W1uJ5P1ZlcsbYgow8XR/uNuqfV2ol116xKbMc0/wlVZOQRpi2FdAbg6/lUx8yurMqpfEy/y3k1Bv1kwVFGXFaCKU5KFlYWK7GbyYGjkKZcamRHeZMN37SUQmYqy2TaK1PJsppPUVljQMtKam5ew4nNegc/nWlFOgwnHUME1rVmF2Sc5O04l22bxtbApUlEreoGtxZ0FCmljK8XIRet1mTYZkzLJCknkxf0++CcP35ozI45RdHq26PQ2FEc+V+NY2sHxLrfptQoiiBJ+ufq0GJaT6etUauPaREjUhQOAbJcysHqroX1cRQh+NCfXspzgEuHRxV29096NwZondfeG4NvASxzQODcadEbjadlKbD8JDDGfJ6n63FKutOpExF1u3kLzGBbcCzLfdR2NqrCYa/HXL/Xm/gUZK9II8Si6RwLPwOq6qB1gqGXUbvTfe3pXmdktWGnxuZpzHn1Q0qmWR7HH0sy0IpACpyfi2J30u/75PjaBqhnU/2Dv/XM+0FfODnpZsjbcdJTGqxr5ZYRYGnjONw7vtCDIZR1lgF4H4ZIaQbgnXdoP3ghSsFBnJwEQRCwQN7+NF6A9wcmuBI8L3h5EMzmsRCbKLSx6YJkOeFWDN0cErws1oPpePvwppnXs5gFvC215ICEgPHfIhTjPDwEh6ujJfw4/6m5OGqd/Xg7igxm3HBde4kIUdSGe5fv0a+/7GUve9k4y5zL2lFUlrVZLpfrNcD278dwD+y5VqdTtkrk4WPcKjud1oL3+OLv2X/yL+O4m4cRAcVRe5imn/1MqOcQUBDe/iT8G/gAfwT2LqTHw2MSR6Y6m5u6hjJMWFymxXI9q+pox821Lxn80NNPPy3l00KcV/IdUr5DqvNCnD+/hG1aZ0+25rnyO5544gnGnmCsIrrjjwtWjL2rqhbtSC8jehmx1z/22GOIjxH9/3iCgAVFEMCfwVPBODgXXA4ejH/YyrHq5ripv7eRRolYgcBgTOrqTJtNB5ahvXer1XS11+IGEMEtXlHHpM7BETz1Td+UqgtPlZ4953qWds8NBnCEh4fXbx0dHTkVnM8j2y3CU96l16+f/cqR8ykcps6f3breS9PnHB4ewmB4cu3oEL7pxmYzHMERbrePBDkvu9Sn4Cn4UNAL3hJ8fV2vwFgxDIrDnGq0KEZ/N2UGGWTAF5hIyBs8XeSzmyT0nbIPbZDp6oZ8NFvxRWloYCzcYyRq/cfGTot1tnouv0RpBpnvac3hsxGeaeJ4ECJZZCDK6zJWZ6EHowcAvtXiZGymp5MpaKMABGFVRhPnKP+cYM1YeM9vIMuqluIdsT7Q3U6rwqjI7cPEbBRyBjxNFVyOiQA/F7g2fZ+d/c9s3Hjrqtivfqa9ED7MTJYqMKYftlqSGB96P2Ks3e8xAMGcm8WltIYJkWWRqdLkynY7mcBpVTEGWlX/iyOz6gBChmR/kX4S/hHez2aSfns9oLAnyu0C0v3ieXTJRWYe/IQdBaRcGHEWGLDI2oFo9coMKBxOJvNaTFt05aSW6Pp0y8Nt4HOAcxaBks/mby7vwpDGgXj4dEVlHmijQsVIPLG0KhGiMC3DEMKwLHwIUViWYQShL66onoYRYFWmzeHhand6mrw1HQ0zmyRW8y4XHd1///33HUaO0WeySWKz4Sjl3heT9MA5Gx4fh9a5SZzQTFu/rUZxMjw8PEiSYWWdI2aSePJiygvVl1Ig5NRXRYHwXa7dcUURZWokLMrgYQPn+6KicJ32XOaa3t7vp1JQdfHC6WlmiBjp7MLpxQslCZn2+0Zr6G/BRNc8Q0aA0+l5706sQUyzFgeQrSxFNPbE+fPTKS4wzz20ARDb4PMcg+j22e1f44x4dzrYC1bBS4JvC342+G1wcAe8Gz4EPwf/gjNcMOiq6xTmL+8W0yY3yzSMbCD2+0XDtaUuQm1bmk8naeGQDYFv/uJumwM8zl2ifIg00RiTL3G9XbFzyeNhCihsVQi/miOYiedSklqFQgrJC5k3i6JqyuLw06WZFHhl46wPv1sQHIWBtMeqd4vNpJk2i2neFE0OR103CHkNcHd6QdBlmbN219NJoTKsa0UZXWApgVYGiPWz05JmCBduEsThCYv2F4YJdUrSOMS+8W49zX2D7lDWrtnsmu10AUOuO20mRY0M4GgP4ZHEol4jKwnFxweRtvrlpqgXuM5Y7BzyASVS13QiN83C6h1f6E9dNKXuym6QO0LU/yvN7yDbfnaTpDLNsQjo2ugv+6xOrAvic3NTvASntVs9zW2dLuMdVs1c/mOn0yGSFt+l94pEYKNqZmP4W6p2hDlIweBvsFncjKZ758uj48Oj7Mp0irSMjR0Nz1+ejxejTidaHB/3+vCv/yAEr0c3qytQLgdgwxBB1EbgWNRGAyDLilGsmOu90FWdZGMJynhHBIyS897FcnBKEQkhsKTHlMcV+FdKzhLBDIDvFQlyxrALrNPvEgC8zEAIjqARtNFAQNlNcAAkyUBMmZJCmp51yoSJMorOQPYIIrYvJ0QPW86jkojO9jN2jknJnlcbuDHPo+c1ahEEUQLEDGesUaZHYh6dF0rCFjjzFSIYo5//j7duKmxJog6Z/84ZhygEoiiy0nLNeEQELeQCGCVArTv39103TfJFFCVJo2d7q9X4YL/udgAWE4jjTub83t5y5KQtBSGBufDLgECMtDm7HaQUAAo4QnIETCNZgSzBHkmhlXJyOUy4UlAAPBNgWa9uGRlKEjIfPrwZGKnMAQkpN5DUflsPhQAOZQXe7vCYyygE/KoX53d7RgZi8twYUBCaVPeE9poBe2BXyBWTItchKJISKJIJKAUUJTKJ0j93CtCTSpDGdbKVUr6bnnw+o2HWJcc5CBExl77nkpqEpEiIjOcepvgCsswIzng8hyP7z8EIA3i8Zt6x5wSGCJpWZTDN+MiDWCr2RmCiXQogEMH0+u1mN9NY2YeJ59NplGG4CwE2uptfef3rX9+tqtD7sKq6b6ustbZ6R56/vluhAtxN1f2hyhnjqh/J82cf6htKcC7UF0bRuyZQDMsn3+rDqtXptKrQQ5k9v11KUlxeGdOEvri/EkJ9sRIiLcsUymry/knJEg/mDupX57tsNYE18J6mhWVMtzEAG9Y7P8kmMahNVBEfmQHKYRfdVZZFxagcguBtTffNzE0QLToxGLvxQFf921N0Mgnn2EvKxzPAK8G495BlNYC0tltluakJlFIJ41YRo0gmxqiQgZK+rLT1vkW8qkZdJUlFMWSAykVhWE4sZyza6/cdYVZWSUp5eDb3kFmHPunXQ6wYZQN9NBwdIREkOUsIkIbOMyEOZ/NxWymAvpMSnFfhnM4L8JBVry0fl5zbkpmuZVXSimFqmm3rHue+wBibhIaOS2gliozYtm0C4yiu4sFEmkJWQP0yYojkjTO/hG5Cl9Gb0AfyMoWpgMT/CGQqMmxJqVLBcxQkGiNCODLSf3et+JIvRDQullMqoc7LOvnoIrgGZc9QdDKluw6MzV8u/b1qNPdptl0NbRtkrWaA44SpZYnVeU0IpyI4AHU3N47fsLFh77bS1PCjqBhsbE+mFgHQ9bm8DOKKKX3f87heqQQ/QeKIkCgmbyZRRGkUkadBNyjx3LTquJTpCkgULrYrCf/77ZWyVQ1DsOwAIsvCQZB6E8u0wPNqUeXI/BzA8tLJX7WqabZvPGo2AXq9Tdfv1utQOC6lMUSM2V9P0zRN0zQ9YhJsuqYJpukYhBh+GGJwvRpCOZqZ9OtYh5fQCtpE96BH0bvrZpeMfLBsJYl5kMlWY5T7zbjol/mywDTbjouhe1vNWYXvCFFyaUKzUYiv0pYTrwhwFbEWdaI4fgSf+VW9SPk7KVqLuSiN4ZnogRFly8wCvoMZY2kMlX1KPfByjHH88gNKg4VEF0ENf3mcbxT98COTyQRwQAMMY8a5SUze6wnDFJw/UobwJI7974375/wYPym086P3vI3lvudBm5E5CBXIrQelfABH/xTjB6QcbCRpaSbOU9511/t+5PbbbydkKcA4WCL4oq7rxuHDOui6/iObZ3DjQIT3/nY8fw7HO40kHludo02s2PnzHK/RRpc9MBOLcE7hD8KKc8q5E4rCwmQMRfE46CFOSUbWDpCntU8n4xxeeOmllzTd0GZGoWXxYdU03TgMtWUfdGVZyiTUtSmlw/dL2fbp+qqUf/LSSy9JOTvmlhUORRhGnmXVlt6uXFdXynJd+bQwLX30Ps3QtZek/Kpm6Foeb/D8H8lBMdpBt6A70X01N0blXSSzhQEGeH+aKocHROFoNB7d5ScszQdFv4z/H14dyR7VSDYHHjQ0U8+DcatWH32HUdP3Tcp+b2/rY6SokyBsgGGm5kwTXTUr1tCewhppum40IP/OMqvjth/bNoRFUTQHH2g2m4PGt4TgMAeCi5djG6h6HTUtTZkArmMaoGmBpSslDAxLFUKIdb2/4pvmh5ZBN6I7PnSC+G1RQyjx/4cX8I/qZf+Nh96LPuyd1E48cJhRcH7BIaIosrUbTiK0J+0ZAzPLMS3M8DWPeWAiloD4rJUP3bZyNMqMBPpxeQ2k660sdun6Wgz+3BuNz+Jjy2maJktet5t13aUkTdPl43BfWcLq2ptuLks/CfZt3vXm7W2A7e0337W5z//wfoBj8/6sY2Mg5zAYRheDYXTteW/O9+f9+aNdwwCcGQZxjgHsF6Y58efGkWFEkWGEbznc75PiOKTp8lKaQqZ0Q29Dmi4tpykcL+ja6oNvWlvr50dvXFwE2N5+85u3twEWF2/8CD94DKpaUkkT424RhmHIeRiGEf9ITWaZrMKIh2EYCh6FYch/EI4dEM1+blZNI4oMI4oMhGruKH4Dr+Q5XqfZZHvjHot+WUnsahA7esFLB4MtSSZBQ9hjgBMxjWvbmmhNaVKqb1SIYtTbWm2xF2z2s60XG7ROBxMz0Dq9f6tHEse9tvafvpy/6Zlnnjn1vmXPK3JFUGpR2fWq6e2farVaUVeXvbRlf+q3f/u3HcYbfNqaVhxdnDy49ztJkliJoStGhDTCMAyN0NJ1ioUwAcPnFQaKygMz7n0KYwxZ4HcIxVHYqgcBXyO/fCHLLvS+fzOP559iie/Lc3/QXWXMdYS4ZwCaNExCAHEk0CW8Cm1UQQtoDZ1Fl9Cjc3IYRTaBYaKiJkykUiPROt+WifHpTj4oRGEFeSKadkQ+ngijA2bJoAzIuDhn5ILnrlJqgVcXU7pkLs7O/dfBYDDAcRxHuHZBp8FAgpDgMCT/Uyc8jsl4SdMoxbZFRlG904rzfD0fE88j0Lp27dqZM6dOXXvLW64BZUEwWApCRn/w/vvvB01rdzQFx70wYQyuYWxa7ZZhQGu0bjyEV5Mk8QBj34dYrhos/upVGy2gkQQ1kGCTh4GNI7mgGz07GqkZiVV7DAylTybIl5aWloeuhyEM5/MhvszZRqPRsHUbvh/C2Hv27NmzZ1erab0+BvpJXE2jVhTBL/YOu3sfeyUm7KbMw//pFdxq5nON5mss8CxywePogwjBfB+bRRgUIIwy5wjUqOD3UUemOgqeRhlOjE6SGuU6wgoxe4HIJblqxMivnTi/p5yPg86fKYIwioMcrhEsrKpp2zYXLwtOqa7rilAlCVFCYNKk3LZts2oJTA47UezQZ2Zo9HuzO7kXzs/MNOazrKa0bHY2nK3VtpaXMCXxj91oslavm1AFBt37gaXwrw9mgmDdfJTig2dekPL/1DS7o3vr1TctLQC/neddAw/V9+rRs2bYgAExpXef0igv7z9wYJ9+48aNKymJ6N+tW1lMVfGT8Tv23jfyKH+gR8srygf2pWvBtvk1wICbNldQYBGwmmv99MGIGmoSGHRENVua4US9g6Z0xf9byeTo3XvsmK3Oirq6Hj3HJMb07DETCGlTrB6JXokoLSmtrE53617dvXtTdWVpSWkkevkfARPl9s67GLg7br/pf78NzmT4BJxQk8kMbkim0411EYmSuH4qVtWlmpoGN6bKysvLUo2Dm5pSdVWRSGZvNkrqO6fTyWlI/yUN4FIiRclYSheR6EXiS8oKlBUpL1D+AxXXUpmj8heqLqU6QU2CmmupTVF7KrU/UHcv9S/SsAvJBMlldKql0yo6V9L5XhpzND5IaiKpZ2nqRdO5pGtJX0tzluZ/yFzIJi/SJUuXK+laS9dz6Zal24V0T9JjGj1/oNeD9D6WPin63Eq/V+k/jYGDGPgmg+YxBCMPYOQvZLOMyjHqSVpupDVH66m03Uv7vYxZxtgHGd+N8Q8yIcOkE5nSjVwHmyXY7Es2z7P5m2xRZMtP2XYe2x3JDll2eJMdP2WnIrsl2O1epnZjn3nkb2S/FPvdyv5JDsxy0DAOHsvBz1I4gENv5egUx1RybBvHXsjxRU54lxNP5KQ8pxzKtAzTbmTGOmZ+yuxBzMkw50HmFpj3KPP7Mf9c5v/BwhQLX2XRASwexuIrWTKRpR+y7EqWT2T5uawYy8oUK9/l1BynFjnrWc7JsqqD1Tuwph9rXmTtnazPs/5TNvzCxjM5t8D5lVzwKhd2cOGjXLQLF//ApXtwWYHLs1xe5IobufJZrrmW6yq5IcmNCW7KcfO53PIut6W4bR53duPOR7nrRu45l3sf5YFdeGgYD3/IIx082sZjSR7v4IlXeXIHnjqRpw/lmW48u46XxvJKnlev5Y023urF2xneyfPukbz/Dx+cycev8kmeT1N8+gefJ/nqTL7u4JtVFFfxHb6bxveD+H4RvyX57UP+uJC/Mvyd5Z9p/PMH/z7Lfz8IORG1oiQvyo4U5VuIymWiahtRfaiomSjqpon6N0VDrWg4VTS8KZI/iM4TReMuIpUTqRtFOiOatxDNv4jMKrHJLNGlTXS5UHTdQ3TrJbpPFD0qRc+86LVO9L5X9O0mBhCDimLwrWJohxg2VozMiuwwMapWjHpUtJwq2ipFe0a0nyrGtolxe4gJY8XEM8WkP8TkVWLKo2KzW8UWGbHlLmLrWrHtWLHto2K7J8X2j4qdPhS75MSuebH7KrHHsWLPnNgrKaYmxNQvxT5HivyNYt93xf5nigMeFQdlxEHvioP/EYVp4pAjxaEnikP/EYctEsfsIo59Uhz3hzj+WnHCp+LEReLED8XJCXHKNmJaUUzfQcyaJWbXitkFMWeimPOmmPulWJwVS5Ji6ati2Syx/F6x4k6xMiNWnitOfVWsqhRr14l1W4gNh4qNSXHuIHHeteL8O8XlSXHFKnHlkeKqaeKagri2TVx7r7geDy3ENrfDtnyObTmPbRuLbb+O7aiB7diO7ZyI7SqI7Z6K7QXbuxY7AHY4HjtyGjvWCju2Gzu+Hzu5HjsbxM71wc63wi542MVm2KXd2JWS2JUIdm0odj0Gu3EZu5UVuzUQu50Ru1MSu1sSu9cKe9gOe9QIe3IaezoSe/oYe74bexmPvY5gb/7A3n+PfaiAfdyMRb7GfhqJ/fwH9utA7NfX2G8O9vtt7M/N2F+3sf+mYv+fRhlqoAzrUeZ6KPtUlP0+ylEP5a6N8tdG+WeiQhlRoU6oSEFUZDsqmoxKOsjJi5x45LxHZeeiclNRueuowkpUKQ1V7oSqLEXVIqj6P6jGfRRVEkUHUcxMFNsJxQ1Ftdai2s9RnT+QL4LqX0cN7qOGEdR4KGo6FDXbjZrfRy1jUOtWqG0QtY2g9u9Rp5WoSzcU3w59lxN9PxUlDETJ36PUlSh9Leq7GQVmIrcTCuZFwccoVBKFuyFvJOrfDvX/Aw1MRgMvo0FBNLgRGhpEw0ai8afRzBg030MLBqJFRdGauWjNc7RuLFoXQeunoo0e2lwFbcmKtq5E296jHUPRzs1od1G053O0dyXaF4P2e+hoPDrWCh3PiY7PRCf/QaeLojMj0dmZ6HwEXayNLr9GV35BVw+jaxPRjYLoVl50/3v0oBt6VAE9Xo+eFkRPL6Nn99GLgejlbfTqH/T6Pnobj94NBQpbbgwAKM4eDACjFNUwiHuvSfnrNEOt+PPyaMZ2BzMRx7WDmSnOioPZqcG3B3NQhLYH81KIyZrvMdIMWMZskQu7AT8fNBrYFwdFbut4MANtLNNoxp8PZiJZ6w5mprZaHszO53bkYA6ibM7BvFRTsauWj9zWsY0b8JzmA/xht6/fqeu0CCUEksNOD39qvz4JoZp1o+pExf698dbj0zwvGG4QHZ3iBryEe/ysH5Xk9o1P8zsD/ImVw05fN+w5QTfYr09CyElPcgNO2O85CYFkx3PdPr3Tvahns9zGDXjP0NZd6mr+8wJausFBofTUNM+pklTVeSkv8af+UDjdDTg+X62omNhYX2w9Xx2nyou1/Zv5Bs6LnFSVNrgE8HBozgDTJpNc+uLHoS4OLQiVw1SaTBinlInyqfSjDwmEzKE8tCjqEEXstX8n3e+jp+HhESRMA6KJJuXeNif8plFi3rQv8aQ92+wA/CRS+T7jvrjfuRKOdwjiEnzGsUO6cDgbwCGMvxWfyT99OXi4uPShN+l4RL0G03rIb5vrttuq5uvUls8tHUSI9O9GCB9vHg5VSKIqzqPnP8VPiDDpbao7+PBRiyhiiCUWH7HUw0ede9vgK9jc/560wfts3kVbtYh8NnhiAAMA) format("woff2")}.fa-brands,.fab{font-weight:400}.fa-monero:before{content:"\f3d0"}.fa-hooli:before{content:"\f427"}.fa-yelp:before{content:"\f1e9"}.fa-cc-visa:before{content:"\f1f0"}.fa-lastfm:before{content:"\f202"}.fa-shopware:before{content:"\f5b5"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-aws:before{content:"\f375"}.fa-redhat:before{content:"\f7bc"}.fa-yoast:before{content:"\f2b1"}.fa-cloudflare:before{content:"\e07d"}.fa-ups:before{content:"\f7e0"}.fa-pixiv:before{content:"\e640"}.fa-wpexplorer:before{content:"\f2de"}.fa-dyalog:before{content:"\f399"}.fa-bity:before{content:"\f37a"}.fa-stackpath:before{content:"\f842"}.fa-buysellads:before{content:"\f20d"}.fa-first-order:before{content:"\f2b0"}.fa-modx:before{content:"\f285"}.fa-guilded:before{content:"\e07e"}.fa-vnv:before{content:"\f40b"}.fa-js-square:before,.fa-square-js:before{content:"\f3b9"}.fa-microsoft:before{content:"\f3ca"}.fa-qq:before{content:"\f1d6"}.fa-orcid:before{content:"\f8d2"}.fa-java:before{content:"\f4e4"}.fa-invision:before{content:"\f7b0"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-centercode:before{content:"\f380"}.fa-glide-g:before{content:"\f2a6"}.fa-drupal:before{content:"\f1a9"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-unity:before{content:"\e049"}.fa-whmcs:before{content:"\f40d"}.fa-rocketchat:before{content:"\f3e8"}.fa-vk:before{content:"\f189"}.fa-untappd:before{content:"\f405"}.fa-mailchimp:before{content:"\f59e"}.fa-css3-alt:before{content:"\f38b"}.fa-reddit-square:before,.fa-square-reddit:before{content:"\f1a2"}.fa-vimeo-v:before{content:"\f27d"}.fa-contao:before{content:"\f26d"}.fa-square-font-awesome:before{content:"\e5ad"}.fa-deskpro:before{content:"\f38f"}.fa-brave:before{content:"\e63c"}.fa-sistrix:before{content:"\f3ee"}.fa-instagram-square:before,.fa-square-instagram:before{content:"\e055"}.fa-battle-net:before{content:"\f835"}.fa-the-red-yeti:before{content:"\f69d"}.fa-hacker-news-square:before,.fa-square-hacker-news:before{content:"\f3af"}.fa-edge:before{content:"\f282"}.fa-threads:before{content:"\e618"}.fa-napster:before{content:"\f3d2"}.fa-snapchat-square:before,.fa-square-snapchat:before{content:"\f2ad"}.fa-google-plus-g:before{content:"\f0d5"}.fa-artstation:before{content:"\f77a"}.fa-markdown:before{content:"\f60f"}.fa-sourcetree:before{content:"\f7d3"}.fa-google-plus:before{content:"\f2b3"}.fa-diaspora:before{content:"\f791"}.fa-foursquare:before{content:"\f180"}.fa-stack-overflow:before{content:"\f16c"}.fa-github-alt:before{content:"\f113"}.fa-phoenix-squadron:before{content:"\f511"}.fa-pagelines:before{content:"\f18c"}.fa-algolia:before{content:"\f36c"}.fa-red-river:before{content:"\f3e3"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-safari:before{content:"\f267"}.fa-google:before{content:"\f1a0"}.fa-font-awesome-alt:before,.fa-square-font-awesome-stroke:before{content:"\f35c"}.fa-atlassian:before{content:"\f77b"}.fa-linkedin-in:before{content:"\f0e1"}.fa-digital-ocean:before{content:"\f391"}.fa-nimblr:before{content:"\f5a8"}.fa-chromecast:before{content:"\f838"}.fa-evernote:before{content:"\f839"}.fa-hacker-news:before{content:"\f1d4"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-adversal:before{content:"\f36a"}.fa-creative-commons:before{content:"\f25e"}.fa-watchman-monitoring:before{content:"\e087"}.fa-fonticons:before{content:"\f280"}.fa-weixin:before{content:"\f1d7"}.fa-shirtsinbulk:before{content:"\f214"}.fa-codepen:before{content:"\f1cb"}.fa-git-alt:before{content:"\f841"}.fa-lyft:before{content:"\f3c3"}.fa-rev:before{content:"\f5b2"}.fa-windows:before{content:"\f17a"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-square-viadeo:before,.fa-viadeo-square:before{content:"\f2aa"}.fa-meetup:before{content:"\f2e0"}.fa-centos:before{content:"\f789"}.fa-adn:before{content:"\f170"}.fa-cloudsmith:before{content:"\f384"}.fa-opensuse:before{content:"\e62b"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-dribbble-square:before,.fa-square-dribbble:before{content:"\f397"}.fa-codiepie:before{content:"\f284"}.fa-node:before{content:"\f419"}.fa-mix:before{content:"\f3cb"}.fa-steam:before{content:"\f1b6"}.fa-cc-apple-pay:before{content:"\f416"}.fa-scribd:before{content:"\f28a"}.fa-debian:before{content:"\e60b"}.fa-openid:before{content:"\f19b"}.fa-instalod:before{content:"\e081"}.fa-expeditedssl:before{content:"\f23e"}.fa-sellcast:before{content:"\f2da"}.fa-square-twitter:before,.fa-twitter-square:before{content:"\f081"}.fa-r-project:before{content:"\f4f7"}.fa-delicious:before{content:"\f1a5"}.fa-freebsd:before{content:"\f3a4"}.fa-vuejs:before{content:"\f41f"}.fa-accusoft:before{content:"\f369"}.fa-ioxhost:before{content:"\f208"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-app-store:before{content:"\f36f"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-itunes-note:before{content:"\f3b5"}.fa-golang:before{content:"\e40f"}.fa-kickstarter:before{content:"\f3bb"}.fa-grav:before{content:"\f2d6"}.fa-weibo:before{content:"\f18a"}.fa-uncharted:before{content:"\e084"}.fa-firstdraft:before{content:"\f3a1"}.fa-square-youtube:before,.fa-youtube-square:before{content:"\f431"}.fa-wikipedia-w:before{content:"\f266"}.fa-rendact:before,.fa-wpressr:before{content:"\f3e4"}.fa-angellist:before{content:"\f209"}.fa-galactic-republic:before{content:"\f50c"}.fa-nfc-directional:before{content:"\e530"}.fa-skype:before{content:"\f17e"}.fa-joget:before{content:"\f3b7"}.fa-fedora:before{content:"\f798"}.fa-stripe-s:before{content:"\f42a"}.fa-meta:before{content:"\e49b"}.fa-laravel:before{content:"\f3bd"}.fa-hotjar:before{content:"\f3b1"}.fa-bluetooth-b:before{content:"\f294"}.fa-square-letterboxd:before{content:"\e62e"}.fa-sticker-mule:before{content:"\f3f7"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-hips:before{content:"\f452"}.fa-behance:before{content:"\f1b4"}.fa-reddit:before{content:"\f1a1"}.fa-discord:before{content:"\f392"}.fa-chrome:before{content:"\f268"}.fa-app-store-ios:before{content:"\f370"}.fa-cc-discover:before{content:"\f1f2"}.fa-wpbeginner:before{content:"\f297"}.fa-confluence:before{content:"\f78d"}.fa-shoelace:before{content:"\e60c"}.fa-mdb:before{content:"\f8ca"}.fa-dochub:before{content:"\f394"}.fa-accessible-icon:before{content:"\f368"}.fa-ebay:before{content:"\f4f4"}.fa-amazon:before{content:"\f270"}.fa-unsplash:before{content:"\e07c"}.fa-yarn:before{content:"\f7e3"}.fa-square-steam:before,.fa-steam-square:before{content:"\f1b7"}.fa-500px:before{content:"\f26e"}.fa-square-vimeo:before,.fa-vimeo-square:before{content:"\f194"}.fa-asymmetrik:before{content:"\f372"}.fa-font-awesome-flag:before,.fa-font-awesome-logo-full:before,.fa-font-awesome:before{content:"\f2b4"}.fa-gratipay:before{content:"\f184"}.fa-apple:before{content:"\f179"}.fa-hive:before{content:"\e07f"}.fa-gitkraken:before{content:"\f3a6"}.fa-keybase:before{content:"\f4f5"}.fa-apple-pay:before{content:"\f415"}.fa-padlet:before{content:"\e4a0"}.fa-amazon-pay:before{content:"\f42c"}.fa-github-square:before,.fa-square-github:before{content:"\f092"}.fa-stumbleupon:before{content:"\f1a4"}.fa-fedex:before{content:"\f797"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-shopify:before{content:"\e057"}.fa-neos:before{content:"\f612"}.fa-square-threads:before{content:"\e619"}.fa-hackerrank:before{content:"\f5f7"}.fa-researchgate:before{content:"\f4f8"}.fa-swift:before{content:"\f8e1"}.fa-angular:before{content:"\f420"}.fa-speakap:before{content:"\f3f3"}.fa-angrycreative:before{content:"\f36e"}.fa-y-combinator:before{content:"\f23b"}.fa-empire:before{content:"\f1d1"}.fa-envira:before{content:"\f299"}.fa-google-scholar:before{content:"\e63b"}.fa-gitlab-square:before,.fa-square-gitlab:before{content:"\e5ae"}.fa-studiovinari:before{content:"\f3f8"}.fa-pied-piper:before{content:"\f2ae"}.fa-wordpress:before{content:"\f19a"}.fa-product-hunt:before{content:"\f288"}.fa-firefox:before{content:"\f269"}.fa-linode:before{content:"\f2b8"}.fa-goodreads:before{content:"\f3a8"}.fa-odnoklassniki-square:before,.fa-square-odnoklassniki:before{content:"\f264"}.fa-jsfiddle:before{content:"\f1cc"}.fa-sith:before{content:"\f512"}.fa-themeisle:before{content:"\f2b2"}.fa-page4:before{content:"\f3d7"}.fa-hashnode:before{content:"\e499"}.fa-react:before{content:"\f41b"}.fa-cc-paypal:before{content:"\f1f4"}.fa-squarespace:before{content:"\f5be"}.fa-cc-stripe:before{content:"\f1f5"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-bitcoin:before{content:"\f379"}.fa-keycdn:before{content:"\f3ba"}.fa-opera:before{content:"\f26a"}.fa-itch-io:before{content:"\f83a"}.fa-umbraco:before{content:"\f8e8"}.fa-galactic-senate:before{content:"\f50d"}.fa-ubuntu:before{content:"\f7df"}.fa-draft2digital:before{content:"\f396"}.fa-stripe:before{content:"\f429"}.fa-houzz:before{content:"\f27c"}.fa-gg:before{content:"\f260"}.fa-dhl:before{content:"\f790"}.fa-pinterest-square:before,.fa-square-pinterest:before{content:"\f0d3"}.fa-xing:before{content:"\f168"}.fa-blackberry:before{content:"\f37b"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-playstation:before{content:"\f3df"}.fa-quinscape:before{content:"\f459"}.fa-less:before{content:"\f41d"}.fa-blogger-b:before{content:"\f37d"}.fa-opencart:before{content:"\f23d"}.fa-vine:before{content:"\f1ca"}.fa-signal-messenger:before{content:"\e663"}.fa-paypal:before{content:"\f1ed"}.fa-gitlab:before{content:"\f296"}.fa-typo3:before{content:"\f42b"}.fa-reddit-alien:before{content:"\f281"}.fa-yahoo:before{content:"\f19e"}.fa-dailymotion:before{content:"\e052"}.fa-affiliatetheme:before{content:"\f36b"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-bootstrap:before{content:"\f836"}.fa-odnoklassniki:before{content:"\f263"}.fa-nfc-symbol:before{content:"\e531"}.fa-mintbit:before{content:"\e62f"}.fa-ethereum:before{content:"\f42e"}.fa-speaker-deck:before{content:"\f83c"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-patreon:before{content:"\f3d9"}.fa-avianex:before{content:"\f374"}.fa-ello:before{content:"\f5f1"}.fa-gofore:before{content:"\f3a7"}.fa-bimobject:before{content:"\f378"}.fa-brave-reverse:before{content:"\e63d"}.fa-facebook-f:before{content:"\f39e"}.fa-google-plus-square:before,.fa-square-google-plus:before{content:"\f0d4"}.fa-mandalorian:before{content:"\f50f"}.fa-first-order-alt:before{content:"\f50a"}.fa-osi:before{content:"\f41a"}.fa-google-wallet:before{content:"\f1ee"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-periscope:before{content:"\f3da"}.fa-fulcrum:before{content:"\f50b"}.fa-cloudscale:before{content:"\f383"}.fa-forumbee:before{content:"\f211"}.fa-mizuni:before{content:"\f3cc"}.fa-schlix:before{content:"\f3ea"}.fa-square-xing:before,.fa-xing-square:before{content:"\f169"}.fa-bandcamp:before{content:"\f2d5"}.fa-wpforms:before{content:"\f298"}.fa-cloudversify:before{content:"\f385"}.fa-usps:before{content:"\f7e1"}.fa-megaport:before{content:"\f5a3"}.fa-magento:before{content:"\f3c4"}.fa-spotify:before{content:"\f1bc"}.fa-optin-monster:before{content:"\f23c"}.fa-fly:before{content:"\f417"}.fa-aviato:before{content:"\f421"}.fa-itunes:before{content:"\f3b4"}.fa-cuttlefish:before{content:"\f38c"}.fa-blogger:before{content:"\f37c"}.fa-flickr:before{content:"\f16e"}.fa-viber:before{content:"\f409"}.fa-soundcloud:before{content:"\f1be"}.fa-digg:before{content:"\f1a6"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-letterboxd:before{content:"\e62d"}.fa-symfony:before{content:"\f83d"}.fa-maxcdn:before{content:"\f136"}.fa-etsy:before{content:"\f2d7"}.fa-facebook-messenger:before{content:"\f39f"}.fa-audible:before{content:"\f373"}.fa-think-peaks:before{content:"\f731"}.fa-bilibili:before{content:"\e3d9"}.fa-erlang:before{content:"\f39d"}.fa-x-twitter:before{content:"\e61b"}.fa-cotton-bureau:before{content:"\f89e"}.fa-dashcube:before{content:"\f210"}.fa-42-group:before,.fa-innosoft:before{content:"\e080"}.fa-stack-exchange:before{content:"\f18d"}.fa-elementor:before{content:"\f430"}.fa-pied-piper-square:before,.fa-square-pied-piper:before{content:"\e01e"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-palfed:before{content:"\f3d8"}.fa-superpowers:before{content:"\f2dd"}.fa-resolving:before{content:"\f3e7"}.fa-xbox:before{content:"\f412"}.fa-searchengin:before{content:"\f3eb"}.fa-tiktok:before{content:"\e07b"}.fa-facebook-square:before,.fa-square-facebook:before{content:"\f082"}.fa-renren:before{content:"\f18b"}.fa-linux:before{content:"\f17c"}.fa-glide:before{content:"\f2a5"}.fa-linkedin:before{content:"\f08c"}.fa-hubspot:before{content:"\f3b2"}.fa-deploydog:before{content:"\f38e"}.fa-twitch:before{content:"\f1e8"}.fa-ravelry:before{content:"\f2d9"}.fa-mixer:before{content:"\e056"}.fa-lastfm-square:before,.fa-square-lastfm:before{content:"\f203"}.fa-vimeo:before{content:"\f40a"}.fa-mendeley:before{content:"\f7b3"}.fa-uniregistry:before{content:"\f404"}.fa-figma:before{content:"\f799"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-dropbox:before{content:"\f16b"}.fa-instagram:before{content:"\f16d"}.fa-cmplid:before{content:"\e360"}.fa-upwork:before{content:"\e641"}.fa-facebook:before{content:"\f09a"}.fa-gripfire:before{content:"\f3ac"}.fa-jedi-order:before{content:"\f50e"}.fa-uikit:before{content:"\f403"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-phabricator:before{content:"\f3db"}.fa-ussunnah:before{content:"\f407"}.fa-earlybirds:before{content:"\f39a"}.fa-trade-federation:before{content:"\f513"}.fa-autoprefixer:before{content:"\f41c"}.fa-whatsapp:before{content:"\f232"}.fa-slideshare:before{content:"\f1e7"}.fa-google-play:before{content:"\f3ab"}.fa-viadeo:before{content:"\f2a9"}.fa-line:before{content:"\f3c0"}.fa-google-drive:before{content:"\f3aa"}.fa-servicestack:before{content:"\f3ec"}.fa-simplybuilt:before{content:"\f215"}.fa-bitbucket:before{content:"\f171"}.fa-imdb:before{content:"\f2d8"}.fa-deezer:before{content:"\e077"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-jira:before{content:"\f7b1"}.fa-docker:before{content:"\f395"}.fa-screenpal:before{content:"\e570"}.fa-bluetooth:before{content:"\f293"}.fa-gitter:before{content:"\f426"}.fa-d-and-d:before{content:"\f38d"}.fa-microblog:before{content:"\e01a"}.fa-cc-diners-club:before{content:"\f24c"}.fa-gg-circle:before{content:"\f261"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-yandex:before{content:"\f413"}.fa-readme:before{content:"\f4d5"}.fa-html5:before{content:"\f13b"}.fa-sellsy:before{content:"\f213"}.fa-sass:before{content:"\f41e"}.fa-wirsindhandwerk:before,.fa-wsh:before{content:"\e2d0"}.fa-buromobelexperte:before{content:"\f37f"}.fa-salesforce:before{content:"\f83b"}.fa-octopus-deploy:before{content:"\e082"}.fa-medapps:before{content:"\f3c6"}.fa-ns8:before{content:"\f3d5"}.fa-pinterest-p:before{content:"\f231"}.fa-apper:before{content:"\f371"}.fa-fort-awesome:before{content:"\f286"}.fa-waze:before{content:"\f83f"}.fa-cc-jcb:before{content:"\f24b"}.fa-snapchat-ghost:before,.fa-snapchat:before{content:"\f2ab"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-rust:before{content:"\e07a"}.fa-wix:before{content:"\f5cf"}.fa-behance-square:before,.fa-square-behance:before{content:"\f1b5"}.fa-supple:before{content:"\f3f9"}.fa-webflow:before{content:"\e65c"}.fa-rebel:before{content:"\f1d0"}.fa-css3:before{content:"\f13c"}.fa-staylinked:before{content:"\f3f5"}.fa-kaggle:before{content:"\f5fa"}.fa-space-awesome:before{content:"\e5ac"}.fa-deviantart:before{content:"\f1bd"}.fa-cpanel:before{content:"\f388"}.fa-goodreads-g:before{content:"\f3a9"}.fa-git-square:before,.fa-square-git:before{content:"\f1d2"}.fa-square-tumblr:before,.fa-tumblr-square:before{content:"\f174"}.fa-trello:before{content:"\f181"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-get-pocket:before{content:"\f265"}.fa-perbyte:before{content:"\e083"}.fa-grunt:before{content:"\f3ad"}.fa-weebly:before{content:"\f5cc"}.fa-connectdevelop:before{content:"\f20e"}.fa-leanpub:before{content:"\f212"}.fa-black-tie:before{content:"\f27e"}.fa-themeco:before{content:"\f5c6"}.fa-python:before{content:"\f3e2"}.fa-android:before{content:"\f17b"}.fa-bots:before{content:"\e340"}.fa-free-code-camp:before{content:"\f2c5"}.fa-hornbill:before{content:"\f592"}.fa-js:before{content:"\f3b8"}.fa-ideal:before{content:"\e013"}.fa-git:before{content:"\f1d3"}.fa-dev:before{content:"\f6cc"}.fa-sketch:before{content:"\f7c6"}.fa-yandex-international:before{content:"\f414"}.fa-cc-amex:before{content:"\f1f3"}.fa-uber:before{content:"\f402"}.fa-github:before{content:"\f09b"}.fa-php:before{content:"\f457"}.fa-alipay:before{content:"\f642"}.fa-youtube:before{content:"\f167"}.fa-skyatlas:before{content:"\f216"}.fa-firefox-browser:before{content:"\e007"}.fa-replyd:before{content:"\f3e6"}.fa-suse:before{content:"\f7d6"}.fa-jenkins:before{content:"\f3b6"}.fa-twitter:before{content:"\f099"}.fa-rockrms:before{content:"\f3e9"}.fa-pinterest:before{content:"\f0d2"}.fa-buffer:before{content:"\f837"}.fa-npm:before{content:"\f3d4"}.fa-yammer:before{content:"\f840"}.fa-btc:before{content:"\f15a"}.fa-dribbble:before{content:"\f17d"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-internet-explorer:before{content:"\f26b"}.fa-stubber:before{content:"\e5c7"}.fa-telegram-plane:before,.fa-telegram:before{content:"\f2c6"}.fa-old-republic:before{content:"\f510"}.fa-odysee:before{content:"\e5c6"}.fa-square-whatsapp:before,.fa-whatsapp-square:before{content:"\f40c"}.fa-node-js:before{content:"\f3d3"}.fa-edge-legacy:before{content:"\e078"}.fa-slack-hash:before,.fa-slack:before{content:"\f198"}.fa-medrt:before{content:"\f3c8"}.fa-usb:before{content:"\f287"}.fa-tumblr:before{content:"\f173"}.fa-vaadin:before{content:"\f408"}.fa-quora:before{content:"\f2c4"}.fa-square-x-twitter:before{content:"\e61a"}.fa-reacteurope:before{content:"\f75d"}.fa-medium-m:before,.fa-medium:before{content:"\f23a"}.fa-amilia:before{content:"\f36d"}.fa-mixcloud:before{content:"\f289"}.fa-flipboard:before{content:"\f44d"}.fa-viacoin:before{content:"\f237"}.fa-critical-role:before{content:"\f6c9"}.fa-sitrox:before{content:"\e44a"}.fa-discourse:before{content:"\f393"}.fa-joomla:before{content:"\f1aa"}.fa-mastodon:before{content:"\f4f6"}.fa-airbnb:before{content:"\f834"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-buy-n-large:before{content:"\f8a6"}.fa-gulp:before{content:"\f3ae"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-strava:before{content:"\f428"}.fa-ember:before{content:"\f423"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-teamspeak:before{content:"\f4f9"}.fa-pushed:before{content:"\f3e1"}.fa-wordpress-simple:before{content:"\f411"}.fa-nutritionix:before{content:"\f3d6"}.fa-wodu:before{content:"\e088"}.fa-google-pay:before{content:"\e079"}.fa-intercom:before{content:"\f7af"}.fa-zhihu:before{content:"\f63f"}.fa-korvue:before{content:"\f42f"}.fa-pix:before{content:"\e43a"}.fa-steam-symbol:before{content:"\f3f6"}:host,:root{--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:400;font-display:block;src:url(data:font/woff2;base64,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) format("woff2")}.fa-regular,.far{font-weight:400}:host,:root{--fa-style-family-classic:"Font Awesome 6 Free";--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src:url(data:font/woff2;base64,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) format("woff2")}.fa-solid,.fas{font-weight:900}@font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2"),url(../webfonts/fa-v4compatibility.ttf) format("truetype");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a} \ No newline at end of file diff --git a/public/install/assets/vendor/font-awesome/6.5.1/webfonts/fa-brands-400.woff2 b/public/install/assets/vendor/font-awesome/6.5.1/webfonts/fa-brands-400.woff2 new file mode 100644 index 00000000..36fbda7d Binary files /dev/null and b/public/install/assets/vendor/font-awesome/6.5.1/webfonts/fa-brands-400.woff2 differ diff --git a/public/install/assets/vendor/font-awesome/6.5.1/webfonts/fa-regular-400.woff2 b/public/install/assets/vendor/font-awesome/6.5.1/webfonts/fa-regular-400.woff2 new file mode 100644 index 00000000..b6cabbac Binary files /dev/null and b/public/install/assets/vendor/font-awesome/6.5.1/webfonts/fa-regular-400.woff2 differ diff --git a/public/install/assets/vendor/font-awesome/6.5.1/webfonts/fa-solid-900.woff2 b/public/install/assets/vendor/font-awesome/6.5.1/webfonts/fa-solid-900.woff2 new file mode 100644 index 00000000..824d518e Binary files /dev/null and b/public/install/assets/vendor/font-awesome/6.5.1/webfonts/fa-solid-900.woff2 differ diff --git a/public/install/assets/vendor/font-awesome/6.5.1/webfonts/fa-v4compatibility.woff2 b/public/install/assets/vendor/font-awesome/6.5.1/webfonts/fa-v4compatibility.woff2 new file mode 100644 index 00000000..e09b5a55 Binary files /dev/null and b/public/install/assets/vendor/font-awesome/6.5.1/webfonts/fa-v4compatibility.woff2 differ diff --git a/public/install/index.php b/public/install/index.php index fd59d26d..306c389b 100644 --- a/public/install/index.php +++ b/public/install/index.php @@ -1,4 +1,7 @@ - - + + @@ -173,7 +177,7 @@ $stepFile = __DIR__.'/views/'.$currentStep.'-'.(STEP_FILE_MAP[$currentStep] ?? ' window.INSTALLER_STATE_LOCALE = ; // DB 최고권한 계정 목록 — 서버 상수를 그대로 내려보내 JS 에 목록을 중복 정의하지 않는다. // 클라이언트 검증은 즉시 피드백용이며, 실제 차단은 서버 3개 경로가 담당한다. - window.INSTALLER_BLOCKED_DB_ACCOUNTS = ; + window.INSTALLER_BLOCKED_DB_ACCOUNTS = ; diff --git a/resources/css/dev-dashboard.css b/resources/css/dev-dashboard.css new file mode 100644 index 00000000..9f21d0d6 --- /dev/null +++ b/resources/css/dev-dashboard.css @@ -0,0 +1,14 @@ +/** + * 개발 대시보드 전용 스타일 + * + * 종전에는 Tailwind Play CDN(`cdn.tailwindcss.com`)이 브라우저에서 실시간으로 CSS 를 + * 만들어 줬다. 그 요청이 실패하면 대시보드가 스타일 없는 문서로 무너지고, 디버그 모드면 + * 프로덕션에서도 접근 가능한 화면이라 외부 의존을 남길 이유가 없다. + * + * 자동 소스 탐지는 끈다(`source(none)`) — 켜 두면 저장소 전체(확장 동봉 자산 포함)를 + * 훑어 빌드가 끝나지 않는다. 대시보드 blade 한 파일만 `@source` 로 지정한다. + */ + +@import "tailwindcss" source(none); + +@source "../views/dev-dashboard.blade.php"; diff --git a/resources/js/core/TemplateApp.ts b/resources/js/core/TemplateApp.ts index 02324cb5..7cdb158f 100644 --- a/resources/js/core/TemplateApp.ts +++ b/resources/js/core/TemplateApp.ts @@ -31,8 +31,13 @@ import { createLogger, Logger } from './utils/Logger'; import { webSocketManager } from './websocket/WebSocketManager'; import { getModuleAssetLoader, parseModuleAssetsFromConfig, parsePluginAssetsFromConfig, parseBundleUrlsFromConfig } from './modules'; import { SystemBannerManager } from './template-engine/SystemBannerManager'; -import { installUnloadGuard, isDocumentUnloading } from './template-engine/networkResilience'; -import { suffixed, extStaticUrl } from './support/assetUrl'; +import { + installUnloadGuard, + isDocumentUnloading, + loadScriptWithRetry, +} from './template-engine/networkResilience'; +import { notifyAssetFailure, clearAssetFailure } from './assets/AssetFailureNotice'; +import { suffixed, extStaticUrl, convertToCurrentMode } from './support/assetUrl'; import { fetchStaticFirst } from './support/fetchStaticFirst'; import { resetLocalInitTracking } from './template-engine/localInitSlot'; /** @@ -245,6 +250,14 @@ export class TemplateApp { private globalStateListeners: Set<(state: GlobalState) => void> = new Set(); /** 현재 진행 중인 라우트 변경 요청 ID (새 요청 시 이전 요청 무시용) */ private currentRouteChangeId: number = 0; + /** + * 재시도까지 실패한 레이아웃 스크립트 id 집합. + * + * 실패를 어딘가에 남기지 않으면 그 스크립트가 등록하는 핸들러가 전부 미등록이어도 + * 화면에는 "버튼이 안 눌린다" 로만 나타난다. `ModuleAssetLoader` 의 `failedJsAssets` + * 와 같은 역할이다. + */ + private failedLayoutScripts: Set = new Set(); /** 현재 레이아웃의 데이터 소스 정의 (if 조건으로 필터링된 결과 — refetch용) */ private currentDataSources: any[] = []; /** @@ -776,6 +789,8 @@ export class TemplateApp { // bundleUrls 부재 시 개별 로딩 폴백 (회귀 안전) if (!bundleUrls) { await this.loadExtensionAssetsIndividually(); + await moduleAssetLoader.loadCustomAssets(); + return; } @@ -783,6 +798,10 @@ export class TemplateApp { await moduleAssetLoader.loadBundle('module', bundleUrls.moduleJs, bundleUrls.moduleCss); await moduleAssetLoader.loadBundle('plugin', bundleUrls.pluginJs, bundleUrls.pluginCss); + // 운영자가 덧붙인 자산은 **마지막**에 붙인다 — CSS 는 나중에 온 규칙이 이기므로, + // 확장 번들보다 뒤에 와야 재정의가 성립한다. + await moduleAssetLoader.loadCustomAssets(); + logger.log('Extension bundle assets loaded successfully'); } catch (error) { // 에셋 로드 실패는 경고만 출력하고 앱 계속 진행 @@ -2067,28 +2086,7 @@ export class TemplateApp { continue; } - // 스크립트 동적 로드 (Promise로 래핑) - const loadPromise = new Promise((resolve, reject) => { - const scriptEl = document.createElement('script'); - scriptEl.src = script.src; - scriptEl.id = script.id; - scriptEl.async = script.async ?? true; - - scriptEl.onload = () => { - logger.log(`Script loaded successfully: ${script.id}`); - resolve(); - }; - - scriptEl.onerror = () => { - logger.warn(`Failed to load script: ${script.id} (${script.src})`); - // 스크립트 로드 실패는 경고만 출력하고 계속 진행 - resolve(); - }; - - document.head.appendChild(scriptEl); - }); - - loadPromises.push(loadPromise); + loadPromises.push(this.loadLayoutScript(script)); } // 모든 스크립트 로드 완료 대기 @@ -2098,6 +2096,66 @@ export class TemplateApp { } } + /** + * 레이아웃 스크립트 1건을 로드합니다 (재시도 + 실패 표면화). + * + * 종전에는 `onerror` 에서 `resolve()` 로 삼켜, 실패가 로그 한 줄 말고는 어디에도 + * 남지 않았다. 그 스크립트가 등록하는 핸들러가 전부 미등록이 되어도 사용자에게는 + * "버튼이 안 눌린다" 로만 나타났다. 같은 저장소의 `ModuleAssetLoader.loadJS` 는 + * 이미 재시도 + 실패 목록 계층을 갖고 있다 — 이 경로만 그 계층이 없었다. + * + * `convertToCurrentMode` 를 거치는 이유: 레이아웃 JSON 의 `src` 는 확장자 형태로 + * 굳어 있는데, 확장자를 정적 location 이 가로채는 서버(자산 URL 이중 모드)에서는 + * 그 형태가 404 다. 서버가 굳혀 내려준 다른 자산 URL 들과 같은 보정을 받아야 한다. + * + * 실패해도 reject 하지 않는다 — 한 스크립트의 실패가 나머지 스크립트 로드를 막지 + * 않는다는 기존 계약을 유지한다. 대신 `failedLayoutScripts` 와 안내 배너로 표면화한다. + * + * @param script 스크립트 정의 + * @returns Promise 성공·실패 모두 resolve + */ + private async loadLayoutScript(script: LayoutScript): Promise { + const url = script.src.startsWith('/') ? convertToCurrentMode(script.src) : script.src; + + try { + await loadScriptWithRetry( + url, + { id: script.id }, + { label: `layout-script:${script.id}` } + ); + + this.failedLayoutScripts.delete(script.id); + clearAssetFailure(`layout-script:${script.id}`); + logger.log(`Script loaded successfully: ${script.id}`); + } catch (error) { + this.failedLayoutScripts.add(script.id); + logger.warn(`Failed to load script after retries: ${script.id} (${url})`, error); + + notifyAssetFailure({ + id: `layout-script:${script.id}`, + label: script.id, + retry: async () => { + document.getElementById(script.id)?.remove(); + await loadScriptWithRetry( + url, + { id: script.id }, + { label: `layout-script:${script.id}` } + ); + this.failedLayoutScripts.delete(script.id); + }, + }); + } + } + + /** + * 끝내 로드하지 못한 레이아웃 스크립트 id 목록을 돌려줍니다. + * + * @returns 실패한 스크립트 id 배열 + */ + public getFailedLayoutScripts(): string[] { + return Array.from(this.failedLayoutScripts); + } + /** * 레이아웃 스크립트 src 가 로드 허용 대상인지 판정합니다 * (KVE-2026-1915 B-2 + 신뢰 출처 허용목록). diff --git a/resources/js/core/__tests__/AssetFailureNotice.test.ts b/resources/js/core/__tests__/AssetFailureNotice.test.ts new file mode 100644 index 00000000..fbbcc945 --- /dev/null +++ b/resources/js/core/__tests__/AssetFailureNotice.test.ts @@ -0,0 +1,210 @@ +/** + * 구동 자산 로드 실패 안내 배너 + * + * 실패를 표면화하지 않으면 사용자에게는 "빈 자리" 로만 나타나고, 자체 서버 로그에도 + * 흔적이 남지 않아 운영자가 원인을 특정할 수 없다. + * + * @scenario asset_class=vendored, outcome=failed + * @effects failed_asset_shows_retry_notice, notice_renders_without_host_component_on_standalone_layout + */ + +import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { + notifyAssetFailure, + clearAssetFailure, + clearAllAssetFailures, + getAssetFailures, + retryAssetFailures, + drainExternalAssetFailures, +} from '../assets/AssetFailureNotice'; + +/** 배너 컨테이너를 돌려줍니다. */ +const container = () => document.getElementById('g7-asset-failure-notice'); + +describe('AssetFailureNotice', () => { + beforeEach(() => { + clearAllAssetFailures(); + document.body.innerHTML = ''; + document.documentElement.classList.remove('dark'); + }); + + afterEach(() => { + clearAllAssetFailures(); + vi.restoreAllMocks(); + }); + + it('호스트 컴포넌트 없이 body 에 직접 배너를 세운다', () => { + notifyAssetFailure({ id: 'editor', label: '편집기' }); + + const el = container(); + + expect(el).not.toBeNull(); + expect(el?.parentElement).toBe(document.body); + expect(el?.getAttribute('role')).toBe('alert'); + expect(el?.getAttribute('aria-live')).toBe('polite'); + }); + + it('caller 가 준 문구를 그대로 보여준다', () => { + notifyAssetFailure({ + id: 'editor', + label: '편집기', + message: '편집기를 불러오지 못했습니다. 임시 입력창으로 전환했습니다.', + }); + + expect(container()?.textContent).toContain('임시 입력창으로 전환했습니다'); + }); + + it('같은 id 는 누적하지 않고 갱신한다', () => { + notifyAssetFailure({ id: 'editor', label: '편집기' }); + notifyAssetFailure({ id: 'editor', label: '편집기(갱신)' }); + + expect(getAssetFailures()).toHaveLength(1); + expect(getAssetFailures()[0].label).toBe('편집기(갱신)'); + }); + + it('여러 자산이 실패하면 건수로 합산하고 항목명을 나열한다', () => { + notifyAssetFailure({ id: 'a', label: '편집기' }); + notifyAssetFailure({ id: 'b', label: '아이콘' }); + + const text = container()?.textContent ?? ''; + + expect(getAssetFailures()).toHaveLength(2); + expect(text).toContain('2'); + expect(text).toContain('편집기'); + expect(text).toContain('아이콘'); + }); + + it('retry 가 없으면 다시 시도 버튼을 렌더하지 않는다', () => { + notifyAssetFailure({ id: 'a', label: '아이콘' }); + + expect(container()?.querySelector('[data-action="retry"]')).toBeNull(); + expect(container()?.querySelector('[data-action="close"]')).not.toBeNull(); + }); + + it('닫기 버튼은 배너를 제거한다 (자동 소멸하지 않고 사용자가 닫을 때까지 유지)', () => { + notifyAssetFailure({ id: 'a', label: '아이콘' }); + + (container()?.querySelector('[data-action="close"]') as HTMLButtonElement).click(); + + expect(container()).toBeNull(); + expect(getAssetFailures()).toHaveLength(0); + }); + + it('재시도가 성공하면 그 항목만 해제된다', async () => { + const retry = vi.fn().mockResolvedValue(undefined); + notifyAssetFailure({ id: 'a', label: '편집기', retry }); + notifyAssetFailure({ id: 'b', label: '아이콘' }); + + await retryAssetFailures(); + + expect(retry).toHaveBeenCalledTimes(1); + expect(getAssetFailures().map(f => f.id)).toEqual(['b']); + }); + + it('재시도가 실패하면 배너를 유지하고 재시도 실패를 알린다', async () => { + const retry = vi.fn().mockRejectedValue(new Error('여전히 실패')); + notifyAssetFailure({ id: 'a', label: '편집기', retry }); + + await retryAssetFailures(); + + expect(getAssetFailures()).toHaveLength(1); + expect(container()?.textContent ?? '').toContain('다시 시도'); + }); + + it('clearFailure 는 지정한 항목만 해제한다', () => { + notifyAssetFailure({ id: 'a', label: '편집기' }); + notifyAssetFailure({ id: 'b', label: '아이콘' }); + + clearAssetFailure('a'); + + expect(getAssetFailures().map(f => f.id)).toEqual(['b']); + expect(container()).not.toBeNull(); + }); + + it('모든 항목이 해제되면 컨테이너를 제거한다', () => { + notifyAssetFailure({ id: 'a', label: '편집기' }); + clearAssetFailure('a'); + + expect(container()).toBeNull(); + }); + + it('다크 모드에서 배경색이 달라진다', () => { + // 색은 개별 프로퍼티로 설정되므로 일괄 문자열 파싱 여부와 무관하게 관측된다. + notifyAssetFailure({ id: 'a', label: '편집기' }); + const light = (container()?.firstElementChild as HTMLElement).style.background; + + clearAllAssetFailures(); + document.documentElement.classList.add('dark'); + notifyAssetFailure({ id: 'a', label: '편집기' }); + const dark = (container()?.firstElementChild as HTMLElement).style.background; + + expect(light).not.toBe(''); + expect(dark).not.toBe(''); + expect(light).not.toBe(dark); + }); + + it('id 가 없는 호출은 무시한다', () => { + notifyAssetFailure({ id: '', label: '편집기' }); + + expect(getAssetFailures()).toHaveLength(0); + expect(container()).toBeNull(); + }); +}); + +describe('서버가 심은 템플릿 externals 의 실패', () => { + beforeEach(() => { + clearAllAssetFailures(); + document.body.innerHTML = ''; + delete (window as any).__g7ExternalAssetFailures; + delete (window as any).__g7ExternalAssetSink; + }); + + afterEach(() => { + clearAllAssetFailures(); + delete (window as any).__g7ExternalAssetFailures; + delete (window as any).__g7ExternalAssetSink; + }); + + it('엔진보다 먼저 쌓인 대기열을 배너로 흘려보낸다', () => { + // 이 태그들은 엔진 번들보다 먼저 평가되므로, 실패가 대기열에 쌓인 채 도착한다. + // 여기서 비우지 않으면 아이콘 폰트 실패가 화면에 영영 드러나지 않는다. + (window as any).__g7ExternalAssetFailures = [ + { id: 'template-external:https://x/fa.css', label: 'fontawesome', retry: () => Promise.resolve() }, + ]; + + drainExternalAssetFailures(); + + expect(getAssetFailures().map(f => f.label)).toEqual(['fontawesome']); + expect(container()).not.toBeNull(); + expect(container()!.textContent).toContain('fontawesome'); + }); + + it('엔진이 뜬 뒤에 생긴 실패도 곧바로 배너로 간다', () => { + drainExternalAssetFailures(); + + expect(typeof (window as any).__g7ExternalAssetSink).toBe('function'); + + (window as any).__g7ExternalAssetSink({ + id: 'template-external:https://x/pretendard.css', + label: 'pretendard', + }); + + expect(getAssetFailures().map(f => f.label)).toEqual(['pretendard']); + }); + + it('id 가 없는 항목은 배너에 싣지 않는다 (식별 불가 항목이 누적되지 않도록)', () => { + (window as any).__g7ExternalAssetFailures = [{ label: '이름만 있는 항목' }]; + + drainExternalAssetFailures(); + + expect(getAssetFailures()).toEqual([]); + }); + + it('대기열이 비어 있어도 sink 는 걸린다 (정상 부팅에서 배너를 만들지 않는다)', () => { + drainExternalAssetFailures(); + + expect(getAssetFailures()).toEqual([]); + expect(container()).toBeNull(); + expect(typeof (window as any).__g7ExternalAssetSink).toBe('function'); + }); +}); diff --git a/resources/js/core/__tests__/G7CoreGlobals.test.ts b/resources/js/core/__tests__/G7CoreGlobals.test.ts index 7050125c..aa9b9f5d 100644 --- a/resources/js/core/__tests__/G7CoreGlobals.test.ts +++ b/resources/js/core/__tests__/G7CoreGlobals.test.ts @@ -1592,3 +1592,81 @@ describe('G7Core.state.getIsolated/setIsolated API', () => { }); }); }); + +/** + * G7Core.asset / G7Core.assets — 확장이 자기 자산을 다루는 seam + * + * 확장 IIFE 번들은 코어의 `assetUrl.ts` 를 import 할 수 없다. 이 seam 이 없으면 확장은 + * URL 을 문자열로 조립하는 수밖에 없고, 그러면 확장자를 정적 location 이 가로채는 + * 서버에서 그 자산만 404 가 된다 — 지금 CDN 이 죽었을 때와 같은 증상이다. + */ +describe('G7CoreGlobals - 자산 API', () => { + let G7Core: any; + + beforeEach(() => { + delete (window as any).G7Core; + (window as any).G7Config = {}; + initializeG7CoreGlobals(createMockDependencies()); + G7Core = (window as any).G7Core; + }); + + afterEach(() => { + delete (window as any).G7Core; + delete (window as any).G7Config; + }); + + /** + * @scenario asset_class=vendored + * @effects runtime_asset_served_same_origin + */ + it('확장 타입별 자산 URL 생성기를 노출한다', () => { + expect(typeof G7Core.asset.template).toBe('function'); + expect(typeof G7Core.asset.module).toBe('function'); + expect(typeof G7Core.asset.plugin).toBe('function'); + expect(typeof G7Core.asset.templateDir).toBe('function'); + expect(typeof G7Core.asset.convertToCurrentMode).toBe('function'); + }); + + it('플러그인 자산 URL 은 same-origin API 경로다', () => { + const url = G7Core.asset.plugin('sirsoft-ckeditor5', 'dist/vendor/ckeditor5/43.3.1/ckeditor5.umd.js'); + + expect(url.startsWith('/api/plugins/assets/sirsoft-ckeditor5')).toBe(true); + expect(url).not.toMatch(/^https?:/); + }); + + it('템플릿 자산 URL 은 dist/ 를 포함하지 않는다 (서버가 자동 부가)', () => { + const url = G7Core.asset.template('sirsoft-basic', 'vendor/font-awesome/6.4.0/css/all.inlined.css'); + + expect(url).toContain('vendor/font-awesome/6.4.0/css/all.inlined.css'); + expect(url).not.toContain('/dist/'); + }); + + it('디렉토리 URL 은 뒤에 파일 경로를 이어 붙일 수 있는 형태다 (AMD 로더용)', () => { + const dir = G7Core.asset.templateDir('sirsoft-admin_basic', 'vendor/monaco-editor/0.54.0/vs'); + + expect(dir.endsWith('/vs')).toBe(true); + expect(dir).not.toContain('?file='); + }); + + it('재시도 로더를 함께 노출한다 (확장이 자기 자산을 직접 로드할 때)', () => { + expect(typeof G7Core.asset.loadScript).toBe('function'); + expect(typeof G7Core.asset.loadStylesheet).toBe('function'); + }); + + /** + * @scenario asset_class=vendored, outcome=failed + * @effects failed_asset_shows_retry_notice + */ + it('자산 실패 안내 API 를 노출한다', () => { + expect(typeof G7Core.assets.notifyFailure).toBe('function'); + expect(typeof G7Core.assets.clearFailure).toBe('function'); + expect(typeof G7Core.assets.getFailures).toBe('function'); + expect(typeof G7Core.assets.retryAll).toBe('function'); + + G7Core.assets.notifyFailure({ id: 'probe', label: '탐침' }); + expect(G7Core.assets.getFailures().map((f: any) => f.id)).toEqual(['probe']); + + G7Core.assets.clearAll(); + expect(G7Core.assets.getFailures()).toEqual([]); + }); +}); diff --git a/resources/js/core/__tests__/ModuleAssetLoader.customAssets.test.ts b/resources/js/core/__tests__/ModuleAssetLoader.customAssets.test.ts new file mode 100644 index 00000000..26d12bb9 --- /dev/null +++ b/resources/js/core/__tests__/ModuleAssetLoader.customAssets.test.ts @@ -0,0 +1,181 @@ +/** + * 사용자 추가 에셋(`custom/`) 로드 + * + * 운영자가 덧붙인 자산은 확장 병합 번들 **뒤**에 붙어야 한다 — CSS 는 나중에 온 규칙이 + * 이기므로, 앞에 붙으면 운영자의 재정의가 확장 스타일에 밀린다. + */ + +import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { ModuleAssetLoader, parseCustomAssetsFromConfig } from '../modules/ModuleAssetLoader'; +import { getAssetFailures, clearAllAssetFailures } from '../assets/AssetFailureNotice'; + +describe('ModuleAssetLoader.loadCustomAssets', () => { + let loader: ModuleAssetLoader; + let requested: Array<{ tag: string; url: string }>; + + /** + * head.appendChild 를 가로채 결과를 발화시킵니다. + * + * @param decide url 을 받아 결과를 돌려주는 판정 함수 + * @return void + */ + function stub(decide: (url: string) => 'load' | 'error' = () => 'load'): void { + vi.spyOn(document.head, 'appendChild').mockImplementation(((node: any) => { + if (node.tagName !== 'SCRIPT' && node.tagName !== 'LINK') { + return node; + } + + const url = String(node.getAttribute('src') ?? node.getAttribute('href') ?? ''); + requested.push({ tag: node.tagName, url }); + document.body.appendChild(node); + + const outcome = decide(url); + + queueMicrotask(() => { + if (outcome === 'error') { + node.onerror?.(new Event('error')); + } else { + node.onload?.(new Event('load')); + } + }); + + return node; + }) as any); + } + + beforeEach(() => { + loader = new ModuleAssetLoader(); + requested = []; + clearAllAssetFailures(); + delete (window as any).G7Config; + }); + + afterEach(() => { + vi.restoreAllMocks(); + clearAllAssetFailures(); + document.querySelectorAll('[id^="g7-custom-"]').forEach(el => el.remove()); + delete (window as any).G7Config; + }); + + describe('parseCustomAssetsFromConfig', () => { + it('설정이 없으면 빈 배열', () => { + expect(parseCustomAssetsFromConfig()).toEqual([]); + }); + + it('형식이 어긋난 항목은 버린다', () => { + (window as any).G7Config = { + customAssets: [ + { id: 'a', type: 'style', url: '/a.css' }, + { id: 'b', type: 'unknown', url: '/b.css' }, + { id: 'c', type: 'script' }, + null, + ], + }; + + expect(parseCustomAssetsFromConfig().map(a => a.id)).toEqual(['a']); + }); + }); + + /** + * @scenario custom_source=convention_scan, custom_asset=css + * @effects custom_asset_loaded_after_extension_bundles + */ + it('목록이 비면 아무 요청도 하지 않는다', async () => { + stub(); + + await loader.loadCustomAssets(); + + expect(requested).toHaveLength(0); + }); + + it('선언 순서대로 로드하고 타입에 맞는 태그를 쓴다', async () => { + (window as any).G7Config = { + customAssets: [ + { id: 'custom:templates:t:a.css', type: 'style', url: '/a.css' }, + { id: 'custom:templates:t:b.js', type: 'script', url: '/b.js' }, + ], + }; + stub(); + + await loader.loadCustomAssets(); + + expect(requested.map(r => r.tag)).toEqual(['LINK', 'SCRIPT']); + expect(requested.map(r => r.url)).toEqual(['/a.css', '/b.js']); + }); + + it('이미 로드된 항목은 다시 요청하지 않는다', async () => { + (window as any).G7Config = { + customAssets: [{ id: 'custom:templates:t:a.css', type: 'style', url: '/a.css' }], + }; + stub(); + + await loader.loadCustomAssets(); + await loader.loadCustomAssets(); + + expect(requested).toHaveLength(1); + }); + + /** + * @scenario custom_source=convention_scan, custom_asset=css, outcome=failed + * @effects failed_asset_shows_retry_notice + */ + it('실패한 항목은 안내로 표면화하되 나머지는 계속 로드한다', async () => { + (window as any).G7Config = { + customAssets: [ + { id: 'custom:templates:t:bad.css', type: 'style', url: '/bad.css' }, + { id: 'custom:templates:t:ok.css', type: 'style', url: '/ok.css' }, + ], + }; + stub(url => (url.includes('/bad.css') ? 'error' : 'load')); + + await expect(loader.loadCustomAssets()).resolves.toBeUndefined(); + + expect(loader.getFailedCssAssets()).toEqual([]); + expect(getAssetFailures().map(f => f.id)).toContain('custom-asset:custom:templates:t:bad.css'); + expect(requested.some(r => r.url === '/ok.css')).toBe(true); + }); + + /** + * 게시본이 GC 로 사라지면 정적 URL 은 404 가 확정된 주소다. 같은 URL 을 재시도해도 + * 복구되지 않으므로 종전 API URL 로 전환해야 한다 — 형제 경로(`loadBundleCss`)가 + * 이미 갖춘 계층이다. 이 계층이 없으면 화면은 정상인데 운영자 자산만 조용히 빠진다. + * + * 세 확장 타입 전부를 건다. 템플릿만 역변환하던 상태에서는 모듈·플러그인이 통과하지 + * 못한다. + */ + it.each([ + ['templates', 'sirsoft-basic', '/api/templates/assets/sirsoft-basic/custom/x.css'], + ['modules', 'sirsoft-page', '/api/modules/assets/sirsoft-page/custom/x.css'], + ['plugins', 'sirsoft-gdpr', '/api/plugins/assets/sirsoft-gdpr/custom/x.css'], + ])('정적 게시 미스는 %s 도 종전 API URL 로 전환한다', async (type, identifier, expectedApi) => { + const staticUrl = `/build/ext/1234/${type}/${identifier}/assets/custom/x.css`; + + (window as any).G7Config = { + customAssets: [ + { id: `custom:${type}:${identifier}:x.css`, type: 'style', url: staticUrl }, + ], + }; + stub(url => (url.startsWith('/build/ext/') ? 'error' : 'load')); + + await loader.loadCustomAssets(); + + // 정적 → API 순서로 정확히 두 번 요청한다 + expect(requested.map(r => r.url)).toEqual([staticUrl, `${expectedApi}?v=1234`]); + + // 폴백이 성공했으므로 실패 배너는 뜨지 않는다 + expect(getAssetFailures()).toEqual([]); + }); + + it('정적 게시 URL 이 아니면 폴백 없이 그대로 재시도한다', async () => { + (window as any).G7Config = { + customAssets: [ + { id: 'custom:templates:t:x.css', type: 'style', url: '/api/templates/assets/t/custom/x.css' }, + ], + }; + stub(() => 'load'); + + await loader.loadCustomAssets(); + + expect(requested.map(r => r.url)).toEqual(['/api/templates/assets/t/custom/x.css']); + }); +}); diff --git a/resources/js/core/__tests__/TemplateApp.layoutScripts.test.ts b/resources/js/core/__tests__/TemplateApp.layoutScripts.test.ts new file mode 100644 index 00000000..9e2e9acd --- /dev/null +++ b/resources/js/core/__tests__/TemplateApp.layoutScripts.test.ts @@ -0,0 +1,241 @@ +/** + * TemplateApp.loadLayoutScripts — 레이아웃 스크립트 로드의 재시도·모드 보정·실패 표면화 + * + * 종전에는 `onerror` 에서 `resolve()` 로 삼켜, 그 스크립트가 등록하는 핸들러가 전부 + * 미등록이어도 사용자에게는 "버튼이 안 눌린다" 로만 나타났다. `src` 도 확장자 형태로 + * 굳어 있어, 확장자를 정적 location 이 가로채는 서버에서는 자체 제공 자산이 404 였다. + */ +import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { TemplateApp } from '../TemplateApp'; +import type { TemplateAppConfig } from '../TemplateApp'; +import { AuthManager } from '../auth/AuthManager'; + +const mockApiClient = { + post: vi.fn().mockResolvedValue({}), + get: vi.fn().mockResolvedValue({}), + removeToken: vi.fn(), + setToken: vi.fn(), + getToken: vi.fn().mockReturnValue(null), + setOnUnauthorized: vi.fn(), +}; + +vi.mock('../api/ApiClient', () => ({ + getApiClient: () => mockApiClient, +})); + +const { sharedActionDispatcher } = vi.hoisted(() => ({ + sharedActionDispatcher: { + setNavigate: vi.fn(), + setGlobalState: vi.fn(), + setDefaultContext: vi.fn(), + setGlobalStateUpdater: vi.fn(), + registerHandler: vi.fn(), + customHandlers: new Map(), + }, +})); + +vi.mock('../template-engine', () => ({ + initTemplateEngine: vi.fn().mockResolvedValue(undefined), + renderTemplate: vi.fn().mockResolvedValue(undefined), + destroyTemplate: vi.fn(), + getActionDispatcher: vi.fn().mockReturnValue(sharedActionDispatcher), + getState: vi.fn().mockReturnValue({ + actionDispatcher: sharedActionDispatcher, + reactRoot: null, + currentLayoutJson: null, + }), +})); + +vi.mock('../template-engine/TransitionManager', () => ({ + transitionManager: { + setPending: vi.fn(), + getIsPending: vi.fn(() => false), + subscribe: vi.fn(() => vi.fn()), + clearSubscribers: vi.fn(), + }, +})); + +vi.mock('../routing/Router', () => ({ + Router: vi.fn(function (this: any) { + this.loadRoutes = vi.fn().mockResolvedValue(undefined); + this.on = vi.fn(); + this.navigateToCurrentPath = vi.fn(); + this.getRoutes = vi.fn().mockReturnValue([]); + }), +})); + +vi.mock('../template-engine/LayoutLoader', async () => { + const actual = await vi.importActual('../template-engine/LayoutLoader'); + return { + ...actual, + LayoutLoader: vi.fn(function (this: any) { + this.loadLayout = vi.fn().mockResolvedValue({ components: [] }); + }), + }; +}); + +vi.mock('../template-engine/ComponentRegistry', () => { + const mockInstance = { + loadComponents: vi.fn().mockResolvedValue(undefined), + getComponent: vi.fn().mockReturnValue(() => null), + hasComponent: vi.fn().mockReturnValue(true), + getInstance: vi.fn(), + }; + mockInstance.getInstance.mockReturnValue(mockInstance); + return { + ComponentRegistry: { + getInstance: vi.fn(() => mockInstance), + }, + }; +}); + + +vi.mock('../support/assetUrl', async () => { + const actual = await vi.importActual('../support/assetUrl'); + return { ...actual, convertToCurrentMode: vi.fn((url: string) => `${url}#converted`) }; +}); + +import { convertToCurrentMode } from '../support/assetUrl'; +import { getAssetFailures, clearAllAssetFailures } from '../assets/AssetFailureNotice'; + +describe('TemplateApp.loadLayoutScripts', () => { + let app: TemplateApp; + let created: HTMLScriptElement[]; + + const build = (trustedScriptHosts: string[] = []): TemplateApp => { + (window as any).G7Config = { trustedScriptHosts }; + const config: TemplateAppConfig = { + templateId: 'sirsoft-admin_basic', + templateType: 'admin', + locale: 'ko', + debug: false, + }; + return new TemplateApp(config); + }; + + /** + * head.appendChild 를 가로채 결과를 발화시킵니다. + * + * 스크립트는 병렬로 로드되므로 "시도 순서" 인덱스로는 어느 스크립트의 시도인지 + * 특정할 수 없다 — URL 로 판정한다. + * + * @param decide src 를 받아 결과를 돌려주는 판정 함수 + */ + const stub = (decide: (src: string, attempt: number) => 'load' | 'error'): void => { + const attempts = new Map(); + + vi.spyOn(document.head, 'appendChild').mockImplementation(((node: any) => { + if (node.tagName !== 'SCRIPT') return node; + + created.push(node); + + const src = String(node.getAttribute('src') ?? ''); + const attempt = (attempts.get(src) ?? 0) + 1; + attempts.set(src, attempt); + + const outcome = decide(src, attempt); + + queueMicrotask(() => { + if (outcome === 'error') { + node.onerror?.(new Event('error')); + } else { + node.onload?.(new Event('load')); + } + }); + + return node; + }) as any); + }; + + /** 언제나 성공하는 판정 */ + const alwaysLoad = () => 'load' as const; + + const load = (app: TemplateApp, scripts: any[]) => + (app as any).loadLayoutScripts(scripts, {}); + + beforeEach(() => { + document.body.innerHTML = '
    '; + created = []; + clearAllAssetFailures(); + app = build(); + }); + + afterEach(() => { + vi.restoreAllMocks(); + clearAllAssetFailures(); + document.querySelectorAll('script[id^="s-"]').forEach(el => el.remove()); + delete (window as any).G7Config; + }); + + /** + * @scenario asset_class=vendored, outcome=loaded + * @effects layout_script_url_converted_to_current_mode + */ + it('same-origin 경로는 현재 자산 URL 모드로 보정해 로드한다', async () => { + stub(alwaysLoad); + + await load(app, [{ id: 's-1', src: '/api/plugins/assets/x/dist/a.js' }]); + + expect(convertToCurrentMode).toHaveBeenCalledWith('/api/plugins/assets/x/dist/a.js'); + expect(created[0].src).toContain('#converted'); + }); + + it('외부 신뢰 호스트 스크립트는 모드 보정 대상이 아니다', async () => { + app = build(['t1.daumcdn.net']); + stub(alwaysLoad); + + await load(app, [{ id: 's-2', src: 'https://t1.daumcdn.net/a.js' }]); + + expect(created[0].src).toBe('https://t1.daumcdn.net/a.js'); + }); + + /** + * @scenario asset_class=vendored, outcome=failed + * @effects layout_script_retries_before_failing + */ + it('일시 실패는 재시도해 복구한다', async () => { + stub((_src, attempt) => (attempt === 1 ? 'error' : 'load')); + + await load(app, [{ id: 's-3', src: '/a.js' }]); + + expect(created).toHaveLength(2); + expect(app.getFailedLayoutScripts()).toEqual([]); + }); + + /** + * @effects failed_layout_script_recorded_and_others_continue, failed_asset_shows_retry_notice + */ + it('끝내 실패하면 기록·안내하되 다른 스크립트는 계속 로드한다', async () => { + // /fail.js 는 몇 번을 시도해도 실패, /ok.js 는 성공 — 병렬 로드라 URL 로 판정한다 + stub(src => (src.includes('/fail.js') ? 'error' : 'load')); + + await load(app, [ + { id: 's-4', src: '/fail.js' }, + { id: 's-5', src: '/ok.js' }, + ]); + + expect(app.getFailedLayoutScripts()).toEqual(['s-4']); + expect(getAssetFailures().map(f => f.id)).toContain('layout-script:s-4'); + // 실패해도 reject 하지 않는다 (여기까지 도달한 것 자체가 계약 충족) + expect(created.filter(el => String(el.getAttribute('src')).includes('/ok.js'))).toHaveLength(1); + }); + + it('이미 로드된 id 는 건너뛴다', async () => { + const existing = document.createElement('script'); + existing.id = 's-6'; + document.body.appendChild(existing); + stub(alwaysLoad); + + await load(app, [{ id: 's-6', src: '/a.js' }]); + + expect(created).toHaveLength(0); + }); + + it('미선언 외부 origin 은 로드하지 않는다', async () => { + stub(alwaysLoad); + + await load(app, [{ id: 's-7', src: 'https://evil.example.com/a.js' }]); + + expect(created).toHaveLength(0); + }); +}); diff --git a/resources/js/core/__tests__/loadLayoutEditorBundle.test.ts b/resources/js/core/__tests__/loadLayoutEditorBundle.test.ts index f108cc70..58a270b7 100644 --- a/resources/js/core/__tests__/loadLayoutEditorBundle.test.ts +++ b/resources/js/core/__tests__/loadLayoutEditorBundle.test.ts @@ -6,7 +6,8 @@ * - 이미 로드됨(__LayoutEditorChrome 존재) → 즉시 반환, + {{-- 스타일: 자체 빌드 CSS (종전 Tailwind Play CDN 대체 — 외부 도달 실패 시 화면이 무너졌다) --}} +