@spfn/cms 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +490 -0
  3. package/dist/actions.d.ts +9 -0
  4. package/dist/actions.d.ts.map +1 -0
  5. package/dist/actions.js +11 -0
  6. package/dist/actions.js.map +1 -0
  7. package/dist/client.d.ts +138 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +62 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/cms.config.d.ts +77 -0
  12. package/dist/cms.config.d.ts.map +1 -0
  13. package/dist/cms.config.js +111 -0
  14. package/dist/cms.config.js.map +1 -0
  15. package/dist/entities/cms-audit-logs.d.ts +213 -0
  16. package/dist/entities/cms-audit-logs.d.ts.map +1 -0
  17. package/dist/entities/cms-audit-logs.js +103 -0
  18. package/dist/entities/cms-audit-logs.js.map +1 -0
  19. package/dist/entities/cms-draft-cache.d.ts +188 -0
  20. package/dist/entities/cms-draft-cache.d.ts.map +1 -0
  21. package/dist/entities/cms-draft-cache.js +112 -0
  22. package/dist/entities/cms-draft-cache.js.map +1 -0
  23. package/dist/entities/cms-label-values.d.ts +192 -0
  24. package/dist/entities/cms-label-values.d.ts.map +1 -0
  25. package/dist/entities/cms-label-values.js +105 -0
  26. package/dist/entities/cms-label-values.js.map +1 -0
  27. package/dist/entities/cms-label-versions.d.ts +207 -0
  28. package/dist/entities/cms-label-versions.d.ts.map +1 -0
  29. package/dist/entities/cms-label-versions.js +80 -0
  30. package/dist/entities/cms-label-versions.js.map +1 -0
  31. package/dist/entities/cms-labels.d.ts +189 -0
  32. package/dist/entities/cms-labels.d.ts.map +1 -0
  33. package/dist/entities/cms-labels.js +48 -0
  34. package/dist/entities/cms-labels.js.map +1 -0
  35. package/dist/entities/cms-published-cache.d.ts +199 -0
  36. package/dist/entities/cms-published-cache.d.ts.map +1 -0
  37. package/dist/entities/cms-published-cache.js +103 -0
  38. package/dist/entities/cms-published-cache.js.map +1 -0
  39. package/dist/entities/index.d.ts +10 -0
  40. package/dist/entities/index.d.ts.map +1 -0
  41. package/dist/entities/index.js +10 -0
  42. package/dist/entities/index.js.map +1 -0
  43. package/dist/generators/index.d.ts +19 -0
  44. package/dist/generators/index.d.ts.map +1 -0
  45. package/dist/generators/index.js +19 -0
  46. package/dist/generators/index.js.map +1 -0
  47. package/dist/generators/label-sync-generator.d.ts +33 -0
  48. package/dist/generators/label-sync-generator.d.ts.map +1 -0
  49. package/dist/generators/label-sync-generator.js +86 -0
  50. package/dist/generators/label-sync-generator.js.map +1 -0
  51. package/dist/helpers/locale.actions.d.ts +132 -0
  52. package/dist/helpers/locale.actions.d.ts.map +1 -0
  53. package/dist/helpers/locale.actions.js +210 -0
  54. package/dist/helpers/locale.actions.js.map +1 -0
  55. package/dist/helpers/locale.constants.d.ts +10 -0
  56. package/dist/helpers/locale.constants.d.ts.map +1 -0
  57. package/dist/helpers/locale.constants.js +10 -0
  58. package/dist/helpers/locale.constants.js.map +1 -0
  59. package/dist/helpers/locale.d.ts +17 -0
  60. package/dist/helpers/locale.d.ts.map +1 -0
  61. package/dist/helpers/locale.js +20 -0
  62. package/dist/helpers/locale.js.map +1 -0
  63. package/dist/helpers/sync.d.ts +41 -0
  64. package/dist/helpers/sync.d.ts.map +1 -0
  65. package/dist/helpers/sync.js +309 -0
  66. package/dist/helpers/sync.js.map +1 -0
  67. package/dist/index.d.ts +20 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +24 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/init.d.ts +31 -0
  72. package/dist/init.d.ts.map +1 -0
  73. package/dist/init.js +36 -0
  74. package/dist/init.js.map +1 -0
  75. package/dist/labels/helpers.d.ts +31 -0
  76. package/dist/labels/helpers.d.ts.map +1 -0
  77. package/dist/labels/helpers.js +60 -0
  78. package/dist/labels/helpers.js.map +1 -0
  79. package/dist/labels/index.d.ts +7 -0
  80. package/dist/labels/index.d.ts.map +1 -0
  81. package/dist/labels/index.js +7 -0
  82. package/dist/labels/index.js.map +1 -0
  83. package/dist/repositories/cms-draft-cache.repository.d.ts +62 -0
  84. package/dist/repositories/cms-draft-cache.repository.d.ts.map +1 -0
  85. package/dist/repositories/cms-draft-cache.repository.js +56 -0
  86. package/dist/repositories/cms-draft-cache.repository.js.map +1 -0
  87. package/dist/repositories/cms-label-values.repository.d.ts +32 -0
  88. package/dist/repositories/cms-label-values.repository.d.ts.map +1 -0
  89. package/dist/repositories/cms-label-values.repository.js +72 -0
  90. package/dist/repositories/cms-label-values.repository.js.map +1 -0
  91. package/dist/repositories/cms-labels.repository.d.ts +53 -0
  92. package/dist/repositories/cms-labels.repository.d.ts.map +1 -0
  93. package/dist/repositories/cms-labels.repository.js +77 -0
  94. package/dist/repositories/cms-labels.repository.js.map +1 -0
  95. package/dist/repositories/cms-published-cache.repository.d.ts +53 -0
  96. package/dist/repositories/cms-published-cache.repository.d.ts.map +1 -0
  97. package/dist/repositories/cms-published-cache.repository.js +54 -0
  98. package/dist/repositories/cms-published-cache.repository.js.map +1 -0
  99. package/dist/repositories/index.d.ts +8 -0
  100. package/dist/repositories/index.d.ts.map +1 -0
  101. package/dist/repositories/index.js +9 -0
  102. package/dist/repositories/index.js.map +1 -0
  103. package/dist/routes/labels/[id]/contract.d.ts +68 -0
  104. package/dist/routes/labels/[id]/contract.d.ts.map +1 -0
  105. package/dist/routes/labels/[id]/contract.js +84 -0
  106. package/dist/routes/labels/[id]/contract.js.map +1 -0
  107. package/dist/routes/labels/[id]/index.d.ts +10 -0
  108. package/dist/routes/labels/[id]/index.d.ts.map +1 -0
  109. package/dist/routes/labels/[id]/index.js +96 -0
  110. package/dist/routes/labels/[id]/index.js.map +1 -0
  111. package/dist/routes/labels/by-key/[key]/contract.d.ts +24 -0
  112. package/dist/routes/labels/by-key/[key]/contract.d.ts.map +1 -0
  113. package/dist/routes/labels/by-key/[key]/contract.js +28 -0
  114. package/dist/routes/labels/by-key/[key]/contract.js.map +1 -0
  115. package/dist/routes/labels/by-key/[key]/index.d.ts +8 -0
  116. package/dist/routes/labels/by-key/[key]/index.d.ts.map +1 -0
  117. package/dist/routes/labels/by-key/[key]/index.js +32 -0
  118. package/dist/routes/labels/by-key/[key]/index.js.map +1 -0
  119. package/dist/routes/labels/contract.d.ts +59 -0
  120. package/dist/routes/labels/contract.d.ts.map +1 -0
  121. package/dist/routes/labels/contract.js +75 -0
  122. package/dist/routes/labels/contract.js.map +1 -0
  123. package/dist/routes/labels/index.d.ts +10 -0
  124. package/dist/routes/labels/index.d.ts.map +1 -0
  125. package/dist/routes/labels/index.js +73 -0
  126. package/dist/routes/labels/index.js.map +1 -0
  127. package/dist/routes/published-cache/contract.d.ts +25 -0
  128. package/dist/routes/published-cache/contract.d.ts.map +1 -0
  129. package/dist/routes/published-cache/contract.js +35 -0
  130. package/dist/routes/published-cache/contract.js.map +1 -0
  131. package/dist/routes/published-cache/index.d.ts +8 -0
  132. package/dist/routes/published-cache/index.d.ts.map +1 -0
  133. package/dist/routes/published-cache/index.js +33 -0
  134. package/dist/routes/published-cache/index.js.map +1 -0
  135. package/dist/routes/sync/contract.d.ts +33 -0
  136. package/dist/routes/sync/contract.d.ts.map +1 -0
  137. package/dist/routes/sync/contract.js +34 -0
  138. package/dist/routes/sync/contract.js.map +1 -0
  139. package/dist/routes/sync/index.d.ts +13 -0
  140. package/dist/routes/sync/index.d.ts.map +1 -0
  141. package/dist/routes/sync/index.js +241 -0
  142. package/dist/routes/sync/index.js.map +1 -0
  143. package/dist/routes/values/[labelId]/[version]/contract.d.ts +29 -0
  144. package/dist/routes/values/[labelId]/[version]/contract.d.ts.map +1 -0
  145. package/dist/routes/values/[labelId]/[version]/contract.js +33 -0
  146. package/dist/routes/values/[labelId]/[version]/contract.js.map +1 -0
  147. package/dist/routes/values/[labelId]/[version]/index.d.ts +8 -0
  148. package/dist/routes/values/[labelId]/[version]/index.d.ts.map +1 -0
  149. package/dist/routes/values/[labelId]/[version]/index.js +45 -0
  150. package/dist/routes/values/[labelId]/[version]/index.js.map +1 -0
  151. package/dist/routes/values/[labelId]/contract.d.ts +38 -0
  152. package/dist/routes/values/[labelId]/contract.d.ts.map +1 -0
  153. package/dist/routes/values/[labelId]/contract.js +59 -0
  154. package/dist/routes/values/[labelId]/contract.js.map +1 -0
  155. package/dist/routes/values/[labelId]/index.d.ts +8 -0
  156. package/dist/routes/values/[labelId]/index.d.ts.map +1 -0
  157. package/dist/routes/values/[labelId]/index.js +42 -0
  158. package/dist/routes/values/[labelId]/index.js.map +1 -0
  159. package/dist/server.d.ts +99 -0
  160. package/dist/server.d.ts.map +1 -0
  161. package/dist/server.js +256 -0
  162. package/dist/server.js.map +1 -0
  163. package/dist/store.d.ts +87 -0
  164. package/dist/store.d.ts.map +1 -0
  165. package/dist/store.js +205 -0
  166. package/dist/store.js.map +1 -0
  167. package/dist/sync.d.ts +11 -0
  168. package/dist/sync.d.ts.map +1 -0
  169. package/dist/sync.js +179 -0
  170. package/dist/sync.js.map +1 -0
  171. package/dist/types.d.ts +74 -0
  172. package/dist/types.d.ts.map +1 -0
  173. package/dist/types.js +7 -0
  174. package/dist/types.js.map +1 -0
  175. package/package.json +95 -0
@@ -0,0 +1,210 @@
1
+ "use server";
2
+ /**
3
+ * Locale Management Server Actions
4
+ *
5
+ * Server Actions으둜 κ΅¬ν˜„λœ locale 관리 ν•¨μˆ˜
6
+ * - μ„œλ²„ μ»΄ν¬λ„ŒνŠΈ: 일반 ν•¨μˆ˜ 호좜둜 λ™μž‘
7
+ * - ν΄λΌμ΄μ–ΈνŠΈ μ»΄ν¬λ„ŒνŠΈ: Server Action으둜 μžλ™ 처리
8
+ */
9
+ import { cookies, headers } from 'next/headers';
10
+ import { getCmsConfig } from '../cms.config.js';
11
+ import { LOCALE_COOKIE_KEY } from './locale.constants.js';
12
+ /**
13
+ * λΈŒλΌμš°μ € μ–Έμ–΄ 감지
14
+ *
15
+ * Accept-Language ν—€λ”μ—μ„œ μ§€μ›ν•˜λŠ” μ–Έμ–΄λ₯Ό μ°ΎμŠ΅λ‹ˆλ‹€.
16
+ *
17
+ * @returns κ°μ§€λœ μ–Έμ–΄ μ½”λ“œ λ˜λŠ” null
18
+ */
19
+ async function detectBrowserLanguage() {
20
+ try {
21
+ const headersList = await headers();
22
+ const acceptLanguage = headersList.get('accept-language');
23
+ if (!acceptLanguage) {
24
+ return null;
25
+ }
26
+ // "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7" ν˜•μ‹ νŒŒμ‹±
27
+ const languages = acceptLanguage
28
+ .split(',')
29
+ .map(lang => {
30
+ const [code] = lang.split(';');
31
+ return code.split('-')[0].trim();
32
+ });
33
+ const config = getCmsConfig();
34
+ // μ§€μ›ν•˜λŠ” μ–Έμ–΄ 쀑 첫 번째 λ§€μΉ­λ˜λŠ” μ–Έμ–΄ λ°˜ν™˜
35
+ for (const lang of languages) {
36
+ if (config.supportedLocales.includes(lang)) {
37
+ return lang;
38
+ }
39
+ }
40
+ return null;
41
+ }
42
+ catch (error) {
43
+ // 헀더 μ ‘κ·Ό μ‹€νŒ¨ μ‹œ
44
+ return null;
45
+ }
46
+ }
47
+ /**
48
+ * ν˜„μž¬ locale κ°€μ Έμ˜€κΈ° (Server Action)
49
+ *
50
+ * μ„œλ²„/ν΄λΌμ΄μ–ΈνŠΈ μ»΄ν¬λ„ŒνŠΈ λͺ¨λ‘μ—μ„œ μ‚¬μš© κ°€λŠ₯
51
+ *
52
+ * μš°μ„ μˆœμœ„:
53
+ * 1. μΏ ν‚€ (μ‚¬μš©μžκ°€ λͺ…μ‹œμ μœΌλ‘œ μ„ νƒν•œ μ–Έμ–΄)
54
+ * 2. λΈŒλΌμš°μ € μ–Έμ–΄ 감지 (μ„€μ •μ—μ„œ ν™œμ„±ν™”λœ 경우)
55
+ * 3. μ‹œμŠ€ν…œ κΈ°λ³Έ μ–Έμ–΄ (CMS μ„€μ •)
56
+ *
57
+ * @returns ν˜„μž¬ locale (예: 'ko', 'en')
58
+ *
59
+ * @example
60
+ * ```tsx
61
+ * // Server Component
62
+ * import { getLocale } from '@spfn/cms';
63
+ *
64
+ * export default async function Page()
65
+ * {
66
+ * const locale = await getLocale();
67
+ * return <div>Current locale: {locale}</div>;
68
+ * }
69
+ * ```
70
+ *
71
+ * @example
72
+ * ```tsx
73
+ * // Client Component
74
+ * 'use client';
75
+ * import { getLocale } from '@spfn/cms/client';
76
+ *
77
+ * export default function LanguageSwitcher()
78
+ * {
79
+ * const [locale, setLocale] = useState('');
80
+ *
81
+ * useEffect(() => {
82
+ * getLocale().then(setLocale);
83
+ * }, []);
84
+ *
85
+ * return <div>Current locale: {locale}</div>;
86
+ * }
87
+ * ```
88
+ */
89
+ export async function getLocale() {
90
+ const config = getCmsConfig();
91
+ // 1μˆœμœ„: μΏ ν‚€ (μ‚¬μš©μžκ°€ λͺ…μ‹œμ μœΌλ‘œ μ„ νƒν•œ μ–Έμ–΄)
92
+ const cookieStore = await cookies();
93
+ const cookieLocale = cookieStore.get(LOCALE_COOKIE_KEY)?.value;
94
+ if (cookieLocale && config.supportedLocales.includes(cookieLocale)) {
95
+ return cookieLocale;
96
+ }
97
+ // 2μˆœμœ„: λΈŒλΌμš°μ € μ–Έμ–΄ 감지 (μ„€μ •μ—μ„œ ν™œμ„±ν™”λœ 경우)
98
+ if (config.detectBrowserLanguage) {
99
+ const browserLang = await detectBrowserLanguage();
100
+ if (browserLang) {
101
+ return browserLang;
102
+ }
103
+ }
104
+ // 3μˆœμœ„: μ‹œμŠ€ν…œ κΈ°λ³Έ μ–Έμ–΄
105
+ return config.defaultLocale;
106
+ }
107
+ /**
108
+ * Locale μ„€μ •ν•˜κΈ° (Server Action)
109
+ *
110
+ * μ„œλ²„/ν΄λΌμ΄μ–ΈνŠΈ μ»΄ν¬λ„ŒνŠΈ λͺ¨λ‘μ—μ„œ μ‚¬μš© κ°€λŠ₯
111
+ * 쿠킀에 locale을 μ €μž₯ν•©λ‹ˆλ‹€.
112
+ *
113
+ * @param locale - μ„€μ •ν•  locale (예: 'ko', 'en')
114
+ * @throws {Error} μ§€μ›ν•˜μ§€ μ•ŠλŠ” locale인 경우
115
+ *
116
+ * @example
117
+ * ```tsx
118
+ * // Server Component (Server Action)
119
+ * import { setLocale } from '@spfn/cms';
120
+ *
121
+ * export default async function Page()
122
+ * {
123
+ * await setLocale('en');
124
+ * return <div>Locale changed</div>;
125
+ * }
126
+ * ```
127
+ *
128
+ * @example
129
+ * ```tsx
130
+ * // Client Component (Server Action)
131
+ * 'use client';
132
+ * import { setLocale } from '@spfn/cms/client';
133
+ *
134
+ * export default function LanguageSwitcher()
135
+ * {
136
+ * const handleChange = async (newLocale: string) =>
137
+ * {
138
+ * await setLocale(newLocale);
139
+ * window.location.reload(); // νŽ˜μ΄μ§€ μƒˆλ‘œκ³ μΉ¨
140
+ * };
141
+ *
142
+ * return (
143
+ * <button onClick={() => handleChange('en')}>
144
+ * Switch to English
145
+ * </button>
146
+ * );
147
+ * }
148
+ * ```
149
+ */
150
+ export async function setLocale(locale) {
151
+ const config = getCmsConfig();
152
+ // μœ νš¨μ„± 검사
153
+ if (!config.supportedLocales.includes(locale)) {
154
+ throw new Error(`Unsupported locale: ${locale}. Supported locales: ${config.supportedLocales.join(', ')}`);
155
+ }
156
+ const cookieStore = await cookies();
157
+ cookieStore.set(LOCALE_COOKIE_KEY, locale, {
158
+ path: '/',
159
+ maxAge: 60 * 60 * 24 * 365, // 1λ…„
160
+ sameSite: 'lax',
161
+ });
162
+ }
163
+ /**
164
+ * μ§€μ›ν•˜λŠ” locale λͺ©λ‘ κ°€μ Έμ˜€κΈ° (Server Action)
165
+ *
166
+ * μ„œλ²„/ν΄λΌμ΄μ–ΈνŠΈ μ»΄ν¬λ„ŒνŠΈ λͺ¨λ‘μ—μ„œ μ‚¬μš© κ°€λŠ₯
167
+ *
168
+ * @returns μ§€μ›ν•˜λŠ” locale λ°°μ—΄ (예: ['ko', 'en', 'ja'])
169
+ *
170
+ * @example
171
+ * ```tsx
172
+ * // Server Component
173
+ * import { getLocales } from '@spfn/cms';
174
+ *
175
+ * export default async function Page()
176
+ * {
177
+ * const locales = await getLocales();
178
+ * return <div>Supported: {locales.join(', ')}</div>;
179
+ * }
180
+ * ```
181
+ *
182
+ * @example
183
+ * ```tsx
184
+ * // Client Component
185
+ * 'use client';
186
+ * import { getLocales } from '@spfn/cms/client';
187
+ *
188
+ * export default function LanguageSwitcher()
189
+ * {
190
+ * const [locales, setLocales] = useState<string[]>([]);
191
+ *
192
+ * useEffect(() => {
193
+ * getLocales().then(setLocales);
194
+ * }, []);
195
+ *
196
+ * return (
197
+ * <div>
198
+ * {locales.map(locale => (
199
+ * <button key={locale}>{locale}</button>
200
+ * ))}
201
+ * </div>
202
+ * );
203
+ * }
204
+ * ```
205
+ */
206
+ export async function getLocales() {
207
+ const config = getCmsConfig();
208
+ return config.supportedLocales;
209
+ }
210
+ //# sourceMappingURL=locale.actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.actions.js","sourceRoot":"","sources":["../../src/helpers/locale.actions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Locale Constants
3
+ *
4
+ * Server/Client μ–‘μͺ½μ—μ„œ μ‚¬μš© κ°€λŠ₯ν•œ locale κ΄€λ ¨ μƒμˆ˜
5
+ */
6
+ /**
7
+ * Locale μΏ ν‚€ ν‚€
8
+ */
9
+ export declare const LOCALE_COOKIE_KEY = "spfn-locale";
10
+ //# sourceMappingURL=locale.constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.constants.d.ts","sourceRoot":"","sources":["../../src/helpers/locale.constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB,gBAAgB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Locale Constants
3
+ *
4
+ * Server/Client μ–‘μͺ½μ—μ„œ μ‚¬μš© κ°€λŠ₯ν•œ locale κ΄€λ ¨ μƒμˆ˜
5
+ */
6
+ /**
7
+ * Locale μΏ ν‚€ ν‚€
8
+ */
9
+ export const LOCALE_COOKIE_KEY = 'spfn-locale';
10
+ //# sourceMappingURL=locale.constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.constants.js","sourceRoot":"","sources":["../../src/helpers/locale.constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC"}
@@ -0,0 +1,17 @@
1
+ import "server-only";
2
+ /**
3
+ * Locale Management Module (Server Components)
4
+ *
5
+ * μ„œλ²„ μ»΄ν¬λ„ŒνŠΈμš© locale 관리 (Server Actions re-export)
6
+ * μ‹€μ œ κ΅¬ν˜„μ€ locale.actions.ts μ°Έμ‘°
7
+ */
8
+ export { getLocale, setLocale, getLocales, } from './locale.actions.js';
9
+ export { LOCALE_COOKIE_KEY } from './locale.constants.js';
10
+ /**
11
+ * Locale μœ νš¨μ„± 검사
12
+ *
13
+ * @param locale - 검사할 locale
14
+ * @returns 지원 μ—¬λΆ€
15
+ */
16
+ export declare function isValidLocale(locale: string): Promise<boolean>;
17
+ //# sourceMappingURL=locale.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../src/helpers/locale.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAErB;;;;;GAKG;AAEH,OAAO,EACH,SAAS,EACT,SAAS,EACT,UAAU,GACb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAIpE"}
@@ -0,0 +1,20 @@
1
+ import "server-only";
2
+ /**
3
+ * Locale Management Module (Server Components)
4
+ *
5
+ * μ„œλ²„ μ»΄ν¬λ„ŒνŠΈμš© locale 관리 (Server Actions re-export)
6
+ * μ‹€μ œ κ΅¬ν˜„μ€ locale.actions.ts μ°Έμ‘°
7
+ */
8
+ export { getLocale, setLocale, getLocales, } from './locale.actions.js';
9
+ export { LOCALE_COOKIE_KEY } from './locale.constants.js';
10
+ /**
11
+ * Locale μœ νš¨μ„± 검사
12
+ *
13
+ * @param locale - 검사할 locale
14
+ * @returns 지원 μ—¬λΆ€
15
+ */
16
+ export async function isValidLocale(locale) {
17
+ const locales = await import('./locale.actions.js').then(m => m.getLocales());
18
+ return locales.includes(locale);
19
+ }
20
+ //# sourceMappingURL=locale.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.js","sourceRoot":"","sources":["../../src/helpers/locale.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAErB;;;;;GAKG;AAEH,OAAO,EACH,SAAS,EACT,SAAS,EACT,UAAU,GACb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAc;IAE9C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9E,OAAO,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * CMS Sync Utilities
3
+ *
4
+ * JSON 파일 기반 라벨 동기화
5
+ */
6
+ import type { SectionDefinition, SyncOptions, SyncResult } from '../types';
7
+ /**
8
+ * μ—¬λŸ¬ μ„Ήμ…˜ 동기화
9
+ */
10
+ export declare function syncAll(sections: SectionDefinition[], options?: SyncOptions): Promise<SyncResult[]>;
11
+ /**
12
+ * JSON νŒŒμΌμ—μ„œ 라벨 λ‘œλ“œ
13
+ */
14
+ export declare function loadLabelsFromJson(labelsDir: string): SectionDefinition[];
15
+ /**
16
+ * μ„Ήμ…˜ 라벨 동기화
17
+ */
18
+ export declare function syncSection(definition: SectionDefinition, options?: SyncOptions): Promise<SyncResult>;
19
+ /**
20
+ * Initialize label sync for server startup
21
+ *
22
+ * Call this in your server.config.ts beforeRoutes hook
23
+ *
24
+ * @param options - Sync options
25
+ * @param options.labelsDir - Path to labels directory (default: 'src/cms/labels')
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * import { initLabelSync } from '@spfn/cms';
30
+ *
31
+ * export default {
32
+ * beforeRoutes: async (app) => {
33
+ * await initLabelSync({ verbose: true });
34
+ * },
35
+ * } satisfies ServerConfig;
36
+ * ```
37
+ */
38
+ export declare function initLabelSync(options?: SyncOptions & {
39
+ labelsDir?: string;
40
+ }): Promise<void>;
41
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/helpers/sync.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAgB,iBAAiB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEzF;;GAEG;AACH,wBAAsB,OAAO,CACzB,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,OAAO,GAAE,WAAgB,GAC1B,OAAO,CAAC,UAAU,EAAE,CAAC,CAWvB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAqCzE;AAqCD;;GAEG;AACH,wBAAsB,WAAW,CAC7B,UAAU,EAAE,iBAAiB,EAC7B,OAAO,GAAE,WAAgB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAoKrB;AAyDD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,WAAW,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAgErG"}
@@ -0,0 +1,309 @@
1
+ /**
2
+ * CMS Sync Utilities
3
+ *
4
+ * JSON 파일 기반 라벨 동기화
5
+ */
6
+ import { existsSync, readdirSync, readFileSync, statSync } from 'fs';
7
+ import { basename, extname, join } from 'path';
8
+ import { extractLabels } from '../labels';
9
+ import { cmsLabelsRepository, cmsPublishedCacheRepository } from '../repositories';
10
+ /**
11
+ * μ—¬λŸ¬ μ„Ήμ…˜ 동기화
12
+ */
13
+ export async function syncAll(sections, options = {}) {
14
+ const results = [];
15
+ for (const definition of sections) {
16
+ const result = await syncSection(definition, options);
17
+ results.push(result);
18
+ }
19
+ return results;
20
+ }
21
+ /**
22
+ * JSON νŒŒμΌμ—μ„œ 라벨 λ‘œλ“œ
23
+ */
24
+ export function loadLabelsFromJson(labelsDir) {
25
+ const sections = [];
26
+ if (!existsSync(labelsDir)) {
27
+ console.warn(`[CMS] Labels directory not found: ${labelsDir}`);
28
+ return sections;
29
+ }
30
+ try {
31
+ const entries = readdirSync(labelsDir);
32
+ for (const entry of entries) {
33
+ const sectionPath = join(labelsDir, entry);
34
+ const stat = statSync(sectionPath);
35
+ if (stat.isDirectory()) {
36
+ const sectionName = entry;
37
+ const labels = loadSectionLabels(sectionPath);
38
+ if (Object.keys(labels).length > 0) {
39
+ sections.push({ section: sectionName, labels });
40
+ }
41
+ }
42
+ }
43
+ }
44
+ catch (error) {
45
+ console.warn(`[CMS] Could not scan labels directory: ${labelsDir}`);
46
+ }
47
+ return sections;
48
+ }
49
+ function loadSectionLabels(sectionPath) {
50
+ const labels = {};
51
+ try {
52
+ const files = readdirSync(sectionPath);
53
+ for (const file of files) {
54
+ if (extname(file) === '.json') {
55
+ const filePath = join(sectionPath, file);
56
+ const categoryName = basename(file, '.json');
57
+ try {
58
+ const content = readFileSync(filePath, 'utf-8');
59
+ labels[categoryName] = JSON.parse(content);
60
+ }
61
+ catch (error) {
62
+ console.warn(`[CMS] Failed to parse ${filePath}`);
63
+ }
64
+ }
65
+ }
66
+ }
67
+ catch (error) {
68
+ console.warn(`[CMS] Could not read section directory: ${sectionPath}`);
69
+ }
70
+ return labels;
71
+ }
72
+ /**
73
+ * μ„Ήμ…˜ 라벨 동기화
74
+ */
75
+ export async function syncSection(definition, options = {}) {
76
+ const { dryRun = false, updateExisting = false, removeUnused = false, verbose = false, } = options;
77
+ const { section } = definition;
78
+ const result = {
79
+ section,
80
+ created: 0,
81
+ updated: 0,
82
+ deleted: 0,
83
+ unchanged: 0,
84
+ errors: [],
85
+ };
86
+ try {
87
+ const definedLabels = extractLabels(definition);
88
+ const definedKeys = new Set(definedLabels.map((l) => l.key));
89
+ const existingLabels = await cmsLabelsRepository.findBySection(section);
90
+ const existingMap = new Map(existingLabels.map((l) => [l.key, l]));
91
+ if (verbose) {
92
+ console.log(`\n[${section}] Found ${definedLabels.length} labels in definition`);
93
+ console.log(`[${section}] Found ${existingLabels.length} labels in DB`);
94
+ }
95
+ // 생성 및 μ—…λ°μ΄νŠΈ
96
+ for (const label of definedLabels) {
97
+ const existing = existingMap.get(label.key);
98
+ if (!existing) {
99
+ if (verbose)
100
+ console.log(` [CREATE] ${label.key}`);
101
+ if (!dryRun) {
102
+ try {
103
+ const defaultValue = typeof label.defaultValue === 'object'
104
+ ? JSON.stringify(label.defaultValue)
105
+ : label.defaultValue;
106
+ await cmsLabelsRepository.create({
107
+ section,
108
+ key: label.key,
109
+ type: 'text',
110
+ defaultValue,
111
+ description: label.description,
112
+ });
113
+ }
114
+ catch (error) {
115
+ result.errors.push({
116
+ key: label.key,
117
+ error: error instanceof Error ? error.message : String(error),
118
+ });
119
+ continue;
120
+ }
121
+ }
122
+ result.created++;
123
+ }
124
+ else if (updateExisting) {
125
+ const newDefaultValue = typeof label.defaultValue === 'object'
126
+ ? JSON.stringify(label.defaultValue)
127
+ : label.defaultValue;
128
+ const hasChanged = existing.defaultValue !== newDefaultValue;
129
+ if (hasChanged) {
130
+ if (verbose) {
131
+ console.log(` [UPDATE] ${label.key}`);
132
+ console.log(` Old: "${existing.defaultValue}"`);
133
+ console.log(` New: "${newDefaultValue}"`);
134
+ }
135
+ if (!dryRun) {
136
+ try {
137
+ await cmsLabelsRepository.updateById(existing.id, {
138
+ defaultValue: newDefaultValue,
139
+ description: label.description,
140
+ });
141
+ }
142
+ catch (error) {
143
+ result.errors.push({
144
+ key: label.key,
145
+ error: error instanceof Error ? error.message : String(error),
146
+ });
147
+ continue;
148
+ }
149
+ }
150
+ result.updated++;
151
+ }
152
+ else {
153
+ result.unchanged++;
154
+ }
155
+ }
156
+ else {
157
+ result.unchanged++;
158
+ }
159
+ }
160
+ // μ‚¬μš©λ˜μ§€ μ•ŠλŠ” 라벨 μ‚­μ œ
161
+ if (removeUnused) {
162
+ for (const existing of existingLabels) {
163
+ if (!definedKeys.has(existing.key)) {
164
+ if (verbose)
165
+ console.log(` [DELETE] ${existing.key}`);
166
+ if (!dryRun) {
167
+ try {
168
+ await cmsLabelsRepository.deleteById(existing.id);
169
+ }
170
+ catch (error) {
171
+ result.errors.push({
172
+ key: existing.key,
173
+ error: error instanceof Error ? error.message : String(error),
174
+ });
175
+ continue;
176
+ }
177
+ }
178
+ result.deleted++;
179
+ }
180
+ }
181
+ }
182
+ // Published cache μ—…λ°μ΄νŠΈ
183
+ if (!dryRun && (result.created > 0 || result.updated > 0 || result.deleted > 0)) {
184
+ if (verbose)
185
+ console.log(` [CACHE] Updating published cache for section: ${section}`);
186
+ await updatePublishedCache(section);
187
+ }
188
+ }
189
+ catch (error) {
190
+ result.errors.push({
191
+ key: '__section__',
192
+ error: error instanceof Error ? error.message : String(error),
193
+ });
194
+ }
195
+ return result;
196
+ }
197
+ /**
198
+ * Published Cache μ—…λ°μ΄νŠΈ
199
+ */
200
+ async function updatePublishedCache(section) {
201
+ const labels = await cmsLabelsRepository.findBySection(section);
202
+ const localesSet = new Set();
203
+ const labelsByLocale = {};
204
+ labels.forEach((label) => {
205
+ try {
206
+ const parsed = JSON.parse(label.defaultValue || '{}');
207
+ if (typeof parsed === 'object' && !Array.isArray(parsed)) {
208
+ // Multilingual
209
+ Object.keys(parsed).forEach((locale) => localesSet.add(locale));
210
+ Object.entries(parsed).forEach(([locale, value]) => {
211
+ if (!labelsByLocale[locale])
212
+ labelsByLocale[locale] = {};
213
+ labelsByLocale[locale][label.key] = value;
214
+ });
215
+ }
216
+ else {
217
+ // Single value
218
+ if (!labelsByLocale.ko)
219
+ labelsByLocale.ko = {};
220
+ labelsByLocale.ko[label.key] = label.defaultValue;
221
+ localesSet.add('ko');
222
+ }
223
+ }
224
+ catch {
225
+ // Plain string
226
+ if (!labelsByLocale.ko)
227
+ labelsByLocale.ko = {};
228
+ labelsByLocale.ko[label.key] = label.defaultValue;
229
+ localesSet.add('ko');
230
+ }
231
+ });
232
+ const timestamp = new Date();
233
+ for (const locale of localesSet) {
234
+ await cmsPublishedCacheRepository.upsert({
235
+ section,
236
+ locale,
237
+ content: labelsByLocale[locale] || {},
238
+ publishedAt: timestamp,
239
+ publishedBy: 'system',
240
+ });
241
+ }
242
+ }
243
+ /**
244
+ * Initialize label sync for server startup
245
+ *
246
+ * Call this in your server.config.ts beforeRoutes hook
247
+ *
248
+ * @param options - Sync options
249
+ * @param options.labelsDir - Path to labels directory (default: 'src/cms/labels')
250
+ *
251
+ * @example
252
+ * ```typescript
253
+ * import { initLabelSync } from '@spfn/cms';
254
+ *
255
+ * export default {
256
+ * beforeRoutes: async (app) => {
257
+ * await initLabelSync({ verbose: true });
258
+ * },
259
+ * } satisfies ServerConfig;
260
+ * ```
261
+ */
262
+ export async function initLabelSync(options = {}) {
263
+ const isDevelopment = process.env.NODE_ENV === 'development';
264
+ const verbose = options.verbose ?? isDevelopment;
265
+ const labelsDir = options.labelsDir ?? 'src/cms/labels';
266
+ if (verbose) {
267
+ console.log('\nπŸ”„ Initializing label sync...\n');
268
+ }
269
+ // Load labels from JSON files
270
+ const sections = loadLabelsFromJson(labelsDir);
271
+ if (sections.length === 0) {
272
+ if (verbose) {
273
+ console.log('⚠️ No labels found in', labelsDir);
274
+ console.log('');
275
+ }
276
+ return;
277
+ }
278
+ const results = await syncAll(sections, {
279
+ updateExisting: isDevelopment, // πŸ”„ 개발 ν™˜κ²½μ—μ„œλŠ” μžλ™μœΌλ‘œ μ—…λ°μ΄νŠΈ
280
+ ...options,
281
+ verbose,
282
+ });
283
+ const totalCreated = results.reduce((sum, r) => sum + r.created, 0);
284
+ const totalUpdated = results.reduce((sum, r) => sum + r.updated, 0);
285
+ const totalUnchanged = results.reduce((sum, r) => sum + r.unchanged, 0);
286
+ const totalErrors = results.reduce((sum, r) => sum + r.errors.length, 0);
287
+ if (verbose) {
288
+ console.log('βœ… Label sync completed\n');
289
+ console.log(` Sections: ${results.length}`);
290
+ console.log(` Created: ${totalCreated}`);
291
+ console.log(` Updated: ${totalUpdated}`);
292
+ console.log(` Unchanged: ${totalUnchanged}`);
293
+ if (totalErrors > 0) {
294
+ console.log(` Errors: ${totalErrors}\n`);
295
+ }
296
+ else {
297
+ console.log('');
298
+ }
299
+ }
300
+ // Log errors
301
+ if (totalErrors > 0) {
302
+ results.forEach((result) => {
303
+ result.errors.forEach((error) => {
304
+ console.error(`[${result.section}] ${error.key}: ${error.error}`);
305
+ });
306
+ });
307
+ }
308
+ }
309
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/helpers/sync.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAGnF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CACzB,QAA6B,EAC7B,UAAuB,EAAE;IAGzB,MAAM,OAAO,GAAiB,EAAE,CAAC;IAEjC,KAAK,MAAM,UAAU,IAAI,QAAQ,EACjC,CAAC;QACG,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAEhD,MAAM,QAAQ,GAAwB,EAAE,CAAC;IAEzC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAC1B,CAAC;QACG,OAAO,CAAC,IAAI,CAAC,qCAAqC,SAAS,EAAE,CAAC,CAAC;QAC/D,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED,IACA,CAAC;QACG,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;QAEvC,KAAK,MAAM,KAAK,IAAI,OAAO,EAC3B,CAAC;YACG,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;YAEnC,IAAI,IAAI,CAAC,WAAW,EAAE,EACtB,CAAC;gBACG,MAAM,WAAW,GAAG,KAAK,CAAC;gBAC1B,MAAM,MAAM,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;gBAE9C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,EAClC,CAAC;oBACG,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;gBACpD,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IACD,OAAO,KAAK,EACZ,CAAC;QACG,OAAO,CAAC,IAAI,CAAC,0CAA0C,SAAS,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC;AAED,SAAS,iBAAiB,CAAC,WAAmB;IAE1C,MAAM,MAAM,GAAiB,EAAE,CAAC;IAEhC,IACA,CAAC;QACG,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;QAEvC,KAAK,MAAM,IAAI,IAAI,KAAK,EACxB,CAAC;YACG,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO,EAC7B,CAAC;gBACG,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;gBACzC,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBAE7C,IACA,CAAC;oBACG,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAChD,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAC/C,CAAC;gBACD,OAAO,KAAK,EACZ,CAAC;oBACG,OAAO,CAAC,IAAI,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;gBACtD,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IACD,OAAO,KAAK,EACZ,CAAC;QACG,OAAO,CAAC,IAAI,CAAC,2CAA2C,WAAW,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC7B,UAA6B,EAC7B,UAAuB,EAAE;IAGzB,MAAM,EACF,MAAM,GAAG,KAAK,EACd,cAAc,GAAG,KAAK,EACtB,YAAY,GAAG,KAAK,EACpB,OAAO,GAAG,KAAK,GAClB,GAAG,OAAO,CAAC;IAEZ,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;IAC/B,MAAM,MAAM,GAAe;QACvB,OAAO;QACP,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,CAAC;QACZ,MAAM,EAAE,EAAE;KACb,CAAC;IAEF,IACA,CAAC;QACG,MAAM,aAAa,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;QAChD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7D,MAAM,cAAc,GAAG,MAAM,mBAAmB,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACxE,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAEnE,IAAI,OAAO,EACX,CAAC;YACG,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,WAAW,aAAa,CAAC,MAAM,uBAAuB,CAAC,CAAC;YACjF,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,WAAW,cAAc,CAAC,MAAM,eAAe,CAAC,CAAC;QAC5E,CAAC;QAED,YAAY;QACZ,KAAK,MAAM,KAAK,IAAI,aAAa,EACjC,CAAC;YACG,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAE5C,IAAI,CAAC,QAAQ,EACb,CAAC;gBACG,IAAI,OAAO;oBAAE,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;gBAEpD,IAAI,CAAC,MAAM,EACX,CAAC;oBACG,IACA,CAAC;wBACG,MAAM,YAAY,GAAG,OAAO,KAAK,CAAC,YAAY,KAAK,QAAQ;4BACvD,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC;4BACpC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;wBAEzB,MAAM,mBAAmB,CAAC,MAAM,CAAC;4BAC7B,OAAO;4BACP,GAAG,EAAE,KAAK,CAAC,GAAG;4BACd,IAAI,EAAE,MAAM;4BACZ,YAAY;4BACZ,WAAW,EAAE,KAAK,CAAC,WAAW;yBACjC,CAAC,CAAC;oBACP,CAAC;oBACD,OAAO,KAAK,EACZ,CAAC;wBACG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;4BACf,GAAG,EAAE,KAAK,CAAC,GAAG;4BACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;yBAChE,CAAC,CAAC;wBACH,SAAS;oBACb,CAAC;gBACL,CAAC;gBAED,MAAM,CAAC,OAAO,EAAE,CAAC;YACrB,CAAC;iBACI,IAAI,cAAc,EACvB,CAAC;gBACG,MAAM,eAAe,GAAG,OAAO,KAAK,CAAC,YAAY,KAAK,QAAQ;oBAC1D,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC;oBACpC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;gBAEzB,MAAM,UAAU,GAAG,QAAQ,CAAC,YAAY,KAAK,eAAe,CAAC;gBAE7D,IAAI,UAAU,EACd,CAAC;oBACG,IAAI,OAAO,EACX,CAAC;wBACG,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;wBACvC,OAAO,CAAC,GAAG,CAAC,aAAa,QAAQ,CAAC,YAAY,GAAG,CAAC,CAAC;wBACnD,OAAO,CAAC,GAAG,CAAC,aAAa,eAAe,GAAG,CAAC,CAAC;oBACjD,CAAC;oBAED,IAAI,CAAC,MAAM,EACX,CAAC;wBACG,IACA,CAAC;4BACG,MAAM,mBAAmB,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,EAAE;gCAC9C,YAAY,EAAE,eAAe;gCAC7B,WAAW,EAAE,KAAK,CAAC,WAAW;6BACjC,CAAC,CAAC;wBACP,CAAC;wBACD,OAAO,KAAK,EACZ,CAAC;4BACG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;gCACf,GAAG,EAAE,KAAK,CAAC,GAAG;gCACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;6BAChE,CAAC,CAAC;4BACH,SAAS;wBACb,CAAC;oBACL,CAAC;oBAED,MAAM,CAAC,OAAO,EAAE,CAAC;gBACrB,CAAC;qBAED,CAAC;oBACG,MAAM,CAAC,SAAS,EAAE,CAAC;gBACvB,CAAC;YACL,CAAC;iBAED,CAAC;gBACG,MAAM,CAAC,SAAS,EAAE,CAAC;YACvB,CAAC;QACL,CAAC;QAED,gBAAgB;QAChB,IAAI,YAAY,EAChB,CAAC;YACG,KAAK,MAAM,QAAQ,IAAI,cAAc,EACrC,CAAC;gBACG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAClC,CAAC;oBACG,IAAI,OAAO;wBAAE,OAAO,CAAC,GAAG,CAAC,cAAc,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;oBAEvD,IAAI,CAAC,MAAM,EACX,CAAC;wBACG,IACA,CAAC;4BACG,MAAM,mBAAmB,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;wBACtD,CAAC;wBACD,OAAO,KAAK,EACZ,CAAC;4BACG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;gCACf,GAAG,EAAE,QAAQ,CAAC,GAAG;gCACjB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;6BAChE,CAAC,CAAC;4BACH,SAAS;wBACb,CAAC;oBACL,CAAC;oBAED,MAAM,CAAC,OAAO,EAAE,CAAC;gBACrB,CAAC;YACL,CAAC;QACL,CAAC;QAED,uBAAuB;QACvB,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,EAC/E,CAAC;YACG,IAAI,OAAO;gBAAE,OAAO,CAAC,GAAG,CAAC,mDAAmD,OAAO,EAAE,CAAC,CAAC;YACvF,MAAM,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,EACZ,CAAC;QACG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,GAAG,EAAE,aAAa;YAClB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAChE,CAAC,CAAC;IACP,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,oBAAoB,CAAC,OAAe;IAE/C,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,MAAM,cAAc,GAAwC,EAAE,CAAC;IAE/D,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QAErB,IACA,CAAC;YACG,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC;YAEtD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EACxD,CAAC;gBACG,eAAe;gBACf,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;gBAChE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE;oBAE/C,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC;wBAAE,cAAc,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;oBACzD,cAAc,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;gBAC9C,CAAC,CAAC,CAAC;YACP,CAAC;iBAED,CAAC;gBACG,eAAe;gBACf,IAAI,CAAC,cAAc,CAAC,EAAE;oBAAE,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC;gBAC/C,cAAc,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC;gBAClD,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;QACL,CAAC;QACD,MACA,CAAC;YACG,eAAe;YACf,IAAI,CAAC,cAAc,CAAC,EAAE;gBAAE,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC;YAC/C,cAAc,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC;YAClD,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,KAAK,MAAM,MAAM,IAAI,UAAU,EAC/B,CAAC;QACG,MAAM,2BAA2B,CAAC,MAAM,CAAC;YACrC,OAAO;YACP,MAAM;YACN,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE;YACrC,WAAW,EAAE,SAAS;YACtB,WAAW,EAAE,QAAQ;SACxB,CAAC,CAAC;IACP,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAgD,EAAE;IAElF,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC;IAC7D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,aAAa,CAAC;IACjD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,gBAAgB,CAAC;IAExD,IAAI,OAAO,EACX,CAAC;QACG,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IACrD,CAAC;IAED,8BAA8B;IAC9B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAE/C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EACzB,CAAC;QACG,IAAI,OAAO,EACX,CAAC;YACG,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;YACjD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;QACD,OAAO;IACX,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE;QACpC,cAAc,EAAE,aAAa,EAAE,wBAAwB;QACvD,GAAG,OAAO;QACV,OAAO;KACV,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACxE,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAEzE,IAAI,OAAO,EACX,CAAC;QACG,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,gBAAgB,YAAY,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,gBAAgB,YAAY,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,iBAAiB,cAAc,EAAE,CAAC,CAAC;QAE/C,IAAI,WAAW,GAAG,CAAC,EACnB,CAAC;YACG,OAAO,CAAC,GAAG,CAAC,gBAAgB,WAAW,IAAI,CAAC,CAAC;QACjD,CAAC;aAED,CAAC;YACG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;IACL,CAAC;IAED,aAAa;IACb,IAAI,WAAW,GAAG,CAAC,EACnB,CAAC;QACG,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YAEvB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBAE5B,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YACtE,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;AACL,CAAC"}