UNPKG

93.6 kBJavaScriptView Raw
1/*!
2 * vue-i18n-bridge v9.2.0-beta.6
3 * (c) 2021 kazuya kawaguchi
4 * Released under the MIT License.
5 */
6import { ref, getCurrentInstance, computed, watch, onBeforeMount, onUnmounted } from '@vue/composition-api';
7
8/**
9 * Original Utilities
10 * written by kazuya kawaguchi
11 */
12const inBrowser = typeof window !== 'undefined';
13let mark;
14{
15 const perf = inBrowser && window.performance;
16 if (perf &&
17 perf.mark &&
18 perf.measure &&
19 perf.clearMarks &&
20 perf.clearMeasures) {
21 mark = (tag) => perf.mark(tag);
22 }
23}
24const RE_ARGS = /\{([0-9a-zA-Z]+)\}/g;
25/* eslint-disable */
26function format(message, ...args) {
27 if (args.length === 1 && isObject(args[0])) {
28 args = args[0];
29 }
30 if (!args || !args.hasOwnProperty) {
31 args = {};
32 }
33 return message.replace(RE_ARGS, (match, identifier) => {
34 return args.hasOwnProperty(identifier) ? args[identifier] : '';
35 });
36}
37const hasSymbol = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
38const makeSymbol = (name) => hasSymbol ? Symbol(name) : name;
39const generateFormatCacheKey = (locale, key, source) => friendlyJSONstringify({ l: locale, k: key, s: source });
40const friendlyJSONstringify = (json) => JSON.stringify(json)
41 .replace(/\u2028/g, '\\u2028')
42 .replace(/\u2029/g, '\\u2029')
43 .replace(/\u0027/g, '\\u0027');
44const isNumber = (val) => typeof val === 'number' && isFinite(val);
45const isDate = (val) => toTypeString(val) === '[object Date]';
46const isRegExp = (val) => toTypeString(val) === '[object RegExp]';
47const isEmptyObject = (val) => isPlainObject(val) && Object.keys(val).length === 0;
48function warn(msg, err) {
49 if (typeof console !== 'undefined') {
50 console.warn(`[intlify] ` + msg);
51 /* istanbul ignore if */
52 if (err) {
53 console.warn(err.stack);
54 }
55 }
56}
57const assign = Object.assign;
58let _globalThis;
59const getGlobalThis = () => {
60 // prettier-ignore
61 return (_globalThis ||
62 (_globalThis =
63 typeof globalThis !== 'undefined'
64 ? globalThis
65 : typeof self !== 'undefined'
66 ? self
67 : typeof window !== 'undefined'
68 ? window
69 : typeof global !== 'undefined'
70 ? global
71 : {}));
72};
73function escapeHtml(rawText) {
74 return rawText
75 .replace(/</g, '&lt;')
76 .replace(/>/g, '&gt;')
77 .replace(/"/g, '&quot;')
78 .replace(/'/g, '&apos;');
79}
80const hasOwnProperty = Object.prototype.hasOwnProperty;
81function hasOwn(obj, key) {
82 return hasOwnProperty.call(obj, key);
83}
84/* eslint-enable */
85/**
86 * Useful Utilities By Evan you
87 * Modified by kazuya kawaguchi
88 * MIT License
89 * https://github.com/vuejs/vue-next/blob/master/packages/shared/src/index.ts
90 * https://github.com/vuejs/vue-next/blob/master/packages/shared/src/codeframe.ts
91 */
92const isArray = Array.isArray;
93const isFunction = (val) => typeof val === 'function';
94const isString = (val) => typeof val === 'string';
95const isBoolean = (val) => typeof val === 'boolean';
96const isObject = (val) => // eslint-disable-line
97 val !== null && typeof val === 'object';
98const objectToString = Object.prototype.toString;
99const toTypeString = (value) => objectToString.call(value);
100const isPlainObject = (val) => toTypeString(val) === '[object Object]';
101// for converting list and named values to displayed strings.
102const toDisplayString = (val) => {
103 return val == null
104 ? ''
105 : isArray(val) || (isPlainObject(val) && val.toString === objectToString)
106 ? JSON.stringify(val, null, 2)
107 : String(val);
108};
109
110const CompileErrorCodes = {
111 // tokenizer error codes
112 EXPECTED_TOKEN: 1,
113 INVALID_TOKEN_IN_PLACEHOLDER: 2,
114 UNTERMINATED_SINGLE_QUOTE_IN_PLACEHOLDER: 3,
115 UNKNOWN_ESCAPE_SEQUENCE: 4,
116 INVALID_UNICODE_ESCAPE_SEQUENCE: 5,
117 UNBALANCED_CLOSING_BRACE: 6,
118 UNTERMINATED_CLOSING_BRACE: 7,
119 EMPTY_PLACEHOLDER: 8,
120 NOT_ALLOW_NEST_PLACEHOLDER: 9,
121 INVALID_LINKED_FORMAT: 10,
122 // parser error codes
123 MUST_HAVE_MESSAGES_IN_PLURAL: 11,
124 UNEXPECTED_EMPTY_LINKED_MODIFIER: 12,
125 UNEXPECTED_EMPTY_LINKED_KEY: 13,
126 UNEXPECTED_LEXICAL_ANALYSIS: 14,
127 // Special value for higher-order compilers to pick up the last code
128 // to avoid collision of error codes. This should always be kept as the last
129 // item.
130 __EXTEND_POINT__: 15
131};
132/** @internal */
133const errorMessages$2 = {
134 // tokenizer error messages
135 [CompileErrorCodes.EXPECTED_TOKEN]: `Expected token: '{0}'`,
136 [CompileErrorCodes.INVALID_TOKEN_IN_PLACEHOLDER]: `Invalid token in placeholder: '{0}'`,
137 [CompileErrorCodes.UNTERMINATED_SINGLE_QUOTE_IN_PLACEHOLDER]: `Unterminated single quote in placeholder`,
138 [CompileErrorCodes.UNKNOWN_ESCAPE_SEQUENCE]: `Unknown escape sequence: \\{0}`,
139 [CompileErrorCodes.INVALID_UNICODE_ESCAPE_SEQUENCE]: `Invalid unicode escape sequence: {0}`,
140 [CompileErrorCodes.UNBALANCED_CLOSING_BRACE]: `Unbalanced closing brace`,
141 [CompileErrorCodes.UNTERMINATED_CLOSING_BRACE]: `Unterminated closing brace`,
142 [CompileErrorCodes.EMPTY_PLACEHOLDER]: `Empty placeholder`,
143 [CompileErrorCodes.NOT_ALLOW_NEST_PLACEHOLDER]: `Not allowed nest placeholder`,
144 [CompileErrorCodes.INVALID_LINKED_FORMAT]: `Invalid linked format`,
145 // parser error messages
146 [CompileErrorCodes.MUST_HAVE_MESSAGES_IN_PLURAL]: `Plural must have messages`,
147 [CompileErrorCodes.UNEXPECTED_EMPTY_LINKED_MODIFIER]: `Unexpected empty linked modifier`,
148 [CompileErrorCodes.UNEXPECTED_EMPTY_LINKED_KEY]: `Unexpected empty linked key`,
149 [CompileErrorCodes.UNEXPECTED_LEXICAL_ANALYSIS]: `Unexpected lexical analysis in token: '{0}'`
150};
151function createCompileError(code, loc, options = {}) {
152 const { domain, messages, args } = options;
153 const msg = format((messages || errorMessages$2)[code] || '', ...(args || []))
154 ;
155 const error = new SyntaxError(String(msg));
156 error.code = code;
157 if (loc) {
158 error.location = loc;
159 }
160 error.domain = domain;
161 return error;
162}
163
164const pathStateMachine = [];
165pathStateMachine[0 /* BEFORE_PATH */] = {
166 ["w" /* WORKSPACE */]: [0 /* BEFORE_PATH */],
167 ["i" /* IDENT */]: [3 /* IN_IDENT */, 0 /* APPEND */],
168 ["[" /* LEFT_BRACKET */]: [4 /* IN_SUB_PATH */],
169 ["o" /* END_OF_FAIL */]: [7 /* AFTER_PATH */]
170};
171pathStateMachine[1 /* IN_PATH */] = {
172 ["w" /* WORKSPACE */]: [1 /* IN_PATH */],
173 ["." /* DOT */]: [2 /* BEFORE_IDENT */],
174 ["[" /* LEFT_BRACKET */]: [4 /* IN_SUB_PATH */],
175 ["o" /* END_OF_FAIL */]: [7 /* AFTER_PATH */]
176};
177pathStateMachine[2 /* BEFORE_IDENT */] = {
178 ["w" /* WORKSPACE */]: [2 /* BEFORE_IDENT */],
179 ["i" /* IDENT */]: [3 /* IN_IDENT */, 0 /* APPEND */],
180 ["0" /* ZERO */]: [3 /* IN_IDENT */, 0 /* APPEND */]
181};
182pathStateMachine[3 /* IN_IDENT */] = {
183 ["i" /* IDENT */]: [3 /* IN_IDENT */, 0 /* APPEND */],
184 ["0" /* ZERO */]: [3 /* IN_IDENT */, 0 /* APPEND */],
185 ["w" /* WORKSPACE */]: [1 /* IN_PATH */, 1 /* PUSH */],
186 ["." /* DOT */]: [2 /* BEFORE_IDENT */, 1 /* PUSH */],
187 ["[" /* LEFT_BRACKET */]: [4 /* IN_SUB_PATH */, 1 /* PUSH */],
188 ["o" /* END_OF_FAIL */]: [7 /* AFTER_PATH */, 1 /* PUSH */]
189};
190pathStateMachine[4 /* IN_SUB_PATH */] = {
191 ["'" /* SINGLE_QUOTE */]: [5 /* IN_SINGLE_QUOTE */, 0 /* APPEND */],
192 ["\"" /* DOUBLE_QUOTE */]: [6 /* IN_DOUBLE_QUOTE */, 0 /* APPEND */],
193 ["[" /* LEFT_BRACKET */]: [
194 4 /* IN_SUB_PATH */,
195 2 /* INC_SUB_PATH_DEPTH */
196 ],
197 ["]" /* RIGHT_BRACKET */]: [1 /* IN_PATH */, 3 /* PUSH_SUB_PATH */],
198 ["o" /* END_OF_FAIL */]: 8 /* ERROR */,
199 ["l" /* ELSE */]: [4 /* IN_SUB_PATH */, 0 /* APPEND */]
200};
201pathStateMachine[5 /* IN_SINGLE_QUOTE */] = {
202 ["'" /* SINGLE_QUOTE */]: [4 /* IN_SUB_PATH */, 0 /* APPEND */],
203 ["o" /* END_OF_FAIL */]: 8 /* ERROR */,
204 ["l" /* ELSE */]: [5 /* IN_SINGLE_QUOTE */, 0 /* APPEND */]
205};
206pathStateMachine[6 /* IN_DOUBLE_QUOTE */] = {
207 ["\"" /* DOUBLE_QUOTE */]: [4 /* IN_SUB_PATH */, 0 /* APPEND */],
208 ["o" /* END_OF_FAIL */]: 8 /* ERROR */,
209 ["l" /* ELSE */]: [6 /* IN_DOUBLE_QUOTE */, 0 /* APPEND */]
210};
211/**
212 * Check if an expression is a literal value.
213 */
214const literalValueRE = /^\s?(?:true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/;
215function isLiteral(exp) {
216 return literalValueRE.test(exp);
217}
218/**
219 * Strip quotes from a string
220 */
221function stripQuotes(str) {
222 const a = str.charCodeAt(0);
223 const b = str.charCodeAt(str.length - 1);
224 return a === b && (a === 0x22 || a === 0x27) ? str.slice(1, -1) : str;
225}
226/**
227 * Determine the type of a character in a keypath.
228 */
229function getPathCharType(ch) {
230 if (ch === undefined || ch === null) {
231 return "o" /* END_OF_FAIL */;
232 }
233 const code = ch.charCodeAt(0);
234 switch (code) {
235 case 0x5b: // [
236 case 0x5d: // ]
237 case 0x2e: // .
238 case 0x22: // "
239 case 0x27: // '
240 return ch;
241 case 0x5f: // _
242 case 0x24: // $
243 case 0x2d: // -
244 return "i" /* IDENT */;
245 case 0x09: // Tab (HT)
246 case 0x0a: // Newline (LF)
247 case 0x0d: // Return (CR)
248 case 0xa0: // No-break space (NBSP)
249 case 0xfeff: // Byte Order Mark (BOM)
250 case 0x2028: // Line Separator (LS)
251 case 0x2029: // Paragraph Separator (PS)
252 return "w" /* WORKSPACE */;
253 }
254 return "i" /* IDENT */;
255}
256/**
257 * Format a subPath, return its plain form if it is
258 * a literal string or number. Otherwise prepend the
259 * dynamic indicator (*).
260 */
261function formatSubPath(path) {
262 const trimmed = path.trim();
263 // invalid leading 0
264 if (path.charAt(0) === '0' && isNaN(parseInt(path))) {
265 return false;
266 }
267 return isLiteral(trimmed)
268 ? stripQuotes(trimmed)
269 : "*" /* ASTARISK */ + trimmed;
270}
271/**
272 * Parse a string path into an array of segments
273 */
274function parse(path) {
275 const keys = [];
276 let index = -1;
277 let mode = 0 /* BEFORE_PATH */;
278 let subPathDepth = 0;
279 let c;
280 let key; // eslint-disable-line
281 let newChar;
282 let type;
283 let transition;
284 let action;
285 let typeMap;
286 const actions = [];
287 actions[0 /* APPEND */] = () => {
288 if (key === undefined) {
289 key = newChar;
290 }
291 else {
292 key += newChar;
293 }
294 };
295 actions[1 /* PUSH */] = () => {
296 if (key !== undefined) {
297 keys.push(key);
298 key = undefined;
299 }
300 };
301 actions[2 /* INC_SUB_PATH_DEPTH */] = () => {
302 actions[0 /* APPEND */]();
303 subPathDepth++;
304 };
305 actions[3 /* PUSH_SUB_PATH */] = () => {
306 if (subPathDepth > 0) {
307 subPathDepth--;
308 mode = 4 /* IN_SUB_PATH */;
309 actions[0 /* APPEND */]();
310 }
311 else {
312 subPathDepth = 0;
313 if (key === undefined) {
314 return false;
315 }
316 key = formatSubPath(key);
317 if (key === false) {
318 return false;
319 }
320 else {
321 actions[1 /* PUSH */]();
322 }
323 }
324 };
325 function maybeUnescapeQuote() {
326 const nextChar = path[index + 1];
327 if ((mode === 5 /* IN_SINGLE_QUOTE */ &&
328 nextChar === "'" /* SINGLE_QUOTE */) ||
329 (mode === 6 /* IN_DOUBLE_QUOTE */ &&
330 nextChar === "\"" /* DOUBLE_QUOTE */)) {
331 index++;
332 newChar = '\\' + nextChar;
333 actions[0 /* APPEND */]();
334 return true;
335 }
336 }
337 while (mode !== null) {
338 index++;
339 c = path[index];
340 if (c === '\\' && maybeUnescapeQuote()) {
341 continue;
342 }
343 type = getPathCharType(c);
344 typeMap = pathStateMachine[mode];
345 transition = typeMap[type] || typeMap["l" /* ELSE */] || 8 /* ERROR */;
346 // check parse error
347 if (transition === 8 /* ERROR */) {
348 return;
349 }
350 mode = transition[0];
351 if (transition[1] !== undefined) {
352 action = actions[transition[1]];
353 if (action) {
354 newChar = c;
355 if (action() === false) {
356 return;
357 }
358 }
359 }
360 // check parse finish
361 if (mode === 7 /* AFTER_PATH */) {
362 return keys;
363 }
364 }
365}
366// path token cache
367const cache = new Map();
368/**
369 * key-value message resolver
370 *
371 * @remarks
372 * Resolves messages with the key-value structure. Note that messages with a hierarchical structure such as objects cannot be resolved
373 *
374 * @param obj - A target object to be resolved with path
375 * @param path - A {@link Path | path} to resolve the value of message
376 *
377 * @returns A resolved {@link PathValue | path value}
378 *
379 * @VueI18nGeneral
380 */
381function resolveWithKeyValue(obj, path) {
382 return isObject(obj) ? obj[path] : null;
383}
384/**
385 * message resolver
386 *
387 * @remarks
388 * Resolves messages. messages with a hierarchical structure such as objects can be resolved. This resolver is used in VueI18n as default.
389 *
390 * @param obj - A target object to be resolved with path
391 * @param path - A {@link Path | path} to resolve the value of message
392 *
393 * @returns A resolved {@link PathValue | path value}
394 *
395 * @VueI18nGeneral
396 */
397function resolveValue(obj, path) {
398 // check object
399 if (!isObject(obj)) {
400 return null;
401 }
402 // parse path
403 let hit = cache.get(path);
404 if (!hit) {
405 hit = parse(path);
406 if (hit) {
407 cache.set(path, hit);
408 }
409 }
410 // check hit
411 if (!hit) {
412 return null;
413 }
414 // resolve path value
415 const len = hit.length;
416 let last = obj;
417 let i = 0;
418 while (i < len) {
419 const val = last[hit[i]];
420 if (val === undefined) {
421 return null;
422 }
423 last = val;
424 i++;
425 }
426 return last;
427}
428
429const DEFAULT_MODIFIER = (str) => str;
430const DEFAULT_MESSAGE = (ctx) => ''; // eslint-disable-line
431const DEFAULT_MESSAGE_DATA_TYPE = 'text';
432const DEFAULT_NORMALIZE = (values) => values.length === 0 ? '' : values.join('');
433const DEFAULT_INTERPOLATE = toDisplayString;
434function pluralDefault(choice, choicesLength) {
435 choice = Math.abs(choice);
436 if (choicesLength === 2) {
437 // prettier-ignore
438 return choice
439 ? choice > 1
440 ? 1
441 : 0
442 : 1;
443 }
444 return choice ? Math.min(choice, 2) : 0;
445}
446function getPluralIndex(options) {
447 // prettier-ignore
448 const index = isNumber(options.pluralIndex)
449 ? options.pluralIndex
450 : -1;
451 // prettier-ignore
452 return options.named && (isNumber(options.named.count) || isNumber(options.named.n))
453 ? isNumber(options.named.count)
454 ? options.named.count
455 : isNumber(options.named.n)
456 ? options.named.n
457 : index
458 : index;
459}
460function normalizeNamed(pluralIndex, props) {
461 if (!props.count) {
462 props.count = pluralIndex;
463 }
464 if (!props.n) {
465 props.n = pluralIndex;
466 }
467}
468function createMessageContext(options = {}) {
469 const locale = options.locale;
470 const pluralIndex = getPluralIndex(options);
471 const pluralRule = isObject(options.pluralRules) &&
472 isString(locale) &&
473 isFunction(options.pluralRules[locale])
474 ? options.pluralRules[locale]
475 : pluralDefault;
476 const orgPluralRule = isObject(options.pluralRules) &&
477 isString(locale) &&
478 isFunction(options.pluralRules[locale])
479 ? pluralDefault
480 : undefined;
481 const plural = (messages) => messages[pluralRule(pluralIndex, messages.length, orgPluralRule)];
482 const _list = options.list || [];
483 const list = (index) => _list[index];
484 // eslint-disable-next-line @typescript-eslint/no-explicit-any
485 const _named = options.named || {};
486 isNumber(options.pluralIndex) && normalizeNamed(pluralIndex, _named);
487 const named = (key) => _named[key];
488 // TODO: need to design resolve message function?
489 function message(key) {
490 // prettier-ignore
491 const msg = isFunction(options.messages)
492 ? options.messages(key)
493 : isObject(options.messages)
494 ? options.messages[key]
495 : false;
496 return !msg
497 ? options.parent
498 ? options.parent.message(key) // resolve from parent messages
499 : DEFAULT_MESSAGE
500 : msg;
501 }
502 const _modifier = (name) => options.modifiers
503 ? options.modifiers[name]
504 : DEFAULT_MODIFIER;
505 const normalize = isPlainObject(options.processor) && isFunction(options.processor.normalize)
506 ? options.processor.normalize
507 : DEFAULT_NORMALIZE;
508 const interpolate = isPlainObject(options.processor) &&
509 isFunction(options.processor.interpolate)
510 ? options.processor.interpolate
511 : DEFAULT_INTERPOLATE;
512 const type = isPlainObject(options.processor) && isString(options.processor.type)
513 ? options.processor.type
514 : DEFAULT_MESSAGE_DATA_TYPE;
515 const ctx = {
516 ["list" /* LIST */]: list,
517 ["named" /* NAMED */]: named,
518 ["plural" /* PLURAL */]: plural,
519 ["linked" /* LINKED */]: (key, modifier) => {
520 // TODO: should check `key`
521 const msg = message(key)(ctx);
522 return isString(modifier) ? _modifier(modifier)(msg) : msg;
523 },
524 ["message" /* MESSAGE */]: message,
525 ["type" /* TYPE */]: type,
526 ["interpolate" /* INTERPOLATE */]: interpolate,
527 ["normalize" /* NORMALIZE */]: normalize
528 };
529 return ctx;
530}
531
532const IntlifyDevToolsHooks = {
533 I18nInit: 'i18n:init',
534 FunctionTranslate: 'function:translate'
535};
536
537let devtools = null;
538function setDevToolsHook(hook) {
539 devtools = hook;
540}
541function initI18nDevTools(i18n, version, meta) {
542 // TODO: queue if devtools is undefined
543 devtools &&
544 devtools.emit(IntlifyDevToolsHooks.I18nInit, {
545 timestamp: Date.now(),
546 i18n,
547 version,
548 meta
549 });
550}
551const translateDevTools = /* #__PURE__*/ createDevToolsHook(IntlifyDevToolsHooks.FunctionTranslate);
552function createDevToolsHook(hook) {
553 return (payloads) => devtools && devtools.emit(hook, payloads);
554}
555
556const CoreWarnCodes = {
557 NOT_FOUND_KEY: 1,
558 FALLBACK_TO_TRANSLATE: 2,
559 CANNOT_FORMAT_NUMBER: 3,
560 FALLBACK_TO_NUMBER_FORMAT: 4,
561 CANNOT_FORMAT_DATE: 5,
562 FALLBACK_TO_DATE_FORMAT: 6,
563 __EXTEND_POINT__: 7
564};
565/** @internal */
566const warnMessages$1 = {
567 [CoreWarnCodes.NOT_FOUND_KEY]: `Not found '{key}' key in '{locale}' locale messages.`,
568 [CoreWarnCodes.FALLBACK_TO_TRANSLATE]: `Fall back to translate '{key}' key with '{target}' locale.`,
569 [CoreWarnCodes.CANNOT_FORMAT_NUMBER]: `Cannot format a number value due to not supported Intl.NumberFormat.`,
570 [CoreWarnCodes.FALLBACK_TO_NUMBER_FORMAT]: `Fall back to number format '{key}' key with '{target}' locale.`,
571 [CoreWarnCodes.CANNOT_FORMAT_DATE]: `Cannot format a date value due to not supported Intl.DateTimeFormat.`,
572 [CoreWarnCodes.FALLBACK_TO_DATE_FORMAT]: `Fall back to datetime format '{key}' key with '{target}' locale.`
573};
574function getWarnMessage$1(code, ...args) {
575 return format(warnMessages$1[code], ...args);
576}
577
578/**
579 * Fallback with simple implemenation
580 *
581 * @remarks
582 * A fallback locale function implemented with a simple fallback algorithm.
583 *
584 * Basically, it returns the value as specified in the `fallbackLocale` props, and is processed with the fallback inside intlify.
585 *
586 * @param ctx - A {@link CoreContext | context}
587 * @param fallback - A {@link FallbackLocale | fallback locale}
588 * @param start - A starting {@link Locale | locale}
589 *
590 * @returns Fallback locales
591 *
592 * @VueI18nGeneral
593 */
594function fallbackWithSimple(ctx, fallback, start // eslint-disable-line @typescript-eslint/no-unused-vars
595) {
596 // prettier-ignore
597 return [...new Set([
598 start,
599 ...(isArray(fallback)
600 ? fallback
601 : isObject(fallback)
602 ? Object.keys(fallback)
603 : isString(fallback)
604 ? [fallback]
605 : [start])
606 ])];
607}
608/**
609 * Fallback with locale chain
610 *
611 * @remarks
612 * A fallback locale function implemented with a fallback chain algorithm. It's used in VueI18n as default.
613 *
614 * @param ctx - A {@link CoreContext | context}
615 * @param fallback - A {@link FallbackLocale | fallback locale}
616 * @param start - A starting {@link Locale | locale}
617 *
618 * @returns Fallback locales
619 *
620 * @VueI18nSee [Fallbacking](../guide/essentials/fallback)
621 *
622 * @VueI18nGeneral
623 */
624function fallbackWithLocaleChain(ctx, fallback, start) {
625 const startLocale = isString(start) ? start : DEFAULT_LOCALE;
626 const context = ctx;
627 if (!context.__localeChainCache) {
628 context.__localeChainCache = new Map();
629 }
630 let chain = context.__localeChainCache.get(startLocale);
631 if (!chain) {
632 chain = [];
633 // first block defined by start
634 let block = [start];
635 // while any intervening block found
636 while (isArray(block)) {
637 block = appendBlockToChain(chain, block, fallback);
638 }
639 // prettier-ignore
640 // last block defined by default
641 const defaults = isArray(fallback) || !isPlainObject(fallback)
642 ? fallback
643 : fallback['default']
644 ? fallback['default']
645 : null;
646 // convert defaults to array
647 block = isString(defaults) ? [defaults] : defaults;
648 if (isArray(block)) {
649 appendBlockToChain(chain, block, false);
650 }
651 context.__localeChainCache.set(startLocale, chain);
652 }
653 return chain;
654}
655function appendBlockToChain(chain, block, blocks) {
656 let follow = true;
657 for (let i = 0; i < block.length && isBoolean(follow); i++) {
658 const locale = block[i];
659 if (isString(locale)) {
660 follow = appendLocaleToChain(chain, block[i], blocks);
661 }
662 }
663 return follow;
664}
665function appendLocaleToChain(chain, locale, blocks) {
666 let follow;
667 const tokens = locale.split('-');
668 do {
669 const target = tokens.join('-');
670 follow = appendItemToChain(chain, target, blocks);
671 tokens.splice(-1, 1);
672 } while (tokens.length && follow === true);
673 return follow;
674}
675function appendItemToChain(chain, target, blocks) {
676 let follow = false;
677 if (!chain.includes(target)) {
678 follow = true;
679 if (target) {
680 follow = target[target.length - 1] !== '!';
681 const locale = target.replace(/!/g, '');
682 chain.push(locale);
683 if ((isArray(blocks) || isPlainObject(blocks)) &&
684 blocks[locale] // eslint-disable-line @typescript-eslint/no-explicit-any
685 ) {
686 // eslint-disable-next-line @typescript-eslint/no-explicit-any
687 follow = blocks[locale];
688 }
689 }
690 }
691 return follow;
692}
693
694/* eslint-disable @typescript-eslint/no-explicit-any */
695/**
696 * Intlify core-base version
697 * @internal
698 */
699const VERSION$1 = '9.2.0-beta.6';
700const NOT_REOSLVED = -1;
701const DEFAULT_LOCALE = 'en-US';
702const MISSING_RESOLVE_VALUE = '';
703function getDefaultLinkedModifiers() {
704 return {
705 upper: (val) => (isString(val) ? val.toUpperCase() : val),
706 lower: (val) => (isString(val) ? val.toLowerCase() : val),
707 // prettier-ignore
708 capitalize: (val) => (isString(val)
709 ? `${val.charAt(0).toLocaleUpperCase()}${val.substr(1)}`
710 : val)
711 };
712}
713let _compiler;
714let _resolver;
715/**
716 * Register the message resolver
717 *
718 * @param resolver - A {@link MessageResolver} function
719 *
720 * @VueI18nGeneral
721 */
722function registerMessageResolver(resolver) {
723 _resolver = resolver;
724}
725let _fallbacker;
726/**
727 * Register the locale fallbacker
728 *
729 * @param fallbacker - A {@link LocaleFallbacker} function
730 *
731 * @VueI18nGeneral
732 */
733function registerLocaleFallbacker(fallbacker) {
734 _fallbacker = fallbacker;
735}
736// Additional Meta for Intlify DevTools
737let _additionalMeta = null;
738const setAdditionalMeta = (meta) => {
739 _additionalMeta = meta;
740};
741const getAdditionalMeta = () => _additionalMeta;
742// ID for CoreContext
743let _cid = 0;
744function createCoreContext(options = {}) {
745 // setup options
746 const version = isString(options.version) ? options.version : VERSION$1;
747 const locale = isString(options.locale) ? options.locale : DEFAULT_LOCALE;
748 const fallbackLocale = isArray(options.fallbackLocale) ||
749 isPlainObject(options.fallbackLocale) ||
750 isString(options.fallbackLocale) ||
751 options.fallbackLocale === false
752 ? options.fallbackLocale
753 : locale;
754 const messages = isPlainObject(options.messages)
755 ? options.messages
756 : { [locale]: {} };
757 const datetimeFormats = isPlainObject(options.datetimeFormats)
758 ? options.datetimeFormats
759 : { [locale]: {} }
760 ;
761 const numberFormats = isPlainObject(options.numberFormats)
762 ? options.numberFormats
763 : { [locale]: {} }
764 ;
765 const modifiers = assign({}, options.modifiers || {}, getDefaultLinkedModifiers());
766 const pluralRules = options.pluralRules || {};
767 const missing = isFunction(options.missing) ? options.missing : null;
768 const missingWarn = isBoolean(options.missingWarn) || isRegExp(options.missingWarn)
769 ? options.missingWarn
770 : true;
771 const fallbackWarn = isBoolean(options.fallbackWarn) || isRegExp(options.fallbackWarn)
772 ? options.fallbackWarn
773 : true;
774 const fallbackFormat = !!options.fallbackFormat;
775 const unresolving = !!options.unresolving;
776 const postTranslation = isFunction(options.postTranslation)
777 ? options.postTranslation
778 : null;
779 const processor = isPlainObject(options.processor) ? options.processor : null;
780 const warnHtmlMessage = isBoolean(options.warnHtmlMessage)
781 ? options.warnHtmlMessage
782 : true;
783 const escapeParameter = !!options.escapeParameter;
784 const messageCompiler = isFunction(options.messageCompiler)
785 ? options.messageCompiler
786 : _compiler;
787 const messageResolver = isFunction(options.messageResolver)
788 ? options.messageResolver
789 : _resolver || resolveWithKeyValue;
790 const localeFallbacker = isFunction(options.localeFallbacker)
791 ? options.localeFallbacker
792 : _fallbacker || fallbackWithSimple;
793 const onWarn = isFunction(options.onWarn) ? options.onWarn : warn;
794 // setup internal options
795 const internalOptions = options;
796 const __datetimeFormatters = isObject(internalOptions.__datetimeFormatters)
797 ? internalOptions.__datetimeFormatters
798 : new Map()
799 ;
800 const __numberFormatters = isObject(internalOptions.__numberFormatters)
801 ? internalOptions.__numberFormatters
802 : new Map()
803 ;
804 const __meta = isObject(internalOptions.__meta) ? internalOptions.__meta : {};
805 _cid++;
806 const context = {
807 version,
808 cid: _cid,
809 locale,
810 fallbackLocale,
811 messages,
812 modifiers,
813 pluralRules,
814 missing,
815 missingWarn,
816 fallbackWarn,
817 fallbackFormat,
818 unresolving,
819 postTranslation,
820 processor,
821 warnHtmlMessage,
822 escapeParameter,
823 messageCompiler,
824 messageResolver,
825 localeFallbacker,
826 onWarn,
827 __meta
828 };
829 {
830 context.datetimeFormats = datetimeFormats;
831 context.numberFormats = numberFormats;
832 context.__datetimeFormatters = __datetimeFormatters;
833 context.__numberFormatters = __numberFormatters;
834 }
835 // NOTE: experimental !!
836 {
837 initI18nDevTools(context, version, __meta);
838 }
839 return context;
840}
841/** @internal */
842function isTranslateFallbackWarn(fallback, key) {
843 return fallback instanceof RegExp ? fallback.test(key) : fallback;
844}
845/** @internal */
846function isTranslateMissingWarn(missing, key) {
847 return missing instanceof RegExp ? missing.test(key) : missing;
848}
849/** @internal */
850function handleMissing(context, key, locale, missingWarn, type) {
851 const { missing, onWarn } = context;
852 if (missing !== null) {
853 const ret = missing(context, locale, key, type);
854 return isString(ret) ? ret : key;
855 }
856 else {
857 if (isTranslateMissingWarn(missingWarn, key)) {
858 onWarn(getWarnMessage$1(CoreWarnCodes.NOT_FOUND_KEY, { key, locale }));
859 }
860 return key;
861 }
862}
863/** @internal */
864function updateFallbackLocale(ctx, locale, fallback) {
865 const context = ctx;
866 context.__localeChainCache = new Map();
867 ctx.localeFallbacker(ctx, fallback, locale);
868}
869/* eslint-enable @typescript-eslint/no-explicit-any */
870
871let code$2 = CompileErrorCodes.__EXTEND_POINT__;
872const inc$2 = () => code$2++;
873const CoreErrorCodes = {
874 INVALID_ARGUMENT: code$2,
875 INVALID_DATE_ARGUMENT: inc$2(),
876 INVALID_ISO_DATE_ARGUMENT: inc$2(),
877 __EXTEND_POINT__: inc$2() // 18
878};
879function createCoreError(code) {
880 return createCompileError(code, null, { messages: errorMessages$1 } );
881}
882/** @internal */
883const errorMessages$1 = {
884 [CoreErrorCodes.INVALID_ARGUMENT]: 'Invalid arguments',
885 [CoreErrorCodes.INVALID_DATE_ARGUMENT]: 'The date provided is an invalid Date object.' +
886 'Make sure your Date represents a valid date.',
887 [CoreErrorCodes.INVALID_ISO_DATE_ARGUMENT]: 'The argument provided is not a valid ISO date string'
888};
889
890const NOOP_MESSAGE_FUNCTION = () => '';
891const isMessageFunction = (val) => isFunction(val);
892// implementation of `translate` function
893function translate(context, ...args) {
894 const { fallbackFormat, postTranslation, unresolving, fallbackLocale, messages } = context;
895 const [key, options] = parseTranslateArgs(...args);
896 const missingWarn = isBoolean(options.missingWarn)
897 ? options.missingWarn
898 : context.missingWarn;
899 const fallbackWarn = isBoolean(options.fallbackWarn)
900 ? options.fallbackWarn
901 : context.fallbackWarn;
902 const escapeParameter = isBoolean(options.escapeParameter)
903 ? options.escapeParameter
904 : context.escapeParameter;
905 const resolvedMessage = !!options.resolvedMessage;
906 // prettier-ignore
907 const defaultMsgOrKey = isString(options.default) || isBoolean(options.default) // default by function option
908 ? !isBoolean(options.default)
909 ? options.default
910 : key
911 : fallbackFormat // default by `fallbackFormat` option
912 ? key
913 : '';
914 const enableDefaultMsg = fallbackFormat || defaultMsgOrKey !== '';
915 const locale = isString(options.locale) ? options.locale : context.locale;
916 // escape params
917 escapeParameter && escapeParams(options);
918 // resolve message format
919 // eslint-disable-next-line prefer-const
920 let [format, targetLocale, message] = !resolvedMessage
921 ? resolveMessageFormat(context, key, locale, fallbackLocale, fallbackWarn, missingWarn)
922 : [
923 key,
924 locale,
925 messages[locale] || {}
926 ];
927 // if you use default message, set it as message format!
928 let cacheBaseKey = key;
929 if (!resolvedMessage &&
930 !(isString(format) || isMessageFunction(format))) {
931 if (enableDefaultMsg) {
932 format = defaultMsgOrKey;
933 cacheBaseKey = format;
934 }
935 }
936 // checking message format and target locale
937 if (!resolvedMessage &&
938 (!(isString(format) || isMessageFunction(format)) ||
939 !isString(targetLocale))) {
940 return unresolving ? NOT_REOSLVED : key;
941 }
942 if (isString(format) && context.messageCompiler == null) {
943 warn(`The message format compilation is not supported in this build. ` +
944 `Because message compiler isn't included. ` +
945 `You need to pre-compilation all message format. ` +
946 `So translate function return '${key}'.`);
947 return key;
948 }
949 // setup compile error detecting
950 let occurred = false;
951 const errorDetector = () => {
952 occurred = true;
953 };
954 // compile message format
955 const msg = !isMessageFunction(format)
956 ? compileMessageFormat(context, key, targetLocale, format, cacheBaseKey, errorDetector)
957 : format;
958 // if occurred compile error, return the message format
959 if (occurred) {
960 return format;
961 }
962 // evaluate message with context
963 const ctxOptions = getMessageContextOptions(context, targetLocale, message, options);
964 const msgContext = createMessageContext(ctxOptions);
965 const messaged = evaluateMessage(context, msg, msgContext);
966 // if use post translation option, proceed it with handler
967 const ret = postTranslation ? postTranslation(messaged) : messaged;
968 // NOTE: experimental !!
969 {
970 // prettier-ignore
971 const payloads = {
972 timestamp: Date.now(),
973 key: isString(key)
974 ? key
975 : isMessageFunction(format)
976 ? format.key
977 : '',
978 locale: targetLocale || (isMessageFunction(format)
979 ? format.locale
980 : ''),
981 format: isString(format)
982 ? format
983 : isMessageFunction(format)
984 ? format.source
985 : '',
986 message: ret
987 };
988 payloads.meta = assign({}, context.__meta, getAdditionalMeta() || {});
989 translateDevTools(payloads);
990 }
991 return ret;
992}
993function escapeParams(options) {
994 if (isArray(options.list)) {
995 options.list = options.list.map(item => isString(item) ? escapeHtml(item) : item);
996 }
997 else if (isObject(options.named)) {
998 Object.keys(options.named).forEach(key => {
999 if (isString(options.named[key])) {
1000 options.named[key] = escapeHtml(options.named[key]);
1001 }
1002 });
1003 }
1004}
1005function resolveMessageFormat(context, key, locale, fallbackLocale, fallbackWarn, missingWarn) {
1006 const { messages, onWarn, messageResolver: resolveValue, localeFallbacker } = context;
1007 const locales = localeFallbacker(context, fallbackLocale, locale); // eslint-disable-line @typescript-eslint/no-explicit-any
1008 let message = {};
1009 let targetLocale;
1010 let format = null;
1011 const type = 'translate';
1012 for (let i = 0; i < locales.length; i++) {
1013 targetLocale = locales[i];
1014 if (locale !== targetLocale &&
1015 isTranslateFallbackWarn(fallbackWarn, key)) {
1016 onWarn(getWarnMessage$1(CoreWarnCodes.FALLBACK_TO_TRANSLATE, {
1017 key,
1018 target: targetLocale
1019 }));
1020 }
1021 message =
1022 messages[targetLocale] || {};
1023 let startTag;
1024 if (inBrowser) {
1025 window.performance.now();
1026 startTag = 'intlify-message-resolve-start';
1027 mark && mark(startTag);
1028 }
1029 if ((format = resolveValue(message, key)) === null) {
1030 // if null, resolve with object key path
1031 format = message[key]; // eslint-disable-line @typescript-eslint/no-explicit-any
1032 }
1033 if (isString(format) || isFunction(format))
1034 break;
1035 const missingRet = handleMissing(context, // eslint-disable-line @typescript-eslint/no-explicit-any
1036 key, targetLocale, missingWarn, type);
1037 if (missingRet !== key) {
1038 format = missingRet;
1039 }
1040 }
1041 return [format, targetLocale, message];
1042}
1043function compileMessageFormat(context, key, targetLocale, format, cacheBaseKey, errorDetector) {
1044 const { messageCompiler, warnHtmlMessage } = context;
1045 if (isMessageFunction(format)) {
1046 const msg = format;
1047 msg.locale = msg.locale || targetLocale;
1048 msg.key = msg.key || key;
1049 return msg;
1050 }
1051 let startTag;
1052 if (inBrowser) {
1053 window.performance.now();
1054 startTag = 'intlify-message-compilation-start';
1055 mark && mark(startTag);
1056 }
1057 const msg = messageCompiler(format, getCompileOptions(context, targetLocale, cacheBaseKey, format, warnHtmlMessage, errorDetector));
1058 msg.locale = targetLocale;
1059 msg.key = key;
1060 msg.source = format;
1061 return msg;
1062}
1063function evaluateMessage(context, msg, msgCtx) {
1064 let startTag;
1065 if (inBrowser) {
1066 window.performance.now();
1067 startTag = 'intlify-message-evaluation-start';
1068 mark && mark(startTag);
1069 }
1070 const messaged = msg(msgCtx);
1071 return messaged;
1072}
1073/** @internal */
1074function parseTranslateArgs(...args) {
1075 const [arg1, arg2, arg3] = args;
1076 const options = {};
1077 if (!isString(arg1) && !isNumber(arg1) && !isMessageFunction(arg1)) {
1078 throw createCoreError(CoreErrorCodes.INVALID_ARGUMENT);
1079 }
1080 // prettier-ignore
1081 const key = isNumber(arg1)
1082 ? String(arg1)
1083 : isMessageFunction(arg1)
1084 ? arg1
1085 : arg1;
1086 if (isNumber(arg2)) {
1087 options.plural = arg2;
1088 }
1089 else if (isString(arg2)) {
1090 options.default = arg2;
1091 }
1092 else if (isPlainObject(arg2) && !isEmptyObject(arg2)) {
1093 options.named = arg2;
1094 }
1095 else if (isArray(arg2)) {
1096 options.list = arg2;
1097 }
1098 if (isNumber(arg3)) {
1099 options.plural = arg3;
1100 }
1101 else if (isString(arg3)) {
1102 options.default = arg3;
1103 }
1104 else if (isPlainObject(arg3)) {
1105 assign(options, arg3);
1106 }
1107 return [key, options];
1108}
1109function getCompileOptions(context, locale, key, source, warnHtmlMessage, errorDetector) {
1110 return {
1111 warnHtmlMessage,
1112 onError: (err) => {
1113 errorDetector && errorDetector(err);
1114 {
1115 throw err;
1116 }
1117 },
1118 onCacheKey: (source) => generateFormatCacheKey(locale, key, source)
1119 };
1120}
1121function getMessageContextOptions(context, locale, message, options) {
1122 const { modifiers, pluralRules, messageResolver: resolveValue } = context;
1123 const resolveMessage = (key) => {
1124 const val = resolveValue(message, key);
1125 if (isString(val)) {
1126 let occurred = false;
1127 const errorDetector = () => {
1128 occurred = true;
1129 };
1130 const msg = compileMessageFormat(context, key, locale, val, key, errorDetector);
1131 return !occurred
1132 ? msg
1133 : NOOP_MESSAGE_FUNCTION;
1134 }
1135 else if (isMessageFunction(val)) {
1136 return val;
1137 }
1138 else {
1139 // TODO: should be implemented warning message
1140 return NOOP_MESSAGE_FUNCTION;
1141 }
1142 };
1143 const ctxOptions = {
1144 locale,
1145 modifiers,
1146 pluralRules,
1147 messages: resolveMessage
1148 };
1149 if (context.processor) {
1150 ctxOptions.processor = context.processor;
1151 }
1152 if (options.list) {
1153 ctxOptions.list = options.list;
1154 }
1155 if (options.named) {
1156 ctxOptions.named = options.named;
1157 }
1158 if (isNumber(options.plural)) {
1159 ctxOptions.pluralIndex = options.plural;
1160 }
1161 return ctxOptions;
1162}
1163
1164const intlDefined = typeof Intl !== 'undefined';
1165const Availabilities = {
1166 dateTimeFormat: intlDefined && typeof Intl.DateTimeFormat !== 'undefined',
1167 numberFormat: intlDefined && typeof Intl.NumberFormat !== 'undefined'
1168};
1169
1170// implementation of `datetime` function
1171function datetime(context, ...args) {
1172 const { datetimeFormats, unresolving, fallbackLocale, onWarn, localeFallbacker } = context;
1173 const { __datetimeFormatters } = context;
1174 if (!Availabilities.dateTimeFormat) {
1175 onWarn(getWarnMessage$1(CoreWarnCodes.CANNOT_FORMAT_DATE));
1176 return MISSING_RESOLVE_VALUE;
1177 }
1178 const [key, value, options, overrides] = parseDateTimeArgs(...args);
1179 const missingWarn = isBoolean(options.missingWarn)
1180 ? options.missingWarn
1181 : context.missingWarn;
1182 const fallbackWarn = isBoolean(options.fallbackWarn)
1183 ? options.fallbackWarn
1184 : context.fallbackWarn;
1185 const part = !!options.part;
1186 const locale = isString(options.locale) ? options.locale : context.locale;
1187 const locales = localeFallbacker(context, // eslint-disable-line @typescript-eslint/no-explicit-any
1188 fallbackLocale, locale);
1189 if (!isString(key) || key === '') {
1190 return new Intl.DateTimeFormat(locale).format(value);
1191 }
1192 // resolve format
1193 let datetimeFormat = {};
1194 let targetLocale;
1195 let format = null;
1196 const type = 'datetime format';
1197 for (let i = 0; i < locales.length; i++) {
1198 targetLocale = locales[i];
1199 if (locale !== targetLocale &&
1200 isTranslateFallbackWarn(fallbackWarn, key)) {
1201 onWarn(getWarnMessage$1(CoreWarnCodes.FALLBACK_TO_DATE_FORMAT, {
1202 key,
1203 target: targetLocale
1204 }));
1205 }
1206 datetimeFormat =
1207 datetimeFormats[targetLocale] || {};
1208 format = datetimeFormat[key];
1209 if (isPlainObject(format))
1210 break;
1211 handleMissing(context, key, targetLocale, missingWarn, type); // eslint-disable-line @typescript-eslint/no-explicit-any
1212 }
1213 // checking format and target locale
1214 if (!isPlainObject(format) || !isString(targetLocale)) {
1215 return unresolving ? NOT_REOSLVED : key;
1216 }
1217 let id = `${targetLocale}__${key}`;
1218 if (!isEmptyObject(overrides)) {
1219 id = `${id}__${JSON.stringify(overrides)}`;
1220 }
1221 let formatter = __datetimeFormatters.get(id);
1222 if (!formatter) {
1223 formatter = new Intl.DateTimeFormat(targetLocale, assign({}, format, overrides));
1224 __datetimeFormatters.set(id, formatter);
1225 }
1226 return !part ? formatter.format(value) : formatter.formatToParts(value);
1227}
1228/** @internal */
1229function parseDateTimeArgs(...args) {
1230 const [arg1, arg2, arg3, arg4] = args;
1231 let options = {};
1232 let overrides = {};
1233 let value;
1234 if (isString(arg1)) {
1235 // Only allow ISO strings - other date formats are often supported,
1236 // but may cause different results in different browsers.
1237 const matches = arg1.match(/(\d{4}-\d{2}-\d{2})(T|\s)?(.*)/);
1238 if (!matches) {
1239 throw createCoreError(CoreErrorCodes.INVALID_ISO_DATE_ARGUMENT);
1240 }
1241 // Some browsers can not parse the iso datetime separated by space,
1242 // this is a compromise solution by replace the 'T'/' ' with 'T'
1243 const dateTime = matches[3]
1244 ? matches[3].trim().startsWith('T')
1245 ? `${matches[1].trim()}${matches[3].trim()}`
1246 : `${matches[1].trim()}T${matches[3].trim()}`
1247 : matches[1].trim();
1248 value = new Date(dateTime);
1249 try {
1250 // This will fail if the date is not valid
1251 value.toISOString();
1252 }
1253 catch (e) {
1254 throw createCoreError(CoreErrorCodes.INVALID_ISO_DATE_ARGUMENT);
1255 }
1256 }
1257 else if (isDate(arg1)) {
1258 if (isNaN(arg1.getTime())) {
1259 throw createCoreError(CoreErrorCodes.INVALID_DATE_ARGUMENT);
1260 }
1261 value = arg1;
1262 }
1263 else if (isNumber(arg1)) {
1264 value = arg1;
1265 }
1266 else {
1267 throw createCoreError(CoreErrorCodes.INVALID_ARGUMENT);
1268 }
1269 if (isString(arg2)) {
1270 options.key = arg2;
1271 }
1272 else if (isPlainObject(arg2)) {
1273 options = arg2;
1274 }
1275 if (isString(arg3)) {
1276 options.locale = arg3;
1277 }
1278 else if (isPlainObject(arg3)) {
1279 overrides = arg3;
1280 }
1281 if (isPlainObject(arg4)) {
1282 overrides = arg4;
1283 }
1284 return [options.key || '', value, options, overrides];
1285}
1286/** @internal */
1287function clearDateTimeFormat(ctx, locale, format) {
1288 const context = ctx;
1289 for (const key in format) {
1290 const id = `${locale}__${key}`;
1291 if (!context.__datetimeFormatters.has(id)) {
1292 continue;
1293 }
1294 context.__datetimeFormatters.delete(id);
1295 }
1296}
1297
1298// implementation of `number` function
1299function number(context, ...args) {
1300 const { numberFormats, unresolving, fallbackLocale, onWarn, localeFallbacker } = context;
1301 const { __numberFormatters } = context;
1302 if (!Availabilities.numberFormat) {
1303 onWarn(getWarnMessage$1(CoreWarnCodes.CANNOT_FORMAT_NUMBER));
1304 return MISSING_RESOLVE_VALUE;
1305 }
1306 const [key, value, options, overrides] = parseNumberArgs(...args);
1307 const missingWarn = isBoolean(options.missingWarn)
1308 ? options.missingWarn
1309 : context.missingWarn;
1310 const fallbackWarn = isBoolean(options.fallbackWarn)
1311 ? options.fallbackWarn
1312 : context.fallbackWarn;
1313 const part = !!options.part;
1314 const locale = isString(options.locale) ? options.locale : context.locale;
1315 const locales = localeFallbacker(context, // eslint-disable-line @typescript-eslint/no-explicit-any
1316 fallbackLocale, locale);
1317 if (!isString(key) || key === '') {
1318 return new Intl.NumberFormat(locale).format(value);
1319 }
1320 // resolve format
1321 let numberFormat = {};
1322 let targetLocale;
1323 let format = null;
1324 const type = 'number format';
1325 for (let i = 0; i < locales.length; i++) {
1326 targetLocale = locales[i];
1327 if (locale !== targetLocale &&
1328 isTranslateFallbackWarn(fallbackWarn, key)) {
1329 onWarn(getWarnMessage$1(CoreWarnCodes.FALLBACK_TO_NUMBER_FORMAT, {
1330 key,
1331 target: targetLocale
1332 }));
1333 }
1334 numberFormat =
1335 numberFormats[targetLocale] || {};
1336 format = numberFormat[key];
1337 if (isPlainObject(format))
1338 break;
1339 handleMissing(context, key, targetLocale, missingWarn, type); // eslint-disable-line @typescript-eslint/no-explicit-any
1340 }
1341 // checking format and target locale
1342 if (!isPlainObject(format) || !isString(targetLocale)) {
1343 return unresolving ? NOT_REOSLVED : key;
1344 }
1345 let id = `${targetLocale}__${key}`;
1346 if (!isEmptyObject(overrides)) {
1347 id = `${id}__${JSON.stringify(overrides)}`;
1348 }
1349 let formatter = __numberFormatters.get(id);
1350 if (!formatter) {
1351 formatter = new Intl.NumberFormat(targetLocale, assign({}, format, overrides));
1352 __numberFormatters.set(id, formatter);
1353 }
1354 return !part ? formatter.format(value) : formatter.formatToParts(value);
1355}
1356/** @internal */
1357function parseNumberArgs(...args) {
1358 const [arg1, arg2, arg3, arg4] = args;
1359 let options = {};
1360 let overrides = {};
1361 if (!isNumber(arg1)) {
1362 throw createCoreError(CoreErrorCodes.INVALID_ARGUMENT);
1363 }
1364 const value = arg1;
1365 if (isString(arg2)) {
1366 options.key = arg2;
1367 }
1368 else if (isPlainObject(arg2)) {
1369 options = arg2;
1370 }
1371 if (isString(arg3)) {
1372 options.locale = arg3;
1373 }
1374 else if (isPlainObject(arg3)) {
1375 overrides = arg3;
1376 }
1377 if (isPlainObject(arg4)) {
1378 overrides = arg4;
1379 }
1380 return [options.key || '', value, options, overrides];
1381}
1382/** @internal */
1383function clearNumberFormat(ctx, locale, format) {
1384 const context = ctx;
1385 for (const key in format) {
1386 const id = `${locale}__${key}`;
1387 if (!context.__numberFormatters.has(id)) {
1388 continue;
1389 }
1390 context.__numberFormatters.delete(id);
1391 }
1392}
1393
1394/**
1395 * Vue I18n Version
1396 *
1397 * @remarks
1398 * Semver format. Same format as the package.json `version` field.
1399 *
1400 * @VueI18nGeneral
1401 */
1402const VERSION = '9.2.0-beta.6';
1403/**
1404 * This is only called development env
1405 * istanbul-ignore-next
1406 */
1407function initDev() {
1408 {
1409 {
1410 console.info(`You are running a development build of vue-i18n.\n` +
1411 `Make sure to use the production build (*.prod.js) when deploying for production.`);
1412 }
1413 }
1414}
1415
1416let code$1 = CoreWarnCodes.__EXTEND_POINT__;
1417const inc$1 = () => code$1++;
1418const I18nWarnCodes = {
1419 FALLBACK_TO_ROOT: code$1,
1420 NOT_SUPPORTED_PRESERVE: inc$1(),
1421 NOT_SUPPORTED_FORMATTER: inc$1(),
1422 NOT_SUPPORTED_PRESERVE_DIRECTIVE: inc$1(),
1423 NOT_SUPPORTED_GET_CHOICE_INDEX: inc$1(),
1424 COMPONENT_NAME_LEGACY_COMPATIBLE: inc$1(),
1425 NOT_FOUND_PARENT_SCOPE: inc$1(),
1426 NOT_SUPPORT_MULTI_I18N_INSTANCE: inc$1() // 14
1427};
1428const warnMessages = {
1429 [I18nWarnCodes.FALLBACK_TO_ROOT]: `Fall back to {type} '{key}' with root locale.`,
1430 [I18nWarnCodes.NOT_SUPPORTED_PRESERVE]: `Not supported 'preserve'.`,
1431 [I18nWarnCodes.NOT_SUPPORTED_FORMATTER]: `Not supported 'formatter'.`,
1432 [I18nWarnCodes.NOT_SUPPORTED_PRESERVE_DIRECTIVE]: `Not supported 'preserveDirectiveContent'.`,
1433 [I18nWarnCodes.NOT_SUPPORTED_GET_CHOICE_INDEX]: `Not supported 'getChoiceIndex'.`,
1434 [I18nWarnCodes.COMPONENT_NAME_LEGACY_COMPATIBLE]: `Component name legacy compatible: '{name}' -> 'i18n'`,
1435 [I18nWarnCodes.NOT_FOUND_PARENT_SCOPE]: `Not found parent scope. use the global scope.`,
1436 [I18nWarnCodes.NOT_SUPPORT_MULTI_I18N_INSTANCE]: `Not support multi i18n instance.`
1437};
1438function getWarnMessage(code, ...args) {
1439 return format(warnMessages[code], ...args);
1440}
1441
1442let code = CompileErrorCodes.__EXTEND_POINT__;
1443const inc = () => code++;
1444const I18nErrorCodes = {
1445 // composer module errors
1446 UNEXPECTED_RETURN_TYPE: code,
1447 // legacy module errors
1448 INVALID_ARGUMENT: inc(),
1449 // i18n module errors
1450 MUST_BE_CALL_SETUP_TOP: inc(),
1451 NOT_INSLALLED: inc(),
1452 NOT_AVAILABLE_IN_LEGACY_MODE: inc(),
1453 // directive module errors
1454 REQUIRED_VALUE: inc(),
1455 INVALID_VALUE: inc(),
1456 // vue-devtools errors
1457 CANNOT_SETUP_VUE_DEVTOOLS_PLUGIN: inc(),
1458 NOT_INSLALLED_WITH_PROVIDE: inc(),
1459 // unexpected error
1460 UNEXPECTED_ERROR: inc(),
1461 // not compatible legacy vue-i18n constructor
1462 NOT_COMPATIBLE_LEGACY_VUE_I18N: inc(),
1463 // bridge support vue 2.x only
1464 BRIDGE_SUPPORT_VUE_2_ONLY: inc(),
1465 // for enhancement
1466 __EXTEND_POINT__: inc() // 27
1467};
1468function createI18nError(code, ...args) {
1469 return createCompileError(code, null, { messages: errorMessages, args } );
1470}
1471const errorMessages = {
1472 [I18nErrorCodes.UNEXPECTED_RETURN_TYPE]: 'Unexpected return type in composer',
1473 [I18nErrorCodes.INVALID_ARGUMENT]: 'Invalid argument',
1474 [I18nErrorCodes.MUST_BE_CALL_SETUP_TOP]: 'Must be called at the top of a `setup` function',
1475 [I18nErrorCodes.NOT_INSLALLED]: 'Need to install with `app.use` function',
1476 [I18nErrorCodes.UNEXPECTED_ERROR]: 'Unexpected error',
1477 [I18nErrorCodes.NOT_AVAILABLE_IN_LEGACY_MODE]: 'Not available in legacy mode',
1478 [I18nErrorCodes.REQUIRED_VALUE]: `Required in value: {0}`,
1479 [I18nErrorCodes.INVALID_VALUE]: `Invalid value`,
1480 [I18nErrorCodes.CANNOT_SETUP_VUE_DEVTOOLS_PLUGIN]: `Cannot setup vue-devtools plugin`,
1481 [I18nErrorCodes.NOT_INSLALLED_WITH_PROVIDE]: 'Need to install with `provide` function',
1482 [I18nErrorCodes.NOT_COMPATIBLE_LEGACY_VUE_I18N]: 'Not compatible legacy VueI18n.',
1483 [I18nErrorCodes.BRIDGE_SUPPORT_VUE_2_ONLY]: 'vue-i18n-bridge support Vue 2.x only'
1484};
1485
1486const SetPluralRulesSymbol = makeSymbol('__setPluralRules');
1487const LegacyInstanceSymbol = /* #__PURE__*/ makeSymbol('__legacyVueI18n');
1488
1489/* eslint-disable @typescript-eslint/no-explicit-any */
1490// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
1491function isLegacyVueI18n(VueI18n) {
1492 if (VueI18n == null || VueI18n.version == null) {
1493 return false;
1494 }
1495 return (Number(VueI18n.version.split('.')[0]) || -1) >= 8;
1496}
1497/**
1498 * Transform flat json in obj to normal json in obj
1499 */
1500function handleFlatJson(obj) {
1501 // check obj
1502 if (!isObject(obj)) {
1503 return obj;
1504 }
1505 for (const key in obj) {
1506 // check key
1507 if (!hasOwn(obj, key)) {
1508 continue;
1509 }
1510 // handle for normal json
1511 if (!key.includes('.')) {
1512 // recursive process value if value is also a object
1513 if (isObject(obj[key])) {
1514 handleFlatJson(obj[key]);
1515 }
1516 }
1517 // handle for flat json, transform to normal json
1518 else {
1519 // go to the last object
1520 const subKeys = key.split('.');
1521 const lastIndex = subKeys.length - 1;
1522 let currentObj = obj;
1523 for (let i = 0; i < lastIndex; i++) {
1524 if (!(subKeys[i] in currentObj)) {
1525 currentObj[subKeys[i]] = {};
1526 }
1527 currentObj = currentObj[subKeys[i]];
1528 }
1529 // update last object value, delete old property
1530 currentObj[subKeys[lastIndex]] = obj[key];
1531 delete obj[key];
1532 // recursive process value if value is also a object
1533 if (isObject(currentObj[subKeys[lastIndex]])) {
1534 handleFlatJson(currentObj[subKeys[lastIndex]]);
1535 }
1536 }
1537 }
1538 return obj;
1539}
1540function getLocaleMessages(locale, options) {
1541 const { messages, __i18n, messageResolver, flatJson } = options;
1542 // prettier-ignore
1543 const ret = isPlainObject(messages)
1544 ? messages
1545 : isArray(__i18n)
1546 ? {}
1547 : { [locale]: {} };
1548 // merge locale messages of i18n custom block
1549 if (isArray(__i18n)) {
1550 __i18n.forEach(({ locale, resource }) => {
1551 if (locale) {
1552 ret[locale] = ret[locale] || {};
1553 deepCopy(resource, ret[locale]);
1554 }
1555 else {
1556 deepCopy(resource, ret);
1557 }
1558 });
1559 }
1560 // handle messages for flat json
1561 if (messageResolver == null && flatJson) {
1562 for (const key in ret) {
1563 if (hasOwn(ret, key)) {
1564 handleFlatJson(ret[key]);
1565 }
1566 }
1567 }
1568 return ret;
1569}
1570const isNotObjectOrIsArray = (val) => !isObject(val) || isArray(val);
1571// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
1572function deepCopy(src, des) {
1573 // src and des should both be objects, and non of then can be a array
1574 if (isNotObjectOrIsArray(src) || isNotObjectOrIsArray(des)) {
1575 throw createI18nError(I18nErrorCodes.INVALID_VALUE);
1576 }
1577 for (const key in src) {
1578 if (hasOwn(src, key)) {
1579 if (isNotObjectOrIsArray(src[key]) || isNotObjectOrIsArray(des[key])) {
1580 // replace with src[key] when:
1581 // src[key] or des[key] is not a object, or
1582 // src[key] or des[key] is a array
1583 des[key] = src[key];
1584 }
1585 else {
1586 // src[key] and des[key] are both object, merge them
1587 deepCopy(src[key], des[key]);
1588 }
1589 }
1590 }
1591}
1592/* eslint-enable @typescript-eslint/no-explicit-any */
1593
1594/* eslint-disable @typescript-eslint/no-explicit-any */
1595const DEVTOOLS_META = '__INTLIFY_META__';
1596let composerID = 0;
1597function defineCoreMissingHandler(missing) {
1598 return ((ctx, locale, key, type) => {
1599 return missing(locale, key, getCurrentInstance() || undefined, type);
1600 });
1601}
1602// for Intlify DevTools
1603const getMetaInfo = () => {
1604 const instance = getCurrentInstance();
1605 return instance && instance.type[DEVTOOLS_META] // eslint-disable-line @typescript-eslint/no-explicit-any
1606 ? { [DEVTOOLS_META]: instance.type[DEVTOOLS_META] } // eslint-disable-line @typescript-eslint/no-explicit-any
1607 : null;
1608};
1609/**
1610 * Create composer interface factory
1611 *
1612 * @internal
1613 */
1614// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
1615function createComposer(options = {}, VueI18nLegacy) {
1616 const { __root } = options;
1617 const _isGlobal = __root === undefined;
1618 let _inheritLocale = isBoolean(options.inheritLocale)
1619 ? options.inheritLocale
1620 : true;
1621 const _locale = ref(
1622 // prettier-ignore
1623 __root && _inheritLocale
1624 ? __root.locale.value
1625 : isString(options.locale)
1626 ? options.locale
1627 : DEFAULT_LOCALE);
1628 const _fallbackLocale = ref(
1629 // prettier-ignore
1630 __root && _inheritLocale
1631 ? __root.fallbackLocale.value
1632 : isString(options.fallbackLocale) ||
1633 isArray(options.fallbackLocale) ||
1634 isPlainObject(options.fallbackLocale) ||
1635 options.fallbackLocale === false
1636 ? options.fallbackLocale
1637 : _locale.value);
1638 const _messages = ref(getLocaleMessages(_locale.value, options));
1639 // prettier-ignore
1640 const _datetimeFormats = ref(isPlainObject(options.datetimeFormats)
1641 ? options.datetimeFormats
1642 : { [_locale.value]: {} })
1643 ;
1644 // prettier-ignore
1645 const _numberFormats = ref(isPlainObject(options.numberFormats)
1646 ? options.numberFormats
1647 : { [_locale.value]: {} })
1648 ;
1649 // warning suppress options
1650 // prettier-ignore
1651 let _missingWarn = __root
1652 ? __root.missingWarn
1653 : isBoolean(options.missingWarn) || isRegExp(options.missingWarn)
1654 ? options.missingWarn
1655 : true;
1656 // prettier-ignore
1657 let _fallbackWarn = __root
1658 ? __root.fallbackWarn
1659 : isBoolean(options.fallbackWarn) || isRegExp(options.fallbackWarn)
1660 ? options.fallbackWarn
1661 : true;
1662 // prettier-ignore
1663 let _fallbackRoot = __root
1664 ? __root.fallbackRoot
1665 : isBoolean(options.fallbackRoot)
1666 ? options.fallbackRoot
1667 : true;
1668 // configure fall back to root
1669 let _fallbackFormat = !!options.fallbackFormat;
1670 // runtime missing
1671 let _missing = isFunction(options.missing) ? options.missing : null;
1672 let _runtimeMissing = isFunction(options.missing)
1673 ? defineCoreMissingHandler(options.missing)
1674 : null;
1675 // postTranslation handler
1676 let _postTranslation = isFunction(options.postTranslation)
1677 ? options.postTranslation
1678 : null;
1679 let _warnHtmlMessage = isBoolean(options.warnHtmlMessage)
1680 ? options.warnHtmlMessage
1681 : true;
1682 let _escapeParameter = !!options.escapeParameter;
1683 // custom linked modifiers
1684 // prettier-ignore
1685 const _modifiers = __root
1686 ? __root.modifiers
1687 : isPlainObject(options.modifiers)
1688 ? options.modifiers
1689 : {};
1690 // pluralRules
1691 let _pluralRules = options.pluralRules || (__root && __root.pluralRules);
1692 // for bridge
1693 let __legacy;
1694 {
1695 if (!isLegacyVueI18n(VueI18nLegacy)) {
1696 createI18nError(I18nErrorCodes.NOT_COMPATIBLE_LEGACY_VUE_I18N);
1697 }
1698 const legacyOptions = {
1699 locale: _locale.value,
1700 fallbackLocale: _fallbackLocale.value,
1701 messages: _messages.value,
1702 dateTimeFormats: _datetimeFormats.value,
1703 numberFormats: _numberFormats.value,
1704 modifiers: _modifiers,
1705 missing: _missing,
1706 fallbackRoot: _fallbackRoot,
1707 postTranslation: _postTranslation,
1708 pluralizationRules: _pluralRules,
1709 escapeParameterHtml: _escapeParameter,
1710 sync: _inheritLocale,
1711 silentFallbackWarn: isBoolean(_fallbackWarn)
1712 ? !_fallbackWarn
1713 : _fallbackWarn,
1714 silentTranslationWarn: isBoolean(_missingWarn)
1715 ? !_missingWarn
1716 : _missingWarn,
1717 formatFallbackMessages: isBoolean(_fallbackFormat)
1718 ? !_fallbackFormat
1719 : _fallbackFormat,
1720 warnHtmlInMessage: isBoolean(_warnHtmlMessage)
1721 ? _warnHtmlMessage
1722 ? 'warn'
1723 : 'off'
1724 : 'off'
1725 };
1726 __legacy = new VueI18nLegacy(legacyOptions);
1727 }
1728 // runtime context
1729 // eslint-disable-next-line prefer-const
1730 let _context;
1731 function getCoreContext() {
1732 const ctxOptions = {
1733 version: VERSION,
1734 locale: _locale.value,
1735 fallbackLocale: _fallbackLocale.value,
1736 messages: _messages.value,
1737 modifiers: _modifiers,
1738 pluralRules: _pluralRules,
1739 missing: _runtimeMissing === null ? undefined : _runtimeMissing,
1740 missingWarn: _missingWarn,
1741 fallbackWarn: _fallbackWarn,
1742 fallbackFormat: _fallbackFormat,
1743 unresolving: true,
1744 postTranslation: _postTranslation === null ? undefined : _postTranslation,
1745 warnHtmlMessage: _warnHtmlMessage,
1746 escapeParameter: _escapeParameter,
1747 messageResolver: options.messageResolver,
1748 __meta: { framework: 'vue' }
1749 };
1750 {
1751 ctxOptions.datetimeFormats = _datetimeFormats.value;
1752 ctxOptions.numberFormats = _numberFormats.value;
1753 ctxOptions.__datetimeFormatters = isPlainObject(_context)
1754 ? _context.__datetimeFormatters
1755 : undefined;
1756 ctxOptions.__numberFormatters = isPlainObject(_context)
1757 ? _context.__numberFormatters
1758 : undefined;
1759 }
1760 return createCoreContext(ctxOptions);
1761 }
1762 _context = getCoreContext();
1763 updateFallbackLocale(_context, _locale.value, _fallbackLocale.value);
1764 // track reactivity
1765 function trackReactivityValues() {
1766 return [
1767 _locale.value,
1768 _fallbackLocale.value,
1769 _messages.value,
1770 _datetimeFormats.value,
1771 _numberFormats.value
1772 ]
1773 ;
1774 }
1775 // locale
1776 const locale = computed({
1777 get: () => _locale.value,
1778 set: val => {
1779 _locale.value = val;
1780 {
1781 if (__legacy) {
1782 __legacy.locale = val;
1783 }
1784 }
1785 _context.locale = _locale.value;
1786 }
1787 });
1788 // fallbackLocale
1789 const fallbackLocale = computed({
1790 get: () => _fallbackLocale.value,
1791 set: val => {
1792 _fallbackLocale.value = val;
1793 {
1794 if (__legacy) {
1795 __legacy.fallbackLocale = val;
1796 }
1797 }
1798 _context.fallbackLocale = _fallbackLocale.value;
1799 updateFallbackLocale(_context, _locale.value, val);
1800 }
1801 });
1802 // messages
1803 const messages = computed(() => _messages.value);
1804 // datetimeFormats
1805 const datetimeFormats = /* #__PURE__*/ computed(() => _datetimeFormats.value);
1806 // numberFormats
1807 const numberFormats = /* #__PURE__*/ computed(() => _numberFormats.value);
1808 // getPostTranslationHandler
1809 function getPostTranslationHandler() {
1810 return isFunction(_postTranslation) ? _postTranslation : null;
1811 }
1812 // setPostTranslationHandler
1813 function setPostTranslationHandler(handler) {
1814 _postTranslation = handler;
1815 _context.postTranslation = handler;
1816 }
1817 // getMissingHandler
1818 function getMissingHandler() {
1819 return _missing;
1820 }
1821 // setMissingHandler
1822 function setMissingHandler(handler) {
1823 if (handler !== null) {
1824 _runtimeMissing = defineCoreMissingHandler(handler);
1825 }
1826 _missing = handler;
1827 _context.missing = _runtimeMissing;
1828 }
1829 function isResolvedTranslateMessage(type, arg // eslint-disable-line @typescript-eslint/no-explicit-any
1830 ) {
1831 return type !== 'translate' || !arg.resolvedMessage;
1832 }
1833 function wrapWithDeps(fn, argumentParser, warnType, fallbackSuccess, fallbackFail, successCondition) {
1834 trackReactivityValues(); // track reactive dependency
1835 // NOTE: experimental !!
1836 let ret;
1837 {
1838 try {
1839 setAdditionalMeta(getMetaInfo());
1840 ret = fn(_context);
1841 }
1842 finally {
1843 setAdditionalMeta(null);
1844 }
1845 }
1846 if (isNumber(ret) && ret === NOT_REOSLVED) {
1847 const [key, arg2] = argumentParser();
1848 if (__root &&
1849 isString(key) &&
1850 isResolvedTranslateMessage(warnType, arg2)) {
1851 if (_fallbackRoot &&
1852 (isTranslateFallbackWarn(_fallbackWarn, key) ||
1853 isTranslateMissingWarn(_missingWarn, key))) {
1854 warn(getWarnMessage(I18nWarnCodes.FALLBACK_TO_ROOT, {
1855 key,
1856 type: warnType
1857 }));
1858 }
1859 }
1860 return __root && _fallbackRoot
1861 ? fallbackSuccess(__root)
1862 : fallbackFail(key);
1863 }
1864 else if (successCondition(ret)) {
1865 return ret;
1866 }
1867 else {
1868 /* istanbul ignore next */
1869 throw createI18nError(I18nErrorCodes.UNEXPECTED_RETURN_TYPE);
1870 }
1871 }
1872 // t
1873 function t(...args) {
1874 return wrapWithDeps(context => Reflect.apply(translate, null, [context, ...args]), () => parseTranslateArgs(...args), 'translate', root => Reflect.apply(root.t, root, [...args]), key => key, val => isString(val));
1875 }
1876 // rt
1877 function rt(...args) {
1878 const [arg1, arg2, arg3] = args;
1879 if (arg3 && !isObject(arg3)) {
1880 throw createI18nError(I18nErrorCodes.INVALID_ARGUMENT);
1881 }
1882 return t(...[arg1, arg2, assign({ resolvedMessage: true }, arg3 || {})]);
1883 }
1884 // d
1885 function d(...args) {
1886 return wrapWithDeps(context => Reflect.apply(datetime, null, [context, ...args]), () => parseDateTimeArgs(...args), 'datetime format', root => Reflect.apply(root.d, root, [...args]), () => MISSING_RESOLVE_VALUE, val => isString(val));
1887 }
1888 // n
1889 function n(...args) {
1890 return wrapWithDeps(context => Reflect.apply(number, null, [context, ...args]), () => parseNumberArgs(...args), 'number format', root => Reflect.apply(root.n, root, [...args]), () => MISSING_RESOLVE_VALUE, val => isString(val));
1891 }
1892 function setPluralRules(rules) {
1893 _pluralRules = rules;
1894 _context.pluralRules = _pluralRules;
1895 }
1896 // te
1897 function te(key, locale) {
1898 const targetLocale = isString(locale) ? locale : _locale.value;
1899 const message = getLocaleMessage(targetLocale);
1900 return _context.messageResolver(message, key) !== null;
1901 }
1902 function resolveMessages(key) {
1903 let messages = null;
1904 const locales = fallbackWithLocaleChain(_context, _fallbackLocale.value, _locale.value);
1905 for (let i = 0; i < locales.length; i++) {
1906 const targetLocaleMessages = _messages.value[locales[i]] || {};
1907 const messageValue = _context.messageResolver(targetLocaleMessages, key);
1908 if (messageValue != null) {
1909 messages = messageValue;
1910 break;
1911 }
1912 }
1913 return messages;
1914 }
1915 // tm
1916 function tm(key) {
1917 const messages = resolveMessages(key);
1918 // prettier-ignore
1919 return messages != null
1920 ? messages
1921 : __root
1922 ? __root.tm(key) || {}
1923 : {};
1924 }
1925 // getLocaleMessage
1926 function getLocaleMessage(locale) {
1927 return (_messages.value[locale] || {});
1928 }
1929 // setLocaleMessage
1930 function setLocaleMessage(locale, message) {
1931 _messages.value[locale] = message;
1932 {
1933 __legacy && __legacy.setLocaleMessage(locale, message);
1934 }
1935 _context.messages = _messages.value;
1936 }
1937 // mergeLocaleMessage
1938 function mergeLocaleMessage(locale, message) {
1939 _messages.value[locale] = _messages.value[locale] || {};
1940 {
1941 __legacy && __legacy.mergeLocaleMessage(locale, message);
1942 }
1943 deepCopy(message, _messages.value[locale]);
1944 _context.messages = _messages.value;
1945 }
1946 // getDateTimeFormat
1947 function getDateTimeFormat(locale) {
1948 return _datetimeFormats.value[locale] || {};
1949 }
1950 // setDateTimeFormat
1951 function setDateTimeFormat(locale, format) {
1952 _datetimeFormats.value[locale] = format;
1953 {
1954 __legacy && __legacy.setDateTimeFormat(locale, format);
1955 }
1956 _context.datetimeFormats = _datetimeFormats.value;
1957 clearDateTimeFormat(_context, locale, format);
1958 }
1959 // mergeDateTimeFormat
1960 function mergeDateTimeFormat(locale, format) {
1961 _datetimeFormats.value[locale] = assign(_datetimeFormats.value[locale] || {}, format);
1962 {
1963 __legacy && __legacy.mergeDateTimeFormat(locale, format);
1964 }
1965 _context.datetimeFormats = _datetimeFormats.value;
1966 clearDateTimeFormat(_context, locale, format);
1967 }
1968 // getNumberFormat
1969 function getNumberFormat(locale) {
1970 return _numberFormats.value[locale] || {};
1971 }
1972 // setNumberFormat
1973 function setNumberFormat(locale, format) {
1974 _numberFormats.value[locale] = format;
1975 {
1976 __legacy && __legacy.setNumberFormat(locale, format);
1977 }
1978 _context.numberFormats = _numberFormats.value;
1979 clearNumberFormat(_context, locale, format);
1980 }
1981 // mergeNumberFormat
1982 function mergeNumberFormat(locale, format) {
1983 _numberFormats.value[locale] = assign(_numberFormats.value[locale] || {}, format);
1984 {
1985 __legacy && __legacy.mergeNumberFormat(locale, format);
1986 }
1987 _context.numberFormats = _numberFormats.value;
1988 clearNumberFormat(_context, locale, format);
1989 }
1990 // for debug
1991 composerID++;
1992 // watch root locale & fallbackLocale
1993 if (__root) {
1994 watch(__root.locale, (val) => {
1995 if (_inheritLocale) {
1996 _locale.value = val;
1997 {
1998 if (__legacy) {
1999 __legacy.locale = val;
2000 }
2001 }
2002 _context.locale = val;
2003 updateFallbackLocale(_context, _locale.value, _fallbackLocale.value);
2004 }
2005 });
2006 watch(__root.fallbackLocale, (val) => {
2007 if (_inheritLocale) {
2008 _fallbackLocale.value = val;
2009 {
2010 if (__legacy) {
2011 __legacy.fallbackLocale = val;
2012 }
2013 }
2014 _context.fallbackLocale = val;
2015 updateFallbackLocale(_context, _locale.value, _fallbackLocale.value);
2016 }
2017 });
2018 }
2019 // define basic composition API!
2020 const composer = {
2021 id: composerID,
2022 locale,
2023 fallbackLocale,
2024 get inheritLocale() {
2025 return _inheritLocale;
2026 },
2027 set inheritLocale(val) {
2028 _inheritLocale = val;
2029 {
2030 if (__legacy) {
2031 __legacy._sync = val;
2032 }
2033 }
2034 if (val && __root) {
2035 _locale.value = __root.locale.value;
2036 _fallbackLocale.value = __root.fallbackLocale.value;
2037 {
2038 if (__legacy) {
2039 __legacy.locale = __root.locale.value;
2040 __legacy.fallbackLocale = __root.fallbackLocale.value;
2041 }
2042 }
2043 updateFallbackLocale(_context, _locale.value, _fallbackLocale.value);
2044 }
2045 },
2046 get availableLocales() {
2047 return Object.keys(_messages.value).sort();
2048 },
2049 messages,
2050 get modifiers() {
2051 return _modifiers;
2052 },
2053 get pluralRules() {
2054 return _pluralRules || {};
2055 },
2056 get isGlobal() {
2057 return _isGlobal;
2058 },
2059 get missingWarn() {
2060 return _missingWarn;
2061 },
2062 set missingWarn(val) {
2063 _missingWarn = val;
2064 _context.missingWarn = _missingWarn;
2065 },
2066 get fallbackWarn() {
2067 return _fallbackWarn;
2068 },
2069 set fallbackWarn(val) {
2070 _fallbackWarn = val;
2071 _context.fallbackWarn = _fallbackWarn;
2072 },
2073 get fallbackRoot() {
2074 return _fallbackRoot;
2075 },
2076 set fallbackRoot(val) {
2077 _fallbackRoot = val;
2078 },
2079 get fallbackFormat() {
2080 return _fallbackFormat;
2081 },
2082 set fallbackFormat(val) {
2083 _fallbackFormat = val;
2084 _context.fallbackFormat = _fallbackFormat;
2085 },
2086 get warnHtmlMessage() {
2087 return _warnHtmlMessage;
2088 },
2089 set warnHtmlMessage(val) {
2090 _warnHtmlMessage = val;
2091 _context.warnHtmlMessage = val;
2092 },
2093 get escapeParameter() {
2094 return _escapeParameter;
2095 },
2096 set escapeParameter(val) {
2097 _escapeParameter = val;
2098 _context.escapeParameter = val;
2099 },
2100 t,
2101 getLocaleMessage,
2102 setLocaleMessage,
2103 mergeLocaleMessage,
2104 getPostTranslationHandler,
2105 setPostTranslationHandler,
2106 getMissingHandler,
2107 setMissingHandler,
2108 [SetPluralRulesSymbol]: setPluralRules
2109 };
2110 {
2111 composer.datetimeFormats = datetimeFormats;
2112 composer.numberFormats = numberFormats;
2113 composer.rt = rt;
2114 composer.te = te;
2115 composer.tm = tm;
2116 composer.d = d;
2117 composer.n = n;
2118 composer.getDateTimeFormat = getDateTimeFormat;
2119 composer.setDateTimeFormat = setDateTimeFormat;
2120 composer.mergeDateTimeFormat = mergeDateTimeFormat;
2121 composer.getNumberFormat = getNumberFormat;
2122 composer.setNumberFormat = setNumberFormat;
2123 composer.mergeNumberFormat = mergeNumberFormat;
2124 }
2125 {
2126 composer[LegacyInstanceSymbol] = __legacy;
2127 }
2128 return composer;
2129}
2130/* eslint-enable @typescript-eslint/no-explicit-any */
2131
2132/**
2133 * Port from vue-i18n@v8.x
2134 * This mixin is used when we use vue-i18n-bridge
2135 */
2136function defineMixin(i18n, VueI18n // eslint-disable-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
2137) {
2138 return {
2139 beforeCreate() {
2140 const options = this.$options; // eslint-disable-line @typescript-eslint/no-explicit-any
2141 if (options.__VUE18N__INSTANCE__) {
2142 return;
2143 }
2144 options.i18n = options.i18n || (options.__i18n ? {} : null);
2145 this._i18nBridgeRoot = i18n;
2146 if (i18n.mode === 'composition') {
2147 this._i18n = i18n;
2148 return;
2149 }
2150 if (options.i18n) {
2151 if (options.i18n instanceof VueI18n) {
2152 // init locale messages via custom blocks
2153 if (options.__i18n) {
2154 try {
2155 const localeMessages = options.i18n && options.i18n.messages
2156 ? options.i18n.messages
2157 : {};
2158 options.__i18n.forEach(resource => deepCopy(localeMessages, JSON.parse(resource)));
2159 Object.keys(localeMessages).forEach((locale) => {
2160 options.i18n.mergeLocaleMessage(locale, localeMessages[locale]);
2161 });
2162 }
2163 catch (e) {
2164 {
2165 console.error(`Cannot parse locale messages via custom blocks.`, e);
2166 }
2167 }
2168 }
2169 this._i18n = options.i18n;
2170 this._i18nWatcher = this._i18n.watchI18nData();
2171 }
2172 else if (isPlainObject(options.i18n)) {
2173 const rootI18n = this.$root &&
2174 this.$root.$i18n &&
2175 this.$root.$i18n instanceof VueI18n
2176 ? this.$root.$i18n
2177 : null;
2178 // component local i18n
2179 if (rootI18n) {
2180 options.i18n.root = this.$root;
2181 options.i18n.formatter = rootI18n.formatter;
2182 options.i18n.fallbackLocale = rootI18n.fallbackLocale;
2183 options.i18n.formatFallbackMessages =
2184 rootI18n.formatFallbackMessages;
2185 options.i18n.silentTranslationWarn = rootI18n.silentTranslationWarn;
2186 options.i18n.silentFallbackWarn = rootI18n.silentFallbackWarn;
2187 options.i18n.pluralizationRules = rootI18n.pluralizationRules;
2188 options.i18n.preserveDirectiveContent =
2189 rootI18n.preserveDirectiveContent;
2190 }
2191 // init locale messages via custom blocks
2192 if (options.__i18n) {
2193 try {
2194 const localeMessages = options.i18n && options.i18n.messages
2195 ? options.i18n.messages
2196 : {};
2197 options.__i18n.forEach(resource => deepCopy(localeMessages, JSON.parse(resource)));
2198 options.i18n.messages = localeMessages;
2199 }
2200 catch (e) {
2201 {
2202 warn(`Cannot parse locale messages via custom blocks.`, e);
2203 }
2204 }
2205 }
2206 const { sharedMessages } = options.i18n;
2207 if (sharedMessages && isPlainObject(sharedMessages)) {
2208 deepCopy(options.i18n.messages, sharedMessages);
2209 }
2210 this._i18n = new VueI18n(options.i18n);
2211 this._i18nWatcher = this._i18n.watchI18nData();
2212 if (options.i18n.sync === undefined || !!options.i18n.sync) {
2213 this._localeWatcher = this.$i18n.watchLocale();
2214 }
2215 if (rootI18n) {
2216 rootI18n.onComponentInstanceCreated(this._i18n);
2217 }
2218 }
2219 else {
2220 {
2221 warn(`Cannot be interpreted 'i18n' option.`);
2222 }
2223 }
2224 }
2225 else if (this.$root &&
2226 this.$root.$i18n &&
2227 this.$root.$i18n instanceof VueI18n) {
2228 // root i18n
2229 this._i18n = this.$root.$i18n;
2230 }
2231 else if (options.parent &&
2232 options.parent.$i18n &&
2233 options.parent.$i18n instanceof VueI18n) {
2234 // parent i18n
2235 this._i18n = options.parent.$i18n;
2236 }
2237 },
2238 beforeMount() {
2239 const options = this.$options; // eslint-disable-line @typescript-eslint/no-explicit-any
2240 if (options.__VUE18N__INSTANCE__) {
2241 return;
2242 }
2243 options.i18n = options.i18n || (options.__i18n ? {} : null);
2244 if (options.i18n) {
2245 if (options.i18n instanceof VueI18n) {
2246 // init locale messages via custom blocks
2247 this._i18n.subscribeDataChanging(this);
2248 this._subscribing = true;
2249 }
2250 else if (isPlainObject(options.i18n)) {
2251 this._i18n.subscribeDataChanging(this);
2252 this._subscribing = true;
2253 }
2254 else {
2255 {
2256 warn(`Cannot be interpreted 'i18n' option.`);
2257 }
2258 }
2259 }
2260 else if (this.$root &&
2261 this.$root.$i18n &&
2262 this.$root.$i18n instanceof VueI18n) {
2263 this._i18n.subscribeDataChanging(this);
2264 this._subscribing = true;
2265 }
2266 else if (options.parent &&
2267 options.parent.$i18n &&
2268 options.parent.$i18n instanceof VueI18n) {
2269 this._i18n.subscribeDataChanging(this);
2270 this._subscribing = true;
2271 }
2272 },
2273 beforeDestroy() {
2274 const options = this.$options; // eslint-disable-line @typescript-eslint/no-explicit-any
2275 if (options.__VUE18N__INSTANCE__) {
2276 return;
2277 }
2278 if (this._i18nBridgeRoot) {
2279 delete this._i18nBridgeRoot;
2280 return;
2281 }
2282 if (i18n.mode === 'composition') {
2283 delete this._i18n;
2284 return;
2285 }
2286 if (!this._i18n) {
2287 return;
2288 }
2289 const self = this; // eslint-disable-line @typescript-eslint/no-explicit-any
2290 this.$nextTick(() => {
2291 if (self._subscribing) {
2292 self._i18n.unsubscribeDataChanging(self);
2293 delete self._subscribing;
2294 }
2295 if (self._i18nWatcher) {
2296 self._i18nWatcher();
2297 self._i18n.destroyVM();
2298 delete self._i18nWatcher;
2299 }
2300 if (self._localeWatcher) {
2301 self._localeWatcher();
2302 delete self._localeWatcher;
2303 }
2304 });
2305 }
2306 };
2307}
2308
2309// for bridge
2310let _legacyVueI18n = null; // eslint-disable-line @typescript-eslint/no-explicit-any
2311let _legacyI18n = null; // eslint-disable-line @typescript-eslint/no-explicit-any
2312/**
2313 * Injection key for {@link useI18n}
2314 *
2315 * @remarks
2316 * The global injection key for I18n instances with `useI18n`. this injection key is used in Web Components.
2317 * Specify the i18n instance created by {@link createI18n} together with `provide` function.
2318 *
2319 * @VueI18nGeneral
2320 */
2321const I18nInjectionKey =
2322/* #__PURE__*/ makeSymbol('global-vue-i18n');
2323// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
2324function createI18n(options = {}, VueI18nLegacy) {
2325 if (_legacyI18n) {
2326 warn(getWarnMessage(I18nWarnCodes.NOT_SUPPORT_MULTI_I18N_INSTANCE));
2327 return _legacyI18n;
2328 }
2329 {
2330 _legacyVueI18n = VueI18nLegacy;
2331 }
2332 // prettier-ignore
2333 const __legacyMode = isBoolean(options.legacy)
2334 ? options.legacy
2335 : true;
2336 !!options.globalInjection;
2337 const __instances = new Map();
2338 const __global = createGlobal(options, __legacyMode, VueI18nLegacy);
2339 function __getInstance(component) {
2340 return __instances.get(component) || null;
2341 }
2342 function __setInstance(component, instance) {
2343 __instances.set(component, instance);
2344 }
2345 function __deleteInstance(component) {
2346 __instances.delete(component);
2347 }
2348 {
2349 // extend legacy VueI18n instance
2350 const i18n = __global[LegacyInstanceSymbol]; // eslint-disable-line @typescript-eslint/no-explicit-any
2351 Object.defineProperty(i18n, 'global', {
2352 get() {
2353 return __global;
2354 }
2355 });
2356 Object.defineProperty(i18n, 'mode', {
2357 get() {
2358 return __legacyMode ? 'legacy' : 'composition';
2359 }
2360 });
2361 Object.defineProperty(i18n, '__instances', {
2362 get() {
2363 return __instances;
2364 }
2365 });
2366 Object.defineProperty(i18n, 'install', {
2367 // eslint-disable-next-line @typescript-eslint/no-explicit-any
2368 value: (Vue) => {
2369 const version = (Vue && Vue.version && Number(Vue.version.split('.')[0])) || -1;
2370 if (version !== 2) {
2371 throw createI18nError(I18nErrorCodes.BRIDGE_SUPPORT_VUE_2_ONLY);
2372 }
2373 Vue.mixin(defineMixin(i18n, _legacyVueI18n));
2374 }
2375 });
2376 const methodMap = {
2377 __getInstance,
2378 __setInstance,
2379 __deleteInstance
2380 };
2381 Object.keys(methodMap).forEach(key => Object.defineProperty(i18n, key, { value: methodMap[key] }) // eslint-disable-line @typescript-eslint/no-explicit-any
2382 );
2383 _legacyI18n = i18n;
2384 return i18n;
2385 }
2386}
2387// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
2388function useI18n(options = {}) {
2389 const instance = getCurrentInstance();
2390 if (instance == null) {
2391 throw createI18nError(I18nErrorCodes.MUST_BE_CALL_SETUP_TOP);
2392 }
2393 {
2394 if (_legacyVueI18n == null || _legacyI18n == null) {
2395 throw createI18nError(I18nErrorCodes.NOT_INSLALLED);
2396 }
2397 }
2398 const i18n = getI18nInstance(instance);
2399 const global = getGlobalComposer(i18n);
2400 const componentOptions = getComponentOptions(instance);
2401 const scope = getScope(options, componentOptions);
2402 if (scope === 'global') {
2403 adjustI18nResources(global, options, componentOptions);
2404 return global;
2405 }
2406 if (scope === 'parent') {
2407 let composer = getComposer(i18n, instance);
2408 if (composer == null) {
2409 {
2410 warn(getWarnMessage(I18nWarnCodes.NOT_FOUND_PARENT_SCOPE));
2411 }
2412 composer = global;
2413 }
2414 return composer;
2415 }
2416 // scope 'local' case
2417 if (i18n.mode === 'legacy') {
2418 throw createI18nError(I18nErrorCodes.NOT_AVAILABLE_IN_LEGACY_MODE);
2419 }
2420 const i18nInternal = i18n;
2421 let composer = i18nInternal.__getInstance(instance);
2422 if (composer == null) {
2423 const composerOptions = assign({}, options);
2424 if ('__i18n' in componentOptions) {
2425 composerOptions.__i18n = componentOptions.__i18n;
2426 }
2427 if (global) {
2428 composerOptions.__root = global;
2429 }
2430 composer = createComposer(composerOptions, _legacyVueI18n);
2431 setupLifeCycle(i18nInternal, instance, composer);
2432 i18nInternal.__setInstance(instance, composer);
2433 }
2434 return composer;
2435}
2436function createGlobal(options, legacyMode, VueI18nLegacy // eslint-disable-line @typescript-eslint/no-explicit-any
2437) {
2438 {
2439 if (!isLegacyVueI18n(VueI18nLegacy)) {
2440 throw createI18nError(I18nErrorCodes.NOT_COMPATIBLE_LEGACY_VUE_I18N);
2441 }
2442 return createComposer(options, VueI18nLegacy);
2443 }
2444}
2445function getI18nInstance(instance) {
2446 {
2447 const vm = instance.proxy;
2448 /* istanbul ignore if */
2449 if (vm == null) {
2450 throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR);
2451 }
2452 const i18n = vm._i18nBridgeRoot; // eslint-disable-line @typescript-eslint/no-explicit-any
2453 /* istanbul ignore if */
2454 if (!i18n) {
2455 throw createI18nError(I18nErrorCodes.NOT_INSLALLED);
2456 }
2457 return i18n;
2458 }
2459}
2460// eslint-disable-next-line @typescript-eslint/no-explicit-any
2461function getComponentOptions(instance) {
2462 return instance.proxy.$options;
2463}
2464// eslint-disable-next-line @typescript-eslint/no-explicit-any
2465function getScope(options, componentOptions) {
2466 // prettier-ignore
2467 return isEmptyObject(options)
2468 ? ('__i18n' in componentOptions)
2469 ? 'local'
2470 : 'global'
2471 : !options.useScope
2472 ? 'local'
2473 : options.useScope;
2474}
2475function getGlobalComposer(i18n) {
2476 // prettier-ignore
2477 return i18n.global;
2478}
2479function adjustI18nResources(global, options, componentOptions // eslint-disable-line @typescript-eslint/no-explicit-any
2480) {
2481 let messages = isObject(options.messages) ? options.messages : {};
2482 if ('__i18nGlobal' in componentOptions) {
2483 messages = getLocaleMessages(global.locale.value, {
2484 messages,
2485 __i18n: componentOptions.__i18nGlobal
2486 });
2487 }
2488 // merge locale messages
2489 const locales = Object.keys(messages);
2490 if (locales.length) {
2491 locales.forEach(locale => {
2492 global.mergeLocaleMessage(locale, messages[locale]);
2493 });
2494 }
2495 {
2496 // merge datetime formats
2497 if (isObject(options.datetimeFormats)) {
2498 const locales = Object.keys(options.datetimeFormats);
2499 if (locales.length) {
2500 locales.forEach(locale => {
2501 global.mergeDateTimeFormat(locale, options.datetimeFormats[locale]);
2502 });
2503 }
2504 }
2505 // merge number formats
2506 if (isObject(options.numberFormats)) {
2507 const locales = Object.keys(options.numberFormats);
2508 if (locales.length) {
2509 locales.forEach(locale => {
2510 global.mergeNumberFormat(locale, options.numberFormats[locale]);
2511 });
2512 }
2513 }
2514 }
2515}
2516function getComposer(i18n, target) {
2517 let composer = null;
2518 const root = target.root;
2519 let current = target.parent;
2520 while (current != null) {
2521 const i18nInternal = i18n;
2522 if (i18n.mode === 'composition') {
2523 composer = i18nInternal.__getInstance(current);
2524 }
2525 else {
2526 {
2527 const vueI18n = i18nInternal.__getInstance(current);
2528 if (vueI18n != null) {
2529 composer = vueI18n
2530 .__composer;
2531 }
2532 }
2533 }
2534 if (composer != null) {
2535 break;
2536 }
2537 if (root === current) {
2538 break;
2539 }
2540 current = current.parent;
2541 }
2542 return composer;
2543}
2544function setupLifeCycle(i18n, target, composer) {
2545 {
2546 // assign legacy VueI18n instance to Vue2 instance
2547 // eslint-disable-next-line @typescript-eslint/no-explicit-any
2548 const vm = target.proxy;
2549 if (vm == null) {
2550 throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR);
2551 }
2552 // eslint-disable-next-line @typescript-eslint/no-explicit-any
2553 const _i18n = composer[LegacyInstanceSymbol];
2554 if (_i18n === i18n) {
2555 throw createI18nError(I18nErrorCodes.UNEXPECTED_ERROR);
2556 }
2557 vm._i18n = _i18n;
2558 vm._i18n_bridge = true;
2559 vm._i18nWatcher = vm._i18n.watchI18nData();
2560 if (vm._i18n._sync) {
2561 vm._localeWatcher = vm._i18n.watchLocale();
2562 }
2563 let subscribing = false;
2564 onBeforeMount(() => {
2565 vm._i18n.subscribeDataChanging(vm);
2566 subscribing = true;
2567 }, target);
2568 onUnmounted(() => {
2569 if (subscribing) {
2570 vm._i18n.unsubscribeDataChanging(vm);
2571 subscribing = false;
2572 }
2573 if (vm._i18nWatcher) {
2574 vm._i18nWatcher();
2575 vm._i18n.destroyVM();
2576 delete vm._i18nWatcher;
2577 }
2578 if (vm._localeWatcher) {
2579 vm._localeWatcher();
2580 delete vm._localeWatcher;
2581 }
2582 delete vm._i18n_bridge;
2583 delete vm._i18n;
2584 }, target);
2585 }
2586}
2587
2588// register message resolver at vue-i18n
2589registerMessageResolver(resolveValue);
2590// register fallback locale at vue-i18n
2591registerLocaleFallbacker(fallbackWithLocaleChain);
2592// NOTE: experimental !!
2593{
2594 const target = getGlobalThis();
2595 target.__INTLIFY__ = true;
2596 setDevToolsHook(target.__INTLIFY_DEVTOOLS_GLOBAL_HOOK__);
2597}
2598{
2599 initDev();
2600}
2601
2602export { I18nInjectionKey, VERSION, createI18n, useI18n };