@intlayer/vue-i18n 9.0.0-canary.1 → 9.0.0-canary.2
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.
- package/dist/cjs/createI18n.cjs +24 -36
- package/dist/cjs/createI18n.cjs.map +1 -1
- package/dist/cjs/formats.cjs +1 -1
- package/dist/cjs/formats.cjs.map +1 -1
- package/dist/cjs/useDictionary.cjs +44 -20
- package/dist/cjs/useDictionary.cjs.map +1 -1
- package/dist/cjs/useDictionaryDynamic.cjs +46 -18
- package/dist/cjs/useDictionaryDynamic.cjs.map +1 -1
- package/dist/esm/createI18n.mjs +25 -37
- package/dist/esm/createI18n.mjs.map +1 -1
- package/dist/esm/formats.mjs +1 -1
- package/dist/esm/formats.mjs.map +1 -1
- package/dist/esm/useDictionary.mjs +44 -20
- package/dist/esm/useDictionary.mjs.map +1 -1
- package/dist/esm/useDictionaryDynamic.mjs +46 -18
- package/dist/esm/useDictionaryDynamic.mjs.map +1 -1
- package/dist/types/createI18n.d.ts.map +1 -1
- package/dist/types/useDictionary.d.ts +13 -6
- package/dist/types/useDictionary.d.ts.map +1 -1
- package/dist/types/useDictionaryDynamic.d.ts +16 -6
- package/dist/types/useDictionaryDynamic.d.ts.map +1 -1
- package/package.json +8 -8
- package/dist/cjs/useI18nDictionary.cjs +0 -47
- package/dist/cjs/useI18nDictionary.cjs.map +0 -1
- package/dist/cjs/useI18nDictionaryDynamic.cjs +0 -43
- package/dist/cjs/useI18nDictionaryDynamic.cjs.map +0 -1
- package/dist/esm/useI18nDictionary.mjs +0 -45
- package/dist/esm/useI18nDictionary.mjs.map +0 -1
- package/dist/esm/useI18nDictionaryDynamic.mjs +0 -41
- package/dist/esm/useI18nDictionaryDynamic.mjs.map +0 -1
- package/dist/types/useI18nDictionary.d.ts +0 -22
- package/dist/types/useI18nDictionary.d.ts.map +0 -1
- package/dist/types/useI18nDictionaryDynamic.d.ts +0 -19
- package/dist/types/useI18nDictionaryDynamic.d.ts.map +0 -1
package/dist/cjs/createI18n.cjs
CHANGED
|
@@ -6,14 +6,12 @@ let _intlayer_config_built = require("@intlayer/config/built");
|
|
|
6
6
|
let _intlayer_config_colors = require("@intlayer/config/colors");
|
|
7
7
|
_intlayer_config_colors = require_runtime.__toESM(_intlayer_config_colors);
|
|
8
8
|
let _intlayer_config_logger = require("@intlayer/config/logger");
|
|
9
|
-
let _intlayer_core_interpreter = require("@intlayer/core/interpreter");
|
|
10
9
|
let vue = require("vue");
|
|
11
10
|
let vue_intlayer = require("vue-intlayer");
|
|
12
11
|
|
|
13
12
|
//#region src/createI18n.ts
|
|
14
13
|
const VERSION = "9.13.1";
|
|
15
14
|
const I18nInjectionKey = Symbol("global-i18n");
|
|
16
|
-
const DEFAULT_NAMESPACE = "translation";
|
|
17
15
|
const navigatePath = (objectValue, path) => {
|
|
18
16
|
if (!path) return objectValue;
|
|
19
17
|
let current = objectValue;
|
|
@@ -32,33 +30,23 @@ const navigatePath = (objectValue, path) => {
|
|
|
32
30
|
* 3. The first key segment as the dictionary key (`'home.title'` →
|
|
33
31
|
* dictionary `home`, path `title`)
|
|
34
32
|
*/
|
|
35
|
-
const lookupRaw = (
|
|
36
|
-
let targetNamespace = namespace;
|
|
37
|
-
let path = key;
|
|
33
|
+
const lookupRaw = (namespace, key) => {
|
|
38
34
|
if (key.includes(":")) {
|
|
39
35
|
const separatorIndex = key.indexOf(":");
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
try {
|
|
44
|
-
const value = navigatePath((0, _intlayer_core_interpreter.getIntlayer)(targetNamespace, locale), path);
|
|
45
|
-
if (value !== void 0 && value !== null) return value;
|
|
46
|
-
} catch {}
|
|
47
|
-
if (path.includes(".")) {
|
|
48
|
-
const separatorIndex = path.indexOf(".");
|
|
49
|
-
const firstSegment = path.slice(0, separatorIndex);
|
|
50
|
-
const restPath = path.slice(separatorIndex + 1);
|
|
51
|
-
try {
|
|
52
|
-
const value = navigatePath((0, _intlayer_core_interpreter.getIntlayer)(firstSegment, locale), restPath);
|
|
53
|
-
if (value !== void 0 && value !== null) return value;
|
|
54
|
-
} catch {}
|
|
36
|
+
key.slice(0, separatorIndex);
|
|
37
|
+
key.slice(separatorIndex + 1);
|
|
55
38
|
}
|
|
56
39
|
};
|
|
57
40
|
/** Translates a key with vue-i18n's polymorphic argument list. */
|
|
58
|
-
const translateKey = (locale, namespace, key, args) => {
|
|
41
|
+
const translateKey = (locale, namespace, key, args, fallbackMessages) => {
|
|
59
42
|
const { values, count, defaultMessage } = require_resolveVueMessage.parseTranslateArguments(args);
|
|
60
|
-
const rawValue = lookupRaw(
|
|
43
|
+
const rawValue = lookupRaw(namespace, key);
|
|
61
44
|
if (rawValue === void 0) {
|
|
45
|
+
if (fallbackMessages?.[locale]) {
|
|
46
|
+
const targetPath = namespace ? `${namespace}.${key}` : key;
|
|
47
|
+
const fallbackValue = navigatePath(fallbackMessages[locale], targetPath);
|
|
48
|
+
if (fallbackValue !== void 0) return require_resolveVueMessage.resolveVueMessage(fallbackValue, values, count, locale);
|
|
49
|
+
}
|
|
62
50
|
if (defaultMessage !== void 0) return require_resolveVueMessage.resolveVueMessage(defaultMessage, values, count, locale);
|
|
63
51
|
return key;
|
|
64
52
|
}
|
|
@@ -69,7 +57,8 @@ const warnDeprecatedRuntimeMessages = (location) => {
|
|
|
69
57
|
(0, _intlayer_config_logger.getAppLogger)({ log: _intlayer_config_built.log })(`${(0, _intlayer_config_logger.colorize)(location, _intlayer_config_colors.CYAN)} has no effect with ${(0, _intlayer_config_logger.colorize)("@intlayer/vue-i18n", _intlayer_config_colors.MAGENTA)} — translations are managed by the compiled intlayer dictionaries.`);
|
|
70
58
|
};
|
|
71
59
|
const createI18n = ((options = {}) => {
|
|
72
|
-
|
|
60
|
+
const fallbackMessages = options.messages;
|
|
61
|
+
if (options.messages !== void 0 && process.env.NODE_ENV === "development") (0, _intlayer_config_logger.getAppLogger)({ log: _intlayer_config_built.log })(`${(0, _intlayer_config_logger.colorize)("createI18n", _intlayer_config_colors.CYAN)}: the ${(0, _intlayer_config_logger.colorize)("`messages`", _intlayer_config_colors.CYAN)} option is used as a fallback. For optimal bundle size, remove the locale JSON imports and use ${(0, _intlayer_config_logger.colorize)("useDictionary", _intlayer_config_colors.CYAN)} or compile your intlayer dictionaries instead:\n ${(0, _intlayer_config_logger.colorize)("Before:", _intlayer_config_colors.GREY)} createI18n({ messages: { en, fr, … } })\n ${(0, _intlayer_config_logger.colorize)("After: ", _intlayer_config_colors.GREY)} createI18n({})`);
|
|
73
62
|
const client = (0, vue_intlayer.createIntlayerClient)(options.locale);
|
|
74
63
|
const datetimeFormats = options.datetimeFormats;
|
|
75
64
|
const numberFormats = options.numberFormats;
|
|
@@ -81,7 +70,7 @@ const createI18n = ((options = {}) => {
|
|
|
81
70
|
client.setLocale(newLocale);
|
|
82
71
|
}
|
|
83
72
|
});
|
|
84
|
-
const globalTranslate = (key, ...args) => translateKey(currentLocale(),
|
|
73
|
+
const globalTranslate = (key, ...args) => translateKey(currentLocale(), void 0, key, args, fallbackMessages);
|
|
85
74
|
const globalDate = (value, formatOrOptions) => require_formats.formatDateValue(value, formatOrOptions, currentLocale(), datetimeFormats);
|
|
86
75
|
const globalNumber = (value, formatOrOptions) => require_formats.formatNumberValue(value, formatOrOptions, currentLocale(), numberFormats);
|
|
87
76
|
const global = {
|
|
@@ -90,8 +79,8 @@ const createI18n = ((options = {}) => {
|
|
|
90
79
|
fallbackLocale: options.fallbackLocale ?? _intlayer_config_built.internationalization?.defaultLocale,
|
|
91
80
|
t: globalTranslate,
|
|
92
81
|
tc: globalTranslate,
|
|
93
|
-
te: (key) => lookupRaw(
|
|
94
|
-
tm: (key) => lookupRaw(
|
|
82
|
+
te: (key) => lookupRaw(void 0, key) !== void 0,
|
|
83
|
+
tm: (key) => lookupRaw(void 0, key) ?? {},
|
|
95
84
|
rt: (message, ...args) => {
|
|
96
85
|
const { values, count } = require_resolveVueMessage.parseTranslateArguments(args);
|
|
97
86
|
return require_resolveVueMessage.resolveVueMessage(message, values, count, currentLocale());
|
|
@@ -104,12 +93,9 @@ const createI18n = ((options = {}) => {
|
|
|
104
93
|
mergeLocaleMessage: (_locale, _messages) => {
|
|
105
94
|
warnDeprecatedRuntimeMessages("mergeLocaleMessage");
|
|
106
95
|
},
|
|
107
|
-
getLocaleMessage: (
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
} catch {
|
|
111
|
-
return {};
|
|
112
|
-
}
|
|
96
|
+
getLocaleMessage: (_locale) => {
|
|
97
|
+
warnDeprecatedRuntimeMessages("getLocaleMessage");
|
|
98
|
+
return {};
|
|
113
99
|
}
|
|
114
100
|
};
|
|
115
101
|
/** Legacy Options-API facade (`this.$i18n`) with a string `locale`. */
|
|
@@ -144,6 +130,7 @@ const createI18n = ((options = {}) => {
|
|
|
144
130
|
const i18nInstance = {
|
|
145
131
|
global,
|
|
146
132
|
mode: options.legacy === true ? "legacy" : "composition",
|
|
133
|
+
__optionsMessages: fallbackMessages,
|
|
147
134
|
install(app) {
|
|
148
135
|
(0, vue_intlayer.installIntlayer)(app, { locale: options.locale });
|
|
149
136
|
app.provide(I18nInjectionKey, i18nInstance);
|
|
@@ -181,7 +168,8 @@ const createI18n = ((options = {}) => {
|
|
|
181
168
|
*/
|
|
182
169
|
const useI18n = (options) => {
|
|
183
170
|
const { locale: currentLocale, setLocale, availableLocales } = (0, vue_intlayer.useLocale)();
|
|
184
|
-
const
|
|
171
|
+
const fallbackMessages = (0, vue.inject)(I18nInjectionKey)?.__optionsMessages;
|
|
172
|
+
const namespace = options?.namespace;
|
|
185
173
|
const datetimeFormats = options?.datetimeFormats;
|
|
186
174
|
const numberFormats = options?.numberFormats;
|
|
187
175
|
const localeRef = (0, vue.computed)({
|
|
@@ -190,14 +178,14 @@ const useI18n = (options) => {
|
|
|
190
178
|
setLocale(newLocale);
|
|
191
179
|
}
|
|
192
180
|
});
|
|
193
|
-
const translate = (key, ...args) => translateKey(currentLocale.value, namespace, String(key), args);
|
|
181
|
+
const translate = (key, ...args) => translateKey(currentLocale.value, namespace, String(key), args, fallbackMessages);
|
|
194
182
|
return {
|
|
195
183
|
locale: localeRef,
|
|
196
184
|
availableLocales,
|
|
197
185
|
t: translate,
|
|
198
186
|
tc: translate,
|
|
199
|
-
te: (key) => lookupRaw(
|
|
200
|
-
tm: (key) => lookupRaw(
|
|
187
|
+
te: (key) => lookupRaw(namespace, String(key)) !== void 0,
|
|
188
|
+
tm: (key) => lookupRaw(namespace, String(key)) ?? {},
|
|
201
189
|
rt: (message, ...args) => {
|
|
202
190
|
const { values, count } = require_resolveVueMessage.parseTranslateArguments(args);
|
|
203
191
|
return require_resolveVueMessage.resolveVueMessage(message, values, count, currentLocale.value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createI18n.cjs","names":["parseTranslateArguments","resolveVueMessage","internationalization","ANSIColors","formatDateValue","formatNumberValue"],"sources":["../../src/createI18n.ts"],"sourcesContent":["import { internationalization, log } from '@intlayer/config/built';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getIntlayer } from '@intlayer/core/interpreter';\nimport type { ValidDotPathsFor } from '@intlayer/core/transpiler';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n App,\n DirectiveBinding,\n InjectionKey,\n WritableComputedRef,\n} from 'vue';\nimport { computed } from 'vue';\nimport type { createI18n as _createI18n, I18n } from 'vue-i18n';\nimport { createIntlayerClient, installIntlayer, useLocale } from 'vue-intlayer';\nimport {\n type DateTimeFormatsConfig,\n formatDateValue,\n formatNumberValue,\n type NumberFormatsConfig,\n} from './formats';\nimport {\n parseTranslateArguments,\n resolveVueMessage,\n} from './resolveVueMessage';\n\nexport const VERSION = '9.13.1';\nexport const I18nInjectionKey: InjectionKey<I18n> = Symbol('global-i18n');\n\nconst DEFAULT_NAMESPACE = 'translation';\n\nconst navigatePath = (objectValue: unknown, path: string): unknown => {\n if (!path) return objectValue;\n let current: unknown = objectValue;\n for (const part of path.split('.')) {\n if (\n current === null ||\n current === undefined ||\n typeof current !== 'object'\n ) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n};\n\n/**\n * Looks up a raw value for a vue-i18n key against intlayer dictionaries.\n *\n * Resolution order:\n * 1. `ns:key` prefix → dictionary `ns`\n * 2. The default namespace dictionary with the full dot-path\n * 3. The first key segment as the dictionary key (`'home.title'` →\n * dictionary `home`, path `title`)\n */\nconst lookupRaw = (locale: string, namespace: string, key: string): unknown => {\n let targetNamespace = namespace;\n let path = key;\n\n if (key.includes(':')) {\n const separatorIndex = key.indexOf(':');\n targetNamespace = key.slice(0, separatorIndex);\n path = key.slice(separatorIndex + 1);\n }\n\n try {\n const dictionary = getIntlayer(\n targetNamespace as DictionaryKeys,\n locale as LocalesValues\n );\n const value = navigatePath(dictionary, path);\n if (value !== undefined && value !== null) return value;\n } catch {}\n\n if (path.includes('.')) {\n const separatorIndex = path.indexOf('.');\n const firstSegment = path.slice(0, separatorIndex);\n const restPath = path.slice(separatorIndex + 1);\n try {\n const dictionary = getIntlayer(\n firstSegment as DictionaryKeys,\n locale as LocalesValues\n );\n const value = navigatePath(dictionary, restPath);\n if (value !== undefined && value !== null) return value;\n } catch {}\n }\n\n return undefined;\n};\n\n/** Translates a key with vue-i18n's polymorphic argument list. */\nconst translateKey = (\n locale: string,\n namespace: string,\n key: string,\n args: unknown[]\n): string => {\n const { values, count, defaultMessage } = parseTranslateArguments(args);\n\n const rawValue = lookupRaw(locale, namespace, key);\n\n if (rawValue === undefined) {\n if (defaultMessage !== undefined) {\n return resolveVueMessage(\n defaultMessage,\n values,\n count,\n locale as LocalesValues\n );\n }\n return key;\n }\n\n return resolveVueMessage(rawValue, values, count, locale as LocalesValues);\n};\n\nconst getAvailableLocales = (): string[] =>\n internationalization?.locales?.map(String) ?? [];\n\nconst warnDeprecatedRuntimeMessages = (location: string) => {\n const appLogger = getAppLogger({ log });\n appLogger(\n `${colorize(location, ANSIColors.CYAN)} has no effect with ${colorize('@intlayer/vue-i18n', ANSIColors.MAGENTA)} — translations are managed by the compiled intlayer dictionaries.`\n );\n};\n\n/** Value accepted by the `v-t` directive. */\ntype TranslateDirectiveValue =\n | string\n | { path: string; args?: Record<string, unknown>; choice?: number };\n\nexport const createI18n = ((options: Record<string, unknown> = {}) => {\n if (options.messages !== undefined) {\n const appLogger = getAppLogger({ log });\n appLogger(\n `${colorize('createI18n', ANSIColors.CYAN)}: the ${colorize('`messages`', ANSIColors.CYAN)} option is ignored when using ${colorize('@intlayer/vue-i18n', ANSIColors.MAGENTA)} — translations are served from the compiled intlayer dictionaries instead. Remove the locale JSON imports and the ${colorize('`messages`', ANSIColors.CYAN)} option to reduce your bundle size:\\n ${colorize('Before:', ANSIColors.GREY)} createI18n({ messages: { en, fr, … } })\\n ${colorize('After: ', ANSIColors.GREY)} createI18n({})`\n );\n }\n\n const client = createIntlayerClient(options.locale as LocalesValues);\n\n const datetimeFormats = options.datetimeFormats as\n | DateTimeFormatsConfig\n | undefined;\n const numberFormats = options.numberFormats as\n | NumberFormatsConfig\n | undefined;\n\n const currentLocale = (): string => String(client.locale.value);\n\n /** Writable ref matching vue-i18n's composition-mode `global.locale`. */\n const localeRef: WritableComputedRef<string> = computed({\n get: () => currentLocale(),\n set: (newLocale: string) => {\n client.setLocale(newLocale as LocalesValues);\n },\n });\n\n const globalTranslate = (key: string, ...args: unknown[]): string =>\n translateKey(currentLocale(), DEFAULT_NAMESPACE, key, args);\n\n const globalDate = (\n value: Date | number | string,\n formatOrOptions?: string | Intl.DateTimeFormatOptions\n ): string =>\n formatDateValue(value, formatOrOptions, currentLocale(), datetimeFormats);\n\n const globalNumber = (\n value: number,\n formatOrOptions?: string | Intl.NumberFormatOptions\n ): string =>\n formatNumberValue(value, formatOrOptions, currentLocale(), numberFormats);\n\n const global = {\n locale: localeRef,\n availableLocales: getAvailableLocales(),\n fallbackLocale: (options.fallbackLocale ??\n internationalization?.defaultLocale) as string,\n t: globalTranslate,\n tc: globalTranslate,\n te: (key: string): boolean =>\n lookupRaw(currentLocale(), DEFAULT_NAMESPACE, key) !== undefined,\n tm: (key: string): unknown =>\n lookupRaw(currentLocale(), DEFAULT_NAMESPACE, key) ?? {},\n rt: (message: unknown, ...args: unknown[]): string => {\n const { values, count } = parseTranslateArguments(args);\n return resolveVueMessage(\n message,\n values,\n count,\n currentLocale() as LocalesValues\n );\n },\n d: globalDate,\n n: globalNumber,\n setLocaleMessage: (_locale: string, _messages: unknown) => {\n warnDeprecatedRuntimeMessages('setLocaleMessage');\n },\n mergeLocaleMessage: (_locale: string, _messages: unknown) => {\n warnDeprecatedRuntimeMessages('mergeLocaleMessage');\n },\n getLocaleMessage: (locale: string): unknown => {\n try {\n return getIntlayer(\n DEFAULT_NAMESPACE as DictionaryKeys,\n locale as LocalesValues\n );\n } catch {\n return {};\n }\n },\n };\n\n /** Legacy Options-API facade (`this.$i18n`) with a string `locale`. */\n const legacyI18n = {\n get locale(): string {\n return currentLocale();\n },\n set locale(newLocale: string) {\n client.setLocale(newLocale as LocalesValues);\n },\n get availableLocales(): string[] {\n return getAvailableLocales();\n },\n t: globalTranslate,\n tc: globalTranslate,\n te: global.te,\n tm: global.tm,\n rt: global.rt,\n d: globalDate,\n n: globalNumber,\n };\n\n const applyTranslateDirective = (\n element: HTMLElement,\n binding: DirectiveBinding<TranslateDirectiveValue>\n ) => {\n const bindingValue = binding.value;\n if (typeof bindingValue === 'string') {\n element.textContent = globalTranslate(bindingValue);\n } else if (bindingValue && typeof bindingValue === 'object') {\n const directiveArgs: unknown[] = [];\n if (bindingValue.args) directiveArgs.push(bindingValue.args);\n if (typeof bindingValue.choice === 'number')\n directiveArgs.push(bindingValue.choice);\n element.textContent = globalTranslate(\n bindingValue.path,\n ...directiveArgs\n );\n }\n };\n\n const i18nInstance = {\n global,\n mode: options.legacy === true ? 'legacy' : 'composition',\n install(app: App) {\n installIntlayer(app, {\n locale: options.locale as LocalesValues,\n });\n\n // Provide under I18nInjectionKey to satisfy inject(I18nInjectionKey) calls\n app.provide(I18nInjectionKey, i18nInstance as unknown as I18n);\n\n // Legacy API support ($t / $tc / $te / $tm / $rt / $d / $n / $i18n)\n app.config.globalProperties.$t = globalTranslate;\n (app.config.globalProperties as Record<string, unknown>).$tc =\n globalTranslate;\n (app.config.globalProperties as Record<string, unknown>).$te = global.te;\n (app.config.globalProperties as Record<string, unknown>).$tm = global.tm;\n (app.config.globalProperties as Record<string, unknown>).$rt = global.rt;\n (app.config.globalProperties as Record<string, unknown>).$d = globalDate;\n (app.config.globalProperties as Record<string, unknown>).$n =\n globalNumber;\n (app.config.globalProperties as Record<string, unknown>).$i18n =\n legacyI18n;\n\n // `v-t` directive support\n app.directive('t', {\n beforeMount: applyTranslateDirective,\n updated: applyTranslateDirective,\n });\n },\n };\n\n return i18nInstance as unknown as I18n;\n}) as typeof _createI18n;\n\n/**\n * Composable providing a typed `t()` function scoped to a dictionary namespace.\n * Pass `{ namespace: 'myDict' }` to restrict keys to valid dot-notation paths\n * within that intlayer dictionary (autocompleted and validated at compile time).\n *\n * Supports vue-i18n's full message syntax: named (`{name}`) and list (`{0}`)\n * interpolation, pipe choice messages (`'car | cars'` with a count argument),\n * plus `te`/`tm`/`rt` and `Intl`-backed `d()`/`n()` formatters.\n *\n * @example\n * ```ts\n * const { t } = useI18n({ namespace: 'about' });\n * t('counter.label'); // ✓ typed; compile error if key doesn't exist\n * t('apples', 5); // pipe plural choice\n * ```\n */\nexport const useI18n = <N extends DictionaryKeys = DictionaryKeys>(\n options?: Record<string, unknown> & { namespace?: N }\n): {\n locale: WritableComputedRef<string>;\n availableLocales: string[];\n t: <P extends ValidDotPathsFor<N>>(key: P, ...args: unknown[]) => string;\n tc: <P extends ValidDotPathsFor<N>>(key: P, ...args: unknown[]) => string;\n te: <P extends ValidDotPathsFor<N>>(key: P) => boolean;\n tm: <P extends ValidDotPathsFor<N>>(key: P) => unknown;\n rt: (message: unknown, ...args: unknown[]) => string;\n d: (\n value: Date | number | string,\n formatOrOptions?: string | Intl.DateTimeFormatOptions\n ) => string;\n n: (\n value: number,\n formatOrOptions?: string | Intl.NumberFormatOptions\n ) => string;\n} => {\n const { locale: currentLocale, setLocale, availableLocales } = useLocale();\n\n const namespace = ((options?.namespace as string) ?? DEFAULT_NAMESPACE) as N;\n\n const datetimeFormats = options?.datetimeFormats as\n | DateTimeFormatsConfig\n | undefined;\n const numberFormats = options?.numberFormats as\n | NumberFormatsConfig\n | undefined;\n\n const localeRef = computed({\n get: () => currentLocale.value as string,\n set: (newLocale: string) => {\n setLocale(newLocale as LocalesValues);\n },\n });\n\n const translate = <P extends ValidDotPathsFor<N>>(\n key: P,\n ...args: unknown[]\n ): string => translateKey(currentLocale.value, namespace, String(key), args);\n\n return {\n locale: localeRef,\n availableLocales: availableLocales as string[],\n t: translate,\n tc: translate,\n te: <P extends ValidDotPathsFor<N>>(key: P): boolean =>\n lookupRaw(currentLocale.value, namespace, String(key)) !== undefined,\n tm: <P extends ValidDotPathsFor<N>>(key: P): unknown =>\n lookupRaw(currentLocale.value, namespace, String(key)) ?? {},\n rt: (message: unknown, ...args: unknown[]): string => {\n const { values, count } = parseTranslateArguments(args);\n return resolveVueMessage(\n message,\n values,\n count,\n currentLocale.value as LocalesValues\n );\n },\n d: (\n value: Date | number | string,\n formatOrOptions?: string | Intl.DateTimeFormatOptions\n ): string =>\n formatDateValue(\n value,\n formatOrOptions,\n currentLocale.value,\n datetimeFormats\n ),\n n: (\n value: number,\n formatOrOptions?: string | Intl.NumberFormatOptions\n ): string =>\n formatNumberValue(\n value,\n formatOrOptions,\n currentLocale.value,\n numberFormats\n ),\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"createI18n.cjs","names":["parseTranslateArguments","resolveVueMessage","internationalization","ANSIColors","formatDateValue","formatNumberValue"],"sources":["../../src/createI18n.ts"],"sourcesContent":["import { internationalization, log } from '@intlayer/config/built';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport type { ValidDotPathsFor } from '@intlayer/core/transpiler';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n App,\n DirectiveBinding,\n InjectionKey,\n WritableComputedRef,\n} from 'vue';\nimport { computed, inject } from 'vue';\nimport type { createI18n as _createI18n, I18n } from 'vue-i18n';\nimport { createIntlayerClient, installIntlayer, useLocale } from 'vue-intlayer';\nimport {\n type DateTimeFormatsConfig,\n formatDateValue,\n formatNumberValue,\n type NumberFormatsConfig,\n} from './formats';\nimport {\n parseTranslateArguments,\n resolveVueMessage,\n} from './resolveVueMessage';\n\nexport const VERSION = '9.13.1';\nexport const I18nInjectionKey: InjectionKey<I18n> = Symbol('global-i18n');\n\nconst navigatePath = (objectValue: unknown, path: string): unknown => {\n if (!path) return objectValue;\n let current: unknown = objectValue;\n for (const part of path.split('.')) {\n if (\n current === null ||\n current === undefined ||\n typeof current !== 'object'\n ) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n};\n\n/**\n * Looks up a raw value for a vue-i18n key against intlayer dictionaries.\n *\n * Resolution order:\n * 1. `ns:key` prefix → dictionary `ns`\n * 2. The default namespace dictionary with the full dot-path\n * 3. The first key segment as the dictionary key (`'home.title'` →\n * dictionary `home`, path `title`)\n */\nconst lookupRaw = (namespace: string | undefined, key: string): unknown => {\n let _targetNamespace = namespace;\n let _path = key;\n\n if (key.includes(':')) {\n const separatorIndex = key.indexOf(':');\n _targetNamespace = key.slice(0, separatorIndex);\n _path = key.slice(separatorIndex + 1);\n }\n\n // Without getDictionaries, global translation fallback to intlayer dictionaries\n // is disabled for bundle optimization purposes.\n // We only lookup if the namespace exists globally, but since we don't have getDictionaries\n // we rely strictly on what vue-i18n already has in its messages.\n\n return undefined;\n};\n\n/** Translates a key with vue-i18n's polymorphic argument list. */\nconst translateKey = (\n locale: string,\n namespace: string | undefined,\n key: string,\n args: unknown[],\n fallbackMessages?: Record<string, unknown>\n): string => {\n const { values, count, defaultMessage } = parseTranslateArguments(args);\n\n const rawValue = lookupRaw(namespace, key);\n\n if (rawValue === undefined) {\n if (fallbackMessages?.[locale]) {\n // Defer to the user's provided messages if not found in dictionaries\n const targetPath = namespace ? `${namespace}.${key}` : key;\n const fallbackValue = navigatePath(fallbackMessages[locale], targetPath);\n if (fallbackValue !== undefined) {\n return resolveVueMessage(\n fallbackValue,\n values,\n count,\n locale as LocalesValues\n );\n }\n }\n if (defaultMessage !== undefined) {\n return resolveVueMessage(\n defaultMessage,\n values,\n count,\n locale as LocalesValues\n );\n }\n return key;\n }\n\n return resolveVueMessage(rawValue, values, count, locale as LocalesValues);\n};\n\nconst getAvailableLocales = (): string[] =>\n internationalization?.locales?.map(String) ?? [];\n\nconst warnDeprecatedRuntimeMessages = (location: string) => {\n const appLogger = getAppLogger({ log });\n appLogger(\n `${colorize(location, ANSIColors.CYAN)} has no effect with ${colorize('@intlayer/vue-i18n', ANSIColors.MAGENTA)} — translations are managed by the compiled intlayer dictionaries.`\n );\n};\n\n/** Value accepted by the `v-t` directive. */\ntype TranslateDirectiveValue =\n | string\n | { path: string; args?: Record<string, unknown>; choice?: number };\n\nexport const createI18n: typeof _createI18n = ((\n options: Record<string, unknown> = {}\n) => {\n const fallbackMessages = options.messages as\n | Record<string, unknown>\n | undefined;\n\n if (\n options.messages !== undefined &&\n process.env.NODE_ENV === 'development'\n ) {\n const appLogger = getAppLogger({ log });\n appLogger(\n `${colorize('createI18n', ANSIColors.CYAN)}: the ${colorize('`messages`', ANSIColors.CYAN)} option is used as a fallback. For optimal bundle size, remove the locale JSON imports and use ${colorize('useDictionary', ANSIColors.CYAN)} or compile your intlayer dictionaries instead:\\n ${colorize('Before:', ANSIColors.GREY)} createI18n({ messages: { en, fr, … } })\\n ${colorize('After: ', ANSIColors.GREY)} createI18n({})`\n );\n }\n\n const client = createIntlayerClient(options.locale as LocalesValues);\n\n const datetimeFormats = options.datetimeFormats as\n | DateTimeFormatsConfig\n | undefined;\n const numberFormats = options.numberFormats as\n | NumberFormatsConfig\n | undefined;\n\n const currentLocale = (): string => String(client.locale.value);\n\n /** Writable ref matching vue-i18n's composition-mode `global.locale`. */\n const localeRef: WritableComputedRef<string> = computed({\n get: () => currentLocale(),\n set: (newLocale: string) => {\n client.setLocale(newLocale as LocalesValues);\n },\n });\n\n const globalTranslate = (key: string, ...args: unknown[]): string =>\n translateKey(currentLocale(), undefined, key, args, fallbackMessages);\n\n const globalDate = (\n value: Date | number | string,\n formatOrOptions?: string | Intl.DateTimeFormatOptions\n ): string =>\n formatDateValue(value, formatOrOptions, currentLocale(), datetimeFormats);\n\n const globalNumber = (\n value: number,\n formatOrOptions?: string | Intl.NumberFormatOptions\n ): string =>\n formatNumberValue(value, formatOrOptions, currentLocale(), numberFormats);\n\n const global = {\n locale: localeRef,\n availableLocales: getAvailableLocales(),\n fallbackLocale: (options.fallbackLocale ??\n internationalization?.defaultLocale) as string,\n t: globalTranslate,\n tc: globalTranslate,\n te: (key: string): boolean => lookupRaw(undefined, key) !== undefined,\n tm: (key: string): unknown => lookupRaw(undefined, key) ?? {},\n rt: (message: unknown, ...args: unknown[]): string => {\n const { values, count } = parseTranslateArguments(args);\n return resolveVueMessage(\n message,\n values,\n count,\n currentLocale() as LocalesValues\n );\n },\n d: globalDate,\n n: globalNumber,\n setLocaleMessage: (_locale: string, _messages: unknown) => {\n warnDeprecatedRuntimeMessages('setLocaleMessage');\n },\n mergeLocaleMessage: (_locale: string, _messages: unknown) => {\n warnDeprecatedRuntimeMessages('mergeLocaleMessage');\n },\n getLocaleMessage: (_locale: string): Record<string, unknown> => {\n warnDeprecatedRuntimeMessages('getLocaleMessage');\n // We do not load global dictionaries anymore for bundle optimization.\n // The user should use useDictionary or rely on manually provided messages.\n return {};\n },\n };\n\n /** Legacy Options-API facade (`this.$i18n`) with a string `locale`. */\n const legacyI18n = {\n get locale(): string {\n return currentLocale();\n },\n set locale(newLocale: string) {\n client.setLocale(newLocale as LocalesValues);\n },\n get availableLocales(): string[] {\n return getAvailableLocales();\n },\n t: globalTranslate,\n tc: globalTranslate,\n te: global.te,\n tm: global.tm,\n rt: global.rt,\n d: globalDate,\n n: globalNumber,\n };\n\n const applyTranslateDirective = (\n element: HTMLElement,\n binding: DirectiveBinding<TranslateDirectiveValue>\n ) => {\n const bindingValue = binding.value;\n if (typeof bindingValue === 'string') {\n element.textContent = globalTranslate(bindingValue);\n } else if (bindingValue && typeof bindingValue === 'object') {\n const directiveArgs: unknown[] = [];\n if (bindingValue.args) directiveArgs.push(bindingValue.args);\n if (typeof bindingValue.choice === 'number')\n directiveArgs.push(bindingValue.choice);\n element.textContent = globalTranslate(\n bindingValue.path,\n ...directiveArgs\n );\n }\n };\n\n const i18nInstance = {\n global,\n mode: options.legacy === true ? 'legacy' : 'composition',\n __optionsMessages: fallbackMessages,\n install(app: App) {\n installIntlayer(app, {\n locale: options.locale as LocalesValues,\n });\n\n // Provide under I18nInjectionKey to satisfy inject(I18nInjectionKey) calls\n app.provide(I18nInjectionKey, i18nInstance as unknown as I18n);\n\n // Legacy API support ($t / $tc / $te / $tm / $rt / $d / $n / $i18n)\n app.config.globalProperties.$t = globalTranslate;\n (app.config.globalProperties as Record<string, unknown>).$tc =\n globalTranslate;\n (app.config.globalProperties as Record<string, unknown>).$te = global.te;\n (app.config.globalProperties as Record<string, unknown>).$tm = global.tm;\n (app.config.globalProperties as Record<string, unknown>).$rt = global.rt;\n (app.config.globalProperties as Record<string, unknown>).$d = globalDate;\n (app.config.globalProperties as Record<string, unknown>).$n =\n globalNumber;\n (app.config.globalProperties as Record<string, unknown>).$i18n =\n legacyI18n;\n\n // `v-t` directive support\n app.directive('t', {\n beforeMount: applyTranslateDirective,\n updated: applyTranslateDirective,\n });\n },\n };\n\n return i18nInstance as unknown as I18n;\n}) as typeof _createI18n;\n\n/**\n * Composable providing a typed `t()` function scoped to a dictionary namespace.\n * Pass `{ namespace: 'myDict' }` to restrict keys to valid dot-notation paths\n * within that intlayer dictionary (autocompleted and validated at compile time).\n *\n * Supports vue-i18n's full message syntax: named (`{name}`) and list (`{0}`)\n * interpolation, pipe choice messages (`'car | cars'` with a count argument),\n * plus `te`/`tm`/`rt` and `Intl`-backed `d()`/`n()` formatters.\n *\n * @example\n * ```ts\n * const { t } = useI18n({ namespace: 'about' });\n * t('counter.label'); // ✓ typed; compile error if key doesn't exist\n * t('apples', 5); // pipe plural choice\n * ```\n */\nexport const useI18n = <N extends DictionaryKeys = DictionaryKeys>(\n options?: Record<string, unknown> & { namespace?: N }\n): {\n locale: WritableComputedRef<string>;\n availableLocales: string[];\n t: <P extends ValidDotPathsFor<N>>(key: P, ...args: unknown[]) => string;\n tc: <P extends ValidDotPathsFor<N>>(key: P, ...args: unknown[]) => string;\n te: <P extends ValidDotPathsFor<N>>(key: P) => boolean;\n tm: <P extends ValidDotPathsFor<N>>(key: P) => unknown;\n rt: (message: unknown, ...args: unknown[]) => string;\n d: (\n value: Date | number | string,\n formatOrOptions?: string | Intl.DateTimeFormatOptions\n ) => string;\n n: (\n value: number,\n formatOrOptions?: string | Intl.NumberFormatOptions\n ) => string;\n} => {\n const { locale: currentLocale, setLocale, availableLocales } = useLocale();\n const instance = inject(I18nInjectionKey) as\n | Record<string, unknown>\n | undefined;\n const fallbackMessages = instance?.__optionsMessages as\n | Record<string, unknown>\n | undefined;\n\n const namespace = options?.namespace as string | undefined as N | undefined;\n\n const datetimeFormats = options?.datetimeFormats as\n | DateTimeFormatsConfig\n | undefined;\n const numberFormats = options?.numberFormats as\n | NumberFormatsConfig\n | undefined;\n\n const localeRef = computed({\n get: () => currentLocale.value as string,\n set: (newLocale: string) => {\n setLocale(newLocale as LocalesValues);\n },\n });\n\n const translate = <P extends ValidDotPathsFor<N>>(\n key: P,\n ...args: unknown[]\n ): string =>\n translateKey(\n currentLocale.value,\n namespace,\n String(key),\n args,\n fallbackMessages\n );\n\n return {\n locale: localeRef,\n availableLocales: availableLocales as string[],\n t: translate,\n tc: translate,\n te: <P extends ValidDotPathsFor<N>>(key: P): boolean =>\n lookupRaw(namespace, String(key)) !== undefined,\n tm: <P extends ValidDotPathsFor<N>>(key: P): unknown =>\n lookupRaw(namespace, String(key)) ?? {},\n rt: (message: unknown, ...args: unknown[]): string => {\n const { values, count } = parseTranslateArguments(args);\n return resolveVueMessage(\n message,\n values,\n count,\n currentLocale.value as LocalesValues\n );\n },\n d: (\n value: Date | number | string,\n formatOrOptions?: string | Intl.DateTimeFormatOptions\n ): string =>\n formatDateValue(\n value,\n formatOrOptions,\n currentLocale.value,\n datetimeFormats\n ),\n n: (\n value: number,\n formatOrOptions?: string | Intl.NumberFormatOptions\n ): string =>\n formatNumberValue(\n value,\n formatOrOptions,\n currentLocale.value,\n numberFormats\n ),\n };\n};\n"],"mappings":"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"}
|
package/dist/cjs/formats.cjs
CHANGED
|
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
|
|
3
3
|
//#region src/formats.ts
|
|
4
4
|
const resolveNamedOptions = (formatOrOptions, locale, namedFormats) => {
|
|
5
|
-
if (typeof formatOrOptions === "string") return namedFormats?.[locale]?.[formatOrOptions] ?? namedFormats?.[locale.split("-")[0]]?.[formatOrOptions];
|
|
5
|
+
if (typeof formatOrOptions === "string") return namedFormats?.[locale]?.[formatOrOptions] ?? namedFormats?.[locale.split("-")[0] ?? ""]?.[formatOrOptions];
|
|
6
6
|
return formatOrOptions;
|
|
7
7
|
};
|
|
8
8
|
/** Formats a date value like vue-i18n's `d()`. */
|
package/dist/cjs/formats.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formats.cjs","names":[],"sources":["../../src/formats.ts"],"sourcesContent":["/**\n * Locale-aware `d()` / `n()` formatting backed by the native `Intl.*` APIs,\n * honoring the `datetimeFormats` / `numberFormats` maps from `createI18n`\n * options (vue-i18n named formats).\n */\n\n/** vue-i18n `datetimeFormats` option shape: locale → format name → options. */\nexport type DateTimeFormatsConfig = Record<\n string,\n Record<string, Intl.DateTimeFormatOptions>\n>;\n\n/** vue-i18n `numberFormats` option shape: locale → format name → options. */\nexport type NumberFormatsConfig = Record<\n string,\n Record<string, Intl.NumberFormatOptions>\n>;\n\nconst resolveNamedOptions = <FormatOptions>(\n formatOrOptions: string | FormatOptions | undefined,\n locale: string,\n namedFormats: Record<string, Record<string, FormatOptions>> | undefined\n): FormatOptions | undefined => {\n if (typeof formatOrOptions === 'string') {\n return (\n namedFormats?.[locale]?.[formatOrOptions] ??\n // Fall back to the base language entry (`'en'` for `'en-GB'`)\n namedFormats?.[locale.split('-')[0]]?.[formatOrOptions]\n );\n }\n return formatOrOptions;\n};\n\n/** Formats a date value like vue-i18n's `d()`. */\nexport const formatDateValue = (\n value: Date | number | string,\n formatOrOptions: string | Intl.DateTimeFormatOptions | undefined,\n locale: string,\n datetimeFormats?: DateTimeFormatsConfig\n): string => {\n const dateValue = value instanceof Date ? value : new Date(value);\n const options = resolveNamedOptions(formatOrOptions, locale, datetimeFormats);\n\n try {\n return new Intl.DateTimeFormat(locale, options).format(dateValue);\n } catch {\n return String(value);\n }\n};\n\n/** Formats a number value like vue-i18n's `n()`. */\nexport const formatNumberValue = (\n value: number,\n formatOrOptions: string | Intl.NumberFormatOptions | undefined,\n locale: string,\n numberFormats?: NumberFormatsConfig\n): string => {\n const options = resolveNamedOptions(formatOrOptions, locale, numberFormats);\n\n try {\n return new Intl.NumberFormat(locale, options).format(value);\n } catch {\n return String(value);\n }\n};\n"],"mappings":";;;AAkBA,MAAM,uBACJ,iBACA,QACA,iBAC8B;AAC9B,KAAI,OAAO,oBAAoB,SAC7B,QACE,eAAe,UAAU,oBAEzB,eAAe,OAAO,MAAM,IAAI,CAAC,MAAM;
|
|
1
|
+
{"version":3,"file":"formats.cjs","names":[],"sources":["../../src/formats.ts"],"sourcesContent":["/**\n * Locale-aware `d()` / `n()` formatting backed by the native `Intl.*` APIs,\n * honoring the `datetimeFormats` / `numberFormats` maps from `createI18n`\n * options (vue-i18n named formats).\n */\n\n/** vue-i18n `datetimeFormats` option shape: locale → format name → options. */\nexport type DateTimeFormatsConfig = Record<\n string,\n Record<string, Intl.DateTimeFormatOptions>\n>;\n\n/** vue-i18n `numberFormats` option shape: locale → format name → options. */\nexport type NumberFormatsConfig = Record<\n string,\n Record<string, Intl.NumberFormatOptions>\n>;\n\nconst resolveNamedOptions = <FormatOptions>(\n formatOrOptions: string | FormatOptions | undefined,\n locale: string,\n namedFormats: Record<string, Record<string, FormatOptions>> | undefined\n): FormatOptions | undefined => {\n if (typeof formatOrOptions === 'string') {\n return (\n namedFormats?.[locale]?.[formatOrOptions] ??\n // Fall back to the base language entry (`'en'` for `'en-GB'`)\n namedFormats?.[locale.split('-')[0] ?? '']?.[formatOrOptions]\n );\n }\n return formatOrOptions;\n};\n\n/** Formats a date value like vue-i18n's `d()`. */\nexport const formatDateValue = (\n value: Date | number | string,\n formatOrOptions: string | Intl.DateTimeFormatOptions | undefined,\n locale: string,\n datetimeFormats?: DateTimeFormatsConfig\n): string => {\n const dateValue = value instanceof Date ? value : new Date(value);\n const options = resolveNamedOptions(formatOrOptions, locale, datetimeFormats);\n\n try {\n return new Intl.DateTimeFormat(locale, options).format(dateValue);\n } catch {\n return String(value);\n }\n};\n\n/** Formats a number value like vue-i18n's `n()`. */\nexport const formatNumberValue = (\n value: number,\n formatOrOptions: string | Intl.NumberFormatOptions | undefined,\n locale: string,\n numberFormats?: NumberFormatsConfig\n): string => {\n const options = resolveNamedOptions(formatOrOptions, locale, numberFormats);\n\n try {\n return new Intl.NumberFormat(locale, options).format(value);\n } catch {\n return String(value);\n }\n};\n"],"mappings":";;;AAkBA,MAAM,uBACJ,iBACA,QACA,iBAC8B;AAC9B,KAAI,OAAO,oBAAoB,SAC7B,QACE,eAAe,UAAU,oBAEzB,eAAe,OAAO,MAAM,IAAI,CAAC,MAAM,MAAM;AAGjD,QAAO;;;AAIT,MAAa,mBACX,OACA,iBACA,QACA,oBACW;CACX,MAAM,YAAY,iBAAiB,OAAO,QAAQ,IAAI,KAAK,MAAM;CACjE,MAAM,UAAU,oBAAoB,iBAAiB,QAAQ,gBAAgB;AAE7E,KAAI;AACF,SAAO,IAAI,KAAK,eAAe,QAAQ,QAAQ,CAAC,OAAO,UAAU;SAC3D;AACN,SAAO,OAAO,MAAM;;;;AAKxB,MAAa,qBACX,OACA,iBACA,QACA,kBACW;CACX,MAAM,UAAU,oBAAoB,iBAAiB,QAAQ,cAAc;AAE3E,KAAI;AACF,SAAO,IAAI,KAAK,aAAa,QAAQ,QAAQ,CAAC,OAAO,MAAM;SACrD;AACN,SAAO,OAAO,MAAM"}
|
|
@@ -1,44 +1,68 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_formats = require('./formats.cjs');
|
|
4
|
+
const require_resolveVueMessage = require('./resolveVueMessage.cjs');
|
|
3
5
|
let vue = require("vue");
|
|
4
6
|
let vue_intlayer = require("vue-intlayer");
|
|
5
7
|
|
|
6
8
|
//#region src/useDictionary.ts
|
|
9
|
+
const navigatePath = (objectValue, path) => {
|
|
10
|
+
if (!path) return objectValue;
|
|
11
|
+
const parts = path.split(".");
|
|
12
|
+
let current = objectValue;
|
|
13
|
+
for (const part of parts) {
|
|
14
|
+
if (current === null || current === void 0 || typeof current !== "object") return;
|
|
15
|
+
current = current[part];
|
|
16
|
+
}
|
|
17
|
+
return current;
|
|
18
|
+
};
|
|
7
19
|
/**
|
|
8
20
|
* Dictionary-accepting variant of `useI18n`.
|
|
9
21
|
*
|
|
10
|
-
* Used internally by the
|
|
11
|
-
* at runtime by key, the
|
|
22
|
+
* Used internally by the Babel optimization: instead of looking up the dictionary
|
|
23
|
+
* at runtime by key, the Babel plugin pre-imports the dictionary JSON at build time
|
|
12
24
|
* and passes it directly here. This enables tree-shaking of unused locale content.
|
|
13
25
|
*/
|
|
14
|
-
const useDictionary = (dictionary,
|
|
15
|
-
const content = (0, vue_intlayer.useDictionary)(dictionary);
|
|
26
|
+
const useDictionary = (dictionary, options) => {
|
|
16
27
|
const { locale: currentLocale, setLocale, availableLocales } = (0, vue_intlayer.useLocale)();
|
|
28
|
+
const namespacePrefix = options?.namespace;
|
|
29
|
+
const datetimeFormats = options?.datetimeFormats;
|
|
30
|
+
const numberFormats = options?.numberFormats;
|
|
31
|
+
const content = (0, vue_intlayer.useDictionary)(dictionary);
|
|
17
32
|
const localeRef = (0, vue.computed)({
|
|
18
33
|
get: () => currentLocale.value,
|
|
19
|
-
set: (
|
|
20
|
-
setLocale(
|
|
34
|
+
set: (newLocale) => {
|
|
35
|
+
setLocale(newLocale);
|
|
21
36
|
}
|
|
22
37
|
});
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
38
|
+
const resolveKey = (lookupKey) => namespacePrefix ? `${namespacePrefix}.${lookupKey}` : lookupKey;
|
|
39
|
+
const lookupRaw = (key) => {
|
|
40
|
+
const result = navigatePath(content, resolveKey(key));
|
|
41
|
+
return result?.$raw?.value ?? result?.value ?? result;
|
|
42
|
+
};
|
|
43
|
+
const translateKey = (key, args) => {
|
|
44
|
+
const { values, count, defaultMessage } = require_resolveVueMessage.parseTranslateArguments(args);
|
|
45
|
+
const rawValue = lookupRaw(key);
|
|
46
|
+
if (rawValue === void 0) {
|
|
47
|
+
if (defaultMessage !== void 0) return require_resolveVueMessage.resolveVueMessage(defaultMessage, values, count, currentLocale.value);
|
|
48
|
+
return key;
|
|
31
49
|
}
|
|
32
|
-
|
|
33
|
-
if (!params) return str;
|
|
34
|
-
return str.replace(/\{(\w+)\}/g, (_, k) => params[k] != null ? String(params[k]) : `{${k}}`);
|
|
50
|
+
return require_resolveVueMessage.resolveVueMessage(rawValue, values, count, currentLocale.value);
|
|
35
51
|
};
|
|
52
|
+
const translate = (key, ...args) => translateKey(String(key), args);
|
|
36
53
|
return {
|
|
37
54
|
locale: localeRef,
|
|
38
55
|
availableLocales,
|
|
39
|
-
t,
|
|
40
|
-
|
|
41
|
-
|
|
56
|
+
t: translate,
|
|
57
|
+
tc: translate,
|
|
58
|
+
te: (key) => lookupRaw(String(key)) !== void 0,
|
|
59
|
+
tm: (key) => lookupRaw(String(key)) ?? {},
|
|
60
|
+
rt: (message, ...args) => {
|
|
61
|
+
const { values, count } = require_resolveVueMessage.parseTranslateArguments(args);
|
|
62
|
+
return require_resolveVueMessage.resolveVueMessage(message, values, count, currentLocale.value);
|
|
63
|
+
},
|
|
64
|
+
d: (value, formatOrOptions) => require_formats.formatDateValue(value, formatOrOptions, currentLocale.value, datetimeFormats),
|
|
65
|
+
n: (value, formatOrOptions) => require_formats.formatNumberValue(value, formatOrOptions, currentLocale.value, numberFormats)
|
|
42
66
|
};
|
|
43
67
|
};
|
|
44
68
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionary.cjs","names":[],"sources":["../../src/useDictionary.ts"],"sourcesContent":["import type { ValidDotPathsFor } from '@intlayer/core/transpiler';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type {
|
|
1
|
+
{"version":3,"file":"useDictionary.cjs","names":["parseTranslateArguments","resolveVueMessage","formatDateValue","formatNumberValue"],"sources":["../../src/useDictionary.ts"],"sourcesContent":["import type { ValidDotPathsFor } from '@intlayer/core/transpiler';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { computed, type WritableComputedRef } from 'vue';\nimport { useDictionary as useDictionaryBase, useLocale } from 'vue-intlayer';\nimport {\n type DateTimeFormatsConfig,\n formatDateValue,\n formatNumberValue,\n type NumberFormatsConfig,\n} from './formats';\nimport {\n parseTranslateArguments,\n resolveVueMessage,\n} from './resolveVueMessage';\n\nconst navigatePath = (objectValue: unknown, path: string): unknown => {\n if (!path) return objectValue;\n const parts = path.split('.');\n let current: unknown = objectValue;\n for (const part of parts) {\n if (\n current === null ||\n current === undefined ||\n typeof current !== 'object'\n ) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n};\n\n/**\n * Dictionary-accepting variant of `useI18n`.\n *\n * Used internally by the Babel optimization: instead of looking up the dictionary\n * at runtime by key, the Babel plugin pre-imports the dictionary JSON at build time\n * and passes it directly here. This enables tree-shaking of unused locale content.\n */\nexport const useDictionary = <\n const T extends Dictionary,\n const N extends DictionaryKeys = DictionaryKeys,\n>(\n dictionary: T,\n options?: Record<string, unknown> & { namespace?: N }\n): {\n locale: WritableComputedRef<string>;\n availableLocales: string[];\n t: <P extends ValidDotPathsFor<N>>(key: P, ...args: unknown[]) => string;\n tc: <P extends ValidDotPathsFor<N>>(key: P, ...args: unknown[]) => string;\n te: <P extends ValidDotPathsFor<N>>(key: P) => boolean;\n tm: <P extends ValidDotPathsFor<N>>(key: P) => unknown;\n rt: (message: unknown, ...args: unknown[]) => string;\n d: (\n value: Date | number | string,\n formatOrOptions?: string | Intl.DateTimeFormatOptions\n ) => string;\n n: (\n value: number,\n formatOrOptions?: string | Intl.NumberFormatOptions\n ) => string;\n} => {\n const { locale: currentLocale, setLocale, availableLocales } = useLocale();\n\n const namespacePrefix = options?.namespace as string | undefined;\n\n const datetimeFormats = options?.datetimeFormats as\n | DateTimeFormatsConfig\n | undefined;\n const numberFormats = options?.numberFormats as\n | NumberFormatsConfig\n | undefined;\n\n const content = useDictionaryBase(dictionary);\n\n const localeRef = computed({\n get: () => currentLocale.value as string,\n set: (newLocale: string) => {\n setLocale(newLocale as LocalesValues);\n },\n });\n\n const resolveKey = (lookupKey: string): string =>\n namespacePrefix ? `${namespacePrefix}.${lookupKey}` : lookupKey;\n\n const lookupRaw = (key: string): unknown => {\n // navigatePath on the returned proxy will correctly resolve nested properties\n const result = navigatePath(content, resolveKey(key));\n // For leaf nodes, we can access .value to get the real underlying primitive/node\n return (result as any)?.$raw?.value ?? (result as any)?.value ?? result;\n };\n\n const translateKey = (key: string, args: unknown[]): string => {\n const { values, count, defaultMessage } = parseTranslateArguments(args);\n const rawValue = lookupRaw(key);\n\n if (rawValue === undefined) {\n if (defaultMessage !== undefined) {\n return resolveVueMessage(\n defaultMessage,\n values,\n count,\n currentLocale.value as LocalesValues\n );\n }\n return key;\n }\n\n return resolveVueMessage(\n rawValue,\n values,\n count,\n currentLocale.value as LocalesValues\n );\n };\n\n const translate = <P extends ValidDotPathsFor<N>>(\n key: P,\n ...args: unknown[]\n ): string => translateKey(String(key), args);\n\n return {\n locale: localeRef,\n availableLocales: availableLocales as string[],\n t: translate,\n tc: translate,\n te: <P extends ValidDotPathsFor<N>>(key: P): boolean =>\n lookupRaw(String(key)) !== undefined,\n tm: <P extends ValidDotPathsFor<N>>(key: P): unknown =>\n lookupRaw(String(key)) ?? {},\n rt: (message: unknown, ...args: unknown[]): string => {\n const { values, count } = parseTranslateArguments(args);\n return resolveVueMessage(\n message,\n values,\n count,\n currentLocale.value as LocalesValues\n );\n },\n d: (\n value: Date | number | string,\n formatOrOptions?: string | Intl.DateTimeFormatOptions\n ): string =>\n formatDateValue(\n value,\n formatOrOptions,\n currentLocale.value,\n datetimeFormats\n ),\n n: (\n value: number,\n formatOrOptions?: string | Intl.NumberFormatOptions\n ): string =>\n formatNumberValue(\n value,\n formatOrOptions,\n currentLocale.value,\n numberFormats\n ),\n };\n};\n"],"mappings":";;;;;;;;AAmBA,MAAM,gBAAgB,aAAsB,SAA0B;AACpE,KAAI,CAAC,KAAM,QAAO;CAClB,MAAM,QAAQ,KAAK,MAAM,IAAI;CAC7B,IAAI,UAAmB;AACvB,MAAK,MAAM,QAAQ,OAAO;AACxB,MACE,YAAY,QACZ,YAAY,UACZ,OAAO,YAAY,SAEnB;AAEF,YAAW,QAAoC;;AAEjD,QAAO;;;;;;;;;AAUT,MAAa,iBAIX,YACA,YAiBG;CACH,MAAM,EAAE,QAAQ,eAAe,WAAW,kDAAgC;CAE1E,MAAM,kBAAkB,SAAS;CAEjC,MAAM,kBAAkB,SAAS;CAGjC,MAAM,gBAAgB,SAAS;CAI/B,MAAM,0CAA4B,WAAW;CAE7C,MAAM,8BAAqB;EACzB,WAAW,cAAc;EACzB,MAAM,cAAsB;AAC1B,aAAU,UAA2B;;EAExC,CAAC;CAEF,MAAM,cAAc,cAClB,kBAAkB,GAAG,gBAAgB,GAAG,cAAc;CAExD,MAAM,aAAa,QAAyB;EAE1C,MAAM,SAAS,aAAa,SAAS,WAAW,IAAI,CAAC;AAErD,SAAQ,QAAgB,MAAM,SAAU,QAAgB,SAAS;;CAGnE,MAAM,gBAAgB,KAAa,SAA4B;EAC7D,MAAM,EAAE,QAAQ,OAAO,mBAAmBA,kDAAwB,KAAK;EACvE,MAAM,WAAW,UAAU,IAAI;AAE/B,MAAI,aAAa,QAAW;AAC1B,OAAI,mBAAmB,OACrB,QAAOC,4CACL,gBACA,QACA,OACA,cAAc,MACf;AAEH,UAAO;;AAGT,SAAOA,4CACL,UACA,QACA,OACA,cAAc,MACf;;CAGH,MAAM,aACJ,KACA,GAAG,SACQ,aAAa,OAAO,IAAI,EAAE,KAAK;AAE5C,QAAO;EACL,QAAQ;EACU;EAClB,GAAG;EACH,IAAI;EACJ,KAAoC,QAClC,UAAU,OAAO,IAAI,CAAC,KAAK;EAC7B,KAAoC,QAClC,UAAU,OAAO,IAAI,CAAC,IAAI,EAAE;EAC9B,KAAK,SAAkB,GAAG,SAA4B;GACpD,MAAM,EAAE,QAAQ,UAAUD,kDAAwB,KAAK;AACvD,UAAOC,4CACL,SACA,QACA,OACA,cAAc,MACf;;EAEH,IACE,OACA,oBAEAC,gCACE,OACA,iBACA,cAAc,OACd,gBACD;EACH,IACE,OACA,oBAEAC,kCACE,OACA,iBACA,cAAc,OACd,cACD;EACJ"}
|
|
@@ -1,40 +1,68 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_formats = require('./formats.cjs');
|
|
4
|
+
const require_resolveVueMessage = require('./resolveVueMessage.cjs');
|
|
3
5
|
let vue = require("vue");
|
|
4
6
|
let vue_intlayer = require("vue-intlayer");
|
|
5
7
|
|
|
6
8
|
//#region src/useDictionaryDynamic.ts
|
|
9
|
+
const navigatePath = (objectValue, path) => {
|
|
10
|
+
if (!path) return objectValue;
|
|
11
|
+
const parts = path.split(".");
|
|
12
|
+
let current = objectValue;
|
|
13
|
+
for (const part of parts) {
|
|
14
|
+
if (current === null || current === void 0 || typeof current !== "object") return;
|
|
15
|
+
current = current[part];
|
|
16
|
+
}
|
|
17
|
+
return current;
|
|
18
|
+
};
|
|
7
19
|
/**
|
|
8
20
|
* Dynamic dictionary-accepting variant of `useI18n`.
|
|
21
|
+
*
|
|
22
|
+
* Used internally by the Babel optimization: instead of looking up the dictionary
|
|
23
|
+
* at runtime by key, the Babel plugin dynamically imports the dictionary JSON
|
|
24
|
+
* (or .mjs module) based on the locale.
|
|
9
25
|
*/
|
|
10
|
-
const useDictionaryDynamic =
|
|
11
|
-
const content = await (0, vue_intlayer.useDictionaryDynamic)(dictionaryPromise, key);
|
|
26
|
+
const useDictionaryDynamic = (dictionaryPromise, key, options) => {
|
|
12
27
|
const { locale: currentLocale, setLocale, availableLocales } = (0, vue_intlayer.useLocale)();
|
|
28
|
+
const namespacePrefix = options?.namespace;
|
|
29
|
+
const datetimeFormats = options?.datetimeFormats;
|
|
30
|
+
const numberFormats = options?.numberFormats;
|
|
31
|
+
const content = (0, vue_intlayer.useDictionaryDynamic)(dictionaryPromise, key);
|
|
13
32
|
const localeRef = (0, vue.computed)({
|
|
14
33
|
get: () => currentLocale.value,
|
|
15
|
-
set: (
|
|
16
|
-
setLocale(
|
|
34
|
+
set: (newLocale) => {
|
|
35
|
+
setLocale(newLocale);
|
|
17
36
|
}
|
|
18
37
|
});
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
38
|
+
const resolveKey = (lookupKey) => namespacePrefix ? `${namespacePrefix}.${lookupKey}` : lookupKey;
|
|
39
|
+
const lookupRaw = (lookupKey) => {
|
|
40
|
+
const result = navigatePath(content, resolveKey(lookupKey));
|
|
41
|
+
return result?.$raw?.value ?? result?.value ?? result;
|
|
42
|
+
};
|
|
43
|
+
const translateKey = (lookupKey, args) => {
|
|
44
|
+
const { values, count, defaultMessage } = require_resolveVueMessage.parseTranslateArguments(args);
|
|
45
|
+
const rawValue = lookupRaw(lookupKey);
|
|
46
|
+
if (rawValue === void 0) {
|
|
47
|
+
if (defaultMessage !== void 0) return require_resolveVueMessage.resolveVueMessage(defaultMessage, values, count, currentLocale.value);
|
|
48
|
+
return lookupKey;
|
|
27
49
|
}
|
|
28
|
-
|
|
29
|
-
if (!params) return str;
|
|
30
|
-
return str.replace(/\{(\w+)\}/g, (_, key) => params[key] != null ? String(params[key]) : `{${key}}`);
|
|
50
|
+
return require_resolveVueMessage.resolveVueMessage(rawValue, values, count, currentLocale.value);
|
|
31
51
|
};
|
|
52
|
+
const translate = (lookupKey, ...args) => translateKey(String(lookupKey), args);
|
|
32
53
|
return {
|
|
33
54
|
locale: localeRef,
|
|
34
55
|
availableLocales,
|
|
35
|
-
t,
|
|
36
|
-
|
|
37
|
-
|
|
56
|
+
t: translate,
|
|
57
|
+
tc: translate,
|
|
58
|
+
te: (lookupKey) => lookupRaw(String(lookupKey)) !== void 0,
|
|
59
|
+
tm: (lookupKey) => lookupRaw(String(lookupKey)) ?? {},
|
|
60
|
+
rt: (message, ...args) => {
|
|
61
|
+
const { values, count } = require_resolveVueMessage.parseTranslateArguments(args);
|
|
62
|
+
return require_resolveVueMessage.resolveVueMessage(message, values, count, currentLocale.value);
|
|
63
|
+
},
|
|
64
|
+
d: (value, formatOrOptions) => require_formats.formatDateValue(value, formatOrOptions, currentLocale.value, datetimeFormats),
|
|
65
|
+
n: (value, formatOrOptions) => require_formats.formatNumberValue(value, formatOrOptions, currentLocale.value, numberFormats)
|
|
38
66
|
};
|
|
39
67
|
};
|
|
40
68
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionaryDynamic.cjs","names":[],"sources":["../../src/useDictionaryDynamic.ts"],"sourcesContent":["import type { ValidDotPathsFor } from '@intlayer/core/transpiler';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { computed, type WritableComputedRef } from 'vue';\nimport {\n useDictionaryDynamic as useDictionaryDynamicBase,\n useLocale,\n} from 'vue-intlayer';\n\n/**\n * Dynamic dictionary-accepting variant of `useI18n`.\n */\nexport const useDictionaryDynamic =
|
|
1
|
+
{"version":3,"file":"useDictionaryDynamic.cjs","names":["parseTranslateArguments","resolveVueMessage","formatDateValue","formatNumberValue"],"sources":["../../src/useDictionaryDynamic.ts"],"sourcesContent":["import type { ValidDotPathsFor } from '@intlayer/core/transpiler';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { computed, type WritableComputedRef } from 'vue';\nimport {\n useDictionaryDynamic as useDictionaryDynamicBase,\n useLocale,\n} from 'vue-intlayer';\nimport {\n type DateTimeFormatsConfig,\n formatDateValue,\n formatNumberValue,\n type NumberFormatsConfig,\n} from './formats';\nimport {\n parseTranslateArguments,\n resolveVueMessage,\n} from './resolveVueMessage';\n\nconst navigatePath = (objectValue: unknown, path: string): unknown => {\n if (!path) return objectValue;\n const parts = path.split('.');\n let current: unknown = objectValue;\n for (const part of parts) {\n if (\n current === null ||\n current === undefined ||\n typeof current !== 'object'\n ) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n};\n\n/**\n * Dynamic dictionary-accepting variant of `useI18n`.\n *\n * Used internally by the Babel optimization: instead of looking up the dictionary\n * at runtime by key, the Babel plugin dynamically imports the dictionary JSON\n * (or .mjs module) based on the locale.\n */\nexport const useDictionaryDynamic = <\n const T extends Dictionary,\n const K extends string,\n const N extends DictionaryKeys = DictionaryKeys,\n>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n key: K,\n options?: Record<string, unknown> & { namespace?: N }\n): {\n locale: WritableComputedRef<string>;\n availableLocales: string[];\n t: <P extends ValidDotPathsFor<N>>(key: P, ...args: unknown[]) => string;\n tc: <P extends ValidDotPathsFor<N>>(key: P, ...args: unknown[]) => string;\n te: <P extends ValidDotPathsFor<N>>(key: P) => boolean;\n tm: <P extends ValidDotPathsFor<N>>(key: P) => unknown;\n rt: (message: unknown, ...args: unknown[]) => string;\n d: (\n value: Date | number | string,\n formatOrOptions?: string | Intl.DateTimeFormatOptions\n ) => string;\n n: (\n value: number,\n formatOrOptions?: string | Intl.NumberFormatOptions\n ) => string;\n} => {\n const { locale: currentLocale, setLocale, availableLocales } = useLocale();\n\n const namespacePrefix = options?.namespace as string | undefined;\n\n const datetimeFormats = options?.datetimeFormats as\n | DateTimeFormatsConfig\n | undefined;\n const numberFormats = options?.numberFormats as\n | NumberFormatsConfig\n | undefined;\n\n const content = useDictionaryDynamicBase<T, any>(\n dictionaryPromise,\n key as any\n );\n\n const localeRef = computed({\n get: () => currentLocale.value as string,\n set: (newLocale: string) => {\n setLocale(newLocale as LocalesValues);\n },\n });\n\n const resolveKey = (lookupKey: string): string =>\n namespacePrefix ? `${namespacePrefix}.${lookupKey}` : lookupKey;\n\n const lookupRaw = (lookupKey: string): unknown => {\n // navigatePath on the returned proxy will correctly resolve nested properties\n const result = navigatePath(content, resolveKey(lookupKey));\n // For leaf nodes, we can access .value to get the real underlying primitive/node\n return (result as any)?.$raw?.value ?? (result as any)?.value ?? result;\n };\n\n const translateKey = (lookupKey: string, args: unknown[]): string => {\n const { values, count, defaultMessage } = parseTranslateArguments(args);\n const rawValue = lookupRaw(lookupKey);\n\n if (rawValue === undefined) {\n if (defaultMessage !== undefined) {\n return resolveVueMessage(\n defaultMessage,\n values,\n count,\n currentLocale.value as LocalesValues\n );\n }\n return lookupKey;\n }\n\n return resolveVueMessage(\n rawValue,\n values,\n count,\n currentLocale.value as LocalesValues\n );\n };\n\n const translate = <P extends ValidDotPathsFor<N>>(\n lookupKey: P,\n ...args: unknown[]\n ): string => translateKey(String(lookupKey), args);\n\n return {\n locale: localeRef,\n availableLocales: availableLocales as string[],\n t: translate,\n tc: translate,\n te: <P extends ValidDotPathsFor<N>>(lookupKey: P): boolean =>\n lookupRaw(String(lookupKey)) !== undefined,\n tm: <P extends ValidDotPathsFor<N>>(lookupKey: P): unknown =>\n lookupRaw(String(lookupKey)) ?? {},\n rt: (message: unknown, ...args: unknown[]): string => {\n const { values, count } = parseTranslateArguments(args);\n return resolveVueMessage(\n message,\n values,\n count,\n currentLocale.value as LocalesValues\n );\n },\n d: (\n value: Date | number | string,\n formatOrOptions?: string | Intl.DateTimeFormatOptions\n ): string =>\n formatDateValue(\n value,\n formatOrOptions,\n currentLocale.value,\n datetimeFormats\n ),\n n: (\n value: number,\n formatOrOptions?: string | Intl.NumberFormatOptions\n ): string =>\n formatNumberValue(\n value,\n formatOrOptions,\n currentLocale.value,\n numberFormats\n ),\n };\n};\n"],"mappings":";;;;;;;;AAuBA,MAAM,gBAAgB,aAAsB,SAA0B;AACpE,KAAI,CAAC,KAAM,QAAO;CAClB,MAAM,QAAQ,KAAK,MAAM,IAAI;CAC7B,IAAI,UAAmB;AACvB,MAAK,MAAM,QAAQ,OAAO;AACxB,MACE,YAAY,QACZ,YAAY,UACZ,OAAO,YAAY,SAEnB;AAEF,YAAW,QAAoC;;AAEjD,QAAO;;;;;;;;;AAUT,MAAa,wBAKX,mBACA,KACA,YAiBG;CACH,MAAM,EAAE,QAAQ,eAAe,WAAW,kDAAgC;CAE1E,MAAM,kBAAkB,SAAS;CAEjC,MAAM,kBAAkB,SAAS;CAGjC,MAAM,gBAAgB,SAAS;CAI/B,MAAM,iDACJ,mBACA,IACD;CAED,MAAM,8BAAqB;EACzB,WAAW,cAAc;EACzB,MAAM,cAAsB;AAC1B,aAAU,UAA2B;;EAExC,CAAC;CAEF,MAAM,cAAc,cAClB,kBAAkB,GAAG,gBAAgB,GAAG,cAAc;CAExD,MAAM,aAAa,cAA+B;EAEhD,MAAM,SAAS,aAAa,SAAS,WAAW,UAAU,CAAC;AAE3D,SAAQ,QAAgB,MAAM,SAAU,QAAgB,SAAS;;CAGnE,MAAM,gBAAgB,WAAmB,SAA4B;EACnE,MAAM,EAAE,QAAQ,OAAO,mBAAmBA,kDAAwB,KAAK;EACvE,MAAM,WAAW,UAAU,UAAU;AAErC,MAAI,aAAa,QAAW;AAC1B,OAAI,mBAAmB,OACrB,QAAOC,4CACL,gBACA,QACA,OACA,cAAc,MACf;AAEH,UAAO;;AAGT,SAAOA,4CACL,UACA,QACA,OACA,cAAc,MACf;;CAGH,MAAM,aACJ,WACA,GAAG,SACQ,aAAa,OAAO,UAAU,EAAE,KAAK;AAElD,QAAO;EACL,QAAQ;EACU;EAClB,GAAG;EACH,IAAI;EACJ,KAAoC,cAClC,UAAU,OAAO,UAAU,CAAC,KAAK;EACnC,KAAoC,cAClC,UAAU,OAAO,UAAU,CAAC,IAAI,EAAE;EACpC,KAAK,SAAkB,GAAG,SAA4B;GACpD,MAAM,EAAE,QAAQ,UAAUD,kDAAwB,KAAK;AACvD,UAAOC,4CACL,SACA,QACA,OACA,cAAc,MACf;;EAEH,IACE,OACA,oBAEAC,gCACE,OACA,iBACA,cAAc,OACd,gBACD;EACH,IACE,OACA,oBAEAC,kCACE,OACA,iBACA,cAAc,OACd,cACD;EACJ"}
|