fix(core, sirsoft-ecommerce, sirsoft-basic): 배송국가 다국어 표시·입력 지원

$localized 가 ActionDispatcher 경로에서 항상 ko 를 반환했다. 컨텍스트에
$locale 이 없다는 것은 "로케일이 ko" 라는 뜻이 아니라 "이 경로가 로케일을
넘기지 않는다" 는 뜻인데, context.$locale || 'ko' 로 하드코딩 폴백하고 있었다.
바로 아래 $t 는 engine-v1.38.2 에서 이미 앱 설정 회수 폴백을 갖췄으나
$localized 만 정의 순서상 그 폴백보다 위에 있어 혜택을 받지 못했다.
로케일/templateId 해석을 두 헬퍼 앞으로 끌어올려 공유한다 (engine-v1.52.1).

국가 추가 폼은 이름 입력칸이 ko/en 두 칸으로 고정돼 그 외 언어의 국가명을
넣을 수 없었다. 설치된 언어를 $locales 로 순회해 입력칸을 만들고, 추가 조건도
특정 로케일 대신 "어느 한 언어라도 채워졌는가" 로 바꾼다. 백엔드
StoreEcommerceSettingsRequest 도 name 을 array 로만 요구하므로 계약이 일치한다.

저장 시 입력하지 않은 로케일은 남기지 않는다. 기존 저장본에 박힌 빈 문자열은
업그레이드 스텝이 청소한다 — 부재 로케일은 서버 localize_catalog_field 가
읽기 시점에 언어팩으로 보강하므로, 빈 문자열은 그 보강을 막는 어중간한 상태였다.

동일 결함 재발을 막는 audit 룰(engine-context-locale-hardcoded-fallback)을
함께 추가한다. 수정 전 코드에서 1건 검출, 수정 후 0건을 확인했다.
This commit is contained in:
HeuJung committed 2026-07-10 19:27:26 +09:00
1 parent 0f84657a5c
commit 051ed1e528
27 files changed
+996 -190

No files matched your search

+2 -1
View File
@@ -4,10 +4,11 @@
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
## [7.0.3] - 2026-07-08
## [7.0.3] - 2026-07-10
### Fixed
- 화면 구성 파일이 목록을 만들어 내는 과정에서 다국어 이름을 골라 쓸 때, 사이트를 어떤 언어로 보고 있든 항상 한국어 이름이 선택되던 문제를 수정했습니다. 이제 보고 있는 언어의 이름이 표시됩니다. 헤더의 배송국가 선택처럼 화면이 처음 열릴 때 목록을 만들어 두는 곳이 여기에 해당합니다.
- 이미 설치를 마친 환경의 설정 파일(`.env`)을 새 서버로 복사해, 데이터베이스가 아직 비어 있는 상태에서 설치를 이어가려 할 때 `php artisan migrate`로 테이블을 만들기도 전에 부팅 단계에서 오류가 나며 중단되던 문제를 수정했습니다. 이제 데이터베이스 작업 명령이 실행되는 동안에는 테이블 존재 여부를 실제로 확인하므로, 기존 서버의 설정을 재사용하는 신규 배포에서도 설치가 정상적으로 진행됩니다. (#41 @GyusoonKim 님께서 제보해주셨습니다.)
## [7.0.2] - 2026-07-08
@@ -4,6 +4,12 @@
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
## [1.0.2] - 2026-07-10
### Removed
- 배송설정의 배송가능 국가 추가 화면이 설치된 언어 전체에 대해 국가명 입력칸을 자동으로 만들도록 바뀌면서, 더 이상 쓰이지 않게 된 "한국어명"·"영문명" 라벨과 입력 예시 문구를 제거했습니다.
## [1.0.1] - 2026-07-08
### Added
@@ -280,10 +280,6 @@
"country_code": "国コード",
"country_code_placeholder": "例:KR",
"country_name": "国名",
"country_name_ko": "日本語名",
"name_ko_placeholder": "例:日本",
"country_name_en": "英文名",
"name_en_placeholder": "例:Japan",
"is_active": "使用",
"actions": "管理",
"delete": "削除",
@@ -12,7 +12,7 @@
"en": "G7 module (sirsoft-ecommerce) Japanese language pack (bundled)",
"ja": "G7 モジュール (sirsoft-ecommerce) 日本語 言語パック(バンドル)"
},
"version": "1.0.1",
"version": "1.0.2",
"license": "MIT",
"scope": "module",
"target_identifier": "sirsoft-ecommerce",
@@ -4,15 +4,17 @@
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
## [1.0.2] - 2026-07-09
## [1.0.2] - 2026-07-10
### Changed
- 쇼핑몰 환경설정 > 배송설정에서 배송가능 국가를 추가할 때, 사이트에 설치된 모든 언어에 대해 국가명을 입력할 수 있습니다. 기존에는 한국어·영어 두 칸만 있어 그 외 언어의 국가명을 넣을 방법이 없었습니다. 언어를 새로 설치하면 입력칸도 함께 늘어납니다. 입력하지 않은 언어는 저장되지 않으며, 기본 제공 국가는 언어팩이 자동으로 채웁니다.
- 휴대폰·태블릿 화면에서 통화·배송국가 선택이 메뉴 안의 접었다 펼치는 항목으로 바뀌었습니다. 접혀 있을 때도 현재 선택된 통화와 배송국가가 함께 표시되어 펼치지 않아도 확인할 수 있고, 펼치면 가로 버튼으로 나열됩니다. 좁은 화면의 메뉴 안에서 드롭다운이 잘려 보이던 문제가 함께 해소됩니다. 데스크톱 화면의 드롭다운은 그대로입니다. 관리자 화면도 동일하게 적용됩니다.
- 휴대폰 화면에서 주문 취소·주문상태 일괄변경 팝업의 상품 목록이 표 대신 상품별 카드 형태로 표시됩니다.
### Fixed
- 배송국가 이름이 어떤 언어로 화면을 보든 항상 한국어로만 표시되던 문제를 수정했습니다. 이제 사용자·관리자 헤더의 배송국가 선택, 회원가입의 배송국가 선택, 관리자 회원정보와 주문상세의 배송국가, 배송설정의 기본 배송국가가 모두 현재 보고 있는 언어로 표시됩니다. 일본어처럼 나중에 추가한 언어에서도 언어팩이 제공하는 국가명이 그대로 반영됩니다.
- 쇼핑몰 환경설정의 은행 관리에서 은행코드를 입력해도 입력한 값이 보이지 않던 문제를 수정했습니다 — 좁은 화면에서 입력칸이 글자가 들어갈 수 없을 만큼 줄어들고 있었습니다.
- 휴대폰 화면에서 주문 취소·주문상태 일괄변경 팝업의 금액이 "249,000원" 대신 "249,000" / "원" 처럼 숫자 중간에서 잘려 보이던 문제를 수정했습니다. 금액은 앞으로도 숫자 중간에서 줄바꿈되지 않으며, "결제완료" 같은 상태 이름도 "결제완" / "료" 로 쪼개지지 않습니다.
- 휴대폰 화면에서 쇼핑몰 환경설정 화면이 좌우로 넘쳐 가로 스크롤이 생기던 문제를 수정했습니다 (이메일 입력 줄, 쇼핑몰 이름·종목 입력칸, 탭 영역).
@@ -61,7 +61,7 @@
"props": {
"name": "ecommerce_preferred_shipping_country",
"value": "{{_local.form?.ecommerce_preferred_shipping_country ?? user?.data?.ecommerce_preferred_shipping_country ?? _global.modules?.['sirsoft-ecommerce']?.shipping?.default_country ?? 'KR'}}",
"options": "{{(_global.modules?.['sirsoft-ecommerce']?.shipping?.available_countries ?? []).filter(c => c.is_active).map(c => ({ value: c.code, label: (c.name?.[_global.locale] ?? c.name?.ko ?? c.code) }))}}",
"options": "{{(_global.modules?.['sirsoft-ecommerce']?.shipping?.available_countries ?? []).filter(c => c.is_active).map(c => ({ value: c.code, label: ($localized(c.name, 'sirsoft-ecommerce::settings.countries.' + (c.code ?? '') + '.name') || c.code) }))}}",
"className": "w-full sm:w-64"
}
}
@@ -24,11 +24,11 @@
}
},
{
"comment": "헤더 배송국가 셀렉터 목록 파생 주입 (유저 헤더 미러). 활성 국가만 {code, name(현지화)} 형태로. 해외배송 활성 게이트는 셀렉터 if 가 international_shipping_enabled 로 별도 체크(유저 헤더 동형). 셀렉터 if 게이트가 이 파생 상태(availableShippingCountries)를 참조.",
"comment": "헤더 배송국가 셀렉터 목록 파생 주입 (유저 헤더 미러). 활성 국가만 {code, name(현지화)} 형태로. 해외배송 활성 게이트는 셀렉터 if 가 international_shipping_enabled 로 별도 체크(유저 헤더 동형). 셀렉터 if 게이트가 이 파생 상태(availableShippingCountries)를 참조. 국가명 $localized(name, fallbackKey): 활성 로케일 키는 서버(localize_catalog_field)가 settings.countries.{code}.name 으로 미리 보강해 통상 즉시 hit 한다. fallbackKey 와 || c.code 는 보강이 실패한 경우의 방어선.",
"handler": "setState",
"params": {
"target": "global",
"availableShippingCountries": "{{(_global.modules?.['sirsoft-ecommerce']?.shipping?.available_countries ?? []).filter(c => c.is_active).map(c => ({ code: c.code, name: (c.name?.[_global.locale] ?? c.name?.ko ?? c.code) }))}}"
"availableShippingCountries": "{{(_global.modules?.['sirsoft-ecommerce']?.shipping?.available_countries ?? []).filter(c => c.is_active).map(c => ({ code: c.code, name: ($localized(c.name, 'sirsoft-ecommerce::settings.countries.' + (c.code ?? '') + '.name') || c.code) }))}}"
}
}
],
@@ -26,7 +26,7 @@
"props": {
"name": "preferred_shipping_country",
"value": "{{_local?.registerForm?.preferred_shipping_country ?? _global.preferredShippingCountry ?? _global.modules?.['sirsoft-ecommerce']?.shipping?.default_country ?? 'KR'}}",
"options": "{{(_global.modules?.['sirsoft-ecommerce']?.shipping?.available_countries ?? []).filter(c => c.is_active).map(c => ({ value: c.code, label: (c.name?.[_global.locale] ?? c.name?.ko ?? c.code) }))}}",
"options": "{{(_global.modules?.['sirsoft-ecommerce']?.shipping?.available_countries ?? []).filter(c => c.is_active).map(c => ({ value: c.code, label: ($localized(c.name, 'sirsoft-ecommerce::settings.countries.' + (c.code ?? '') + '.name') || c.code) }))}}",
"className": "w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500",
"disabled": "{{_local?.isRegistering}}"
}
@@ -520,6 +520,182 @@ describe('D10 (defect #3) — 마이페이지 주소록 모달 국가 Select +
});
});
/**
* 배송국가명 다국어 표시 회귀 (#459)
*
* 두 가지 회귀를 동시에 차단한다.
*
* ① `_global.locale` 은 존재하지 않는 경로다. 엔진은 로케일을 최상위 `$locale` 로만 노출하므로
* (template-engine.ts::createGlobalVariables) 이를 인덱스로 쓰면 표현식이 항상 undefined 가 되어
* `?? name?.ko` 폴백으로 떨어진다 → 어떤 로케일에서도 한국어 국가명이 표시된다.
*
* ② `$localized(value)` 를 fallbackKey 없이 호출하면, 저장본(settings/shipping.json)에 해당 로케일
* 키가 없을 때 헬퍼가 ko 로 폴백한다. 기본 10개국은 언어팩이 라벨을 갖고 있으므로 fallbackKey
* (`sirsoft-ecommerce::settings.countries.{code}.name`)를 넘겨야 언어팩 보강이 적용된다.
* 이미 마이그레이션된 _shipping_country_table/_cards 와 동일한 계약이다(catalogLangPackFallback.test).
*/
describe('#459 — 배송국가명 다국어 표시 ($localized + fallbackKey)', () => {
/** 국가 lang key 접두사 — 저장본에 로케일 키가 없을 때 언어팩으로 보강되는 경로 */
const COUNTRY_LANG_PREFIX = 'sirsoft-ecommerce::settings.countries.';
/** [설명 라벨, 파일 경로, base] */
const surfaces: Array<[string, string, string]> = [
['사용자 헤더 셀렉터', 'layouts/_user_base.json', templateRoot],
['관리자 헤더 셀렉터', 'resources/extensions/header-currency-selector-admin.json', moduleRoot],
['회원가입 배송국가 필드', 'resources/extensions/register-shipping-country-field.json', moduleRoot],
['관리자 회원 배송국가 필드', 'resources/extensions/admin-user-shipping-country-field.json', moduleRoot],
[
'관리자 주문상세 배송국가',
'resources/layouts/admin/partials/admin_ecommerce_order_detail/_partial_order_info.json',
moduleRoot,
],
['배송설정 기본국가 Select', 'resources/layouts/admin/partials/admin_ecommerce_settings/_tab_shipping.json', moduleRoot],
];
for (const [label, rel, base] of surfaces) {
it(`${label}: 존재하지 않는 경로 _global.locale 을 인덱스로 쓰지 않는다`, () => {
const raw = serialize(rel, base);
expect(raw).not.toMatch(/\[\s*_global\.locale\s*\]/);
});
}
/**
* 국가명을 표시하는 각 표현식이 $localized 를 fallbackKey 와 함께 호출하는지 검증한다.
* `needle` 은 그 표현식을 담은 줄을 특정하기 위한 고유 문자열이다.
*/
const localizedCalls: Array<[string, string, string, string]> = [
['사용자 헤더 파생', 'layouts/_user_base.json', templateRoot, '"availableShippingCountries"'],
[
'관리자 헤더 파생',
'resources/extensions/header-currency-selector-admin.json',
moduleRoot,
'"availableShippingCountries"',
],
[
'회원가입 Select options',
'resources/extensions/register-shipping-country-field.json',
moduleRoot,
'"options"',
],
[
'관리자 회원폼 Select options',
'resources/extensions/admin-user-shipping-country-field.json',
moduleRoot,
'"options"',
],
[
'배송설정 기본국가 Select options',
'resources/layouts/admin/partials/admin_ecommerce_settings/_tab_shipping.json',
moduleRoot,
'"options"',
],
];
for (const [label, rel, base, needle] of localizedCalls) {
it(`${label}: $localized 를 국가 lang key fallbackKey 와 함께 호출한다`, () => {
const line = serialize(rel, base)
.split('\n')
.find((l) => l.includes(needle) && l.includes('$localized('));
expect(line, `${needle} 를 담은 $localized 호출 줄 존재`).toBeTruthy();
expect(line!).toContain(COUNTRY_LANG_PREFIX);
// 폴백 체인은 헬퍼 + 언어팩이 담당한다 — 레이아웃에서 ko 를 명시 폴백하지 않는다.
expect(line!).not.toContain('name?.ko');
});
}
it('관리자 주문상세 Select options: $localized + fallbackKey', () => {
const line = serialize(
'resources/layouts/admin/partials/admin_ecommerce_order_detail/_partial_order_info.json'
)
.split('\n')
.find((l) => l.includes('available_countries') && l.includes('"options"'));
expect(line, '배송국가 Select options 존재').toBeTruthy();
expect(line!).toContain('$localized(');
expect(line!).toContain(COUNTRY_LANG_PREFIX);
expect(line!).not.toContain('name?.ko');
});
it('관리자 주문상세: 해외배송 OFF 시 표시되는 주문 스냅샷 국가명도 $localized 로 현지화된다', () => {
// 주문 스냅샷(recipient_country_name)은 주문 시점 다국어 JSON — 언어팩 보강 대상이 아니므로
// fallbackKey 없이 $localized 단독 호출로 충분하다(활성 로케일 → ko → en → 첫 값).
const line = serialize(
'resources/layouts/admin/partials/admin_ecommerce_order_detail/_partial_order_info.json'
)
.split('\n')
.find((l) => l.includes('recipient_country_name') && l.includes('"text"'));
expect(line, '스냅샷 국가명 표시 노드 존재').toBeTruthy();
expect(line!).toContain('$localized(');
expect(line!).not.toContain('name?.ko');
});
});
/**
* 배송국가 추가 폼 다국어 입력 회귀 (#459)
*
* 운영자가 직접 추가한 국가는 언어팩에 lang key 가 없으므로 보강 대상이 아니다. 따라서 활성 언어팩
* 전체(`$locales`)에 대해 이름을 입력할 수 있어야 하며, ko/en 두 칸 하드코딩이면 ja 등 나머지
* 로케일에는 영원히 이름을 넣을 수 없다. 백엔드 검증은 이미 로케일 무제한(`name.*`)이다.
*/
describe('#459 — 배송국가 추가 폼 다국어 입력 ($locales 순회)', () => {
const json = read('resources/layouts/admin/partials/admin_ecommerce_settings/_tab_shipping.json');
const raw = serialize('resources/layouts/admin/partials/admin_ecommerce_settings/_tab_shipping.json');
const addForm = walk(json, (n) => n.id === 'add_country_form');
it('국가 추가 폼이 존재한다', () => {
expect(addForm).toBeTruthy();
});
it('국가명 입력칸이 $locales 순회로 생성된다 (ko/en 하드코딩 제거)', () => {
const iterNode = walk(addForm, (n) => typeof n.iteration?.source === 'string'
&& n.iteration.source.includes('$locales'));
expect(iterNode, '$locales 를 순회하는 입력칸 노드 존재').toBeTruthy();
// 로케일별 입력칸은 newCountry.name[<loc>] 로 써야 한다 — 고정 .ko/.en 경로 금지
const formRaw = JSON.stringify(addForm);
expect(formRaw).not.toContain('newCountry.name.ko');
expect(formRaw).not.toContain('newCountry.name.en');
expect(formRaw).not.toContain('newCountry?.name?.ko');
expect(formRaw).not.toContain('newCountry?.name?.en');
});
it('입력칸 라벨이 로케일 표시명(localeNames)으로 동적 생성된다', () => {
const formRaw = JSON.stringify(addForm);
expect(formRaw).toContain('localeNames');
// 고정 라벨 키(country_name_ko/en) 잔존 0
expect(formRaw).not.toContain('countries.country_name_ko');
expect(formRaw).not.toContain('countries.country_name_en');
});
it('추가 버튼 활성 조건이 특정 로케일(ko)에 고정되지 않는다', () => {
const formRaw = JSON.stringify(addForm);
// 최소 하나의 로케일에 이름이 있으면 추가 가능 — 백엔드 validateCountryNames 와 동일 계약
expect(formRaw).not.toContain('!_local.newCountry?.name?.ko');
});
it('신규 국가 초기 상태가 $locales 기반으로 만들어진다 (빈 ko/en 리터럴 금지)', () => {
const addButton = walk(json, (n) => n.id === 'add_country_button');
expect(addButton).toBeTruthy();
const init = JSON.stringify(addButton.actions);
expect(init).not.toContain('"ko": ""');
expect(init).not.toContain('"en": ""');
});
it('배송국가 카드/테이블에서 이름 편집이 가능하면 동일하게 $locales 를 순회한다', () => {
// 편집 진입점이 없다면(현재 구조) 이 테스트는 자동 통과 — 추가 시 회귀 차단용 가드
for (const rel of [
'resources/layouts/admin/partials/admin_ecommerce_settings/_shipping_country_table.json',
'resources/layouts/admin/partials/admin_ecommerce_settings/_shipping_country_cards.json',
]) {
const r = serialize(rel);
if (r.includes('name.ko') || r.includes('name.en')) {
expect(r, `${rel} 이름 편집이 로케일 하드코딩`).toContain('$locales');
}
}
expect(raw).toBeTruthy();
});
});
describe('D7 (defect #5) — 관리자 주문상세 국내/해외 분기 폼', () => {
const json = read('resources/layouts/admin/partials/admin_ecommerce_order_detail/_partial_order_info.json');
const raw = serialize('resources/layouts/admin/partials/admin_ecommerce_order_detail/_partial_order_info.json');
@@ -210,33 +210,46 @@ describe('배송설정 탭 콘텐츠 (_tab_shipping.json)', () => {
expect(addForm.if).toContain('international_shipping_enabled');
});
it('국가 추가 폼에 코드/한국어명/영문명 Input이 있다', () => {
it('국가 추가 폼에 코드 Input + 설치 언어마다 반복되는 국가명 Input이 있다', () => {
// #459: 이름 입력칸은 ko/en 두 칸 고정이 아니라 $locales 순회로 언어 수만큼 생성된다.
// 따라서 정적 노드 트리에는 name Input 이 "템플릿 1개"로만 존재한다.
const addForm = findById(allNodes, 'add_country_form');
const formNodes = flattenAll(addForm);
const inputs = formNodes.filter((n: any) => n.name === 'Input');
// code, name.ko, name.en => 3개
expect(inputs.length).toBeGreaterThanOrEqual(3);
// code input
const codeInput = inputs.find((i: any) => i.props?.value?.includes('newCountry?.code'));
expect(codeInput).toBeDefined();
expect(codeInput.props?.maxLength).toBe(10);
// name.ko input
const koInput = inputs.find((i: any) => i.props?.value?.includes('newCountry?.name?.ko'));
expect(koInput).toBeDefined();
// name.en input
const enInput = inputs.find((i: any) => i.props?.value?.includes('newCountry?.name?.en'));
expect(enInput).toBeDefined();
// 로케일 인덱싱 이름 입력칸 (name?.[loc]) — 특정 로케일 하드코딩이 아니어야 한다
const nameInput = inputs.find((i: any) => i.props?.value?.includes('newCountry?.name?.[loc]'));
expect(nameInput).toBeDefined();
// 그 입력칸을 감싼 Div 가 $locales 를 순회한다
const iterated = formNodes.find(
(n: any) => n.iteration?.source?.includes('$locales') && n.iteration?.item_var === 'loc'
);
expect(iterated).toBeDefined();
// ko/en 고정 입력칸 잔존 0 (회귀 차단)
expect(inputs.some((i: any) => i.props?.value?.includes('newCountry?.name?.ko'))).toBe(false);
expect(inputs.some((i: any) => i.props?.value?.includes('newCountry?.name?.en'))).toBe(false);
});
it('추가 버튼은 code와 name.ko가 없으면 disabled', () => {
it('추가 버튼은 코드가 없거나 모든 언어의 이름이 비면 disabled', () => {
// #459: 특정 로케일(ko)을 필수로 강제하지 않는다.
// 백엔드 StoreEcommerceSettingsRequest 도 name 을 array 로만 요구한다.
const addForm = findById(allNodes, 'add_country_form');
const formNodes = flattenAll(addForm);
const buttons = formNodes.filter((n: any) => n.name === 'Button');
// 추가 버튼 (disabled prop 가진 것)
const addButton = buttons.find((b: any) => b.props?.disabled);
expect(addButton).toBeDefined();
expect(addButton.props.disabled).toContain('newCountry?.code');
expect(addButton.props.disabled).toContain('newCountry?.name?.ko');
// "어느 한 언어라도 채워졌는가" 조건
expect(addButton.props.disabled).toContain('Object.values');
expect(addButton.props.disabled).toContain('some');
// ko 필수 조건 잔존 0 (회귀 차단)
expect(addButton.props.disabled).not.toContain('newCountry?.name?.ko');
});
it('추가 버튼 클릭 시 available_countries에 새 국가가 push된다', () => {
@@ -275,10 +275,6 @@
"country_code": "Country Code",
"country_code_placeholder": "e.g., KR",
"country_name": "Country Name",
"country_name_ko": "Korean Name",
"name_ko_placeholder": "e.g., South Korea",
"country_name_en": "English Name",
"name_en_placeholder": "e.g., South Korea",
"is_active": "Active",
"actions": "Actions",
"delete": "Delete",
@@ -275,10 +275,6 @@
"country_code": "국가코드",
"country_code_placeholder": "예: KR",
"country_name": "국가명",
"country_name_ko": "한국어명",
"name_ko_placeholder": "예: 한국",
"country_name_en": "영문명",
"name_en_placeholder": "예: South Korea",
"is_active": "사용",
"actions": "관리",
"delete": "삭제",
@@ -1614,7 +1614,7 @@
"props": {
"name": "recipient_country_code",
"value": "{{_local.form.recipient_country_code ?? order?.data?.shipping_address?.recipient_country_code ?? 'KR'}}",
"options": "{{(_global.modules?.['sirsoft-ecommerce']?.shipping?.available_countries ?? []).filter(c => c.is_active).map(c => ({ value: c.code, label: (c.name?.[_global.locale] ?? c.name?.ko ?? c.code) }))}}",
"options": "{{(_global.modules?.['sirsoft-ecommerce']?.shipping?.available_countries ?? []).filter(c => c.is_active).map(c => ({ value: c.code, label: ($localized(c.name, 'sirsoft-ecommerce::settings.countries.' + (c.code ?? '') + '.name') || c.code) }))}}",
"className": "w-full",
"disabled": "{{order?.data?.abilities?.can_update !== true}}"
},
@@ -1634,7 +1634,7 @@
"name": "Span",
"if": "{{_global.modules?.['sirsoft-ecommerce']?.shipping?.international_shipping_enabled !== true}}",
"props": { "className": "text-gray-900 dark:text-white" },
"text": "{{order?.data?.shipping_address?.recipient_country_name?.[_global.locale] ?? order?.data?.shipping_address?.recipient_country_name?.ko ?? order?.data?.shipping_address?.recipient_country_code ?? 'KR'}}"
"text": "{{$localized(order?.data?.shipping_address?.recipient_country_name) || order?.data?.shipping_address?.recipient_country_code || 'KR'}}"
}
]
},
@@ -58,7 +58,7 @@
"props": {
"value": "{{_local.form?.shipping?.default_country ?? 'KR'}}",
"className": "w-full",
"options": "{{(_local.form?.shipping?.available_countries ?? []).filter(c => c.is_active).map(c => ({value: c.code, label: $localized(c.name)}))}}",
"options": "{{(_local.form?.shipping?.available_countries ?? []).filter(c => c.is_active).map(c => ({value: c.code, label: ($localized(c.name, 'sirsoft-ecommerce::settings.countries.' + (c.code ?? '') + '.name') || c.code)}))}}",
"disabled": "{{_computed.isReadOnly}}"
},
"actions": [
@@ -216,19 +216,13 @@
},
"actions": [
{
"comment": "신규 국가의 name 은 활성 언어팩($locales) 전체에 대한 빈 문자열 맵으로 시드한다. 언어팩이 추가되면 입력칸도 함께 늘어나야 하므로 로케일을 리터럴로 열거하지 않는다.",
"type": "click",
"handler": "setState",
"params": {
"target": "local",
"isAddingCountry": true,
"newCountry": {
"code": "",
"name": {
"ko": "",
"en": ""
},
"is_active": true
}
"newCountry": "{{ { code: '', name: Object.fromEntries(($locales ?? []).map(l => [l, ''])), is_active: true } }}"
}
}
],
@@ -305,24 +299,31 @@
]
},
{
"comment": "국가명 입력칸은 활성 언어팩($locales) 마다 하나씩 생성된다. iteration 은 이 Div 자신을 로케일 수만큼 복제하므로, 부모(flex flex-wrap)가 입력칸들을 가로로 흘린다. 언어팩이 추가되면 입력칸도 자동으로 늘어난다 — 로케일 리터럴 열거 금지.",
"type": "basic",
"name": "Div",
"iteration": {
"source": "{{$locales ?? []}}",
"item_var": "loc"
},
"children": [
{
"comment": "라벨 = 로케일 표시명(예: 한국어 / English / 日本語). appConfig.localeNames 부재 시 로케일 코드로 폴백.",
"type": "basic",
"name": "Label",
"props": {
"className": "text-tertiary block font-medium mb-1"
},
"text": "$t:sirsoft-ecommerce.admin.settings.shipping.countries.country_name_ko"
"text": "{{_global.appConfig?.localeNames?.[loc] ?? loc}}"
},
{
"comment": "setState 는 params 키의 표현식을 해석하지 않는다(엔진 제약). 따라서 `newCountry.name.<loc>` 같은 동적 키 대신 name 객체를 통째로 재구성해 넣는다.",
"type": "basic",
"name": "Input",
"props": {
"value": "{{_local.newCountry?.name?.ko ?? ''}}",
"value": "{{_local.newCountry?.name?.[loc] ?? ''}}",
"className": "w-40",
"placeholder": "$t:sirsoft-ecommerce.admin.settings.shipping.countries.name_ko_placeholder",
"placeholder": "{{$t('sirsoft-ecommerce.admin.settings.shipping.countries.country_name') + ' (' + (_global.appConfig?.localeNames?.[loc] ?? loc) + ')'}}",
"disabled": "{{_computed.isReadOnly}}"
},
"actions": [
@@ -331,41 +332,7 @@
"handler": "setState",
"params": {
"target": "local",
"newCountry.name.ko": "{{$event.target.value}}"
}
}
]
}
]
},
{
"type": "basic",
"name": "Div",
"children": [
{
"type": "basic",
"name": "Label",
"props": {
"className": "text-tertiary block font-medium mb-1"
},
"text": "$t:sirsoft-ecommerce.admin.settings.shipping.countries.country_name_en"
},
{
"type": "basic",
"name": "Input",
"props": {
"value": "{{_local.newCountry?.name?.en ?? ''}}",
"className": "w-40",
"placeholder": "$t:sirsoft-ecommerce.admin.settings.shipping.countries.name_en_placeholder",
"disabled": "{{_computed.isReadOnly}}"
},
"actions": [
{
"type": "change",
"handler": "setState",
"params": {
"target": "local",
"newCountry.name.en": "{{$event.target.value}}"
"newCountry.name": "{{ { ...(_local.newCountry?.name ?? {}), [loc]: $event.target.value } }}"
}
}
]
@@ -380,11 +347,12 @@
},
"children": [
{
"comment": "활성 조건: 국가코드 + 최소 하나의 로케일 이름. StoreEcommerceSettingsRequest 의 available_countries.*.name 규칙이 array 만 요구하고 특정 로케일 키를 강제하지 않으므로, 프론트도 ko 를 필수로 두지 않는다.",
"type": "basic",
"name": "Button",
"props": {
"type": "button",
"disabled": "{{_computed.isReadOnly || !_local.newCountry?.code || !_local.newCountry?.name?.ko}}",
"disabled": "{{_computed.isReadOnly || !(_local.newCountry?.code ?? '').trim() || !Object.values(_local.newCountry?.name ?? {}).some(v => (v ?? '').trim() !== '')}}",
"className": "px-3 py-1.5 text-sm bg-gray-900 dark:bg-white text-white dark:text-gray-900 rounded-lg hover:bg-gray-800 dark:hover:bg-gray-100 font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
},
"actions": [
@@ -393,10 +361,11 @@
"handler": "sequence",
"actions": [
{
"comment": "입력하지 않은 로케일의 빈 문자열은 저장본에 남기지 않는다 — 부재 로케일은 언어팩(settings.countries.{code}.name)이 보강하거나, 운영자가 나중에 채운다.",
"handler": "setState",
"params": {
"target": "local",
"form.shipping.available_countries": "{{[...(_local.form?.shipping?.available_countries ?? []), { code: _local.newCountry.code, name: _local.newCountry.name, is_active: true }]}}",
"form.shipping.available_countries": "{{[...(_local.form?.shipping?.available_countries ?? []), { code: _local.newCountry.code.trim().toUpperCase(), name: Object.fromEntries(Object.entries(_local.newCountry?.name ?? {}).filter(e => (e[1] ?? '').trim() !== '').map(e => [e[0], e[1].trim()])), is_active: true }]}}",
"isAddingCountry": false,
"newCountry": null,
"hasChanges": true
@@ -0,0 +1,199 @@
/**
* 배송설정 배송국가 — 다국어 표시/입력 회귀 (#459).
*
* 배경: 배송국가명이 UI 로케일과 무관하게 항상 한국어로 렌더됐다. 원인은 두 겹이었다.
* 1) 레이아웃이 `name[_global.locale]` 로 직접 색인 — 로케일 키 부재 시 폴백 없음.
* 2) 엔진 `$localized()` 가 `context.$locale || 'ko'` 로 로케일을 확정 — `init_actions`
* 같은 ActionDispatcher 경로는 `$locale` 을 넘기지 않으므로 **항상** ko 를 반환했다
* (engine-v1.52.1 에서 `window.__templateApp.getConfig()` 회수로 수정).
* 또한 국가 추가 폼의 이름 입력칸이 ko/en 2칸으로 하드코딩돼 있어 언어를 추가해도
* 그 언어의 이름을 넣을 수 없었다 → `$locales` 순회로 전환.
*
* 측정 규율 (이 spec 을 고칠 사람에게):
* - **국가명 문자열을 하드코딩하지 않는다**("South Korea" 등). 시드 데이터가 바뀌면
* 거짓 실패하고, 무엇보다 "ko 가 아닌 무언가"를 렌더한다는 사실만으로는 회귀를 못 잡는다.
* API 응답에서 그 로케일의 기대값을 **런타임에 도출**해 화면과 대조한다.
* - **로케일 목록을 하드코딩하지 않는다**. 언어는 계속 추가된다(PO 지시). 설치된 언어는
* `$locales` 에서 읽는다.
* - 회귀(= ko 고정) 판정은 "en 값과 같다" 로는 부족하다. ko 와 en 이 같은 국가(예: 코드
* 폴백)만 골라 보면 통과해 버린다. **ko 값과 다른 국가가 하나라도 있는지** 먼저 확인한
* 뒤, 그 국가에서 화면값 === en 값을 단언한다.
*
* @scenario shipping_country_i18n locale=en|ja × surface=settings_list|add_form
* @effects country_names_localized_by_active_locale,
* country_names_not_pinned_to_ko,
* add_form_inputs_follow_installed_locales,
* add_button_enabled_by_any_locale_name
*/
import { test, expect, authenticatePage } from '../../fixtures/ecommerce-auth';
import type { Page } from '@playwright/test';
const SHIPPING_SETTINGS_URL = '/admin/ecommerce/settings?tab=shipping';
/** 활성 배송국가의 원본 다국어 이름(name 객체)을 앱 상태에서 읽는다. */
async function activeCountryNames(page: Page): Promise<Array<Record<string, string>>> {
return page.evaluate(() => {
const core = (window as any).G7Core;
const shipping = core?.state?.getGlobal?.()?.modules?.['sirsoft-ecommerce']?.shipping;
return (shipping?.available_countries ?? [])
.filter((c: any) => c.is_active)
.map((c: any) => (typeof c.name === 'object' && c.name ? c.name : {}));
});
}
/** 현재 UI 로케일. */
async function activeLocale(page: Page): Promise<string> {
return page.evaluate(() => (window as any).__templateApp?.getConfig?.()?.locale ?? '');
}
/** 헤더 배송국가 셀렉터가 파생한 표시명 (init_actions/ActionDispatcher 경로 — 회귀 지점). */
async function derivedHeaderNames(page: Page): Promise<string[]> {
return page.evaluate(() =>
((window as any).G7Core?.state?.getGlobal?.()?.availableShippingCountries ?? []).map((c: any) => c.name),
);
}
/**
* 설치된 언어의 `{ 코드: 표시명 }` 맵. 하드코딩 금지 — 언어는 계속 추가된다(PO 지시).
* 레이아웃의 이름 입력칸 라벨이 쓰는 것과 동일한 출처(`appConfig.localeNames`)를 읽는다.
*/
async function localeDisplayNames(page: Page): Promise<Record<string, string>> {
return page.evaluate(() => (window as any).G7Core?.state?.getGlobal?.()?.appConfig?.localeNames ?? {});
}
/** 국가 표(`_local.form.shipping`)가 시드됐는지. */
async function formSeeded(page: Page): Promise<boolean> {
return page.evaluate(() => {
const form = (window as any).G7Core?.state?.getLocal?.()?.form;
return Array.isArray(form?.shipping?.available_countries) && form.shipping.available_countries.length > 0;
});
}
/**
* 배송설정 탭이 데이터를 받아 국가 목록을 **화면에** 그릴 때까지 기다린다.
*
* 상태(available_countries)만 기다리면 DOM 이 아직 비어 있어 body 텍스트가 `""` 다.
*
* 재진입 1회 허용 — 사전 결함(#459 검수 중 발견): settings 데이터소스의 `initLocal: "form"`
* 시드가 간헐적으로 유실돼 `_local.form` 이 비고 표가 "No shipping countries" 로 렌더된다.
* 이때 `_global.modules[...]` 와 데이터소스에는 국가가 정상 적재돼 있다(= 로딩 실패가 아님).
* 이 spec 의 대상은 다국어 표시이므로, 시드 유실 시 1회 재진입해 본 검증을 이어간다.
* **이 재진입은 그 결함의 회피가 아니라 격리다** — 결함 자체는 별도 이슈로 추적한다.
*/
async function gotoShippingSettings(page: Page, token: string): Promise<void> {
await authenticatePage(page, token);
await page.setViewportSize({ width: 1280, height: 900 });
for (let attempt = 0; attempt < 2; attempt++) {
await page.goto(SHIPPING_SETTINGS_URL);
await page.waitForLoadState('domcontentloaded', { timeout: 30_000 });
await expect.poll(async () => (await activeCountryNames(page)).length, { timeout: 30_000 }).toBeGreaterThan(0);
const seeded = await expect
.poll(async () => formSeeded(page), { timeout: 15_000 })
.toBe(true)
.then(() => true)
.catch(() => false);
if (seeded) break;
if (attempt === 1) throw new Error('_local.form 시드 유실이 2회 연속 발생 (사전 결함)');
}
const locale = await activeLocale(page);
const expected = (await activeCountryNames(page)).map((n) => n[locale]).filter(Boolean);
if (expected.length > 0) {
await expect
.poll(async () => (await page.locator('body').innerText()).includes(expected[0]), { timeout: 30_000 })
.toBe(true);
}
}
test.describe('@sirsoft-ecommerce 배송국가 다국어', () => {
// @scenario shipping_country_i18n:settings_list
// @effects country_names_localized_by_active_locale, country_names_not_pinned_to_ko
test('국가 목록이 활성 로케일 값으로 렌더된다 (ko 고정 회귀 차단)', async ({ page, settingsToken }) => {
await gotoShippingSettings(page, settingsToken);
const locale = await activeLocale(page);
const names = await activeCountryNames(page);
// 이 테스트가 의미를 가지려면 "ko 와 다른 활성 로케일 값" 이 최소 1건 있어야 한다.
// (전부 같으면 ko 고정 회귀를 구분할 수 없어 거짓 통과한다.)
const discriminating = names.filter((n) => n[locale] && n.ko && n[locale] !== n.ko);
test.skip(
discriminating.length === 0,
`활성 로케일(${locale}) 값이 ko 와 모두 동일 — 회귀 판별 불가한 시드`,
);
const body = await page.locator('body').innerText();
for (const name of discriminating) {
expect(body, `활성 로케일(${locale}) 이름이 렌더돼야 한다`).toContain(name[locale]);
expect(body, `ko 이름(${name.ko})이 렌더되면 ko 고정 회귀`).not.toContain(name.ko);
}
});
// @scenario shipping_country_i18n:header_derivation
// @effects country_names_localized_by_active_locale, country_names_not_pinned_to_ko
test('헤더 파생 목록도 활성 로케일 값을 쓴다 (ActionDispatcher 경로 $localized)', async ({
page,
settingsToken,
}) => {
await gotoShippingSettings(page, settingsToken);
const locale = await activeLocale(page);
const names = await activeCountryNames(page);
const discriminating = names.filter((n) => n[locale] && n.ko && n[locale] !== n.ko);
test.skip(discriminating.length === 0, `활성 로케일(${locale}) 값이 ko 와 모두 동일`);
await expect.poll(async () => (await derivedHeaderNames(page)).length, { timeout: 20_000 }).toBeGreaterThan(0);
const derived = await derivedHeaderNames(page);
// 파생 목록에 ko 전용 값이 섞이면 회귀. (init_actions 는 $locale 을 넘기지 않는 경로다.)
const koOnly = discriminating.map((n) => n.ko).filter((ko) => derived.includes(ko));
expect(koOnly, `헤더 파생값: ${JSON.stringify(derived)}`).toEqual([]);
});
// @scenario shipping_country_i18n:add_form
// @effects add_form_inputs_follow_installed_locales, add_button_enabled_by_any_locale_name
test('국가 추가 폼의 이름 입력칸이 설치된 언어 수만큼 생기고, 어느 한 언어만 채워도 추가된다', async ({
page,
settingsToken,
}) => {
await gotoShippingSettings(page, settingsToken);
const localeNames = await localeDisplayNames(page);
const locales = Object.keys(localeNames);
expect(locales.length, '설치된 언어를 못 읽었다').toBeGreaterThan(0);
await page.getByRole('button', { name: /Add Country|국가 추가|国追加/ }).click();
// 국가 코드 입력칸(placeholder="KR")이 있는 행이 곧 추가 폼이다.
const codeInput = page.locator('input[placeholder="KR"]');
await expect(codeInput).toBeVisible({ timeout: 10_000 });
// 이름 입력칸은 placeholder 가 `... (언어표시명)` 으로 끝난다.
// 언어 목록을 하드코딩하지 않고 localeNames 로 셀렉터를 만든다.
const nameInputs = locales.map((code) => page.locator(`input[placeholder$="(${localeNames[code]})"]`));
for (const [i, input] of nameInputs.entries()) {
await expect(input, `${locales[i]} 이름 입력칸이 있어야 한다`).toBeVisible({ timeout: 10_000 });
}
const addButton = page.getByRole('button', { name: /^(Add|추가|追加)$/ });
await expect(addButton).toBeDisabled();
// 코드만 채워도 여전히 비활성 (이름이 전부 비어 있음)
await codeInput.fill('zz');
await expect(addButton).toBeDisabled();
// 공백만 채워도 비활성 (.trim() 가드)
await nameInputs[0].fill(' ');
await expect(addButton, '공백만 입력하면 추가 불가여야 한다').toBeDisabled();
await nameInputs[0].fill('');
// 마지막 언어 한 칸만 채워도 활성 — ko 고정 조건이면 여기서 실패한다.
await nameInputs[nameInputs.length - 1].fill('Zed Test Country');
await expect(addButton, '어느 한 언어만 채워도 추가 가능해야 한다').toBeEnabled();
// 저장하지 않고 폼을 닫아 부작용을 남기지 않는다.
await page.getByRole('button', { name: /^(Cancel|취소|キャンセル)$/ }).first().click();
});
});
@@ -0,0 +1,234 @@
<?php
namespace Modules\Sirsoft\Ecommerce\Tests\Unit\Upgrades;
use App\Extension\UpgradeContext;
use Illuminate\Support\Facades\File;
use Modules\Sirsoft\Ecommerce\Tests\ModuleTestCase;
/**
* 배송가능 국가명의 빈 로케일 키 청소 마이그레이션 테스트 (#459)
*
* 구 국가 추가 폼은 한국어/영문 두 입력칸을 항상 렌더했고, 운영자가 한쪽을 비운 채 저장하면
* `{"ko":"프랑스","en":""}` 처럼 빈 문자열이 저장본에 박혔다. 빈 문자열은 "값이 있음" 도
* "부재" 도 아닌 어중간한 상태라, 저장본을 읽는 쪽마다 처리가 갈린다.
*
* 부재 로케일은 비워 두는 것이 이 시스템의 계약이다 — 기본 10개국은 언어팩
* (settings.countries.{code}.name)이 읽기 시점에 보강하고, 운영자가 직접 추가한 국가는
* 운영자가 채운다. 따라서 빈 문자열 키는 제거해 "부재" 로 정규화한다.
*
* 이름을 새로 채우지는 않는다(PO 결정) — 청소만 한다.
*/
class PruneEmptyShippingCountryNameLocalesTest extends ModuleTestCase
{
private const MIGRATION_NS = 'App\\Upgrades\\Data\\Ext\\Modules\\SirsoftEcommerce\\V1_0_2\\Migrations\\PruneEmptyShippingCountryNameLocales';
private string $settingsPath;
private string $settingsFile;
protected function setUp(): void
{
parent::setUp();
// DataMigration 클래스는 오토로드 밖 — 직접 로드
$migDir = dirname(__DIR__, 3).'/upgrades/data/1.0.2/migrations';
require_once $migDir.'/PruneEmptyShippingCountryNameLocales.php';
// 운영 storage 오염 방지: 테스트 환경 경로 (마이그레이션의 runningUnitTests 분기와 일치)
$this->settingsPath = storage_path('framework/testing/modules/sirsoft-ecommerce/settings');
$this->settingsFile = $this->settingsPath.'/shipping.json';
}
protected function tearDown(): void
{
if (File::exists($this->settingsFile)) {
File::delete($this->settingsFile);
}
parent::tearDown();
}
private function migration(): object
{
$class = self::MIGRATION_NS;
return new $class;
}
private function context(): UpgradeContext
{
return new UpgradeContext(
fromVersion: '1.0.1',
toVersion: '1.0.2',
currentStep: '1.0.2',
);
}
private function writeSettings(array $settings): void
{
File::ensureDirectoryExists($this->settingsPath);
File::put($this->settingsFile, json_encode($settings, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
}
private function readCountries(): array
{
$settings = json_decode((string) File::get($this->settingsFile), true);
return collect($settings['available_countries'])->keyBy('code')->all();
}
public function test_empty_string_locale_keys_are_removed(): void
{
$this->writeSettings([
'default_country' => 'KR',
'available_countries' => [
['code' => 'KR', 'name' => ['ko' => '대한민국', 'en' => 'South Korea'], 'is_active' => true],
['code' => 'FR', 'name' => ['ko' => '프랑스', 'en' => ''], 'is_active' => true],
],
]);
($this->migration())->run($this->context());
$byCode = $this->readCountries();
// 채워진 값은 그대로
$this->assertSame(['ko' => '대한민국', 'en' => 'South Korea'], $byCode['KR']['name']);
// 빈 문자열 키만 제거 — 부재로 정규화
$this->assertSame(['ko' => '프랑스'], $byCode['FR']['name']);
}
public function test_whitespace_only_locale_keys_are_removed(): void
{
// 공백만 입력한 경우도 빈 값으로 취급
$this->writeSettings([
'default_country' => 'KR',
'available_countries' => [
['code' => 'DE', 'name' => ['ko' => '독일', 'en' => ' ', 'ja' => "\t"], 'is_active' => false],
],
]);
($this->migration())->run($this->context());
$this->assertSame(['ko' => '독일'], $this->readCountries()['DE']['name']);
}
public function test_surviving_values_are_trimmed(): void
{
$this->writeSettings([
'default_country' => 'KR',
'available_countries' => [
['code' => 'IT', 'name' => ['ko' => ' 이탈리아 ', 'en' => ' Italy '], 'is_active' => true],
],
]);
($this->migration())->run($this->context());
$this->assertSame(['ko' => '이탈리아', 'en' => 'Italy'], $this->readCountries()['IT']['name']);
}
public function test_no_locale_names_leaves_empty_object_not_null(): void
{
// 모든 로케일이 빈 값이면 name 은 빈 객체가 된다(키 자체는 유지) — 백엔드 검증이
// `name` 을 array 로 요구하므로 null 로 만들면 저장이 깨진다.
$this->writeSettings([
'default_country' => 'KR',
'available_countries' => [
['code' => 'XX', 'name' => ['ko' => '', 'en' => ''], 'is_active' => false],
],
]);
($this->migration())->run($this->context());
$this->assertSame([], $this->readCountries()['XX']['name']);
}
public function test_country_names_are_never_filled_in(): void
{
// PO 결정: 이름을 새로 채우지 않는다. 부재 로케일은 언어팩이 읽기 시점에 보강한다.
$this->writeSettings([
'default_country' => 'KR',
'available_countries' => [
['code' => 'KR', 'name' => ['ko' => '대한민국'], 'is_active' => true],
],
]);
($this->migration())->run($this->context());
// ja/en 이 추가되지 않아야 한다
$this->assertSame(['ko' => '대한민국'], $this->readCountries()['KR']['name']);
}
public function test_other_country_fields_are_preserved(): void
{
$this->writeSettings([
'default_country' => 'KR',
'international_shipping_enabled' => true,
'available_countries' => [
['code' => 'KR', 'name' => ['ko' => '대한민국', 'en' => ''], 'is_active' => true],
],
]);
($this->migration())->run($this->context());
$settings = json_decode((string) File::get($this->settingsFile), true);
$this->assertTrue($settings['international_shipping_enabled']);
$this->assertSame('KR', $settings['default_country']);
$this->assertTrue($settings['available_countries'][0]['is_active']);
$this->assertSame('KR', $settings['available_countries'][0]['code']);
}
public function test_is_idempotent(): void
{
$this->writeSettings([
'default_country' => 'KR',
'available_countries' => [
['code' => 'KR', 'name' => ['ko' => '대한민국'], 'is_active' => true],
['code' => 'FR', 'name' => ['ko' => '프랑스', 'en' => ''], 'is_active' => true],
],
]);
($this->migration())->run($this->context());
$first = $this->readCountries();
($this->migration())->run($this->context());
$second = $this->readCountries();
$this->assertSame($first, $second);
$this->assertSame(['ko' => '프랑스'], $second['FR']['name']);
}
public function test_missing_file_is_noop(): void
{
if (File::exists($this->settingsFile)) {
File::delete($this->settingsFile);
}
($this->migration())->run($this->context());
$this->assertFalse(File::exists($this->settingsFile));
}
public function test_missing_available_countries_is_noop(): void
{
$this->writeSettings(['default_country' => 'KR']);
($this->migration())->run($this->context());
$settings = json_decode((string) File::get($this->settingsFile), true);
$this->assertSame('KR', $settings['default_country']);
$this->assertArrayNotHasKey('available_countries', $settings);
}
public function test_non_array_name_is_left_untouched(): void
{
// 구 스키마 잔재(문자열 name)는 이 마이그레이션의 책임이 아니다 — 건드리지 않는다.
$this->writeSettings([
'default_country' => 'KR',
'available_countries' => [
['code' => 'KR', 'name' => '대한민국', 'is_active' => true],
],
]);
($this->migration())->run($this->context());
$this->assertSame('대한민국', $this->readCountries()['KR']['name']);
}
}
@@ -0,0 +1,21 @@
<?php
namespace Modules\Sirsoft\Ecommerce\Upgrades;
use App\Extension\AbstractUpgradeStep;
/**
* Ecommerce 모듈 1.0.2 업그레이드 스텝
*
* 배송가능 국가명(shipping.available_countries[].name)의 저장본에 남아 있는 빈 로케일 키를
* 제거한다. 구 국가 추가 폼이 한국어/영문 두 칸만 렌더했던 탓에, 한쪽을 비운 채 저장하면
* 빈 문자열이 저장본에 박혔다. 부재 로케일은 비워 두는 것이 계약이며(언어팩이 읽기 시점에
* 보강), 빈 문자열은 그 계약을 어기는 어중간한 상태였다.
*
* 국가명을 새로 채우지는 않는다 — 언어팩 보강이 그 역할을 한다.
*
* 모든 비즈니스 로직은 data/1.0.2/migrations/ 로 격리(AbstractUpgradeStep 규약).
*
* @upgrade-path B
*/
class Upgrade_1_0_2 extends AbstractUpgradeStep {}
@@ -0,0 +1,139 @@
<?php
namespace App\Upgrades\Data\Ext\Modules\SirsoftEcommerce\V1_0_2\Migrations;
use App\Extension\Upgrade\DataMigration;
use App\Extension\UpgradeContext;
use Illuminate\Support\Facades\File;
/**
* 배송가능 국가명(available_countries[].name)의 빈 로케일 키를 제거.
*
* 구 국가 추가 폼은 한국어/영문 두 입력칸만 렌더했고, 운영자가 한쪽을 비운 채 저장하면
* `{"ko":"프랑스","en":""}` 처럼 빈 문자열이 저장본에 박혔다. 빈 문자열은 "값이 있음" 도
* "부재" 도 아닌 어중간한 상태다.
*
* 이 시스템의 계약은 "부재 로케일은 비워 둔다" 이다 — 기본 국가는 언어팩
* (`sirsoft-ecommerce::settings.countries.{code}.name`)이 읽기 시점에 보강하고
* (EcommerceSettingsService::getAllSettings), 운영자가 직접 추가한 국가는 운영자가 채운다.
* 따라서 빈 문자열 키를 제거해 "부재" 로 정규화한다.
*
* 이름을 새로 채우지는 않는다 — 언어팩 보강이 그 역할을 하며, 저장본에 값을 박으면
* 운영자 편집값으로 승격되어 이후 언어팩 갱신이 반영되지 않는다.
*
* name 이 배열이 아닌 구 스키마 잔재(문자열)는 이 마이그레이션의 책임이 아니라 건드리지 않는다.
*
* idempotent: 빈 키가 없고 모든 값이 trim 상태면 no-op (파일 쓰기 없음).
*
* V-1 안전: Illuminate\Support\Facades\File + 로컬 헬퍼만 사용.
*/
class PruneEmptyShippingCountryNameLocales implements DataMigration
{
private const MODULE_IDENTIFIER = 'sirsoft-ecommerce';
public function name(): string
{
return 'PruneEmptyShippingCountryNameLocales';
}
public function run(UpgradeContext $context): void
{
$path = $this->settingsFilePath();
if (! File::exists($path)) {
$context->logger->info('[ecommerce:1.0.2] shipping.json 미존재 — 국가명 빈 로케일 청소 스킵');
return;
}
$settings = json_decode((string) File::get($path), true);
if (! is_array($settings) || ! isset($settings['available_countries']) || ! is_array($settings['available_countries'])) {
$context->logger->info('[ecommerce:1.0.2] shipping.json 에 배송가능 국가 목록 없음 — 국가명 빈 로케일 청소 스킵');
return;
}
$countries = $settings['available_countries'];
$prunedKeys = 0;
foreach ($countries as $idx => $country) {
$name = $country['name'] ?? null;
// 구 스키마 잔재(문자열 name)는 대상 아님
if (! is_array($name)) {
continue;
}
$cleaned = $this->pruneEmptyLocales($name);
if ($cleaned !== $name) {
$prunedKeys += count($name) - count($cleaned);
$countries[$idx]['name'] = $cleaned;
}
}
if ($countries === $settings['available_countries']) {
$context->logger->info('[ecommerce:1.0.2] 국가명에 빈 로케일 키 없음 — 변경 없음 (idempotent)');
return;
}
$settings['available_countries'] = $countries;
// 인코딩 플래그는 EcommerceSettingsService 의 저장부와 동일해야 한다.
// 다르면 이 스텝이 국가명과 무관한 값(URL 등)의 이스케이프까지 조용히 바꿔 쓴다.
File::put($path, json_encode($settings, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
$context->logger->info(sprintf(
'[ecommerce:1.0.2] 국가명 빈 로케일 키 %d개 제거 완료 (국가 %d개 검사)',
$prunedKeys,
count($countries),
));
}
/**
* 다국어 이름 맵에서 빈 값(공백 포함) 로케일 키를 제거하고 남은 값을 trim 합니다.
*
* 모든 로케일이 비어 있으면 빈 배열을 반환합니다 — null 이 아니라 빈 배열이어야
* 백엔드 검증(`shipping.available_countries.*.name` => array)이 깨지지 않습니다.
*
* @param array<string, mixed> $name 로케일 => 국가명 맵
* @return array<string, string> 빈 로케일이 제거되고 trim 된 맵
*/
private function pruneEmptyLocales(array $name): array
{
$cleaned = [];
foreach ($name as $locale => $value) {
if (! is_string($value)) {
continue;
}
$trimmed = trim($value);
if ($trimmed === '') {
continue;
}
$cleaned[$locale] = $trimmed;
}
return $cleaned;
}
/**
* shipping.json 의 저장 경로를 반환합니다.
*
* 테스트 환경에서는 운영 storage 오염을 막기 위해 framework/testing 경로를 사용합니다
* (EcommerceSettingsService 의 저장 경로 분기와 동일).
*
* @return string 설정 파일 절대 경로
*/
private function settingsFilePath(): string
{
$base = app()->runningUnitTests()
? 'framework/testing/modules/'
: 'app/modules/';
return storage_path($base.self::MODULE_IDENTIFIER.'/settings/shipping.json');
}
}
+4 -4
View File
@@ -1,14 +1,14 @@
var Rz=Object.defineProperty;var eM=(ln,i,u)=>i in ln?Rz(ln,i,{enumerable:!0,configurable:!0,writable:!0,value:u}):ln[i]=u;var Ii=(ln,i,u)=>eM(ln,typeof i!="symbol"?i+"":i,u);(function(ln,i,u,Sn){"use strict";function Lt(){const e=typeof window<"u"?window.G7Core?.__runtime:void 0;if(!e)throw new Error("[layout-editor] window.G7Core.__runtime 이 없습니다. 코어 번들(template-engine.min.js)이 편집기 번들보다 먼저 로드되어야 합니다.");return e}const Ai=Lt();Ai.TranslationProvider;const tt=Ai.useTranslation;Ai.TranslationReactContext;function rt(){return typeof window>"u"?null:window.__g7Devtools??null}function wl(e,t){const n=rt();if(!n?.trackEditorState)return;const o={templateIdentifier:e.templateIdentifier,editMode:e.editMode,selectedRoutePath:e.selectedRoute?.path??null,selectedLayoutName:e.selectedRoute?.layoutName??null,routeTreeSize:e.routeTree.length,isRouteTreeCollapsed:e.isRouteTreeCollapsed,locale:e.locale,previewDevice:e.previewDevice,previewZoom:e.previewZoom,lastAction:t,timestamp:Date.now()};try{n.trackEditorState(o)}catch{}}function Bh(){const e=rt();if(e?.clearEditorStateData)try{e.clearEditorStateData()}catch{}}function Wh(e){const t=rt();if(t?.trackEditorSampleMatch)try{t.trackEditorSampleMatch(e)}catch{}}function jh(){const e=rt();if(e?.clearEditorSampleData)try{e.clearEditorSampleData()}catch{}}function Hh(e){const t=rt();if(t?.trackEditorHistoryEntry)try{t.trackEditorHistoryEntry(e)}catch{}}function Fh(){const e=rt();if(e?.clearEditorHistoryData)try{e.clearEditorHistoryData()}catch{}}function kl(e){const t=rt();if(t?.trackEditorSelection)try{t.trackEditorSelection(e)}catch{}}function Kh(){const e=rt();if(e?.clearEditorSelectionData)try{e.clearEditorSelectionData()}catch{}}function or(e){const t=rt();if(t?.trackEditorPropertyPatch)try{t.trackEditorPropertyPatch(e)}catch{}}function Cn(e){const t=rt();if(t?.trackEditorDnd)try{t.trackEditorDnd(e)}catch{}}function Vh(){const e=rt();if(e?.clearEditorDndData)try{e.clearEditorDndData()}catch{}}function st(e){const t=rt();if(t?.trackEditorDocument)try{t.trackEditorDocument(e)}catch{}}function Uh(){const e=rt();if(e?.clearEditorDocumentData)try{e.clearEditorDocumentData()}catch{}}function qh(e){const t=rt();if(t?.trackEditorSpecMerge)try{t.trackEditorSpecMerge(e)}catch{}}function Gh(){const e=rt();if(e?.clearEditorSpecMergeData)try{e.clearEditorSpecMergeData()}catch{}}function Ti(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+e.charCodeAt(n)>>>0;return t}function Et(e){const t=rt();if(t?.trackEditorI18n)try{t.trackEditorI18n(e)}catch{}}function Yh(){const e=rt();if(e?.clearEditorI18nData)try{e.clearEditorI18nData()}catch{}}function Sl(e){const t=rt();if(t?.trackPageState)try{t.trackPageState(e)}catch{}}function Xh(){const e=rt();if(e?.clearPageStateData)try{e.clearPageStateData()}catch{}}const Cl="g7le.routeTree.collapsed";function Jh(){if(typeof window>"u")return!1;try{return window.localStorage?.getItem(Cl)==="1"}catch{return!1}}function Zh(e){if(!(typeof window>"u"))try{window.localStorage?.setItem(Cl,e?"1":"0")}catch{}}function Qh(e,t){return{templateIdentifier:e,routeTree:[],routesError:null,selectedRoute:null,isRouteTreeCollapsed:Jh(),editMode:"route",returnRoute:null,returnEditMode:null,locale:t,previewDevice:"desktop",previewZoom:1,previewCustomWidth:1024,previewColorScheme:"light",history:{canUndo:!1,canRedo:!1},isPaletteOpen:!1,availableStates:[],activeStateId:null,layoutVersions:{},extensionVersions:{}}}function Rh(e,t){switch(t.type){case"SET_ROUTE_TREE":return{...e,routeTree:t.tree,routesError:null};case"SET_ROUTES_ERROR":return{...e,routesError:t.error};case"SELECT_ROUTE":return{...e,editMode:"route",selectedRoute:t.route,returnRoute:null,returnEditMode:null};case"TOGGLE_ROUTE_TREE":return{...e,isRouteTreeCollapsed:!e.isRouteTreeCollapsed};case"SET_LOCALE":return{...e,locale:t.locale};case"ENTER_BASE_EDIT":return{...e,editMode:"base",returnRoute:t.returnRoute!==void 0?t.returnRoute:e.selectedRoute,selectedRoute:{path:`__base__/${t.layoutName}`,layoutName:t.layoutName}};case"EXIT_BASE_EDIT":return{...e,editMode:"route",selectedRoute:e.returnRoute,returnRoute:null};case"ENTER_MODAL_EDIT":return{...e,editMode:"modal",returnRoute:t.returnRoute!==void 0?t.returnRoute:e.selectedRoute,selectedRoute:{path:`__modal__/${t.modalId}`,layoutName:t.hostLayout}};case"EXIT_MODAL_EDIT":return{...e,editMode:"route",selectedRoute:e.returnRoute,returnRoute:null};case"ENTER_EXTENSION_EDIT":return{...e,editMode:"extension",returnRoute:t.returnRoute!==void 0?t.returnRoute:e.selectedRoute,selectedRoute:{path:`__extension__/${t.extensionId}`,layoutName:t.extensionHost??null}};case"SET_RETURN_ROUTE":return e.editMode==="route"||e.returnRoute!==null?e:{...e,returnRoute:t.route};case"EXIT_EXTENSION_EDIT":return{...e,editMode:"route",selectedRoute:e.returnRoute,returnRoute:null};case"ENTER_ITERATION_ITEM_EDIT":return{...e,editMode:"iteration_item",returnRoute:t.returnRoute!==void 0?t.returnRoute:e.selectedRoute,returnEditMode:e.ediLine truncated
var Rz=Object.defineProperty;var eM=(ln,i,u)=>i in ln?Rz(ln,i,{enumerable:!0,configurable:!0,writable:!0,value:u}):ln[i]=u;var Ii=(ln,i,u)=>eM(ln,typeof i!="symbol"?i+"":i,u);(function(ln,i,u,Sn){"use strict";function Lt(){const e=typeof window<"u"?window.G7Core?.__runtime:void 0;if(!e)throw new Error("[layout-editor] window.G7Core.__runtime 이 없습니다. 코어 번들(template-engine.min.js)이 편집기 번들보다 먼저 로드되어야 합니다.");return e}const Ai=Lt();Ai.TranslationProvider;const tt=Ai.useTranslation;Ai.TranslationReactContext;function rt(){return typeof window>"u"?null:window.__g7Devtools??null}function wl(e,t){const n=rt();if(!n?.trackEditorState)return;const o={templateIdentifier:e.templateIdentifier,editMode:e.editMode,selectedRoutePath:e.selectedRoute?.path??null,selectedLayoutName:e.selectedRoute?.layoutName??null,routeTreeSize:e.routeTree.length,isRouteTreeCollapsed:e.isRouteTreeCollapsed,locale:e.locale,previewDevice:e.previewDevice,previewZoom:e.previewZoom,lastAction:t,timestamp:Date.now()};try{n.trackEditorState(o)}catch{}}function Bh(){const e=rt();if(e?.clearEditorStateData)try{e.clearEditorStateData()}catch{}}function Wh(e){const t=rt();if(t?.trackEditorSampleMatch)try{t.trackEditorSampleMatch(e)}catch{}}function jh(){const e=rt();if(e?.clearEditorSampleData)try{e.clearEditorSampleData()}catch{}}function Hh(e){const t=rt();if(t?.trackEditorHistoryEntry)try{t.trackEditorHistoryEntry(e)}catch{}}function Fh(){const e=rt();if(e?.clearEditorHistoryData)try{e.clearEditorHistoryData()}catch{}}function kl(e){const t=rt();if(t?.trackEditorSelection)try{t.trackEditorSelection(e)}catch{}}function Kh(){const e=rt();if(e?.clearEditorSelectionData)try{e.clearEditorSelectionData()}catch{}}function or(e){const t=rt();if(t?.trackEditorPropertyPatch)try{t.trackEditorPropertyPatch(e)}catch{}}function Cn(e){const t=rt();if(t?.trackEditorDnd)try{t.trackEditorDnd(e)}catch{}}function Vh(){const e=rt();if(e?.clearEditorDndData)try{e.clearEditorDndData()}catch{}}function st(e){const t=rt();if(t?.trackEditorDocument)try{t.trackEditorDocument(e)}catch{}}function Uh(){const e=rt();if(e?.clearEditorDocumentData)try{e.clearEditorDocumentData()}catch{}}function qh(e){const t=rt();if(t?.trackEditorSpecMerge)try{t.trackEditorSpecMerge(e)}catch{}}function Gh(){const e=rt();if(e?.clearEditorSpecMergeData)try{e.clearEditorSpecMergeData()}catch{}}function Ti(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+e.charCodeAt(n)>>>0;return t}function Et(e){const t=rt();if(t?.trackEditorI18n)try{t.trackEditorI18n(e)}catch{}}function Yh(){const e=rt();if(e?.clearEditorI18nData)try{e.clearEditorI18nData()}catch{}}function Sl(e){const t=rt();if(t?.trackPageState)try{t.trackPageState(e)}catch{}}function Xh(){const e=rt();if(e?.clearPageStateData)try{e.clearPageStateData()}catch{}}const Cl="g7le.routeTree.collapsed";function Jh(){if(typeof window>"u")return!1;try{return window.localStorage?.getItem(Cl)==="1"}catch{return!1}}function Zh(e){if(!(typeof window>"u"))try{window.localStorage?.setItem(Cl,e?"1":"0")}catch{}}function Qh(e,t){return{templateIdentifier:e,routeTree:[],routesError:null,selectedRoute:null,isRouteTreeCollapsed:Jh(),editMode:"route",returnRoute:null,returnEditMode:null,locale:t,previewDevice:"desktop",previewZoom:1,previewCustomWidth:1024,previewColorScheme:"light",history:{canUndo:!1,canRedo:!1},isPaletteOpen:!1,availableStates:[],activeStateId:null,layoutVersions:{},extensionVersions:{}}}function Rh(e,t){switch(t.type){case"SET_ROUTE_TREE":return{...e,routeTree:t.tree,routesError:null};case"SET_ROUTES_ERROR":return{...e,routesError:t.error};case"SELECT_ROUTE":return{...e,editMode:"route",selectedRoute:t.route,returnRoute:null,returnEditMode:null};case"TOGGLE_ROUTE_TREE":return{...e,isRouteTreeCollapsed:!e.isRouteTreeCollapsed};case"SET_LOCALE":return{...e,locale:t.locale};case"ENTER_BASE_EDIT":return{...e,editMode:"base",returnRoute:t.returnRoute!==void 0?t.returnRoute:e.selectedRoute,selectedRoute:{path:`__base__/${t.layoutName}`,layoutName:t.layoutName}};case"EXIT_BASE_EDIT":return{...e,editMode:"route",selectedRoute:e.returnRoute,returnRoute:null};case"ENTER_MODAL_EDIT":return{...e,editMode:"modal",returnRoute:t.returnRoute!==void 0?t.returnRoute:e.selectedRoute,selectedRoute:{path:`__modal__/${t.modalId}`,layoutName:t.hostLayout}};case"EXIT_MODAL_EDIT":return{...e,editMode:"route",selectedRoute:e.returnRoute,returnRoute:null};case"ENTER_EXTENSION_EDIT":return{...e,editMode:"extension",returnRoute:t.returnRoute!==void 0?t.returnRoute:e.selectedRoute,selectedRoute:{path:`__extension__/${t.extensionId}`,layoutName:t.extensionHost??null}};case"SET_RETURN_ROUTE":return e.editMode==="route"||e.returnRoute!==null?e:{...e,returnRoute:t.route};case"EXIT_EXTENSION_EDIT":return{...e,editMode:"route",selectedRoute:e.returnRoute,returnRoute:null};case"ENTER_ITERATION_ITEM_EDIT":return{...e,editMode:"iteration_item",returnRoute:t.returnRoute!==void 0?t.returnRoute:e.selectedRoute,returnEditMode:e.ediLine truncated
"keyword": "",
"page": 1
}`,shapeErrorKey:"layout_editor.json_block.must_be_object",validate:_=>{const S=Object.keys(_??{}).filter(E=>!$s(E));return S.length?a("layout_editor.json_block.invalid_keys",{keys:S.join(", ")}):null}}):i.jsxs(i.Fragment,{children:[v.length===0?i.jsx("p",{"data-testid":`g7le-initstate-${e}-empty`,style:ES,children:a("layout_editor.initstate.no_values")}):v.map(_=>{const E=Ew(b,r,_)==="inherited",C=e==="isolated"&&l[_];return i.jsx(aS,{scope:e,itemKey:_,value:o[_],inherited:E,isOrphan:!!C,onChangeValue:N=>x(_,N),onRemove:()=>k(_),t:a},_)}),i.jsxs("div",{style:xS,children:[i.jsx("input",{type:"text","data-testid":`g7le-initstate-${e}-add-name`,value:d,placeholder:a("layout_editor.initstate.value_name"),onChange:_=>{c(_.target.value),y&&g(null)},onKeyDown:_=>{_.key==="Enter"&&(_.preventDefault(),w())},"aria-invalid":y?!0:void 0,style:{...wS,...y?kS:null}}),i.jsx("select",{"data-testid":`g7le-initstate-${e}-add-kind`,value:p,onChange:_=>f(_.target.value),"aria-label":a("layout_editor.initstate.value_kind"),style:CS,children:iS.map(_=>i.jsx("option",{value:_.kind,children:a(_.labelKey)},_.kind))}),i.jsxs("button",{type:"button","data-testid":`g7le-initstate-${e}-add`,onClick:w,style:$S,children:["+ ",a("layout_editor.initstate.add_value")]})]}),y?i.jsx("p",{"data-testid":`g7le-initstate-${e}-add-error`,style:SS,children:y}):null]})]})}function aS({scope:e,itemKey:t,value:n,inherited:o,isOrphan:r,onChangeValue:s,onRemove:a,t:l}){const[d,c]=u.useState(!1);let p;try{p=JSON.stringify(n,null,2)??String(n)}catch{p=String(n)}return i.jsxs("div",{"data-testid":`g7le-initstate-${e}-item-${t}`,style:yS,children:[i.jsxs("div",{style:bS,children:[o?i.jsx("span",{"data-testid":`g7le-initstate-inherited-${t}`,style:mS,children:"🔗"}):null,i.jsx("code",{style:vS,children:t}),i.jsx("span",{style:{flex:1}}),i.jsx("button",{type:"button","data-testid":`g7le-initstate-code-${t}`,onClick:()=>c(f=>!f),style:Ws,"aria-label":l("layout_editor.value_tree.show_source"),title:l("layout_editor.value_tree.show_source"),children:"</>"}),o?i.jsx("button",{type:"button","data-testid":`g7le-initstate-revert-${t}`,onClick:a,style:Ws,children:l("layout_editor.initstate.revert")}):i.jsx("button",{type:"button","data-testid":`g7le-initstate-remove-${t}`,onClick:a,style:Ws,"aria-label":l("layout_editor.init_actions.remove"),children:"✕"})]}),d?i.jsx("pre",{"data-testid":`g7le-initstate-code-block-${t}`,style:AS,children:p}):null,i.jsx(Dn,{value:n,onChange:s,t:l,path:t,scope:e}),r?i.jsxs("p",{"data-testid":`g7le-initstate-isolated-orphan-${t}`,style:_S,children:["⚠ ",l("layout_editor.initstate.isolated_orphan")]}):null]})}const lS={display:"flex",flexDirection:"column",gap:14,minWidth:0},dS={margin:0,fontSize:13,fontWeight:700,color:"#0f172a"},cS={margin:0,fontSize:11,color:"#1d4ed8",background:"#eff6ff",padding:"6px 8px",borderRadius:6},uS={display:"flex",flexDirection:"column",gap:8,padding:10,border:"1px solid #e2e8f0",borderRadius:10,minWidth:0},pS={display:"flex",alignItems:"center",justifyContent:"space-between",gap:8},fS={fontSize:12,fontWeight:700,color:"#475569"},gS={margin:0,fontSize:11,color:"#94a3b8"},hS={padding:"2px 8px",fontSize:11,border:"1px solid #cbd5e1",borderRadius:6,background:"#fff",color:"#475569",cursor:"pointer"},yS={display:"flex",flexDirection:"column",gap:4,padding:"6px 8px",border:"1px solid #f1f5f9",borderRadius:6,minWidth:0},bS={display:"flex",alignItems:"center",gap:6},mS={fontSize:12},vS={fontSize:12,color:"#0f172a",fontFamily:"monospace"},Ws={border:"1px solid #cbd5e1",borderRadius:6,background:"#fff",color:"#475569",cursor:"pointer",fontSize:11,padding:"2px 6px"},_S={margin:0,fontSize:11,color:"#b45309",background:"#fef3c7",padding:"4px 6px",borderRadius:6},xS={display:"flex",gap:6,alignItems:"center"},wS={padding:"4px 8px",fontSize:12,border:"1px solid #cbd5e1",borderRadius:6},kS={border:"1px solid #dc2626"},SS={margin:0,fontSize:11,color:"#dc2626"},CS={padding:"4px 8px",fontSize:12,border:"1px solid #cbd5e1",borderRadius:6,background:"#fff",color:"#0f172a"},$S={padding:"2px 10px",fontSize:11,border:"1px dashed #94a3b8",borderRadius:6,background:"#fff",color:"#475569",cursor:"pointer"},ES={margin:0,fontSize:12,color:"#94a3b8"},IS={margin:0,fontSize:11,color:"#94a3b8"},AS={margin:"2px 0",padding:"6px 8px",fontSize:11,fontFamily:"monospace",color:"#0f172a",background:"#f1f5f9",border:"1px solid #e2e8f0",borderRadius:6,whiteSpace:"pre-wrap",wordBreak:"break-all",overflowX:"auto"},TS={self:"layout_editor.error_rows.source_self",inherited:"layout_editor.error_rows.source_inherited",template:"layout_editor.error_rows.source_template",none:"layout_editor.error_rows.source_none"};function js({value:e,onChange:t,t:n,codes:o,mode:r="local",sourceOf:s,renderActionList:a,testIdPrefix:l="g7le-error-rows"}){const d=o??Object.keys(e),c=u.useCallback((f,y)=>{t({...e,[f]:y})},[e,t]),p=u.useCallback(f=>{const y={...e};delete y[f],t(y)},[e,t]);return i.jsx("div",{className:l,"data-testid":l,children:d.map(f=>{const y=e[f],g= Line truncated
"page": "{{query.page ?? 1}}"
}`,shapeErrorKey:"layout_editor.data_sources.error.params_object",invalidErrorKey:"layout_editor.data_sources.error.params_json",t:n,onChange:I=>x(P=>P&&{...P,paramsRawValue:I??{},paramsRawValid:!0}),onValidityChange:I=>x(P=>P&&{...P,paramsRawValid:I})}):i.jsxs("div",{"data-testid":"g7le-data-sources-field-params",children:[b.paramRows.length===0&&i.jsx("p",{"data-testid":"g7le-ds-params-empty",style:WC,children:n("layout_editor.data_sources.field.params_empty")}),i.jsx(Dr,{value:b.paramRows.map(I=>({key:I.key,value:I.value})),onChange:I=>x({...b,paramRows:I.map(P=>({key:P.key??"",value:P.value??""}))}),keyField:"key",valueField:"value",t:n,candidates:d,testidPrefix:"g7le-ds-params-kv",keyPlaceholder:n("layout_editor.data_sources.field.param_key_placeholder"),valuePlaceholder:"{{query.page ?? 1}}",addLabel:n("layout_editor.data_sources.field.param_add")}),(()=>{const I=qs(b.paramRows);return Object.keys(I).length===0?null:i.jsxs("div",{style:Au,children:[i.jsxs("button",{type:"button","data-testid":"g7le-ds-params-preview-toggle","aria-expanded":_,onClick:()=>S(P=>!P),style:Tu,children:[_?"▴":"▾"," ",n("layout_editor.data_sources.field.params_preview")]}),_&&i.jsx("pre",{"data-testid":"g7le-ds-params-preview",style:{...Du,marginTop:4},children:JSON.stringify(I,null,2)})]})})()]}),i.jsx("div",{style:{fontSize:11,color:"#94a3b8",marginTop:4},children:n("layout_editor.data_sources.field.params_hint")})]}),i.jsxs("div",{style:ut,children:[i.jsx("label",{style:ct,children:n("layout_editor.data_sources.field.fallback")}),b.fallbackEnabled?i.jsxs("div",{"data-testid":"g7le-data-sources-field-fallback",style:{display:"flex",flexDirection:"column",gap:6},children:[i.jsx(Dn,{value:b.fallbackValue===void 0?{}:b.fallbackValue,onChange:I=>x({...b,fallbackValue:I}),t:n,path:"fallback",scope:"ds-fallback",renderStringLeaf:I=>i.jsx(Ve,{value:I.value,onChange:I.onChange,t:n,candidates:d,testidPrefix:I.testidPrefix})}),(()=>{const I=b.fallbackValue===void 0?{}:b.fallbackValue;return i.jsxs("div",{style:Au,children:[i.jsxs("button",{type:"button","data-testid":"g7le-ds-fallback-preview-toggle","aria-expanded":E,onClick:()=>C(P=>!P),style:Tu,children:[E?"▴":"▾"," ",n("layout_editor.data_sources.field.fallback_preview")]}),E&&i.jsx("pre",{"data-testid":"g7le-ds-fallback-preview",style:{...Du,marginTop:4},children:JSON.stringify(I,null,2)})]})})(),i.jsx("button",{type:"button","data-testid":"g7le-data-sources-field-fallback-clear",onClick:()=>x({...b,fallbackEnabled:!1,fallbackValue:void 0}),style:{...on,padding:"2px 8px",fontSize:11,alignSelf:"flex-start",color:"#dc2626",borderColor:"#fecaca"},children:n("layout_editor.data_sources.field.fallback_clear")})]}):i.jsxs("button",{type:"button","data-testid":"g7le-data-sources-field-fallback-add",onClick:()=>x({...b,fallbackEnabled:!0,fallbackValue:{}}),style:{...on,padding:"4px 10px",display:"block"},children:["+ ",n("layout_editor.data_sources.field.fallback_add")]})]}),b.type==="websocket"&&i.jsxs("div",{"data-testid":"g7le-ds-ws-section",style:To,children:[i.jsx("div",{style:Do,children:n("layout_editor.data_sources.section.websocket")}),i.jsxs("div",{style:ut,children:[i.jsx("label",{style:ct,children:n("layout_editor.data_sources.field.channel")}),i.jsx("input",{"data-testid":"g7le-ds-ws-channel",style:jt,value:b.channel,onChange:I=>x({...b,channel:I.target.value}),placeholder:"core.admin.dashboard"})]}),i.jsxs("div",{style:ut,children:[i.jsx("label",{style:ct,children:n("layout_editor.data_sources.field.event")}),i.jsx("input",{"data-testid":"g7le-ds-ws-event",style:jt,value:b.event,onChange:I=>x({...b,event:I.target.value}),placeholder:"dashboard.stats.updated"})]}),i.jsxs("div",{style:ut,children:[i.jsx("label",{style:ct,children:n("layout_editor.data_sources.field.channel_type")}),i.jsx("select",{"data-testid":"g7le-ds-ws-channeltype",style:jt,value:b.channel_type,onChange:I=>x({...b,channel_type:I.target.value}),children:MC.map(I=>i.jsx("option",{value:I,children:I},I))})]}),i.jsxs("div",{style:ut,children:[i.jsx("label",{style:ct,children:n("layout_editor.data_sources.field.target_source")}),i.jsx("input",{"data-testid":"g7le-ds-ws-target",style:jt,value:b.target_source,onChange:I=>x({...b,target_source:I.target.value}),list:"g7le-ds-ws-target-list"}),i.jsx("datalist",{id:"g7le-ds-ws-target-list",children:h.filter(I=>I.id!==b.id).map(I=>typeof I.id=="string"?i.jsx("option",{value:I.id},I.id):null)})]}),i.jsxs("div",{style:ut,children:[i.jsx("label",{style:ct,children:n("layout_editor.data_sources.field.on_receive")}),i.jsx("div",{"data-testid":"g7le-ds-ws-onreceive",children:i.jsx(Gt,{actions:b.onReceive,onChange:I=>x({...b,onReceive:I}),t:n,recipes:s,candidatePools:z,chipContext:"payload",actionChipCandidates:l?.actionChipCandidates??null,testIdPrefix:"g7le-ds-onreceive-list"})})]})]}),i.jsxs("div",{style:To,children:[i.jsx("div",{style:Do,children:n("layout_editor.data_sources.section.on_success")}),i.jsx("div",{"data-testid":"g7le-ds-onsuccess",children:i.j Line truncated
`).split(`
`);return t.length>0&&t[t.length-1]===""&&t.pop(),t}const Fu=4e3;function m$(e,t,n=3){const o=Hu(e),r=Hu(t);let s=0;const a=Math.min(o.length,r.length);for(;s<a&&o[s]===r[s];)s++;let l=0;const d=Math.min(o.length,r.length)-s;for(;l<d&&o[o.length-1-l]===r[r.length-1-l];)l++;const c=o.slice(s,o.length-l),p=r.slice(s,r.length-l);if(c.length>Fu||p.length>Fu)return{hunks:[],addedCount:-1,removedCount:-1,identical:!1};const f=y$(c,p),y=b$(c,p,f),g=[];let m=s,h=s,v=0,b=0;for(let w=0;w<s;w++)g.push({kind:"context",oldLine:w+1,newLine:w+1,content:o[w]});for(const w of y)w.kind==="context"?(m++,h++,g.push({kind:"context",oldLine:m,newLine:h,content:w.content})):w.kind==="remove"?(m++,b++,g.push({kind:"remove",oldLine:m,newLine:null,content:w.content})):(h++,v++,g.push({kind:"add",oldLine:null,newLine:h,content:w.content}));for(let w=0;w<l;w++){const _=o.length-l+w,S=r.length-l+w;g.push({kind:"context",oldLine:_+1,newLine:S+1,content:o[_]})}const x=v===0&&b===0;return{hunks:v$(g,n),addedCount:v,removedCount:b,identical:x}}function v$(e,t){const n=[];for(let r=0;r<e.length;r++)e[r].kind!=="context"&&n.push(r);if(n.length===0)return[];const o=[];for(const r of n){const s=Math.max(0,r-t),a=Math.min(e.length-1,r+t),l=o[o.length-1];l&&s<=l.end+1?l.end=Math.max(l.end,a):o.push({start:s,end:a})}return o.map(r=>{const s=e.slice(r.start,r.end+1);let a=0,l=0,d=0,c=0;for(const g of s)g.oldLine!==null&&(a===0&&(a=g.oldLine),d++),g.newLine!==null&&(l===0&&(l=g.newLine),c++);const p=a||(d===0?0:1),f=l||(c===0?0:1);return{header:`@@ -${p},${d} +${f},${c} @@`,oldStart:p,oldCount:d,newStart:f,newCount:c,lines:s}})}function Ku(e){return JSON.stringify(Ys(e),null,2)}function Ys(e){if(Array.isArray(e))return e.map(Ys);if(e&&typeof e=="object"){const t=e,n={};for(const o of Object.keys(t).sort())n[o]=Ys(t[o]);return n}return e}const _$={display:"flex",flexDirection:"column",height:"100%",minHeight:0},x$={display:"flex",alignItems:"center",gap:8,padding:"12px 16px",borderBottom:"1px solid #e2e8f0",background:"#f8fafc"},w$={display:"inline-flex",alignItems:"center",gap:4,padding:"4px 10px",borderRadius:6,border:"1px solid #cbd5e1",background:"#ffffff",color:"#0f172a",fontSize:12,fontWeight:600,cursor:"pointer",outline:"none"},k$={marginLeft:"auto",border:"none",background:"transparent",fontSize:16,color:"#64748b",cursor:"pointer",outline:"none"},S$={display:"flex",alignItems:"center",gap:12,padding:"8px 16px",borderBottom:"1px solid #e2e8f0",background:"#ffffff",fontSize:12,fontWeight:600},C$={flex:1,minHeight:0,overflow:"auto",background:"#ffffff",fontFamily:'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace',fontSize:12,lineHeight:1.5},Vu={padding:"24px 12px",textAlign:"center",color:"#94a3b8",fontSize:13},$$={padding:"2px 12px",background:"#f1f5f9",color:"#64748b",borderTop:"1px solid #e2e8f0",borderBottom:"1px solid #e2e8f0",userSelect:"none"};function E$(e){return e==="add"?{row:{background:"#e6ffed"},gutter:{background:"#cdffd8",color:"#22863a"},sign:"+",signColor:"#22863a"}:e==="remove"?{row:{background:"#ffeef0"},gutter:{background:"#ffdce0",color:"#b31d28"},sign:"-",signColor:"#b31d28"}:{row:{background:"#ffffff"},gutter:{background:"#f8fafc",color:"#94a3b8"},sign:" ",signColor:"#94a3b8"}}const Uu={display:"inline-block",width:44,textAlign:"right",padding:"0 6px",color:"#94a3b8",userSelect:"none",borderRight:"1px solid #e2e8f0",whiteSpace:"nowrap"};function I$({oldVersion:e,newVersion:t,oldContent:n,newContent:o,t:r,onBack:s,onClose:a}){const l=u.useMemo(()=>{const c=Ku(n),p=Ku(o);return m$(c,p)},[n,o]),d=l.addedCount<0;return i.jsxs("div",{className:"g7le-version-diff","data-testid":"g7le-version-diff",style:_$,children:[i.jsxs("div",{"data-modal-drag-handle":!0,style:x$,children:[i.jsxs("button",{type:"button",onClick:s,style:w$,"data-testid":"g7le-version-diff-back",children:["← ",r("layout_editor.version_history.diff_back")]}),i.jsx("span",{style:{fontSize:14,fontWeight:700},"data-testid":"g7le-version-diff-title",children:r("layout_editor.version_history.diff_title",{old:e,new:t})}),i.jsx("button",{type:"button","aria-label":r("layout_editor.version_history.close"),onClick:a,style:k$,"data-testid":"g7le-version-diff-close",children:"✕"})]}),!d&&i.jsxs("div",{style:S$,"data-testid":"g7le-version-diff-summary",children:[i.jsx("span",{style:{color:"#16a34a"},"data-testid":"g7le-version-diff-added",children:r("layout_editor.version_history.added",{count:Math.max(0,l.addedCount)})}),i.jsx("span",{style:{color:"#dc2626"},"data-testid":"g7le-version-diff-removed",children:r("layout_editor.version_history.removed",{count:Math.max(0,l.removedCount)})})]}),i.jsx("div",{style:C$,children:d?i.jsx("div",{style:Vu,"data-testid":"g7le-version-diff-too-large",children:r("layout_editor.version_history.diff_too_large")}):l.identical?i.jsx("div",{style:Vu,"data-testid":"g7le-version-diff-identical",children:r("layout_editor.version_history.diff_identical")}):l.hunks.map((c,p)=>i.jsxs("div",{"data-testid":`gLine truncated
`);return t.length>0&&t[t.length-1]===""&&t.pop(),t}const Fu=4e3;function m$(e,t,n=3){const o=Hu(e),r=Hu(t);let s=0;const a=Math.min(o.length,r.length);for(;s<a&&o[s]===r[s];)s++;let l=0;const d=Math.min(o.length,r.length)-s;for(;l<d&&o[o.length-1-l]===r[r.length-1-l];)l++;const c=o.slice(s,o.length-l),p=r.slice(s,r.length-l);if(c.length>Fu||p.length>Fu)return{hunks:[],addedCount:-1,removedCount:-1,identical:!1};const f=y$(c,p),y=b$(c,p,f),g=[];let m=s,h=s,v=0,b=0;for(let w=0;w<s;w++)g.push({kind:"context",oldLine:w+1,newLine:w+1,content:o[w]});for(const w of y)w.kind==="context"?(m++,h++,g.push({kind:"context",oldLine:m,newLine:h,content:w.content})):w.kind==="remove"?(m++,b++,g.push({kind:"remove",oldLine:m,newLine:null,content:w.content})):(h++,v++,g.push({kind:"add",oldLine:null,newLine:h,content:w.content}));for(let w=0;w<l;w++){const _=o.length-l+w,S=r.length-l+w;g.push({kind:"context",oldLine:_+1,newLine:S+1,content:o[_]})}const x=v===0&&b===0;return{hunks:v$(g,n),addedCount:v,removedCount:b,identical:x}}function v$(e,t){const n=[];for(let r=0;r<e.length;r++)e[r].kind!=="context"&&n.push(r);if(n.length===0)return[];const o=[];for(const r of n){const s=Math.max(0,r-t),a=Math.min(e.length-1,r+t),l=o[o.length-1];l&&s<=l.end+1?l.end=Math.max(l.end,a):o.push({start:s,end:a})}return o.map(r=>{const s=e.slice(r.start,r.end+1);let a=0,l=0,d=0,c=0;for(const g of s)g.oldLine!==null&&(a===0&&(a=g.oldLine),d++),g.newLine!==null&&(l===0&&(l=g.newLine),c++);const p=a||(d===0?0:1),f=l||(c===0?0:1);return{header:`@@ -${p},${d} +${f},${c} @@`,oldStart:p,oldCount:d,newStart:f,newCount:c,lines:s}})}function Ku(e){return JSON.stringify(Ys(e),null,2)}function Ys(e){if(Array.isArray(e))return e.map(Ys);if(e&&typeof e=="object"){const t=e,n={};for(const o of Object.keys(t).sort())n[o]=Ys(t[o]);return n}return e}const _$={display:"flex",flexDirection:"column",height:"100%",minHeight:0},x$={display:"flex",alignItems:"center",gap:8,padding:"12px 16px",borderBottom:"1px solid #e2e8f0",background:"#f8fafc"},w$={display:"inline-flex",alignItems:"center",gap:4,padding:"4px 10px",borderRadius:6,border:"1px solid #cbd5e1",background:"#ffffff",color:"#0f172a",fontSize:12,fontWeight:600,cursor:"pointer",outline:"none"},k$={marginLeft:"auto",border:"none",background:"transparent",fontSize:16,color:"#64748b",cursor:"pointer",outline:"none"},S$={display:"flex",alignItems:"center",gap:12,padding:"8px 16px",borderBottom:"1px solid #e2e8f0",background:"#ffffff",fontSize:12,fontWeight:600},C$={flex:1,minHeight:0,overflow:"auto",background:"#ffffff",fontFamily:'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace',fontSize:12,lineHeight:1.5},Vu={padding:"24px 12px",textAlign:"center",color:"#94a3b8",fontSize:13},$$={padding:"2px 12px",background:"#f1f5f9",color:"#64748b",borderTop:"1px solid #e2e8f0",borderBottom:"1px solid #e2e8f0",userSelect:"none"};function E$(e){return e==="add"?{row:{background:"#e6ffed"},gutter:{background:"#cdffd8",color:"#22863a"},sign:"+",signColor:"#22863a"}:e==="remove"?{row:{background:"#ffeef0"},gutter:{background:"#ffdce0",color:"#b31d28"},sign:"-",signColor:"#b31d28"}:{row:{background:"#ffffff"},gutter:{background:"#f8fafc",color:"#94a3b8"},sign:" ",signColor:"#94a3b8"}}const Uu={display:"inline-block",width:44,textAlign:"right",padding:"0 6px",color:"#94a3b8",userSelect:"none",borderRight:"1px solid #e2e8f0",whiteSpace:"nowrap"};function I$({oldVersion:e,newVersion:t,oldContent:n,newContent:o,t:r,onBack:s,onClose:a}){const l=u.useMemo(()=>{const c=Ku(n),p=Ku(o);return m$(c,p)},[n,o]),d=l.addedCount<0;return i.jsxs("div",{className:"g7le-version-diff","data-testid":"g7le-version-diff",style:_$,children:[i.jsxs("div",{"data-modal-drag-handle":!0,style:x$,children:[i.jsxs("button",{type:"button",onClick:s,style:w$,"data-testid":"g7le-version-diff-back",children:["← ",r("layout_editor.version_history.diff_back")]}),i.jsx("span",{style:{fontSize:14,fontWeight:700},"data-testid":"g7le-version-diff-title",children:r("layout_editor.version_history.diff_title",{old:e,new:t})}),i.jsx("button",{type:"button","aria-label":r("layout_editor.version_history.close"),onClick:a,style:k$,"data-testid":"g7le-version-diff-close",children:"✕"})]}),!d&&i.jsxs("div",{style:S$,"data-testid":"g7le-version-diff-summary",children:[i.jsx("span",{style:{color:"#16a34a"},"data-testid":"g7le-version-diff-added",children:r("layout_editor.version_history.added",{count:Math.max(0,l.addedCount)})}),i.jsx("span",{style:{color:"#dc2626"},"data-testid":"g7le-version-diff-removed",children:r("layout_editor.version_history.removed",{count:Math.max(0,l.removedCount)})})]}),i.jsx("div",{style:C$,children:d?i.jsx("div",{style:Vu,"data-testid":"g7le-version-diff-too-large",children:r("layout_editor.version_history.diff_too_large")}):l.identical?i.jsx("div",{style:Vu,"data-testid":"g7le-version-diff-identical",children:r("layout_editor.version_history.diff_identical")}):l.hunks.map((c,p)=>i.jsxs("div",{"data-testid":`gLine truncated
To pick up a draggable item, press the space bar.
While dragging, use the arrow keys to move the item.
Press space again to drop the item in its new position, or press escape to cancel.
`},I7={onDragStart(e){let{active:t}=e;return"Picked up draggable item "+t.id+"."},onDragOver(e){let{active:t,over:n}=e;return n?"Draggable item "+t.id+" was moved over droppable area "+n.id+".":"Draggable item "+t.id+" is no longer over a droppable area."},onDragEnd(e){let{active:t,over:n}=e;return n?"Draggable item "+t.id+" was dropped over droppable area "+n.id:"Draggable item "+t.id+" was dropped."},onDragCancel(e){let{active:t}=e;return"Dragging was cancelled. Draggable item "+t.id+" was dropped."}};function A7(e){let{announcements:t=I7,container:n,hiddenTextDescribedById:o,screenReaderInstructions:r=E7}=e;const{announce:s,announcement:a}=S7(),l=Qr("DndLiveRegion"),[d,c]=u.useState(!1);if(u.useEffect(()=>{c(!0)},[]),C7(u.useMemo(()=>({onDragStart(f){let{active:y}=f;s(t.onDragStart({active:y}))},onDragMove(f){let{active:y,over:g}=f;t.onDragMove&&s(t.onDragMove({active:y,over:g}))},onDragOver(f){let{active:y,over:g}=f;s(t.onDragOver({active:y,over:g}))},onDragEnd(f){let{active:y,over:g}=f;s(t.onDragEnd({active:y,over:g}))},onDragCancel(f){let{active:y,over:g}=f;s(t.onDragCancel({active:y,over:g}))}}),[s,t])),!d)return null;const p=u.createElement(u.Fragment,null,u.createElement(w7,{id:o,value:r.draggable}),u.createElement(k7,{id:l,announcement:a}));return n?Sn.createPortal(p,n):p}var it;(function(e){e.DragStart="dragStart",e.DragMove="dragMove",e.DragEnd="dragEnd",e.DragCancel="dragCancel",e.DragOver="dragOver",e.RegisterDroppable="registerDroppable",e.SetDroppableDisabled="setDroppableDisabled",e.UnregisterDroppable="unregisterDroppable"})(it||(it={}));function ti(){}function T7(e,t){return u.useMemo(()=>({sensor:e,options:t??{}}),[e,t])}function D7(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return u.useMemo(()=>[...t].filter(o=>o!=null),[...t])}const Ht=Object.freeze({x:0,y:0});function N7(e,t){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function z7(e,t){const n=ei(e);if(!n)return"0 0";const o={x:(n.x-t.left)/t.width*100,y:(n.y-t.top)/t.height*100};return o.x+"% "+o.y+"%"}function M7(e,t){let{data:{value:n}}=e,{data:{value:o}}=t;return n-o}function L7(e,t){let{data:{value:n}}=e,{data:{value:o}}=t;return o-n}function P7(e){let{left:t,top:n,height:o,width:r}=e;return[{x:t,y:n},{x:t+r,y:n},{x:t,y:n+o},{x:t+r,y:n+o}]}function O7(e,t){if(!e||e.length===0)return null;const[n]=e;return n[t]}function B7(e,t){const n=Math.max(t.top,e.top),o=Math.max(t.left,e.left),r=Math.min(t.left+t.width,e.left+e.width),s=Math.min(t.top+t.height,e.top+e.height),a=r-o,l=s-n;if(o<r&&n<s){const d=t.width*t.height,c=e.width*e.height,p=a*l,f=p/(d+c-p);return Number(f.toFixed(4))}return 0}const W7=e=>{let{collisionRect:t,droppableRects:n,droppableContainers:o}=e;const r=[];for(const s of o){const{id:a}=s,l=n.get(a);if(l){const d=B7(l,t);d>0&&r.push({id:a,data:{droppableContainer:s,value:d}})}}return r.sort(L7)};function j7(e,t){const{top:n,left:o,bottom:r,right:s}=t;return n<=e.y&&e.y<=r&&o<=e.x&&e.x<=s}const H7=e=>{let{droppableContainers:t,droppableRects:n,pointerCoordinates:o}=e;if(!o)return[];const r=[];for(const s of t){const{id:a}=s,l=n.get(a);if(l&&j7(o,l)){const c=P7(l).reduce((f,y)=>f+N7(o,y),0),p=Number((c/4).toFixed(4));r.push({id:a,data:{droppableContainer:s,value:p}})}}return r.sort(M7)};function F7(e,t,n){return{...e,scaleX:t&&n?t.width/n.width:1,scaleY:t&&n?t.height/n.height:1}}function Op(e,t){return e&&t?{x:e.left-t.left,y:e.top-t.top}:Ht}function K7(e){return function(n){for(var o=arguments.length,r=new Array(o>1?o-1:0),s=1;s<o;s++)r[s-1]=arguments[s];return r.reduce((a,l)=>({...a,top:a.top+e*l.y,bottom:a.bottom+e*l.y,left:a.left+e*l.x,right:a.right+e*l.x}),{...n})}}const V7=K7(1);function Bp(e){if(e.startsWith("matrix3d(")){const t=e.slice(9,-1).split(/, /);return{x:+t[12],y:+t[13],scaleX:+t[0],scaleY:+t[5]}}else if(e.startsWith("matrix(")){const t=e.slice(7,-1).split(/, /);return{x:+t[4],y:+t[5],scaleX:+t[0],scaleY:+t[3]}}return null}function U7(e,t,n){const o=Bp(t);if(!o)return e;const{scaleX:r,scaleY:s,x:a,y:l}=o,d=e.left-a-(1-r)*parseFloat(n),c=e.top-l-(1-s)*parseFloat(n.slice(n.indexOf(" ")+1)),p=r?e.width/r:e.width,f=s?e.height/s:e.height;return{width:p,height:f,top:c,right:d+p,bottom:c+f,left:d}}const q7={ignoreTransform:!1};function Bo(e,t){t===void 0&&(t=q7);let n=e.getBoundingClientRect();if(t.ignoreTransform){const{transform:c,transformOrigin:p}=_t(e).getComputedStyle(e);c&&(n=U7(n,c,p))}const{top:o,left:r,width:s,height:a,bottom:l,right:d}=n;return{top:o,left:r,width:s,height:a,bottom:l,right:d}}function Wp(e){return Bo(e,{ignoreTransform:!0})}function G7(e){const t=e.innerWidth,n=e.innerHeight;return{top:0,left:0,right:t,bottom:n,width:t,height:n}}function Y7(e,t){return t===void 0&&(t=_t(e).getComputedStyle(e)),t.position==="fixed"}function X7(e,t){t===void 0&&(t=_t(e).getComputedStyle(e));const n=/(auto|scroll|overlay)/;return["overflow","overflowX","overflowY"].some(r=>{const s=t[r];return typeof s=="string"?n.test(s):!1})}function aa(e,t){const n=[]; Line truncated
`:"",e.message]})]}),i.jsxs("div",{style:{display:"flex",justifyContent:"center",gap:8,flexWrap:"wrap"},children:[e.kind==="unauthorized"&&i.jsx("button",{type:"button","data-testid":"g7le-access-error-action-signin",onClick:a,style:Ha,children:t("layout_editor.access_error.action.sign_in")}),e.kind==="forbidden"&&i.jsx("button",{type:"button","data-testid":"g7le-access-error-action-home",onClick:r,style:Ha,children:t("layout_editor.access_error.action.go_home")}),(e.kind==="not_found"||e.kind==="server_error"||e.kind==="network"||e.kind==="unknown")&&i.jsx("button",{type:"button","data-testid":"g7le-access-error-action-retry",onClick:s,style:Ha,children:t("layout_editor.access_error.action.retry")}),e.kind!=="unauthorized"&&i.jsx("button",{type:"button","data-testid":"g7le-access-error-action-home-secondary",onClick:r,style:h4,children:t("layout_editor.access_error.action.go_admin_home")})]})]})]})}const Ha={padding:"8px 16px",background:"#2563eb",color:"#fff",border:"1px solid #1d4ed8",borderRadius:6,fontSize:13,fontWeight:600,cursor:"pointer"},h4={padding:"8px 16px",background:"#fff",color:"#475569",border:"1px solid #cbd5e1",borderRadius:6,fontSize:13,fontWeight:500,cursor:"pointer"};function y4(e){const t=window;if(typeof t>"u")return{getSnapshot:()=>({globalState:{},localState:{}}),restore:()=>{}};const n=t.G7Core||{},o={templateApp:t.__templateApp,g7CoreState:n.state,g7CoreDispatch:n.dispatch,g7CoreData:n.data,g7CoreModal:n.modal,g7CoreToast:n.toast};let r={...e.initialGlobalState??{}};r._local||(r._local={});const s=[],a=()=>{const c={globalState:{...r},localState:{...r._local??{}}};for(const p of s)try{p(r)}catch{}e.onChange?.(c)},l={},d={getGlobalState:()=>r,setGlobalState:(c,p)=>{typeof c=="function"?r=c(r):r={...r,...c},a()},onGlobalStateChange:c=>(s.push(c),()=>{const p=s.indexOf(c);p>=0&&s.splice(p,1)}),get globalState(){return r},getActionDispatcher:()=>e.actionDispatcher,getDataSource:c=>l[c]??null,setDataSource:(c,p)=>{l[c]=p},refetchDataSource:async c=>null,updateDataSourceItem:(c,p,f)=>l[c]??null,getLocale:()=>e.locale,changeLocale:c=>{},getRouter:()=>({navigate:()=>{},replace:()=>{},push:()=>{}}),updateQueryParams:()=>{}};return t.__templateApp=d,n&&typeof n.dispatch=="function"&&(n.dispatch=(c,p)=>{try{return e.actionDispatcher.executeAction(c,p??{})}catch{return}}),n&&typeof n.modal=="object"&&n.modal!==null&&(n.modal={...n.modal,open:()=>{},close:()=>{},closeAll:()=>{}}),n&&typeof n.toast=="object"&&n.toast!==null&&(n.toast={...n.toast,push:()=>{},dismiss:()=>{}}),{getSnapshot:()=>({globalState:{...r},localState:{...r._local??{}}}),restore:()=>{t.__templateApp===d&&(t.__templateApp=o.templateApp),t.G7Core&&(o.g7CoreState!==void 0&&(t.G7Core.state=o.g7CoreState),o.g7CoreDispatch!==void 0&&(t.G7Core.dispatch=o.g7CoreDispatch),o.g7CoreData!==void 0&&(t.G7Core.data=o.g7CoreData),o.g7CoreModal!==void 0&&(t.G7Core.modal=o.g7CoreModal),o.g7CoreToast!==void 0&&(t.G7Core.toast=o.g7CoreToast)),s.length=0}}}const b4=new Set(["id","userId","postId","orderId","productId","categoryId","commentId","noticeId","inquiryId","addressId","wishlistId","notificationId","roleId","menuId"]);function m4(e){if(!e)return{};const t={},n=/:([a-zA-Z_][a-zA-Z0-9_]*)/g;let o;for(;(o=n.exec(e))!==null;){const r=o[1];t[r]=v4(r)}return t}function v4(e){return b4.has(e)||/Id$|_id$/.test(e)?"1":"sample"}const _4=ar("LayoutEditor");function Go(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function hi(e){if(Array.isArray(e))return e.map(t=>hi(t));if(Go(e)){const t={};for(const[n,o]of Object.entries(e))t[n]=hi(o);return t}return e}function pg(e,t="",n=new Set){for(const[o,r]of Object.entries(e)){const s=t?`${t}.${o}`:o;Go(r)?pg(r,s,n):n.add(s)}return n}function fg(e,t,n,o,r,s=""){for(const[a,l]of Object.entries(t)){const d=s?`${s}.${a}`:a;if(n.has(d)){r(`[LayoutEditor] sampleGlobal key conflict: extension '${o}' override of core key '${d}' ignored`);continue}const c=e[a];Go(l)&&Go(c)?fg(c,l,n,o,r,d):e[a]=hi(l)}}function Fa(e){const t=e.warn??(r=>_4.warn(r)),n=hi(e.coreSeed??{});e.isGuestOnly&&"currentUser"in n&&delete n.currentUser;const o=pg(n);for(const r of e.sources)Go(r.sampleGlobal)&&fg(n,r.sampleGlobal,o,r.id,t);return e.isGuestOnly&&"currentUser"in n&&delete n.currentUser,n}function x4(e){const t={};if(!e||typeof e!="object"||Array.isArray(e))return t;for(const[n,o]of Object.entries(e))n.startsWith("$")&&(t[n]=o);return t}function w4(e){const t={};if(!e||typeof e!="object"||Array.isArray(e))return t;for(const[n,o]of Object.entries(e))n.startsWith("$")||(t[n]=o);return t}function k4(e){if(typeof e!="string")return null;const t=/^\s*\{\{\s*([\s\S]*?)\s*\}\}\s*$/.exec(e);if(!t)return null;let n=t[1];const o=n.indexOf("??");return o>=0&&(n=n.slice(0,o)),n=n.replace(/\?\./g,".").replace(/\s+/g,""),n===""||!/^[A-Za-z_$][A-Za-z0-9_$]*(\.[A-Za-z_$][A-Za-z0-9_$]*)*$/.test(n)?null:n.split(".")}function S4(e,t){const n=k4(t);if(!n||n.length===0)return e;let o=e;for(let a=0;a<n.length;a++){if(o==null||typeof o!="obj Line truncated
`},I7={onDragStart(e){let{active:t}=e;return"Picked up draggable item "+t.id+"."},onDragOver(e){let{active:t,over:n}=e;return n?"Draggable item "+t.id+" was moved over droppable area "+n.id+".":"Draggable item "+t.id+" is no longer over a droppable area."},onDragEnd(e){let{active:t,over:n}=e;return n?"Draggable item "+t.id+" was dropped over droppable area "+n.id:"Draggable item "+t.id+" was dropped."},onDragCancel(e){let{active:t}=e;return"Dragging was cancelled. Draggable item "+t.id+" was dropped."}};function A7(e){let{announcements:t=I7,container:n,hiddenTextDescribedById:o,screenReaderInstructions:r=E7}=e;const{announce:s,announcement:a}=S7(),l=Qr("DndLiveRegion"),[d,c]=u.useState(!1);if(u.useEffect(()=>{c(!0)},[]),C7(u.useMemo(()=>({onDragStart(f){let{active:y}=f;s(t.onDragStart({active:y}))},onDragMove(f){let{active:y,over:g}=f;t.onDragMove&&s(t.onDragMove({active:y,over:g}))},onDragOver(f){let{active:y,over:g}=f;s(t.onDragOver({active:y,over:g}))},onDragEnd(f){let{active:y,over:g}=f;s(t.onDragEnd({active:y,over:g}))},onDragCancel(f){let{active:y,over:g}=f;s(t.onDragCancel({active:y,over:g}))}}),[s,t])),!d)return null;const p=u.createElement(u.Fragment,null,u.createElement(w7,{id:o,value:r.draggable}),u.createElement(k7,{id:l,announcement:a}));return n?Sn.createPortal(p,n):p}var it;(function(e){e.DragStart="dragStart",e.DragMove="dragMove",e.DragEnd="dragEnd",e.DragCancel="dragCancel",e.DragOver="dragOver",e.RegisterDroppable="registerDroppable",e.SetDroppableDisabled="setDroppableDisabled",e.UnregisterDroppable="unregisterDroppable"})(it||(it={}));function ti(){}function T7(e,t){return u.useMemo(()=>({sensor:e,options:t??{}}),[e,t])}function D7(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return u.useMemo(()=>[...t].filter(o=>o!=null),[...t])}const Ht=Object.freeze({x:0,y:0});function N7(e,t){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function z7(e,t){const n=ei(e);if(!n)return"0 0";const o={x:(n.x-t.left)/t.width*100,y:(n.y-t.top)/t.height*100};return o.x+"% "+o.y+"%"}function M7(e,t){let{data:{value:n}}=e,{data:{value:o}}=t;return n-o}function L7(e,t){let{data:{value:n}}=e,{data:{value:o}}=t;return o-n}function P7(e){let{left:t,top:n,height:o,width:r}=e;return[{x:t,y:n},{x:t+r,y:n},{x:t,y:n+o},{x:t+r,y:n+o}]}function O7(e,t){if(!e||e.length===0)return null;const[n]=e;return n[t]}function B7(e,t){const n=Math.max(t.top,e.top),o=Math.max(t.left,e.left),r=Math.min(t.left+t.width,e.left+e.width),s=Math.min(t.top+t.height,e.top+e.height),a=r-o,l=s-n;if(o<r&&n<s){const d=t.width*t.height,c=e.width*e.height,p=a*l,f=p/(d+c-p);return Number(f.toFixed(4))}return 0}const W7=e=>{let{collisionRect:t,droppableRects:n,droppableContainers:o}=e;const r=[];for(const s of o){const{id:a}=s,l=n.get(a);if(l){const d=B7(l,t);d>0&&r.push({id:a,data:{droppableContainer:s,value:d}})}}return r.sort(L7)};function j7(e,t){const{top:n,left:o,bottom:r,right:s}=t;return n<=e.y&&e.y<=r&&o<=e.x&&e.x<=s}const H7=e=>{let{droppableContainers:t,droppableRects:n,pointerCoordinates:o}=e;if(!o)return[];const r=[];for(const s of t){const{id:a}=s,l=n.get(a);if(l&&j7(o,l)){const c=P7(l).reduce((f,y)=>f+N7(o,y),0),p=Number((c/4).toFixed(4));r.push({id:a,data:{droppableContainer:s,value:p}})}}return r.sort(M7)};function F7(e,t,n){return{...e,scaleX:t&&n?t.width/n.width:1,scaleY:t&&n?t.height/n.height:1}}function Op(e,t){return e&&t?{x:e.left-t.left,y:e.top-t.top}:Ht}function K7(e){return function(n){for(var o=arguments.length,r=new Array(o>1?o-1:0),s=1;s<o;s++)r[s-1]=arguments[s];return r.reduce((a,l)=>({...a,top:a.top+e*l.y,bottom:a.bottom+e*l.y,left:a.left+e*l.x,right:a.right+e*l.x}),{...n})}}const V7=K7(1);function Bp(e){if(e.startsWith("matrix3d(")){const t=e.slice(9,-1).split(/, /);return{x:+t[12],y:+t[13],scaleX:+t[0],scaleY:+t[5]}}else if(e.startsWith("matrix(")){const t=e.slice(7,-1).split(/, /);return{x:+t[4],y:+t[5],scaleX:+t[0],scaleY:+t[3]}}return null}function U7(e,t,n){const o=Bp(t);if(!o)return e;const{scaleX:r,scaleY:s,x:a,y:l}=o,d=e.left-a-(1-r)*parseFloat(n),c=e.top-l-(1-s)*parseFloat(n.slice(n.indexOf(" ")+1)),p=r?e.width/r:e.width,f=s?e.height/s:e.height;return{width:p,height:f,top:c,right:d+p,bottom:c+f,left:d}}const q7={ignoreTransform:!1};function Bo(e,t){t===void 0&&(t=q7);let n=e.getBoundingClientRect();if(t.ignoreTransform){const{transform:c,transformOrigin:p}=_t(e).getComputedStyle(e);c&&(n=U7(n,c,p))}const{top:o,left:r,width:s,height:a,bottom:l,right:d}=n;return{top:o,left:r,width:s,height:a,bottom:l,right:d}}function Wp(e){return Bo(e,{ignoreTransform:!0})}function G7(e){const t=e.innerWidth,n=e.innerHeight;return{top:0,left:0,right:t,bottom:n,width:t,height:n}}function Y7(e,t){return t===void 0&&(t=_t(e).getComputedStyle(e)),t.position==="fixed"}function X7(e,t){t===void 0&&(t=_t(e).getComputedStyle(e));const n=/(auto|scroll|overlay)/;return["overflow","overflowX","overflowY"].some(r=>{const s=t[r];return typeof s=="string"?n.test(s):!1})}function aa(e,t){const n=[]; Line truncated
`:"",e.message]})]}),i.jsxs("div",{style:{display:"flex",justifyContent:"center",gap:8,flexWrap:"wrap"},children:[e.kind==="unauthorized"&&i.jsx("button",{type:"button","data-testid":"g7le-access-error-action-signin",onClick:a,style:Ha,children:t("layout_editor.access_error.action.sign_in")}),e.kind==="forbidden"&&i.jsx("button",{type:"button","data-testid":"g7le-access-error-action-home",onClick:r,style:Ha,children:t("layout_editor.access_error.action.go_home")}),(e.kind==="not_found"||e.kind==="server_error"||e.kind==="network"||e.kind==="unknown")&&i.jsx("button",{type:"button","data-testid":"g7le-access-error-action-retry",onClick:s,style:Ha,children:t("layout_editor.access_error.action.retry")}),e.kind!=="unauthorized"&&i.jsx("button",{type:"button","data-testid":"g7le-access-error-action-home-secondary",onClick:r,style:h4,children:t("layout_editor.access_error.action.go_admin_home")})]})]})]})}const Ha={padding:"8px 16px",background:"#2563eb",color:"#fff",border:"1px solid #1d4ed8",borderRadius:6,fontSize:13,fontWeight:600,cursor:"pointer"},h4={padding:"8px 16px",background:"#fff",color:"#475569",border:"1px solid #cbd5e1",borderRadius:6,fontSize:13,fontWeight:500,cursor:"pointer"};function y4(e){const t=window;if(typeof t>"u")return{getSnapshot:()=>({globalState:{},localState:{}}),restore:()=>{}};const n=t.G7Core||{},o={templateApp:t.__templateApp,g7CoreState:n.state,g7CoreDispatch:n.dispatch,g7CoreData:n.data,g7CoreModal:n.modal,g7CoreToast:n.toast};let r={...e.initialGlobalState??{}};r._local||(r._local={});const s=[],a=()=>{const c={globalState:{...r},localState:{...r._local??{}}};for(const p of s)try{p(r)}catch{}e.onChange?.(c)},l={},d={getGlobalState:()=>r,setGlobalState:(c,p)=>{typeof c=="function"?r=c(r):r={...r,...c},a()},onGlobalStateChange:c=>(s.push(c),()=>{const p=s.indexOf(c);p>=0&&s.splice(p,1)}),get globalState(){return r},getActionDispatcher:()=>e.actionDispatcher,getDataSource:c=>l[c]??null,setDataSource:(c,p)=>{l[c]=p},refetchDataSource:async c=>null,updateDataSourceItem:(c,p,f)=>l[c]??null,getLocale:()=>e.locale,changeLocale:c=>{},getRouter:()=>({navigate:()=>{},replace:()=>{},push:()=>{}}),updateQueryParams:()=>{}};return t.__templateApp=d,n&&typeof n.dispatch=="function"&&(n.dispatch=(c,p)=>{try{return e.actionDispatcher.executeAction(c,p??{})}catch{return}}),n&&typeof n.modal=="object"&&n.modal!==null&&(n.modal={...n.modal,open:()=>{},close:()=>{},closeAll:()=>{}}),n&&typeof n.toast=="object"&&n.toast!==null&&(n.toast={...n.toast,push:()=>{},dismiss:()=>{}}),{getSnapshot:()=>({globalState:{...r},localState:{...r._local??{}}}),restore:()=>{t.__templateApp===d&&(t.__templateApp=o.templateApp),t.G7Core&&(o.g7CoreState!==void 0&&(t.G7Core.state=o.g7CoreState),o.g7CoreDispatch!==void 0&&(t.G7Core.dispatch=o.g7CoreDispatch),o.g7CoreData!==void 0&&(t.G7Core.data=o.g7CoreData),o.g7CoreModal!==void 0&&(t.G7Core.modal=o.g7CoreModal),o.g7CoreToast!==void 0&&(t.G7Core.toast=o.g7CoreToast)),s.length=0}}}const b4=new Set(["id","userId","postId","orderId","productId","categoryId","commentId","noticeId","inquiryId","addressId","wishlistId","notificationId","roleId","menuId"]);function m4(e){if(!e)return{};const t={},n=/:([a-zA-Z_][a-zA-Z0-9_]*)/g;let o;for(;(o=n.exec(e))!==null;){const r=o[1];t[r]=v4(r)}return t}function v4(e){return b4.has(e)||/Id$|_id$/.test(e)?"1":"sample"}const _4=ar("LayoutEditor");function Go(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function hi(e){if(Array.isArray(e))return e.map(t=>hi(t));if(Go(e)){const t={};for(const[n,o]of Object.entries(e))t[n]=hi(o);return t}return e}function pg(e,t="",n=new Set){for(const[o,r]of Object.entries(e)){const s=t?`${t}.${o}`:o;Go(r)?pg(r,s,n):n.add(s)}return n}function fg(e,t,n,o,r,s=""){for(const[a,l]of Object.entries(t)){const d=s?`${s}.${a}`:a;if(n.has(d)){r(`[LayoutEditor] sampleGlobal key conflict: extension '${o}' override of core key '${d}' ignored`);continue}const c=e[a];Go(l)&&Go(c)?fg(c,l,n,o,r,d):e[a]=hi(l)}}function Fa(e){const t=e.warn??(r=>_4.warn(r)),n=hi(e.coreSeed??{});e.isGuestOnly&&"currentUser"in n&&delete n.currentUser;const o=pg(n);for(const r of e.sources)Go(r.sampleGlobal)&&fg(n,r.sampleGlobal,o,r.id,t);return e.isGuestOnly&&"currentUser"in n&&delete n.currentUser,n}function x4(e){const t={};if(!e||typeof e!="object"||Array.isArray(e))return t;for(const[n,o]of Object.entries(e))n.startsWith("$")&&(t[n]=o);return t}function w4(e){const t={};if(!e||typeof e!="object"||Array.isArray(e))return t;for(const[n,o]of Object.entries(e))n.startsWith("$")||(t[n]=o);return t}function k4(e){if(typeof e!="string")return null;const t=/^\s*\{\{\s*([\s\S]*?)\s*\}\}\s*$/.exec(e);if(!t)return null;let n=t[1];const o=n.indexOf("??");return o>=0&&(n=n.slice(0,o)),n=n.replace(/\?\./g,".").replace(/\s+/g,""),n===""||!/^[A-Za-z_$][A-Za-z0-9_$]*(\.[A-Za-z_$][A-Za-z0-9_$]*)*$/.test(n)?null:n.split(".")}function S4(e,t){const n=k4(t);if(!n||n.length===0)return e;let o=e;for(let a=0;a<n.length;a++){if(o==null||typeof o!="obj Line truncated
//# sourceMappingURL=layout-editor.min.js.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"layout-editor.min.js","sources":["../../../resources/js/core/template-engine/layout-editor/__runtime-shims/runtime.ts","../../../resources/js/core/template-engine/layout-editor/__runtime-shims/TranslationContext.ts","../../../resources/js/core/template-engine/layout-editor/devtools/editorTrackers.ts","../../../resources/js/core/template-engine/layout-editor/LayoutEditorContext.tsx","../../../resources/js/core/template-engine/layout-editor/LayoutDocumentContext.tsx","../../../resources/js/core/template-engine/layout-editor/EditorModalContext.tsx","../../../resources/js/core/template-engine/layout-editor/components/EditorToolbar.tsx","../../../resources/js/core/template-engine/layout-editor/utils/authToken.ts","../../../resources/js/core/template-engine/layout-editor/utils/layoutAttachments.ts","../../../resources/js/core/template-engine/layout-editor/components/property-controls/LayoutAttachmentManager.tsx","../../../resources/js/core/template-engine/layout-editor/utils/customTranslations.ts","../../../resources/js/core/template-engine/layout-editor/__runtime-shims/TranslationEngine.ts","../../../resources/js/core/template-engine/layout-editor/__runtime-shims/Logger.ts","../../../resources/js/core/template-engine/layout-editor/spec/editorSpecLoader.ts","../../../resources/js/core/template-engine/layout-editor/spec/bindingCandidates.ts","../../../resources/js/core/template-engine/layout-editor/spec/inlineBindingUtils.ts","../../../resources/js/core/template-engine/layout-editor/utils/layoutTreeUtils.ts","../../../resources/js/core/template-engine/layout-editor/hooks/useInlineEdit.ts","../../../resources/js/core/template-engine/layout-editor/hooks/pendingCustomTranslations.ts","../../../resources/js/core/template-engine/layout-editor/components/LocaleSwitcher.tsx","../../../resources/js/core/template-engine/layout-editor/components/property-controls/PlaceholderChipInput.tsx","../../../resources/js/core/template-engine/layout-editor/components/property-controls/CustomTranslationManager.tsx","../../../resources/js/core/template-engine/layout-editor/hooks/usePageSettings.ts","../../../resources/js/core/template-engine/layout-editor/sample-data/sampleDataProvider.ts","../../../resources/js/core/template-engine/layout-editor/__runtime-shims/DataBindingEngine.ts","../../../resources/js/core/template-engine/layout-editor/spec/computedRecipeEngine.ts","../../../resources/js/core/template-engine/layout-editor/hooks/useBindingCandidates.ts","../../../resources/js/core/template-engine/layout-editor/hooks/useSeoBindingCandidates.ts","../../../resources/js/core/template-engine/layout-editor/spec/candidatePools.ts","../../../resources/js/core/template-engine/layout-editor/spec/actionRecipeEngine.ts","../../../resources/js/core/template-engine/layout-editor/hooks/useCustomTranslation.ts","../../../resources/js/core/template-engine/layout-editor/components/property-controls/inlineBindingApi.ts","../../../resources/js/core/template-engine/layout-editor/components/property-controls/TranslationField.tsx","../../../resources/js/core/template-engine/layout-editor/components/shared/FloatingDropdown.tsx","../../../resources/js/core/template-engine/layout-editor/components/property-controls/InlineBindingScalarPicker.tsx","../../../resources/js/core/template-engine/layout-editor/spec/expressionValueTree.ts","../../../resources/js/core/template-engine/layout-editor/components/DropLine.tsx","../../../resources/js/core/template-engine/layout-editor/hooks/useListDragReorder.ts","../../../resources/js/core/template-engine/layout-editor/components/page-settings/SegmentedValueEditor.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/ConditionalValueEditor.tsx","../../../resources/js/core/template-engine/layout-editor/components/property-controls/I18nTextField.tsx","../../../resources/js/core/template-engine/layout-editor/components/property-controls/TagInputControl.tsx","../../../resources/js/core/template-engine/layout-editor/spec/widgetRegistry.ts","../../../resources/js/core/template-engine/layout-editor/components/page-settings/MetaForm.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/FormPrimitives.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/BindingChipTextInput.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/DataChipValueInput.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/KeyValueChipEditor.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/SeoOgForm.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/SeoStructuredDataEditor.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/SeoVarsEditor.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/SeoBotPreviewPanel.tsx","../../..Line truncated
{"version":3,"file":"layout-editor.min.js","sources":["../../../resources/js/core/template-engine/layout-editor/__runtime-shims/runtime.ts","../../../resources/js/core/template-engine/layout-editor/__runtime-shims/TranslationContext.ts","../../../resources/js/core/template-engine/layout-editor/devtools/editorTrackers.ts","../../../resources/js/core/template-engine/layout-editor/LayoutEditorContext.tsx","../../../resources/js/core/template-engine/layout-editor/LayoutDocumentContext.tsx","../../../resources/js/core/template-engine/layout-editor/EditorModalContext.tsx","../../../resources/js/core/template-engine/layout-editor/components/EditorToolbar.tsx","../../../resources/js/core/template-engine/layout-editor/utils/authToken.ts","../../../resources/js/core/template-engine/layout-editor/utils/layoutAttachments.ts","../../../resources/js/core/template-engine/layout-editor/components/property-controls/LayoutAttachmentManager.tsx","../../../resources/js/core/template-engine/layout-editor/utils/customTranslations.ts","../../../resources/js/core/template-engine/layout-editor/__runtime-shims/TranslationEngine.ts","../../../resources/js/core/template-engine/layout-editor/__runtime-shims/Logger.ts","../../../resources/js/core/template-engine/layout-editor/spec/editorSpecLoader.ts","../../../resources/js/core/template-engine/layout-editor/spec/bindingCandidates.ts","../../../resources/js/core/template-engine/layout-editor/spec/inlineBindingUtils.ts","../../../resources/js/core/template-engine/layout-editor/utils/layoutTreeUtils.ts","../../../resources/js/core/template-engine/layout-editor/hooks/useInlineEdit.ts","../../../resources/js/core/template-engine/layout-editor/hooks/pendingCustomTranslations.ts","../../../resources/js/core/template-engine/layout-editor/components/LocaleSwitcher.tsx","../../../resources/js/core/template-engine/layout-editor/components/property-controls/PlaceholderChipInput.tsx","../../../resources/js/core/template-engine/layout-editor/components/property-controls/CustomTranslationManager.tsx","../../../resources/js/core/template-engine/layout-editor/hooks/usePageSettings.ts","../../../resources/js/core/template-engine/layout-editor/sample-data/sampleDataProvider.ts","../../../resources/js/core/template-engine/layout-editor/__runtime-shims/DataBindingEngine.ts","../../../resources/js/core/template-engine/layout-editor/spec/computedRecipeEngine.ts","../../../resources/js/core/template-engine/layout-editor/hooks/useBindingCandidates.ts","../../../resources/js/core/template-engine/layout-editor/hooks/useSeoBindingCandidates.ts","../../../resources/js/core/template-engine/layout-editor/spec/candidatePools.ts","../../../resources/js/core/template-engine/layout-editor/spec/actionRecipeEngine.ts","../../../resources/js/core/template-engine/layout-editor/hooks/useCustomTranslation.ts","../../../resources/js/core/template-engine/layout-editor/components/property-controls/inlineBindingApi.ts","../../../resources/js/core/template-engine/layout-editor/components/property-controls/TranslationField.tsx","../../../resources/js/core/template-engine/layout-editor/components/shared/FloatingDropdown.tsx","../../../resources/js/core/template-engine/layout-editor/components/property-controls/InlineBindingScalarPicker.tsx","../../../resources/js/core/template-engine/layout-editor/spec/expressionValueTree.ts","../../../resources/js/core/template-engine/layout-editor/components/DropLine.tsx","../../../resources/js/core/template-engine/layout-editor/hooks/useListDragReorder.ts","../../../resources/js/core/template-engine/layout-editor/components/page-settings/SegmentedValueEditor.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/ConditionalValueEditor.tsx","../../../resources/js/core/template-engine/layout-editor/components/property-controls/I18nTextField.tsx","../../../resources/js/core/template-engine/layout-editor/components/property-controls/TagInputControl.tsx","../../../resources/js/core/template-engine/layout-editor/spec/widgetRegistry.ts","../../../resources/js/core/template-engine/layout-editor/components/page-settings/MetaForm.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/FormPrimitives.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/BindingChipTextInput.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/DataChipValueInput.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/KeyValueChipEditor.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/SeoOgForm.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/SeoStructuredDataEditor.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/SeoVarsEditor.tsx","../../../resources/js/core/template-engine/layout-editor/components/page-settings/SeoBotPreviewPanel.tsx","../../..Line truncated
+32 -75
View File
@@ -1,57 +1,20 @@
var tx=Object.defineProperty;var nx=(Vt,Ka,Wa)=>Ka in Vt?tx(Vt,Ka,{enumerable:!0,configurable:!0,writable:!0,value:Wa}):Vt[Ka]=Wa;var $=(Vt,Ka,Wa)=>nx(Vt,typeof Ka!="symbol"?Ka+"":Ka,Wa);(function(Vt){"use strict";function Ka(l,e){for(var a=0;a<e.length;a++){const r=e[a];if(typeof r!="string"&&!Array.isArray(r)){for(const i in r)if(i!=="default"&&!(i in l)){const o=Object.getOwnPropertyDescriptor(r,i);o&&Object.defineProperty(l,i,o.get?o:{enumerable:!0,get:()=>r[i]})}}}return Object.freeze(Object.defineProperty(l,Symbol.toStringTag,{value:"Module"}))}function Wa(l){return l&&l.__esModule&&Object.prototype.hasOwnProperty.call(l,"default")?l.default:l}var zu={exports:{}},Fe={};/**
* @license React
* react.production.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var dg;function iS(){if(dg)return Fe;dg=1;var l=Symbol.for("react.transitional.element"),e=Symbol.for("react.portal"),a=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),o=Symbol.for("react.consumer"),u=Symbol.for("react.context"),d=Symbol.for("react.forward_ref"),f=Symbol.for("react.suspense"),g=Symbol.for("react.memo"),m=Symbol.for("react.lazy"),b=Symbol.for("react.activity"),v=Symbol.iterator;function E(x){return x===null||typeof x!="object"?null:(x=v&&x[v]||x["@@iterator"],typeof x=="function"?x:null)}var S={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},A=Object.assign,T={};function D(x,F,ue){this.props=x,this.context=F,this.refs=T,this.updater=ue||S}D.prototype.isReactComponent={},D.prototype.setState=function(x,F){if(typeof x!="object"&&typeof x!="function"&&x!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,x,F,"setState")},D.prototype.forceUpdate=function(x){this.updater.enqueueForceUpdate(this,x,"forceUpdate")};function M(){}M.prototype=D.prototype;function O(x,F,ue){this.props=x,this.context=F,this.refs=T,this.updater=ue||S}var L=O.prototype=new M;L.constructor=O,A(L,D.prototype),L.isPureReactComponent=!0;var P=Array.isArray;function U(){}var B={H:null,A:null,T:null,S:null},Y=Object.prototype.hasOwnProperty;function ge(x,F,ue){var fe=ue.ref;return{$$typeof:l,type:x,key:F,ref:fe!==void 0?fe:null,props:ue}}function Ae(x,F){return ge(x.type,F,x.props)}function Oe(x){return typeof x=="object"&&x!==null&&x.$$typeof===l}function Ne(x){var F={"=":"=0",":":"=2"};return"$"+x.replace(/[=:]/g,function(ue){return F[ue]})}var He=/\/+/g;function Ze(x,F){return typeof x=="object"&&x!==null&&x.key!=null?Ne(""+x.key):F.toString(36)}function pt(x){switch(x.status){case"fulfilled":return x.value;case"rejected":throw x.reason;default:switch(typeof x.status=="string"?x.then(U,U):(x.status="pending",x.then(function(F){x.status==="pending"&&(x.status="fulfilled",x.value=F)},function(F){x.status==="pending"&&(x.status="rejected",x.reason=F)})),x.status){case"fulfilled":return x.value;case"rejected":throw x.reason}}throw x}function Q(x,F,ue,fe,te){var ye=typeof x;(ye==="undefined"||ye==="boolean")&&(x=null);var je=!1;if(x===null)je=!0;else switch(ye){case"bigint":case"string":case"number":je=!0;break;case"object":switch(x.$$typeof){case l:case e:je=!0;break;case m:return je=x._init,Q(je(x._payload),F,ue,fe,te)}}if(je)return te=te(x),je=fe===""?"."+Ze(x,0):fe,P(te)?(ue="",je!=null&&(ue=je.replace(He,"$&/")+"/"),Q(te,F,ue,"",function(Ie){return Ie})):te!=null&&(Oe(te)&&(te=Ae(te,ue+(te.key==null||x&&x.key===te.key?"":(""+te.key).replace(He,"$&/")+"/")+je)),F.push(te)),1;je=0;var Me=fe===""?".":fe+":";if(P(x))for(var Pe=0;Pe<x.length;Pe++)fe=x[Pe],ye=Me+Ze(fe,Pe),je+=Q(fe,F,ue,ye,te);else if(Pe=E(x),typeof Pe=="function")for(x=Pe.call(x),Pe=0;!(fe=x.next()).done;)fe=fe.value,ye=Me+Ze(fe,Pe++),je+=Q(fe,F,ue,ye,te);else if(ye==="object"){if(typeof x.then=="function")return Q(pt(x),F,ue,fe,te);throw F=String(x),Error("Objects are not valid as a React child (found: "+(F==="[object Object]"?"object with keys {"+Object.keys(x).join(", ")+"}":F)+"). If you meant to render a collection of children, use an array instead.")}return je}function de(x,F,ue){if(x==null)return x;var fe=[],te=0;return Q(x,fe,"","",function(ye){return F.call(ue,ye,te++)}),fe}function me(x){if(x._status===-1){var F=x._result;F=F(),F.then(function(ue){(x._status===0||x._status===-1)&&(x._status=1,x._result=ue)},function(ue){(x._status===0||x._status===-1)&&(x._status=2,x._result=ue)}),x._status===-1&&(x._status=0,x._result=F)}if(x._status===1)return x._result.default;throw x._result}var ne=typeof reportError=="function"?reportError:function(x){if(typeof window=="object"&&typeof window.ErrorEvent=="function"){var F=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof x=="object"&&x!==null&&typeof x.message=="string"?String(x.message):String(x),error:x});if(!window.dispatchEvent(F))return}else if(typeof process=="object"&&typeof process.emit=="function"){process.emit("uncaughtException",x);return}console.error(x)},pe={map:de,forEach:function(x,F,ue){de(x,function(){F.apply(this,arguments)},ue)},count:function(x){var F=0;return de(x,function(){F++}),F},toArray:function(x){return de(x,function(F){return F})||[]},only:function(x){if(!Oe(x))throw Error("React.Children.only expected to receive a single React element child.");return x}};return Fe.Activity=b,Fe.Children=pe,Fe.Component=D,Fe.Fragment=a,Fe.Profiler=i,Fe.PureComponent=O,Fe.StrictMode=r,Fe.Suspense=f,Fe.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=B,Fe.__COMPILER_RUNTIME={__proto__:null,c:function(x){return B.H.useMemoCache(x)}},Fe.cache=function(x){return function(){return x.apply(null,arguments)}},Fe.cacheSignal=function(){return null},Line truncated
* @license React
* scheduler.production.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var hg;function sS(){return hg||(hg=1,(function(l){function e(Q,de){var me=Q.length;Q.push(de);e:for(;0<me;){var ne=me-1>>>1,pe=Q[ne];if(0<i(pe,de))Q[ne]=de,Q[me]=pe,me=ne;else break e}}function a(Q){return Q.length===0?null:Q[0]}function r(Q){if(Q.length===0)return null;var de=Q[0],me=Q.pop();if(me!==de){Q[0]=me;e:for(var ne=0,pe=Q.length,x=pe>>>1;ne<x;){var F=2*(ne+1)-1,ue=Q[F],fe=F+1,te=Q[fe];if(0>i(ue,me))fe<pe&&0>i(te,ue)?(Q[ne]=te,Q[fe]=me,ne=fe):(Q[ne]=ue,Q[F]=me,ne=F);else if(fe<pe&&0>i(te,me))Q[ne]=te,Q[fe]=me,ne=fe;else break e}}return de}function i(Q,de){var me=Q.sortIndex-de.sortIndex;return me!==0?me:Q.id-de.id}if(l.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var o=performance;l.unstable_now=function(){return o.now()}}else{var u=Date,d=u.now();l.unstable_now=function(){return u.now()-d}}var f=[],g=[],m=1,b=null,v=3,E=!1,S=!1,A=!1,T=!1,D=typeof setTimeout=="function"?setTimeout:null,M=typeof clearTimeout=="function"?clearTimeout:null,O=typeof setImmediate<"u"?setImmediate:null;function L(Q){for(var de=a(g);de!==null;){if(de.callback===null)r(g);else if(de.startTime<=Q)r(g),de.sortIndex=de.expirationTime,e(f,de);else break;de=a(g)}}function P(Q){if(A=!1,L(Q),!S)if(a(f)!==null)S=!0,U||(U=!0,Ne());else{var de=a(g);de!==null&&pt(P,de.startTime-Q)}}var U=!1,B=-1,Y=5,ge=-1;function Ae(){return T?!0:!(l.unstable_now()-ge<Y)}function Oe(){if(T=!1,U){var Q=l.unstable_now();ge=Q;var de=!0;try{e:{S=!1,A&&(A=!1,M(B),B=-1),E=!0;var me=v;try{t:{for(L(Q),b=a(f);b!==null&&!(b.expirationTime>Q&&Ae());){var ne=b.callback;if(typeof ne=="function"){b.callback=null,v=b.priorityLevel;var pe=ne(b.expirationTime<=Q);if(Q=l.unstable_now(),typeof pe=="function"){b.callback=pe,L(Q),de=!0;break t}b===a(f)&&r(f),L(Q)}else r(f);b=a(f)}if(b!==null)de=!0;else{var x=a(g);x!==null&&pt(P,x.startTime-Q),de=!1}}break e}finally{b=null,v=me,E=!1}de=void 0}}finally{de?Ne():U=!1}}}var Ne;if(typeof O=="function")Ne=function(){O(Oe)};else if(typeof MessageChannel<"u"){var He=new MessageChannel,Ze=He.port2;He.port1.onmessage=Oe,Ne=function(){Ze.postMessage(null)}}else Ne=function(){D(Oe,0)};function pt(Q,de){B=D(function(){Q(l.unstable_now())},de)}l.unstable_IdlePriority=5,l.unstable_ImmediatePriority=1,l.unstable_LowPriority=4,l.unstable_NormalPriority=3,l.unstable_Profiling=null,l.unstable_UserBlockingPriority=2,l.unstable_cancelCallback=function(Q){Q.callback=null},l.unstable_forceFrameRate=function(Q){0>Q||125<Q?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):Y=0<Q?Math.floor(1e3/Q):5},l.unstable_getCurrentPriorityLevel=function(){return v},l.unstable_next=function(Q){switch(v){case 1:case 2:case 3:var de=3;break;default:de=v}var me=v;v=de;try{return Q()}finally{v=me}},l.unstable_requestPaint=function(){T=!0},l.unstable_runWithPriority=function(Q,de){switch(Q){case 1:case 2:case 3:case 4:case 5:break;default:Q=3}var me=v;v=Q;try{return de()}finally{v=me}},l.unstable_scheduleCallback=function(Q,de,me){var ne=l.unstable_now();switch(typeof me=="object"&&me!==null?(me=me.delay,me=typeof me=="number"&&0<me?ne+me:ne):me=ne,Q){case 1:var pe=-1;break;case 2:pe=250;break;case 5:pe=1073741823;break;case 4:pe=1e4;break;default:pe=5e3}return pe=me+pe,Q={id:m++,callback:de,priorityLevel:Q,startTime:me,expirationTime:pe,sortIndex:-1},me>ne?(Q.sortIndex=me,e(g,Q),a(f)===null&&Q===a(g)&&(A?(M(B),B=-1):A=!0,pt(P,me-ne))):(Q.sortIndex=pe,e(f,Q),S||E||(S=!0,U||(U=!0,Ne()))),Q},l.unstable_shouldYield=Ae,l.unstable_wrapCallback=function(Q){var de=v;return function(){var me=v;v=de;try{return Q.apply(this,arguments)}finally{v=me}}}})(Bu)),Bu}var gg;function oS(){return gg||(gg=1,Uu.exports=sS()),Uu.exports}var qu={exports:{}},pn={};/**
* @license React
* react-dom.production.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var pg;function lS(){if(pg)return pn;pg=1;var l=Iu();function e(f){var g="https://react.dev/errors/"+f;if(1<arguments.length){g+="?args[]="+encodeURIComponent(arguments[1]);for(var m=2;m<arguments.length;m++)g+="&args[]="+encodeURIComponent(arguments[m])}return"Minified React error #"+f+"; visit "+g+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}function a(){}var r={d:{f:a,r:function(){throw Error(e(522))},D:a,C:a,L:a,m:a,X:a,S:a,M:a},p:0,findDOMNode:null},i=Symbol.for("react.portal");function o(f,g,m){var b=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:i,key:b==null?null:""+b,children:f,containerInfo:g,implementation:m}}var u=l.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function d(f,g){if(f==="font")return"";if(typeof g=="string")return g==="use-credentials"?g:""}return pn.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=r,pn.createPortal=function(f,g){var m=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!g||g.nodeType!==1&&g.nodeType!==9&&g.nodeType!==11)throw Error(e(299));return o(f,g,null,m)},pn.flushSync=function(f){var g=u.T,m=r.p;try{if(u.T=null,r.p=2,f)return f()}finally{u.T=g,r.p=m,r.d.f()}},pn.preconnect=function(f,g){typeof f=="string"&&(g?(g=g.crossOrigin,g=typeof g=="string"?g==="use-credentials"?g:"":void 0):g=null,r.d.C(f,g))},pn.prefetchDNS=function(f){typeof f=="string"&&r.d.D(f)},pn.preinit=function(f,g){if(typeof f=="string"&&g&&typeof g.as=="string"){var m=g.as,b=d(m,g.crossOrigin),v=typeof g.integrity=="string"?g.integrity:void 0,E=typeof g.fetchPriority=="string"?g.fetchPriority:void 0;m==="style"?r.d.S(f,typeof g.precedence=="string"?g.precedence:void 0,{crossOrigin:b,integrity:v,fetchPriority:E}):m==="script"&&r.d.X(f,{crossOrigin:b,integrity:v,fetchPriority:E,nonce:typeof g.nonce=="string"?g.nonce:void 0})}},pn.preinitModule=function(f,g){if(typeof f=="string")if(typeof g=="object"&&g!==null){if(g.as==null||g.as==="script"){var m=d(g.as,g.crossOrigin);r.d.M(f,{crossOrigin:m,integrity:typeof g.integrity=="string"?g.integrity:void 0,nonce:typeof g.nonce=="string"?g.nonce:void 0})}}else g==null&&r.d.M(f)},pn.preload=function(f,g){if(typeof f=="string"&&typeof g=="object"&&g!==null&&typeof g.as=="string"){var m=g.as,b=d(m,g.crossOrigin);r.d.L(f,m,{crossOrigin:b,integrity:typeof g.integrity=="string"?g.integrity:void 0,nonce:typeof g.nonce=="string"?g.nonce:void 0,type:typeof g.type=="string"?g.type:void 0,fetchPriority:typeof g.fetchPriority=="string"?g.fetchPriority:void 0,referrerPolicy:typeof g.referrerPolicy=="string"?g.referrerPolicy:void 0,imageSrcSet:typeof g.imageSrcSet=="string"?g.imageSrcSet:void 0,imageSizes:typeof g.imageSizes=="string"?g.imageSizes:void 0,media:typeof g.media=="string"?g.media:void 0})}},pn.preloadModule=function(f,g){if(typeof f=="string")if(g){var m=d(g.as,g.crossOrigin);r.d.m(f,{as:typeof g.as=="string"&&g.as!=="script"?g.as:void 0,crossOrigin:m,integrity:typeof g.integrity=="string"?g.integrity:void 0})}else r.d.m(f)},pn.requestFormReset=function(f){r.d.r(f)},pn.unstable_batchedUpdates=function(f,g){return f(g)},pn.useFormState=function(f,g,m){return u.H.useFormState(f,g,m)},pn.useFormStatus=function(){return u.H.useHostTransitionStatus()},pn.version="19.2.0",pn}var mg;function yg(){if(mg)return qu.exports;mg=1;function l(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(l)}catch(e){console.error(e)}}return l(),qu.exports=lS(),qu.exports}/**
* @license React
* react-dom-client.production.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var bg;function cS(){if(bg)return qs;bg=1;var l=oS(),e=Iu(),a=yg();function r(t){var n="https://react.dev/errors/"+t;if(1<arguments.length){n+="?args[]="+encodeURIComponent(arguments[1]);for(var s=2;s<arguments.length;s++)n+="&args[]="+encodeURIComponent(arguments[s])}return"Minified React error #"+t+"; visit "+n+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}function i(t){return!(!t||t.nodeType!==1&&t.nodeType!==9&&t.nodeType!==11)}function o(t){var n=t,s=t;if(t.alternate)for(;n.return;)n=n.return;else{t=n;do n=t,(n.flags&4098)!==0&&(s=n.return),t=n.return;while(t)}return n.tag===3?s:null}function u(t){if(t.tag===13){var n=t.memoizedState;if(n===null&&(t=t.alternate,t!==null&&(n=t.memoizedState)),n!==null)return n.dehydrated}return null}function d(t){if(t.tag===31){var n=t.memoizedState;if(n===null&&(t=t.alternate,t!==null&&(n=t.memoizedState)),n!==null)return n.dehydrated}return null}function f(t){if(o(t)!==t)throw Error(r(188))}function g(t){var n=t.alternate;if(!n){if(n=o(t),n===null)throw Error(r(188));return n!==t?null:t}for(var s=t,c=n;;){var h=s.return;if(h===null)break;var p=h.alternate;if(p===null){if(c=h.return,c!==null){s=c;continue}break}if(h.child===p.child){for(p=h.child;p;){if(p===s)return f(h),t;if(p===c)return f(h),n;p=p.sibling}throw Error(r(188))}if(s.return!==c.return)s=h,c=p;else{for(var w=!1,k=h.child;k;){if(k===s){w=!0,s=h,c=p;break}if(k===c){w=!0,c=h,s=p;break}k=k.sibling}if(!w){for(k=p.child;k;){if(k===s){w=!0,s=p,c=h;break}if(k===c){w=!0,c=p,s=h;break}k=k.sibling}if(!w)throw Error(r(189))}}if(s.alternate!==c)throw Error(r(190))}if(s.tag!==3)throw Error(r(188));return s.stateNode.current===s?t:n}function m(t){var n=t.tag;if(n===5||n===26||n===27||n===6)return t;for(t=t.child;t!==null;){if(n=m(t),n!==null)return n;t=t.sibling}return null}var b=Object.assign,v=Symbol.for("react.element"),E=Symbol.for("react.transitional.element"),S=Symbol.for("react.portal"),A=Symbol.for("react.fragment"),T=Symbol.for("react.strict_mode"),D=Symbol.for("react.profiler"),M=Symbol.for("react.consumer"),O=Symbol.for("react.context"),L=Symbol.for("react.forward_ref"),P=Symbol.for("react.suspense"),U=Symbol.for("react.suspense_list"),B=Symbol.for("react.memo"),Y=Symbol.for("react.lazy"),ge=Symbol.for("react.activity"),Ae=Symbol.for("react.memo_cache_sentinel"),Oe=Symbol.iterator;function Ne(t){return t===null||typeof t!="object"?null:(t=Oe&&t[Oe]||t["@@iterator"],typeof t=="function"?t:null)}var He=Symbol.for("react.client.reference");function Ze(t){if(t==null)return null;if(typeof t=="function")return t.$$typeof===He?null:t.displayName||t.name||null;if(typeof t=="string")return t;switch(t){case A:return"Fragment";case D:return"Profiler";case T:return"StrictMode";case P:return"Suspense";case U:return"SuspenseList";case ge:return"Activity"}if(typeof t=="object")switch(t.$$typeof){case S:return"Portal";case O:return t.displayName||"Context";case M:return(t._context.displayName||"Context")+".Consumer";case L:var n=t.render;return t=t.displayName,t||(t=n.displayName||n.name||"",t=t!==""?"ForwardRef("+t+")":"ForwardRef"),t;case B:return n=t.displayName||null,n!==null?n:Ze(t.type)||"Memo";case Y:n=t._payload,t=t._init;try{return Ze(t(n))}catch{}}return null}var pt=Array.isArray,Q=e.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,de=a.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,me={pending:!1,data:null,method:null,action:null},ne=[],pe=-1;function x(t){return{current:t}}function F(t){0>pe||(t.current=ne[pe],ne[pe]=null,pe--)}function ue(t,n){pe++,ne[pe]=t.current,t.current=n}var fe=x(null),te=x(null),ye=x(null),je=x(null);function Me(t,n){switch(ue(ye,n),ue(te,t),ue(fe,null),n.nodeType){case 9:case 11:t=(t=n.documentElement)&&(t=t.namespaceURI)?xv(t):0;break;default:if(t=n.tagName,n=n.namespaceURI)n=xv(n),t=Tv(n,t);else switch(t){case"svg":t=1;break;case"math":t=2;break;default:t=0}}F(fe),ue(fe,t)}function Pe(){F(fe),F(te),F(ye)}function Ie(t){t.memoizedState!==null&&ue(je,t);var n=fe.current,s=Tv(n,t.type);n!==s&&(ue(te,t),ue(fe,s))}function Lt(t){te.current===t&&(F(fe),F(te)),je.current===t&&(F(je),Al._currentValue=me)}var At,en;function Tt(t){if(At===void 0)try{throw Error()}catch(s){var n=s.stack.trim().match(/\n( *(at )?)/);At=n&&n[1]||"",en=-1<s.stack.indexOf(`
var Sx=Object.defineProperty;var wx=(Vt,Ka,Wa)=>Ka in Vt?Sx(Vt,Ka,{enumerable:!0,configurable:!0,writable:!0,value:Wa}):Vt[Ka]=Wa;var $=(Vt,Ka,Wa)=>wx(Vt,typeof Ka!="symbol"?Ka+"":Ka,Wa);(function(Vt){"use strict";function Ka(o,e){for(var a=0;a<e.length;a++){const r=e[a];if(typeof r!="string"&&!Array.isArray(r)){for(const i in r)if(i!=="default"&&!(i in o)){const l=Object.getOwnPropertyDescriptor(r,i);l&&Object.defineProperty(o,i,l.get?l:{enumerable:!0,get:()=>r[i]})}}}return Object.freeze(Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}))}function Wa(o){return o&&o.__esModule&&Object.prototype.hasOwnProperty.call(o,"default")?o.default:o}var Iu={exports:{}},We={};var Cg;function dS(){if(Cg)return We;Cg=1;var o=Symbol.for("react.transitional.element"),e=Symbol.for("react.portal"),a=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),l=Symbol.for("react.consumer"),u=Symbol.for("react.context"),d=Symbol.for("react.forward_ref"),f=Symbol.for("react.suspense"),g=Symbol.for("react.memo"),m=Symbol.for("react.lazy"),b=Symbol.for("react.activity"),v=Symbol.iterator;function S(x){return x===null||typeof x!="object"?null:(x=v&&x[v]||x["@@iterator"],typeof x=="function"?x:null)}var _={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},A=Object.assign,R={};function L(x,K,re){this.props=x,this.context=K,this.refs=R,this.updater=re||_}L.prototype.isReactComponent={},L.prototype.setState=function(x,K){if(typeof x!="object"&&typeof x!="function"&&x!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,x,K,"setState")},L.prototype.forceUpdate=function(x){this.updater.enqueueForceUpdate(this,x,"forceUpdate")};function M(){}M.prototype=L.prototype;function T(x,K,re){this.props=x,this.context=K,this.refs=R,this.updater=re||_}var D=T.prototype=new M;D.constructor=T,A(D,L.prototype),D.isPureReactComponent=!0;var U=Array.isArray;function j(){}var q={H:null,A:null,T:null,S:null},X=Object.prototype.hasOwnProperty;function ge(x,K,re){var de=re.ref;return{$$typeof:o,type:x,key:K,ref:de!==void 0?de:null,props:re}}function Ee(x,K){return ge(x.type,K,x.props)}function Ce(x){return typeof x=="object"&&x!==null&&x.$$typeof===o}function $e(x){var K={"=":"=0",":":"=2"};return"$"+x.replace(/[=:]/g,function(re){return K[re]})}var Be=/\/+/g;function Xe(x,K){return typeof x=="object"&&x!==null&&x.key!=null?$e(""+x.key):K.toString(36)}function ht(x){switch(x.status){case"fulfilled":return x.value;case"rejected":throw x.reason;default:switch(typeof x.status=="string"?x.then(j,j):(x.status="pending",x.then(function(K){x.status==="pending"&&(x.status="fulfilled",x.value=K)},function(K){x.status==="pending"&&(x.status="rejected",x.reason=K)})),x.status){case"fulfilled":return x.value;case"rejected":throw x.reason}}throw x}function Q(x,K,re,de,ie){var me=typeof x;(me==="undefined"||me==="boolean")&&(x=null);var Ne=!1;if(x===null)Ne=!0;else switch(me){case"bigint":case"string":case"number":Ne=!0;break;case"object":switch(x.$$typeof){case o:case e:Ne=!0;break;case m:return Ne=x._init,Q(Ne(x._payload),K,re,de,ie)}}if(Ne)return ie=ie(x),Ne=de===""?"."+Xe(x,0):de,U(ie)?(re="",Ne!=null&&(re=Ne.replace(Be,"$&/")+"/"),Q(ie,K,re,"",function(Ae){return Ae})):ie!=null&&(Ce(ie)&&(ie=Ee(ie,re+(ie.key==null||x&&x.key===ie.key?"":(""+ie.key).replace(Be,"$&/")+"/")+Ne)),K.push(ie)),1;Ne=0;var Se=de===""?".":de+":";if(U(x))for(var Ie=0;Ie<x.length;Ie++)de=x[Ie],me=Se+Xe(de,Ie),Ne+=Q(de,K,re,me,ie);else if(Ie=S(x),typeof Ie=="function")for(x=Ie.call(x),Ie=0;!(de=x.next()).done;)de=de.value,me=Se+Xe(de,Ie++),Ne+=Q(de,K,re,me,ie);else if(me==="object"){if(typeof x.then=="function")return Q(ht(x),K,re,de,ie);throw K=String(x),Error("Objects are not valid as a React child (found: "+(K==="[object Object]"?"object with keys {"+Object.keys(x).join(", ")+"}":K)+"). If you meant to render a collection of children, use an array instead.")}return Ne}function fe(x,K,re){if(x==null)return x;var de=[],ie=0;return Q(x,de,"","",function(me){return K.call(re,me,ie++)}),de}function ye(x){if(x._status===-1){var K=x._result;K=K(),K.then(function(re){(x._status===0||x._status===-1)&&(x._status=1,x._result=re)},function(re){(x._status===0||x._status===-1)&&(x._status=2,x._result=re)}),x._status===-1&&(x._status=0,x._result=K)}if(x._status===1)return x._result.default;throw x._result}var te=typeof reportError=="function"?reportError:function(x){if(typeof window=="object"&&typeof window.ErrorEvent=="function"){var K=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof x=="object"&&x!==null&&typeof x.message=="string"?String(x.message):String(x),error:x});if(!window.dispatchEvent(K))return}else if(typeof process=="object"&&typeof process.emit=="function"){process.emit("uncaughtException",x);return}console.error(x)},he={map:fe,forEach:function(x,KLine truncated
at`)?" (<anonymous>)":-1<s.stack.indexOf("@")?"@unknown:0:0":""}return`
`+At+t+en}var ln=!1;function vt(t,n){if(!t||ln)return"";ln=!0;var s=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var c={DetermineComponentFrameRoot:function(){try{if(n){var ce=function(){throw Error()};if(Object.defineProperty(ce.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(ce,[])}catch(ee){var X=ee}Reflect.construct(t,[],ce)}else{try{ce.call()}catch(ee){X=ee}t.call(ce.prototype)}}else{try{throw Error()}catch(ee){X=ee}(ce=t())&&typeof ce.catch=="function"&&ce.catch(function(){})}}catch(ee){if(ee&&X&&typeof ee.stack=="string")return[ee.stack,X.stack]}return[null,null]}};c.DetermineComponentFrameRoot.displayName="DetermineComponentFrameRoot";var h=Object.getOwnPropertyDescriptor(c.DetermineComponentFrameRoot,"name");h&&h.configurable&&Object.defineProperty(c.DetermineComponentFrameRoot,"name",{value:"DetermineComponentFrameRoot"});var p=c.DetermineComponentFrameRoot(),w=p[0],k=p[1];if(w&&k){var I=w.split(`
`),W=k.split(`
`);for(h=c=0;c<I.length&&!I[c].includes("DetermineComponentFrameRoot");)c++;for(;h<W.length&&!W[h].includes("DetermineComponentFrameRoot");)h++;if(c===I.length||h===W.length)for(c=I.length-1,h=W.length-1;1<=c&&0<=h&&I[c]!==W[h];)h--;for(;1<=c&&0<=h;c--,h--)if(I[c]!==W[h]){if(c!==1||h!==1)do if(c--,h--,0>h||I[c]!==W[h]){var ae=`
`+I[c].replace(" at new "," at ");return t.displayName&&ae.includes("<anonymous>")&&(ae=ae.replace("<anonymous>",t.displayName)),ae}while(1<=c&&0<=h);break}}}finally{ln=!1,Error.prepareStackTrace=s}return(s=t?t.displayName||t.name:"")?Tt(s):""}function Za(t,n){switch(t.tag){case 26:case 27:case 5:return Tt(t.type);case 16:return Tt("Lazy");case 13:return t.child!==n&&n!==null?Tt("Suspense Fallback"):Tt("Suspense");case 19:return Tt("SuspenseList");case 0:case 15:return vt(t.type,!1);case 11:return vt(t.type.render,!1);case 1:return vt(t.type,!0);case 31:return Tt("Activity");default:return""}}function wn(t){try{var n="",s=null;do n+=Za(t,s),s=t,t=t.return;while(t);return n}catch(c){return`
`+Rt+t+_t}var un=!1;function gt(t,n){if(!t||un)return"";un=!0;var s=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var c={DetermineComponentFrameRoot:function(){try{if(n){var ue=function(){throw Error()};if(Object.defineProperty(ue.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(ue,[])}catch(ee){var J=ee}Reflect.construct(t,[],ue)}else{try{ue.call()}catch(ee){J=ee}t.call(ue.prototype)}}else{try{throw Error()}catch(ee){J=ee}(ue=t())&&typeof ue.catch=="function"&&ue.catch(function(){})}}catch(ee){if(ee&&J&&typeof ee.stack=="string")return[ee.stack,J.stack]}return[null,null]}};c.DetermineComponentFrameRoot.displayName="DetermineComponentFrameRoot";var h=Object.getOwnPropertyDescriptor(c.DetermineComponentFrameRoot,"name");h&&h.configurable&&Object.defineProperty(c.DetermineComponentFrameRoot,"name",{value:"DetermineComponentFrameRoot"});var p=c.DetermineComponentFrameRoot(),w=p[0],k=p[1];if(w&&k){var z=w.split(`
`),Y=k.split(`
`);for(h=c=0;c<z.length&&!z[c].includes("DetermineComponentFrameRoot");)c++;for(;h<Y.length&&!Y[h].includes("DetermineComponentFrameRoot");)h++;if(c===z.length||h===Y.length)for(c=z.length-1,h=Y.length-1;1<=c&&0<=h&&z[c]!==Y[h];)h--;for(;1<=c&&0<=h;c--,h--)if(z[c]!==Y[h]){if(c!==1||h!==1)do if(c--,h--,0>h||z[c]!==Y[h]){var ae=`
`+z[c].replace(" at new "," at ");return t.displayName&&ae.includes("<anonymous>")&&(ae=ae.replace("<anonymous>",t.displayName)),ae}while(1<=c&&0<=h);break}}}finally{un=!1,Error.prepareStackTrace=s}return(s=t?t.displayName||t.name:"")?dt(s):""}function za(t,n){switch(t.tag){case 26:case 27:case 5:return dt(t.type);case 16:return dt("Lazy");case 13:return t.child!==n&&n!==null?dt("Suspense Fallback"):dt("Suspense");case 19:return dt("SuspenseList");case 0:case 15:return gt(t.type,!1);case 11:return gt(t.type.render,!1);case 1:return gt(t.type,!0);case 31:return dt("Activity");default:return""}}function kn(t){try{var n="",s=null;do n+=za(t,s),s=t,t=t.return;while(t);return n}catch(c){return`
Error generating stack: `+c.message+`
`+c.stack}}var qn=Object.prototype.hasOwnProperty,Bt=l.unstable_scheduleCallback,Rn=l.unstable_cancelCallback,_a=l.unstable_shouldYield,Pn=l.unstable_requestPaint,Ft=l.unstable_now,yt=l.unstable_getCurrentPriorityLevel,er=l.unstable_ImmediatePriority,Gn=l.unstable_UserBlockingPriority,tn=l.unstable_NormalPriority,yn=l.unstable_LowPriority,ta=l.unstable_IdlePriority,Cn=l.log,tr=l.unstable_setDisableYieldValue,Vn=null,qt=null;function En(t){if(typeof Cn=="function"&&tr(t),qt&&typeof qt.setStrictMode=="function")try{qt.setStrictMode(Vn,t)}catch{}}var q=Math.clz32?Math.clz32:J,le=Math.log,oe=Math.LN2;function J(t){return t>>>=0,t===0?32:31-(le(t)/oe|0)|0}var he=256,ve=262144,we=4194304;function _e(t){var n=t&42;if(n!==0)return n;switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return t&261888;case 262144:case 524288:case 1048576:case 2097152:return t&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function Be(t,n,s){var c=t.pendingLanes;if(c===0)return 0;var h=0,p=t.suspendedLanes,w=t.pingedLanes;t=t.warmLanes;var k=c&134217727;return k!==0?(c=k&~p,c!==0?h=_e(c):(w&=k,w!==0?h=_e(w):s||(s=k&~t,s!==0&&(h=_e(s))))):(k=c&~p,k!==0?h=_e(k):w!==0?h=_e(w):s||(s=c&~t,s!==0&&(h=_e(s)))),h===0?0:n!==0&&n!==h&&(n&p)===0&&(p=h&-h,s=n&-n,p>=s||p===32&&(s&4194048)!==0)?n:h}function $e(t,n){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&n)===0}function Re(t,n){switch(t){case 1:case 2:case 4:case 8:case 64:return n+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return n+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function xe(){var t=we;return we<<=1,(we&62914560)===0&&(we=4194304),t}function Ke(t){for(var n=[],s=0;31>s;s++)n.push(t);return n}function qe(t,n){t.pendingLanes|=n,n!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function Ce(t,n,s,c,h,p){var w=t.pendingLanes;t.pendingLanes=s,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=s,t.entangledLanes&=s,t.errorRecoveryDisabledLanes&=s,t.shellSuspendCounter=0;var k=t.entanglements,I=t.expirationTimes,W=t.hiddenUpdates;for(s=w&~s;0<s;){var ae=31-q(s),ce=1<<ae;k[ae]=0,I[ae]=-1;var X=W[ae];if(X!==null)for(W[ae]=null,ae=0;ae<X.length;ae++){var ee=X[ae];ee!==null&&(ee.lane&=-536870913)}s&=~ce}c!==0&&Ee(t,c,0),p!==0&&h===0&&t.tag!==0&&(t.suspendedLanes|=p&~(w&~n))}function Ee(t,n,s){t.pendingLanes|=n,t.suspendedLanes&=~n;var c=31-q(n);t.entangledLanes|=n,t.entanglements[c]=t.entanglements[c]|1073741824|s&261930}function Le(t,n){var s=t.entangledLanes|=n;for(t=t.entanglements;s;){var c=31-q(s),h=1<<c;h&n|t[c]&n&&(t[c]|=n),s&=~h}}function nt(t,n){var s=n&-n;return s=(s&42)!==0?1:kt(s),(s&(t.suspendedLanes|n))!==0?0:s}function kt(t){switch(t){case 2:t=1;break;case 8:t=4;break;case 32:t=16;break;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:t=128;break;case 268435456:t=134217728;break;default:t=0}return t}function bn(t){return t&=-t,2<t?8<t?(t&134217727)!==0?32:268435456:8:2}function Kt(){var t=de.p;return t!==0?t:(t=window.event,t===void 0?32:Xv(t.type))}function na(t,n){var s=de.p;try{return de.p=t,n()}finally{de.p=s}}var Dn=Math.random().toString(36).slice(2),nn="__reactFiber$"+Dn,un="__reactProps$"+Dn,On="__reactContainer$"+Dn,_o="__reactEvents$"+Dn,Qd="__reactListeners$"+Dn,Zd="__reactHandles$"+Dn,as="__reactResources$"+Dn,nr="__reactMarker$"+Dn;function Ao(t){delete t[nn],delete t[un],delete t[_o],delete t[Qd],delete t[Zd]}function Dr(t){var n=t[nn];if(n)return n;for(var s=t.parentNode;s;){if(n=s[On]||s[nn]){if(s=n.alternate,n.child!==null||s!==null&&s.child!==null)for(t=$v(t);t!==null;){if(s=t[nn])return s;t=$v(t)}return n}t=s,s=t.parentNode}return null}function Or(t){if(t=t[nn]||t[On]){var n=t.tag;if(n===5||n===6||n===13||n===31||n===26||n===27||n===3)return t}return null}function yi(t){var n=t.tag;if(n===5||n===26||n===27||n===6)return t.stateNode;throw Error(r(33))}function ja(t){var n=t[as];return n||(n=t[as]={hoistableStyles:new Map,hoistableScripts:new Map}),n}function Wt(t){t[nr]=!0}var vc=new Set,Sc={};function ar(t,n){Lr(t,n),Lr(t+"Capture",n)}function Lr(t,n){for(Sc[t]=n,t=0;t<n.length;t++)vc.add(n[t])}var Aa=RegExp("^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D Line truncated
`).replace(EA,"")}function _v(t,n){return n=Ev(n),Ev(t)===n}function Et(t,n,s,c,h,p){switch(s){case"children":typeof c=="string"?n==="body"||n==="textarea"&&c===""||$r(t,c):(typeof c=="number"||typeof c=="bigint")&&n!=="body"&&$r(t,""+c);break;case"className":is(t,"class",c);break;case"tabIndex":is(t,"tabindex",c);break;case"dir":case"role":case"viewBox":case"width":case"height":is(t,s,c);break;case"style":Ba(t,c,p);break;case"data":if(n!=="object"){is(t,"data",c);break}case"src":case"href":if(c===""&&(n!=="a"||s!=="href")){t.removeAttribute(s);break}if(c==null||typeof c=="function"||typeof c=="symbol"||typeof c=="boolean"){t.removeAttribute(s);break}c=ls(""+c),t.setAttribute(s,c);break;case"action":case"formAction":if(typeof c=="function"){t.setAttribute(s,"javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you\\'re trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')");break}else typeof p=="function"&&(s==="formAction"?(n!=="input"&&Et(t,n,"name",h.name,h,null),Et(t,n,"formEncType",h.formEncType,h,null),Et(t,n,"formMethod",h.formMethod,h,null),Et(t,n,"formTarget",h.formTarget,h,null)):(Et(t,n,"encType",h.encType,h,null),Et(t,n,"method",h.method,h,null),Et(t,n,"target",h.target,h,null)));if(c==null||typeof c=="symbol"||typeof c=="boolean"){t.removeAttribute(s);break}c=ls(""+c),t.setAttribute(s,c);break;case"onClick":c!=null&&(t.onclick=aa);break;case"onScroll":c!=null&&tt("scroll",t);break;case"onScrollEnd":c!=null&&tt("scrollend",t);break;case"dangerouslySetInnerHTML":if(c!=null){if(typeof c!="object"||!("__html"in c))throw Error(r(61));if(s=c.__html,s!=null){if(h.children!=null)throw Error(r(60));t.innerHTML=s}}break;case"multiple":t.multiple=c&&typeof c!="function"&&typeof c!="symbol";break;case"muted":t.muted=c&&typeof c!="function"&&typeof c!="symbol";break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"defaultValue":case"defaultChecked":case"innerHTML":case"ref":break;case"autoFocus":break;case"xlinkHref":if(c==null||typeof c=="function"||typeof c=="boolean"||typeof c=="symbol"){t.removeAttribute("xlink:href");break}s=ls(""+c),t.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",s);break;case"contentEditable":case"spellCheck":case"draggable":case"value":case"autoReverse":case"externalResourcesRequired":case"focusable":case"preserveAlpha":c!=null&&typeof c!="function"&&typeof c!="symbol"?t.setAttribute(s,""+c):t.removeAttribute(s);break;case"inert":case"allowFullScreen":case"async":case"autoPlay":case"controls":case"default":case"defer":case"disabled":case"disablePictureInPicture":case"disableRemotePlayback":case"formNoValidate":case"hidden":case"loop":case"noModule":case"noValidate":case"open":case"playsInline":case"readOnly":case"required":case"reversed":case"scoped":case"seamless":case"itemScope":c&&typeof c!="function"&&typeof c!="symbol"?t.setAttribute(s,""):t.removeAttribute(s);break;case"capture":case"download":c===!0?t.setAttribute(s,""):c!==!1&&c!=null&&typeof c!="function"&&typeof c!="symbol"?t.setAttribute(s,c):t.removeAttribute(s);break;case"cols":case"rows":case"size":case"span":c!=null&&typeof c!="function"&&typeof c!="symbol"&&!isNaN(c)&&1<=c?t.setAttribute(s,c):t.removeAttribute(s);break;case"rowSpan":case"start":c==null||typeof c=="function"||typeof c=="symbol"||isNaN(c)?t.removeAttribute(s):t.setAttribute(s,c);break;case"popover":tt("beforetoggle",t),tt("toggle",t),rs(t,"popover",c);break;case"xlinkActuate":xa(t,"http://www.w3.org/1999/xlink","xlink:actuate",c);break;case"xlinkArcrole":xa(t,"http://www.w3.org/1999/xlink","xlink:arcrole",c);break;case"xlinkRole":xa(t,"http://www.w3.org/1999/xlink","xlink:role",c);break;case"xlinkShow":xa(t,"http://www.w3.org/1999/xlink","xlink:show",c);break;case"xlinkTitle":xa(t,"http://www.w3.org/1999/xlink","xlink:title",c);break;case"xlinkType":xa(t,"http://www.w3.org/1999/xlink","xlink:type",c);break;case"xmlBase":xa(t,"http://www.w3.org/XML/1998/namespace","xml:base",c);break;case"xmlLang":xa(t,"http://www.w3.org/XML/1998/namespace","xml:lang",c);break;case"xmlSpace":xa(t,"http://www.w3.org/XML/1998/namespace","xml:space",c);break;case"is":rs(t,"is",c);break;case"innerText":case"textContent":break;default:(!(2<s.length)||s[0]!=="o"&&s[0]!=="O"||s[1]!=="n"&&s[1]!=="N")&&(s=nf.get(s)||s,rs(t,s,c))}}function Kh(t,n,s,c,h,p){switch(s){case"style":Ba(t,c,p);break;case"dangerouslySetInnerHTML":if(c!=null){if(typeof c!="object"||!("__html"in c))throw Error(r(61));if(s=c.__html,s!=null){if(h.children!=null)throw Error(r(60));t.innerHTML=s}}break;case"children":typeof c=="string"?$r(t,c):(typeof c=="number"||typeof c=="bigint")&&$r(t,""+c);break;case"onScroll":c!=null&&tt("scroll",t);break;case"onScrollEnd":c!=null&&tt("scrollend",t);break;case"onClick":c!=null&&(t.onclick=aa);break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"inne Line truncated
`).forEach(function(u){i=u.indexOf(":"),a=u.substring(0,i).trim().toLowerCase(),r=u.substring(i+1).trim(),!(!a||e[a]&&_w[a])&&(a==="set-cookie"?e[a]?e[a].push(r):e[a]=[r]:e[a]=e[a]?e[a]+", "+r:r)}),e},ep=Symbol("internals");function to(l){return l&&String(l).trim().toLowerCase()}function Bl(l){return l===!1||l==null?l:Z.isArray(l)?l.map(Bl):String(l)}function xw(l){const e=Object.create(null),a=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=a.exec(l);)e[r[1]]=r[2];return e}const Tw=l=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(l.trim());function id(l,e,a,r,i){if(Z.isFunction(r))return r.call(this,e,a);if(i&&(e=a),!!Z.isString(e)){if(Z.isString(r))return e.indexOf(r)!==-1;if(Z.isRegExp(r))return r.test(e)}}function kw(l){return l.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(e,a,r)=>a.toUpperCase()+r)}function Rw(l,e){const a=Z.toCamelCase(" "+e);["get","set","has"].forEach(r=>{Object.defineProperty(l,r+a,{value:function(i,o,u){return this[r].call(this,e,i,o,u)},configurable:!0})})}let xn=class{constructor(e){e&&this.set(e)}set(e,a,r){const i=this;function o(d,f,g){const m=to(f);if(!m)throw new Error("header name must be a non-empty string");const b=Z.findKey(i,m);(!b||i[b]===void 0||g===!0||g===void 0&&i[b]!==!1)&&(i[b||f]=Bl(d))}const u=(d,f)=>Z.forEach(d,(g,m)=>o(g,m,f));if(Z.isPlainObject(e)||e instanceof this.constructor)u(e,a);else if(Z.isString(e)&&(e=e.trim())&&!Tw(e))u(Aw(e),a);else if(Z.isObject(e)&&Z.isIterable(e)){let d={},f,g;for(const m of e){if(!Z.isArray(m))throw TypeError("Object iterator must return a key-value pair");d[g=m[0]]=(f=d[g])?Z.isArray(f)?[...f,m[1]]:[f,m[1]]:m[1]}u(d,a)}else e!=null&&o(a,e,r);return this}get(e,a){if(e=to(e),e){const r=Z.findKey(this,e);if(r){const i=this[r];if(!a)return i;if(a===!0)return xw(i);if(Z.isFunction(a))return a.call(this,i,r);if(Z.isRegExp(a))return a.exec(i);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,a){if(e=to(e),e){const r=Z.findKey(this,e);return!!(r&&this[r]!==void 0&&(!a||id(this,this[r],r,a)))}return!1}delete(e,a){const r=this;let i=!1;function o(u){if(u=to(u),u){const d=Z.findKey(r,u);d&&(!a||id(r,r[d],d,a))&&(delete r[d],i=!0)}}return Z.isArray(e)?e.forEach(o):o(e),i}clear(e){const a=Object.keys(this);let r=a.length,i=!1;for(;r--;){const o=a[r];(!e||id(this,this[o],o,e,!0))&&(delete this[o],i=!0)}return i}normalize(e){const a=this,r={};return Z.forEach(this,(i,o)=>{const u=Z.findKey(r,o);if(u){a[u]=Bl(i),delete a[o];return}const d=e?kw(o):String(o).trim();d!==o&&delete a[o],a[d]=Bl(i),r[d]=!0}),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const a=Object.create(null);return Z.forEach(this,(r,i)=>{r!=null&&r!==!1&&(a[i]=e&&Z.isArray(r)?r.join(", "):r)}),a}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([e,a])=>e+": "+a).join(`
`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...a){const r=new this(e);return a.forEach(i=>r.set(i)),r}static accessor(e){const r=(this[ep]=this[ep]={accessors:{}}).accessors,i=this.prototype;function o(u){const d=to(u);r[d]||(Rw(i,u),r[d]=!0)}return Z.isArray(e)?e.forEach(o):o(e),this}};xn.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),Z.reduceDescriptors(xn.prototype,({value:l},e)=>{let a=e[0].toUpperCase()+e.slice(1);return{get:()=>l,set(r){this[a]=r}}}),Z.freezeMethods(xn);function sd(l,e){const a=this||eo,r=e||a,i=xn.from(r.headers);let o=r.data;return Z.forEach(l,function(d){o=d.call(a,o,i.normalize(),e?e.status:void 0)}),i.normalize(),o}function tp(l){return!!(l&&l.__CANCEL__)}function Fi(l,e,a){Ye.call(this,l??"canceled",Ye.ERR_CANCELED,e,a),this.name="CanceledError"}Z.inherits(Fi,Ye,{__CANCEL__:!0});function np(l,e,a){const r=a.config.validateStatus;!a.status||!r||r(a.status)?l(a):e(new Ye("Request failed with status code "+a.status,[Ye.ERR_BAD_REQUEST,Ye.ERR_BAD_RESPONSE][Math.floor(a.status/100)-4],a.config,a.request,a))}function Dw(l){const e=/^([-+\w]{1,25})(:?\/\/|:)/.exec(l);return e&&e[1]||""}function Ow(l,e){l=l||10;const a=new Array(l),r=new Array(l);let i=0,o=0,u;return e=e!==void 0?e:1e3,function(f){const g=Date.now(),m=r[o];u||(u=g),a[i]=f,r[i]=g;let b=o,v=0;for(;b!==i;)v+=a[b++],b=b%l;if(i=(i+1)%l,i===o&&(o=(o+1)%l),g-u<e)return;const E=m&&g-m;return E?Math.round(v*1e3/E):void 0}}function Lw(l,e){let a=0,r=1e3/e,i,o;const u=(g,m=Date.now())=>{a=m,i=null,o&&(clearTimeout(o),o=null),l(...g)};return[(...g)=>{const m=Date.now(),b=m-a;b>=r?u(g,m):(i=g,o||(o=setTimeout(()=>{o=null,u(i)},r-b)))},()=>i&&u(i)]}const ql=(l,e,a=3)=>{let r=0;const i=Ow(50,250);return Lw(o=>{const u=o.loaded,d=o.lengthComputable?o.total:void 0,f=u-r,g=i(f),m=u<=d;r=u;const b={loaded:u,total:d,progress:d?u/d:void 0,bytes:f,rate:g||void 0,estimated:g&&d&&m?(d-u)/g:void 0,event:o,lengthComputable:d!=null,[e?"download":"upload"]:!0};l(b)},a)},ap=(l,e)=>{const a=l!=null;return[r=>e[0]({lengthComputable:a,total:l,loaded:r}),e[1]]},rp=l=>(...e)=>Z.asap(()=>l(...e)),Mw=mn.hasStandardBrowserEnv?((l,e)=>a=>(a=new URL(a,mn.origin),l.protocol===a.protocol&&l.host===a.host&&(e||l.port===a.port)))(new URL(mn.origin),mn.navigator&&/(msie|trident)/i.test(mn.navigator.userAgent)):()=>!0,$w=mn.hasStandardBrowserEnv?{write(l,e,a,r,i,o){const u=[l+"="+encodeURIComponent(e)];Z.isNumber(a)&&u.push("expires="+new Date(a).toGMTString()),Z.isString(r)&&u.push("path="+r),Z.isString(i)&&u.push("domain="+i),o===!0&&u.push("secure"),document.cookie=u.join("; ")},read(l){const e=document.cookie.match(new RegExp("(^|;\\s*)("+l+")=([^;]*)"));return e?decodeURIComponent(e[3]):null},remove(l){this.write(l,"",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function Nw(l){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(l)}function Hw(l,e){return e?l.replace(/\/?\/$/,"")+"/"+e.replace(/^\/+/,""):l}function ip(l,e,a){let r=!Nw(e);return l&&(r||a==!1)?Hw(l,e):e}const sp=l=>l instanceof xn?{...l}:l;function di(l,e){e=e||{};const a={};function r(g,m,b,v){return Z.isPlainObject(g)&&Z.isPlainObject(m)?Z.merge.call({caseless:v},g,m):Z.isPlainObject(m)?Z.merge({},m):Z.isArray(m)?m.slice():m}function i(g,m,b,v){if(Z.isUndefined(m)){if(!Z.isUndefined(g))return r(void 0,g,b,v)}else return r(g,m,b,v)}function o(g,m){if(!Z.isUndefined(m))return r(void 0,m)}function u(g,m){if(Z.isUndefined(m)){if(!Z.isUndefined(g))return r(void 0,g)}else return r(void 0,m)}function d(g,m,b){if(b in e)return r(g,m);if(b in l)return r(void 0,g)}const f={url:o,method:o,data:o,baseURL:u,transformRequest:u,transformResponse:u,paramsSerializer:u,timeout:u,timeoutMessage:u,withCredentials:u,withXSRFToken:u,adapter:u,responseType:u,xsrfCookieName:u,xsrfHeaderName:u,onUploadProgress:u,onDownloadProgress:u,decompress:u,maxContentLength:u,maxBodyLength:u,beforeRedirect:u,transport:u,httpAgent:u,httpsAgent:u,cancelToken:u,socketPath:u,responseEncoding:u,validateStatus:d,headers:(g,m,b)=>i(sp(g),sp(m),b,!0)};return Z.forEach(Object.keys({...l,...e}),function(m){const b=f[m]||i,v=b(l[m],e[m],m);Z.isUndefined(v)&&b!==d||(a[m]=v)}),a}const op=l=>{const e=di({},l);let{data:a,withXSRFToken:r,xsrfHeaderName:i,xsrfCookieName:o,headers:u,auth:d}=e;if(e.headers=u=xn.from(u),e.url=Xg(ip(e.baseURL,e.url,e.allowAbsoluteUrls),l.params,l.paramsSerializer),d&&u.set("Authorization","Basic "+btoa((d.username||"")+":"+(d.password?unescape(encodeURIComponent(d.password)):""))),Z.isFormData(a)){if(mn.hasStandardBrowserEnv||mn.hasStandardBrowserWebWorkerEnv)u.setContentType(void 0);else if(Z.isFunction(a.getHeaders)){const f=a.getHeaders(),g=["content-type","content-length"];Object.entries(f).forEach(([m,b])=>{g.includes(m.toLowerCase())&&u.set(m,b)})}}if(mn.hasStandardBrowserEnv&&(r&&Z.isFunction(r)&&(r=r(e)),r||r!==!1&&Mw(e.url))) Line truncated
`+u.map(gp).join(`
`):" "+gp(u[0]):"as no adapter specified";throw new Ye("There is no suitable adapter to dispatch the request "+d,"ERR_NOT_SUPPORT")}return i},adapters:od};function ld(l){if(l.cancelToken&&l.cancelToken.throwIfRequested(),l.signal&&l.signal.aborted)throw new Fi(null,l)}function mp(l){return ld(l),l.headers=xn.from(l.headers),l.data=sd.call(l,l.transformRequest),["post","put","patch"].indexOf(l.method)!==-1&&l.headers.setContentType("application/x-www-form-urlencoded",!1),pp.getAdapter(l.adapter||eo.adapter,l)(l).then(function(r){return ld(l),r.data=sd.call(l,l.transformResponse,r),r.headers=xn.from(r.headers),r},function(r){return tp(r)||(ld(l),r&&r.response&&(r.response.data=sd.call(l,l.transformResponse,r.response),r.response.headers=xn.from(r.response.headers))),Promise.reject(r)})}const yp="1.12.2",Gl={};["object","boolean","number","function","string","symbol"].forEach((l,e)=>{Gl[l]=function(r){return typeof r===l||"a"+(e<1?"n ":" ")+l}});const bp={};Gl.transitional=function(e,a,r){function i(o,u){return"[Axios v"+yp+"] Transitional option '"+o+"'"+u+(r?". "+r:"")}return(o,u,d)=>{if(e===!1)throw new Ye(i(u," has been removed"+(a?" in "+a:"")),Ye.ERR_DEPRECATED);return a&&!bp[u]&&(bp[u]=!0,console.warn(i(u," has been deprecated since v"+a+" and will be removed in the near future"))),e?e(o,u,d):!0}},Gl.spelling=function(e){return(a,r)=>(console.warn(`${r} is likely a misspelling of ${e}`),!0)};function Fw(l,e,a){if(typeof l!="object")throw new Ye("options must be an object",Ye.ERR_BAD_OPTION_VALUE);const r=Object.keys(l);let i=r.length;for(;i-- >0;){const o=r[i],u=e[o];if(u){const d=l[o],f=d===void 0||u(d,o,l);if(f!==!0)throw new Ye("option "+o+" must be "+f,Ye.ERR_BAD_OPTION_VALUE);continue}if(a!==!0)throw new Ye("Unknown option "+o,Ye.ERR_BAD_OPTION)}}const Vl={assertOptions:Fw,validators:Gl},Ma=Vl.validators;let fi=class{constructor(e){this.defaults=e||{},this.interceptors={request:new Jg,response:new Jg}}async request(e,a){try{return await this._request(e,a)}catch(r){if(r instanceof Error){let i={};Error.captureStackTrace?Error.captureStackTrace(i):i=new Error;const o=i.stack?i.stack.replace(/^.+\n/,""):"";try{r.stack?o&&!String(r.stack).endsWith(o.replace(/^.+\n.+\n/,""))&&(r.stack+=`
`+o):r.stack=o}catch{}}throw r}}_request(e,a){typeof e=="string"?(a=a||{},a.url=e):a=e||{},a=di(this.defaults,a);const{transitional:r,paramsSerializer:i,headers:o}=a;r!==void 0&&Vl.assertOptions(r,{silentJSONParsing:Ma.transitional(Ma.boolean),forcedJSONParsing:Ma.transitional(Ma.boolean),clarifyTimeoutError:Ma.transitional(Ma.boolean)},!1),i!=null&&(Z.isFunction(i)?a.paramsSerializer={serialize:i}:Vl.assertOptions(i,{encode:Ma.function,serialize:Ma.function},!0)),a.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?a.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:a.allowAbsoluteUrls=!0),Vl.assertOptions(a,{baseUrl:Ma.spelling("baseURL"),withXsrfToken:Ma.spelling("withXSRFToken")},!0),a.method=(a.method||this.defaults.method||"get").toLowerCase();let u=o&&Z.merge(o.common,o[a.method]);o&&Z.forEach(["delete","get","head","post","put","patch","common"],S=>{delete o[S]}),a.headers=xn.concat(u,o);const d=[];let f=!0;this.interceptors.request.forEach(function(A){typeof A.runWhen=="function"&&A.runWhen(a)===!1||(f=f&&A.synchronous,d.unshift(A.fulfilled,A.rejected))});const g=[];this.interceptors.response.forEach(function(A){g.push(A.fulfilled,A.rejected)});let m,b=0,v;if(!f){const S=[mp.bind(this),void 0];for(S.unshift(...d),S.push(...g),v=S.length,m=Promise.resolve(a);b<v;)m=m.then(S[b++],S[b++]);return m}v=d.length;let E=a;for(;b<v;){const S=d[b++],A=d[b++];try{E=S(E)}catch(T){A.call(this,T);break}}try{m=mp.call(this,E)}catch(S){return Promise.reject(S)}for(b=0,v=g.length;b<v;)m=m.then(g[b++],g[b++]);return m}getUri(e){e=di(this.defaults,e);const a=ip(e.baseURL,e.url,e.allowAbsoluteUrls);return Xg(a,e.params,e.paramsSerializer)}};Z.forEach(["delete","get","head","options"],function(e){fi.prototype[e]=function(a,r){return this.request(di(r||{},{method:e,url:a,data:(r||{}).data}))}}),Z.forEach(["post","put","patch"],function(e){function a(r){return function(o,u,d){return this.request(di(d||{},{method:e,headers:r?{"Content-Type":"multipart/form-data"}:{},url:o,data:u}))}}fi.prototype[e]=a(),fi.prototype[e+"Form"]=a(!0)});let Kw=class aS{constructor(e){if(typeof e!="function")throw new TypeError("executor must be a function.");let a;this.promise=new Promise(function(o){a=o});const r=this;this.promise.then(i=>{if(!r._listeners)return;let o=r._listeners.length;for(;o-- >0;)r._listeners[o](i);r._listeners=null}),this.promise.then=i=>{let o;const u=new Promise(d=>{r.subscribe(d),o=d}).then(i);return u.cancel=function(){r.unsubscribe(o)},u},e(function(o,u,d){r.reason||(r.reason=new Fi(o,u,d),a(r.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const a=this._listeners.indexOf(e);a!==-1&&this._listeners.splice(a,1)}toAbortSignal(){const e=new AbortController,a=r=>{e.abort(r)};return this.subscribe(a),e.signal.unsubscribe=()=>this.unsubscribe(a),e.signal}static source(){let e;return{token:new aS(function(i){e=i}),cancel:e}}};function Ww(l){return function(a){return l.apply(null,a)}}function Yw(l){return Z.isObject(l)&&l.isAxiosError===!0}const cd={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(cd).forEach(([l,e])=>{cd[e]=l});function vp(l){const e=new fi(l),a=Ng(fi.prototype.request,e);return Z.extend(a,fi.prototype,e,{allOwnKeys:!0}),Z.extend(a,e,null,{allOwnKeys:!0}),a.create=function(i){return vp(di(l,i))},a}const Ut=vp(eo);Ut.Axios=fi,Ut.CanceledError=Fi,Ut.CancelToken=Kw,Ut.isCancel=tp,Ut.VERSION=yp,Ut.toFormData=Ul,Ut.AxiosError=Ye,Ut.Cancel=Ut.CanceledError,Ut.all=function(e){return Promise.all(e)},Ut.spread=Ww,Ut.isAxiosError=Yw,Ut.mergeConfig=di,Ut.AxiosHeaders=xn,Ut.formToJSON=l=>Zg(Z.isHTMLForm(l)?new FormData(l):l),Ut.getAdapter=pp.getAdapter,Ut.HttpStatusCode=cd,Ut.default=Ut;const{Ax Line truncated
* @license React
* react-jsx-runtime.production.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var wp;function e0(){if(wp)return ao;wp=1;var l=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function a(r,i,o){var u=null;if(o!==void 0&&(u=""+o),i.key!==void 0&&(u=""+i.key),"key"in i){o={};for(var d in i)d!=="key"&&(o[d]=i[d])}else o=i;return i=o.ref,{$$typeof:l,type:r,key:u,ref:i!==void 0?i:null,props:o}}return ao.Fragment=e,ao.jsx=a,ao.jsxs=a,ao}var Cp;function t0(){return Cp||(Cp=1,gd.exports=e0()),gd.exports}var ct=t0();const n0=Ka({__proto__:null,default:Wa(ct)},[ct]),pd=dt("ParentContextProvider"),Ep=N.createContext(null);let Wl=null;function md(){Wl?(pd.log("[triggerModalParentUpdate] 모달 부모 컨텍스트 업데이트 트리거"),Wl()):pd.warn("[triggerModalParentUpdate] Provider가 아직 마운트되지 않음")}const _p=({children:l})=>{const[e,a]=N.useState(0),r=N.useRef(!0),i=N.useCallback(()=>{const u=window.__g7LayoutContextStack||[];return u[u.length-1]?.dataContext},[]);N.useEffect(()=>(r.current=!0,Wl=()=>{r.current&&(a(u=>u+1),pd.log("[ParentContextProvider] 버전 업데이트됨"))},()=>{r.current=!1,Wl=null}),[]);const o={version:e,getParentDataContext:i};return ct.jsx(Ep.Provider,{value:o,children:l})};function a0(){return N.useContext(Ep)}const z=dt("ActionDispatcher"),Ap=new Set(["navigate","navigateBack","navigateForward","replaceUrl","refresh","logout"]),r0=new Set(["redirect"]);function jn(){try{return window.G7Core?.devTools}catch{return}}class Mt extends Error{constructor(e,a,r){super(e),this.action=a,this.originalError=r,this.name="ActionError"}}const ns=class ns{constructor(e={},a,r){$(this,"bindingEngine");$(this,"translationEngine");$(this,"translationContext");$(this,"customHandlers",new Map);$(this,"defaultContext");$(this,"globalStateUpdater");$(this,"errorHandlingSetup",!1);$(this,"debounceTimers",new Map);$(this,"pendingDebounceFlushers",new Map);$(this,"debounceAccumulatedValues",new Map);$(this,"globalHeaders",[]);$(this,"namedActions",{});$(this,"previewMode",!1);$(this,"intervals",new Map);this.bindingEngine=new Sn,this.translationEngine=a,this.translationContext=r,this.defaultContext=e,this.registerDefaultHandlers(),this.setupErrorHandling()}setGlobalHeaders(e){this.globalHeaders=e||[]}setNamedActions(e){this.namedActions=e||{};const a=jn();a?.isEnabled?.()&&a.setNamedActionDefinitions?.(this.namedActions),z.log("[setNamedActions] registered:",Object.keys(this.namedActions))}getNamedActions(){return this.namedActions}setPreviewMode(e){this.previewMode=e,z.log("Preview mode:",e?"enabled":"disabled")}isPreviewMode(){return this.previewMode}static getPreviewSuppressedHandlers(){return Ap}static getPreviewSuppressedLayoutFeatures(){return r0}resolveActionRef(e){if(!e.actionRef)return e;const a=this.namedActions[e.actionRef];if(!a)return z.warn(`[resolveActionRef] named action not found: "${e.actionRef}"`),e;const r=jn();r?.isEnabled?.()&&r.trackNamedActionRef?.({actionRefName:e.actionRef,resolvedHandler:a.handler,timestamp:Date.now()});const{actionRef:i,type:o,key:u,event:d,...f}=e,g={...a,...Object.fromEntries(Object.entries(f).filter(([,m])=>m!==void 0)),type:o??a.type};return u!==void 0&&(g.key=u),d!==void 0&&(g.event=d),g}matchesPattern(e,a){if(a==="*")return!0;const r=a.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${r}$`).test(e)}getMatchingGlobalHeaders(e,a){const r={};for(const i of this.globalHeaders)this.matchesPattern(e,i.pattern)&&Object.entries(i.headers).forEach(([o,u])=>{const d=Pi(u,a,{skipCache:!0});d!=null&&d!==""&&(r[o]=String(d))});return r}setupErrorHandling(){if(this.errorHandlingSetup)return;ma().setActionExecutor(async(a,r)=>{const i={type:"click",handler:a.handler,target:a.target,params:a.params,actions:a.actions},o={data:{...this.defaultContext.data,error:r.error}};return await this.dispatchAction(i,o)}),this.errorHandlingSetup=!0}registerDefaultHandlers(){this.registerHandler("refetchDataSource",async(a,r)=>{const i=a.params?.dataSourceId,o=a.params?.sync;if(!i){z.warn("refetchDataSource: dataSourceId is required");return}if(typeof window<"u"&&window.G7Core?.dataSource?.refetch){const u=window.G7Core?.state?.get?.()||{},d={...r.state?._global,...u},f=window.G7Core?.state?.getLocal?.()||{},g=r.data?._local||r.state||{},m={...f,...g},b=r.isolatedContext?.state;z.log("[refetchDataSource] localStateOverride:",m),await window.G7Core.dataSource.refetch(i,{...o?{sync:!0}:{},...d?{globalStateOverride:d}:{},...m?{localStateOverride:m}:{},...b?{isolatedStateOverride:b}:{}})}else z.warn("refetchDataSource: G7Core.dataSource.refetch is not available")}),this.registerHandler("appendDataSource",async(a,r)=>{const{dataSourceId:i,dataPath:o,newData:u}=a.params||{};if(!i){z.warn("appendDataSource: dataSourceId is required");return}if(u===void 0){z.warn("appendDataSource: newData is required");return}if(typeof window<"u"&&window.G7Core?.dataSource?.updateData){if(!Array.isArray(u)){z.warn("appendDataSource: newData must be an array, got:",typeof u,u);return}await window.G7Core.dataSource.updLine truncated
`+c.stack}}var Dn=Object.prototype.hasOwnProperty,jt=o.unstable_scheduleCallback,On=o.unstable_cancelCallback,ea=o.unstable_shouldYield,ja=o.unstable_requestPaint,Ft=o.unstable_now,Rr=o.unstable_getCurrentPriorityLevel,Za=o.unstable_ImmediatePriority,bn=o.unstable_UserBlockingPriority,en=o.unstable_NormalPriority,et=o.unstable_LowPriority,ta=o.unstable_IdlePriority,En=o.log,er=o.unstable_setDisableYieldValue,Ea=null,tn=null;function _n(t){if(typeof En=="function"&&er(t),tn&&typeof tn.setStrictMode=="function")try{tn.setStrictMode(Ea,t)}catch{}}var P=Math.clz32?Math.clz32:Z,ce=Math.log,le=Math.LN2;function Z(t){return t>>>=0,t===0?32:31-(ce(t)/le|0)|0}var be=256,ve=262144,Te=4194304;function xe(t){var n=t&42;if(n!==0)return n;switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return t&261888;case 262144:case 524288:case 1048576:case 2097152:return t&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function je(t,n,s){var c=t.pendingLanes;if(c===0)return 0;var h=0,p=t.suspendedLanes,w=t.pingedLanes;t=t.warmLanes;var k=c&134217727;return k!==0?(c=k&~p,c!==0?h=xe(c):(w&=k,w!==0?h=xe(w):s||(s=k&~t,s!==0&&(h=xe(s))))):(k=c&~p,k!==0?h=xe(k):w!==0?h=xe(w):s||(s=c&~t,s!==0&&(h=xe(s)))),h===0?0:n!==0&&n!==h&&(n&p)===0&&(p=h&-h,s=n&-n,p>=s||p===32&&(s&4194048)!==0)?n:h}function qe(t,n){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&n)===0}function ke(t,n){switch(t){case 1:case 2:case 4:case 8:case 64:return n+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return n+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function De(){var t=Te;return Te<<=1,(Te&62914560)===0&&(Te=4194304),t}function Ke(t){for(var n=[],s=0;31>s;s++)n.push(t);return n}function Ve(t,n){t.pendingLanes|=n,n!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function _e(t,n,s,c,h,p){var w=t.pendingLanes;t.pendingLanes=s,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=s,t.entangledLanes&=s,t.errorRecoveryDisabledLanes&=s,t.shellSuspendCounter=0;var k=t.entanglements,z=t.expirationTimes,Y=t.hiddenUpdates;for(s=w&~s;0<s;){var ae=31-P(s),ue=1<<ae;k[ae]=0,z[ae]=-1;var J=Y[ae];if(J!==null)for(Y[ae]=null,ae=0;ae<J.length;ae++){var ee=J[ae];ee!==null&&(ee.lane&=-536870913)}s&=~ue}c!==0&&Re(t,c,0),p!==0&&h===0&&t.tag!==0&&(t.suspendedLanes|=p&~(w&~n))}function Re(t,n,s){t.pendingLanes|=n,t.suspendedLanes&=~n;var c=31-P(n);t.entangledLanes|=n,t.entanglements[c]=t.entanglements[c]|1073741824|s&261930}function ze(t,n){var s=t.entangledLanes|=n;for(t=t.entanglements;s;){var c=31-P(s),h=1<<c;h&n|t[c]&n&&(t[c]|=n),s&=~h}}function st(t,n){var s=n&-n;return s=(s&42)!==0?1:Dt(s),(s&(t.suspendedLanes|n))!==0?0:s}function Dt(t){switch(t){case 2:t=1;break;case 8:t=4;break;case 32:t=16;break;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:t=128;break;case 268435456:t=134217728;break;default:t=0}return t}function nn(t){return t&=-t,2<t?8<t?(t&134217727)!==0?32:268435456:8:2}function Kt(){var t=fe.p;return t!==0?t:(t=window.event,t===void 0?32:tS(t.type))}function Pn(t,n){var s=fe.p;try{return fe.p=t,n()}finally{fe.p=s}}var Ln=Math.random().toString(36).slice(2),an="__reactFiber$"+Ln,vn="__reactProps$"+Ln,kr="__reactContainer$"+Ln,Eo="__reactEvents$"+Ln,af="__reactListeners$"+Ln,dc="__reactHandles$"+Ln,Ua="__reactResources$"+Ln,pi="__reactMarker$"+Ln;function _o(t){delete t[an],delete t[vn],delete t[Eo],delete t[af],delete t[dc]}function Dr(t){var n=t[an];if(n)return n;for(var s=t.parentNode;s;){if(n=s[kr]||s[an]){if(s=n.alternate,n.child!==null||s!==null&&s.child!==null)for(t=jv(t);t!==null;){if(s=t[an])return s;t=jv(t)}return n}t=s,s=t.parentNode}return null}function Ba(t){if(t=t[an]||t[kr]){var n=t.tag;if(n===5||n===6||n===13||n===31||n===26||n===27||n===3)return t}return null}function tr(t){var n=t.tag;if(n===5||n===26||n===27||n===6)return t.stateNode;throw Error(r(33))}function Or(t){var n=t[Ua];return n||(n=t[Ua]={hoistableStyles:new Map,hoistableScripts:new Map}),n}function Wt(t){t[pi]=!0}var fc=new Set,hc={};function _a(t,n){Lr(t,n),Lr(t+"Capture",n)}function Lr(t,n){for(hc[t]=n,t=0;t<n.length;t++)fc.add(n[t])}var rf=RegExp("^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D Line truncated
`).replace(qA,"")}function kv(t,n){return n=Rv(n),Rv(t)===n}function xt(t,n,s,c,h,p){switch(s){case"children":typeof c=="string"?n==="body"||n==="textarea"&&c===""||Hr(t,c):(typeof c=="number"||typeof c=="bigint")&&n!=="body"&&Hr(t,""+c);break;case"className":mi(t,"class",c);break;case"tabIndex":mi(t,"tabindex",c);break;case"dir":case"role":case"viewBox":case"width":case"height":mi(t,s,c);break;case"style":Sc(t,c,p);break;case"data":if(n!=="object"){mi(t,"data",c);break}case"src":case"href":if(c===""&&(n!=="a"||s!=="href")){t.removeAttribute(s);break}if(c==null||typeof c=="function"||typeof c=="symbol"||typeof c=="boolean"){t.removeAttribute(s);break}c=na(""+c),t.setAttribute(s,c);break;case"action":case"formAction":if(typeof c=="function"){t.setAttribute(s,"javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you\\'re trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')");break}else typeof p=="function"&&(s==="formAction"?(n!=="input"&&xt(t,n,"name",h.name,h,null),xt(t,n,"formEncType",h.formEncType,h,null),xt(t,n,"formMethod",h.formMethod,h,null),xt(t,n,"formTarget",h.formTarget,h,null)):(xt(t,n,"encType",h.encType,h,null),xt(t,n,"method",h.method,h,null),xt(t,n,"target",h.target,h,null)));if(c==null||typeof c=="symbol"||typeof c=="boolean"){t.removeAttribute(s);break}c=na(""+c),t.setAttribute(s,c);break;case"onClick":c!=null&&(t.onclick=Aa);break;case"onScroll":c!=null&&nt("scroll",t);break;case"onScrollEnd":c!=null&&nt("scrollend",t);break;case"dangerouslySetInnerHTML":if(c!=null){if(typeof c!="object"||!("__html"in c))throw Error(r(61));if(s=c.__html,s!=null){if(h.children!=null)throw Error(r(60));t.innerHTML=s}}break;case"multiple":t.multiple=c&&typeof c!="function"&&typeof c!="symbol";break;case"muted":t.muted=c&&typeof c!="function"&&typeof c!="symbol";break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"defaultValue":case"defaultChecked":case"innerHTML":case"ref":break;case"autoFocus":break;case"xlinkHref":if(c==null||typeof c=="function"||typeof c=="boolean"||typeof c=="symbol"){t.removeAttribute("xlink:href");break}s=na(""+c),t.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",s);break;case"contentEditable":case"spellCheck":case"draggable":case"value":case"autoReverse":case"externalResourcesRequired":case"focusable":case"preserveAlpha":c!=null&&typeof c!="function"&&typeof c!="symbol"?t.setAttribute(s,""+c):t.removeAttribute(s);break;case"inert":case"allowFullScreen":case"async":case"autoPlay":case"controls":case"default":case"defer":case"disabled":case"disablePictureInPicture":case"disableRemotePlayback":case"formNoValidate":case"hidden":case"loop":case"noModule":case"noValidate":case"open":case"playsInline":case"readOnly":case"required":case"reversed":case"scoped":case"seamless":case"itemScope":c&&typeof c!="function"&&typeof c!="symbol"?t.setAttribute(s,""):t.removeAttribute(s);break;case"capture":case"download":c===!0?t.setAttribute(s,""):c!==!1&&c!=null&&typeof c!="function"&&typeof c!="symbol"?t.setAttribute(s,c):t.removeAttribute(s);break;case"cols":case"rows":case"size":case"span":c!=null&&typeof c!="function"&&typeof c!="symbol"&&!isNaN(c)&&1<=c?t.setAttribute(s,c):t.removeAttribute(s);break;case"rowSpan":case"start":c==null||typeof c=="function"||typeof c=="symbol"||isNaN(c)?t.removeAttribute(s):t.setAttribute(s,c);break;case"popover":nt("beforetoggle",t),nt("toggle",t),Mn(t,"popover",c);break;case"xlinkActuate":dn(t,"http://www.w3.org/1999/xlink","xlink:actuate",c);break;case"xlinkArcrole":dn(t,"http://www.w3.org/1999/xlink","xlink:arcrole",c);break;case"xlinkRole":dn(t,"http://www.w3.org/1999/xlink","xlink:role",c);break;case"xlinkShow":dn(t,"http://www.w3.org/1999/xlink","xlink:show",c);break;case"xlinkTitle":dn(t,"http://www.w3.org/1999/xlink","xlink:title",c);break;case"xlinkType":dn(t,"http://www.w3.org/1999/xlink","xlink:type",c);break;case"xmlBase":dn(t,"http://www.w3.org/XML/1998/namespace","xml:base",c);break;case"xmlLang":dn(t,"http://www.w3.org/XML/1998/namespace","xml:lang",c);break;case"xmlSpace":dn(t,"http://www.w3.org/XML/1998/namespace","xml:space",c);break;case"is":Mn(t,"is",c);break;case"innerText":case"textContent":break;default:(!(2<s.length)||s[0]!=="o"&&s[0]!=="O"||s[1]!=="n"&&s[1]!=="N")&&(s=uf.get(s)||s,Mn(t,s,c))}}function rg(t,n,s,c,h,p){switch(s){case"style":Sc(t,c,p);break;case"dangerouslySetInnerHTML":if(c!=null){if(typeof c!="object"||!("__html"in c))throw Error(r(61));if(s=c.__html,s!=null){if(h.children!=null)throw Error(r(60));t.innerHTML=s}}break;case"children":typeof c=="string"?Hr(t,c):(typeof c=="number"||typeof c=="bigint")&&Hr(t,""+c);break;case"onScroll":c!=null&&nt("scroll",t);break;case"onScrollEnd":c!=null&&nt("scrollend",t);break;case"onClick":c!=null&&(t.onclick=Aa);break;case"suppressContentEditableWarning":case"suppressHydrationWarning":case"inne Line truncated
`).forEach(function(u){i=u.indexOf(":"),a=u.substring(0,i).trim().toLowerCase(),r=u.substring(i+1).trim(),!(!a||e[a]&&Cw[a])&&(a==="set-cookie"?e[a]?e[a].push(r):e[a]=[r]:e[a]=e[a]?e[a]+", "+r:r)}),e};function _w(o){let e=0,a=o.length;for(;e<a;){const r=o.charCodeAt(e);if(r!==9&&r!==32)break;e+=1}for(;a>e;){const r=o.charCodeAt(a-1);if(r!==9&&r!==32)break;a-=1}return e===0&&a===o.length?o:o.slice(e,a)}const Aw=new RegExp("[\\u0000-\\u0008\\u000a-\\u001f\\u007f]+","g"),xw=new RegExp("[^\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+","g");function nd(o,e){return F.isArray(o)?o.map(a=>nd(a,e)):_w(String(o).replace(e,""))}const Tw=o=>nd(o,Aw),Rw=o=>nd(o,xw);function np(o){const e=Object.create(null);return F.forEach(o.toJSON(),(a,r)=>{e[r]=Rw(a)}),e}const ap=Symbol("internals");function Qs(o){return o&&String(o).trim().toLowerCase()}function Ll(o){return o===!1||o==null?o:F.isArray(o)?o.map(Ll):Tw(String(o))}function kw(o){const e=Object.create(null),a=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=a.exec(o);)e[r[1]]=r[2];return e}const Dw=o=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(o.trim());function ad(o,e,a,r,i){if(F.isFunction(r))return r.call(this,e,a);if(i&&(e=a),!!F.isString(e)){if(F.isString(r))return e.indexOf(r)!==-1;if(F.isRegExp(r))return r.test(e)}}function Ow(o){return o.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(e,a,r)=>a.toUpperCase()+r)}function Lw(o,e){const a=F.toCamelCase(" "+e);["get","set","has"].forEach(r=>{Object.defineProperty(o,r+a,{__proto__:null,value:function(i,l,u){return this[r].call(this,e,i,l,u)},configurable:!0})})}let Cn=class{constructor(e){e&&this.set(e)}set(e,a,r){const i=this;function l(d,f,g){const m=Qs(f);if(!m)throw new Error("header name must be a non-empty string");const b=F.findKey(i,m);(!b||i[b]===void 0||g===!0||g===void 0&&i[b]!==!1)&&(i[b||f]=Ll(d))}const u=(d,f)=>F.forEach(d,(g,m)=>l(g,m,f));if(F.isPlainObject(e)||e instanceof this.constructor)u(e,a);else if(F.isString(e)&&(e=e.trim())&&!Dw(e))u(Ew(e),a);else if(F.isObject(e)&&F.isIterable(e)){let d={},f,g;for(const m of e){if(!F.isArray(m))throw TypeError("Object iterator must return a key-value pair");d[g=m[0]]=(f=d[g])?F.isArray(f)?[...f,m[1]]:[f,m[1]]:m[1]}u(d,a)}else e!=null&&l(a,e,r);return this}get(e,a){if(e=Qs(e),e){const r=F.findKey(this,e);if(r){const i=this[r];if(!a)return i;if(a===!0)return kw(i);if(F.isFunction(a))return a.call(this,i,r);if(F.isRegExp(a))return a.exec(i);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,a){if(e=Qs(e),e){const r=F.findKey(this,e);return!!(r&&this[r]!==void 0&&(!a||ad(this,this[r],r,a)))}return!1}delete(e,a){const r=this;let i=!1;function l(u){if(u=Qs(u),u){const d=F.findKey(r,u);d&&(!a||ad(r,r[d],d,a))&&(delete r[d],i=!0)}}return F.isArray(e)?e.forEach(l):l(e),i}clear(e){const a=Object.keys(this);let r=a.length,i=!1;for(;r--;){const l=a[r];(!e||ad(this,this[l],l,e,!0))&&(delete this[l],i=!0)}return i}normalize(e){const a=this,r={};return F.forEach(this,(i,l)=>{const u=F.findKey(r,l);if(u){a[u]=Ll(i),delete a[l];return}const d=e?Ow(l):String(l).trim();d!==l&&delete a[l],a[d]=Ll(i),r[d]=!0}),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const a=Object.create(null);return F.forEach(this,(r,i)=>{r!=null&&r!==!1&&(a[i]=e&&F.isArray(r)?r.join(", "):r)}),a}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([e,a])=>e+": "+a).join(`
`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...a){const r=new this(e);return a.forEach(i=>r.set(i)),r}static accessor(e){const r=(this[ap]=this[ap]={accessors:{}}).accessors,i=this.prototype;function l(u){const d=Qs(u);r[d]||(Lw(i,u),r[d]=!0)}return F.isArray(e)?e.forEach(l):l(e),this}};Cn.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),F.reduceDescriptors(Cn.prototype,({value:o},e)=>{let a=e[0].toUpperCase()+e.slice(1);return{get:()=>o,set(r){this[a]=r}}}),F.freezeMethods(Cn);const Mw="[REDACTED ****]";function $w(o){if(F.hasOwnProp(o,"toJSON"))return!0;let e=Object.getPrototypeOf(o);for(;e&&e!==Object.prototype;){if(F.hasOwnProp(e,"toJSON"))return!0;e=Object.getPrototypeOf(e)}return!1}function Nw(o,e){const a=new Set(e.map(l=>String(l).toLowerCase())),r=[],i=l=>{if(l===null||typeof l!="object"||F.isBuffer(l))return l;if(r.indexOf(l)!==-1)return;l instanceof Cn&&(l=l.toJSON()),r.push(l);let u;if(F.isArray(l))u=[],l.forEach((d,f)=>{const g=i(d);F.isUndefined(g)||(u[f]=g)});else{if(!F.isPlainObject(l)&&$w(l))return r.pop(),l;u=Object.create(null);for(const[d,f]of Object.entries(l)){const g=a.has(d.toLowerCase())?Mw:i(f);F.isUndefined(g)||(u[d]=g)}}return r.pop(),u};return i(o)}let Le=class lS extends Error{static from(e,a,r,i,l,u){const d=new lS(e.message,a||e.code,r,i,l);return d.cause=e,d.name=e.name,e.status!=null&&d.status==null&&(d.status=e.status),u&&Object.assign(d,u),d}constructor(e,a,r,i,l){super(e),Object.defineProperty(this,"message",{__proto__:null,value:e,enumerable:!0,writable:!0,configurable:!0}),this.name="AxiosError",this.isAxiosError=!0,a&&(this.code=a),r&&(this.config=r),i&&(this.request=i),l&&(this.response=l,this.status=l.status)}toJSON(){const e=this.config,a=e&&F.hasOwnProp(e,"redact")?e.redact:void 0,r=F.isArray(a)&&a.length>0?Nw(e,a):F.toJSONObject(e);return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:r,code:this.code,status:this.status}}};Le.ERR_BAD_OPTION_VALUE="ERR_BAD_OPTION_VALUE",Le.ERR_BAD_OPTION="ERR_BAD_OPTION",Le.ECONNABORTED="ECONNABORTED",Le.ETIMEDOUT="ETIMEDOUT",Le.ECONNREFUSED="ECONNREFUSED",Le.ERR_NETWORK="ERR_NETWORK",Le.ERR_FR_TOO_MANY_REDIRECTS="ERR_FR_TOO_MANY_REDIRECTS",Le.ERR_DEPRECATED="ERR_DEPRECATED",Le.ERR_BAD_RESPONSE="ERR_BAD_RESPONSE",Le.ERR_BAD_REQUEST="ERR_BAD_REQUEST",Le.ERR_CANCELED="ERR_CANCELED",Le.ERR_NOT_SUPPORT="ERR_NOT_SUPPORT",Le.ERR_INVALID_URL="ERR_INVALID_URL",Le.ERR_FORM_DATA_DEPTH_EXCEEDED="ERR_FORM_DATA_DEPTH_EXCEEDED";const Hw=null;function rd(o){return F.isPlainObject(o)||F.isArray(o)}function rp(o){return F.endsWith(o,"[]")?o.slice(0,-2):o}function id(o,e,a){return o?o.concat(e).map(function(i,l){return i=rp(i),!a&&l?"["+i+"]":i}).join(a?".":""):e}function Iw(o){return F.isArray(o)&&!o.some(rd)}const zw=F.toFlatObject(F,{},null,function(e){return/^is[A-Z]/.test(e)});function Ml(o,e,a){if(!F.isObject(o))throw new TypeError("target must be an object");e=e||new FormData,a=F.toFlatObject(a,{metaTokens:!0,dots:!1,indexes:!1},!1,function(R,L){return!F.isUndefined(L[R])});const r=a.metaTokens,i=a.visitor||b,l=a.dots,u=a.indexes,d=a.Blob||typeof Blob<"u"&&Blob,f=a.maxDepth===void 0?100:a.maxDepth,g=d&&F.isSpecCompliantForm(e);if(!F.isFunction(i))throw new TypeError("visitor must be a function");function m(A){if(A===null)return"";if(F.isDate(A))return A.toISOString();if(F.isBoolean(A))return A.toString();if(!g&&F.isBlob(A))throw new Le("Blob is not supported. Use a Buffer instead.");return F.isArrayBuffer(A)||F.isTypedArray(A)?g&&typeof Blob=="function"?new Blob([A]):Buffer.from(A):A}function b(A,R,L){let M=A;if(F.isReactNative(e)&&F.isReactNativeBlob(A))return e.append(id(L,R,l),m(A)),!1;if(A&&!L&&typeof A=="object"){if(F.endsWith(R,"{}"))R=r?R:R.slice(0,-2),A=JSON.stringify(A);else if(F.isArray(A)&&Iw(A)||(F.isFileList(A)||F.endsWith(R,"[]"))&&(M=F.toArray(A)))return R=rp(R),M.forEach(function(D,U){!(F.isUndefined(D)||D===null)&&e.append(u===!0?id([R],U,l):u===null?R:R+"[]",m(D))}),!1}return rd(A)?!0:(e.append(id(L,R,l),m(A)),!1)}const v=[],S=Object.assign(zw,{defaultVisitor:b,convertValue:m,isVisitable:rd});function _(A,R,L=0){if(!F.isUndefined(A)){if(L>f)throw new Le("Object is too deeply nested ("+L+" levels). Max depth: "+f,Le.ERR_FORM_DATA_DEPTH_EXCEEDED);if(v.indexOf(A)!==-1)throw Error("Circular reference detected in "+R.join("."));v.push(A),F.forEach(A,function(T,D){(!(F.isUndefined(T)||T===null)&&i.call(e,T,F.isString(D)?D.trim():D,R,S))===!0&&_(T,R?R.concat(D):[D],L+1)}),v.pop()}}if(!F.isObject(o))throw new TypeError("data must be an object");return _(o),e}function ip(o){const e={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+"};return encodeURIComponent(o).replace(/[!'()~]|%20/g,function(r){return e[r]})} Line truncated
`+u.map(wp).join(`
`):" "+wp(u[0]):"as no adapter specified";throw new Le("There is no suitable adapter to dispatch the request "+d,"ERR_NOT_SUPPORT")}return i}const Cp={getAdapter:h0,adapters:fd};function hd(o){if(o.cancelToken&&o.cancelToken.throwIfRequested(),o.signal&&o.signal.aborted)throw new eo(null,o)}function Ep(o){return hd(o),o.headers=Cn.from(o.headers),o.data=ud.call(o,o.transformRequest),["post","put","patch"].indexOf(o.method)!==-1&&o.headers.setContentType("application/x-www-form-urlencoded",!1),Cp.getAdapter(o.adapter||Zs.adapter,o)(o).then(function(r){hd(o),o.response=r;try{r.data=ud.call(o,o.transformResponse,r)}finally{delete o.response}return r.headers=Cn.from(r.headers),r},function(r){if(!up(r)&&(hd(o),r&&r.response)){o.response=r.response;try{r.response.data=ud.call(o,o.transformResponse,r.response)}finally{delete o.response}r.response.headers=Cn.from(r.response.headers)}return Promise.reject(r)})}const Hl={};["object","boolean","number","function","string","symbol"].forEach((o,e)=>{Hl[o]=function(r){return typeof r===o||"a"+(e<1?"n ":" ")+o}});const _p={};Hl.transitional=function(e,a,r){function i(l,u){return"[Axios v"+dd+"] Transitional option '"+l+"'"+u+(r?". "+r:"")}return(l,u,d)=>{if(e===!1)throw new Le(i(u," has been removed"+(a?" in "+a:"")),Le.ERR_DEPRECATED);return a&&!_p[u]&&(_p[u]=!0,console.warn(i(u," has been deprecated since v"+a+" and will be removed in the near future"))),e?e(l,u,d):!0}},Hl.spelling=function(e){return(a,r)=>(console.warn(`${r} is likely a misspelling of ${e}`),!0)};function g0(o,e,a){if(typeof o!="object")throw new Le("options must be an object",Le.ERR_BAD_OPTION_VALUE);const r=Object.keys(o);let i=r.length;for(;i-- >0;){const l=r[i],u=Object.prototype.hasOwnProperty.call(e,l)?e[l]:void 0;if(u){const d=o[l],f=d===void 0||u(d,l,o);if(f!==!0)throw new Le("option "+l+" must be "+f,Le.ERR_BAD_OPTION_VALUE);continue}if(a!==!0)throw new Le("Unknown option "+l,Le.ERR_BAD_OPTION)}}const Il={assertOptions:g0,validators:Hl},Jn=Il.validators;let ui=class{constructor(e){this.defaults=e||{},this.interceptors={request:new lp,response:new lp}}async request(e,a){try{return await this._request(e,a)}catch(r){if(r instanceof Error){let i={};Error.captureStackTrace?Error.captureStackTrace(i):i=new Error;const l=(()=>{if(!i.stack)return"";const u=i.stack.indexOf(`
`);return u===-1?"":i.stack.slice(u+1)})();try{if(!r.stack)r.stack=l;else if(l){const u=l.indexOf(`
`),d=u===-1?-1:l.indexOf(`
`,u+1),f=d===-1?"":l.slice(d+1);String(r.stack).endsWith(f)||(r.stack+=`
`+l)}}catch{}}throw r}}_request(e,a){typeof e=="string"?(a=a||{},a.url=e):a=e||{},a=ci(this.defaults,a);const{transitional:r,paramsSerializer:i,headers:l}=a;r!==void 0&&Il.assertOptions(r,{silentJSONParsing:Jn.transitional(Jn.boolean),forcedJSONParsing:Jn.transitional(Jn.boolean),clarifyTimeoutError:Jn.transitional(Jn.boolean),legacyInterceptorReqResOrdering:Jn.transitional(Jn.boolean)},!1),i!=null&&(F.isFunction(i)?a.paramsSerializer={serialize:i}:Il.assertOptions(i,{encode:Jn.function,serialize:Jn.function},!0)),a.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?a.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:a.allowAbsoluteUrls=!0),Il.assertOptions(a,{baseUrl:Jn.spelling("baseURL"),withXsrfToken:Jn.spelling("withXSRFToken")},!0),a.method=(a.method||this.defaults.method||"get").toLowerCase();let u=l&&F.merge(l.common,l[a.method]);l&&F.forEach(["delete","get","head","post","put","patch","query","common"],_=>{delete l[_]}),a.headers=Cn.concat(u,l);const d=[];let f=!0;this.interceptors.request.forEach(function(A){if(typeof A.runWhen=="function"&&A.runWhen(a)===!1)return;f=f&&A.synchronous;const R=a.transitional||od;R&&R.legacyInterceptorReqResOrdering?d.unshift(A.fulfilled,A.rejected):d.push(A.fulfilled,A.rejected)});const g=[];this.interceptors.response.forEach(function(A){g.push(A.fulfilled,A.rejected)});let m,b=0,v;if(!f){const _=[Ep.bind(this),void 0];for(_.unshift(...d),_.push(...g),v=_.length,m=Promise.resolve(a);b<v;)m=m.then(_[b++],_[b++]);return m}v=d.length;let S=a;for(;b<v;){const _=d[b++],A=d[b++];try{S=_(S)}catch(R){A.call(this,R);break}}try{m=Ep.call(this,S)}catch(_){return Promise.reject(_)}for(b=0,v=g.length;b<v;)m=m.then(g[b++],g[b++]);return m}getUri(e){e=ci(this.defaults,e);const a=gp(e.baseURL,e.url,e.allowAbsoluteUrls);return op(a,e.params,e.paramsSerializer)}};F.forEach(["delete","get","head","options"],function(e){ui.prototype[e]=function(a,r){return this.request(ci(r||{},{method:e,url:a,data:(r||{}).data}))}}),F.forEach(["post","put","patch","query"],function(e){function a(r){return function(l,u,d){return this.request(ci(d||{},{method:e,headers:r?{"Content-Type":"multipart/form-data"}:{},url:l,data:u}))}}ui.prototype[e]=a(),e!=="query"&&(ui.prototype[e+"Form"]=a(!0))});let p0=class cS{constructor(e){if(typeof e!="function")throw new TypeError("executor must be a function.");let a;this.promise=new Promise(function(l){a=l});const r=this;this.promise.then(i=>{if(!r._listeners)return;let l=r._listeners.length;for(;l-- >0;)r._listeners[l](i);r._listeners=null}),this.promise.then=i=>{let l;const u=new Promise(d=>{r.subscribe(d),l=d}).then(i);return u.cancel=function(){r.unsubscribe(l)},u},e(function(l,u,d){r.reason||(r.reason=new eo(l,u,d),a(r.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const a=this._listeners.indexOf(e);a!==-1&&this._listeners.splice(a,1)}toAbortSignal(){const e=new AbortController,a=r=>{e.abort(r)};return this.subscribe(a),e.signal.unsubscribe=()=>this.unsubscribe(a),e.signal}static source(){let e;return{token:new cS(function(i){e=i}),cancel:e}}};function m0(o){return function(a){return o.apply(null,a)}}function y0(o){return F.isObject(o)&&o.isAxiosError===!0}const gd={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(gd).forEach(([o,e])=>{gd[e]=o});function Ap(o){const e=new ui(o),a=Fg(ui.prototype.request,e);return F.extend(a,ui.prototype,e,{allOwnKeys:!0}),F.extend(a,e,null,{allOwnKeys:!0}),a.create=function(i){return Ap(ci(o,i))},a}const qt=Ap(Zs);qt.Axios=ui,qt.CanceledError=eo,qt.CancelToken=p0,qt.isCa Line truncated
position: fixed;
inset: 0;
background-color: rgba(0, 0, 0, 0.5);
@@ -84,11 +47,11 @@ Error generating stack: `+c.message+`
justify-content: center;
color: #666;
transition: background-color 0.2s;
`,i.onmouseenter=()=>{i.style.backgroundColor="rgba(0, 0, 0, 0.2)"},i.onmouseleave=()=>{i.style.backgroundColor="rgba(0, 0, 0, 0.1)"};const o=()=>{a.parentNode&&a.parentNode.removeChild(a)};i.onclick=o;const u=d=>{this.isImeComposing(d)||d.key==="Escape"&&(o(),document.removeEventListener("keydown",u))};return document.addEventListener("keydown",u),a.onclick=d=>{d.target===a&&o()},r.appendChild(i),a.appendChild(r),document.body.appendChild(a),{overlay:a,layer:r,closeLayer:o}}getNestedProperty(e,a){return a.split(".").reduce((r,i)=>r&&r[i]!==void 0?r[i]:void 0,e)}async handleSaveToLocalStorage(e,a){const{key:r,value:i}=e;if(!r)return z.error("saveToLocalStorage: key parameter is required"),!1;try{const o=typeof i=="string"?i:JSON.stringify(i);return localStorage.setItem(r,o),z.log(`saveToLocalStorage: saved ${r}`,i),!0}catch(o){return z.error("saveToLocalStorage: failed to save",{key:r,error:o}),!1}}async handleLoadFromLocalStorage(e,a){const{key:r,target:i,stateKey:o,defaultValue:u}=e;if(!r)return z.error("loadFromLocalStorage: key parameter is required"),u;try{const d=localStorage.getItem(r);if(d===null)return z.log(`loadFromLocalStorage: no value found for ${r}, using default`),o&&a.setState&&a.setState({[o]:u}),u;let f;try{f=JSON.parse(d)}catch{f=d}return z.log(`loadFromLocalStorage: loaded ${r}`,f),o&&a.setState&&a.setState({[o]:f}),f}catch(d){return z.error("loadFromLocalStorage: failed to load",{key:r,error:d}),u}}async handleCustomAction(e,a){const r=this.customHandlers.get(e.handler);if(!r){if(this.previewMode){z.warn(`[Preview] Unknown action handler "${e.handler}" — skipped (preview mode)`);return}throw new Mt(`Unknown action handler: ${e.handler}`,e)}return await r(e,a)}resolveParams(e,a){if(!e)return{};const r={};for(const[i,o]of Object.entries(e))i.includes("{{")&&z.warn(`[resolveParams] setState params의 키에 표현식이 포함되어 있습니다: "${i}". 키는 해석되지 않습니다. 배열 항목 수정은 .map()/.filter() 패턴을 사용하세요.`),typeof o=="string"&&o.includes("{{")?r[i]=this.evaluateExpression(o,a):typeof o=="string"?r[i]=o:Array.isArray(o)?r[i]=o.map(u=>typeof u=="string"&&u.includes("{{")?this.evaluateExpression(u,a):u):typeof o=="object"&&o!==null&&!Array.isArray(o)&&Object.getPrototypeOf(o)!==Object.prototype&&Object.getPrototypeOf(o)!==null?r[i]=o:typeof o=="object"&&o!==null?r[i]=this.resolveParams(o,a):r[i]=o;return r}resolveValue(e,a){return a?this.bindingEngine.resolveBindings(e,a,{skipCache:!0}):e}evaluateExpressions(e,a){let r={};for(const[i,o]of Object.entries(e))if(i==="..."){let u=o;typeof o=="string"&&o.includes("{{")&&(u=this.evaluateExpression(o,a)),u&&typeof u=="object"&&!Array.isArray(u)&&(r={...r,...u})}else typeof o=="string"&&o.includes("{{")?r[i]=this.evaluateExpression(o,a):typeof o=="object"&&o!==null&&!Array.isArray(o)?r[i]=this.evaluateExpressions(o,a):r[i]=o;return r}evaluateExpressionsIfNeeded(e,a){const r={};for(const[i,o]of Object.entries(e))typeof o=="string"&&o.includes("{{")?r[i]=this.evaluateExpression(o,a):r[i]=o;return r}evaluateExpression(e,a){if(!a)return e;const r=e.match(/^\{\{(.+)\}\}$/);if(!(r&&!r[1].includes("}}")&&!r[1].includes("{{"))){let d=a;if(e.includes("_global")){const g=window.G7Core?.state?.get()?._global;g&&(d={...a,_global:g})}if(e.includes("_computed")||e.includes("$computed")){const g=window.__g7ActionContext?.computedRef?.current;g&&Object.keys(g).length>0&&(d={...d,_computed:g,$computed:g})}return this.bindingEngine.resolveBindings(e,d,{skipCache:!0})}let o=r[1].trim();o=o.replace(/\$args\.(\d+)/g,"$args[$1]");let u=a;if(o.includes("_global")){const f=window.G7Core?.state?.get()?._global;f&&(u={...a,_global:f})}if(o.includes("_computed")||o.includes("$computed")){const f=window.__g7ActionContext?.computedRef?.current;f&&Object.keys(f).length>0&&(u={...u,_computed:f,$computed:f})}o.includes("_global.modules")&&(z.log("[evaluateExpression] expression:",o),z.log("[evaluateExpression] dataContext._global:",u._global),z.log("[evaluateExpression] dataContext._global?.modules:",u._global?.modules));try{const d=this.bindingEngine.evaluateExpression(o,u);return o.includes("_global.modules")&&z.log("[evaluateExpression] result:",d),typeof d=="string"&&d.startsWith("$t:")&&this.translationEngine&&this.translationContext?this.translationEngine.resolveTranslations(d,this.translationContext,a):d}catch(d){return z.error("Expression evaluation failed:",e,d),e}}setDefaultContext(e){this.defaultContext={...this.defaultContext,...e}}setGlobalStateUpdater(e){this.globalStateUpdater=e}getGlobalStateUpdater(){return this.globalStateUpdater}async dispatchAction(e,a){const r={...this.defaultContext,...a,data:{...this.defaultContext.data,...a?.data}};if(e.confirm){let i=this.resolveValue(e.confirm,r.data);if(this.translationEngine&&this.translationContext&&i.startsWith("$t:")&&(i=this.translationEngine.resolveTranslations(i,this.translationContext,r.data)),!confirm(i))return{success:!1}}try{return await this.executeActi Line truncated
`,i.onmouseenter=()=>{i.style.backgroundColor="rgba(0, 0, 0, 0.2)"},i.onmouseleave=()=>{i.style.backgroundColor="rgba(0, 0, 0, 0.1)"};const l=()=>{a.parentNode&&a.parentNode.removeChild(a)};i.onclick=l;const u=d=>{this.isImeComposing(d)||d.key==="Escape"&&(l(),document.removeEventListener("keydown",u))};return document.addEventListener("keydown",u),a.onclick=d=>{d.target===a&&l()},r.appendChild(i),a.appendChild(r),document.body.appendChild(a),{overlay:a,layer:r,closeLayer:l}}getNestedProperty(e,a){return a.split(".").reduce((r,i)=>r&&r[i]!==void 0?r[i]:void 0,e)}async handleSaveToLocalStorage(e,a){const{key:r,value:i}=e;if(!r)return I.error("saveToLocalStorage: key parameter is required"),!1;try{const l=typeof i=="string"?i:JSON.stringify(i);return localStorage.setItem(r,l),I.log(`saveToLocalStorage: saved ${r}`,i),!0}catch(l){return I.error("saveToLocalStorage: failed to save",{key:r,error:l}),!1}}async handleLoadFromLocalStorage(e,a){const{key:r,target:i,stateKey:l,defaultValue:u}=e;if(!r)return I.error("loadFromLocalStorage: key parameter is required"),u;try{const d=localStorage.getItem(r);if(d===null)return I.log(`loadFromLocalStorage: no value found for ${r}, using default`),l&&a.setState&&a.setState({[l]:u}),u;let f;try{f=JSON.parse(d)}catch{f=d}return I.log(`loadFromLocalStorage: loaded ${r}`,f),l&&a.setState&&a.setState({[l]:f}),f}catch(d){return I.error("loadFromLocalStorage: failed to load",{key:r,error:d}),u}}async handleCustomAction(e,a){const r=this.customHandlers.get(e.handler);if(!r){if(this.previewMode){I.warn(`[Preview] Unknown action handler "${e.handler}" — skipped (preview mode)`);return}throw new Nt(`Unknown action handler: ${e.handler}`,e)}return await r(e,a)}resolveParams(e,a){if(!e)return{};const r={};for(const[i,l]of Object.entries(e))i.includes("{{")&&I.warn(`[resolveParams] setState params의 키에 표현식이 포함되어 있습니다: "${i}". 키는 해석되지 않습니다. 배열 항목 수정은 .map()/.filter() 패턴을 사용하세요.`),typeof l=="string"&&l.includes("{{")?r[i]=this.evaluateExpression(l,a):typeof l=="string"?r[i]=l:Array.isArray(l)?r[i]=l.map(u=>typeof u=="string"&&u.includes("{{")?this.evaluateExpression(u,a):u):typeof l=="object"&&l!==null&&!Array.isArray(l)&&Object.getPrototypeOf(l)!==Object.prototype&&Object.getPrototypeOf(l)!==null?r[i]=l:typeof l=="object"&&l!==null?r[i]=this.resolveParams(l,a):r[i]=l;return r}resolveValue(e,a){return a?this.bindingEngine.resolveBindings(e,a,{skipCache:!0}):e}evaluateExpressions(e,a){let r={};for(const[i,l]of Object.entries(e))if(i==="..."){let u=l;typeof l=="string"&&l.includes("{{")&&(u=this.evaluateExpression(l,a)),u&&typeof u=="object"&&!Array.isArray(u)&&(r={...r,...u})}else typeof l=="string"&&l.includes("{{")?r[i]=this.evaluateExpression(l,a):typeof l=="object"&&l!==null&&!Array.isArray(l)?r[i]=this.evaluateExpressions(l,a):r[i]=l;return r}evaluateExpressionsIfNeeded(e,a){const r={};for(const[i,l]of Object.entries(e))typeof l=="string"&&l.includes("{{")?r[i]=this.evaluateExpression(l,a):r[i]=l;return r}evaluateExpression(e,a){if(!a)return e;const r=e.match(/^\{\{(.+)\}\}$/);if(!(r&&!r[1].includes("}}")&&!r[1].includes("{{"))){let d=a;if(e.includes("_global")){const g=window.G7Core?.state?.get()?._global;g&&(d={...a,_global:g})}if(e.includes("_computed")||e.includes("$computed")){const g=window.__g7ActionContext?.computedRef?.current;g&&Object.keys(g).length>0&&(d={...d,_computed:g,$computed:g})}return this.bindingEngine.resolveBindings(e,d,{skipCache:!0})}let l=r[1].trim();l=l.replace(/\$args\.(\d+)/g,"$args[$1]");let u=a;if(l.includes("_global")){const f=window.G7Core?.state?.get()?._global;f&&(u={...a,_global:f})}if(l.includes("_computed")||l.includes("$computed")){const f=window.__g7ActionContext?.computedRef?.current;f&&Object.keys(f).length>0&&(u={...u,_computed:f,$computed:f})}l.includes("_global.modules")&&(I.log("[evaluateExpression] expression:",l),I.log("[evaluateExpression] dataContext._global:",u._global),I.log("[evaluateExpression] dataContext._global?.modules:",u._global?.modules));try{const d=this.bindingEngine.evaluateExpression(l,u);return l.includes("_global.modules")&&I.log("[evaluateExpression] result:",d),typeof d=="string"&&d.startsWith("$t:")&&this.translationEngine&&this.translationContext?this.translationEngine.resolveTranslations(d,this.translationContext,a):d}catch(d){return I.error("Expression evaluation failed:",e,d),e}}setDefaultContext(e){this.defaultContext={...this.defaultContext,...e}}setGlobalStateUpdater(e){this.globalStateUpdater=e}getGlobalStateUpdater(){return this.globalStateUpdater}async dispatchAction(e,a){const r={...this.defaultContext,...a,data:{...this.defaultContext.data,...a?.data}};if(e.confirm){let i=this.resolveValue(e.confirm,r.data);if(this.translationEngine&&this.translationContext&&i.startsWith("$t:")&&(i=this.translationEngine.resolveTranslations(i,this.translationContext,r.data)),!confirm(i))return{success:!1}}try{return await this.executeActi Line truncated
To pick up a draggable item, press the space bar.
While dragging, use the arrow keys to move the item.
Press space again to drop the item in its new position, or press escape to cancel.
`},M0={onDragStart(l){let{active:e}=l;return"Picked up draggable item "+e.id+"."},onDragOver(l){let{active:e,over:a}=l;return a?"Draggable item "+e.id+" was moved over droppable area "+a.id+".":"Draggable item "+e.id+" is no longer over a droppable area."},onDragEnd(l){let{active:e,over:a}=l;return a?"Draggable item "+e.id+" was dropped over droppable area "+a.id:"Draggable item "+e.id+" was dropped."},onDragCancel(l){let{active:e}=l;return"Dragging was cancelled. Draggable item "+e.id+" was dropped."}};function $0(l){let{announcements:e=M0,container:a,hiddenTextDescribedById:r,screenReaderInstructions:i=L0}=l;const{announce:o,announcement:u}=R0(),d=lo("DndLiveRegion"),[f,g]=N.useState(!1);if(N.useEffect(()=>{g(!0)},[]),D0(N.useMemo(()=>({onDragStart(b){let{active:v}=b;o(e.onDragStart({active:v}))},onDragMove(b){let{active:v,over:E}=b;e.onDragMove&&o(e.onDragMove({active:v,over:E}))},onDragOver(b){let{active:v,over:E}=b;o(e.onDragOver({active:v,over:E}))},onDragEnd(b){let{active:v,over:E}=b;o(e.onDragEnd({active:v,over:E}))},onDragCancel(b){let{active:v,over:E}=b;o(e.onDragCancel({active:v,over:E}))}}),[o,e])),!f)return null;const m=We.createElement(We.Fragment,null,We.createElement(T0,{id:r,value:i.draggable}),We.createElement(k0,{id:d,announcement:u}));return a?Ar.createPortal(m,a):m}var Zt;(function(l){l.DragStart="dragStart",l.DragMove="dragMove",l.DragEnd="dragEnd",l.DragCancel="dragCancel",l.DragOver="dragOver",l.RegisterDroppable="registerDroppable",l.SetDroppableDisabled="setDroppableDisabled",l.UnregisterDroppable="unregisterDroppable"})(Zt||(Zt={}));function ec(){}function jp(l,e){return N.useMemo(()=>({sensor:l,options:e??{}}),[l,e])}function N0(){for(var l=arguments.length,e=new Array(l),a=0;a<l;a++)e[a]=arguments[a];return N.useMemo(()=>[...e].filter(r=>r!=null),[...e])}const ya=Object.freeze({x:0,y:0});function Up(l,e){return Math.sqrt(Math.pow(l.x-e.x,2)+Math.pow(l.y-e.y,2))}function Bp(l,e){let{data:{value:a}}=l,{data:{value:r}}=e;return a-r}function H0(l,e){let{data:{value:a}}=l,{data:{value:r}}=e;return r-a}function qp(l){let{left:e,top:a,height:r,width:i}=l;return[{x:e,y:a},{x:e+i,y:a},{x:e,y:a+r},{x:e+i,y:a+r}]}function Pp(l,e){if(!l||l.length===0)return null;const[a]=l;return a[e]}function Gp(l,e,a){return e===void 0&&(e=l.left),a===void 0&&(a=l.top),{x:e+l.width*.5,y:a+l.height*.5}}const z0=l=>{let{collisionRect:e,droppableRects:a,droppableContainers:r}=l;const i=Gp(e,e.left,e.top),o=[];for(const u of r){const{id:d}=u,f=a.get(d);if(f){const g=Up(Gp(f),i);o.push({id:d,data:{droppableContainer:u,value:g}})}}return o.sort(Bp)},I0=l=>{let{collisionRect:e,droppableRects:a,droppableContainers:r}=l;const i=qp(e),o=[];for(const u of r){const{id:d}=u,f=a.get(d);if(f){const g=qp(f),m=i.reduce((v,E,S)=>v+Up(g[S],E),0),b=Number((m/4).toFixed(4));o.push({id:d,data:{droppableContainer:u,value:b}})}}return o.sort(Bp)};function j0(l,e){const a=Math.max(e.top,l.top),r=Math.max(e.left,l.left),i=Math.min(e.left+e.width,l.left+l.width),o=Math.min(e.top+e.height,l.top+l.height),u=i-r,d=o-a;if(r<i&&a<o){const f=e.width*e.height,g=l.width*l.height,m=u*d,b=m/(f+g-m);return Number(b.toFixed(4))}return 0}const U0=l=>{let{collisionRect:e,droppableRects:a,droppableContainers:r}=l;const i=[];for(const o of r){const{id:u}=o,d=a.get(u);if(d){const f=j0(d,e);f>0&&i.push({id:u,data:{droppableContainer:o,value:f}})}}return i.sort(H0)};function B0(l,e,a){return{...l,scaleX:e&&a?e.width/a.width:1,scaleY:e&&a?e.height/a.height:1}}function Vp(l,e){return l&&e?{x:l.left-e.left,y:l.top-e.top}:ya}function q0(l){return function(a){for(var r=arguments.length,i=new Array(r>1?r-1:0),o=1;o<r;o++)i[o-1]=arguments[o];return i.reduce((u,d)=>({...u,top:u.top+l*d.y,bottom:u.bottom+l*d.y,left:u.left+l*d.x,right:u.right+l*d.x}),{...a})}}const P0=q0(1);function G0(l){if(l.startsWith("matrix3d(")){const e=l.slice(9,-1).split(/, /);return{x:+e[12],y:+e[13],scaleX:+e[0],scaleY:+e[5]}}else if(l.startsWith("matrix(")){const e=l.slice(7,-1).split(/, /);return{x:+e[4],y:+e[5],scaleX:+e[0],scaleY:+e[3]}}return null}function V0(l,e,a){const r=G0(e);if(!r)return l;const{scaleX:i,scaleY:o,x:u,y:d}=r,f=l.left-u-(1-i)*parseFloat(a),g=l.top-d-(1-o)*parseFloat(a.slice(a.indexOf(" ")+1)),m=i?l.width/i:l.width,b=o?l.height/o:l.height;return{width:m,height:b,top:g,right:f+m,bottom:g+b,left:f}}const F0={ignoreTransform:!1};function Qi(l,e){e===void 0&&(e=F0);let a=l.getBoundingClientRect();if(e.ignoreTransform){const{transform:g,transformOrigin:m}=Tn(l).getComputedStyle(l);g&&(a=V0(a,g,m))}const{top:r,left:i,width:o,height:u,bottom:d,right:f}=a;return{top:r,left:i,width:o,height:u,bottom:d,right:f}}function Fp(l){return Qi(l,{ignoreTransform:!0})}function K0(l){const e=l.innerWidth,a=l.innerHeight;return{top:0,left:0,right:e,bottom:a,width:e,height:a}}function W0(l,e){return e===void 0&&(e=Tn(l).getComputedStyle(l)),e.position==="fixed"}function Y0(l,e){e===void 0&&(e=Tn(l).getComputedStyle(l));const a=/(auto|scroll|overlay)/;return["overflow","overflowX Line truncated
`},tC={onDragStart(o){let{active:e}=o;return"Picked up draggable item "+e.id+"."},onDragOver(o){let{active:e,over:a}=o;return a?"Draggable item "+e.id+" was moved over droppable area "+a.id+".":"Draggable item "+e.id+" is no longer over a droppable area."},onDragEnd(o){let{active:e,over:a}=o;return a?"Draggable item "+e.id+" was dropped over droppable area "+a.id:"Draggable item "+e.id+" was dropped."},onDragCancel(o){let{active:e}=o;return"Dragging was cancelled. Draggable item "+e.id+" was dropped."}};function nC(o){let{announcements:e=tC,container:a,hiddenTextDescribedById:r,screenReaderInstructions:i=eC}=o;const{announce:l,announcement:u}=J0(),d=oo("DndLiveRegion"),[f,g]=N.useState(!1);if(N.useEffect(()=>{g(!0)},[]),Q0(N.useMemo(()=>({onDragStart(b){let{active:v}=b;l(e.onDragStart({active:v}))},onDragMove(b){let{active:v,over:S}=b;e.onDragMove&&l(e.onDragMove({active:v,over:S}))},onDragOver(b){let{active:v,over:S}=b;l(e.onDragOver({active:v,over:S}))},onDragEnd(b){let{active:v,over:S}=b;l(e.onDragEnd({active:v,over:S}))},onDragCancel(b){let{active:v,over:S}=b;l(e.onDragCancel({active:v,over:S}))}}),[l,e])),!f)return null;const m=Ye.createElement(Ye.Fragment,null,Ye.createElement(Y0,{id:r,value:i.draggable}),Ye.createElement(X0,{id:d,announcement:u}));return a?Er.createPortal(m,a):m}var Zt;(function(o){o.DragStart="dragStart",o.DragMove="dragMove",o.DragEnd="dragEnd",o.DragCancel="dragCancel",o.DragOver="dragOver",o.RegisterDroppable="registerDroppable",o.SetDroppableDisabled="setDroppableDisabled",o.UnregisterDroppable="unregisterDroppable"})(Zt||(Zt={}));function Fl(){}function Vp(o,e){return N.useMemo(()=>({sensor:o,options:e??{}}),[o,e])}function aC(){for(var o=arguments.length,e=new Array(o),a=0;a<o;a++)e[a]=arguments[a];return N.useMemo(()=>[...e].filter(r=>r!=null),[...e])}const ma=Object.freeze({x:0,y:0});function Fp(o,e){return Math.sqrt(Math.pow(o.x-e.x,2)+Math.pow(o.y-e.y,2))}function Kp(o,e){let{data:{value:a}}=o,{data:{value:r}}=e;return a-r}function rC(o,e){let{data:{value:a}}=o,{data:{value:r}}=e;return r-a}function Wp(o){let{left:e,top:a,height:r,width:i}=o;return[{x:e,y:a},{x:e+i,y:a},{x:e,y:a+r},{x:e+i,y:a+r}]}function Yp(o,e){if(!o||o.length===0)return null;const[a]=o;return a[e]}function Xp(o,e,a){return e===void 0&&(e=o.left),a===void 0&&(a=o.top),{x:e+o.width*.5,y:a+o.height*.5}}const iC=o=>{let{collisionRect:e,droppableRects:a,droppableContainers:r}=o;const i=Xp(e,e.left,e.top),l=[];for(const u of r){const{id:d}=u,f=a.get(d);if(f){const g=Fp(Xp(f),i);l.push({id:d,data:{droppableContainer:u,value:g}})}}return l.sort(Kp)},sC=o=>{let{collisionRect:e,droppableRects:a,droppableContainers:r}=o;const i=Wp(e),l=[];for(const u of r){const{id:d}=u,f=a.get(d);if(f){const g=Wp(f),m=i.reduce((v,S,_)=>v+Fp(g[_],S),0),b=Number((m/4).toFixed(4));l.push({id:d,data:{droppableContainer:u,value:b}})}}return l.sort(Kp)};function oC(o,e){const a=Math.max(e.top,o.top),r=Math.max(e.left,o.left),i=Math.min(e.left+e.width,o.left+o.width),l=Math.min(e.top+e.height,o.top+o.height),u=i-r,d=l-a;if(r<i&&a<l){const f=e.width*e.height,g=o.width*o.height,m=u*d,b=m/(f+g-m);return Number(b.toFixed(4))}return 0}const lC=o=>{let{collisionRect:e,droppableRects:a,droppableContainers:r}=o;const i=[];for(const l of r){const{id:u}=l,d=a.get(u);if(d){const f=oC(d,e);f>0&&i.push({id:u,data:{droppableContainer:l,value:f}})}}return i.sort(rC)};function cC(o,e,a){return{...o,scaleX:e&&a?e.width/a.width:1,scaleY:e&&a?e.height/a.height:1}}function Jp(o,e){return o&&e?{x:o.left-e.left,y:o.top-e.top}:ma}function uC(o){return function(a){for(var r=arguments.length,i=new Array(r>1?r-1:0),l=1;l<r;l++)i[l-1]=arguments[l];return i.reduce((u,d)=>({...u,top:u.top+o*d.y,bottom:u.bottom+o*d.y,left:u.left+o*d.x,right:u.right+o*d.x}),{...a})}}const dC=uC(1);function fC(o){if(o.startsWith("matrix3d(")){const e=o.slice(9,-1).split(/, /);return{x:+e[12],y:+e[13],scaleX:+e[0],scaleY:+e[5]}}else if(o.startsWith("matrix(")){const e=o.slice(7,-1).split(/, /);return{x:+e[4],y:+e[5],scaleX:+e[0],scaleY:+e[3]}}return null}function hC(o,e,a){const r=fC(e);if(!r)return o;const{scaleX:i,scaleY:l,x:u,y:d}=r,f=o.left-u-(1-i)*parseFloat(a),g=o.top-d-(1-l)*parseFloat(a.slice(a.indexOf(" ")+1)),m=i?o.width/i:o.width,b=l?o.height/l:o.height;return{width:m,height:b,top:g,right:f+m,bottom:g+b,left:f}}const gC={ignoreTransform:!1};function ts(o,e){e===void 0&&(e=gC);let a=o.getBoundingClientRect();if(e.ignoreTransform){const{transform:g,transformOrigin:m}=Tn(o).getComputedStyle(o);g&&(a=hC(a,g,m))}const{top:r,left:i,width:l,height:u,bottom:d,right:f}=a;return{top:r,left:i,width:l,height:u,bottom:d,right:f}}function Qp(o){return ts(o,{ignoreTransform:!0})}function pC(o){const e=o.innerWidth,a=o.innerHeight;return{top:0,left:0,right:e,bottom:a,width:e,height:a}}function mC(o,e){return e===void 0&&(e=Tn(o).getComputedStyle(o)),e.position==="fixed"}function yC(o,e){e===void 0&&(e=Tn(o).getComputedStyle(o));const a=/(auto|scroll|overlay)/;return["overflow","overflowX Line truncated
<div style="padding: 1rem; border: 2px dashed #ccc; background: #f9f9f9; text-align: center;">
<p style="margin: 0; color: #666;">Component not found: <strong>${e}</strong></p>
</div>
@@ -97,7 +60,7 @@ Error generating stack: `+c.message+`
<p style="margin: 0 0 0.5rem 0; color: #c62828; font-weight: bold;">Component Error: ${e}</p>
<p style="margin: 0; color: #666; font-size: 0.875rem;">${a?.message||"Unknown error"}</p>
</div>
`,r}renderErrorState(e,a){const r=a instanceof Error?a.message:String(a),i=a instanceof va?a.code:"UNKNOWN_ERROR";e.innerHTML=`
`,r}renderErrorState(e,a){const r=a instanceof Error?a.message:String(a),i=a instanceof ba?a.code:"UNKNOWN_ERROR";e.innerHTML=`
<div class="layout-error" data-error-code="${i}" style="
padding: 2rem;
text-align: center;
@@ -139,25 +102,19 @@ Error generating stack: `+c.message+`
"
>페이지 새로고침</button>
</div>
`,Un.error("Error state rendered:",i,r)}getCurrentLayout(){return this.currentLayout}clear(){this.currentLayout=null,this.layoutCache.clear(),Un.log("Layout data and cache cleared")}}const SE=dt("TranslationContext"),Bd=N.createContext(null),uc=({children:l,translationEngine:e,translationContext:a})=>{const r=N.useMemo(()=>(o,u)=>{if(u){const d="|"+Object.entries(u).map(([f,g])=>`${f}=${g}`).join("|");return e.translate(o,a,d)}return e.translate(o,a)},[e,a]),i=N.useMemo(()=>({translationEngine:e,translationContext:a,t:r}),[e,a,r]);return ct.jsx(Bd.Provider,{value:i,children:l})},vm=()=>{const l=N.useContext(Bd);return l||(SE.warn("TranslationProvider 외부에서 호출되었습니다. 키를 그대로 반환합니다."),{t:e=>e,translationEngine:null,translationContext:null})},kr=dt("SlotContext"),wE={registerToSlot:()=>{kr.warn("SlotContext not available: registerToSlot called outside SlotProvider")},unregisterFromSlot:()=>{kr.warn("SlotContext not available: unregisterFromSlot called outside SlotProvider")},getSlotComponents:()=>[],subscribeToSlot:()=>()=>{},clearAllSlots:()=>{},isEnabled:!1},CE=N.createContext(wE),qd=({children:l})=>{const e=N.useRef(new Map),a=N.useRef(new Map),r=N.useCallback(m=>{const b=a.current.get(m);b&&b.forEach(v=>{try{v()}catch(E){kr.error(`Slot subscriber error (slotId: ${m}):`,E)}})},[]),i=N.useCallback((m,b,v)=>{if(!m||!b){kr.warn("registerToSlot: slotId and componentId are required");return}e.current.has(m)||e.current.set(m,new Map);const E=e.current.get(m),S=E.get(b);S&&S.registrationKey===v.registrationKey||(E.set(b,v),kr.log(`Component registered to slot: ${b} -> ${m} (order: ${v.order})`),r(m))},[r]),o=N.useCallback((m,b)=>{const v=e.current.get(m);v&&v.has(b)&&(v.delete(b),kr.log(`Component unregistered from slot: ${b} <- ${m}`),v.size===0&&e.current.delete(m),r(m))},[r]),u=N.useCallback(m=>{const b=e.current.get(m);return b?Array.from(b.values()).sort((v,E)=>v.order-E.order):[]},[]),d=N.useCallback((m,b)=>{a.current.has(m)||a.current.set(m,new Set);const v=a.current.get(m);return v.add(b),()=>{v.delete(b),v.size===0&&a.current.delete(m)}},[]),f=N.useCallback(()=>{e.current.forEach((m,b)=>{r(b)}),e.current.clear(),a.current.clear(),kr.log("All slots cleared")},[r]),g=N.useMemo(()=>({registerToSlot:i,unregisterFromSlot:o,getSlotComponents:u,subscribeToSlot:d,clearAllSlots:f,isEnabled:!0}),[i,o,u,d,f]);return N.useLayoutEffect(()=>{typeof window<"u"&&(window.__slotContextValue=g,kr.log("SlotContext exposed to window.__slotContextValue"))},[g]),ct.jsx(CE.Provider,{value:g,children:l})};class Pd{constructor(){this.notificationCreatedEvent=".Illuminate\\Notifications\\Events\\BroadcastNotificationCreated"}listenForWhisper(e,a){return this.listen(".client-"+e,a)}notification(e){return this.listen(this.notificationCreatedEvent,e)}stopListeningForNotification(e){return this.stopListening(this.notificationCreatedEvent,e)}stopListeningForWhisper(e,a){return this.stopListening(".client-"+e,a)}}class Sm{constructor(e){this.namespace=e}format(e){return[".","\\"].includes(e.charAt(0))?e.substring(1):(this.namespace&&(e=this.namespace+"."+e),e.replace(/\./g,"\\"))}setNamespace(e){this.namespace=e}}function EE(l){try{new l}catch(e){if(e instanceof Error&&e.message.includes("is not a constructor"))return!1}return!0}class Gd extends Pd{constructor(e,a,r){super(),this.name=a,this.pusher=e,this.options=r,this.eventFormatter=new Sm(this.options.namespace),this.subscribe()}subscribe(){this.subscription=this.pusher.subscribe(this.name)}unsubscribe(){this.pusher.unsubscribe(this.name)}listen(e,a){return this.on(this.eventFormatter.format(e),a),this}listenToAll(e){return this.subscription.bind_global((a,r)=>{if(a.startsWith("pusher:"))return;let i=String(this.options.namespace??"").replace(/\./g,"\\"),o=a.startsWith(i)?a.substring(i.length+1):"."+a;e(o,r)}),this}stopListening(e,a){return a?this.subscription.unbind(this.eventFormatter.format(e),a):this.subscription.unbind(this.eventFormatter.format(e)),this}stopListeningToAll(e){return e?this.subscription.unbind_global(e):this.subscription.unbind_global(),this}subscribed(e){return this.on("pusher:subscription_succeeded",()=>{e()}),this}error(e){return this.on("pusher:subscription_error",a=>{e(a)}),this}on(e,a){return this.subscription.bind(e,a),this}}class wm extends Gd{whisper(e,a){return this.pusher.channels.channels[this.name].trigger(`client-${e}`,a),this}}class _E extends Gd{whisper(e,a){return this.pusher.channels.channels[this.name].trigger(`client-${e}`,a),this}}class AE extends wm{here(e){return this.on("pusher:subscription_succeeded",a=>{e(Object.keys(a.members).map(r=>a.members[r]))}),this}joining(e){return this.on("pusher:member_added",a=>{e(a.info)}),this}whisper(e,a){return this.pusher.channels.channels[this.name].trigger(`client-${e}`,a),this}leaving(e){return this.on("pusher:member_removed",a=>{e(a.info)}),this}}class Cm extends Pd{constructor(e,a,r){super(),this.events={},this.listeners={},this.name=a,this.socket=e,this.op Line truncated
* Pusher JavaScript Library v8.4.0
* https://pusher.com/
*
* Copyright 2020, Pusher
* Released under the MIT licence.
*/var Tm;function OE(){return Tm||(Tm=1,(function(l,e){(function(r,i){l.exports=i()})(window,function(){return(function(a){var r={};function i(o){if(r[o])return r[o].exports;var u=r[o]={i:o,l:!1,exports:{}};return a[o].call(u.exports,u,u.exports,i),u.l=!0,u.exports}return i.m=a,i.c=r,i.d=function(o,u,d){i.o(o,u)||Object.defineProperty(o,u,{enumerable:!0,get:d})},i.r=function(o){typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"__esModule",{value:!0})},i.t=function(o,u){if(u&1&&(o=i(o)),u&8||u&4&&typeof o=="object"&&o&&o.__esModule)return o;var d=Object.create(null);if(i.r(d),Object.defineProperty(d,"default",{enumerable:!0,value:o}),u&2&&typeof o!="string")for(var f in o)i.d(d,f,function(g){return o[g]}.bind(null,f));return d},i.n=function(o){var u=o&&o.__esModule?function(){return o.default}:function(){return o};return i.d(u,"a",u),u},i.o=function(o,u){return Object.prototype.hasOwnProperty.call(o,u)},i.p="",i(i.s=2)})([(function(a,r,i){var o=this&&this.__extends||(function(){var A=function(T,D){return A=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(M,O){M.__proto__=O}||function(M,O){for(var L in O)O.hasOwnProperty(L)&&(M[L]=O[L])},A(T,D)};return function(T,D){A(T,D);function M(){this.constructor=T}T.prototype=D===null?Object.create(D):(M.prototype=D.prototype,new M)}})();Object.defineProperty(r,"__esModule",{value:!0});var u=256,d=(function(){function A(T){T===void 0&&(T="="),this._paddingCharacter=T}return A.prototype.encodedLength=function(T){return this._paddingCharacter?(T+2)/3*4|0:(T*8+5)/6|0},A.prototype.encode=function(T){for(var D="",M=0;M<T.length-2;M+=3){var O=T[M]<<16|T[M+1]<<8|T[M+2];D+=this._encodeByte(O>>>18&63),D+=this._encodeByte(O>>>12&63),D+=this._encodeByte(O>>>6&63),D+=this._encodeByte(O>>>0&63)}var L=T.length-M;if(L>0){var O=T[M]<<16|(L===2?T[M+1]<<8:0);D+=this._encodeByte(O>>>18&63),D+=this._encodeByte(O>>>12&63),L===2?D+=this._encodeByte(O>>>6&63):D+=this._paddingCharacter||"",D+=this._paddingCharacter||""}return D},A.prototype.maxDecodedLength=function(T){return this._paddingCharacter?T/4*3|0:(T*6+7)/8|0},A.prototype.decodedLength=function(T){return this.maxDecodedLength(T.length-this._getPaddingLength(T))},A.prototype.decode=function(T){if(T.length===0)return new Uint8Array(0);for(var D=this._getPaddingLength(T),M=T.length-D,O=new Uint8Array(this.maxDecodedLength(M)),L=0,P=0,U=0,B=0,Y=0,ge=0,Ae=0;P<M-4;P+=4)B=this._decodeChar(T.charCodeAt(P+0)),Y=this._decodeChar(T.charCodeAt(P+1)),ge=this._decodeChar(T.charCodeAt(P+2)),Ae=this._decodeChar(T.charCodeAt(P+3)),O[L++]=B<<2|Y>>>4,O[L++]=Y<<4|ge>>>2,O[L++]=ge<<6|Ae,U|=B&u,U|=Y&u,U|=ge&u,U|=Ae&u;if(P<M-1&&(B=this._decodeChar(T.charCodeAt(P)),Y=this._decodeChar(T.charCodeAt(P+1)),O[L++]=B<<2|Y>>>4,U|=B&u,U|=Y&u),P<M-2&&(ge=this._decodeChar(T.charCodeAt(P+2)),O[L++]=Y<<4|ge>>>2,U|=ge&u),P<M-3&&(Ae=this._decodeChar(T.charCodeAt(P+3)),O[L++]=ge<<6|Ae,U|=Ae&u),U!==0)throw new Error("Base64Coder: incorrect characters for decoding");return O},A.prototype._encodeByte=function(T){var D=T;return D+=65,D+=25-T>>>8&6,D+=51-T>>>8&-75,D+=61-T>>>8&-15,D+=62-T>>>8&3,String.fromCharCode(D)},A.prototype._decodeChar=function(T){var D=u;return D+=(42-T&T-44)>>>8&-u+T-43+62,D+=(46-T&T-48)>>>8&-u+T-47+63,D+=(47-T&T-58)>>>8&-u+T-48+52,D+=(64-T&T-91)>>>8&-u+T-65+0,D+=(96-T&T-123)>>>8&-u+T-97+26,D},A.prototype._getPaddingLength=function(T){var D=0;if(this._paddingCharacter){for(var M=T.length-1;M>=0&&T[M]===this._paddingCharacter;M--)D++;if(T.length<4||D>2)throw new Error("Base64Coder: incorrect padding")}return D},A})();r.Coder=d;var f=new d;function g(A){return f.encode(A)}r.encode=g;function m(A){return f.decode(A)}r.decode=m;var b=(function(A){o(T,A);function T(){return A!==null&&A.apply(this,arguments)||this}return T.prototype._encodeByte=function(D){var M=D;return M+=65,M+=25-D>>>8&6,M+=51-D>>>8&-75,M+=61-D>>>8&-13,M+=62-D>>>8&49,String.fromCharCode(M)},T.prototype._decodeChar=function(D){var M=u;return M+=(44-D&D-46)>>>8&-u+D-45+62,M+=(94-D&D-96)>>>8&-u+D-95+63,M+=(47-D&D-58)>>>8&-u+D-48+52,M+=(64-D&D-91)>>>8&-u+D-65+0,M+=(96-D&D-123)>>>8&-u+D-97+26,M},T})(d);r.URLSafeCoder=b;var v=new b;function E(A){return v.encode(A)}r.encodeURLSafe=E;function S(A){return v.decode(A)}r.decodeURLSafe=S,r.encodedLength=function(A){return f.encodedLength(A)},r.maxDecodedLength=function(A){return f.maxDecodedLength(A)},r.decodedLength=function(A){return f.decodedLength(A)}}),(function(a,r,i){Object.defineProperty(r,"__esModule",{value:!0});var o="utf8: invalid string",u="utf8: invalid source encoding";function d(m){for(var b=new Uint8Array(f(m)),v=0,E=0;E<m.length;E++){var S=m.charCodeAt(E);S<128?b[v++]=S:S<2048?(b[v++]=192|S>>6,b[v++]=128|S&63):S<55296?(b[v++]=224|S>>12,b[v++]=128|S>>6&63,b[v++]=128|S&63):(E++,S=(S&1023)<<10,S|=m.charCodeAt(E)&1023,S+=65536,b[v++]=240|S>>18,b[v++]=128|S>>12&63,b[v++]=128|S>>6&63,b[v++]=128|S&63)}return b}r.encode=d;function f(m){for(var b=0,v=0Line truncated
`);return R!==-1?(this.position+=R+1,C.slice(0,R)):null}isBufferTooLong(y){return this.position===y.length&&y.length>$r}}var os;(function(_){_[_.CONNECTING=0]="CONNECTING",_[_.OPEN=1]="OPEN",_[_.CLOSED=3]="CLOSED"})(os||(os={}));var Ba=os,Oo=1;class nf{constructor(y,C){this.hooks=y,this.session=cs(1e3)+"/"+Nr(8),this.location=af(C),this.readyState=Ba.CONNECTING,this.openStream()}send(y){return this.sendRaw(JSON.stringify([y]))}ping(){this.hooks.sendHeartbeat(this)}close(y,C){this.onClose(y,C,!0)}sendRaw(y){if(this.readyState===Ba.OPEN)try{return Ge.createSocketRequest("POST",aa(ls(this.location,this.session))).start(y),!0}catch{return!1}else return!1}reconnect(){this.closeStream(),this.openStream()}onClose(y,C,R){this.closeStream(),this.readyState=Ba.CLOSED,this.onclose&&this.onclose({code:y,reason:C,wasClean:R})}onChunk(y){if(y.status===200){this.readyState===Ba.OPEN&&this.onActivity();var C,R=y.data.slice(0,1);switch(R){case"o":C=JSON.parse(y.data.slice(1)||"{}"),this.onOpen(C);break;case"a":C=JSON.parse(y.data.slice(1)||"[]");for(var H=0;H<C.length;H++)this.onEvent(C[H]);break;case"m":C=JSON.parse(y.data.slice(1)||"null"),this.onEvent(C);break;case"h":this.hooks.onHeartbeat(this);break;case"c":C=JSON.parse(y.data.slice(1)||"[]"),this.onClose(C[0],C[1],!0);break}}}onOpen(y){this.readyState===Ba.CONNECTING?(y&&y.hostname&&(this.location.base=Lo(this.location.base,y.hostname)),this.readyState=Ba.OPEN,this.onopen&&this.onopen()):this.onClose(1006,"Server lost session",!0)}onEvent(y){this.readyState===Ba.OPEN&&this.onmessage&&this.onmessage({data:y})}onActivity(){this.onactivity&&this.onactivity()}onError(y){this.onerror&&this.onerror(y)}openStream(){this.stream=Ge.createSocketRequest("POST",aa(this.hooks.getReceiveURL(this.location,this.session))),this.stream.bind("chunk",y=>{this.onChunk(y)}),this.stream.bind("finished",y=>{this.hooks.onFinished(this,y)}),this.stream.bind("buffer_too_long",()=>{this.reconnect()});try{this.stream.start()}catch(y){te.defer(()=>{this.onError(y),this.onClose(1006,"Could not start streaming",!1)})}}closeStream(){this.stream&&(this.stream.unbind_all(),this.stream.close(),this.stream=null)}}function af(_){var y=/([^\?]*)\/*(\??.*)/.exec(_);return{base:y[1],queryString:y[2]}}function ls(_,y){return _.base+"/"+y+"/xhr_send"}function aa(_){var y=_.indexOf("?")===-1?"?":"&";return _+y+"t="+ +new Date+"&n="+Oo++}function Lo(_,y){var C=/(https?:\/\/)([^\/:]+)((\/|:)?.*)/.exec(_);return C[1]+y+C[3]}function cs(_){return Ge.randomInt(_)}function Nr(_){for(var y=[],C=0;C<_;C++)y.push(cs(32).toString(32));return y.join("")}var Hr=nf,_c={getReceiveURL:function(_,y){return _.base+"/"+y+"/xhr_streaming"+_.queryString},onHeartbeat:function(_){_.sendRaw("[]")},sendHeartbeat:function(_){_.sendRaw("[]")},onFinished:function(_,y){_.onClose(1006,"Connection interrupted ("+y+")",!1)}},Mo=_c,Ac={getReceiveURL:function(_,y){return _.base+"/"+y+"/xhr"+_.queryString},onHeartbeat:function(){},sendHeartbeat:function(_){_.sendRaw("[]")},onFinished:function(_,y){y===200?_.reconnect():_.onClose(1006,"Connection interrupted ("+y+")",!1)}},vi=Ac,Ta={getRequest:function(_){var y=Ge.getXHRAPI(),C=new y;return C.onreadystatechange=C.onprogress=function(){switch(C.readyState){case 3:C.responseText&&C.responseText.length>0&&_.onChunk(C.status,C.responseText);break;case 4:C.responseText&&C.responseText.length>0&&_.onChunk(C.status,C.responseText),_.emit("finished",C.status),_.close();break}},C},abortRequest:function(_){_.onreadystatechange=null,_.abort()}},$o=Ta,Si={createStreamingSocket(_){return this.createSocket(Mo,_)},createPollingSocket(_){return this.createSocket(vi,_)},createSocket(_,y){return new Hr(_,y)},createXHR(_,y){return this.createRequest($o,_,y)},createRequest(_,y,C){return new tf(_,y,C)}},ka=Si;ka.createXDR=function(_,y){return this.createRequest(Ec,_,y)};var No=ka,us={nextAuthCallbackID:1,auth_callbacks:{},ScriptReceivers:u,DependenciesReceivers:m,getDefaultStrategy:Do,Transports:Kt,transportConnectionInitializer:Mr,HTTPFactory:No,TimelineTransport:tr,getXHRAPI(){return window.XMLHttpRequest},getWebSocketAPI(){return window.WebSocket||window.MozWebSocket},setup(_){window.Pusher=_;var y=()=>{this.onDocumentBody(_.ready)};window.JSON?y():b.load("json2",{},y)},getDocument(){return document},getProtocol(){return this.getDocument().location.protocol},getAuthorizers(){return{ajax:Ae,jsonp:Gn}},onDocumentBody(_){document.body?_():setTimeout(()=>{this.onDocumentBody(_)},0)},createJSONPRequest(_,y){return new yn(_,y)},createScriptRequest(_){return new tn(_)},getLocalStorage(){try{return window.localStorage}catch{return}},createXHR(){return this.getXHRAPI()?this.createXMLHttpRequest():this.createMicrosoftXHR()},createXMLHttpRequest(){var _=this.getXHRAPI();return new _},createMicrosoftXHR(){return new ActiveXObject("Microsoft.XMLHTTP")},getNetwork(){return Dn},createWebSocket(_){var y=this.getWebSocketAPI();return new y(_)},createSocketRequest(_,y){if(this.isXHRSupported())return this.HTTPFactory.createXHR(_ Line truncated
`,Bn.error("Error state rendered:",i,r)}getCurrentLayout(){return this.currentLayout}clear(){this.currentLayout=null,this.layoutCache.clear(),Bn.log("Layout data and cache cleared")}}const qE=ft("TranslationContext"),Fd=N.createContext(null),nc=({children:o,translationEngine:e,translationContext:a})=>{const r=N.useMemo(()=>(l,u)=>{if(u){const d="|"+Object.entries(u).map(([f,g])=>`${f}=${g}`).join("|");return e.translate(l,a,d)}return e.translate(l,a)},[e,a]),i=N.useMemo(()=>({translationEngine:e,translationContext:a,t:r}),[e,a,r]);return ct.jsx(Fd.Provider,{value:i,children:o})},Am=()=>{const o=N.useContext(Fd);return o||(qE.warn("TranslationProvider 외부에서 호출되었습니다. 키를 그대로 반환합니다."),{t:e=>e,translationEngine:null,translationContext:null})},xr=ft("SlotContext"),PE={registerToSlot:()=>{xr.warn("SlotContext not available: registerToSlot called outside SlotProvider")},unregisterFromSlot:()=>{xr.warn("SlotContext not available: unregisterFromSlot called outside SlotProvider")},getSlotComponents:()=>[],subscribeToSlot:()=>()=>{},clearAllSlots:()=>{},isEnabled:!1},GE=N.createContext(PE),Kd=({children:o})=>{const e=N.useRef(new Map),a=N.useRef(new Map),r=N.useCallback(m=>{const b=a.current.get(m);b&&b.forEach(v=>{try{v()}catch(S){xr.error(`Slot subscriber error (slotId: ${m}):`,S)}})},[]),i=N.useCallback((m,b,v)=>{if(!m||!b){xr.warn("registerToSlot: slotId and componentId are required");return}e.current.has(m)||e.current.set(m,new Map);const S=e.current.get(m),_=S.get(b);_&&_.registrationKey===v.registrationKey||(S.set(b,v),xr.log(`Component registered to slot: ${b} -> ${m} (order: ${v.order})`),r(m))},[r]),l=N.useCallback((m,b)=>{const v=e.current.get(m);v&&v.has(b)&&(v.delete(b),xr.log(`Component unregistered from slot: ${b} <- ${m}`),v.size===0&&e.current.delete(m),r(m))},[r]),u=N.useCallback(m=>{const b=e.current.get(m);return b?Array.from(b.values()).sort((v,S)=>v.order-S.order):[]},[]),d=N.useCallback((m,b)=>{a.current.has(m)||a.current.set(m,new Set);const v=a.current.get(m);return v.add(b),()=>{v.delete(b),v.size===0&&a.current.delete(m)}},[]),f=N.useCallback(()=>{e.current.forEach((m,b)=>{r(b)}),e.current.clear(),a.current.clear(),xr.log("All slots cleared")},[r]),g=N.useMemo(()=>({registerToSlot:i,unregisterFromSlot:l,getSlotComponents:u,subscribeToSlot:d,clearAllSlots:f,isEnabled:!0}),[i,l,u,d,f]);return N.useLayoutEffect(()=>{typeof window<"u"&&(window.__slotContextValue=g,xr.log("SlotContext exposed to window.__slotContextValue"))},[g]),ct.jsx(GE.Provider,{value:g,children:o})};class Wd{constructor(){this.notificationCreatedEvent=".Illuminate\\Notifications\\Events\\BroadcastNotificationCreated"}listenForWhisper(e,a){return this.listen(".client-"+e,a)}notification(e){return this.listen(this.notificationCreatedEvent,e)}stopListeningForNotification(e){return this.stopListening(this.notificationCreatedEvent,e)}stopListeningForWhisper(e,a){return this.stopListening(".client-"+e,a)}}class xm{constructor(e){this.namespace=e}format(e){return[".","\\"].includes(e.charAt(0))?e.substring(1):(this.namespace&&(e=this.namespace+"."+e),e.replace(/\./g,"\\"))}setNamespace(e){this.namespace=e}}function VE(o){try{return Reflect.construct(String,[],o),!0}catch{return!1}}class Yd extends Wd{constructor(e,a,r){super(),this.name=a,this.pusher=e,this.options=r,this.eventFormatter=new xm(this.options.namespace),this.subscribe()}subscribe(){this.subscription=this.pusher.subscribe(this.name)}unsubscribe(){this.pusher.unsubscribe(this.name)}listen(e,a){return this.on(this.eventFormatter.format(e),a),this}listenToAll(e){return this.subscription.bind_global((a,r)=>{if(a.startsWith("pusher:"))return;let i=String(this.options.namespace??"").replace(/\./g,"\\"),l=a.startsWith(i)?a.substring(i.length+1):"."+a;e(l,r)}),this}stopListening(e,a){return a?this.subscription.unbind(this.eventFormatter.format(e),a):this.subscription.unbind(this.eventFormatter.format(e)),this}stopListeningToAll(e){return e?this.subscription.unbind_global(e):this.subscription.unbind_global(),this}subscribed(e){return this.on("pusher:subscription_succeeded",()=>{e()}),this}error(e){return this.on("pusher:subscription_error",a=>{e(a)}),this}on(e,a){return this.subscription.bind(e,a),this}}class Tm extends Yd{whisper(e,a){return this.pusher.channels.channels[this.name].trigger(`client-${e}`,a),this}}class FE extends Yd{whisper(e,a){return this.pusher.channels.channels[this.name].trigger(`client-${e}`,a),this}}class KE extends Tm{here(e){return this.on("pusher:subscription_succeeded",a=>{e(Object.keys(a.members).map(r=>a.members[r]))}),this}joining(e){return this.on("pusher:member_added",a=>{e(a.info)}),this}whisper(e,a){return this.pusher.channels.channels[this.name].trigger(`client-${e}`,a),this}leaving(e){return this.on("pusher:member_removed",a=>{e(a.info)}),this}}class Rm extends Wd{constructor(e,a,r){super(),this.events={},this.listeners={},this.name=a,this.socket=e,this.options=r,this.eventFormatter=new xm(this.op Line truncated
`);return O!==-1?(this.position+=O+1,C.slice(0,O)):null}isBufferTooLong(y){return this.position===y.length&&y.length>xo}}var To;(function(E){E[E.CONNECTING=0]="CONNECTING",E[E.OPEN=1]="OPEN",E[E.CLOSED=3]="CLOSED"})(To||(To={}));const na=To;var Aa=1;class Ro{constructor(y,C){this.hooks=y,this.session=os(1e3)+"/"+Cc(8),this.location=ko(C),this.readyState=na.CONNECTING,this.openStream()}send(y){return this.sendRaw(JSON.stringify([y]))}ping(){this.hooks.sendHeartbeat(this)}close(y,C){this.onClose(y,C,!0)}sendRaw(y){if(this.readyState===na.OPEN)try{return Ue.createSocketRequest("POST",ar(Ir(this.location,this.session))).start(y),!0}catch{return!1}else return!1}reconnect(){this.closeStream(),this.openStream()}onClose(y,C,O){this.closeStream(),this.readyState=na.CLOSED,this.onclose&&this.onclose({code:y,reason:C,wasClean:O})}onChunk(y){if(y.status===200){this.readyState===na.OPEN&&this.onActivity();var C,O=y.data.slice(0,1);switch(O){case"o":C=JSON.parse(y.data.slice(1)||"{}"),this.onOpen(C);break;case"a":C=JSON.parse(y.data.slice(1)||"[]");for(var H=0;H<C.length;H++)this.onEvent(C[H]);break;case"m":C=JSON.parse(y.data.slice(1)||"null"),this.onEvent(C);break;case"h":this.hooks.onHeartbeat(this);break;case"c":C=JSON.parse(y.data.slice(1)||"[]"),this.onClose(C[0],C[1],!0);break}}}onOpen(y){this.readyState===na.CONNECTING?(y&&y.hostname&&(this.location.base=wc(this.location.base,y.hostname)),this.readyState=na.OPEN,this.onopen&&this.onopen()):this.onClose(1006,"Server lost session",!0)}onEvent(y){this.readyState===na.OPEN&&this.onmessage&&this.onmessage({data:y})}onActivity(){this.onactivity&&this.onactivity()}onError(y){this.onerror&&this.onerror(y)}openStream(){this.stream=Ue.createSocketRequest("POST",ar(this.hooks.getReceiveURL(this.location,this.session))),this.stream.bind("chunk",y=>{this.onChunk(y)}),this.stream.bind("finished",y=>{this.hooks.onFinished(this,y)}),this.stream.bind("buffer_too_long",()=>{this.reconnect()});try{this.stream.start()}catch(y){Ie.defer(()=>{this.onError(y),this.onClose(1006,"Could not start streaming",!1)})}}closeStream(){this.stream&&(this.stream.unbind_all(),this.stream.close(),this.stream=null)}}function ko(E){var y=/([^\?]*)\/*(\??.*)/.exec(E);return{base:y[1],queryString:y[2]}}function Ir(E,y){return E.base+"/"+y+"/xhr_send"}function ar(E){var y=E.indexOf("?")===-1?"?":"&";return E+y+"t="+ +new Date+"&n="+Aa++}function wc(E,y){var C=/(https?:\/\/)([^\/:]+)((\/|:)?.*)/.exec(E);return C[1]+y+C[3]}function os(E){return Ue.randomInt(E)}function Cc(E){for(var y=[],C=0;C<E;C++)y.push(os(32).toString(32));return y.join("")}const bi=Ro;var xa={getReceiveURL:function(E,y){return E.base+"/"+y+"/xhr_streaming"+E.queryString},onHeartbeat:function(E){E.sendRaw("[]")},sendHeartbeat:function(E){E.sendRaw("[]")},onFinished:function(E,y){E.onClose(1006,"Connection interrupted ("+y+")",!1)}};const Do=xa;var vi={getReceiveURL:function(E,y){return E.base+"/"+y+"/xhr"+E.queryString},onHeartbeat:function(){},sendHeartbeat:function(E){E.sendRaw("[]")},onFinished:function(E,y){y===200?E.reconnect():E.onClose(1006,"Connection interrupted ("+y+")",!1)}};const qa=vi;var Oo={getRequest:function(E){var y=Ue.getXHRAPI(),C=new y;return C.onreadystatechange=C.onprogress=function(){switch(C.readyState){case 3:C.responseText&&C.responseText.length>0&&E.onChunk(C.status,C.responseText);break;case 4:C.responseText&&C.responseText.length>0&&E.onChunk(C.status,C.responseText),E.emit("finished",C.status),E.close();break}},C},abortRequest:function(E){E.onreadystatechange=null,E.abort()}};const ls=Oo;var Ec={createStreamingSocket(E){return this.createSocket(Do,E)},createPollingSocket(E){return this.createSocket(qa,E)},createSocket(E,y){return new bi(E,y)},createXHR(E,y){return this.createRequest(ls,E,y)},createRequest(E,y,C){return new uf(E,y,C)}};const Si=Ec;Si.createXDR=function(E,y){return this.createRequest(Sc,E,y)};var _c={nextAuthCallbackID:1,auth_callbacks:{},ScriptReceivers:m,DependenciesReceivers:_,getDefaultStrategy:Hr,Transports:vn,transportConnectionInitializer:cf,HTTPFactory:Si,TimelineTransport:P,getXHRAPI(){return window.XMLHttpRequest},getWebSocketAPI(){return window.WebSocket||window.MozWebSocket},setup(E){window.Pusher=E;var y=()=>{this.onDocumentBody(E.ready)};window.JSON?y():A.load("json2",{},y)},getDocument(){return document},getProtocol(){return this.getDocument().location.protocol},getAuthorizers(){return{ajax:Xe,jsonp:En}},onDocumentBody(E){document.body?E():setTimeout(()=>{this.onDocumentBody(E)},0)},createJSONPRequest(E,y){return new Ea(E,y)},createScriptRequest(E){return new er(E)},getLocalStorage(){try{return window.localStorage}catch{return}},createXHR(){return this.getXHRAPI()?this.createXMLHttpRequest():this.createMicrosoftXHR()},createXMLHttpRequest(){var E=this.getXHRAPI();return new E},createMicrosoftXHR(){return new ActiveXObject("Microsoft.XMLHTTP")},getNetwork(){return Eo},createWebSocket(E){var y=this.getWebSocketAPI();return new y(E)},createSocketRequest(E,y){if(this.isXHRSuppor Line truncated
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: ${o?"#111827":"#f9fafb"};
background-color: ${l?"#111827":"#f9fafb"};
padding: 1rem;
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
`,card:`
max-width: 28rem;
width: 100%;
background-color: ${o?"#1f2937":"#ffffff"};
background-color: ${l?"#1f2937":"#ffffff"};
border-radius: 0.5rem;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
padding: 2rem;
@@ -170,17 +127,17 @@ Error generating stack: `+c.message+`
`,title:`
font-size: 1.5rem;
font-weight: 700;
color: ${o?"#ffffff":"#111827"};
color: ${l?"#ffffff":"#111827"};
margin-bottom: 1rem;
`,message:`
color: ${o?"#d1d5db":"#4b5563"};
color: ${l?"#d1d5db":"#4b5563"};
margin-bottom: 0.5rem;
line-height: 1.625;
`,detailMessage:`
font-size: 0.875rem;
color: ${o?"#9ca3af":"#6b7280"};
color: ${l?"#9ca3af":"#6b7280"};
margin-bottom: 1.5rem;
background-color: ${o?"#374151":"#f3f4f6"};
background-color: ${l?"#374151":"#f3f4f6"};
padding: 0.5rem 0.75rem;
border-radius: 0.25rem;
`,spacer:`
@@ -188,17 +145,17 @@ Error generating stack: `+c.message+`
`,stackContainer:`
margin-top: 1.5rem;
padding: 1rem;
background-color: ${o?"#374151":"#f3f4f6"};
background-color: ${l?"#374151":"#f3f4f6"};
border-radius: 0.375rem;
text-align: left;
`,stackTitle:`
font-size: 0.875rem;
font-weight: 600;
color: ${o?"#e5e7eb":"#374151"};
color: ${l?"#e5e7eb":"#374151"};
margin-bottom: 0.5rem;
`,stackTrace:`
font-size: 0.75rem;
color: ${o?"#d1d5db":"#4b5563"};
color: ${l?"#d1d5db":"#4b5563"};
overflow-x: auto;
white-space: pre-wrap;
word-break: break-word;
@@ -267,7 +224,7 @@ Error generating stack: `+c.message+`
`:""}
</div>
</div>
`}static renderFromError(e,a,r,i=!1,o,u,d){let f,g;if(a.userMessageKey.startsWith("$t:"))if(u&&o)try{f=u.translate(a.userMessageKey,o)}catch{f=a.userMessageKey.replace("$t:","")}else f=a.userMessageKey.replace("$t:","");else f=a.userMessageKey;if(d){const m=d;m.details?.apiMessage?g=m.details.apiMessage:m.response?.data?.message&&(g=m.response.data.message)}this.render(e,{title:r,message:f,detailMessage:g,icon:a.icon,showStack:a.showStack,stackTrace:a.stack,showReloadButton:a.recoverable,debug:i})}static escapeHtml(e){if(!e)return"";const a=document.createElement("div");return a.textContent=e,a.innerHTML}}const Zi=dt("Router");class UE{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,a){this.eventHandlers.has(e)||this.eventHandlers.set(e,[]),this.eventHandlers.get(e).push(a)}async emit(e,...a){const r=this.eventHandlers.get(e);r&&await Promise.all(r.map(i=>i(...a)))}async loadRoutes(e){try{const a=e!==void 0&&e>0?`?v=${e}`:"",r=await fetch(`/api/templates/${this.templateIdentifier}/routes.json${a}`);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,Zi.log(`Loaded ${this.routes.length} routes${e?` (v=${e})`:""}`);else throw new Error("Invalid routes data format")}catch(a){throw Zi.error("Error loading routes:",a),a}}setRoutes(e){this.routes=e,Zi.log(`Set ${this.routes.length} routes`)}match(e){for(const a of this.routes){const r=this.matchPattern(a.path,e);if(r!==null)return{route:a,params:r}}return null}matchPattern(e,a){const r=[];let i=e.replace(/:([^/]+)/g,(f,g)=>(r.push(g),"([^/]+)"));i.startsWith("*/")&&(i="(?:/[^/]+)?"+i.slice(1)),i=i.replace(/\//g,"\\/");const o=new RegExp(`^${i}$`),u=a.match(o);if(!u)return null;const d={};return r.forEach((f,g)=>{d[f]=u[g+1]}),d}getRoutes(){return[...this.routes]}getAuthType(e,a){return e.auth_type?e.auth_type:a.startsWith("/admin")?"admin":"user"}async navigateToCurrentPath(){const e=window.location.pathname,a=window.location.search,r=this.match(e);if(!r){Zi.warn(`No route matched for path: ${e}`),this.emit("routeNotFound",e);return}if(r.route.redirect){Zi.log(`Redirecting from ${e} to ${r.route.redirect}`),this.navigate(r.route.redirect);return}if(r.route.auth_required){const u=this.getAuthType(r.route,e),d=ga.getInstance();let f=d.isAuthenticated()&&d.getAuthType()===u;if(f||(f=await d.checkAuth(u)),!f){const g=d.getLoginRedirectUrl(u,e+a);Zi.log(`Not authenticated, redirecting to: ${g}`),window.location.href=g;return}}const i=new URLSearchParams(a),o={};for(const u of i.keys()){if(u in o)continue;const d=i.getAll(u);d.length>1?o[u]=d:d.length===1&&(u.endsWith("[]")?o[u]=d:o[u]=d[0])}await this.emit("routeChange",{path:e,layout:r.route.layout,endpoint:r.route.endpoint,params:{...r.route.params||{},...r.params},query:o,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 a=this.pendingNavigation;this.executeNavigation(a)}}}}const BE=/^\/admin\/layout-editor\/([^/?#]+)\/?$/;function Lm(l){const e=BE.exec(l);return e?{templateIdentifier:e[1]}:null}const Nt=dt("ErrorPageHandler");class qE{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(`/api/templates/${this.templateId}/config.json`);if(!e.ok)return this.debug&&Nt.warn("Failed to load template config:",e.statusText),this.configLoaded=!0,null;const a=await e.json();if(!a.success||!a.data)return this.debug&&Nt.warn("Invalid template config response"),this.configLoaded=!0,null;const r=a.data;return!r.error_config||!r.error_config.layouts?(this.debug&&Nt.warn("No error_config found in template.json"),this.configLoaded=!0,null):(this.errorConfig=r.error_config,this.configLoaded=!0,this.debug&&Nt.log("Error config loaded:",this.errorConfig),this.errorConfig)}catch(e){return Nt.error("Failed to load error config:",e),this.configLoaded=!0,null}}async rend Line truncated
`}static renderFromError(e,a,r,i=!1,l,u,d){let f,g;if(a.userMessageKey.startsWith("$t:"))if(u&&l)try{f=u.translate(a.userMessageKey,l)}catch{f=a.userMessageKey.replace("$t:","")}else f=a.userMessageKey.replace("$t:","");else f=a.userMessageKey;if(d){const m=d;m.details?.apiMessage?g=m.details.apiMessage:m.response?.data?.message&&(g=m.response.data.message)}this.render(e,{title:r,message:f,detailMessage:g,icon:a.icon,showStack:a.showStack,stackTrace:a.stack,showReloadButton:a.recoverable,debug:i})}static escapeHtml(e){if(!e)return"";const a=document.createElement("div");return a.textContent=e,a.innerHTML}}const ns=ft("Router");class l_{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,a){this.eventHandlers.has(e)||this.eventHandlers.set(e,[]),this.eventHandlers.get(e).push(a)}async emit(e,...a){const r=this.eventHandlers.get(e);r&&await Promise.all(r.map(i=>i(...a)))}async loadRoutes(e){try{const a=e!==void 0&&e>0?`?v=${e}`:"",r=await fetch(`/api/templates/${this.templateIdentifier}/routes.json${a}`);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,ns.log(`Loaded ${this.routes.length} routes${e?` (v=${e})`:""}`);else throw new Error("Invalid routes data format")}catch(a){throw ns.error("Error loading routes:",a),a}}setRoutes(e){this.routes=e,ns.log(`Set ${this.routes.length} routes`)}match(e){for(const a of this.routes){const r=this.matchPattern(a.path,e);if(r!==null)return{route:a,params:r}}return null}matchPattern(e,a){const r=[];let i=e.replace(/:([^/]+)/g,(f,g)=>(r.push(g),"([^/]+)"));i.startsWith("*/")&&(i="(?:/[^/]+)?"+i.slice(1)),i=i.replace(/\//g,"\\/");const l=new RegExp(`^${i}$`),u=a.match(l);if(!u)return null;const d={};return r.forEach((f,g)=>{d[f]=u[g+1]}),d}getRoutes(){return[...this.routes]}getAuthType(e,a){return e.auth_type?e.auth_type:a.startsWith("/admin")?"admin":"user"}async navigateToCurrentPath(){const e=window.location.pathname,a=window.location.search,r=this.match(e);if(!r){ns.warn(`No route matched for path: ${e}`),this.emit("routeNotFound",e);return}if(r.route.redirect){ns.log(`Redirecting from ${e} to ${r.route.redirect}`),this.navigate(r.route.redirect);return}if(r.route.auth_required){const u=this.getAuthType(r.route,e),d=ha.getInstance();let f=d.isAuthenticated()&&d.getAuthType()===u;if(f||(f=await d.checkAuth(u)),!f){const g=d.getLoginRedirectUrl(u,e+a);ns.log(`Not authenticated, redirecting to: ${g}`),window.location.href=g;return}}const i=new URLSearchParams(a),l={};for(const u of i.keys()){if(u in l)continue;const d=i.getAll(u);d.length>1?l[u]=d:d.length===1&&(u.endsWith("[]")?l[u]=d:l[u]=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 a=this.pendingNavigation;this.executeNavigation(a)}}}}const c_=/^\/admin\/layout-editor\/([^/?#]+)\/?$/;function zm(o){const e=c_.exec(o);return e?{templateIdentifier:e[1]}:null}const It=ft("ErrorPageHandler");class u_{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(`/api/templates/${this.templateId}/config.json`);if(!e.ok)return this.debug&&It.warn("Failed to load template config:",e.statusText),this.configLoaded=!0,null;const a=await e.json();if(!a.success||!a.data)return this.debug&&It.warn("Invalid template config response"),this.configLoaded=!0,null;const r=a.data;return!r.error_config||!r.error_config.layouts?(this.debug&&It.warn("No error_config found in template.json"),this.configLoaded=!0,null):(this.errorConfig=r.error_config,this.configLoaded=!0,this.debug&&It.log("Error config loaded:",this.errorConfig),this.errorConfig)}catch(e){return It.error("Failed to load error config:",e),this.configLoaded=!0,null}}async rend Line truncated
with(ctx) {
try {
return Boolean(${r});
@@ -275,7 +232,7 @@ Error generating stack: `+c.message+`
return false;
}
}
`)(a)}return!!e}catch(r){return j.warn(`Failed to evaluate script condition: ${e}`,r),!1}}showInitError(e){const a=Om(e);Kd.renderFromError("app",a,"초기화 실패",this.config.debug,{templateId:this.config.templateId,locale:this.config.locale},void 0,e)}showTransitionOverlay(e,a){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&&a){this.renderSkeletonOverlay(r.target,r.skeleton,a,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 o,u="";switch(r.style){case"blur":o=i?"rgba(17,24,39,0.3)":"rgba(255,255,255,0.3)",u="backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);";break;case"fade":o=i?"rgba(17,24,39,0.8)":"rgba(255,255,255,0.8)";break;case"skeleton":o=i?"rgb(17,24,39)":"rgb(249,250,251)";break;case"opaque":default:o=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:${o};${u}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=o;for(const f of u.split(";")){const g=f.indexOf(":");g!==-1&&d.style.setProperty(f.slice(0,g).trim(),f.slice(g+1).trim())}document.body.appendChild(d),this.transitionOverlayEl=d}}hideTransitionOverlay(){this.transitionOverlayEl&&(this.transitionOverlayEl.remove(),this.transitionOverlayEl=null),this.hideSkeletonOverlay()}renderSkeletonOverlay(e,a,r,i){const u=fa.getInstance().getComponent(a.component);if(!u){j.log(`Skeleton component "${a.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){j.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)",b=f==="fullpage"?"app":f==="fallback"?i:e,v=`#${CSS.escape(b)}`,E=document.createElement("style");E.id="g7-skeleton-overlay-style",E.textContent=`${v}{position:relative;z-index:0;}${v}::after{content:'';position:absolute;inset:0;background:${m};z-index:2147483646;pointer-events:none;}`,document.head.appendChild(E),this.transitionOverlayEl=E;const S=document.createElement("div");if(S.id="g7-skeleton-overlay",S.setAttribute("role","status"),S.setAttribute("aria-busy","true"),S.setAttribute("aria-label","Loading..."),f==="fullpage")S.style.cssText=["position:fixed","inset:0","z-index:20","overflow:hidden","pointer-events:none",`background:${m}`].join(";")+";";else{const O=d.getBoundingClientRect(),L=window.scrollX||document.documentElement.scrollLeft,P=window.scrollY||document.documentElement.scrollTop;S.style.cssText=["position:absolute",`top:${O.top+P}px`,`left:${O.left+L}px`,`width:${O.width}px`,`height:${O.height}px`,"z-index:20","overflow:hidden","pointer-events:none",`background:${m}`].join(";")+";"}document.body.appendChild(S),this.skeletonOverlayContainer=S;const A=r.components||[];let T;if(f==="fullpage")T=A;else{const O=f==="fallback"?i:e;T=this.findComponentChildrenById(A,O)}const D=Pu.createRoot(S);this.skeletonOverlayRoot=D,Ar.flushSync(()=>{D.render(We.createElement(u,{components:T,options:{animation:a.animation||"pulse",iteration_count:a.iteration_count||5}}))});const M=f==="fullpage"?"fullpage (#app)":f==="fallback"?`fallback (#${i})`:`target (#${e})`;j.log(`Skeleton overlay rendered [${M}] with "${a.component}" (${T.length} components)`)}findComponentChildrenById(e,a){const r=i=>{for(const o of i){if(o.id===a)return o.children||[];if(o.children&&Array.isArray(o.children)){const u=r(o.children);if(u!==null)return u}}return null};return r(e)||e}renderSpinnerOverlay(e,a,r){let i=document.getElementById(e),o="target";if(!i&&r&&(i=document.getElementById(r),o="fallback"),i||(i=document.getElementById("app"),o="fullpage"),!i){j.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.hideSkele Line truncated
`)(a)}return!!e}catch(r){return B.warn(`Failed to evaluate script condition: ${e}`,r),!1}}showInitError(e){const a=Im(e);Qd.renderFromError("app",a,"초기화 실패",this.config.debug,{templateId:this.config.templateId,locale:this.config.locale},void 0,e)}showTransitionOverlay(e,a){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&&a){this.renderSkeletonOverlay(r.target,r.skeleton,a,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,u="";switch(r.style){case"blur":l=i?"rgba(17,24,39,0.3)":"rgba(255,255,255,0.3)",u="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};${u}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 u.split(";")){const g=f.indexOf(":");g!==-1&&d.style.setProperty(f.slice(0,g).trim(),f.slice(g+1).trim())}document.body.appendChild(d),this.transitionOverlayEl=d}}hideTransitionOverlay(){this.transitionOverlayEl&&(this.transitionOverlayEl.remove(),this.transitionOverlayEl=null),this.hideSkeletonOverlay()}renderSkeletonOverlay(e,a,r,i){const u=da.getInstance().getComponent(a.component);if(!u){B.log(`Skeleton component "${a.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){B.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)",b=f==="fullpage"?"app":f==="fallback"?i:e,v=`#${CSS.escape(b)}`,S=document.createElement("style");S.id="g7-skeleton-overlay-style",S.textContent=`${v}{position:relative;z-index:0;}${v}::after{content:'';position:absolute;inset:0;background:${m};z-index:2147483646;pointer-events:none;}`,document.head.appendChild(S),this.transitionOverlayEl=S;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 T=d.getBoundingClientRect(),D=window.scrollX||document.documentElement.scrollLeft,U=window.scrollY||document.documentElement.scrollTop;_.style.cssText=["position:absolute",`top:${T.top+U}px`,`left:${T.left+D}px`,`width:${T.width}px`,`height:${T.height}px`,"z-index:20","overflow:hidden","pointer-events:none",`background:${m}`].join(";")+";"}document.body.appendChild(_),this.skeletonOverlayContainer=_;const A=r.components||[];let R;if(f==="fullpage")R=A;else{const T=f==="fallback"?i:e;R=this.findComponentChildrenById(A,T)}const L=Pu.createRoot(_);this.skeletonOverlayRoot=L,Er.flushSync(()=>{L.render(Ye.createElement(u,{components:R,options:{animation:a.animation||"pulse",iteration_count:a.iteration_count||5}}))});const M=f==="fullpage"?"fullpage (#app)":f==="fallback"?`fallback (#${i})`:`target (#${e})`;B.log(`Skeleton overlay rendered [${M}] with "${a.component}" (${R.length} components)`)}findComponentChildrenById(e,a){const r=i=>{for(const l of i){if(l.id===a)return l.children||[];if(l.children&&Array.isArray(l.children)){const u=r(l.children);if(u!==null)return u}}return null};return r(e)||e}renderSpinnerOverlay(e,a,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){B.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(); Line truncated
with(ctx) {
try {
return ${e};
@@ -283,5 +240,5 @@ Error generating stack: `+c.message+`
return undefined;
}
}
`)(a)}catch(r){j.warn(`Expression evaluation failed: ${e}`,r);return}}async executeInitActions(e,a={}){const{getActionDispatcher:r}=await Promise.resolve().then(()=>Ia),i=r();if(!i){j.warn("ActionDispatcher not available for init_actions");return}j.log("Executing init_actions:",e.map(d=>d.handler)),j.log("Init actions dataContext:",a),j.log("Init actions dataContext._global:",a._global);const o=e.map(d=>d.handler).filter(d=>d.includes("."));o.length>0&&await this.waitForHandlers(i,o);let u={...a};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},g=i.createHandler(f,u),m=new Event("init");await g(m),j.log(`Init action executed: ${d.handler}`);const b=this.globalState;u={...u,_global:{...b},_local:b._local||u._local||{}},j.log(`Data context refreshed after ${d.handler}:`,{cartKey:u._global?.cartKey})}catch(f){j.error(`Failed to execute init action: ${d.handler}`,f)}}async waitForHandlers(e,a,r=5e3){const i=Date.now(),o=50,u=()=>a.every(d=>e.customHandlers?.has(d));if(u()){j.log("All module handlers already registered");return}return j.log("Waiting for module handlers:",a),new Promise(d=>{const f=()=>{if(u()){j.log("All module handlers now registered"),d();return}if(Date.now()-i>=r){const g=a.filter(m=>!e.customHandlers?.has(m));j.warn("Timeout waiting for handlers:",g),d();return}setTimeout(f,o)};f()})}};$(Ea,"LOCALE_STORAGE_KEY","g7_locale"),$(Ea,"CACHE_VERSION_STORAGE_KEY","g7_cache_version");let mo=Ea;function Xd(l){const e=new mo(l);return l.websocket&&(hc.configure(l.websocket),j.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=Xd,window.G7Core.dataSource={refetch:async(l,e)=>{const a=window.__templateApp;if(!a){j.warn("TemplateApp not initialized (G7Core.dataSource.refetch)");return}return a.refetchDataSource(l,e)},get:l=>{const e=window.__templateApp;if(!e){j.warn("TemplateApp not initialized (G7Core.dataSource.get)");return}return e.getDataSource(l)}});function KE(l={}){const{checked:e,value:a,name:r,type:i="checkbox"}=l,u=a!==void 0?a:i==="checkbox"||i==="radio"?e??!1:String(e??""),d={checked:e??!1,value:u,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 WE(l={}){const{button:e=0,clientX:a=0,clientY:r=0}=l;return{button:e,clientX:a,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 YE(){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 XE(l,e="keydown"){return{key:l,code:l.length===1?`Key${l.toUpperCase()}`:l,preventDefault:()=>{},stopPropagation:()=>{},nativeEvent:new KeyboardEvent(e,{key:l}),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 JE={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|le Line truncated
`)(a)}catch(r){B.warn(`Expression evaluation failed: ${e}`,r);return}}async executeInitActions(e,a={}){const{getActionDispatcher:r}=await Promise.resolve().then(()=>Ia),i=r();if(!i){B.warn("ActionDispatcher not available for init_actions");return}B.log("Executing init_actions:",e.map(d=>d.handler)),B.log("Init actions dataContext:",a),B.log("Init actions dataContext._global:",a._global);const l=e.map(d=>d.handler).filter(d=>d.includes("."));l.length>0&&await this.waitForHandlers(i,l);let u={...a};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},g=i.createHandler(f,u),m=new Event("init");await g(m),B.log(`Init action executed: ${d.handler}`);const b=this.globalState;u={...u,_global:{...b},_local:b._local||u._local||{}},B.log(`Data context refreshed after ${d.handler}:`,{cartKey:u._global?.cartKey})}catch(f){B.error(`Failed to execute init action: ${d.handler}`,f)}}async waitForHandlers(e,a,r=5e3){const i=Date.now(),l=50,u=()=>a.every(d=>e.customHandlers?.has(d));if(u()){B.log("All module handlers already registered");return}return B.log("Waiting for module handlers:",a),new Promise(d=>{const f=()=>{if(u()){B.log("All module handlers now registered"),d();return}if(Date.now()-i>=r){const g=a.filter(m=>!e.customHandlers?.has(m));B.warn("Timeout waiting for handlers:",g),d();return}setTimeout(f,l)};f()})}};$(Ca,"LOCALE_STORAGE_KEY","g7_locale"),$(Ca,"CACHE_VERSION_STORAGE_KEY","g7_cache_version");let po=Ca;function tf(o){const e=new po(o);return o.websocket&&(ic.configure(o.websocket),B.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=tf,window.G7Core.dataSource={refetch:async(o,e)=>{const a=window.__templateApp;if(!a){B.warn("TemplateApp not initialized (G7Core.dataSource.refetch)");return}return a.refetchDataSource(o,e)},get:o=>{const e=window.__templateApp;if(!e){B.warn("TemplateApp not initialized (G7Core.dataSource.get)");return}return e.getDataSource(o)}});function p_(o={}){const{checked:e,value:a,name:r,type:i="checkbox"}=o,u=a!==void 0?a:i==="checkbox"||i==="radio"?e??!1:String(e??""),d={checked:e??!1,value:u,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 m_(o={}){const{button:e=0,clientX:a=0,clientY:r=0}=o;return{button:e,clientX:a,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 y_(){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 b_(o,e="keydown"){return{key:o,code:o.length===1?`Key${o.toUpperCase()}`:o,preventDefault:()=>{},stopPropagation:()=>{},nativeEvent:new KeyboardEvent(e,{key:o}),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 v_={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|le Line truncated
//# sourceMappingURL=template-engine.min.js.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"template-engine.min.js","sources":["../../../node_modules/react/cjs/react.production.js","../../../node_modules/react/index.js","../../../node_modules/scheduler/cjs/scheduler.production.js","../../../node_modules/scheduler/index.js","../../../node_modules/react-dom/cjs/react-dom.production.js","../../../node_modules/react-dom/index.js","../../../node_modules/react-dom/cjs/react-dom-client.production.js","../../../node_modules/react-dom/client.js","../../../resources/js/core/utils/Logger.ts","../../../resources/js/core/template-engine/ComponentRegistry.ts","../../../resources/js/core/template-engine/TranslationEngine.ts","../../../resources/js/core/template-engine/PipeRegistry.ts","../../../resources/js/core/template-engine/rawMarkers.ts","../../../resources/js/core/template-engine/DataBindingEngine.ts","../../../resources/js/core/template-engine/ResponsiveManager.ts","../../../resources/js/core/template-engine/helpers/ConditionEvaluator.ts","../../../resources/js/core/template-engine/helpers/RenderHelpers.ts","../../../node_modules/axios/lib/helpers/bind.js","../../../node_modules/axios/lib/utils.js","../../../node_modules/axios/lib/core/AxiosError.js","../../../node_modules/axios/lib/helpers/null.js","../../../node_modules/axios/lib/helpers/toFormData.js","../../../node_modules/axios/lib/helpers/AxiosURLSearchParams.js","../../../node_modules/axios/lib/helpers/buildURL.js","../../../node_modules/axios/lib/core/InterceptorManager.js","../../../node_modules/axios/lib/defaults/transitional.js","../../../node_modules/axios/lib/platform/browser/index.js","../../../node_modules/axios/lib/platform/browser/classes/URLSearchParams.js","../../../node_modules/axios/lib/platform/browser/classes/FormData.js","../../../node_modules/axios/lib/platform/browser/classes/Blob.js","../../../node_modules/axios/lib/platform/common/utils.js","../../../node_modules/axios/lib/platform/index.js","../../../node_modules/axios/lib/helpers/toURLEncodedForm.js","../../../node_modules/axios/lib/helpers/formDataToJSON.js","../../../node_modules/axios/lib/defaults/index.js","../../../node_modules/axios/lib/helpers/parseHeaders.js","../../../node_modules/axios/lib/core/AxiosHeaders.js","../../../node_modules/axios/lib/core/transformData.js","../../../node_modules/axios/lib/cancel/isCancel.js","../../../node_modules/axios/lib/cancel/CanceledError.js","../../../node_modules/axios/lib/core/settle.js","../../../node_modules/axios/lib/helpers/parseProtocol.js","../../../node_modules/axios/lib/helpers/speedometer.js","../../../node_modules/axios/lib/helpers/throttle.js","../../../node_modules/axios/lib/helpers/progressEventReducer.js","../../../node_modules/axios/lib/helpers/isURLSameOrigin.js","../../../node_modules/axios/lib/helpers/cookies.js","../../../node_modules/axios/lib/helpers/isAbsoluteURL.js","../../../node_modules/axios/lib/helpers/combineURLs.js","../../../node_modules/axios/lib/core/buildFullPath.js","../../../node_modules/axios/lib/core/mergeConfig.js","../../../node_modules/axios/lib/helpers/resolveConfig.js","../../../node_modules/axios/lib/adapters/xhr.js","../../../node_modules/axios/lib/helpers/composeSignals.js","../../../node_modules/axios/lib/helpers/trackStream.js","../../../node_modules/axios/lib/adapters/fetch.js","../../../node_modules/axios/lib/adapters/adapters.js","../../../node_modules/axios/lib/core/dispatchRequest.js","../../../node_modules/axios/lib/env/data.js","../../../node_modules/axios/lib/helpers/validator.js","../../../node_modules/axios/lib/core/Axios.js","../../../node_modules/axios/lib/cancel/CancelToken.js","../../../node_modules/axios/lib/helpers/spread.js","../../../node_modules/axios/lib/helpers/isAxiosError.js","../../../node_modules/axios/lib/helpers/HttpStatusCode.js","../../../node_modules/axios/lib/axios.js","../../../node_modules/axios/index.js","../../../resources/js/core/identity/types.ts","../../../resources/js/core/identity/IdentityGuardInterceptor.ts","../../../resources/js/core/api/ApiClient.ts","../../../resources/js/core/auth/AuthManager.ts","../../../resources/js/core/types/ErrorHandling.ts","../../../resources/js/core/error/ErrorHandlingResolver.ts","../../../node_modules/react/cjs/react-jsx-runtime.production.js","../../../node_modules/react/jsx-runtime.js","../../../resources/js/core/template-engine/ParentContextProvider.tsx","../../../resources/js/core/template-engine/ActionDispatcher.ts","../../../resources/js/core/template-engine/TransitionManager.ts","../../../resources/js/core/template-engine/TransitionContext.tsx","../../../resources/js/core/template-engine/ResponsiveContext.tsx","../../../resources/js/core/hooks/useControllableState.ts","../../../resources/js/core/template-engine/FormContext.tsx","../../../resources/js/core/template-engine/IsolatedStateContext.tsx","../../../node_modules/@dnd-kit/utilities/dist/utilities.esm.js","../../../node_modules/@dnd-kit/accessibility/dist/accessibility.esm.js","../../../node_modules/@dnd-kit/core/dist/core.esm.jLine truncated
{"version":3,"file":"template-engine.min.js","sources":["../../../node_modules/react/cjs/react.production.js","../../../node_modules/react/index.js","../../../node_modules/scheduler/cjs/scheduler.production.js","../../../node_modules/scheduler/index.js","../../../node_modules/react-dom/cjs/react-dom.production.js","../../../node_modules/react-dom/index.js","../../../node_modules/react-dom/cjs/react-dom-client.production.js","../../../node_modules/react-dom/client.js","../../../resources/js/core/utils/Logger.ts","../../../resources/js/core/template-engine/ComponentRegistry.ts","../../../resources/js/core/template-engine/TranslationEngine.ts","../../../resources/js/core/template-engine/PipeRegistry.ts","../../../resources/js/core/template-engine/rawMarkers.ts","../../../resources/js/core/template-engine/DataBindingEngine.ts","../../../resources/js/core/template-engine/ResponsiveManager.ts","../../../resources/js/core/template-engine/helpers/ConditionEvaluator.ts","../../../resources/js/core/template-engine/helpers/RenderHelpers.ts","../../../node_modules/axios/lib/helpers/bind.js","../../../node_modules/axios/lib/utils.js","../../../node_modules/axios/lib/helpers/parseHeaders.js","../../../node_modules/axios/lib/helpers/sanitizeHeaderValue.js","../../../node_modules/axios/lib/core/AxiosHeaders.js","../../../node_modules/axios/lib/core/AxiosError.js","../../../node_modules/axios/lib/helpers/null.js","../../../node_modules/axios/lib/helpers/toFormData.js","../../../node_modules/axios/lib/helpers/AxiosURLSearchParams.js","../../../node_modules/axios/lib/helpers/buildURL.js","../../../node_modules/axios/lib/core/InterceptorManager.js","../../../node_modules/axios/lib/defaults/transitional.js","../../../node_modules/axios/lib/platform/browser/index.js","../../../node_modules/axios/lib/platform/browser/classes/URLSearchParams.js","../../../node_modules/axios/lib/platform/browser/classes/FormData.js","../../../node_modules/axios/lib/platform/browser/classes/Blob.js","../../../node_modules/axios/lib/platform/common/utils.js","../../../node_modules/axios/lib/platform/index.js","../../../node_modules/axios/lib/helpers/toURLEncodedForm.js","../../../node_modules/axios/lib/helpers/formDataToJSON.js","../../../node_modules/axios/lib/defaults/index.js","../../../node_modules/axios/lib/core/transformData.js","../../../node_modules/axios/lib/cancel/isCancel.js","../../../node_modules/axios/lib/cancel/CanceledError.js","../../../node_modules/axios/lib/core/settle.js","../../../node_modules/axios/lib/helpers/parseProtocol.js","../../../node_modules/axios/lib/helpers/speedometer.js","../../../node_modules/axios/lib/helpers/throttle.js","../../../node_modules/axios/lib/helpers/progressEventReducer.js","../../../node_modules/axios/lib/helpers/isURLSameOrigin.js","../../../node_modules/axios/lib/helpers/cookies.js","../../../node_modules/axios/lib/helpers/isAbsoluteURL.js","../../../node_modules/axios/lib/helpers/combineURLs.js","../../../node_modules/axios/lib/core/buildFullPath.js","../../../node_modules/axios/lib/core/mergeConfig.js","../../../node_modules/axios/lib/helpers/resolveConfig.js","../../../node_modules/axios/lib/adapters/xhr.js","../../../node_modules/axios/lib/helpers/composeSignals.js","../../../node_modules/axios/lib/helpers/trackStream.js","../../../node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js","../../../node_modules/axios/lib/env/data.js","../../../node_modules/axios/lib/adapters/fetch.js","../../../node_modules/axios/lib/adapters/adapters.js","../../../node_modules/axios/lib/core/dispatchRequest.js","../../../node_modules/axios/lib/helpers/validator.js","../../../node_modules/axios/lib/core/Axios.js","../../../node_modules/axios/lib/cancel/CancelToken.js","../../../node_modules/axios/lib/helpers/spread.js","../../../node_modules/axios/lib/helpers/isAxiosError.js","../../../node_modules/axios/lib/helpers/HttpStatusCode.js","../../../node_modules/axios/lib/axios.js","../../../node_modules/axios/index.js","../../../resources/js/core/identity/types.ts","../../../resources/js/core/identity/IdentityGuardInterceptor.ts","../../../resources/js/core/api/ApiClient.ts","../../../resources/js/core/auth/AuthManager.ts","../../../resources/js/core/types/ErrorHandling.ts","../../../resources/js/core/error/ErrorHandlingResolver.ts","../../../node_modules/react/cjs/react-jsx-runtime.production.js","../../../node_modules/react/jsx-runtime.js","../../../resources/js/core/template-engine/ParentContextProvider.tsx","../../../resources/js/core/template-engine/ActionDispatcher.ts","../../../resources/js/core/template-engine/TransitionManager.ts","../../../resources/js/core/template-engine/TransitionContext.tsx","../../../resources/js/core/template-engine/ResponsiveContext.tsx","../../../resources/js/core/hooks/useControllableState.ts","../../../resources/js/core/template-engine/FormContext.tsx","../../../resources/js/core/template-engine/IsolatedStateContext.tsx","../../../node_modules/@dnd-kit/utilities/dist/utiliLine truncated
@@ -5,6 +5,18 @@
>
> 형식: [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)
## [engine-v1.52.1] - 2026-07-10
### Fixed
#### `$localized()` 가 ActionDispatcher 경로에서 항상 ko 를 반환하던 문제
- `DataBindingEngine.evaluateExpression()` — `$localized()` 의 활성 로케일 해석이 `context.$locale || 'ko'` 로 하드코딩 폴백해, `$locale` 을 컨텍스트에 담지 않는 경로(`init_actions` / `actions` 등 ActionDispatcher 가 빌드하는 data context)에서 로케일과 무관하게 늘 ko 값을 반환했다. `$locale` 부재는 "로케일이 ko" 가 아니라 "이 경로가 로케일을 넘기지 않는다" 는 뜻이다.
- 로케일/`templateId` 해석을 `$localized` 와 `$t` 앞으로 끌어올려 공유한다. `$t` 가 engine-v1.38.2 에서 이미 갖고 있던 `window.__templateApp.getConfig()` 회수 폴백을 `$localized` 도 그대로 사용한다. 컨텍스트의 `$locale` 이 있으면 그것이 우선하고, 없을 때만 앱 설정에서 회수하며, 그마저 없으면 종전대로 ko 로 폴백한다.
- 부수 효과 — `$t` 의 로케일 회수 조건이 `!templateId` 에서 `!templateId || !locale` 로 넓어졌다. `$templateId` 는 있는데 `$locale` 만 없는 컨텍스트에서 종전에는 ko 로 번역되던 것이 이제 앱 로케일로 번역된다.
> 사용자 영향: 헤더 배송국가 셀렉터처럼 `init_actions` 파생으로 만든 다국어 목록이, 서버가 내려준 en/ja 이름 대신 한국어로 표시되던 문제가 해소된다.
## [engine-v1.52.0] - 2026-07-04
### Added
@@ -1119,13 +1119,33 @@ export class DataBindingEngine {
extendedContext.$computed = context._computed;
}
// 활성 로케일 / 템플릿 ID 해석 — $localized 와 $t 가 공유한다.
//
// @since engine-v1.38.2 ActionDispatcher 경로 fallback — bindActionsToProps
// 이후 createHandler 에서 빌드된 action data context 는 `$templateId`/`$locale`
// 을 명시적으로 포함하지 않을 수 있다. 이 경우 `window.__templateApp.getConfig()`
// 로부터 회수하여 `{{$event.target.checked ? '$t:A' : '$t:B'}}` 같은 조건부
// $t: 평가가 raw key 를 반환하던 버그를 해결한다.
//
// @since engine-v1.52.1 회수 결과를 `$localized` 도 공유한다. 이전에는 `$localized`
// 가 `$t` 보다 먼저 `context.$locale || 'ko'` 로 로케일을 확정해, ActionDispatcher
// 경로(init_actions 파생 등)에서 항상 ko 값을 반환했다. `$locale` 이 컨텍스트에
// 없는 것은 로케일이 ko 라는 뜻이 아니라 "이 경로가 로케일을 안 넘긴다"는 뜻이다.
let templateId = context.$templateId;
let resolvedLocale = context.$locale;
if (typeof window !== 'undefined' && (!templateId || !resolvedLocale)) {
const appConfig = (window as any).__templateApp?.getConfig?.();
templateId ??= appConfig?.templateId;
resolvedLocale ??= appConfig?.locale;
}
const locale = resolvedLocale || 'ko';
// $localized 헬퍼 함수 추가
// 다국어 객체에서 현재 로케일에 해당하는 값을 반환
// 사용법:
// $localized(value) - 객체면 로케일 우선순위로 반환, 문자열이면 그대로
// $localized(value, fallbackKey) - 활성 로케일 키 부재 시 $t(fallbackKey) 호출
// (settings JSON 등 시스템 카탈로그의 lang pack 보강용)
const locale = context.$locale || 'ko';
extendedContext.$localized = (value: any, fallbackKey?: string): string => {
if (value == null && !fallbackKey) {
return '';
@@ -1175,28 +1195,11 @@ export class DataBindingEngine {
// $t 헬퍼 함수 추가
// 번역 키를 사용하여 다국어 텍스트를 반환
// 사용법: $t('admin.settings.info.write_only') - 번역된 텍스트 반환
// 컨텍스트에서 번역 관련 정보 추출
//
// @since engine-v1.38.2 ActionDispatcher 경로 fallback — bindActionsToProps
// 이후 createHandler 에서 빌드된 action data context 는 `$templateId`/`$locale`
// 을 명시적으로 포함하지 않을 수 있다. 이 경우 `window.__templateApp.getConfig()`
// 로부터 회수하여 `{{$event.target.checked ? '$t:A' : '$t:B'}}` 같은 조건부
// $t: 평가가 raw key 를 반환하던 버그를 해결한다.
let templateId = context.$templateId;
let resolvedLocale = locale;
if (!templateId && typeof window !== 'undefined') {
const templateApp = (window as any).__templateApp;
const appConfig = templateApp?.getConfig?.();
if (appConfig?.templateId) {
templateId = appConfig.templateId;
if (!context.$locale && appConfig.locale) {
resolvedLocale = appConfig.locale;
}
}
}
// templateId / locale 은 위에서 해석된 값을 그대로 사용한다($localized 와 공유).
const translationContext = {
templateId: templateId || '',
locale: resolvedLocale,
locale,
};
extendedContext.$t = (key: string): string => {
if (!key || typeof key !== 'string') {
@@ -1,4 +1,4 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { DataBindingEngine, DataBindingError } from '../DataBindingEngine';
describe('DataBindingEngine', () => {
@@ -566,19 +566,103 @@ describe('DataBindingEngine', () => {
expect(result).toBe('');
});
it('$locale 없으면 ko 기본값 사용', () => {
it('$locale 없고 앱도 미초기화면 ko 기본값 사용', () => {
const context = {
_global: {
selectedModule: {
name: { ko: '게시판 모듈', en: 'Board Module' },
},
},
// $locale 없음
// $locale 없음 — window.__templateApp 도 없는 순수 환경
};
const result = engine.evaluateExpression('$localized(_global.selectedModule.name)', context);
expect(result).toBe('게시판 모듈');
});
/**
* ActionDispatcher 경로($locale 미주입)에서의 로케일 회수.
*
* `init_actions` / `actions` 로 실행되는 표현식의 data context 는 `$locale` 을 담지
* 않는다(ActionDispatcher 가 빌드하는 컨텍스트라 렌더 컨텍스트와 다르다). 이때
* `$localized` 가 `'ko'` 로 하드코딩 폴백하면, en/ja 로케일에서도 한국어 값이 나온다.
*
* `$t` 는 engine-v1.38.2 에서 동일 함정을 `window.__templateApp.getConfig()` 회수로
* 이미 해결했다. `$localized` 도 같은 회수 경로를 공유해야 한다.
*
* 회귀 배경(#459): 헤더 배송국가 셀렉터가 `init_actions` 파생이라, 서버가 en/ja 이름을
* 내려줘도 화면에는 늘 한국어 국가명이 표시됐다.
*/
describe('$locale 미주입 시 window.__templateApp 로케일 회수 (ActionDispatcher 경로)', () => {
const name = { ko: '대한민국', en: 'South Korea', ja: '大韓民国' };
afterEach(() => {
delete (window as any).__templateApp;
});
it('앱 로케일이 en 이면 en 값을 반환한다', () => {
(window as any).__templateApp = {
getConfig: () => ({ templateId: 'sirsoft-admin_basic', locale: 'en' }),
};
// $locale 없음 — ActionDispatcher 컨텍스트 모사
const result = engine.evaluateExpression('$localized(_global.country.name)', {
_global: { country: { name } },
});
expect(result).toBe('South Korea');
});
it('앱 로케일이 ja 이면 ja 값을 반환한다', () => {
(window as any).__templateApp = {
getConfig: () => ({ templateId: 'sirsoft-basic', locale: 'ja' }),
};
const result = engine.evaluateExpression('$localized(_global.country.name)', {
_global: { country: { name } },
});
expect(result).toBe('大韓民国');
});
it('컨텍스트의 $locale 이 앱 설정보다 우선한다', () => {
(window as any).__templateApp = {
getConfig: () => ({ templateId: 'sirsoft-basic', locale: 'ja' }),
};
const result = engine.evaluateExpression('$localized(_global.country.name)', {
_global: { country: { name } },
$locale: 'en',
});
expect(result).toBe('South Korea');
});
it('map() 콜백 안에서도 회수된 로케일이 적용된다 (파생 목록 생성 패턴)', () => {
(window as any).__templateApp = {
getConfig: () => ({ templateId: 'sirsoft-admin_basic', locale: 'en' }),
};
const result = engine.evaluateExpression(
'(_global.countries ?? []).map(c => ({ code: c.code, name: $localized(c.name) }))',
{
_global: {
countries: [
{ code: 'KR', name },
{ code: 'US', name: { ko: '미국', en: 'United States', ja: 'アメリカ' } },
],
},
}
);
expect(result).toEqual([
{ code: 'KR', name: 'South Korea' },
{ code: 'US', name: 'United States' },
]);
});
it('앱 설정에 locale 이 없으면 ko 로 폴백한다', () => {
(window as any).__templateApp = {
getConfig: () => ({ templateId: 'sirsoft-basic' }),
};
const result = engine.evaluateExpression('$localized(_global.country.name)', {
_global: { country: { name } },
});
expect(result).toBe('대한민국');
});
});
it('resolveBindings에서 $localized 사용', () => {
const context = {
_global: {
@@ -4,7 +4,7 @@
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
[Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
## [1.0.2] - 2026-07-09
## [1.0.2] - 2026-07-10
### Changed
@@ -12,6 +12,8 @@
### Fixed
- 헤더의 배송국가 선택에서 국가 이름이 어떤 언어로 사이트를 보든 항상 한국어로만 표시되던 문제를 수정했습니다. 이제 현재 보고 있는 언어로 국가 이름이 표시됩니다.
#### 모바일 화면
- 휴대폰 화면에서 헤더가 가로로 넘쳐 사이트명이 잘리고 메뉴 버튼이 화면 밖으로 밀려나던 문제를 수정했습니다. 언어·통화 선택은 메뉴(햄버거) 안으로 옮겼습니다.
@@ -85,11 +85,11 @@
}
},
{
"_comment": "헤더 배송국가 셀렉터 목록 주입 (MP08 후속). 활성 국가만 {code, name(현지화), flag_class(fi fi-xx)} 형태로. 해외배송 OFF 시 KR 만 활성이라 셀렉터 자연 숨김(2개↑ 게이트).",
"_comment": "헤더 배송국가 셀렉터 목록 주입 (MP08 후속). 활성 국가만 {code, name(현지화), flag_class(fi fi-xx)} 형태로. 해외배송 OFF 시 KR 만 활성이라 셀렉터 자연 숨김(2개↑ 게이트). 국가명 $localized(name, fallbackKey): 활성 로케일 키는 서버(localize_catalog_field)가 settings.countries.{code}.name 으로 미리 보강해 통상 즉시 hit 한다. fallbackKey 와 || c.code 는 보강이 실패한 경우의 방어선.",
"handler": "setState",
"params": {
"target": "global",
"availableShippingCountries": "{{(_global.modules?.['sirsoft-ecommerce']?.shipping?.available_countries ?? []).filter(c => c.is_active).map(c => ({ code: c.code, name: (c.name?.[_global.locale] ?? c.name?.ko ?? c.code), flag_class: ('fi fi-' + (c.code ?? '').toLowerCase()) }))}}"
"availableShippingCountries": "{{(_global.modules?.['sirsoft-ecommerce']?.shipping?.available_countries ?? []).filter(c => c.is_active).map(c => ({ code: c.code, name: ($localized(c.name, 'sirsoft-ecommerce::settings.countries.' + (c.code ?? '') + '.name') || c.code), flag_class: ('fi fi-' + (c.code ?? '').toLowerCase()) }))}}"
}
},
{