@intlayer/core 8.9.4-canary.0 → 8.9.4
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/dictionaryManipulator/orderDictionaries.cjs +2 -2
- package/dist/cjs/dictionaryManipulator/orderDictionaries.cjs.map +1 -1
- package/dist/cjs/index.cjs +3 -0
- package/dist/cjs/messageFormat/ICU.cjs +47 -12
- package/dist/cjs/messageFormat/ICU.cjs.map +1 -1
- package/dist/cjs/messageFormat/i18next.cjs +49 -12
- package/dist/cjs/messageFormat/i18next.cjs.map +1 -1
- package/dist/cjs/messageFormat/index.cjs +3 -0
- package/dist/cjs/messageFormat/po.cjs +171 -0
- package/dist/cjs/messageFormat/po.cjs.map +1 -0
- package/dist/cjs/messageFormat/vue-i18n.cjs +23 -9
- package/dist/cjs/messageFormat/vue-i18n.cjs.map +1 -1
- package/dist/esm/dictionaryManipulator/orderDictionaries.mjs +2 -2
- package/dist/esm/dictionaryManipulator/orderDictionaries.mjs.map +1 -1
- package/dist/esm/index.mjs +2 -1
- package/dist/esm/messageFormat/ICU.mjs +47 -12
- package/dist/esm/messageFormat/ICU.mjs.map +1 -1
- package/dist/esm/messageFormat/i18next.mjs +49 -12
- package/dist/esm/messageFormat/i18next.mjs.map +1 -1
- package/dist/esm/messageFormat/index.mjs +2 -1
- package/dist/esm/messageFormat/po.mjs +167 -0
- package/dist/esm/messageFormat/po.mjs.map +1 -0
- package/dist/esm/messageFormat/vue-i18n.mjs +23 -9
- package/dist/esm/messageFormat/vue-i18n.mjs.map +1 -1
- package/dist/types/dictionaryManipulator/orderDictionaries.d.ts +5 -1
- package/dist/types/dictionaryManipulator/orderDictionaries.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/messageFormat/ICU.d.ts.map +1 -1
- package/dist/types/messageFormat/i18next.d.ts.map +1 -1
- package/dist/types/messageFormat/index.d.ts +2 -1
- package/dist/types/messageFormat/po.d.ts +15 -0
- package/dist/types/messageFormat/po.d.ts.map +1 -0
- package/dist/types/messageFormat/vue-i18n.d.ts.map +1 -1
- package/package.json +6 -6
|
@@ -3,6 +3,7 @@ import { enu as enumeration } from "../transpiler/enumeration/enumeration.mjs";
|
|
|
3
3
|
import { gender } from "../transpiler/gender/gender.mjs";
|
|
4
4
|
import { html } from "../transpiler/html/html.mjs";
|
|
5
5
|
import { insert as insertion } from "../transpiler/insertion/insertion.mjs";
|
|
6
|
+
import { plural } from "../transpiler/plural/plural.mjs";
|
|
6
7
|
import * as NodeTypes from "@intlayer/types/nodeType";
|
|
7
8
|
|
|
8
9
|
//#region src/messageFormat/i18next.ts
|
|
@@ -165,21 +166,34 @@ const i18nextNodesToIntlayer = (nodes) => {
|
|
|
165
166
|
}
|
|
166
167
|
if (node.type === "plural") {
|
|
167
168
|
const options = {};
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
169
|
+
let hasExactMatch = false;
|
|
170
|
+
for (const key of Object.keys(node.options)) if (key.startsWith("=")) {
|
|
171
|
+
hasExactMatch = true;
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
if (hasExactMatch) {
|
|
175
|
+
for (const [key, val] of Object.entries(node.options)) {
|
|
176
|
+
let newKey = key;
|
|
177
|
+
if (key.startsWith("=")) newKey = key.substring(1);
|
|
178
|
+
else if (key === "one") newKey = "1";
|
|
179
|
+
else if (key === "two") newKey = "2";
|
|
180
|
+
else if (key === "few") newKey = "<=3";
|
|
181
|
+
else if (key === "many") newKey = ">=4";
|
|
182
|
+
else if (key === "other") newKey = "fallback";
|
|
183
|
+
options[newKey] = i18nextNodesToIntlayer(val.map((v) => {
|
|
184
|
+
if (typeof v === "string") return v.replace(/#/g, `{{${node.name}}}`);
|
|
185
|
+
return v;
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
options.__intlayer_icu_var = node.name;
|
|
189
|
+
return enumeration(options);
|
|
190
|
+
} else {
|
|
191
|
+
for (const [key, val] of Object.entries(node.options)) options[key] = i18nextNodesToIntlayer(val.map((v) => {
|
|
177
192
|
if (typeof v === "string") return v.replace(/#/g, `{{${node.name}}}`);
|
|
178
193
|
return v;
|
|
179
194
|
}));
|
|
195
|
+
return plural(options);
|
|
180
196
|
}
|
|
181
|
-
options.__intlayer_icu_var = node.name;
|
|
182
|
-
return enumeration(options);
|
|
183
197
|
}
|
|
184
198
|
if (node.type === "select") {
|
|
185
199
|
const options = {};
|
|
@@ -214,7 +228,7 @@ const i18nextToIntlayerPlugin = {
|
|
|
214
228
|
const intlayerToI18nextPlugin = {
|
|
215
229
|
canHandle: (node) => {
|
|
216
230
|
if (typeof node === "string") return true;
|
|
217
|
-
if (node && typeof node === "object" && (node.nodeType === NodeTypes.INSERTION || node.nodeType === NodeTypes.HTML || node.nodeType === NodeTypes.ENUMERATION || node.nodeType === NodeTypes.GENDER || node.nodeType === "composite")) return true;
|
|
231
|
+
if (node && typeof node === "object" && (node.nodeType === NodeTypes.INSERTION || node.nodeType === NodeTypes.HTML || node.nodeType === NodeTypes.ENUMERATION || node.nodeType === NodeTypes.PLURAL || node.nodeType === NodeTypes.GENDER || node.nodeType === "composite")) return true;
|
|
218
232
|
if (Array.isArray(node)) {
|
|
219
233
|
if (node.length === 0) return false;
|
|
220
234
|
let hasNode = false;
|
|
@@ -234,6 +248,29 @@ const intlayerToI18nextPlugin = {
|
|
|
234
248
|
return node[NodeTypes.INSERTION];
|
|
235
249
|
}
|
|
236
250
|
if (node.nodeType === NodeTypes.HTML) return node[NodeTypes.HTML];
|
|
251
|
+
if (node.nodeType === NodeTypes.PLURAL) {
|
|
252
|
+
const options = node[NodeTypes.PLURAL];
|
|
253
|
+
const transformedOptions = {};
|
|
254
|
+
for (const [key, val] of Object.entries(options)) {
|
|
255
|
+
const childVal = next(val, props);
|
|
256
|
+
transformedOptions[key] = typeof childVal === "string" ? childVal : JSON.stringify(childVal);
|
|
257
|
+
}
|
|
258
|
+
let varName = "count";
|
|
259
|
+
const fallbackVal = transformedOptions.other || Object.values(transformedOptions)[0];
|
|
260
|
+
if (fallbackVal) {
|
|
261
|
+
const match = fallbackVal.match(/\{\{([a-zA-Z0-9_]+)\}\}/) || fallbackVal.match(/\{([a-zA-Z0-9_]+)\}(?!,)/);
|
|
262
|
+
if (match) varName = match[1];
|
|
263
|
+
}
|
|
264
|
+
const parts = [];
|
|
265
|
+
for (const [key, val] of Object.entries(transformedOptions)) {
|
|
266
|
+
const icuKey = key;
|
|
267
|
+
let strVal = val;
|
|
268
|
+
strVal = strVal.replace(/\{\{([^}]+)\}\}/g, "{$1}");
|
|
269
|
+
strVal = strVal.replace(new RegExp(`\\{${varName}\\}`, "g"), "#");
|
|
270
|
+
parts.push(`${icuKey} {${strVal}}`);
|
|
271
|
+
}
|
|
272
|
+
return `{${varName}, plural, ${parts.join(" ")}}`;
|
|
273
|
+
}
|
|
237
274
|
if (node.nodeType === NodeTypes.ENUMERATION) {
|
|
238
275
|
const options = node[NodeTypes.ENUMERATION];
|
|
239
276
|
const transformedOptions = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18next.mjs","names":["insert","enu"],"sources":["../../../src/messageFormat/i18next.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { deepTransformNode } from '../interpreter';\nimport { enu, gender, html, insert } from '../transpiler';\nimport type { JsonValue } from './ICU';\n\n// Types for our AST\ntype I18NextNode =\n | string\n | {\n type: 'argument';\n name: string;\n format?: { type: string; style?: string };\n }\n | { type: 'plural'; name: string; options: Record<string, I18NextNode[]> }\n | { type: 'select'; name: string; options: Record<string, I18NextNode[]> };\n\nconst parseI18Next = (text: string): I18NextNode[] => {\n let index = 0;\n\n const parseNodes = (): I18NextNode[] => {\n const nodes: I18NextNode[] = [];\n let currentText = '';\n\n while (index < text.length) {\n const char = text[index];\n\n // Standard i18next variable: {{var}}\n if (char === '{' && text[index + 1] === '{') {\n if (currentText) {\n nodes.push(currentText);\n currentText = '';\n }\n index += 2; // skip {{\n nodes.push(parseStandardArgument());\n }\n // ICU syntax: {var} or {var, plural, ...}\n else if (char === '{') {\n if (currentText) {\n nodes.push(currentText);\n currentText = '';\n }\n index++; // skip {\n nodes.push(parseICUArgument());\n } else if (char === '}') {\n // End of current block (likely ICU block end)\n break;\n } else {\n currentText += char;\n index++;\n }\n }\n\n if (currentText) {\n nodes.push(currentText);\n }\n return nodes;\n };\n\n const parseStandardArgument = (): I18NextNode => {\n // We are past '{{'\n let name = '';\n while (index < text.length) {\n // Check for closing }}\n if (text[index] === '}' && text[index + 1] === '}') {\n index += 2; // skip }}\n return { type: 'argument', name: name.trim() };\n }\n name += text[index];\n index++;\n }\n throw new Error('Unclosed i18next variable');\n };\n\n const parseICUArgument = (): I18NextNode => {\n // We are past '{'\n let name = '';\n while (index < text.length && /[^,}]/.test(text[index])) {\n name += text[index];\n index++;\n }\n name = name.trim();\n\n if (index >= text.length) throw new Error('Unclosed argument');\n\n if (text[index] === '}') {\n index++;\n return { type: 'argument', name };\n }\n\n // Must be comma\n if (text[index] === ',') {\n index++;\n // Parse type\n let type = '';\n while (index < text.length && /[^,}]/.test(text[index])) {\n type += text[index];\n index++;\n }\n type = type.trim();\n\n if (index >= text.length) throw new Error('Unclosed argument');\n\n if (text[index] === '}') {\n index++;\n return { type: 'argument', name, format: { type } };\n }\n\n if (text[index] === ',') {\n index++;\n\n // If plural or select, parse options\n if (type === 'plural' || type === 'select') {\n const options: Record<string, I18NextNode[]> = {};\n\n while (index < text.length && text[index] !== '}') {\n while (index < text.length && /\\s/.test(text[index])) index++;\n\n let key = '';\n while (index < text.length && /[^{\\s]/.test(text[index])) {\n key += text[index];\n index++;\n }\n\n while (index < text.length && /\\s/.test(text[index])) index++;\n\n if (text[index] !== '{')\n throw new Error('Expected { after option key');\n index++; // skip {\n\n const value = parseNodes();\n\n if (text[index] !== '}')\n throw new Error('Expected } after option value');\n index++; // skip }\n\n options[key] = value;\n\n while (index < text.length && /\\s/.test(text[index])) index++;\n }\n\n index++; // skip closing argument }\n\n if (type === 'plural') {\n return { type: 'plural', name, options };\n } else if (type === 'select') {\n return { type: 'select', name, options };\n }\n } else {\n // Parse style for number/date/time\n let style = '';\n while (index < text.length && text[index] !== '}') {\n style += text[index];\n index++;\n }\n if (index >= text.length) throw new Error('Unclosed argument');\n\n style = style.trim();\n index++; // skip }\n\n return { type: 'argument', name, format: { type, style } };\n }\n }\n }\n\n throw new Error('Malformed argument');\n };\n\n return parseNodes();\n};\n\nconst i18nextNodesToIntlayer = (nodes: I18NextNode[]): any => {\n if (nodes.length === 0) return '';\n if (nodes.length === 1 && typeof nodes[0] === 'string') {\n const node = nodes[0];\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(node)) {\n return html(node);\n }\n return node;\n }\n\n const canFlatten = nodes.every(\n (node) => typeof node === 'string' || node.type === 'argument'\n );\n\n if (canFlatten) {\n let str = '';\n for (const node of nodes) {\n if (typeof node === 'string') {\n str += node;\n } else if (typeof node !== 'string' && node.type === 'argument') {\n if (node.format) {\n // For formatted arguments, use ICU syntax: {name, type, style}\n str += `{${node.name}, ${node.format.type}${\n node.format.style ? `, ${node.format.style}` : ''\n }}`;\n } else {\n // For simple arguments, use standard i18next: {{name}}\n str += `{{${node.name}}}`;\n }\n }\n }\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(str)) {\n return html(str);\n }\n return insert(str);\n }\n\n if (nodes.length === 1) {\n const node = nodes[0];\n if (typeof node === 'string') {\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(node)) {\n return html(node);\n }\n return node;\n }\n\n if (node.type === 'argument') {\n if (node.format) {\n return insert(\n `{${node.name}, ${node.format.type}${\n node.format.style ? `, ${node.format.style}` : ''\n }}`\n );\n }\n return insert(`{{${node.name}}}`);\n }\n\n if (node.type === 'plural') {\n const options: Record<string, any> = {};\n for (const [key, val] of Object.entries(node.options)) {\n let newKey = key;\n if (key.startsWith('=')) {\n newKey = key.substring(1);\n } else if (key === 'one') {\n newKey = '1';\n } else if (key === 'two') {\n newKey = '2';\n } else if (key === 'few') {\n newKey = '<=3';\n } else if (key === 'many') {\n newKey = '>=4';\n } else if (key === 'other') {\n newKey = 'fallback';\n }\n // Handle # replacement\n const replacedVal = val.map((v) => {\n if (typeof v === 'string') {\n // In ICU plural, # is replaced by the number\n // In i18next, if using ICU plugin, it behaves same.\n // We map it to {{varName}} in Intlayer\n return v.replace(/#/g, `{{${node.name}}}`);\n }\n return v;\n });\n\n options[newKey] = i18nextNodesToIntlayer(replacedVal);\n }\n\n // Preserve variable name\n options.__intlayer_icu_var = node.name;\n\n return enu(options);\n }\n\n if (node.type === 'select') {\n const options: Record<string, any> = {};\n for (const [key, val] of Object.entries(node.options)) {\n options[key] = i18nextNodesToIntlayer(val);\n }\n\n // Check for gender\n const optionKeys = Object.keys(options);\n const isGender =\n (options.male || options.female) &&\n optionKeys.every((k) =>\n ['male', 'female', 'other', 'fallback'].includes(k)\n );\n\n if (isGender) {\n return gender({\n fallback: options.other,\n male: options.male,\n female: options.female,\n });\n }\n\n // Preserve variable name for generic select\n options.__intlayer_icu_var = node.name;\n\n return enu(options);\n }\n }\n\n return nodes.map((node) => i18nextNodesToIntlayer([node]));\n};\n\nconst i18nextToIntlayerPlugin = {\n canHandle: (node: any) =>\n typeof node === 'string' &&\n (node.includes('{') ||\n node.includes('}') ||\n /<[a-zA-Z0-9-]+[^>]*>/.test(node)),\n transform: (node: any) => {\n try {\n const ast = parseI18Next(node);\n return i18nextNodesToIntlayer(ast);\n } catch {\n return node;\n }\n },\n};\n\nconst intlayerToI18nextPlugin = {\n canHandle: (node: any) => {\n if (typeof node === 'string') return true;\n\n if (\n node &&\n typeof node === 'object' &&\n (node.nodeType === NodeTypes.INSERTION ||\n node.nodeType === NodeTypes.HTML ||\n node.nodeType === NodeTypes.ENUMERATION ||\n node.nodeType === NodeTypes.GENDER ||\n node.nodeType === 'composite')\n ) {\n return true;\n }\n\n if (Array.isArray(node)) {\n if (node.length === 0) return false;\n\n let hasNode = false;\n let hasPlainObjectOrArray = false;\n\n for (const item of node) {\n if (typeof item === 'string') {\n } else if (\n item &&\n typeof item === 'object' &&\n (item.nodeType === NodeTypes.INSERTION ||\n item.nodeType === NodeTypes.HTML ||\n item.nodeType === NodeTypes.ENUMERATION ||\n item.nodeType === NodeTypes.GENDER ||\n item.nodeType === 'composite')\n ) {\n hasNode = true;\n } else {\n hasPlainObjectOrArray = true;\n }\n }\n\n // If it contains plain objects or nested arrays, it's a structural array\n if (hasPlainObjectOrArray) return false;\n // If it contains ONLY strings, it's a structural array, not a composite string\n if (!hasNode) return false;\n\n return true;\n }\n\n return false;\n },\n transform: (node: any, props: any, next: any) => {\n if (typeof node === 'string') {\n return node;\n }\n\n if (node.nodeType === NodeTypes.INSERTION) {\n if (node[NodeTypes.INSERTION].match(/\\{[^}]*,[^}]*\\}/)) {\n return node[NodeTypes.INSERTION];\n }\n return node[NodeTypes.INSERTION];\n }\n\n if (node.nodeType === NodeTypes.HTML) {\n return node[NodeTypes.HTML];\n }\n\n if (node.nodeType === NodeTypes.ENUMERATION) {\n const options = node[NodeTypes.ENUMERATION];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n if (key === '__intlayer_icu_var') continue;\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n let varName = options.__intlayer_icu_var || 'count';\n\n if (!options.__intlayer_icu_var) {\n const fallbackVal =\n transformedOptions.fallback ||\n transformedOptions.other ||\n Object.values(transformedOptions)[0];\n\n const match =\n fallbackVal.match(/\\{\\{([a-zA-Z0-9_]+)\\}\\}/) ||\n fallbackVal.match(/\\{([a-zA-Z0-9_]+)\\}(?!,)/);\n if (match) {\n varName = match[1];\n }\n }\n\n const keys = Object.keys(transformedOptions);\n const pluralKeys = [\n '1',\n '2',\n '<=3',\n '>=4',\n 'fallback',\n 'other',\n 'zero',\n 'one',\n 'two',\n 'few',\n 'many',\n ];\n const isPlural = keys.every(\n (k) => pluralKeys.includes(k) || /^[<>=]?\\d+(\\.\\d+)?$/.test(k)\n );\n\n const parts = [];\n\n if (isPlural) {\n for (const [key, val] of Object.entries(transformedOptions)) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n else if (key === '<=3') icuKey = 'few';\n else if (key === '>=4') icuKey = 'many';\n else if (/^\\d+$/.test(key)) icuKey = `=${key}`;\n\n let strVal = val;\n\n strVal = strVal.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n strVal = strVal.replace(new RegExp(`\\\\{${varName}\\\\}`, 'g'), '#');\n\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, plural, ${parts.join(' ')}}`;\n } else {\n const entries = Object.entries(transformedOptions).sort(\n ([keyA], [keyB]) => {\n if (keyA === 'fallback' || keyA === 'other') return 1;\n if (keyB === 'fallback' || keyB === 'other') return -1;\n return 0;\n }\n );\n\n for (const [key, val] of entries) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n\n let strVal = val;\n strVal = strVal.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, select, ${parts.join(' ')}}`;\n }\n }\n\n if (node.nodeType === NodeTypes.GENDER) {\n const options = node[NodeTypes.GENDER];\n const varName = 'gender';\n const parts = [];\n\n const entries = Object.entries(options).sort(([keyA], [keyB]) => {\n if (keyA === 'fallback') return 1;\n if (keyB === 'fallback') return -1;\n return 0;\n });\n\n for (const [key, val] of entries) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n\n const childVal = next(val, props);\n let strVal =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n\n strVal = strVal.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, select, ${parts.join(' ')}}`;\n }\n\n if (\n Array.isArray(node) ||\n (node.nodeType === 'composite' && Array.isArray(node.composite))\n ) {\n const arr = Array.isArray(node) ? node : node.composite;\n const items = arr.map((item: any) => next(item, props));\n return items.join('');\n }\n\n return next(node, props);\n },\n};\n\nexport const intlayerToI18nextFormatter = (\n message: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(message, {\n dictionaryKey: 'i18next',\n keyPath: [],\n plugins: [{ id: 'i18next', ...intlayerToI18nextPlugin }],\n });\n};\n\nexport const i18nextToIntlayerFormatter = (\n message: JsonValue\n): Dictionary['content'] => {\n return deepTransformNode(message, {\n dictionaryKey: 'i18next',\n keyPath: [],\n plugins: [{ id: 'i18next', ...i18nextToIntlayerPlugin }],\n });\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"i18next.mjs","names":["insert","enu"],"sources":["../../../src/messageFormat/i18next.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { deepTransformNode } from '../interpreter';\nimport { enu, gender, html, insert, plural } from '../transpiler';\nimport type { JsonValue } from './ICU';\n\n// Types for our AST\ntype I18NextNode =\n | string\n | {\n type: 'argument';\n name: string;\n format?: { type: string; style?: string };\n }\n | { type: 'plural'; name: string; options: Record<string, I18NextNode[]> }\n | { type: 'select'; name: string; options: Record<string, I18NextNode[]> };\n\nconst parseI18Next = (text: string): I18NextNode[] => {\n let index = 0;\n\n const parseNodes = (): I18NextNode[] => {\n const nodes: I18NextNode[] = [];\n let currentText = '';\n\n while (index < text.length) {\n const char = text[index];\n\n // Standard i18next variable: {{var}}\n if (char === '{' && text[index + 1] === '{') {\n if (currentText) {\n nodes.push(currentText);\n currentText = '';\n }\n index += 2; // skip {{\n nodes.push(parseStandardArgument());\n }\n // ICU syntax: {var} or {var, plural, ...}\n else if (char === '{') {\n if (currentText) {\n nodes.push(currentText);\n currentText = '';\n }\n index++; // skip {\n nodes.push(parseICUArgument());\n } else if (char === '}') {\n // End of current block (likely ICU block end)\n break;\n } else {\n currentText += char;\n index++;\n }\n }\n\n if (currentText) {\n nodes.push(currentText);\n }\n return nodes;\n };\n\n const parseStandardArgument = (): I18NextNode => {\n // We are past '{{'\n let name = '';\n while (index < text.length) {\n // Check for closing }}\n if (text[index] === '}' && text[index + 1] === '}') {\n index += 2; // skip }}\n return { type: 'argument', name: name.trim() };\n }\n name += text[index];\n index++;\n }\n throw new Error('Unclosed i18next variable');\n };\n\n const parseICUArgument = (): I18NextNode => {\n // We are past '{'\n let name = '';\n while (index < text.length && /[^,}]/.test(text[index])) {\n name += text[index];\n index++;\n }\n name = name.trim();\n\n if (index >= text.length) throw new Error('Unclosed argument');\n\n if (text[index] === '}') {\n index++;\n return { type: 'argument', name };\n }\n\n // Must be comma\n if (text[index] === ',') {\n index++;\n // Parse type\n let type = '';\n while (index < text.length && /[^,}]/.test(text[index])) {\n type += text[index];\n index++;\n }\n type = type.trim();\n\n if (index >= text.length) throw new Error('Unclosed argument');\n\n if (text[index] === '}') {\n index++;\n return { type: 'argument', name, format: { type } };\n }\n\n if (text[index] === ',') {\n index++;\n\n // If plural or select, parse options\n if (type === 'plural' || type === 'select') {\n const options: Record<string, I18NextNode[]> = {};\n\n while (index < text.length && text[index] !== '}') {\n while (index < text.length && /\\s/.test(text[index])) index++;\n\n let key = '';\n while (index < text.length && /[^{\\s]/.test(text[index])) {\n key += text[index];\n index++;\n }\n\n while (index < text.length && /\\s/.test(text[index])) index++;\n\n if (text[index] !== '{')\n throw new Error('Expected { after option key');\n index++; // skip {\n\n const value = parseNodes();\n\n if (text[index] !== '}')\n throw new Error('Expected } after option value');\n index++; // skip }\n\n options[key] = value;\n\n while (index < text.length && /\\s/.test(text[index])) index++;\n }\n\n index++; // skip closing argument }\n\n if (type === 'plural') {\n return { type: 'plural', name, options };\n } else if (type === 'select') {\n return { type: 'select', name, options };\n }\n } else {\n // Parse style for number/date/time\n let style = '';\n while (index < text.length && text[index] !== '}') {\n style += text[index];\n index++;\n }\n if (index >= text.length) throw new Error('Unclosed argument');\n\n style = style.trim();\n index++; // skip }\n\n return { type: 'argument', name, format: { type, style } };\n }\n }\n }\n\n throw new Error('Malformed argument');\n };\n\n return parseNodes();\n};\n\nconst i18nextNodesToIntlayer = (nodes: I18NextNode[]): any => {\n if (nodes.length === 0) return '';\n if (nodes.length === 1 && typeof nodes[0] === 'string') {\n const node = nodes[0];\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(node)) {\n return html(node);\n }\n return node;\n }\n\n const canFlatten = nodes.every(\n (node) => typeof node === 'string' || node.type === 'argument'\n );\n\n if (canFlatten) {\n let str = '';\n for (const node of nodes) {\n if (typeof node === 'string') {\n str += node;\n } else if (typeof node !== 'string' && node.type === 'argument') {\n if (node.format) {\n // For formatted arguments, use ICU syntax: {name, type, style}\n str += `{${node.name}, ${node.format.type}${\n node.format.style ? `, ${node.format.style}` : ''\n }}`;\n } else {\n // For simple arguments, use standard i18next: {{name}}\n str += `{{${node.name}}}`;\n }\n }\n }\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(str)) {\n return html(str);\n }\n return insert(str);\n }\n\n if (nodes.length === 1) {\n const node = nodes[0];\n if (typeof node === 'string') {\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(node)) {\n return html(node);\n }\n return node;\n }\n\n if (node.type === 'argument') {\n if (node.format) {\n return insert(\n `{${node.name}, ${node.format.type}${\n node.format.style ? `, ${node.format.style}` : ''\n }}`\n );\n }\n return insert(`{{${node.name}}}`);\n }\n\n if (node.type === 'plural') {\n const options: Record<string, any> = {};\n let hasExactMatch = false;\n\n for (const key of Object.keys(node.options)) {\n if (key.startsWith('=')) {\n hasExactMatch = true;\n break;\n }\n }\n\n if (hasExactMatch) {\n for (const [key, val] of Object.entries(node.options)) {\n let newKey = key;\n if (key.startsWith('=')) {\n newKey = key.substring(1);\n } else if (key === 'one') {\n newKey = '1';\n } else if (key === 'two') {\n newKey = '2';\n } else if (key === 'few') {\n newKey = '<=3';\n } else if (key === 'many') {\n newKey = '>=4';\n } else if (key === 'other') {\n newKey = 'fallback';\n }\n // Handle # replacement\n const replacedVal = val.map((v) => {\n if (typeof v === 'string') {\n // In ICU plural, # is replaced by the number\n // In i18next, if using ICU plugin, it behaves same.\n // We map it to {{varName}} in Intlayer\n return v.replace(/#/g, `{{${node.name}}}`);\n }\n return v;\n });\n\n options[newKey] = i18nextNodesToIntlayer(replacedVal);\n }\n\n // Preserve variable name\n options.__intlayer_icu_var = node.name;\n\n return enu(options);\n } else {\n for (const [key, val] of Object.entries(node.options)) {\n // Handle # replacement\n const replacedVal = val.map((v) => {\n if (typeof v === 'string') {\n return v.replace(/#/g, `{{${node.name}}}`);\n }\n return v;\n });\n\n options[key] = i18nextNodesToIntlayer(replacedVal);\n }\n\n return plural(options as any);\n }\n }\n\n if (node.type === 'select') {\n const options: Record<string, any> = {};\n for (const [key, val] of Object.entries(node.options)) {\n options[key] = i18nextNodesToIntlayer(val);\n }\n\n // Check for gender\n const optionKeys = Object.keys(options);\n const isGender =\n (options.male || options.female) &&\n optionKeys.every((k) =>\n ['male', 'female', 'other', 'fallback'].includes(k)\n );\n\n if (isGender) {\n return gender({\n fallback: options.other,\n male: options.male,\n female: options.female,\n });\n }\n\n // Preserve variable name for generic select\n options.__intlayer_icu_var = node.name;\n\n return enu(options);\n }\n }\n\n return nodes.map((node) => i18nextNodesToIntlayer([node]));\n};\n\nconst i18nextToIntlayerPlugin = {\n canHandle: (node: any) =>\n typeof node === 'string' &&\n (node.includes('{') ||\n node.includes('}') ||\n /<[a-zA-Z0-9-]+[^>]*>/.test(node)),\n transform: (node: any) => {\n try {\n const ast = parseI18Next(node);\n return i18nextNodesToIntlayer(ast);\n } catch {\n return node;\n }\n },\n};\n\nconst intlayerToI18nextPlugin = {\n canHandle: (node: any) => {\n if (typeof node === 'string') return true;\n\n if (\n node &&\n typeof node === 'object' &&\n (node.nodeType === NodeTypes.INSERTION ||\n node.nodeType === NodeTypes.HTML ||\n node.nodeType === NodeTypes.ENUMERATION ||\n node.nodeType === NodeTypes.PLURAL ||\n node.nodeType === NodeTypes.GENDER ||\n node.nodeType === 'composite')\n ) {\n return true;\n }\n\n if (Array.isArray(node)) {\n if (node.length === 0) return false;\n\n let hasNode = false;\n let hasPlainObjectOrArray = false;\n\n for (const item of node) {\n if (typeof item === 'string') {\n } else if (\n item &&\n typeof item === 'object' &&\n (item.nodeType === NodeTypes.INSERTION ||\n item.nodeType === NodeTypes.HTML ||\n item.nodeType === NodeTypes.ENUMERATION ||\n item.nodeType === NodeTypes.GENDER ||\n item.nodeType === 'composite')\n ) {\n hasNode = true;\n } else {\n hasPlainObjectOrArray = true;\n }\n }\n\n // If it contains plain objects or nested arrays, it's a structural array\n if (hasPlainObjectOrArray) return false;\n // If it contains ONLY strings, it's a structural array, not a composite string\n if (!hasNode) return false;\n\n return true;\n }\n\n return false;\n },\n transform: (node: any, props: any, next: any) => {\n if (typeof node === 'string') {\n return node;\n }\n\n if (node.nodeType === NodeTypes.INSERTION) {\n if (node[NodeTypes.INSERTION].match(/\\{[^}]*,[^}]*\\}/)) {\n return node[NodeTypes.INSERTION];\n }\n return node[NodeTypes.INSERTION];\n }\n\n if (node.nodeType === NodeTypes.HTML) {\n return node[NodeTypes.HTML];\n }\n\n if (node.nodeType === NodeTypes.PLURAL) {\n const options = node[NodeTypes.PLURAL];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n let varName = 'count';\n\n const fallbackVal =\n transformedOptions.other || Object.values(transformedOptions)[0];\n\n if (fallbackVal) {\n const match =\n fallbackVal.match(/\\{\\{([a-zA-Z0-9_]+)\\}\\}/) ||\n fallbackVal.match(/\\{([a-zA-Z0-9_]+)\\}(?!,)/);\n if (match) {\n varName = match[1];\n }\n }\n\n const parts = [];\n\n for (const [key, val] of Object.entries(transformedOptions)) {\n const icuKey = key;\n let strVal = val;\n\n strVal = strVal.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n strVal = strVal.replace(new RegExp(`\\\\{${varName}\\\\}`, 'g'), '#');\n\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, plural, ${parts.join(' ')}}`;\n }\n\n if (node.nodeType === NodeTypes.ENUMERATION) {\n const options = node[NodeTypes.ENUMERATION];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n if (key === '__intlayer_icu_var') continue;\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n let varName = options.__intlayer_icu_var || 'count';\n\n if (!options.__intlayer_icu_var) {\n const fallbackVal =\n transformedOptions.fallback ||\n transformedOptions.other ||\n Object.values(transformedOptions)[0];\n\n const match =\n fallbackVal.match(/\\{\\{([a-zA-Z0-9_]+)\\}\\}/) ||\n fallbackVal.match(/\\{([a-zA-Z0-9_]+)\\}(?!,)/);\n if (match) {\n varName = match[1];\n }\n }\n\n const keys = Object.keys(transformedOptions);\n const pluralKeys = [\n '1',\n '2',\n '<=3',\n '>=4',\n 'fallback',\n 'other',\n 'zero',\n 'one',\n 'two',\n 'few',\n 'many',\n ];\n const isPlural = keys.every(\n (k) => pluralKeys.includes(k) || /^[<>=]?\\d+(\\.\\d+)?$/.test(k)\n );\n\n const parts = [];\n\n if (isPlural) {\n for (const [key, val] of Object.entries(transformedOptions)) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n else if (key === '<=3') icuKey = 'few';\n else if (key === '>=4') icuKey = 'many';\n else if (/^\\d+$/.test(key)) icuKey = `=${key}`;\n\n let strVal = val;\n\n strVal = strVal.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n strVal = strVal.replace(new RegExp(`\\\\{${varName}\\\\}`, 'g'), '#');\n\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, plural, ${parts.join(' ')}}`;\n } else {\n const entries = Object.entries(transformedOptions).sort(\n ([keyA], [keyB]) => {\n if (keyA === 'fallback' || keyA === 'other') return 1;\n if (keyB === 'fallback' || keyB === 'other') return -1;\n return 0;\n }\n );\n\n for (const [key, val] of entries) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n\n let strVal = val;\n strVal = strVal.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, select, ${parts.join(' ')}}`;\n }\n }\n\n if (node.nodeType === NodeTypes.GENDER) {\n const options = node[NodeTypes.GENDER];\n const varName = 'gender';\n const parts = [];\n\n const entries = Object.entries(options).sort(([keyA], [keyB]) => {\n if (keyA === 'fallback') return 1;\n if (keyB === 'fallback') return -1;\n return 0;\n });\n\n for (const [key, val] of entries) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n\n const childVal = next(val, props);\n let strVal =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n\n strVal = strVal.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, select, ${parts.join(' ')}}`;\n }\n\n if (\n Array.isArray(node) ||\n (node.nodeType === 'composite' && Array.isArray(node.composite))\n ) {\n const arr = Array.isArray(node) ? node : node.composite;\n const items = arr.map((item: any) => next(item, props));\n return items.join('');\n }\n\n return next(node, props);\n },\n};\n\nexport const intlayerToI18nextFormatter = (\n message: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(message, {\n dictionaryKey: 'i18next',\n keyPath: [],\n plugins: [{ id: 'i18next', ...intlayerToI18nextPlugin }],\n });\n};\n\nexport const i18nextToIntlayerFormatter = (\n message: JsonValue\n): Dictionary['content'] => {\n return deepTransformNode(message, {\n dictionaryKey: 'i18next',\n keyPath: [],\n plugins: [{ id: 'i18next', ...i18nextToIntlayerPlugin }],\n });\n};\n"],"mappings":";;;;;;;;;AAiBA,MAAM,gBAAgB,SAAgC;CACpD,IAAI,QAAQ;CAEZ,MAAM,mBAAkC;EACtC,MAAM,QAAuB,EAAE;EAC/B,IAAI,cAAc;EAElB,OAAO,QAAQ,KAAK,QAAQ;GAC1B,MAAM,OAAO,KAAK;GAGlB,IAAI,SAAS,OAAO,KAAK,QAAQ,OAAO,KAAK;IAC3C,IAAI,aAAa;KACf,MAAM,KAAK,YAAY;KACvB,cAAc;;IAEhB,SAAS;IACT,MAAM,KAAK,uBAAuB,CAAC;UAGhC,IAAI,SAAS,KAAK;IACrB,IAAI,aAAa;KACf,MAAM,KAAK,YAAY;KACvB,cAAc;;IAEhB;IACA,MAAM,KAAK,kBAAkB,CAAC;UACzB,IAAI,SAAS,KAElB;QACK;IACL,eAAe;IACf;;;EAIJ,IAAI,aACF,MAAM,KAAK,YAAY;EAEzB,OAAO;;CAGT,MAAM,8BAA2C;EAE/C,IAAI,OAAO;EACX,OAAO,QAAQ,KAAK,QAAQ;GAE1B,IAAI,KAAK,WAAW,OAAO,KAAK,QAAQ,OAAO,KAAK;IAClD,SAAS;IACT,OAAO;KAAE,MAAM;KAAY,MAAM,KAAK,MAAM;KAAE;;GAEhD,QAAQ,KAAK;GACb;;EAEF,MAAM,IAAI,MAAM,4BAA4B;;CAG9C,MAAM,yBAAsC;EAE1C,IAAI,OAAO;EACX,OAAO,QAAQ,KAAK,UAAU,QAAQ,KAAK,KAAK,OAAO,EAAE;GACvD,QAAQ,KAAK;GACb;;EAEF,OAAO,KAAK,MAAM;EAElB,IAAI,SAAS,KAAK,QAAQ,MAAM,IAAI,MAAM,oBAAoB;EAE9D,IAAI,KAAK,WAAW,KAAK;GACvB;GACA,OAAO;IAAE,MAAM;IAAY;IAAM;;EAInC,IAAI,KAAK,WAAW,KAAK;GACvB;GAEA,IAAI,OAAO;GACX,OAAO,QAAQ,KAAK,UAAU,QAAQ,KAAK,KAAK,OAAO,EAAE;IACvD,QAAQ,KAAK;IACb;;GAEF,OAAO,KAAK,MAAM;GAElB,IAAI,SAAS,KAAK,QAAQ,MAAM,IAAI,MAAM,oBAAoB;GAE9D,IAAI,KAAK,WAAW,KAAK;IACvB;IACA,OAAO;KAAE,MAAM;KAAY;KAAM,QAAQ,EAAE,MAAM;KAAE;;GAGrD,IAAI,KAAK,WAAW,KAAK;IACvB;IAGA,IAAI,SAAS,YAAY,SAAS,UAAU;KAC1C,MAAM,UAAyC,EAAE;KAEjD,OAAO,QAAQ,KAAK,UAAU,KAAK,WAAW,KAAK;MACjD,OAAO,QAAQ,KAAK,UAAU,KAAK,KAAK,KAAK,OAAO,EAAE;MAEtD,IAAI,MAAM;MACV,OAAO,QAAQ,KAAK,UAAU,SAAS,KAAK,KAAK,OAAO,EAAE;OACxD,OAAO,KAAK;OACZ;;MAGF,OAAO,QAAQ,KAAK,UAAU,KAAK,KAAK,KAAK,OAAO,EAAE;MAEtD,IAAI,KAAK,WAAW,KAClB,MAAM,IAAI,MAAM,8BAA8B;MAChD;MAEA,MAAM,QAAQ,YAAY;MAE1B,IAAI,KAAK,WAAW,KAClB,MAAM,IAAI,MAAM,gCAAgC;MAClD;MAEA,QAAQ,OAAO;MAEf,OAAO,QAAQ,KAAK,UAAU,KAAK,KAAK,KAAK,OAAO,EAAE;;KAGxD;KAEA,IAAI,SAAS,UACX,OAAO;MAAE,MAAM;MAAU;MAAM;MAAS;UACnC,IAAI,SAAS,UAClB,OAAO;MAAE,MAAM;MAAU;MAAM;MAAS;WAErC;KAEL,IAAI,QAAQ;KACZ,OAAO,QAAQ,KAAK,UAAU,KAAK,WAAW,KAAK;MACjD,SAAS,KAAK;MACd;;KAEF,IAAI,SAAS,KAAK,QAAQ,MAAM,IAAI,MAAM,oBAAoB;KAE9D,QAAQ,MAAM,MAAM;KACpB;KAEA,OAAO;MAAE,MAAM;MAAY;MAAM,QAAQ;OAAE;OAAM;OAAO;MAAE;;;;EAKhE,MAAM,IAAI,MAAM,qBAAqB;;CAGvC,OAAO,YAAY;;AAGrB,MAAM,0BAA0B,UAA8B;CAC5D,IAAI,MAAM,WAAW,GAAG,OAAO;CAC/B,IAAI,MAAM,WAAW,KAAK,OAAO,MAAM,OAAO,UAAU;EACtD,MAAM,OAAO,MAAM;EACnB,IAAI,uBAAuB,KAAK,KAAK,EACnC,OAAO,KAAK,KAAK;EAEnB,OAAO;;CAOT,IAJmB,MAAM,OACtB,SAAS,OAAO,SAAS,YAAY,KAAK,SAAS,WAGxC,EAAE;EACd,IAAI,MAAM;EACV,KAAK,MAAM,QAAQ,OACjB,IAAI,OAAO,SAAS,UAClB,OAAO;OACF,IAAI,OAAO,SAAS,YAAY,KAAK,SAAS,YACnD,IAAI,KAAK,QAEP,OAAO,IAAI,KAAK,KAAK,IAAI,KAAK,OAAO,OACnC,KAAK,OAAO,QAAQ,KAAK,KAAK,OAAO,UAAU,GAChD;OAGD,OAAO,KAAK,KAAK,KAAK;EAI5B,IAAI,uBAAuB,KAAK,IAAI,EAClC,OAAO,KAAK,IAAI;EAElB,OAAOA,UAAO,IAAI;;CAGpB,IAAI,MAAM,WAAW,GAAG;EACtB,MAAM,OAAO,MAAM;EACnB,IAAI,OAAO,SAAS,UAAU;GAC5B,IAAI,uBAAuB,KAAK,KAAK,EACnC,OAAO,KAAK,KAAK;GAEnB,OAAO;;EAGT,IAAI,KAAK,SAAS,YAAY;GAC5B,IAAI,KAAK,QACP,OAAOA,UACL,IAAI,KAAK,KAAK,IAAI,KAAK,OAAO,OAC5B,KAAK,OAAO,QAAQ,KAAK,KAAK,OAAO,UAAU,GAChD,GACF;GAEH,OAAOA,UAAO,KAAK,KAAK,KAAK,IAAI;;EAGnC,IAAI,KAAK,SAAS,UAAU;GAC1B,MAAM,UAA+B,EAAE;GACvC,IAAI,gBAAgB;GAEpB,KAAK,MAAM,OAAO,OAAO,KAAK,KAAK,QAAQ,EACzC,IAAI,IAAI,WAAW,IAAI,EAAE;IACvB,gBAAgB;IAChB;;GAIJ,IAAI,eAAe;IACjB,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,KAAK,QAAQ,EAAE;KACrD,IAAI,SAAS;KACb,IAAI,IAAI,WAAW,IAAI,EACrB,SAAS,IAAI,UAAU,EAAE;UACpB,IAAI,QAAQ,OACjB,SAAS;UACJ,IAAI,QAAQ,OACjB,SAAS;UACJ,IAAI,QAAQ,OACjB,SAAS;UACJ,IAAI,QAAQ,QACjB,SAAS;UACJ,IAAI,QAAQ,SACjB,SAAS;KAaX,QAAQ,UAAU,uBAVE,IAAI,KAAK,MAAM;MACjC,IAAI,OAAO,MAAM,UAIf,OAAO,EAAE,QAAQ,MAAM,KAAK,KAAK,KAAK,IAAI;MAE5C,OAAO;OAG2C,CAAC;;IAIvD,QAAQ,qBAAqB,KAAK;IAElC,OAAOC,YAAI,QAAQ;UACd;IACL,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,KAAK,QAAQ,EASnD,QAAQ,OAAO,uBAPK,IAAI,KAAK,MAAM;KACjC,IAAI,OAAO,MAAM,UACf,OAAO,EAAE,QAAQ,MAAM,KAAK,KAAK,KAAK,IAAI;KAE5C,OAAO;MAGwC,CAAC;IAGpD,OAAO,OAAO,QAAe;;;EAIjC,IAAI,KAAK,SAAS,UAAU;GAC1B,MAAM,UAA+B,EAAE;GACvC,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,KAAK,QAAQ,EACnD,QAAQ,OAAO,uBAAuB,IAAI;GAI5C,MAAM,aAAa,OAAO,KAAK,QAAQ;GAOvC,KALG,QAAQ,QAAQ,QAAQ,WACzB,WAAW,OAAO,MAChB;IAAC;IAAQ;IAAU;IAAS;IAAW,CAAC,SAAS,EAAE,CACpD,EAGD,OAAO,OAAO;IACZ,UAAU,QAAQ;IAClB,MAAM,QAAQ;IACd,QAAQ,QAAQ;IACjB,CAAC;GAIJ,QAAQ,qBAAqB,KAAK;GAElC,OAAOA,YAAI,QAAQ;;;CAIvB,OAAO,MAAM,KAAK,SAAS,uBAAuB,CAAC,KAAK,CAAC,CAAC;;AAG5D,MAAM,0BAA0B;CAC9B,YAAY,SACV,OAAO,SAAS,aACf,KAAK,SAAS,IAAI,IACjB,KAAK,SAAS,IAAI,IAClB,uBAAuB,KAAK,KAAK;CACrC,YAAY,SAAc;EACxB,IAAI;GAEF,OAAO,uBADK,aAAa,KACQ,CAAC;UAC5B;GACN,OAAO;;;CAGZ;AAED,MAAM,0BAA0B;CAC9B,YAAY,SAAc;EACxB,IAAI,OAAO,SAAS,UAAU,OAAO;EAErC,IACE,QACA,OAAO,SAAS,aACf,KAAK,aAAa,UAAU,aAC3B,KAAK,aAAa,UAAU,QAC5B,KAAK,aAAa,UAAU,eAC5B,KAAK,aAAa,UAAU,UAC5B,KAAK,aAAa,UAAU,UAC5B,KAAK,aAAa,cAEpB,OAAO;EAGT,IAAI,MAAM,QAAQ,KAAK,EAAE;GACvB,IAAI,KAAK,WAAW,GAAG,OAAO;GAE9B,IAAI,UAAU;GACd,IAAI,wBAAwB;GAE5B,KAAK,MAAM,QAAQ,MACjB,IAAI,OAAO,SAAS,UAAU,QACvB,IACL,QACA,OAAO,SAAS,aACf,KAAK,aAAa,UAAU,aAC3B,KAAK,aAAa,UAAU,QAC5B,KAAK,aAAa,UAAU,eAC5B,KAAK,aAAa,UAAU,UAC5B,KAAK,aAAa,cAEpB,UAAU;QAEV,wBAAwB;GAK5B,IAAI,uBAAuB,OAAO;GAElC,IAAI,CAAC,SAAS,OAAO;GAErB,OAAO;;EAGT,OAAO;;CAET,YAAY,MAAW,OAAY,SAAc;EAC/C,IAAI,OAAO,SAAS,UAClB,OAAO;EAGT,IAAI,KAAK,aAAa,UAAU,WAAW;GACzC,IAAI,KAAK,UAAU,WAAW,MAAM,kBAAkB,EACpD,OAAO,KAAK,UAAU;GAExB,OAAO,KAAK,UAAU;;EAGxB,IAAI,KAAK,aAAa,UAAU,MAC9B,OAAO,KAAK,UAAU;EAGxB,IAAI,KAAK,aAAa,UAAU,QAAQ;GACtC,MAAM,UAAU,KAAK,UAAU;GAE/B,MAAM,qBAA6C,EAAE;GACrD,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,QAAQ,EAAE;IAChD,MAAM,WAAW,KAAK,KAAK,MAAM;IACjC,mBAAmB,OACjB,OAAO,aAAa,WAAW,WAAW,KAAK,UAAU,SAAS;;GAGtE,IAAI,UAAU;GAEd,MAAM,cACJ,mBAAmB,SAAS,OAAO,OAAO,mBAAmB,CAAC;GAEhE,IAAI,aAAa;IACf,MAAM,QACJ,YAAY,MAAM,0BAA0B,IAC5C,YAAY,MAAM,2BAA2B;IAC/C,IAAI,OACF,UAAU,MAAM;;GAIpB,MAAM,QAAQ,EAAE;GAEhB,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,mBAAmB,EAAE;IAC3D,MAAM,SAAS;IACf,IAAI,SAAS;IAEb,SAAS,OAAO,QAAQ,oBAAoB,OAAO;IACnD,SAAS,OAAO,QAAQ,IAAI,OAAO,MAAM,QAAQ,MAAM,IAAI,EAAE,IAAI;IAEjE,MAAM,KAAK,GAAG,OAAO,IAAI,OAAO,GAAG;;GAErC,OAAO,IAAI,QAAQ,YAAY,MAAM,KAAK,IAAI,CAAC;;EAGjD,IAAI,KAAK,aAAa,UAAU,aAAa;GAC3C,MAAM,UAAU,KAAK,UAAU;GAE/B,MAAM,qBAA6C,EAAE;GACrD,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,QAAQ,EAAE;IAChD,IAAI,QAAQ,sBAAsB;IAClC,MAAM,WAAW,KAAK,KAAK,MAAM;IACjC,mBAAmB,OACjB,OAAO,aAAa,WAAW,WAAW,KAAK,UAAU,SAAS;;GAGtE,IAAI,UAAU,QAAQ,sBAAsB;GAE5C,IAAI,CAAC,QAAQ,oBAAoB;IAC/B,MAAM,cACJ,mBAAmB,YACnB,mBAAmB,SACnB,OAAO,OAAO,mBAAmB,CAAC;IAEpC,MAAM,QACJ,YAAY,MAAM,0BAA0B,IAC5C,YAAY,MAAM,2BAA2B;IAC/C,IAAI,OACF,UAAU,MAAM;;GAIpB,MAAM,OAAO,OAAO,KAAK,mBAAmB;GAC5C,MAAM,aAAa;IACjB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACD;GACD,MAAM,WAAW,KAAK,OACnB,MAAM,WAAW,SAAS,EAAE,IAAI,sBAAsB,KAAK,EAAE,CAC/D;GAED,MAAM,QAAQ,EAAE;GAEhB,IAAI,UAAU;IACZ,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,mBAAmB,EAAE;KAC3D,IAAI,SAAS;KACb,IAAI,QAAQ,YAAY,SAAS;UAC5B,IAAI,QAAQ,OAAO,SAAS;UAC5B,IAAI,QAAQ,OAAO,SAAS;UAC5B,IAAI,QAAQ,KAAK,IAAI,EAAE,SAAS,IAAI;KAEzC,IAAI,SAAS;KAEb,SAAS,OAAO,QAAQ,oBAAoB,OAAO;KACnD,SAAS,OAAO,QAAQ,IAAI,OAAO,MAAM,QAAQ,MAAM,IAAI,EAAE,IAAI;KAEjE,MAAM,KAAK,GAAG,OAAO,IAAI,OAAO,GAAG;;IAErC,OAAO,IAAI,QAAQ,YAAY,MAAM,KAAK,IAAI,CAAC;UAC1C;IACL,MAAM,UAAU,OAAO,QAAQ,mBAAmB,CAAC,MAChD,CAAC,OAAO,CAAC,UAAU;KAClB,IAAI,SAAS,cAAc,SAAS,SAAS,OAAO;KACpD,IAAI,SAAS,cAAc,SAAS,SAAS,OAAO;KACpD,OAAO;MAEV;IAED,KAAK,MAAM,CAAC,KAAK,QAAQ,SAAS;KAChC,IAAI,SAAS;KACb,IAAI,QAAQ,YAAY,SAAS;KAEjC,IAAI,SAAS;KACb,SAAS,OAAO,QAAQ,oBAAoB,OAAO;KAEnD,MAAM,KAAK,GAAG,OAAO,IAAI,OAAO,GAAG;;IAErC,OAAO,IAAI,QAAQ,YAAY,MAAM,KAAK,IAAI,CAAC;;;EAInD,IAAI,KAAK,aAAa,UAAU,QAAQ;GACtC,MAAM,UAAU,KAAK,UAAU;GAC/B,MAAM,UAAU;GAChB,MAAM,QAAQ,EAAE;GAEhB,MAAM,UAAU,OAAO,QAAQ,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU;IAC/D,IAAI,SAAS,YAAY,OAAO;IAChC,IAAI,SAAS,YAAY,OAAO;IAChC,OAAO;KACP;GAEF,KAAK,MAAM,CAAC,KAAK,QAAQ,SAAS;IAChC,IAAI,SAAS;IACb,IAAI,QAAQ,YAAY,SAAS;IAEjC,MAAM,WAAW,KAAK,KAAK,MAAM;IACjC,IAAI,SACF,OAAO,aAAa,WAAW,WAAW,KAAK,UAAU,SAAS;IAEpE,SAAS,OAAO,QAAQ,oBAAoB,OAAO;IACnD,MAAM,KAAK,GAAG,OAAO,IAAI,OAAO,GAAG;;GAErC,OAAO,IAAI,QAAQ,YAAY,MAAM,KAAK,IAAI,CAAC;;EAGjD,IACE,MAAM,QAAQ,KAAK,IAClB,KAAK,aAAa,eAAe,MAAM,QAAQ,KAAK,UAAU,EAI/D,QAFY,MAAM,QAAQ,KAAK,GAAG,OAAO,KAAK,WAC5B,KAAK,SAAc,KAAK,MAAM,MAAM,CAC1C,CAAC,KAAK,GAAG;EAGvB,OAAO,KAAK,MAAM,MAAM;;CAE3B;AAED,MAAa,8BACX,YACc;CACd,OAAO,kBAAkB,SAAS;EAChC,eAAe;EACf,SAAS,EAAE;EACX,SAAS,CAAC;GAAE,IAAI;GAAW,GAAG;GAAyB,CAAC;EACzD,CAAC;;AAGJ,MAAa,8BACX,YAC0B;CAC1B,OAAO,kBAAkB,SAAS;EAChC,eAAe;EACf,SAAS,EAAE;EACX,SAAS,CAAC;GAAE,IAAI;GAAW,GAAG;GAAyB,CAAC;EACzD,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { icuToIntlayerFormatter, intlayerToICUFormatter } from "./ICU.mjs";
|
|
2
2
|
import { i18nextToIntlayerFormatter, intlayerToI18nextFormatter } from "./i18next.mjs";
|
|
3
|
+
import { intlayerToPortableObjectFormatter, portableObjectToIntlayerFormatter } from "./po.mjs";
|
|
3
4
|
import { intlayerToVueI18nFormatter, vueI18nToIntlayerFormatter } from "./vue-i18n.mjs";
|
|
4
5
|
|
|
5
|
-
export { i18nextToIntlayerFormatter, icuToIntlayerFormatter, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToVueI18nFormatter, vueI18nToIntlayerFormatter };
|
|
6
|
+
export { i18nextToIntlayerFormatter, icuToIntlayerFormatter, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToPortableObjectFormatter, intlayerToVueI18nFormatter, portableObjectToIntlayerFormatter, vueI18nToIntlayerFormatter };
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { deepTransformNode } from "../interpreter/getContent/deepTransform.mjs";
|
|
2
|
+
import { enu as enumeration } from "../transpiler/enumeration/enumeration.mjs";
|
|
3
|
+
import { gender } from "../transpiler/gender/gender.mjs";
|
|
4
|
+
import { html } from "../transpiler/html/html.mjs";
|
|
5
|
+
import { insert as insertion } from "../transpiler/insertion/insertion.mjs";
|
|
6
|
+
import { plural } from "../transpiler/plural/plural.mjs";
|
|
7
|
+
import * as NodeTypes from "@intlayer/types/nodeType";
|
|
8
|
+
|
|
9
|
+
//#region src/messageFormat/po.ts
|
|
10
|
+
/**
|
|
11
|
+
* Extracts the string value from a transformed AST node or generic object.
|
|
12
|
+
*/
|
|
13
|
+
const extractStringValue = (val) => {
|
|
14
|
+
if (typeof val === "string") return val;
|
|
15
|
+
if (val && typeof val === "object" && "msgstr" in val) return val.msgstr[0] || "";
|
|
16
|
+
return JSON.stringify(val);
|
|
17
|
+
};
|
|
18
|
+
const intlayerToPoPlugin = {
|
|
19
|
+
canHandle: (node) => {
|
|
20
|
+
if (typeof node === "string") return true;
|
|
21
|
+
if (node && typeof node === "object" && (node.nodeType === NodeTypes.INSERTION || node.nodeType === NodeTypes.HTML || node.nodeType === NodeTypes.ENUMERATION || node.nodeType === NodeTypes.PLURAL || node.nodeType === NodeTypes.GENDER || node.nodeType === "composite")) return true;
|
|
22
|
+
if (Array.isArray(node)) {
|
|
23
|
+
if (node.length === 0) return false;
|
|
24
|
+
let hasNode = false;
|
|
25
|
+
let hasPlainObjectOrArray = false;
|
|
26
|
+
for (const item of node) if (typeof item === "string") {} else if (item && typeof item === "object" && (item.nodeType === NodeTypes.INSERTION || item.nodeType === NodeTypes.HTML || item.nodeType === NodeTypes.ENUMERATION || item.nodeType === NodeTypes.PLURAL || item.nodeType === NodeTypes.GENDER || item.nodeType === "composite")) hasNode = true;
|
|
27
|
+
else hasPlainObjectOrArray = true;
|
|
28
|
+
if (hasPlainObjectOrArray) return false;
|
|
29
|
+
if (!hasNode) return false;
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
},
|
|
34
|
+
transform: (node, props, next) => {
|
|
35
|
+
if (typeof node === "string") {
|
|
36
|
+
const poVal = node.replace(/\{\{([^}]+)\}\}/g, "%($1)s");
|
|
37
|
+
return {
|
|
38
|
+
msgid: poVal,
|
|
39
|
+
msgstr: [poVal]
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (node.nodeType === NodeTypes.INSERTION) return next(node[NodeTypes.INSERTION], props);
|
|
43
|
+
if (node.nodeType === NodeTypes.HTML) {
|
|
44
|
+
const val = node[NodeTypes.HTML];
|
|
45
|
+
return {
|
|
46
|
+
msgid: val,
|
|
47
|
+
msgstr: [val]
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (node.nodeType === NodeTypes.PLURAL || node.nodeType === NodeTypes.ENUMERATION) {
|
|
51
|
+
const isPlural = node.nodeType === NodeTypes.PLURAL;
|
|
52
|
+
const options = isPlural ? node[NodeTypes.PLURAL] : node[NodeTypes.ENUMERATION];
|
|
53
|
+
const rawMsgid = isPlural ? options.one || options.other || options.fallback : options.fallback || options["0"];
|
|
54
|
+
const msgid = extractStringValue(next(rawMsgid, props));
|
|
55
|
+
const msgid_plural = isPlural ? extractStringValue(next(options.other || options.fallback || rawMsgid, props)) : extractStringValue(next(options.fallback || rawMsgid, props));
|
|
56
|
+
const msgstr = [];
|
|
57
|
+
if (isPlural) {
|
|
58
|
+
if ("zero" in options) msgstr.push(extractStringValue(next(options.zero, props)));
|
|
59
|
+
msgstr.push(extractStringValue(next(options.one || options.fallback, props)));
|
|
60
|
+
if ("two" in options) msgstr.push(extractStringValue(next(options.two, props)));
|
|
61
|
+
if ("few" in options) msgstr.push(extractStringValue(next(options.few, props)));
|
|
62
|
+
if ("many" in options) msgstr.push(extractStringValue(next(options.many, props)));
|
|
63
|
+
const otherVal = extractStringValue(next(options.other || options.fallback, props));
|
|
64
|
+
if (!msgstr.includes(otherVal)) msgstr.push(otherVal);
|
|
65
|
+
} else {
|
|
66
|
+
msgstr[0] = extractStringValue(next(options.fallback || options["0"], props));
|
|
67
|
+
msgstr[1] = msgstr[0];
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
msgctxt: isPlural ? void 0 : "enumeration",
|
|
71
|
+
msgid,
|
|
72
|
+
msgid_plural,
|
|
73
|
+
msgstr
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (node.nodeType === NodeTypes.GENDER) {
|
|
77
|
+
const options = node[NodeTypes.GENDER];
|
|
78
|
+
const fallback = extractStringValue(next(options.fallback, props));
|
|
79
|
+
return {
|
|
80
|
+
msgctxt: "gender",
|
|
81
|
+
msgid: fallback,
|
|
82
|
+
msgstr: [
|
|
83
|
+
extractStringValue(next(options.male || options.fallback, props)),
|
|
84
|
+
extractStringValue(next(options.female || options.fallback, props)),
|
|
85
|
+
fallback
|
|
86
|
+
]
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
if (Array.isArray(node) || node.nodeType === "composite" && Array.isArray(node.composite)) {
|
|
90
|
+
const combined = (Array.isArray(node) ? node : node.composite).map((item) => extractStringValue(next(item, props))).join("");
|
|
91
|
+
return {
|
|
92
|
+
msgid: combined,
|
|
93
|
+
msgstr: [combined]
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return node;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const poToIntlayerPlugin = {
|
|
100
|
+
canHandle: (node) => node && typeof node === "object" && "msgid" in node && "msgstr" in node,
|
|
101
|
+
transform: (node) => {
|
|
102
|
+
const msgstr = node.msgstr || [];
|
|
103
|
+
const isPlural = Boolean(node.msgid_plural) || msgstr.length > 1;
|
|
104
|
+
const processString = (str) => {
|
|
105
|
+
if (!str) return "";
|
|
106
|
+
const parsed = str.replace(/%\(([a-zA-Z0-9_-]+)\)[sdf]/g, "{{$1}}");
|
|
107
|
+
if (/<[a-zA-Z0-9-]+[^>]*>/.test(parsed)) return html(parsed);
|
|
108
|
+
if (parsed.includes("{{")) return insertion(parsed);
|
|
109
|
+
return parsed;
|
|
110
|
+
};
|
|
111
|
+
if (!isPlural) return processString(msgstr[0] || node.msgid || "");
|
|
112
|
+
const options = {};
|
|
113
|
+
if (node.msgctxt === "gender") return gender({
|
|
114
|
+
male: processString(msgstr[0] || node.msgid),
|
|
115
|
+
female: processString(msgstr[1] || msgstr[0]),
|
|
116
|
+
fallback: processString(msgstr[2] || msgstr[msgstr.length - 1])
|
|
117
|
+
});
|
|
118
|
+
if (node.msgctxt === "enumeration") return enumeration({
|
|
119
|
+
"0": processString(msgstr[0]),
|
|
120
|
+
fallback: processString(msgstr[msgstr.length - 1])
|
|
121
|
+
});
|
|
122
|
+
if (msgstr.length === 2) {
|
|
123
|
+
options.one = processString(msgstr[0]);
|
|
124
|
+
options.other = processString(msgstr[1]);
|
|
125
|
+
} else if (msgstr.length === 3) {
|
|
126
|
+
options.one = processString(msgstr[0]);
|
|
127
|
+
options.few = processString(msgstr[1]);
|
|
128
|
+
options.other = processString(msgstr[2]);
|
|
129
|
+
} else if (msgstr.length === 6) {
|
|
130
|
+
options.zero = processString(msgstr[0]);
|
|
131
|
+
options.one = processString(msgstr[1]);
|
|
132
|
+
options.two = processString(msgstr[2]);
|
|
133
|
+
options.few = processString(msgstr[3]);
|
|
134
|
+
options.many = processString(msgstr[4]);
|
|
135
|
+
options.other = processString(msgstr[5]);
|
|
136
|
+
} else {
|
|
137
|
+
options.one = processString(msgstr[0]);
|
|
138
|
+
options.other = processString(msgstr[msgstr.length - 1]);
|
|
139
|
+
for (let i = 1; i < msgstr.length - 1; i++) options[`${i + 1}`] = processString(msgstr[i]);
|
|
140
|
+
}
|
|
141
|
+
return plural(options);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
const intlayerToPortableObjectFormatter = (dictionary) => {
|
|
145
|
+
return deepTransformNode(dictionary, {
|
|
146
|
+
dictionaryKey: "po",
|
|
147
|
+
keyPath: [],
|
|
148
|
+
plugins: [{
|
|
149
|
+
id: "po",
|
|
150
|
+
...intlayerToPoPlugin
|
|
151
|
+
}]
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
const portableObjectToIntlayerFormatter = (message) => {
|
|
155
|
+
return deepTransformNode(message, {
|
|
156
|
+
dictionaryKey: "po",
|
|
157
|
+
keyPath: [],
|
|
158
|
+
plugins: [{
|
|
159
|
+
id: "po",
|
|
160
|
+
...poToIntlayerPlugin
|
|
161
|
+
}]
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
//#endregion
|
|
166
|
+
export { intlayerToPortableObjectFormatter, portableObjectToIntlayerFormatter };
|
|
167
|
+
//# sourceMappingURL=po.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"po.mjs","names":["insert","enu"],"sources":["../../../src/messageFormat/po.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { deepTransformNode } from '../interpreter';\nimport { enu, gender, html, insert, plural } from '../transpiler';\nimport type { JsonValue } from './ICU';\n\nexport type PortableObject = {\n msgid: string;\n msgctxt?: string;\n msgid_plural?: string;\n msgstr: string[];\n};\n\n/**\n * Extracts the string value from a transformed AST node or generic object.\n */\nconst extractStringValue = (val: any): string => {\n if (typeof val === 'string') return val;\n if (val && typeof val === 'object' && 'msgstr' in val) {\n return val.msgstr[0] || '';\n }\n return JSON.stringify(val);\n};\n\nconst intlayerToPoPlugin = {\n canHandle: (node: any) => {\n if (typeof node === 'string') return true;\n\n if (\n node &&\n typeof node === 'object' &&\n (node.nodeType === NodeTypes.INSERTION ||\n node.nodeType === NodeTypes.HTML ||\n node.nodeType === NodeTypes.ENUMERATION ||\n node.nodeType === NodeTypes.PLURAL ||\n node.nodeType === NodeTypes.GENDER ||\n node.nodeType === 'composite')\n ) {\n return true;\n }\n\n // Handle structural string arrays (composite phrases)\n if (Array.isArray(node)) {\n if (node.length === 0) return false;\n let hasNode = false;\n let hasPlainObjectOrArray = false;\n\n for (const item of node) {\n if (typeof item === 'string') {\n } else if (\n item &&\n typeof item === 'object' &&\n (item.nodeType === NodeTypes.INSERTION ||\n item.nodeType === NodeTypes.HTML ||\n item.nodeType === NodeTypes.ENUMERATION ||\n item.nodeType === NodeTypes.PLURAL ||\n item.nodeType === NodeTypes.GENDER ||\n item.nodeType === 'composite')\n ) {\n hasNode = true;\n } else {\n hasPlainObjectOrArray = true;\n }\n }\n\n if (hasPlainObjectOrArray) return false;\n if (!hasNode) return false;\n return true;\n }\n\n return false;\n },\n transform: (node: any, props: any, next: any): PortableObject => {\n // 1. Strings\n if (typeof node === 'string') {\n const poVal = node.replace(/\\{\\{([^}]+)\\}\\}/g, '%($1)s');\n return { msgid: poVal, msgstr: [poVal] };\n }\n\n // 2. Insertions & Variables\n if (node.nodeType === NodeTypes.INSERTION) {\n return next(node[NodeTypes.INSERTION], props);\n }\n\n // 3. HTML\n if (node.nodeType === NodeTypes.HTML) {\n const val = node[NodeTypes.HTML];\n return { msgid: val, msgstr: [val] };\n }\n\n // 4. Plurals & Enumerations\n if (\n node.nodeType === NodeTypes.PLURAL ||\n node.nodeType === NodeTypes.ENUMERATION\n ) {\n const isPlural = node.nodeType === NodeTypes.PLURAL;\n const options = isPlural\n ? node[NodeTypes.PLURAL]\n : node[NodeTypes.ENUMERATION];\n\n const rawMsgid = isPlural\n ? options.one || options.other || options.fallback\n : options.fallback || options['0'];\n\n const msgid = extractStringValue(next(rawMsgid, props));\n const msgid_plural = isPlural\n ? extractStringValue(\n next(options.other || options.fallback || rawMsgid, props)\n )\n : extractStringValue(next(options.fallback || rawMsgid, props));\n\n const msgstr: string[] = [];\n\n if (isPlural) {\n // Standard CLDR/Gettext mapping fallback\n if ('zero' in options)\n msgstr.push(extractStringValue(next(options.zero, props)));\n msgstr.push(\n extractStringValue(next(options.one || options.fallback, props))\n );\n if ('two' in options)\n msgstr.push(extractStringValue(next(options.two, props)));\n if ('few' in options)\n msgstr.push(extractStringValue(next(options.few, props)));\n if ('many' in options)\n msgstr.push(extractStringValue(next(options.many, props)));\n\n // Ensure 'other' is always the last fallback if others are missing\n const otherVal = extractStringValue(\n next(options.other || options.fallback, props)\n );\n if (!msgstr.includes(otherVal)) msgstr.push(otherVal);\n } else {\n // Enums don't have standard PO mapping, pack linearly\n msgstr[0] = extractStringValue(\n next(options.fallback || options['0'], props)\n );\n msgstr[1] = msgstr[0];\n }\n\n return {\n msgctxt: isPlural ? undefined : 'enumeration',\n msgid,\n msgid_plural,\n msgstr,\n };\n }\n\n // 5. Gender (mapped to PO via msgctxt)\n if (node.nodeType === NodeTypes.GENDER) {\n const options = node[NodeTypes.GENDER];\n const fallback = extractStringValue(next(options.fallback, props));\n return {\n msgctxt: 'gender',\n msgid: fallback,\n msgstr: [\n extractStringValue(next(options.male || options.fallback, props)),\n extractStringValue(next(options.female || options.fallback, props)),\n fallback,\n ],\n };\n }\n\n // 6. Arrays / Composites\n if (\n Array.isArray(node) ||\n (node.nodeType === 'composite' && Array.isArray(node.composite))\n ) {\n const arr = Array.isArray(node) ? node : node.composite;\n const combined = arr\n .map((item: any) => extractStringValue(next(item, props)))\n .join('');\n return { msgid: combined, msgstr: [combined] };\n }\n\n return node;\n },\n};\n\nconst poToIntlayerPlugin = {\n canHandle: (node: any) =>\n node && typeof node === 'object' && 'msgid' in node && 'msgstr' in node,\n\n transform: (node: PortableObject) => {\n const msgstr = node.msgstr || [];\n const isPlural = Boolean(node.msgid_plural) || msgstr.length > 1;\n\n const processString = (str: string) => {\n if (!str) return '';\n // Convert Python/C-style gettext variables %(name)s or %(name)d -> {{name}}\n const parsed = str.replace(/%\\(([a-zA-Z0-9_-]+)\\)[sdf]/g, '{{$1}}');\n\n if (/<[a-zA-Z0-9-]+[^>]*>/.test(parsed)) return html(parsed);\n if (parsed.includes('{{')) return insert(parsed);\n return parsed;\n };\n\n // Fast-path: Single string translation\n if (!isPlural) {\n return processString(msgstr[0] || node.msgid || '');\n }\n\n // Handle Plural/Enum/Gender matrix\n const options: Record<string, any> = {};\n\n if (node.msgctxt === 'gender') {\n return gender({\n male: processString(msgstr[0] || node.msgid),\n female: processString(msgstr[1] || msgstr[0]),\n fallback: processString(msgstr[2] || msgstr[msgstr.length - 1]),\n });\n }\n\n if (node.msgctxt === 'enumeration') {\n return enu({\n '0': processString(msgstr[0]),\n fallback: processString(msgstr[msgstr.length - 1]),\n });\n }\n\n // Plural Form Mapping based on array length (Gettext Plural-Forms approximation)\n if (msgstr.length === 2) {\n options.one = processString(msgstr[0]);\n options.other = processString(msgstr[1]);\n } else if (msgstr.length === 3) {\n // E.g., Polish/Russian: one, few, many/other\n options.one = processString(msgstr[0]);\n options.few = processString(msgstr[1]);\n options.other = processString(msgstr[2]);\n } else if (msgstr.length === 6) {\n // E.g., Arabic: zero, one, two, few, many, other\n options.zero = processString(msgstr[0]);\n options.one = processString(msgstr[1]);\n options.two = processString(msgstr[2]);\n options.few = processString(msgstr[3]);\n options.many = processString(msgstr[4]);\n options.other = processString(msgstr[5]);\n } else {\n // Generic arbitrary length mapping\n options.one = processString(msgstr[0]);\n options.other = processString(msgstr[msgstr.length - 1]);\n for (let i = 1; i < msgstr.length - 1; i++) {\n options[`${i + 1}`] = processString(msgstr[i]);\n }\n }\n\n return plural(options as any);\n },\n};\n\nexport const intlayerToPortableObjectFormatter = (\n dictionary: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(dictionary, {\n dictionaryKey: 'po',\n keyPath: [],\n plugins: [{ id: 'po', ...intlayerToPoPlugin }],\n });\n};\n\nexport const portableObjectToIntlayerFormatter = (\n message: JsonValue\n): Dictionary['content'] => {\n return deepTransformNode(message, {\n dictionaryKey: 'po',\n keyPath: [],\n plugins: [{ id: 'po', ...poToIntlayerPlugin }],\n });\n};\n"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { deepTransformNode } from "../interpreter/getContent/deepTransform.mjs";
|
|
2
2
|
import { enu as enumeration } from "../transpiler/enumeration/enumeration.mjs";
|
|
3
3
|
import { insert as insertion } from "../transpiler/insertion/insertion.mjs";
|
|
4
|
+
import { plural } from "../transpiler/plural/plural.mjs";
|
|
4
5
|
import * as NodeTypes from "@intlayer/types/nodeType";
|
|
5
6
|
|
|
6
7
|
//#region src/messageFormat/vue-i18n.ts
|
|
@@ -67,14 +68,16 @@ const vueI18nNodesToIntlayer = (parts) => {
|
|
|
67
68
|
if (parts.length === 1) return vueI18nPartToIntlayer(parts[0]);
|
|
68
69
|
const options = {};
|
|
69
70
|
const varName = "count";
|
|
70
|
-
if (parts.length === 2) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
71
|
+
if (parts.length === 2) return plural({
|
|
72
|
+
one: vueI18nPartToIntlayer(parts[0]),
|
|
73
|
+
other: vueI18nPartToIntlayer(parts[1])
|
|
74
|
+
});
|
|
75
|
+
if (parts.length === 3) return plural({
|
|
76
|
+
zero: vueI18nPartToIntlayer(parts[0]),
|
|
77
|
+
one: vueI18nPartToIntlayer(parts[1]),
|
|
78
|
+
other: vueI18nPartToIntlayer(parts[2])
|
|
79
|
+
});
|
|
80
|
+
parts.forEach((part, index) => {
|
|
78
81
|
if (index === parts.length - 1) options.fallback = vueI18nPartToIntlayer(part);
|
|
79
82
|
else options[index.toString()] = vueI18nPartToIntlayer(part);
|
|
80
83
|
});
|
|
@@ -94,7 +97,7 @@ const vueI18nToIntlayerPlugin = {
|
|
|
94
97
|
const intlayerToVueI18nPlugin = {
|
|
95
98
|
canHandle: (node) => {
|
|
96
99
|
if (typeof node === "string") return true;
|
|
97
|
-
if (node && typeof node === "object" && (node.nodeType === NodeTypes.INSERTION || node.nodeType === NodeTypes.ENUMERATION || node.nodeType === NodeTypes.GENDER || node.nodeType === "composite")) return true;
|
|
100
|
+
if (node && typeof node === "object" && (node.nodeType === NodeTypes.INSERTION || node.nodeType === NodeTypes.ENUMERATION || node.nodeType === NodeTypes.PLURAL || node.nodeType === NodeTypes.GENDER || node.nodeType === "composite")) return true;
|
|
98
101
|
if (Array.isArray(node)) {
|
|
99
102
|
if (node.length === 0) return false;
|
|
100
103
|
let hasNode = false;
|
|
@@ -110,6 +113,17 @@ const intlayerToVueI18nPlugin = {
|
|
|
110
113
|
transform: (node, props, next) => {
|
|
111
114
|
if (typeof node === "string") return node.replace(/\{\{([^}]+)\}\}/g, "{$1}");
|
|
112
115
|
if (node.nodeType === NodeTypes.INSERTION) return node[NodeTypes.INSERTION].replace(/\{\{([^}]+)\}\}/g, "{$1}");
|
|
116
|
+
if (node.nodeType === NodeTypes.PLURAL) {
|
|
117
|
+
const options = node[NodeTypes.PLURAL];
|
|
118
|
+
const transformedOptions = {};
|
|
119
|
+
for (const [key, val] of Object.entries(options)) {
|
|
120
|
+
const childVal = next(val, props);
|
|
121
|
+
transformedOptions[key] = typeof childVal === "string" ? childVal : JSON.stringify(childVal);
|
|
122
|
+
}
|
|
123
|
+
if (transformedOptions.zero && transformedOptions.one && transformedOptions.other) return `${transformedOptions.zero} | ${transformedOptions.one} | ${transformedOptions.other}`;
|
|
124
|
+
if (transformedOptions.one && transformedOptions.other) return `${transformedOptions.one} | ${transformedOptions.other}`;
|
|
125
|
+
return transformedOptions.other || Object.values(transformedOptions)[0];
|
|
126
|
+
}
|
|
113
127
|
if (node.nodeType === NodeTypes.ENUMERATION) {
|
|
114
128
|
const options = node[NodeTypes.ENUMERATION];
|
|
115
129
|
const transformedOptions = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vue-i18n.mjs","names":["insert","enu"],"sources":["../../../src/messageFormat/vue-i18n.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { deepTransformNode } from '../interpreter';\nimport { enu, insert } from '../transpiler';\nimport type { JsonValue } from './ICU';\n\n// Types for our AST\ntype VueI18nNode =\n | string\n | {\n type: 'argument';\n name: string;\n };\n\nconst parseVueI18nPart = (text: string): VueI18nNode[] => {\n let index = 0;\n const nodes: VueI18nNode[] = [];\n let currentText = '';\n\n while (index < text.length) {\n const char = text[index];\n\n if (char === '{') {\n if (currentText) {\n nodes.push(currentText);\n currentText = '';\n }\n index++; // skip {\n let name = '';\n while (index < text.length && text[index] !== '}') {\n name += text[index];\n index++;\n }\n if (index < text.length) {\n index++; // skip }\n }\n nodes.push({ type: 'argument', name: name.trim() });\n } else {\n currentText += char;\n index++;\n }\n }\n\n if (currentText) {\n nodes.push(currentText);\n }\n\n return nodes;\n};\n\nconst parseVueI18n = (text: string): VueI18nNode[][] => {\n // Split by | but handle escaped \\|\n const parts: string[] = [];\n let currentPart = '';\n let index = 0;\n\n while (index < text.length) {\n const char = text[index];\n if (char === '\\\\' && index + 1 < text.length && text[index + 1] === '|') {\n currentPart += '|';\n index += 2;\n } else if (char === '|') {\n parts.push(currentPart.trim()); // Trim to remove surrounding spaces\n currentPart = '';\n index++;\n } else {\n currentPart += char;\n index++;\n }\n }\n parts.push(currentPart.trim()); // Trim last part too\n\n return parts.map(parseVueI18nPart);\n};\n\nconst vueI18nPartToIntlayer = (nodes: VueI18nNode[]): any => {\n if (nodes.length === 0) return '';\n if (nodes.length === 1 && typeof nodes[0] === 'string') return nodes[0];\n\n let str = '';\n for (const node of nodes) {\n if (typeof node === 'string') {\n str += node;\n } else {\n str += `{{${node.name}}}`;\n }\n }\n return insert(str);\n};\n\nconst vueI18nNodesToIntlayer = (parts: VueI18nNode[][]): any => {\n if (parts.length === 1) {\n return vueI18nPartToIntlayer(parts[0]);\n }\n\n // Handle pluralization (choice)\n const options: Record<string, any> = {};\n const varName = 'count'; // Default variable for vue-i18n choices\n\n if (parts.length === 2) {\n // 2 choices: 1 | other\n options['1'] = vueI18nPartToIntlayer(parts[0]);\n options.fallback = vueI18nPartToIntlayer(parts[1]);\n } else if (parts.length === 3) {\n // 3 choices: 0 | 1 | other\n options['0'] = vueI18nPartToIntlayer(parts[0]);\n options['1'] = vueI18nPartToIntlayer(parts[1]);\n options.fallback = vueI18nPartToIntlayer(parts[2]);\n } else {\n // > 3 choices: 0 | 1 | 2 | ... | other\n parts.forEach((part, index) => {\n if (index === parts.length - 1) {\n options.fallback = vueI18nPartToIntlayer(part);\n } else {\n options[index.toString()] = vueI18nPartToIntlayer(part);\n }\n });\n }\n\n // Preserve variable name\n options.__intlayer_vue_i18n_var = varName;\n\n return enu(options);\n};\n\nconst vueI18nToIntlayerPlugin = {\n canHandle: (node: any) =>\n typeof node === 'string' && (node.includes('{') || node.includes('|')),\n transform: (node: any) => {\n try {\n const ast = parseVueI18n(node);\n return vueI18nNodesToIntlayer(ast);\n } catch {\n return node;\n }\n },\n};\n\nconst intlayerToVueI18nPlugin = {\n canHandle: (node: any) => {\n if (typeof node === 'string') return true;\n\n if (\n node &&\n typeof node === 'object' &&\n (node.nodeType === NodeTypes.INSERTION ||\n node.nodeType === NodeTypes.ENUMERATION ||\n node.nodeType === NodeTypes.GENDER ||\n node.nodeType === 'composite')\n ) {\n return true;\n }\n\n if (Array.isArray(node)) {\n if (node.length === 0) return false;\n\n let hasNode = false;\n let hasPlainObjectOrArray = false;\n\n for (const item of node) {\n if (typeof item === 'string') {\n } else if (\n item &&\n typeof item === 'object' &&\n (item.nodeType === NodeTypes.INSERTION ||\n item.nodeType === NodeTypes.ENUMERATION ||\n item.nodeType === NodeTypes.GENDER ||\n item.nodeType === 'composite')\n ) {\n hasNode = true;\n } else {\n hasPlainObjectOrArray = true;\n }\n }\n\n // If it contains plain objects or nested arrays, it's a structural array\n if (hasPlainObjectOrArray) return false;\n // If it contains ONLY strings, it's a structural array, not a composite string\n if (!hasNode) return false;\n\n return true;\n }\n\n return false;\n },\n transform: (node: any, props: any, next: any) => {\n if (typeof node === 'string') {\n // replace {{...}} with {...} even in strings\n return node.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n }\n\n if (node.nodeType === NodeTypes.INSERTION) {\n // {{name}} -> {name}\n return node[NodeTypes.INSERTION].replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n }\n\n if (node.nodeType === NodeTypes.ENUMERATION) {\n const options = node[NodeTypes.ENUMERATION];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n if (key === '__intlayer_vue_i18n_var') continue;\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n const keys = Object.keys(transformedOptions);\n\n if (keys.includes('0')) {\n const indices = keys.filter((key) => /^\\d+$/.test(key)).map(Number);\n const maxIndex = Math.max(...indices);\n\n const fallback =\n transformedOptions.fallback || transformedOptions.other;\n const resultParts = [];\n\n if (maxIndex <= 1 && !keys.includes('2')) {\n const zero = transformedOptions['0'] || '';\n const one = transformedOptions['1'] || '';\n return `${zero} | ${one} | ${fallback}`;\n }\n\n const limit = Math.max(1, maxIndex);\n\n for (let i = 0; i <= limit; i++) {\n const key = i.toString();\n if (transformedOptions[key]) {\n resultParts.push(transformedOptions[key]);\n } else {\n resultParts.push('');\n }\n }\n resultParts.push(fallback);\n return resultParts.join(' | ').replace(/ \\| {2}\\| /g, ' | | ');\n }\n\n if (\n keys.includes('1') &&\n (keys.includes('fallback') || keys.includes('other'))\n ) {\n return `${transformedOptions['1']} | ${transformedOptions.fallback || transformedOptions.other}`;\n }\n\n if (\n keys.length === 1 &&\n (keys.includes('fallback') || keys.includes('other'))\n ) {\n return transformedOptions.fallback || transformedOptions.other;\n }\n\n return (\n transformedOptions.fallback || Object.values(transformedOptions)[0]\n );\n }\n\n if (node.nodeType === NodeTypes.GENDER) {\n const options = node[NodeTypes.GENDER];\n const transformedOptions: Record<string, any> = {};\n\n for (const [key, val] of Object.entries(options)) {\n let newKey = key;\n if (key === 'fallback') newKey = 'other';\n\n const childVal = next(val, props);\n transformedOptions[newKey] = childVal;\n }\n return transformedOptions;\n }\n\n if (\n Array.isArray(node) ||\n (node.nodeType === 'composite' && Array.isArray(node.composite))\n ) {\n const arr = Array.isArray(node) ? node : node.composite;\n const items = arr.map((item: any) => next(item, props));\n return items.join('');\n }\n\n return next(node, props);\n },\n};\n\nexport const intlayerToVueI18nFormatter = (\n message: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(message, {\n dictionaryKey: 'vue-i18n',\n keyPath: [],\n plugins: [{ id: 'vue-i18n', ...intlayerToVueI18nPlugin }],\n });\n};\n\nexport const vueI18nToIntlayerFormatter = (\n message: JsonValue\n): Dictionary['content'] => {\n return deepTransformNode(message, {\n dictionaryKey: 'vue-i18n',\n keyPath: [],\n plugins: [{ id: 'vue-i18n', ...vueI18nToIntlayerPlugin }],\n });\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vue-i18n.mjs","names":["insert","enu"],"sources":["../../../src/messageFormat/vue-i18n.ts"],"sourcesContent":["import type { Dictionary } from '@intlayer/types/dictionary';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { deepTransformNode } from '../interpreter';\nimport { enu, insert, plural } from '../transpiler';\nimport type { JsonValue } from './ICU';\n\n// Types for our AST\ntype VueI18nNode =\n | string\n | {\n type: 'argument';\n name: string;\n };\n\nconst parseVueI18nPart = (text: string): VueI18nNode[] => {\n let index = 0;\n const nodes: VueI18nNode[] = [];\n let currentText = '';\n\n while (index < text.length) {\n const char = text[index];\n\n if (char === '{') {\n if (currentText) {\n nodes.push(currentText);\n currentText = '';\n }\n index++; // skip {\n let name = '';\n while (index < text.length && text[index] !== '}') {\n name += text[index];\n index++;\n }\n if (index < text.length) {\n index++; // skip }\n }\n nodes.push({ type: 'argument', name: name.trim() });\n } else {\n currentText += char;\n index++;\n }\n }\n\n if (currentText) {\n nodes.push(currentText);\n }\n\n return nodes;\n};\n\nconst parseVueI18n = (text: string): VueI18nNode[][] => {\n // Split by | but handle escaped \\|\n const parts: string[] = [];\n let currentPart = '';\n let index = 0;\n\n while (index < text.length) {\n const char = text[index];\n if (char === '\\\\' && index + 1 < text.length && text[index + 1] === '|') {\n currentPart += '|';\n index += 2;\n } else if (char === '|') {\n parts.push(currentPart.trim()); // Trim to remove surrounding spaces\n currentPart = '';\n index++;\n } else {\n currentPart += char;\n index++;\n }\n }\n parts.push(currentPart.trim()); // Trim last part too\n\n return parts.map(parseVueI18nPart);\n};\n\nconst vueI18nPartToIntlayer = (nodes: VueI18nNode[]): any => {\n if (nodes.length === 0) return '';\n if (nodes.length === 1 && typeof nodes[0] === 'string') return nodes[0];\n\n let str = '';\n for (const node of nodes) {\n if (typeof node === 'string') {\n str += node;\n } else {\n str += `{{${node.name}}}`;\n }\n }\n return insert(str);\n};\n\nconst vueI18nNodesToIntlayer = (parts: VueI18nNode[][]): any => {\n if (parts.length === 1) {\n return vueI18nPartToIntlayer(parts[0]);\n }\n\n // Handle pluralization (choice)\n const options: Record<string, any> = {};\n const varName = 'count'; // Default variable for vue-i18n choices\n\n if (parts.length === 2) {\n // 2 choices: 1 | other\n return plural({\n one: vueI18nPartToIntlayer(parts[0]),\n other: vueI18nPartToIntlayer(parts[1]),\n });\n }\n\n if (parts.length === 3) {\n // 3 choices: 0 | 1 | other\n return plural({\n zero: vueI18nPartToIntlayer(parts[0]),\n one: vueI18nPartToIntlayer(parts[1]),\n other: vueI18nPartToIntlayer(parts[2]),\n });\n }\n\n // > 3 choices: 0 | 1 | 2 | ... | other\n parts.forEach((part, index) => {\n if (index === parts.length - 1) {\n options.fallback = vueI18nPartToIntlayer(part);\n } else {\n options[index.toString()] = vueI18nPartToIntlayer(part);\n }\n });\n\n // Preserve variable name\n options.__intlayer_vue_i18n_var = varName;\n\n return enu(options);\n};\n\nconst vueI18nToIntlayerPlugin = {\n canHandle: (node: any) =>\n typeof node === 'string' && (node.includes('{') || node.includes('|')),\n transform: (node: any) => {\n try {\n const ast = parseVueI18n(node);\n return vueI18nNodesToIntlayer(ast);\n } catch {\n return node;\n }\n },\n};\n\nconst intlayerToVueI18nPlugin = {\n canHandle: (node: any) => {\n if (typeof node === 'string') return true;\n\n if (\n node &&\n typeof node === 'object' &&\n (node.nodeType === NodeTypes.INSERTION ||\n node.nodeType === NodeTypes.ENUMERATION ||\n node.nodeType === NodeTypes.PLURAL ||\n node.nodeType === NodeTypes.GENDER ||\n node.nodeType === 'composite')\n ) {\n return true;\n }\n\n if (Array.isArray(node)) {\n if (node.length === 0) return false;\n\n let hasNode = false;\n let hasPlainObjectOrArray = false;\n\n for (const item of node) {\n if (typeof item === 'string') {\n } else if (\n item &&\n typeof item === 'object' &&\n (item.nodeType === NodeTypes.INSERTION ||\n item.nodeType === NodeTypes.ENUMERATION ||\n item.nodeType === NodeTypes.GENDER ||\n item.nodeType === 'composite')\n ) {\n hasNode = true;\n } else {\n hasPlainObjectOrArray = true;\n }\n }\n\n // If it contains plain objects or nested arrays, it's a structural array\n if (hasPlainObjectOrArray) return false;\n // If it contains ONLY strings, it's a structural array, not a composite string\n if (!hasNode) return false;\n\n return true;\n }\n\n return false;\n },\n transform: (node: any, props: any, next: any) => {\n if (typeof node === 'string') {\n // replace {{...}} with {...} even in strings\n return node.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n }\n\n if (node.nodeType === NodeTypes.INSERTION) {\n // {{name}} -> {name}\n return node[NodeTypes.INSERTION].replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n }\n\n if (node.nodeType === NodeTypes.PLURAL) {\n const options = node[NodeTypes.PLURAL];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n if (\n transformedOptions.zero &&\n transformedOptions.one &&\n transformedOptions.other\n ) {\n return `${transformedOptions.zero} | ${transformedOptions.one} | ${transformedOptions.other}`;\n }\n\n if (transformedOptions.one && transformedOptions.other) {\n return `${transformedOptions.one} | ${transformedOptions.other}`;\n }\n\n return transformedOptions.other || Object.values(transformedOptions)[0];\n }\n\n if (node.nodeType === NodeTypes.ENUMERATION) {\n const options = node[NodeTypes.ENUMERATION];\n\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n if (key === '__intlayer_vue_i18n_var') continue;\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n const keys = Object.keys(transformedOptions);\n\n if (keys.includes('0')) {\n const indices = keys.filter((key) => /^\\d+$/.test(key)).map(Number);\n const maxIndex = Math.max(...indices);\n\n const fallback =\n transformedOptions.fallback || transformedOptions.other;\n const resultParts = [];\n\n if (maxIndex <= 1 && !keys.includes('2')) {\n const zero = transformedOptions['0'] || '';\n const one = transformedOptions['1'] || '';\n return `${zero} | ${one} | ${fallback}`;\n }\n\n const limit = Math.max(1, maxIndex);\n\n for (let i = 0; i <= limit; i++) {\n const key = i.toString();\n if (transformedOptions[key]) {\n resultParts.push(transformedOptions[key]);\n } else {\n resultParts.push('');\n }\n }\n resultParts.push(fallback);\n return resultParts.join(' | ').replace(/ \\| {2}\\| /g, ' | | ');\n }\n\n if (\n keys.includes('1') &&\n (keys.includes('fallback') || keys.includes('other'))\n ) {\n return `${transformedOptions['1']} | ${transformedOptions.fallback || transformedOptions.other}`;\n }\n\n if (\n keys.length === 1 &&\n (keys.includes('fallback') || keys.includes('other'))\n ) {\n return transformedOptions.fallback || transformedOptions.other;\n }\n\n return (\n transformedOptions.fallback || Object.values(transformedOptions)[0]\n );\n }\n\n if (node.nodeType === NodeTypes.GENDER) {\n const options = node[NodeTypes.GENDER];\n const transformedOptions: Record<string, any> = {};\n\n for (const [key, val] of Object.entries(options)) {\n let newKey = key;\n if (key === 'fallback') newKey = 'other';\n\n const childVal = next(val, props);\n transformedOptions[newKey] = childVal;\n }\n return transformedOptions;\n }\n\n if (\n Array.isArray(node) ||\n (node.nodeType === 'composite' && Array.isArray(node.composite))\n ) {\n const arr = Array.isArray(node) ? node : node.composite;\n const items = arr.map((item: any) => next(item, props));\n return items.join('');\n }\n\n return next(node, props);\n },\n};\n\nexport const intlayerToVueI18nFormatter = (\n message: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(message, {\n dictionaryKey: 'vue-i18n',\n keyPath: [],\n plugins: [{ id: 'vue-i18n', ...intlayerToVueI18nPlugin }],\n });\n};\n\nexport const vueI18nToIntlayerFormatter = (\n message: JsonValue\n): Dictionary['content'] => {\n return deepTransformNode(message, {\n dictionaryKey: 'vue-i18n',\n keyPath: [],\n plugins: [{ id: 'vue-i18n', ...vueI18nToIntlayerPlugin }],\n });\n};\n"],"mappings":"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"}
|
|
@@ -8,7 +8,11 @@ import { Dictionary } from "@intlayer/types/dictionary";
|
|
|
8
8
|
* @param priorityStrategy - The priority strategy ('local_first' or 'distant_first')
|
|
9
9
|
* @returns Ordered array of dictionaries
|
|
10
10
|
*/
|
|
11
|
-
declare const orderDictionaries: (dictionaries: Dictionary[]
|
|
11
|
+
declare const orderDictionaries: (dictionaries: Dictionary[], config?: {
|
|
12
|
+
editor: {
|
|
13
|
+
dictionaryPriorityStrategy: "local_first" | "distant_first";
|
|
14
|
+
};
|
|
15
|
+
}) => Dictionary[];
|
|
12
16
|
//#endregion
|
|
13
17
|
export { orderDictionaries };
|
|
14
18
|
//# sourceMappingURL=orderDictionaries.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orderDictionaries.d.ts","names":[],"sources":["../../../src/dictionaryManipulator/orderDictionaries.ts"],"mappings":";;;;;AAUA;;;;;cAAa,iBAAA,
|
|
1
|
+
{"version":3,"file":"orderDictionaries.d.ts","names":[],"sources":["../../../src/dictionaryManipulator/orderDictionaries.ts"],"mappings":";;;;;AAUA;;;;;cAAa,iBAAA,GACX,YAAA,EAAc,UAAA,IACd,MAAA;EACE,MAAA;IACE,0BAAA;EAAA;AAAA,MAGH,UAAA"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -81,10 +81,11 @@ import { createRenderer, renderFor } from "./markdown/renderer.js";
|
|
|
81
81
|
import { allowInline, anyScopeRegex, attributeValueToNodePropValue, blockRegex, captureNothing, cx, get, inlineRegex, normalizeAttributeKey, normalizeWhitespace, parseBlock, parseCaptureInline, parseInline, parseSimpleInline, parseStyleAttribute, parseTableAlign, parseTableAlignCapture, parseTableCells, parseTableRow, qualifies, renderNothing, sanitizer, simpleInlineRegex, slugify, some, startsWith, trimEnd, trimLeadingWhitespaceOutsideFences, unescapeString, unquote } from "./markdown/utils.js";
|
|
82
82
|
import { JsonValue, icuToIntlayerFormatter, intlayerToICUFormatter } from "./messageFormat/ICU.js";
|
|
83
83
|
import { i18nextToIntlayerFormatter, intlayerToI18nextFormatter } from "./messageFormat/i18next.js";
|
|
84
|
+
import { PortableObject, intlayerToPortableObjectFormatter, portableObjectToIntlayerFormatter } from "./messageFormat/po.js";
|
|
84
85
|
import { intlayerToVueI18nFormatter, vueI18nToIntlayerFormatter } from "./messageFormat/vue-i18n.js";
|
|
85
86
|
import { checkIsURLAbsolute } from "./utils/checkIsURLAbsolute.js";
|
|
86
87
|
import { getCookie } from "./utils/getCookie.js";
|
|
87
88
|
import { isSameKeyPath } from "./utils/isSameKeyPath.js";
|
|
88
89
|
import { isValidElement } from "./utils/isValidReactElement.js";
|
|
89
90
|
import { parseYaml } from "./utils/parseYaml.js";
|
|
90
|
-
export { ATTRIBUTES_TO_SANITIZE, ATTRIBUTE_TO_NODE_PROP_MAP, ATTR_EXTRACTOR_R, BLOCKQUOTE_ALERT_R, BLOCKQUOTE_R, BLOCKQUOTE_TRIM_LEFT_MULTILINE_R, BLOCK_END_R, BREAK_LINE_R, BREAK_THEMATIC_R, BlockQuoteNode, BoldTextNode, BreakLineNode, BreakThematicNode, CAPTURE_LETTER_AFTER_HYPHEN, CODE_BLOCK_FENCED_R, CODE_BLOCK_R, CODE_INLINE_R, CONSECUTIVE_NEWLINE_R, CR_NEWLINE_R, CUSTOM_COMPONENT_R, CachedIntl, CachedIntl as Intl, CodeBlockNode, CodeFencedNode, CodeInlineNode, CompileOptions, ComponentOverrides, ConditionCond, ConditionContent, ConditionContentStates, CookieBuildAttributes, CustomComponentNode, DO_NOT_PROCESS_HTML_ELEMENTS, DURATION_DELAY_TRIGGER, DateTimePreset, DeepTransformContent, DotPath, ElementType, EnterFormat, EnumerationCond, EnumerationContent, EnumerationContentState, EscapedTextNode, FOOTNOTE_R, FOOTNOTE_REFERENCE_R, FORMFEED_R, FRONT_MATTER_R, FileCond, FileContent, FileContentConstructor, FootnoteNode, FootnoteReferenceNode, GFMTaskNode, GFM_TASK_R, Gender, GenderCond, GenderContent, GenderContentStates, GenerateSitemapOptions, GetNestingResult, GetPrefixOptions, GetPrefixResult, HEADING_ATX_COMPLIANT_R, HEADING_R, HEADING_SETEXT_R, HTMLCommentNode, HTMLContent, HTMLContentConstructor, HTMLNode, HTMLSelfClosingNode, HTMLTag, HTMLTagsType, HTMLValidationIssue, HTMLValidationResult, HTML_BLOCK_ELEMENT_R, HTML_CHAR_CODE_R, HTML_COMMENT_R, HTML_CUSTOM_ATTR_R, HTML_LEFT_TRIM_AMOUNT_R, HTML_SELF_CLOSING_ELEMENT_R, HTML_TAGS, HeadingNode, HeadingSetextNode, IInterpreterPlugin, IInterpreterPluginState, INLINE_SKIP_R, INTERPOLATION_R, ImageNode, InsertionCond, InsertionContent, InsertionContentConstructor, IsAny, ItalicTextNode, JsonValue, LINK_AUTOLINK_BARE_URL_R, LINK_AUTOLINK_R, LIST_LOOKBEHIND_R, LOOKAHEAD, LinkAngleBraceNode, LinkBareURLNode, LinkNode, ListType, LocaleStorage, LocaleStorageClient, LocaleStorageClientOptions, LocaleStorageOptions, LocaleStorageServer, LocaleStorageServerOptions, LocalizedPathResult, MarkdownContent, MarkdownContentConstructor, MarkdownContext, MarkdownOptions, MarkdownRuntime, HTMLValidationIssue as MarkdownValidationIssue, MarkdownValidationResult, MarkedTextNode, NAMED_CODES_TO_UNICODE, NP_TABLE_R, NestedCond, NestedContent, NestedContentState, NestedParser, NewlineNode, NodeProps, ORDERED, ORDERED_LIST_BULLET, ORDERED_LIST_ITEM_PREFIX, ORDERED_LIST_ITEM_PREFIX_R, ORDERED_LIST_ITEM_R, ORDERED_LIST_R, OrderedListNode, PARAGRAPH_R, ParagraphNode, ParseState, Parser, ParserResult, Plugins, PluralCategory, PluralCond, PluralContent, PluralContentState, Priority, PriorityValue, REFERENCE_IMAGE_OR_LINK, REFERENCE_IMAGE_R, REFERENCE_LINK_R, ReferenceImageNode, ReferenceLinkNode, ReferenceNode, RenderRuleHook, Rule, RuleOutput, RuleType, RuleTypeValue, Rules, SHORTCODE_R, SHOULD_RENDER_AS_BLOCK_R, SitemapUrlEntry, StrikethroughTextNode, TABLE_CENTER_ALIGN, TABLE_LEFT_ALIGN, TABLE_RIGHT_ALIGN, TABLE_TRIM_PIPES, TAB_R, TEXT_BOLD_R, TEXT_EMPHASIZED_R, TEXT_ESCAPED_R, TEXT_MARKED_R, TEXT_PLAIN_R, TEXT_STRIKETHROUGHED_R, TRIM_STARTING_NEWLINES, TableNode, TableSeparatorNode, TextNode, TranslationCond, TranslationContent, UNESCAPE_R, UNORDERED, UNORDERED_LIST_BULLET, UNORDERED_LIST_ITEM_PREFIX, UNORDERED_LIST_ITEM_PREFIX_R, UNORDERED_LIST_ITEM_R, UNORDERED_LIST_R, UnionKeys, UnorderedListNode, VOID_ELEMENTS, ValidDotPathsFor, ValueAtKey, WrappedIntl, allowInline, anyScopeRegex, attributeValueToNodePropValue, bindIntl, blockRegex, buildMaskPlugin, captureNothing, checkIsURLAbsolute, checkMissingLocalesPlugin, compact, compile, compileWithOptions, condition as cond, conditionPlugin, createCompiler, createRenderer, currency, cx, date, deepTransformNode, editDictionaryByKeyPath, enumeration as enu, enumerationPlugin, fallbackPlugin, file, fileContent, filePlugin, filterMissingTranslationsOnlyPlugin, filterTranslationsOnlyPlugin, findMatchingCondition, gender, genderPlugin, generateListItemPrefix, generateListItemPrefixRegex, generateListItemRegex, generateListRegex, generateSitemap, generateSitemapUrl, get, getBasePlugins, getBrowserLocale, getCachedIntl, getCanonicalPath, getCondition, getContent, getContentNodeByKeyPath, getCookie, getDefaultNode, getDictionary, getEmptyNode, getEnumeration, getFilterMissingTranslationsContent, getFilterMissingTranslationsDictionary, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary, getFilteredLocalesContent, getFilteredLocalesDictionary, getHTML, getHTMLTextDir, getInsertionValues, getInternalPath, getIntlayer, getLocale, getLocaleFromPath, getLocaleFromStorage, getLocaleFromStorageClient, getLocaleFromStorageServer, getLocaleLang, getLocaleName, getLocalizedContent, getLocalizedPath, getLocalizedUrl, getMarkdownMetadata, getMaskContent, getMissingLocalesContent, getMissingLocalesContentFromDictionary, getMultilingualDictionary, getMultilingualUrls, getNesting, getNodeChildren, getNodeType, getPathWithoutLocale, getPerLocaleDictionary, getPlural, getPrefix, getReplacedValuesContent, getRewritePath, getRewriteRules, getSplittedContent, getSplittedDictionaryContent, getTranslation, html, i18nextToIntlayerFormatter, icuToIntlayerFormatter, inlineRegex, insertion as insert, insertContentInDictionary, insertionPlugin, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToVueI18nFormatter, isSameKeyPath, isValidElement, list, localeDetector, localeFlatMap, localeMap, localeRecord, localeResolver, localeStorageOptions, markdown as md, mergeDictionaries, nesting as nest, nestedPlugin, normalizeAttributeKey, normalizeDictionaries, normalizeDictionary, normalizeWhitespace, number, orderDictionaries, parseBlock, parseCaptureInline, parseInline, parseSimpleInline, parseStyleAttribute, parseTableAlign, parseTableAlignCapture, parseTableCells, parseTableRow, parseYaml, parserFor, percentage, plural, pluralPlugin, presets, qualifies, relativeTime, removeContentNodeByKeyPath, renameContentNodeByKeyPath, renderFor, renderNothing, sanitizer, setLocaleInStorage, setLocaleInStorageClient, setLocaleInStorageServer, simpleInlineRegex, slugify, some, splitInsertionTemplate, startsWith, translation as t, translationPlugin, trimEnd, trimLeadingWhitespaceOutsideFences, unescapeString, units, unquote, updateNodeChildren, validateHTML, validateMarkdown, validatePrefix, vueI18nToIntlayerFormatter };
|
|
91
|
+
export { ATTRIBUTES_TO_SANITIZE, ATTRIBUTE_TO_NODE_PROP_MAP, ATTR_EXTRACTOR_R, BLOCKQUOTE_ALERT_R, BLOCKQUOTE_R, BLOCKQUOTE_TRIM_LEFT_MULTILINE_R, BLOCK_END_R, BREAK_LINE_R, BREAK_THEMATIC_R, BlockQuoteNode, BoldTextNode, BreakLineNode, BreakThematicNode, CAPTURE_LETTER_AFTER_HYPHEN, CODE_BLOCK_FENCED_R, CODE_BLOCK_R, CODE_INLINE_R, CONSECUTIVE_NEWLINE_R, CR_NEWLINE_R, CUSTOM_COMPONENT_R, CachedIntl, CachedIntl as Intl, CodeBlockNode, CodeFencedNode, CodeInlineNode, CompileOptions, ComponentOverrides, ConditionCond, ConditionContent, ConditionContentStates, CookieBuildAttributes, CustomComponentNode, DO_NOT_PROCESS_HTML_ELEMENTS, DURATION_DELAY_TRIGGER, DateTimePreset, DeepTransformContent, DotPath, ElementType, EnterFormat, EnumerationCond, EnumerationContent, EnumerationContentState, EscapedTextNode, FOOTNOTE_R, FOOTNOTE_REFERENCE_R, FORMFEED_R, FRONT_MATTER_R, FileCond, FileContent, FileContentConstructor, FootnoteNode, FootnoteReferenceNode, GFMTaskNode, GFM_TASK_R, Gender, GenderCond, GenderContent, GenderContentStates, GenerateSitemapOptions, GetNestingResult, GetPrefixOptions, GetPrefixResult, HEADING_ATX_COMPLIANT_R, HEADING_R, HEADING_SETEXT_R, HTMLCommentNode, HTMLContent, HTMLContentConstructor, HTMLNode, HTMLSelfClosingNode, HTMLTag, HTMLTagsType, HTMLValidationIssue, HTMLValidationResult, HTML_BLOCK_ELEMENT_R, HTML_CHAR_CODE_R, HTML_COMMENT_R, HTML_CUSTOM_ATTR_R, HTML_LEFT_TRIM_AMOUNT_R, HTML_SELF_CLOSING_ELEMENT_R, HTML_TAGS, HeadingNode, HeadingSetextNode, IInterpreterPlugin, IInterpreterPluginState, INLINE_SKIP_R, INTERPOLATION_R, ImageNode, InsertionCond, InsertionContent, InsertionContentConstructor, IsAny, ItalicTextNode, JsonValue, LINK_AUTOLINK_BARE_URL_R, LINK_AUTOLINK_R, LIST_LOOKBEHIND_R, LOOKAHEAD, LinkAngleBraceNode, LinkBareURLNode, LinkNode, ListType, LocaleStorage, LocaleStorageClient, LocaleStorageClientOptions, LocaleStorageOptions, LocaleStorageServer, LocaleStorageServerOptions, LocalizedPathResult, MarkdownContent, MarkdownContentConstructor, MarkdownContext, MarkdownOptions, MarkdownRuntime, HTMLValidationIssue as MarkdownValidationIssue, MarkdownValidationResult, MarkedTextNode, NAMED_CODES_TO_UNICODE, NP_TABLE_R, NestedCond, NestedContent, NestedContentState, NestedParser, NewlineNode, NodeProps, ORDERED, ORDERED_LIST_BULLET, ORDERED_LIST_ITEM_PREFIX, ORDERED_LIST_ITEM_PREFIX_R, ORDERED_LIST_ITEM_R, ORDERED_LIST_R, OrderedListNode, PARAGRAPH_R, ParagraphNode, ParseState, Parser, ParserResult, Plugins, PluralCategory, PluralCond, PluralContent, PluralContentState, PortableObject, Priority, PriorityValue, REFERENCE_IMAGE_OR_LINK, REFERENCE_IMAGE_R, REFERENCE_LINK_R, ReferenceImageNode, ReferenceLinkNode, ReferenceNode, RenderRuleHook, Rule, RuleOutput, RuleType, RuleTypeValue, Rules, SHORTCODE_R, SHOULD_RENDER_AS_BLOCK_R, SitemapUrlEntry, StrikethroughTextNode, TABLE_CENTER_ALIGN, TABLE_LEFT_ALIGN, TABLE_RIGHT_ALIGN, TABLE_TRIM_PIPES, TAB_R, TEXT_BOLD_R, TEXT_EMPHASIZED_R, TEXT_ESCAPED_R, TEXT_MARKED_R, TEXT_PLAIN_R, TEXT_STRIKETHROUGHED_R, TRIM_STARTING_NEWLINES, TableNode, TableSeparatorNode, TextNode, TranslationCond, TranslationContent, UNESCAPE_R, UNORDERED, UNORDERED_LIST_BULLET, UNORDERED_LIST_ITEM_PREFIX, UNORDERED_LIST_ITEM_PREFIX_R, UNORDERED_LIST_ITEM_R, UNORDERED_LIST_R, UnionKeys, UnorderedListNode, VOID_ELEMENTS, ValidDotPathsFor, ValueAtKey, WrappedIntl, allowInline, anyScopeRegex, attributeValueToNodePropValue, bindIntl, blockRegex, buildMaskPlugin, captureNothing, checkIsURLAbsolute, checkMissingLocalesPlugin, compact, compile, compileWithOptions, condition as cond, conditionPlugin, createCompiler, createRenderer, currency, cx, date, deepTransformNode, editDictionaryByKeyPath, enumeration as enu, enumerationPlugin, fallbackPlugin, file, fileContent, filePlugin, filterMissingTranslationsOnlyPlugin, filterTranslationsOnlyPlugin, findMatchingCondition, gender, genderPlugin, generateListItemPrefix, generateListItemPrefixRegex, generateListItemRegex, generateListRegex, generateSitemap, generateSitemapUrl, get, getBasePlugins, getBrowserLocale, getCachedIntl, getCanonicalPath, getCondition, getContent, getContentNodeByKeyPath, getCookie, getDefaultNode, getDictionary, getEmptyNode, getEnumeration, getFilterMissingTranslationsContent, getFilterMissingTranslationsDictionary, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary, getFilteredLocalesContent, getFilteredLocalesDictionary, getHTML, getHTMLTextDir, getInsertionValues, getInternalPath, getIntlayer, getLocale, getLocaleFromPath, getLocaleFromStorage, getLocaleFromStorageClient, getLocaleFromStorageServer, getLocaleLang, getLocaleName, getLocalizedContent, getLocalizedPath, getLocalizedUrl, getMarkdownMetadata, getMaskContent, getMissingLocalesContent, getMissingLocalesContentFromDictionary, getMultilingualDictionary, getMultilingualUrls, getNesting, getNodeChildren, getNodeType, getPathWithoutLocale, getPerLocaleDictionary, getPlural, getPrefix, getReplacedValuesContent, getRewritePath, getRewriteRules, getSplittedContent, getSplittedDictionaryContent, getTranslation, html, i18nextToIntlayerFormatter, icuToIntlayerFormatter, inlineRegex, insertion as insert, insertContentInDictionary, insertionPlugin, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToPortableObjectFormatter, intlayerToVueI18nFormatter, isSameKeyPath, isValidElement, list, localeDetector, localeFlatMap, localeMap, localeRecord, localeResolver, localeStorageOptions, markdown as md, mergeDictionaries, nesting as nest, nestedPlugin, normalizeAttributeKey, normalizeDictionaries, normalizeDictionary, normalizeWhitespace, number, orderDictionaries, parseBlock, parseCaptureInline, parseInline, parseSimpleInline, parseStyleAttribute, parseTableAlign, parseTableAlignCapture, parseTableCells, parseTableRow, parseYaml, parserFor, percentage, plural, pluralPlugin, portableObjectToIntlayerFormatter, presets, qualifies, relativeTime, removeContentNodeByKeyPath, renameContentNodeByKeyPath, renderFor, renderNothing, sanitizer, setLocaleInStorage, setLocaleInStorageClient, setLocaleInStorageServer, simpleInlineRegex, slugify, some, splitInsertionTemplate, startsWith, translation as t, translationPlugin, trimEnd, trimLeadingWhitespaceOutsideFences, unescapeString, units, unquote, updateNodeChildren, validateHTML, validateMarkdown, validatePrefix, vueI18nToIntlayerFormatter };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ICU.d.ts","names":[],"sources":["../../../src/messageFormat/ICU.ts"],"mappings":";;;KA6CY,SAAA,sCAKR,SAAA;EAAA,CACG,GAAA,WAAc,SAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"ICU.d.ts","names":[],"sources":["../../../src/messageFormat/ICU.ts"],"mappings":";;;KA6CY,SAAA,sCAKR,SAAA;EAAA,CACG,GAAA,WAAc,SAAA;AAAA;AAAA,cAkiBR,sBAAA,GACX,OAAA,EAAS,UAAA,gBACR,SAAA;AAAA,cAQU,sBAAA,GACX,OAAA,EAAS,UAAA,gBACR,SAAA"}
|