@intlayer/babel 9.3.0 → 9.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +24 -24
  2. package/dist/cjs/_virtual/_rolldown/runtime.cjs +1 -2
  3. package/dist/cjs/babel-plugin-intlayer-extract.cjs.map +1 -1
  4. package/dist/cjs/babel-plugin-intlayer-optimize.cjs +9 -5
  5. package/dist/cjs/babel-plugin-intlayer-optimize.cjs.map +1 -1
  6. package/dist/cjs/babel-plugin-intlayer-purge.cjs.map +1 -1
  7. package/dist/cjs/babel-plugin-intlayer-usage-analyzer.cjs +0 -1
  8. package/dist/cjs/babel-plugin-intlayer-usage-analyzer.cjs.map +1 -1
  9. package/dist/cjs/babelParser.cjs.map +1 -1
  10. package/dist/cjs/extractContent/babelProcessor.cjs +50 -49
  11. package/dist/cjs/extractContent/babelProcessor.cjs.map +1 -1
  12. package/dist/cjs/extractContent/contentWriter.cjs +3 -2
  13. package/dist/cjs/extractContent/contentWriter.cjs.map +1 -1
  14. package/dist/cjs/extractContent/extractContent.cjs +4 -2
  15. package/dist/cjs/extractContent/extractContent.cjs.map +1 -1
  16. package/dist/cjs/extractContent/processTsxFile.cjs.map +1 -1
  17. package/dist/cjs/extractContent/utils/constants.cjs +0 -1
  18. package/dist/cjs/extractContent/utils/constants.cjs.map +1 -1
  19. package/dist/cjs/extractContent/utils/detectPackageName.cjs.map +1 -1
  20. package/dist/cjs/extractContent/utils/extractDictionaryInfo.cjs +5 -3
  21. package/dist/cjs/extractContent/utils/extractDictionaryInfo.cjs.map +1 -1
  22. package/dist/cjs/extractContent/utils/extractDictionaryKey.cjs.map +1 -1
  23. package/dist/cjs/extractContent/utils/generateKey.cjs +0 -1
  24. package/dist/cjs/extractContent/utils/generateKey.cjs.map +1 -1
  25. package/dist/cjs/extractContent/utils/getExistingIntlayerInfo.cjs.map +1 -1
  26. package/dist/cjs/extractContent/utils/resolveDictionaryKey.cjs.map +1 -1
  27. package/dist/cjs/extractContent/utils/shouldExtract.cjs +0 -1
  28. package/dist/cjs/extractContent/utils/shouldExtract.cjs.map +1 -1
  29. package/dist/cjs/extractScriptBlocks.cjs.map +1 -1
  30. package/dist/cjs/getExtractPluginOptions.cjs +4 -2
  31. package/dist/cjs/getExtractPluginOptions.cjs.map +1 -1
  32. package/dist/cjs/getOptimizePluginOptions.cjs.map +1 -1
  33. package/dist/cjs/getPurgePluginOptions.cjs.map +1 -1
  34. package/dist/cjs/transformers.cjs.map +1 -1
  35. package/dist/esm/babel-plugin-intlayer-optimize.mjs +9 -5
  36. package/dist/esm/babel-plugin-intlayer-optimize.mjs.map +1 -1
  37. package/dist/esm/extractContent/babelProcessor.mjs +50 -49
  38. package/dist/esm/extractContent/babelProcessor.mjs.map +1 -1
  39. package/dist/esm/extractContent/contentWriter.mjs +3 -2
  40. package/dist/esm/extractContent/contentWriter.mjs.map +1 -1
  41. package/dist/esm/extractContent/extractContent.mjs +4 -2
  42. package/dist/esm/extractContent/extractContent.mjs.map +1 -1
  43. package/dist/esm/extractContent/utils/extractDictionaryInfo.mjs +5 -3
  44. package/dist/esm/extractContent/utils/extractDictionaryInfo.mjs.map +1 -1
  45. package/dist/esm/extractContent/utils/getExistingIntlayerInfo.mjs.map +1 -1
  46. package/dist/esm/getExtractPluginOptions.mjs +4 -2
  47. package/dist/esm/getExtractPluginOptions.mjs.map +1 -1
  48. package/package.json +9 -10
package/README.md CHANGED
@@ -47,27 +47,27 @@ With **per-locale content files**, **TypeScript autocompletion**, **tree-shakabl
47
47
 
48
48
  ## Keys benefits of Intlayer:
49
49
 
50
- | Feature | Description |
51
- | --------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
52
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/frameworks.png?raw=true" alt="Feature" width="700"> | **Cross-Frameworks Support**<br><br>Intlayer is compatible with all major frameworks and libraries, including Next.js, React, Vite, Vue.js, Nuxt, Preact, Express, and more. |
53
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/javascript_content_management.jpg?raw=true" alt="Feature" width="700"> | **JavaScript-Powered Content Management**<br><br>Harness the flexibility of JavaScript to define and manage your content efficiently. <br><br> - [Content declaration](https://intlayer.org/doc/concept/content) |
54
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/per_locale_content_declaration_file.png?raw=true" alt="Feature" width="700"> | **Per-Locale Content Declaration File**<br><br>Speed up your development by declaring your content once, before auto generation.<br><br> - [Per-Locale Content Declaration File](https://intlayer.org/doc/concept/per-locale-file) |
55
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/compiler.jpg?raw=true" alt="Feature" width="700"> | **Compiler**<br><br>The Intlayer Compiler extract automatically the content from the components and generate the dictionary files.<br><br> - [Compiler](https://intlayer.org/doc/compiler) |
56
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true" alt="Feature" width="700"> | **Type-Safe Environment**<br><br>Leverage TypeScript to ensure your content definitions and code are error-free, while also benefiting from IDE autocompletion.<br><br> - [TypeScript configuration](https://intlayer.org/doc/environment/vite-and-react#configure-typescript) |
57
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/config_file.png?raw=true" alt="Feature" width="700"> | **Simplified Setup**<br><br>Get up and running quickly with minimal configuration. Adjust settings for internationalization, routing, AI, build, and content handling with ease. <br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs) |
58
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/content_retrieval.png?raw=true" alt="Feature" width="700"> | **Simplified Content Retrieval**<br><br>No need to call your `t` function for each piece of content. Retrieve all your content directly using a single hook.<br><br> - [React integration](https://intlayer.org/doc/environment/create-react-app) |
59
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/server_component.png?raw=true" alt="Feature" width="700"> | **Consistent Server Component Implementation**<br><br>Perfectly suited for Next.js server components, use the same implementation for both client and server components, no need to pass your `t` function across each server component. <br><br> - [Server Components](https://intlayer.org/doc/environment/nextjs#step-7-utilize-content-in-your-code) |
60
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/file_tree.png?raw=true" alt="Feature" width="700"> | **Organized Codebase**<br><br>Keep your codebase more organized: 1 component = 1 dictionary in the same folder. Translations close to their respective components, enhance maintainability and clarity. <br><br> - [How Intlayer works](https://intlayer.org/doc/concept/how-works-intlayer) |
61
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/url_routing.png?raw=true" alt="Feature" width="700"> | **Enhanced Routing**<br><br>Full support of app routing, adapting seamlessly to complex application structures, for Next.js, React, Vite, Vue.js, etc.<br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs) |
62
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/markdown.png?raw=true" alt="Feature" width="700"> | **Markdown Support**<br><br>Import and interpret, locale files and remote Markdown for multilingual content like privacy policies, documentation, etc. Interpret and make Markdown metadata accessible in your code.<br><br> - [Content files](https://intlayer.org/doc/concept/content/file) |
63
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/visual_editor.png?raw=true" alt="Feature" width="700"> | **Free Visual Editor & CMS**<br><br>A free visual editor and CMS are available for content writers, removing the need for a localization platform. Keep your content synchronized using Git, or externalize it totally or partially with the CMS.<br><br> - [Intlayer Editor](https://intlayer.org/doc/concept/editor) <br> - [Intlayer CMS](https://intlayer.org/doc/concept/cms) |
64
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/bundle.png?raw=true" alt="Feature" width="700"> | **Tree-shakable Content**<br><br>Tree-shakable content, reducing the size of the final bundle. Loads content per component, excluding any unused content from your bundle. Supports lazy loading to enhance app loading efficiency. <br><br> - [App build optimization](https://intlayer.org/doc/concept/how-works-intlayer#app-build-optimization) |
65
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/static_rendering.png?raw=true" alt="Feature" width="700"> | **Static Rendering**<br><br>Doesn't block Static Rendering. <br><br> - [Next.js integration](https://intlayer.org/doc/environment/nextjs) |
66
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/AI_translation.png?raw=true" alt="Feature" width="700"> | **AI-Powered Translation**<br><br>Transform your website into 231 languages with just one click using Intlayer's advanced AI-powered translation tools using your own AI provider / API key. <br><br> - [CI/CD integration](https://intlayer.org/doc/concept/ci-cd) <br> - [Intlayer CLI](https://intlayer.org/doc/concept/cli) <br> - [Auto fill](https://intlayer.org/doc/concept/auto-fill) |
67
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/mcp.png?raw=true" alt="Feature" width="700"> | **MCP Server Integration**<br><br>Provides an MCP (Model Context Protocol) server for IDE automation, enabling seamless content management and i18n workflows directly within your development environment. <br><br> - [MCP Server](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/mcp_server.md) |
68
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/vscode_extension.png?raw=true" alt="Feature" width="700"> | **VSCode Extension**<br><br>Intlayer provides a VSCode extension to help you manage your content and translations, building your dictionaries, translating your content, and more. <br><br> - [VSCode Extension](https://intlayer.org/doc/vs-code-extension) |
69
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/interoperability.png?raw=true" alt="Feature" width="700"> | **Interoperability**<br><br>Allow interoperability with react-i18next, next-i18next, next-intl, react-intl, vue-i18n. <br><br> - [Intlayer and react-intl](https://intlayer.org/blog/intlayer-with-react-intl) <br> - [Intlayer and next-intl](https://intlayer.org/blog/intlayer-with-next-intl) <br> - [Intlayer and next-i18next](https://intlayer.org/blog/intlayer-with-next-i18next) <br> - [Intlayer and vue-i18n](https://intlayer.org/blog/intlayer-with-vue-i18n) |
70
- | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/benchmark.png?raw=true" alt="Feature" width="700"> | **Performances & Benchmark**<br><br>Uses advanced tree-shaking and dynamic loading to boost performances and keep the solution as light as possible. <br><br> - [Performances & Benchmark](https://intlayer.org/doc/benchmark) |
50
+ | Feature | Description |
51
+ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
52
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/frameworks.png?raw=true" alt="Feature" width="700"> | **Cross-Frameworks Support**<br><br>Intlayer is compatible with all major frameworks and libraries, including Next.js, React, Vite, Vue.js, Nuxt, Preact, Express, and more. |
53
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/javascript_content_management.jpg?raw=true" alt="Feature" width="700"> | **JavaScript-Powered Content Management**<br><br>Harness the flexibility of JavaScript to define and manage your content efficiently. <br><br> - [Content declaration](https://intlayer.org/doc/concept/content) |
54
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/per_locale_content_declaration_file.png?raw=true" alt="Feature" width="700"> | **Per-Locale Content Declaration File**<br><br>Speed up your development by declaring your content once, before auto generation.<br><br> - [Per-Locale Content Declaration File](https://intlayer.org/doc/concept/per-locale-file) |
55
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/compiler.jpg?raw=true" alt="Feature" width="700"> | **Compiler**<br><br>The Intlayer Compiler extract automatically the content from the components and generate the dictionary files.<br><br> - [Compiler](https://intlayer.org/doc/compiler) |
56
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true" alt="Feature" width="700"> | **Type-Safe Environment**<br><br>Leverage TypeScript to ensure your content definitions and code are error-free, while also benefiting from IDE autocompletion.<br><br> - [TypeScript configuration](https://intlayer.org/doc/environment/vite-and-react#configure-typescript) |
57
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/config_file.png?raw=true" alt="Feature" width="700"> | **Simplified Setup**<br><br>Get up and running quickly with minimal configuration. Adjust settings for internationalization, routing, AI, build, and content handling with ease. <br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs) |
58
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/content_retrieval.png?raw=true" alt="Feature" width="700"> | **Simplified Content Retrieval**<br><br>No need to call your `t` function for each piece of content. Retrieve all your content directly using a single hook.<br><br> - [React integration](https://intlayer.org/doc/environment/create-react-app) |
59
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/server_component.png?raw=true" alt="Feature" width="700"> | **Consistent Server Component Implementation**<br><br>Perfectly suited for Next.js server components, use the same implementation for both client and server components, no need to pass your `t` function across each server component. <br><br> - [Server Components](https://intlayer.org/doc/environment/nextjs#step-7-utilize-content-in-your-code) |
60
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/file_tree.png?raw=true" alt="Feature" width="700"> | **Organized Codebase**<br><br>Keep your codebase more organized: 1 component = 1 dictionary in the same folder. Translations close to their respective components, enhance maintainability and clarity. <br><br> - [How Intlayer works](https://intlayer.org/doc/concept/how-works-intlayer) |
61
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/url_routing.png?raw=true" alt="Feature" width="700"> | **Enhanced Routing**<br><br>Full support of app routing, adapting seamlessly to complex application structures, for Next.js, React, Vite, Vue.js, etc.<br><br> - [Explore Next.js integration](https://intlayer.org/doc/environment/nextjs) |
62
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/markdown.png?raw=true" alt="Feature" width="700"> | **Markdown Support**<br><br>Import and interpret, locale files and remote Markdown for multilingual content like privacy policies, documentation, etc. Interpret and make Markdown metadata accessible in your code.<br><br> - [Content files](https://intlayer.org/doc/concept/content/file) |
63
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/visual_editor.png?raw=true" alt="Feature" width="700"> | **Free Visual Editor & CMS**<br><br>A free visual editor and CMS are available for content writers, removing the need for a localization platform. Keep your content synchronized using Git, or externalize it totally or partially with the CMS.<br><br> - [Intlayer Editor](https://intlayer.org/doc/concept/editor) <br> - [Intlayer CMS](https://intlayer.org/doc/concept/cms) |
64
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/bundle.png?raw=true" alt="Feature" width="700"> | **Tree-shakable Content**<br><br>Tree-shakable content, reducing the size of the final bundle. Loads content per component, excluding any unused content from your bundle. Supports lazy loading to enhance app loading efficiency. <br><br> - [App build optimization](https://intlayer.org/doc/concept/how-works-intlayer#app-build-optimization) |
65
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/static_rendering.png?raw=true" alt="Feature" width="700"> | **Static Rendering**<br><br>Doesn't block Static Rendering. <br><br> - [Next.js integration](https://intlayer.org/doc/environment/nextjs) |
66
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/AI_translation.png?raw=true" alt="Feature" width="700"> | **AI-Powered Translation**<br><br>Transform your website into 231 languages with just one click using Intlayer's advanced AI-powered translation tools using your own AI provider / API key. <br><br> - [CI/CD integration](https://intlayer.org/doc/concept/ci-cd) <br> - [Intlayer CLI](https://intlayer.org/doc/concept/cli) <br> - [Auto fill](https://intlayer.org/doc/concept/auto-fill) |
67
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/mcp.png?raw=true" alt="Feature" width="700"> | **MCP Server Integration**<br><br>Provides an MCP (Model Context Protocol) server for IDE automation, enabling seamless content management and i18n workflows directly within your development environment. <br><br> - [MCP Server](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/mcp_server.md) |
68
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/vscode_extension.png?raw=true" alt="Feature" width="700"> | **VSCode Extension**<br><br>Intlayer provides a VSCode extension to help you manage your content and translations, building your dictionaries, translating your content, and more. <br><br> - [VSCode Extension](https://intlayer.org/doc/vs-code-extension) |
69
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/interoperability.png?raw=true" alt="Feature" width="700"> | **Interoperability**<br><br>Allow interoperability with react-i18next, next-i18next, next-intl, react-intl, vue-i18n. <br><br> - [Intlayer and react-intl](https://intlayer.org/blog/intlayer-with-react-intl) <br> - [Intlayer and next-intl](https://intlayer.org/blog/intlayer-with-next-intl) <br> - [Intlayer and next-i18next](https://intlayer.org/blog/intlayer-with-next-i18next) <br> - [Intlayer and vue-i18n](https://intlayer.org/blog/intlayer-with-vue-i18n) <br> - [Intlayer compat adapters](https://intlayer.org/doc/compatibility) |
70
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/benchmark.png?raw=true" alt="Feature" width="700"> | **Performances & Benchmark**<br><br>Uses advanced tree-shaking and dynamic loading to boost performances and keep the solution as light as possible. <br><br> - [Performances & Benchmark](https://intlayer.org/doc/benchmark) |
71
71
 
72
72
  ---
73
73
 
@@ -162,7 +162,7 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
162
162
  <li><a href="https://intlayer.org/doc/concept/cms" rel=''>Intlayer CMS</a></li>
163
163
  <li><a href="https://intlayer.org/doc/concept/content" rel=''>Dictionary</a>
164
164
  <ul>
165
- <li><a href="https://intlayer.org/doc/concept/content/per-locale-file" rel=''>Per-Locale Content Declaration File</a></li>
165
+ <li><a href="https://intlayer.org/doc/concept/per-locale-file" rel=''>Per-Locale Content Declaration File</a></li>
166
166
  <li><a href="https://intlayer.org/doc/concept/content/translation" rel=''>Translation</a></li>
167
167
  <li><a href="https://intlayer.org/doc/concept/content/enumeration" rel=''>Enumeration</a></li>
168
168
  <li><a href="https://intlayer.org/doc/concept/content/condition" rel=''>Condition</a></li>
@@ -183,7 +183,7 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
183
183
  <ul>
184
184
  <li><a href="https://intlayer.org/doc/environment/nextjs/15" rel=''>Next.js 15</a></li>
185
185
  <li><a href="https://intlayer.org/doc/environment/nextjs/14" rel=''>Next.js 14 (App Router)</a></li>
186
- <li><a href="https://intlayer.org/doc/environment/nextjs/next-with-Page-Router" rel=''>Next.js Page Router</a></li>
186
+ <li><a href="https://intlayer.org/doc/environment/nextjs/next-with-page-router" rel=''>Next.js Page Router</a></li>
187
187
  <li><a href="https://intlayer.org/doc/environment/nextjs/compiler" rel=''>Next.js using Compiler</a></li>
188
188
  </ul>
189
189
  </li>
@@ -212,7 +212,7 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
212
212
  <li><a href="https://intlayer.org/doc/environment/sveltekit" rel=''>SvelteKit</a></li>
213
213
  <li><a href="https://intlayer.org/doc/environment/vite-and-preact" rel=''>Vite + Preact</a></li>
214
214
  <li><a href="https://intlayer.org/doc/environment/vite-and-vue" rel=''>Vite + Vue</a></li>
215
- <li><a href="https://intlayer.org/doc/environment/vite-and-nuxt" rel=''>Vite + Nuxt</a></li>
215
+ <li><a href="https://intlayer.org/doc/environment/nuxt-and-vue" rel=''>Vite + Nuxt</a></li>
216
216
  <li><a href="https://intlayer.org/doc/environment/vite-and-solid" rel=''>Vite + Solid</a></li>
217
217
  <li><a href="https://intlayer.org/doc/environment/angular" rel=''>Angular</a></li>
218
218
  <li>
@@ -19,11 +19,10 @@ var __copyProps = (to, from, except, desc) => {
19
19
  }
20
20
  return to;
21
21
  };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
23
23
  value: mod,
24
24
  enumerable: true
25
25
  }) : target, mod));
26
26
 
27
27
  //#endregion
28
-
29
28
  exports.__toESM = __toESM;
@@ -1 +1 @@
1
- {"version":3,"file":"babel-plugin-intlayer-extract.cjs","names":["getNormalizedFilesListSet","detectPackageName","extractContentSync","ANSIColors"],"sources":["../../src/babel-plugin-intlayer-extract.ts"],"sourcesContent":["import { relative } from 'node:path';\nimport type { PluginObject, PluginPass } from '@babel/core';\nimport { parse } from '@babel/parser';\nimport type * as BabelTypes from '@babel/types';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizePath, getAppLogger } from '@intlayer/config/logger';\nimport { normalizePath } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { FilePathPattern } from '@intlayer/types/filePathPattern';\nimport { extractContentSync } from './extractContent/extractContent';\nimport type { PackageName } from './extractContent/utils/constants';\nimport { detectPackageName } from './extractContent/utils/detectPackageName';\nimport { getNormalizedFilesListSet } from './normalizedFilesList';\n\nexport type ExtractResult = {\n dictionaryKey: string;\n filePath: string;\n content: Record<string, string>;\n locale: Locale;\n};\n\nexport type ExtractPluginOptions = {\n packageName?: PackageName;\n filesList: string[];\n enabled: boolean;\n\n shouldExtract?: (text: string) => boolean;\n configuration: IntlayerConfig;\n /**\n * Callback invoked for each extracted dictionary key/content pair.\n * Used by `getExtractPluginOptions` to write dictionaries to disk.\n * May be async — the plugin will fire-and-forget (Babel transforms are sync).\n */\n onExtract?: (result: ExtractResult) => void | Promise<void>;\n /**\n * Defines the output files path.\n */\n output?: FilePathPattern;\n};\n\ntype State = PluginPass & { opts: ExtractPluginOptions };\n\n/**\n * Babel plugin that extracts translatable content from source files and\n * injects Intlayer hooks (`useIntlayer` / `getIntlayer`) automatically.\n *\n * Designed for use with Babel-based build tools such as Next.js and Webpack.\n *\n * @example babel.config.js\n * ```js\n * const { intlayerExtractBabelPlugin, getExtractPluginOptions } = require('@intlayer/babel');\n * module.exports = {\n * presets: ['next/babel'],\n * plugins: [\n * [intlayerExtractBabelPlugin, getExtractPluginOptions()],\n * ],\n * };\n * ```\n */\nexport const intlayerExtractBabelPlugin = (_babel: {\n types: typeof BabelTypes;\n}): PluginObject<State> => {\n return {\n name: 'babel-plugin-intlayer-extract',\n\n visitor: {\n Program: {\n enter(programPath, state) {\n const opts = state.opts;\n\n // Merge plugin options with the unified compiler config\n const isEnabled = opts.enabled;\n\n if (isEnabled === false) return;\n\n const filename = state.file.opts.filename;\n\n if (!filename) return;\n\n // Compare as POSIX paths (babel filenames use OS separators on Windows).\n if (\n opts.filesList &&\n !getNormalizedFilesListSet(opts.filesList).has(\n normalizePath(filename)\n )\n ) {\n return;\n }\n\n const fileCode: string = state.file.code ?? '';\n if (!fileCode) return;\n\n const appLogger = getAppLogger(opts.configuration);\n const packageName = opts.packageName ?? detectPackageName(filename);\n\n const { saveComponents } = opts.configuration.compiler;\n\n const result = extractContentSync(filename, packageName, {\n configuration: opts.configuration,\n code: fileCode,\n onExtract: (extractResult: {\n key: string;\n content: Record<string, string>;\n }) => {\n if (opts.onExtract) {\n opts.onExtract({\n dictionaryKey: extractResult.key,\n filePath: filename,\n content: extractResult.content,\n locale: opts.configuration.internationalization.defaultLocale,\n });\n }\n },\n declarationOnly: !saveComponents,\n });\n\n if (!result) return;\n\n const { transformedCode: modifiedCode } = result;\n\n if (!modifiedCode) return;\n\n // Replace the Babel AST with the transformed code by re-parsing it.\n // This lets Babel serialise the injected hooks/imports through its\n // own code generator, preserving compatibility with other plugins.\n try {\n const newAst = parse(modifiedCode, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n\n programPath.node.body = newAst.program.body;\n programPath.node.directives = newAst.program.directives;\n\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} Extracted content from ${colorizePath(relative(opts.configuration.system.baseDir, filename))}`,\n { level: 'debug' }\n );\n } catch (error) {\n appLogger(\n [\n `Failed to parse transformed code for ${colorizePath(relative(opts.configuration.system.baseDir, filename))}:`,\n error,\n ],\n { level: 'error' }\n );\n }\n },\n },\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DA,MAAa,8BAA8B,WAEhB;CACzB,OAAO;EACL,MAAM;EAEN,SAAS,EACP,SAAS,EACP,MAAM,aAAa,OAAO;GACxB,MAAM,OAAO,MAAM;GAKnB,IAFkB,KAAK,YAEL,OAAO;GAEzB,MAAM,WAAW,MAAM,KAAK,KAAK;GAEjC,IAAI,CAAC,UAAU;GAGf,IACE,KAAK,aACL,CAACA,sDAA0B,KAAK,SAAS,CAAC,CAAC,8CAC3B,QAAQ,CACxB,GAEA;GAGF,MAAM,WAAmB,MAAM,KAAK,QAAQ;GAC5C,IAAI,CAAC,UAAU;GAEf,MAAM,sDAAyB,KAAK,aAAa;GACjD,MAAM,cAAc,KAAK,eAAeC,iEAAkB,QAAQ;GAElE,MAAM,EAAE,mBAAmB,KAAK,cAAc;GAE9C,MAAM,SAASC,yDAAmB,UAAU,aAAa;IACvD,eAAe,KAAK;IACpB,MAAM;IACN,YAAY,kBAGN;KACJ,IAAI,KAAK,WACP,KAAK,UAAU;MACb,eAAe,cAAc;MAC7B,UAAU;MACV,SAAS,cAAc;MACvB,QAAQ,KAAK,cAAc,qBAAqB;KAClD,CAAC;IAEL;IACA,iBAAiB,CAAC;GACpB,CAAC;GAED,IAAI,CAAC,QAAQ;GAEb,MAAM,EAAE,iBAAiB,iBAAiB;GAE1C,IAAI,CAAC,cAAc;GAKnB,IAAI;IACF,MAAM,kCAAe,cAAc;KACjC,YAAY;KACZ,SAAS,CAAC,OAAO,YAAY;IAC/B,CAAC;IAED,YAAY,KAAK,OAAO,OAAO,QAAQ;IACvC,YAAY,KAAK,aAAa,OAAO,QAAQ;IAE7C,UACE,yCAAY,aAAaC,wBAAW,SAAS,EAAE,4FAAgD,KAAK,cAAc,OAAO,SAAS,QAAQ,CAAC,KAC3I,EAAE,OAAO,QAAQ,CACnB;GACF,SAAS,OAAO;IACd,UACE,CACE,0GAA8D,KAAK,cAAc,OAAO,SAAS,QAAQ,CAAC,EAAE,IAC5G,KACF,GACA,EAAE,OAAO,QAAQ,CACnB;GACF;EACF,EACF,EACF;CACF;AACF"}
1
+ {"version":3,"file":"babel-plugin-intlayer-extract.cjs","names":["getNormalizedFilesListSet","normalizePath","getAppLogger","detectPackageName","extractContentSync","parse","colorize","ANSIColors","colorizePath","relative"],"sources":["../../src/babel-plugin-intlayer-extract.ts"],"sourcesContent":["import { relative } from 'node:path';\nimport type { PluginObject, PluginPass } from '@babel/core';\nimport { parse } from '@babel/parser';\nimport type * as BabelTypes from '@babel/types';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizePath, getAppLogger } from '@intlayer/config/logger';\nimport { normalizePath } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { FilePathPattern } from '@intlayer/types/filePathPattern';\nimport { extractContentSync } from './extractContent/extractContent';\nimport type { PackageName } from './extractContent/utils/constants';\nimport { detectPackageName } from './extractContent/utils/detectPackageName';\nimport { getNormalizedFilesListSet } from './normalizedFilesList';\n\nexport type ExtractResult = {\n dictionaryKey: string;\n filePath: string;\n content: Record<string, string>;\n locale: Locale;\n};\n\nexport type ExtractPluginOptions = {\n packageName?: PackageName;\n filesList: string[];\n enabled: boolean;\n\n shouldExtract?: (text: string) => boolean;\n configuration: IntlayerConfig;\n /**\n * Callback invoked for each extracted dictionary key/content pair.\n * Used by `getExtractPluginOptions` to write dictionaries to disk.\n * May be async — the plugin will fire-and-forget (Babel transforms are sync).\n */\n onExtract?: (result: ExtractResult) => void | Promise<void>;\n /**\n * Defines the output files path.\n */\n output?: FilePathPattern;\n};\n\ntype State = PluginPass & { opts: ExtractPluginOptions };\n\n/**\n * Babel plugin that extracts translatable content from source files and\n * injects Intlayer hooks (`useIntlayer` / `getIntlayer`) automatically.\n *\n * Designed for use with Babel-based build tools such as Next.js and Webpack.\n *\n * @example babel.config.js\n * ```js\n * const { intlayerExtractBabelPlugin, getExtractPluginOptions } = require('@intlayer/babel');\n * module.exports = {\n * presets: ['next/babel'],\n * plugins: [\n * [intlayerExtractBabelPlugin, getExtractPluginOptions()],\n * ],\n * };\n * ```\n */\nexport const intlayerExtractBabelPlugin = (_babel: {\n types: typeof BabelTypes;\n}): PluginObject<State> => {\n return {\n name: 'babel-plugin-intlayer-extract',\n\n visitor: {\n Program: {\n enter(programPath, state) {\n const opts = state.opts;\n\n // Merge plugin options with the unified compiler config\n const isEnabled = opts.enabled;\n\n if (isEnabled === false) return;\n\n const filename = state.file.opts.filename;\n\n if (!filename) return;\n\n // Compare as POSIX paths (babel filenames use OS separators on Windows).\n if (\n opts.filesList &&\n !getNormalizedFilesListSet(opts.filesList).has(\n normalizePath(filename)\n )\n ) {\n return;\n }\n\n const fileCode: string = state.file.code ?? '';\n if (!fileCode) return;\n\n const appLogger = getAppLogger(opts.configuration);\n const packageName = opts.packageName ?? detectPackageName(filename);\n\n const { saveComponents } = opts.configuration.compiler;\n\n const result = extractContentSync(filename, packageName, {\n configuration: opts.configuration,\n code: fileCode,\n onExtract: (extractResult: {\n key: string;\n content: Record<string, string>;\n }) => {\n if (opts.onExtract) {\n opts.onExtract({\n dictionaryKey: extractResult.key,\n filePath: filename,\n content: extractResult.content,\n locale: opts.configuration.internationalization.defaultLocale,\n });\n }\n },\n declarationOnly: !saveComponents,\n });\n\n if (!result) return;\n\n const { transformedCode: modifiedCode } = result;\n\n if (!modifiedCode) return;\n\n // Replace the Babel AST with the transformed code by re-parsing it.\n // This lets Babel serialise the injected hooks/imports through its\n // own code generator, preserving compatibility with other plugins.\n try {\n const newAst = parse(modifiedCode, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n\n programPath.node.body = newAst.program.body;\n programPath.node.directives = newAst.program.directives;\n\n appLogger(\n `${colorize('Compiler:', ANSIColors.GREY_DARK)} Extracted content from ${colorizePath(relative(opts.configuration.system.baseDir, filename))}`,\n { level: 'debug' }\n );\n } catch (error) {\n appLogger(\n [\n `Failed to parse transformed code for ${colorizePath(relative(opts.configuration.system.baseDir, filename))}:`,\n error,\n ],\n { level: 'error' }\n );\n }\n },\n },\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DA,MAAa,8BAA8B,WAEhB;CACzB,OAAO;EACL,MAAM;EAEN,SAAS,EACP,SAAS,EACP,MAAM,aAAa,OAAO;GACxB,MAAM,OAAO,MAAM;GAKnB,IAFkB,KAAK,YAEL,OAAO;GAEzB,MAAM,WAAW,MAAM,KAAK,KAAK;GAEjC,IAAI,CAAC,UAAU;GAGf,IACE,KAAK,aACL,CAACA,sDAA0B,KAAK,SAAS,CAAC,CAAC,QACzCC,sCAAc,QAAQ,CACxB,GAEA;GAGF,MAAM,WAAmB,MAAM,KAAK,QAAQ;GAC5C,IAAI,CAAC,UAAU;GAEf,MAAM,gBAAYC,sCAAa,KAAK,aAAa;GACjD,MAAM,cAAc,KAAK,eAAeC,iEAAkB,QAAQ;GAElE,MAAM,EAAE,mBAAmB,KAAK,cAAc;GAE9C,MAAM,SAASC,yDAAmB,UAAU,aAAa;IACvD,eAAe,KAAK;IACpB,MAAM;IACN,YAAY,kBAGN;KACJ,IAAI,KAAK,WACP,KAAK,UAAU;MACb,eAAe,cAAc;MAC7B,UAAU;MACV,SAAS,cAAc;MACvB,QAAQ,KAAK,cAAc,qBAAqB;KAClD,CAAC;IAEL;IACA,iBAAiB,CAAC;GACpB,CAAC;GAED,IAAI,CAAC,QAAQ;GAEb,MAAM,EAAE,iBAAiB,iBAAiB;GAE1C,IAAI,CAAC,cAAc;GAKnB,IAAI;IACF,MAAM,aAASC,qBAAM,cAAc;KACjC,YAAY;KACZ,SAAS,CAAC,OAAO,YAAY;IAC/B,CAAC;IAED,YAAY,KAAK,OAAO,OAAO,QAAQ;IACvC,YAAY,KAAK,aAAa,OAAO,QAAQ;IAE7C,UACE,OAAGC,kCAAS,aAAaC,wBAAW,SAAS,EAAE,8BAA0BC,0CAAaC,oBAAS,KAAK,cAAc,OAAO,SAAS,QAAQ,CAAC,KAC3I,EAAE,OAAO,QAAQ,CACnB;GACF,SAAS,OAAO;IACd,UACE,CACE,4CAAwCD,0CAAaC,oBAAS,KAAK,cAAc,OAAO,SAAS,QAAQ,CAAC,EAAE,IAC5G,KACF,GACA,EAAE,OAAO,QAAQ,CACnB;GACF;EACF,EACF,EACF;CACF;AACF"}
@@ -394,9 +394,11 @@ const intlayerOptimizeBabelPlugin = (babel) => {
394
394
  const { dictionaryKey, keyPrefix } = splitNamespace(namespaceMatch.fullNamespace);
395
395
  const compatOverrideMode = state.opts.dictionaryModeMap?.[dictionaryKey];
396
396
  let compatCallMode = "static";
397
- if (compatUseDynamicHelpers) if (compatOverrideMode === "dynamic" || compatOverrideMode === "fetch") compatCallMode = compatOverrideMode;
398
- else if (state.opts.importMode === "dynamic" || state.opts.importMode === "fetch") compatCallMode = state.opts.importMode;
399
- else compatCallMode = "dynamic";
397
+ if (compatUseDynamicHelpers) {
398
+ if (compatOverrideMode === "dynamic" || compatOverrideMode === "fetch") compatCallMode = compatOverrideMode;
399
+ else if (state.opts.importMode === "dynamic" || state.opts.importMode === "fetch") compatCallMode = state.opts.importMode;
400
+ else compatCallMode = "dynamic";
401
+ }
400
402
  let dictionaryIdent;
401
403
  if (compatCallMode === "static") {
402
404
  let staticIdent = state._newStaticImports?.get(dictionaryKey);
@@ -424,8 +426,10 @@ const intlayerOptimizeBabelPlugin = (babel) => {
424
426
  callArguments.splice(insertAt, 0, ...insertedArguments);
425
427
  } else if (compatCallMode !== "static") callArguments.unshift(t.identifier(dictionaryIdent.name), t.stringLiteral(dictionaryKey));
426
428
  else callArguments.unshift(t.identifier(dictionaryIdent.name));
427
- if (namespaceMatch.optionProperty && namespaceMatch.optionsObject) if (keyPrefix) namespaceMatch.optionProperty.value = t.stringLiteral(keyPrefix);
428
- else namespaceMatch.optionsObject.properties = namespaceMatch.optionsObject.properties.filter((property) => property !== namespaceMatch.optionProperty);
429
+ if (namespaceMatch.optionProperty && namespaceMatch.optionsObject) {
430
+ if (keyPrefix) namespaceMatch.optionProperty.value = t.stringLiteral(keyPrefix);
431
+ else namespaceMatch.optionsObject.properties = namespaceMatch.optionsObject.properties.filter((property) => property !== namespaceMatch.optionProperty);
432
+ }
429
433
  return;
430
434
  }
431
435
  const originalImportedName = state._callerMap?.get(callee.name);
@@ -1 +1 @@
1
- {"version":3,"file":"babel-plugin-intlayer-optimize.cjs","names":["getNormalizedFilesListSet"],"sources":["../../src/babel-plugin-intlayer-optimize.ts"],"sourcesContent":["import { dirname, join, relative } from 'node:path';\nimport type { NodePath, PluginObject, PluginPass } from '@babel/core';\nimport type * as BabelTypes from '@babel/types';\nimport {\n type CallerDescriptor,\n getRewritableCallers,\n} from '@intlayer/config/callers';\nimport { normalizePath } from '@intlayer/config/utils';\nimport { getPathHash } from '@intlayer/engine/utils';\nimport { getNormalizedFilesListSet } from './normalizedFilesList';\n\nconst PACKAGE_LIST = [\n 'intlayer',\n '@intlayer/core',\n '@intlayer/core/interpreter',\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'svelte-intlayer',\n 'vue-intlayer',\n 'angular-intlayer',\n 'preact-intlayer',\n 'solid-intlayer',\n 'lit-intlayer',\n 'vanilla-intlayer',\n];\n\nconst CALLER_LIST = ['useIntlayer', 'getIntlayer'] as const;\n\n/**\n * Packages that support dynamic import\n */\nconst PACKAGE_LIST_DYNAMIC = [\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'preact-intlayer',\n 'vue-intlayer',\n 'solid-intlayer',\n 'svelte-intlayer',\n 'angular-intlayer',\n 'lit-intlayer',\n 'vanilla-intlayer',\n] as const;\n\nconst STATIC_IMPORT_FUNCTION = {\n getIntlayer: 'getDictionary',\n useIntlayer: 'useDictionary',\n} as const;\n\nconst DYNAMIC_IMPORT_FUNCTION = {\n useIntlayer: 'useDictionaryDynamic',\n} as const;\n\n/** Import rename table applied when the helper plan for a package is `dynamic`. */\nconst DYNAMIC_HELPER_MAP: Record<string, string> = {\n ...STATIC_IMPORT_FUNCTION,\n ...DYNAMIC_IMPORT_FUNCTION,\n};\n\n/**\n * Packages whose SSR-static `useDictionary` lives in a `/server` subpath\n * because it differs from the root one. Solid's reserves one hydration\n * resource slot so hydration ids stay aligned with the client's\n * `useDictionaryDynamic`; for other frameworks the root `useDictionary` is\n * already the correct SSR-static implementation.\n */\nconst SSR_STATIC_IMPORT_SOURCE: Partial<Record<string, string>> = {\n 'solid-intlayer': 'solid-intlayer/server',\n};\n\ntype CallerName = (typeof CALLER_LIST)[number];\ntype ImportMode = 'static' | 'dynamic' | 'fetch';\n\n/**\n * Options for the optimization Babel plugin\n */\nexport type OptimizePluginOptions = {\n /**\n * If false, the plugin will not apply any transformation.\n */\n optimize?: boolean;\n /**\n * The path to the dictionaries directory.\n */\n dictionariesDir: string;\n /**\n * The path to the dictionaries entry file.\n */\n dictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries entry file.\n */\n unmergedDictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries directory.\n */\n unmergedDictionariesDir: string;\n /**\n * The path to the dictionaries directory.\n */\n dynamicDictionariesDir: string;\n /**\n * The path to the dynamic dictionaries entry file.\n */\n dynamicDictionariesEntryPath: string;\n /**\n * The path to the fetch dictionaries directory.\n */\n fetchDictionariesDir: string;\n /**\n * The path to the fetch dictionaries entry file.\n */\n fetchDictionariesEntryPath: string;\n /**\n * If true, the plugin will replace the dictionary entry file with `export default {}`.\n */\n replaceDictionaryEntry: boolean;\n /**\n * Keys of the dictionaries that reference other dictionaries through\n * `nest()`.\n *\n * For those, the injected static import points at the generated companion\n * module (`<dictionariesDir>/nested/<key>.mjs`) instead of the raw JSON. The\n * companion re-exports the dictionary with its nest targets attached, so\n * `getNesting` resolves them from that local reference rather than from the\n * global registry this plugin empties — and each target lands in the chunk of\n * the dictionary referencing it.\n *\n * Dynamic and fetch modes need nothing here: their generated loaders already\n * attach the same targets per locale.\n */\n nestingDictionaryKeys?: string[];\n /**\n * If true, the plugin will activate the dynamic import of the dictionaries. It will rely on Suspense to load the dictionaries.\n */\n importMode: 'static' | 'dynamic' | 'fetch' | undefined;\n /**\n * Map of dictionary keys to their specific import mode.\n */\n dictionaryModeMap?: Record<\n string,\n 'static' | 'dynamic' | 'fetch' | undefined\n >;\n /**\n * Files list to traverse.\n */\n filesList: string[];\n /**\n * Whether the current transform is for an SSR bundle.\n */\n isServer?: boolean;\n /**\n * Compat-adapter caller descriptors injected by the compat packages'\n * bundler plugins (e.g. `@intlayer/react-i18next/plugin`).\n *\n * Callers carrying `staticReplacement` / `dynamicReplacement` are rewritten\n * the same way as native `useIntlayer` calls: the namespace string argument\n * is replaced by a pre-imported dictionary object and the import specifier\n * is re-pointed to the dictionary-accepting variant, e.g.\n * `useTranslation('about')` → `useDictionary(_dictHash)`.\n *\n * No compat-specific name is hard-coded in this plugin — the whole rewrite\n * is driven by these descriptors.\n */\n compatCallers?: CallerDescriptor[];\n};\n\ntype State = PluginPass & {\n opts: OptimizePluginOptions;\n /** map key → generated ident (per-file) for static imports */\n _newStaticImports?: Map<string, BabelTypes.Identifier>;\n /** map key → generated ident (per-file) for dynamic imports */\n _newDynamicImports?: Map<string, BabelTypes.Identifier>;\n /** whether the current file imported *any* intlayer package */\n _hasValidImport?: boolean;\n /** map from local identifier name to the imported intlayer func name ('useIntlayer' | 'getIntlayer') */\n _callerMap?: Map<string, (typeof CALLER_LIST)[number]>;\n /** map from local identifier name to the intlayer package it was imported from */\n _callerPackageMap?: Map<string, string>;\n /** map from local identifier name to the compat caller descriptor it was imported as */\n _compatCallerMap?: Map<string, CallerDescriptor>;\n /** whether the current file *is* the dictionaries entry file */\n _isDictEntry?: boolean;\n /** whether the current file is included in the filesList */\n _isIncluded?: boolean;\n};\n\n/**\n * Replicates the xxHash64 → Base-62 algorithm used by the SWC version\n * and prefixes an underscore so the generated identifiers never collide\n * with user-defined ones.\n */\nconst makeIdent = (\n key: string,\n t: typeof BabelTypes\n): BabelTypes.Identifier => {\n const hash = getPathHash(key);\n return t.identifier(`_${hash}`);\n};\n\n/**\n * Builds the module specifier pointing at `targetPath` from `fromFile`, with\n * forward slashes and an explicit `./` prefix so bundlers never treat it as a\n * bare package specifier.\n */\nconst toRelativeSpecifier = (fromFile: string, targetPath: string): string => {\n // Fix windows path\n const relativePath = normalizePath(relative(dirname(fromFile), targetPath));\n\n // Fix relative path\n if (!relativePath.startsWith('./') && !relativePath.startsWith('../')) {\n return `./${relativePath}`;\n }\n\n return relativePath;\n};\n\n/**\n * Subdirectory of the compiled dictionaries holding the companion modules that\n * re-export a dictionary with its `nest()` targets attached. Mirrors\n * `NESTED_DICTIONARIES_SUBDIR` in `@intlayer/engine`.\n */\nconst NESTED_DICTIONARIES_SUBDIR = 'nested';\n\nconst computeImport = (\n fromFile: string,\n dictionariesDir: string,\n dynamicDictionariesDir: string,\n fetchDictionariesDir: string,\n key: string,\n importMode: 'static' | 'dynamic' | 'fetch',\n hasNestedDictionaries = false\n): string => {\n // Static mode is the only one needing the companion: the dynamic and fetch\n // loaders already attach the nest targets per locale.\n let dictionaryPath = hasNestedDictionaries\n ? join(dictionariesDir, NESTED_DICTIONARIES_SUBDIR, `${key}.mjs`)\n : join(dictionariesDir, `${key}.json`);\n\n if (importMode === 'fetch') {\n dictionaryPath = join(fetchDictionariesDir, `${key}.mjs`);\n }\n\n if (importMode === 'dynamic') {\n dictionaryPath = join(dynamicDictionariesDir, `${key}.mjs`);\n }\n\n return toRelativeSpecifier(fromFile, dictionaryPath);\n};\n\nconst getKeyFromArgument = (\n arg: BabelTypes.Node | null | undefined,\n t: typeof BabelTypes\n): string | undefined => {\n if (arg && t.isStringLiteral(arg)) {\n return arg.value;\n }\n\n if (\n arg &&\n t.isTemplateLiteral(arg) &&\n arg.expressions.length === 0 &&\n arg.quasis.length === 1\n ) {\n return arg.quasis[0]?.value.cooked ?? arg.quasis[0]?.value.raw;\n }\n\n return undefined;\n};\n\nconst isCallerName = (name: string): name is CallerName =>\n CALLER_LIST.includes(name as CallerName);\n\n/**\n * Splits a namespace string at the first `.` to separate the dictionary key\n * from an optional key prefix for nested namespaces, mirroring the SWC\n * plugin's `split_namespace`.\n *\n * `'about'` → `{ dictionaryKey: 'about', keyPrefix: '' }`\n * `'about.counter'` → `{ dictionaryKey: 'about', keyPrefix: 'counter' }`\n */\nconst splitNamespace = (\n namespace: string\n): { dictionaryKey: string; keyPrefix: string } => {\n const dotPosition = namespace.indexOf('.');\n if (dotPosition === -1) return { dictionaryKey: namespace, keyPrefix: '' };\n return {\n dictionaryKey: namespace.slice(0, dotPosition),\n keyPrefix: namespace.slice(dotPosition + 1),\n };\n};\n\n/**\n * Result of statically resolving the namespace of a compat caller call-site.\n */\ntype CompatNamespaceMatch = {\n /** The full namespace string, e.g. `'about.counter'`. */\n fullNamespace: string;\n /** Index of the positional namespace argument, when read from an argument. */\n argumentIndex?: number;\n /**\n * The options-object property holding the namespace, when read from an\n * option. The rewrite mutates it in place (key-prefix remainder) or removes\n * it from `optionsObject`.\n */\n optionProperty?: BabelTypes.ObjectProperty;\n /** The options object owning `optionProperty`. */\n optionsObject?: BabelTypes.ObjectExpression;\n};\n\n/**\n * Statically resolves the namespace of a compat caller call-site from its\n * descriptor's `namespaceSources` (argument / option / fixed — the\n * per-message-id `path-first-segment` form cannot bind one dictionary to the\n * call site and is skipped). Returns `undefined` when the namespace is absent\n * or dynamic, in which case the call is left untouched and resolves through\n * the runtime dictionary registry.\n */\nconst resolveCompatNamespaceMatch = (\n t: typeof BabelTypes,\n callArguments: BabelTypes.CallExpression['arguments'],\n descriptor: CallerDescriptor\n): CompatNamespaceMatch | undefined => {\n for (const source of descriptor.namespaceSources) {\n if (source.from === 'fixed') {\n return { fullNamespace: source.value };\n }\n\n if (source.from === 'argument') {\n const namespace = getKeyFromArgument(callArguments[source.index], t);\n if (namespace !== undefined) {\n return { fullNamespace: namespace, argumentIndex: source.index };\n }\n continue;\n }\n\n if (source.from === 'option') {\n const optionsArgument = callArguments[source.argumentIndex];\n if (!optionsArgument || !t.isObjectExpression(optionsArgument)) continue;\n\n for (const property of optionsArgument.properties) {\n if (!t.isObjectProperty(property)) continue;\n const keyMatches =\n (t.isIdentifier(property.key) &&\n property.key.name === source.property) ||\n (t.isStringLiteral(property.key) &&\n property.key.value === source.property);\n if (!keyMatches) continue;\n\n const namespace = getKeyFromArgument(property.value, t);\n if (namespace !== undefined) {\n return {\n fullNamespace: namespace,\n optionProperty: property,\n optionsObject: optionsArgument,\n };\n }\n }\n }\n }\n\n return undefined;\n};\n\nconst isDynamicPackage = (\n packageName: string\n): packageName is (typeof PACKAGE_LIST_DYNAMIC)[number] =>\n PACKAGE_LIST_DYNAMIC.includes(\n packageName as (typeof PACKAGE_LIST_DYNAMIC)[number]\n );\n\n/**\n * Helper family every `useIntlayer`/`getIntlayer` call from one package import\n * resolves to in the current file. `ssrStatic` is the SSR bundle of a\n * dynamic-mode file: rewritten to the static `useDictionary` (from the\n * package's `/server` entry when it has one — see\n * `SSR_STATIC_IMPORT_SOURCE`) so the server renders static JSON while the\n * client keeps the dynamic loader.\n */\ntype PackageHelperPlan = 'static' | 'dynamic' | 'ssrStatic';\n\n/**\n * Decides, once per package import, which helper family applies to this file.\n * The import rewrite and the per-call rewrite must both derive from this\n * single decision, or the emitted helper and its argument shape diverge.\n *\n * Fetch wins over `ssrStatic`: fetch dictionaries are runtime content, so the\n * server must keep the real fetch path instead of rendering build-time JSON.\n */\nconst resolveHelperPlan = (\n packageName: string,\n importMode: ImportMode | undefined,\n isServer: boolean | undefined,\n packageHasDynamicCall: boolean,\n packageHasFetchCall: boolean\n): PackageHelperPlan => {\n if (!isDynamicPackage(packageName)) return 'static';\n\n if (importMode === 'fetch' || packageHasFetchCall) return 'dynamic';\n\n if (importMode === 'dynamic' || packageHasDynamicCall) {\n return isServer === true ? 'ssrStatic' : 'dynamic';\n }\n\n return 'static';\n};\n\n/**\n * Babel plugin that transforms Intlayer function calls and auto-imports dictionaries.\n *\n * This plugin transforms calls to `useIntlayer()` and `getIntlayer()` from various Intlayer\n * packages into optimized dictionary access patterns, automatically importing the required\n * dictionary files based on the configured import mode.\n *\n * ## Supported Input Patterns\n *\n * The plugin recognizes these function calls:\n *\n * ```ts\n * // useIntlayer\n * import { useIntlayer } from 'react-intlayer';\n * import { useIntlayer } from 'next-intlayer';\n *\n * // getIntlayer\n * import { getIntlayer } from 'intlayer';\n *\n * // Usage\n * const content = useIntlayer('app');\n * const content = getIntlayer('app');\n * ```\n *\n * ## Transformation Modes\n *\n * ### Static Mode (default: `importMode = \"static\"`)\n *\n * Imports JSON dictionaries directly and replaces function calls with dictionary access:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import { useDictionary as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash);\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Dynamic Mode (`importMode = \"dynamic\"`)\n *\n * Uses dynamic dictionary loading with Suspense support:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Fetch Mode (`importMode = \"fetch\"`)\n *\n * Uses fetch-based dictionary loading for remote dictionaries:\n *\n * **Output if `dictionaryModeMap` includes the key with \"fetch\" value:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_fetch from '../../.intlayer/fetch_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_fetch, \"app\");\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * > If `dictionaryModeMap` does not include the key with \"fetch\" value, the plugin will fallback to the dynamic import mode.\n *\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n */\nexport const intlayerOptimizeBabelPlugin = (babel: {\n types: typeof BabelTypes;\n}): PluginObject<State> => {\n const { types: t } = babel;\n\n return {\n name: 'babel-plugin-intlayer-transform',\n\n pre() {\n this._newStaticImports = new Map();\n this._newDynamicImports = new Map();\n this._callerMap = new Map();\n this._callerPackageMap = new Map();\n this._compatCallerMap = new Map();\n this._isIncluded = true;\n this._hasValidImport = false;\n this._isDictEntry = false;\n\n // If optimize is false, skip processing entirely\n if (this.opts.optimize === false) {\n this._isIncluded = false;\n return;\n }\n\n // If filesList is provided, check if current file is included\n const filename = this.file.opts.filename\n ? normalizePath(this.file.opts.filename)\n : undefined;\n if (this.opts.filesList && filename) {\n const isIncluded = getNormalizedFilesListSet(this.opts.filesList).has(\n filename\n );\n\n if (!isIncluded) {\n // Force _isIncluded to false to skip processing\n this._isIncluded = false;\n return;\n }\n }\n },\n\n visitor: {\n /* If this file *is* the dictionaries entry, short-circuit: export {} */\n Program: {\n enter(programPath, state) {\n // Safe access to filename\n const filename = state.file.opts.filename\n ? normalizePath(state.file.opts.filename)\n : undefined;\n const dictionariesEntryPath = state.opts.dictionariesEntryPath\n ? normalizePath(state.opts.dictionariesEntryPath)\n : undefined;\n\n // Check if this is the correct file to transform\n\n if (\n state.opts.replaceDictionaryEntry &&\n filename === dictionariesEntryPath\n ) {\n state._isDictEntry = true;\n\n // Traverse the program to surgically remove/edit specific parts\n programPath.traverse({\n // Remove all import statements (cleaning up 'sssss.json')\n ImportDeclaration(path) {\n path.remove();\n },\n\n // Find the variable definition and empty the object\n VariableDeclarator(path) {\n // We look for: const x = { ... }\n\n if (t.isObjectExpression(path.node.init)) {\n // Set the object properties to an empty array: {}\n path.node.init.properties = [];\n }\n },\n });\n\n // (Optional) Stop other plugins from processing this file further if needed\n // programPath.stop();\n }\n },\n\n /**\n * After full traversal, process imports and call expressions, then inject the JSON dictionary imports.\n *\n * We do the transformation in Program.exit (via a manual traverse) rather than using\n * top-level ImportDeclaration/CallExpression visitors. This ensures that if another plugin\n * (like babel-plugin-intlayer-extract) adds new useIntlayer calls in its Program.exit,\n * we will see and transform them here because our Program.exit runs after theirs.\n */\n exit(programPath, state) {\n if (state._isDictEntry) return; // nothing else to do – already replaced\n\n if (!state._isIncluded) return; // early-out if file is not included\n\n // Compat callers the optimize pass can rewrite (injected by the\n // compat packages' bundler plugins — nothing is hard-coded here).\n const rewritableCompatCallers = getRewritableCallers(\n state.opts.compatCallers ?? []\n );\n\n // Manual traversal to process imports and call expressions\n // This runs AFTER all other plugins' visitors have completed\n programPath.traverse({\n /* Inspect every intlayer import before deciding helper rewrites. */\n ImportDeclaration(path) {\n const src = path.node.source.value;\n\n const isNativePackage = PACKAGE_LIST.includes(src);\n const compatCallersForSource = rewritableCompatCallers.filter(\n (descriptor) => descriptor.importSources.includes(src)\n );\n\n if (!isNativePackage && compatCallersForSource.length === 0) {\n return;\n }\n\n state._hasValidImport = true;\n\n for (const spec of path.node.specifiers) {\n if (!t.isImportSpecifier(spec)) continue;\n\n const importedName = t.isIdentifier(spec.imported)\n ? spec.imported.name\n : (spec.imported as BabelTypes.StringLiteral).value;\n\n if (isNativePackage && isCallerName(importedName)) {\n state._callerMap?.set(spec.local.name, importedName);\n state._callerPackageMap?.set(spec.local.name, src);\n }\n\n const compatDescriptor = compatCallersForSource.find(\n (descriptor) => descriptor.callerName === importedName\n );\n if (compatDescriptor) {\n state._compatCallerMap?.set(\n spec.local.name,\n compatDescriptor\n );\n }\n }\n },\n });\n\n // Pre-pass to determine if dictionary-level overrides require the\n // dynamic helper in an otherwise static file, and to disable the\n // rewrite for compat callers with unresolvable call sites.\n const packagesWithDynamicCall = new Set<string>();\n const packagesWithFetchCall = new Set<string>();\n let compatHasDynamicCall = false;\n const unresolvableCompatLocalNames = new Set<string>();\n programPath.traverse({\n CallExpression(path) {\n const callee = path.node.callee;\n\n if (!t.isIdentifier(callee)) return;\n\n const compatDescriptor = state._compatCallerMap?.get(callee.name);\n if (compatDescriptor) {\n const namespaceMatch = resolveCompatNamespaceMatch(\n t,\n path.node.arguments,\n compatDescriptor\n );\n\n if (!namespaceMatch) {\n // Dynamic/absent namespace: the whole local caller must keep\n // its original implementation — rewriting the import while\n // leaving this call untouched would hand a raw namespace\n // string to the dictionary-accepting helper.\n unresolvableCompatLocalNames.add(callee.name);\n return;\n }\n\n const { dictionaryKey } = splitNamespace(\n namespaceMatch.fullNamespace\n );\n const compatOverrideMode =\n state.opts.dictionaryModeMap?.[dictionaryKey];\n if (\n compatOverrideMode === 'dynamic' ||\n compatOverrideMode === 'fetch'\n ) {\n compatHasDynamicCall = true;\n }\n return;\n }\n\n const originalImportedName = state._callerMap?.get(callee.name);\n if (originalImportedName !== 'useIntlayer') return;\n\n const callerPackage = state._callerPackageMap?.get(callee.name);\n if (!callerPackage) return;\n\n const key = getKeyFromArgument(path.node.arguments[0], t);\n if (!key) return;\n\n const dictionaryOverrideMode =\n state.opts.dictionaryModeMap?.[key];\n\n if (dictionaryOverrideMode === 'dynamic') {\n packagesWithDynamicCall.add(callerPackage);\n } else if (dictionaryOverrideMode === 'fetch') {\n packagesWithFetchCall.add(callerPackage);\n }\n },\n });\n\n for (const localName of unresolvableCompatLocalNames) {\n state._compatCallerMap?.delete(localName);\n }\n\n const getHelperPlan = (packageName: string): PackageHelperPlan =>\n resolveHelperPlan(\n packageName,\n state.opts.importMode,\n state.opts.isServer,\n packagesWithDynamicCall.has(packageName),\n packagesWithFetchCall.has(packageName)\n );\n\n // Compat helpers are swapped per file (one import specifier serves\n // every call), so the dynamic decision is file-level: a global\n // dynamic/fetch mode or any per-dictionary override flips all\n // rewritten compat calls to the dynamic helper.\n const compatUseDynamicHelpers =\n state.opts.importMode === 'dynamic' ||\n state.opts.importMode === 'fetch' ||\n compatHasDynamicCall;\n\n programPath.traverse({\n ImportDeclaration(path) {\n const src = path.node.source.value;\n\n // Compat caller import rename: point the specifier at the\n // dictionary-accepting helper exported by the compat package\n // (`useTranslation` → `useDictionary`), keeping the local alias\n // so call sites read unchanged. Locals with unresolvable call\n // sites were dropped from the map and keep the original import.\n for (const spec of path.node.specifiers) {\n if (!t.isImportSpecifier(spec)) continue;\n\n const compatDescriptor = state._compatCallerMap?.get(\n spec.local.name\n );\n if (!compatDescriptor) continue;\n if (!compatDescriptor.importSources.includes(src)) continue;\n\n spec.imported = t.identifier(\n compatUseDynamicHelpers\n ? compatDescriptor.dynamicReplacement!\n : compatDescriptor.staticReplacement!\n );\n }\n\n if (!PACKAGE_LIST.includes(src)) return;\n\n // Per-import swap, mirrored across bundles — Solid hydration\n // ids rely on the SSR and client helpers consuming one\n // resource slot per call alike (see solid-intlayer/server).\n const helperPlan = getHelperPlan(src);\n const serverSource =\n helperPlan === 'ssrStatic'\n ? SSR_STATIC_IMPORT_SOURCE[src]\n : undefined;\n\n const helperMap: Record<string, string> =\n helperPlan === 'dynamic'\n ? DYNAMIC_HELPER_MAP\n : STATIC_IMPORT_FUNCTION;\n\n const serverSpecifiers: BabelTypes.ImportSpecifier[] = [];\n\n for (const spec of path.node.specifiers) {\n if (!t.isImportSpecifier(spec)) continue;\n\n const importedName = t.isIdentifier(spec.imported)\n ? spec.imported.name\n : (spec.imported as BabelTypes.StringLiteral).value;\n\n if (!isCallerName(importedName)) continue;\n\n if (serverSource && importedName === 'useIntlayer') {\n spec.imported = t.identifier('useDictionary');\n serverSpecifiers.push(spec);\n continue;\n }\n\n const newIdentifier = helperMap[importedName];\n\n if (newIdentifier) {\n // Keep the local alias intact (so calls remain `useIntlayer` /\n // `getIntlayer`), but rewrite the imported identifier so it\n // points to our helper implementation.\n spec.imported = t.identifier(newIdentifier);\n }\n }\n\n if (serverSpecifiers.length > 0 && serverSource) {\n // Move the helper to the /server entry, keeping any other\n // specifiers (useLocale, …) on the original import.\n path.insertAfter(\n t.importDeclaration(\n serverSpecifiers,\n t.stringLiteral(serverSource)\n )\n );\n path.node.specifiers = path.node.specifiers.filter(\n (spec) =>\n !serverSpecifiers.includes(\n spec as BabelTypes.ImportSpecifier\n )\n );\n if (path.node.specifiers.length === 0) {\n path.remove();\n }\n }\n },\n\n /* Replace calls: useIntlayer(\"foo\") → useDictionary(_hash) or useDictionaryDynamic(_hash, \"foo\") */\n CallExpression(path) {\n const callee = path.node.callee;\n\n if (!t.isIdentifier(callee)) return;\n\n // Compat caller rewrite, e.g. (mirroring the SWC plugin):\n // static: useTranslation('about.counter', opts)\n // → useDictionary(_hash, 'counter', opts)\n // dynamic: useTranslation('about.counter', opts)\n // → useDictionaryDynamic(_hash_dyn, 'about', 'counter', opts)\n // option: useI18n({ namespace: 'about' })\n // → useDictionary(_hash, {})\n // fixed: useLingui() → useDictionary(_hash)\n const compatDescriptor = state._compatCallerMap?.get(callee.name);\n if (compatDescriptor) {\n const callArguments = path.node.arguments;\n const namespaceMatch = resolveCompatNamespaceMatch(\n t,\n callArguments,\n compatDescriptor\n );\n if (!namespaceMatch) return; // filtered by the pre-pass — stay safe\n\n state._hasValidImport = true;\n\n const { dictionaryKey, keyPrefix } = splitNamespace(\n namespaceMatch.fullNamespace\n );\n const compatOverrideMode =\n state.opts.dictionaryModeMap?.[dictionaryKey];\n\n // The import specifier serves every call in the file, so a\n // dynamic file receives a dynamic loader for every call.\n let compatCallMode: ImportMode = 'static';\n if (compatUseDynamicHelpers) {\n if (\n compatOverrideMode === 'dynamic' ||\n compatOverrideMode === 'fetch'\n ) {\n compatCallMode = compatOverrideMode;\n } else if (\n state.opts.importMode === 'dynamic' ||\n state.opts.importMode === 'fetch'\n ) {\n compatCallMode = state.opts.importMode;\n } else {\n compatCallMode = 'dynamic';\n }\n }\n\n let dictionaryIdent: BabelTypes.Identifier;\n if (compatCallMode === 'static') {\n let staticIdent = state._newStaticImports?.get(dictionaryKey);\n if (!staticIdent) {\n staticIdent = makeIdent(dictionaryKey, t);\n state._newStaticImports?.set(dictionaryKey, staticIdent);\n }\n dictionaryIdent = staticIdent;\n } else {\n let dynamicIdent =\n state._newDynamicImports?.get(dictionaryKey);\n if (!dynamicIdent) {\n const hash = getPathHash(dictionaryKey);\n const suffix = compatCallMode === 'fetch' ? 'fetch' : 'dyn';\n dynamicIdent = t.identifier(`_${hash}_${suffix}`);\n state._newDynamicImports?.set(dictionaryKey, dynamicIdent);\n }\n dictionaryIdent = dynamicIdent;\n }\n\n if (namespaceMatch.argumentIndex !== undefined) {\n // Positional namespace: replace the string with the\n // dictionary, then (dynamic) key and (nested) prefix.\n callArguments[namespaceMatch.argumentIndex] = t.identifier(\n dictionaryIdent.name\n );\n const insertAt = namespaceMatch.argumentIndex + 1;\n const insertedArguments: BabelTypes.Expression[] = [];\n if (compatCallMode !== 'static') {\n insertedArguments.push(t.stringLiteral(dictionaryKey));\n }\n if (keyPrefix) {\n insertedArguments.push(t.stringLiteral(keyPrefix));\n }\n callArguments.splice(insertAt, 0, ...insertedArguments);\n } else if (compatCallMode !== 'static') {\n // Fixed / option namespace, dynamic helper: prepend the\n // loader and the dictionary key.\n callArguments.unshift(\n t.identifier(dictionaryIdent.name),\n t.stringLiteral(dictionaryKey)\n );\n } else {\n // Fixed / option namespace, static helper: prepend the\n // dictionary object.\n callArguments.unshift(t.identifier(dictionaryIdent.name));\n }\n\n // Option namespace: leave only the key-prefix remainder in the\n // options object (or drop the property for a plain namespace),\n // so the runtime helper does not re-apply the dictionary key\n // as a lookup prefix.\n if (\n namespaceMatch.optionProperty &&\n namespaceMatch.optionsObject\n ) {\n if (keyPrefix) {\n namespaceMatch.optionProperty.value =\n t.stringLiteral(keyPrefix);\n } else {\n namespaceMatch.optionsObject.properties =\n namespaceMatch.optionsObject.properties.filter(\n (property) => property !== namespaceMatch.optionProperty\n );\n }\n }\n\n return;\n }\n\n const originalImportedName = state._callerMap?.get(callee.name);\n if (!originalImportedName) return;\n\n // Ensure we ultimately emit helper imports for files that *invoke*\n // the hooks, even if they didn't import them directly (edge cases with\n // re-exports).\n state._hasValidImport = true;\n\n const key = getKeyFromArgument(path.node.arguments[0], t);\n if (!key) return;\n\n const callerPackage = state._callerPackageMap?.get(callee.name);\n const importMode = state.opts.importMode;\n const isUseIntlayer = originalImportedName === 'useIntlayer';\n const dictionaryOverrideMode =\n state.opts.dictionaryModeMap?.[key];\n const helperPlan =\n callerPackage === undefined\n ? 'static'\n : getHelperPlan(callerPackage);\n\n // Decide per-call mode: 'static' | 'dynamic' | 'fetch'.\n let perCallMode: ImportMode = 'static';\n\n if (isUseIntlayer && helperPlan === 'dynamic') {\n if (dictionaryOverrideMode) {\n perCallMode = dictionaryOverrideMode;\n } else if (importMode === 'dynamic' || importMode === 'fetch') {\n perCallMode = importMode;\n }\n } else if (isUseIntlayer && helperPlan === 'static') {\n // The global mode is static, but a per-dictionary override can\n // still force dynamic/fetch for this specific call.\n if (\n dictionaryOverrideMode === 'dynamic' ||\n dictionaryOverrideMode === 'fetch'\n ) {\n perCallMode = dictionaryOverrideMode;\n }\n }\n\n let ident: BabelTypes.Identifier;\n\n if (perCallMode === 'fetch') {\n // Use fetch dictionaries entry for selected keys\n let dynamicIdent = state._newDynamicImports?.get(key);\n\n if (!dynamicIdent) {\n const hash = getPathHash(key);\n dynamicIdent = t.identifier(`_${hash}_fetch`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Helper: first argument is the dictionary entry, second is the key\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else if (perCallMode === 'dynamic') {\n // Use dynamic dictionaries entry\n let dynamicIdent = state._newDynamicImports?.get(key);\n\n if (!dynamicIdent) {\n // Create a unique identifier for dynamic imports by appending a suffix\n const hash = getPathHash(key);\n dynamicIdent = t.identifier(`_${hash}_dyn`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Dynamic helper: first argument is the dictionary, second is the key.\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else {\n // Use static imports for getIntlayer or useIntlayer when not using dynamic helpers\n let staticIdent = state._newStaticImports?.get(key);\n\n if (!staticIdent) {\n staticIdent = makeIdent(key, t);\n state._newStaticImports?.set(key, staticIdent);\n }\n ident = staticIdent;\n\n // Static helper (useDictionary / getDictionary): replace key with ident.\n // After the splice above the key is always at index 0.\n path.node.arguments[0] = t.identifier(ident.name);\n }\n },\n });\n\n // Early-out if we touched nothing\n\n if (!state._hasValidImport) return;\n\n const file = state.file.opts.filename!;\n const dictionariesDir = state.opts.dictionariesDir;\n const dynamicDictionariesDir = state.opts.dynamicDictionariesDir;\n const fetchDictionariesDir = state.opts.fetchDictionariesDir;\n const imports: BabelTypes.ImportDeclaration[] = [];\n\n const nestingDictionaryKeys = new Set(\n state.opts.nestingDictionaryKeys ?? []\n );\n\n // Generate static JSON imports (getIntlayer always uses JSON dictionaries)\n for (const [key, ident] of state._newStaticImports!) {\n // Dictionaries holding `nest()` references are imported through\n // their companion module, which re-exports them with the nest\n // targets attached.\n const hasNestedDictionaries = nestingDictionaryKeys.has(key);\n\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n 'static',\n hasNestedDictionaries\n );\n\n const importDeclarationNode = t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n );\n\n // Add 'type: json' attribute for JSON files\n if (!hasNestedDictionaries) {\n importDeclarationNode.attributes = [\n t.importAttribute(\n t.identifier('type'),\n t.stringLiteral('json')\n ),\n ];\n }\n\n imports.push(importDeclarationNode);\n }\n\n // Generate dynamic/fetch imports (for useIntlayer when using dynamic/fetch helpers)\n for (const [key, ident] of state._newDynamicImports!) {\n const modeForThisIdent: 'dynamic' | 'fetch' = ident.name.endsWith(\n '_fetch'\n )\n ? 'fetch'\n : 'dynamic';\n\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n modeForThisIdent\n );\n imports.push(\n t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n )\n );\n }\n\n if (!imports.length) return;\n\n /* Keep \"use client\" / \"use server\" directives at the very top. */\n const bodyPaths = programPath.get(\n 'body'\n ) as NodePath<BabelTypes.Statement>[];\n let insertPos = 0;\n for (const stmtPath of bodyPaths) {\n const stmt = stmtPath.node;\n\n if (\n t.isExpressionStatement(stmt) &&\n t.isStringLiteral(stmt.expression) &&\n !stmt.expression.value.startsWith('import') &&\n !stmt.expression.value.startsWith('require')\n ) {\n insertPos += 1;\n } else {\n break;\n }\n }\n\n programPath.node.body.splice(insertPos, 0, ...imports);\n },\n },\n },\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"babel-plugin-intlayer-optimize.cjs","names":["getPathHash","normalizePath","relative","dirname","join","getNormalizedFilesListSet","getRewritableCallers"],"sources":["../../src/babel-plugin-intlayer-optimize.ts"],"sourcesContent":["import { dirname, join, relative } from 'node:path';\nimport type { NodePath, PluginObject, PluginPass } from '@babel/core';\nimport type * as BabelTypes from '@babel/types';\nimport {\n type CallerDescriptor,\n getRewritableCallers,\n} from '@intlayer/config/callers';\nimport { normalizePath } from '@intlayer/config/utils';\nimport { getPathHash } from '@intlayer/engine/utils';\nimport { getNormalizedFilesListSet } from './normalizedFilesList';\n\nconst PACKAGE_LIST = [\n 'intlayer',\n '@intlayer/core',\n '@intlayer/core/interpreter',\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'svelte-intlayer',\n 'vue-intlayer',\n 'angular-intlayer',\n 'preact-intlayer',\n 'solid-intlayer',\n 'lit-intlayer',\n 'vanilla-intlayer',\n];\n\nconst CALLER_LIST = ['useIntlayer', 'getIntlayer'] as const;\n\n/**\n * Packages that support dynamic import\n */\nconst PACKAGE_LIST_DYNAMIC = [\n 'react-intlayer',\n 'react-intlayer/client',\n 'react-intlayer/server',\n 'next-intlayer',\n 'next-intlayer/client',\n 'next-intlayer/server',\n 'preact-intlayer',\n 'vue-intlayer',\n 'solid-intlayer',\n 'svelte-intlayer',\n 'angular-intlayer',\n 'lit-intlayer',\n 'vanilla-intlayer',\n] as const;\n\nconst STATIC_IMPORT_FUNCTION = {\n getIntlayer: 'getDictionary',\n useIntlayer: 'useDictionary',\n} as const;\n\nconst DYNAMIC_IMPORT_FUNCTION = {\n useIntlayer: 'useDictionaryDynamic',\n} as const;\n\n/** Import rename table applied when the helper plan for a package is `dynamic`. */\nconst DYNAMIC_HELPER_MAP: Record<string, string> = {\n ...STATIC_IMPORT_FUNCTION,\n ...DYNAMIC_IMPORT_FUNCTION,\n};\n\n/**\n * Packages whose SSR-static `useDictionary` lives in a `/server` subpath\n * because it differs from the root one. Solid's reserves one hydration\n * resource slot so hydration ids stay aligned with the client's\n * `useDictionaryDynamic`; for other frameworks the root `useDictionary` is\n * already the correct SSR-static implementation.\n */\nconst SSR_STATIC_IMPORT_SOURCE: Partial<Record<string, string>> = {\n 'solid-intlayer': 'solid-intlayer/server',\n};\n\ntype CallerName = (typeof CALLER_LIST)[number];\ntype ImportMode = 'static' | 'dynamic' | 'fetch';\n\n/**\n * Options for the optimization Babel plugin\n */\nexport type OptimizePluginOptions = {\n /**\n * If false, the plugin will not apply any transformation.\n */\n optimize?: boolean;\n /**\n * The path to the dictionaries directory.\n */\n dictionariesDir: string;\n /**\n * The path to the dictionaries entry file.\n */\n dictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries entry file.\n */\n unmergedDictionariesEntryPath: string;\n /**\n * The path to the unmerged dictionaries directory.\n */\n unmergedDictionariesDir: string;\n /**\n * The path to the dictionaries directory.\n */\n dynamicDictionariesDir: string;\n /**\n * The path to the dynamic dictionaries entry file.\n */\n dynamicDictionariesEntryPath: string;\n /**\n * The path to the fetch dictionaries directory.\n */\n fetchDictionariesDir: string;\n /**\n * The path to the fetch dictionaries entry file.\n */\n fetchDictionariesEntryPath: string;\n /**\n * If true, the plugin will replace the dictionary entry file with `export default {}`.\n */\n replaceDictionaryEntry: boolean;\n /**\n * Keys of the dictionaries that reference other dictionaries through\n * `nest()`.\n *\n * For those, the injected static import points at the generated companion\n * module (`<dictionariesDir>/nested/<key>.mjs`) instead of the raw JSON. The\n * companion re-exports the dictionary with its nest targets attached, so\n * `getNesting` resolves them from that local reference rather than from the\n * global registry this plugin empties — and each target lands in the chunk of\n * the dictionary referencing it.\n *\n * Dynamic and fetch modes need nothing here: their generated loaders already\n * attach the same targets per locale.\n */\n nestingDictionaryKeys?: string[];\n /**\n * If true, the plugin will activate the dynamic import of the dictionaries. It will rely on Suspense to load the dictionaries.\n */\n importMode: 'static' | 'dynamic' | 'fetch' | undefined;\n /**\n * Map of dictionary keys to their specific import mode.\n */\n dictionaryModeMap?: Record<\n string,\n 'static' | 'dynamic' | 'fetch' | undefined\n >;\n /**\n * Files list to traverse.\n */\n filesList: string[];\n /**\n * Whether the current transform is for an SSR bundle.\n */\n isServer?: boolean;\n /**\n * Compat-adapter caller descriptors injected by the compat packages'\n * bundler plugins (e.g. `@intlayer/react-i18next/plugin`).\n *\n * Callers carrying `staticReplacement` / `dynamicReplacement` are rewritten\n * the same way as native `useIntlayer` calls: the namespace string argument\n * is replaced by a pre-imported dictionary object and the import specifier\n * is re-pointed to the dictionary-accepting variant, e.g.\n * `useTranslation('about')` → `useDictionary(_dictHash)`.\n *\n * No compat-specific name is hard-coded in this plugin — the whole rewrite\n * is driven by these descriptors.\n */\n compatCallers?: CallerDescriptor[];\n};\n\ntype State = PluginPass & {\n opts: OptimizePluginOptions;\n /** map key → generated ident (per-file) for static imports */\n _newStaticImports?: Map<string, BabelTypes.Identifier>;\n /** map key → generated ident (per-file) for dynamic imports */\n _newDynamicImports?: Map<string, BabelTypes.Identifier>;\n /** whether the current file imported *any* intlayer package */\n _hasValidImport?: boolean;\n /** map from local identifier name to the imported intlayer func name ('useIntlayer' | 'getIntlayer') */\n _callerMap?: Map<string, (typeof CALLER_LIST)[number]>;\n /** map from local identifier name to the intlayer package it was imported from */\n _callerPackageMap?: Map<string, string>;\n /** map from local identifier name to the compat caller descriptor it was imported as */\n _compatCallerMap?: Map<string, CallerDescriptor>;\n /** whether the current file *is* the dictionaries entry file */\n _isDictEntry?: boolean;\n /** whether the current file is included in the filesList */\n _isIncluded?: boolean;\n};\n\n/**\n * Replicates the xxHash64 → Base-62 algorithm used by the SWC version\n * and prefixes an underscore so the generated identifiers never collide\n * with user-defined ones.\n */\nconst makeIdent = (\n key: string,\n t: typeof BabelTypes\n): BabelTypes.Identifier => {\n const hash = getPathHash(key);\n return t.identifier(`_${hash}`);\n};\n\n/**\n * Builds the module specifier pointing at `targetPath` from `fromFile`, with\n * forward slashes and an explicit `./` prefix so bundlers never treat it as a\n * bare package specifier.\n */\nconst toRelativeSpecifier = (fromFile: string, targetPath: string): string => {\n // Fix windows path\n const relativePath = normalizePath(relative(dirname(fromFile), targetPath));\n\n // Fix relative path\n if (!relativePath.startsWith('./') && !relativePath.startsWith('../')) {\n return `./${relativePath}`;\n }\n\n return relativePath;\n};\n\n/**\n * Subdirectory of the compiled dictionaries holding the companion modules that\n * re-export a dictionary with its `nest()` targets attached. Mirrors\n * `NESTED_DICTIONARIES_SUBDIR` in `@intlayer/engine`.\n */\nconst NESTED_DICTIONARIES_SUBDIR = 'nested';\n\nconst computeImport = (\n fromFile: string,\n dictionariesDir: string,\n dynamicDictionariesDir: string,\n fetchDictionariesDir: string,\n key: string,\n importMode: 'static' | 'dynamic' | 'fetch',\n hasNestedDictionaries = false\n): string => {\n // Static mode is the only one needing the companion: the dynamic and fetch\n // loaders already attach the nest targets per locale.\n let dictionaryPath = hasNestedDictionaries\n ? join(dictionariesDir, NESTED_DICTIONARIES_SUBDIR, `${key}.mjs`)\n : join(dictionariesDir, `${key}.json`);\n\n if (importMode === 'fetch') {\n dictionaryPath = join(fetchDictionariesDir, `${key}.mjs`);\n }\n\n if (importMode === 'dynamic') {\n dictionaryPath = join(dynamicDictionariesDir, `${key}.mjs`);\n }\n\n return toRelativeSpecifier(fromFile, dictionaryPath);\n};\n\nconst getKeyFromArgument = (\n arg: BabelTypes.Node | null | undefined,\n t: typeof BabelTypes\n): string | undefined => {\n if (arg && t.isStringLiteral(arg)) {\n return arg.value;\n }\n\n if (\n arg &&\n t.isTemplateLiteral(arg) &&\n arg.expressions.length === 0 &&\n arg.quasis.length === 1\n ) {\n return arg.quasis[0]?.value.cooked ?? arg.quasis[0]?.value.raw;\n }\n\n return undefined;\n};\n\nconst isCallerName = (name: string): name is CallerName =>\n CALLER_LIST.includes(name as CallerName);\n\n/**\n * Splits a namespace string at the first `.` to separate the dictionary key\n * from an optional key prefix for nested namespaces, mirroring the SWC\n * plugin's `split_namespace`.\n *\n * `'about'` → `{ dictionaryKey: 'about', keyPrefix: '' }`\n * `'about.counter'` → `{ dictionaryKey: 'about', keyPrefix: 'counter' }`\n */\nconst splitNamespace = (\n namespace: string\n): { dictionaryKey: string; keyPrefix: string } => {\n const dotPosition = namespace.indexOf('.');\n if (dotPosition === -1) return { dictionaryKey: namespace, keyPrefix: '' };\n return {\n dictionaryKey: namespace.slice(0, dotPosition),\n keyPrefix: namespace.slice(dotPosition + 1),\n };\n};\n\n/**\n * Result of statically resolving the namespace of a compat caller call-site.\n */\ntype CompatNamespaceMatch = {\n /** The full namespace string, e.g. `'about.counter'`. */\n fullNamespace: string;\n /** Index of the positional namespace argument, when read from an argument. */\n argumentIndex?: number;\n /**\n * The options-object property holding the namespace, when read from an\n * option. The rewrite mutates it in place (key-prefix remainder) or removes\n * it from `optionsObject`.\n */\n optionProperty?: BabelTypes.ObjectProperty;\n /** The options object owning `optionProperty`. */\n optionsObject?: BabelTypes.ObjectExpression;\n};\n\n/**\n * Statically resolves the namespace of a compat caller call-site from its\n * descriptor's `namespaceSources` (argument / option / fixed — the\n * per-message-id `path-first-segment` form cannot bind one dictionary to the\n * call site and is skipped). Returns `undefined` when the namespace is absent\n * or dynamic, in which case the call is left untouched and resolves through\n * the runtime dictionary registry.\n */\nconst resolveCompatNamespaceMatch = (\n t: typeof BabelTypes,\n callArguments: BabelTypes.CallExpression['arguments'],\n descriptor: CallerDescriptor\n): CompatNamespaceMatch | undefined => {\n for (const source of descriptor.namespaceSources) {\n if (source.from === 'fixed') {\n return { fullNamespace: source.value };\n }\n\n if (source.from === 'argument') {\n const namespace = getKeyFromArgument(callArguments[source.index], t);\n if (namespace !== undefined) {\n return { fullNamespace: namespace, argumentIndex: source.index };\n }\n continue;\n }\n\n if (source.from === 'option') {\n const optionsArgument = callArguments[source.argumentIndex];\n if (!optionsArgument || !t.isObjectExpression(optionsArgument)) continue;\n\n for (const property of optionsArgument.properties) {\n if (!t.isObjectProperty(property)) continue;\n const keyMatches =\n (t.isIdentifier(property.key) &&\n property.key.name === source.property) ||\n (t.isStringLiteral(property.key) &&\n property.key.value === source.property);\n if (!keyMatches) continue;\n\n const namespace = getKeyFromArgument(property.value, t);\n if (namespace !== undefined) {\n return {\n fullNamespace: namespace,\n optionProperty: property,\n optionsObject: optionsArgument,\n };\n }\n }\n }\n }\n\n return undefined;\n};\n\nconst isDynamicPackage = (\n packageName: string\n): packageName is (typeof PACKAGE_LIST_DYNAMIC)[number] =>\n PACKAGE_LIST_DYNAMIC.includes(\n packageName as (typeof PACKAGE_LIST_DYNAMIC)[number]\n );\n\n/**\n * Helper family every `useIntlayer`/`getIntlayer` call from one package import\n * resolves to in the current file. `ssrStatic` is the SSR bundle of a\n * dynamic-mode file: rewritten to the static `useDictionary` (from the\n * package's `/server` entry when it has one — see\n * `SSR_STATIC_IMPORT_SOURCE`) so the server renders static JSON while the\n * client keeps the dynamic loader.\n */\ntype PackageHelperPlan = 'static' | 'dynamic' | 'ssrStatic';\n\n/**\n * Decides, once per package import, which helper family applies to this file.\n * The import rewrite and the per-call rewrite must both derive from this\n * single decision, or the emitted helper and its argument shape diverge.\n *\n * Fetch wins over `ssrStatic`: fetch dictionaries are runtime content, so the\n * server must keep the real fetch path instead of rendering build-time JSON.\n */\nconst resolveHelperPlan = (\n packageName: string,\n importMode: ImportMode | undefined,\n isServer: boolean | undefined,\n packageHasDynamicCall: boolean,\n packageHasFetchCall: boolean\n): PackageHelperPlan => {\n if (!isDynamicPackage(packageName)) return 'static';\n\n if (importMode === 'fetch' || packageHasFetchCall) return 'dynamic';\n\n if (importMode === 'dynamic' || packageHasDynamicCall) {\n return isServer === true ? 'ssrStatic' : 'dynamic';\n }\n\n return 'static';\n};\n\n/**\n * Babel plugin that transforms Intlayer function calls and auto-imports dictionaries.\n *\n * This plugin transforms calls to `useIntlayer()` and `getIntlayer()` from various Intlayer\n * packages into optimized dictionary access patterns, automatically importing the required\n * dictionary files based on the configured import mode.\n *\n * ## Supported Input Patterns\n *\n * The plugin recognizes these function calls:\n *\n * ```ts\n * // useIntlayer\n * import { useIntlayer } from 'react-intlayer';\n * import { useIntlayer } from 'next-intlayer';\n *\n * // getIntlayer\n * import { getIntlayer } from 'intlayer';\n *\n * // Usage\n * const content = useIntlayer('app');\n * const content = getIntlayer('app');\n * ```\n *\n * ## Transformation Modes\n *\n * ### Static Mode (default: `importMode = \"static\"`)\n *\n * Imports JSON dictionaries directly and replaces function calls with dictionary access:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import { useDictionary as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash);\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Dynamic Mode (`importMode = \"dynamic\"`)\n *\n * Uses dynamic dictionary loading with Suspense support:\n *\n * **Output:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * ### Fetch Mode (`importMode = \"fetch\"`)\n *\n * Uses fetch-based dictionary loading for remote dictionaries:\n *\n * **Output if `dictionaryModeMap` includes the key with \"fetch\" value:**\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_fetch from '../../.intlayer/fetch_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_fetch, \"app\");\n * const content2 = getIntlayer(_dicHash);\n * ```\n *\n * > If `dictionaryModeMap` does not include the key with \"fetch\" value, the plugin will fallback to the dynamic import mode.\n *\n * ```ts\n * import _dicHash from '../../.intlayer/dictionaries/app.json' with { type: 'json' };\n * import _dicHash_dyn from '../../.intlayer/dynamic_dictionaries/app.mjs';\n * import { useDictionaryDynamic as useIntlayer } from 'react-intlayer';\n * import { getDictionary as getIntlayer } from 'intlayer';\n *\n * const content1 = useIntlayer(_dicHash_dyn, 'app');\n * const content2 = getIntlayer(_dicHash);\n * ```\n */\nexport const intlayerOptimizeBabelPlugin = (babel: {\n types: typeof BabelTypes;\n}): PluginObject<State> => {\n const { types: t } = babel;\n\n return {\n name: 'babel-plugin-intlayer-transform',\n\n pre() {\n this._newStaticImports = new Map();\n this._newDynamicImports = new Map();\n this._callerMap = new Map();\n this._callerPackageMap = new Map();\n this._compatCallerMap = new Map();\n this._isIncluded = true;\n this._hasValidImport = false;\n this._isDictEntry = false;\n\n // If optimize is false, skip processing entirely\n if (this.opts.optimize === false) {\n this._isIncluded = false;\n return;\n }\n\n // If filesList is provided, check if current file is included\n const filename = this.file.opts.filename\n ? normalizePath(this.file.opts.filename)\n : undefined;\n if (this.opts.filesList && filename) {\n const isIncluded = getNormalizedFilesListSet(this.opts.filesList).has(\n filename\n );\n\n if (!isIncluded) {\n // Force _isIncluded to false to skip processing\n this._isIncluded = false;\n return;\n }\n }\n },\n\n visitor: {\n /* If this file *is* the dictionaries entry, short-circuit: export {} */\n Program: {\n enter(programPath, state) {\n // Safe access to filename\n const filename = state.file.opts.filename\n ? normalizePath(state.file.opts.filename)\n : undefined;\n const dictionariesEntryPath = state.opts.dictionariesEntryPath\n ? normalizePath(state.opts.dictionariesEntryPath)\n : undefined;\n\n // Check if this is the correct file to transform\n\n if (\n state.opts.replaceDictionaryEntry &&\n filename === dictionariesEntryPath\n ) {\n state._isDictEntry = true;\n\n // Traverse the program to surgically remove/edit specific parts\n programPath.traverse({\n // Remove all import statements (cleaning up 'sssss.json')\n ImportDeclaration(path) {\n path.remove();\n },\n\n // Find the variable definition and empty the object\n VariableDeclarator(path) {\n // We look for: const x = { ... }\n\n if (t.isObjectExpression(path.node.init)) {\n // Set the object properties to an empty array: {}\n path.node.init.properties = [];\n }\n },\n });\n\n // (Optional) Stop other plugins from processing this file further if needed\n // programPath.stop();\n }\n },\n\n /**\n * After full traversal, process imports and call expressions, then inject the JSON dictionary imports.\n *\n * We do the transformation in Program.exit (via a manual traverse) rather than using\n * top-level ImportDeclaration/CallExpression visitors. This ensures that if another plugin\n * (like babel-plugin-intlayer-extract) adds new useIntlayer calls in its Program.exit,\n * we will see and transform them here because our Program.exit runs after theirs.\n */\n exit(programPath, state) {\n if (state._isDictEntry) return; // nothing else to do – already replaced\n\n if (!state._isIncluded) return; // early-out if file is not included\n\n // Compat callers the optimize pass can rewrite (injected by the\n // compat packages' bundler plugins — nothing is hard-coded here).\n const rewritableCompatCallers = getRewritableCallers(\n state.opts.compatCallers ?? []\n );\n\n // Manual traversal to process imports and call expressions\n // This runs AFTER all other plugins' visitors have completed\n programPath.traverse({\n /* Inspect every intlayer import before deciding helper rewrites. */\n ImportDeclaration(path) {\n const src = path.node.source.value;\n\n const isNativePackage = PACKAGE_LIST.includes(src);\n const compatCallersForSource = rewritableCompatCallers.filter(\n (descriptor) => descriptor.importSources.includes(src)\n );\n\n if (!isNativePackage && compatCallersForSource.length === 0) {\n return;\n }\n\n state._hasValidImport = true;\n\n for (const spec of path.node.specifiers) {\n if (!t.isImportSpecifier(spec)) continue;\n\n const importedName = t.isIdentifier(spec.imported)\n ? spec.imported.name\n : (spec.imported as BabelTypes.StringLiteral).value;\n\n if (isNativePackage && isCallerName(importedName)) {\n state._callerMap?.set(spec.local.name, importedName);\n state._callerPackageMap?.set(spec.local.name, src);\n }\n\n const compatDescriptor = compatCallersForSource.find(\n (descriptor) => descriptor.callerName === importedName\n );\n if (compatDescriptor) {\n state._compatCallerMap?.set(\n spec.local.name,\n compatDescriptor\n );\n }\n }\n },\n });\n\n // Pre-pass to determine if dictionary-level overrides require the\n // dynamic helper in an otherwise static file, and to disable the\n // rewrite for compat callers with unresolvable call sites.\n const packagesWithDynamicCall = new Set<string>();\n const packagesWithFetchCall = new Set<string>();\n let compatHasDynamicCall = false;\n const unresolvableCompatLocalNames = new Set<string>();\n programPath.traverse({\n CallExpression(path) {\n const callee = path.node.callee;\n\n if (!t.isIdentifier(callee)) return;\n\n const compatDescriptor = state._compatCallerMap?.get(callee.name);\n if (compatDescriptor) {\n const namespaceMatch = resolveCompatNamespaceMatch(\n t,\n path.node.arguments,\n compatDescriptor\n );\n\n if (!namespaceMatch) {\n // Dynamic/absent namespace: the whole local caller must keep\n // its original implementation — rewriting the import while\n // leaving this call untouched would hand a raw namespace\n // string to the dictionary-accepting helper.\n unresolvableCompatLocalNames.add(callee.name);\n return;\n }\n\n const { dictionaryKey } = splitNamespace(\n namespaceMatch.fullNamespace\n );\n const compatOverrideMode =\n state.opts.dictionaryModeMap?.[dictionaryKey];\n if (\n compatOverrideMode === 'dynamic' ||\n compatOverrideMode === 'fetch'\n ) {\n compatHasDynamicCall = true;\n }\n return;\n }\n\n const originalImportedName = state._callerMap?.get(callee.name);\n if (originalImportedName !== 'useIntlayer') return;\n\n const callerPackage = state._callerPackageMap?.get(callee.name);\n if (!callerPackage) return;\n\n const key = getKeyFromArgument(path.node.arguments[0], t);\n if (!key) return;\n\n const dictionaryOverrideMode =\n state.opts.dictionaryModeMap?.[key];\n\n if (dictionaryOverrideMode === 'dynamic') {\n packagesWithDynamicCall.add(callerPackage);\n } else if (dictionaryOverrideMode === 'fetch') {\n packagesWithFetchCall.add(callerPackage);\n }\n },\n });\n\n for (const localName of unresolvableCompatLocalNames) {\n state._compatCallerMap?.delete(localName);\n }\n\n const getHelperPlan = (packageName: string): PackageHelperPlan =>\n resolveHelperPlan(\n packageName,\n state.opts.importMode,\n state.opts.isServer,\n packagesWithDynamicCall.has(packageName),\n packagesWithFetchCall.has(packageName)\n );\n\n // Compat helpers are swapped per file (one import specifier serves\n // every call), so the dynamic decision is file-level: a global\n // dynamic/fetch mode or any per-dictionary override flips all\n // rewritten compat calls to the dynamic helper.\n const compatUseDynamicHelpers =\n state.opts.importMode === 'dynamic' ||\n state.opts.importMode === 'fetch' ||\n compatHasDynamicCall;\n\n programPath.traverse({\n ImportDeclaration(path) {\n const src = path.node.source.value;\n\n // Compat caller import rename: point the specifier at the\n // dictionary-accepting helper exported by the compat package\n // (`useTranslation` → `useDictionary`), keeping the local alias\n // so call sites read unchanged. Locals with unresolvable call\n // sites were dropped from the map and keep the original import.\n for (const spec of path.node.specifiers) {\n if (!t.isImportSpecifier(spec)) continue;\n\n const compatDescriptor = state._compatCallerMap?.get(\n spec.local.name\n );\n if (!compatDescriptor) continue;\n if (!compatDescriptor.importSources.includes(src)) continue;\n\n spec.imported = t.identifier(\n compatUseDynamicHelpers\n ? compatDescriptor.dynamicReplacement!\n : compatDescriptor.staticReplacement!\n );\n }\n\n if (!PACKAGE_LIST.includes(src)) return;\n\n // Per-import swap, mirrored across bundles — Solid hydration\n // ids rely on the SSR and client helpers consuming one\n // resource slot per call alike (see solid-intlayer/server).\n const helperPlan = getHelperPlan(src);\n const serverSource =\n helperPlan === 'ssrStatic'\n ? SSR_STATIC_IMPORT_SOURCE[src]\n : undefined;\n\n const helperMap: Record<string, string> =\n helperPlan === 'dynamic'\n ? DYNAMIC_HELPER_MAP\n : STATIC_IMPORT_FUNCTION;\n\n const serverSpecifiers: BabelTypes.ImportSpecifier[] = [];\n\n for (const spec of path.node.specifiers) {\n if (!t.isImportSpecifier(spec)) continue;\n\n const importedName = t.isIdentifier(spec.imported)\n ? spec.imported.name\n : (spec.imported as BabelTypes.StringLiteral).value;\n\n if (!isCallerName(importedName)) continue;\n\n if (serverSource && importedName === 'useIntlayer') {\n spec.imported = t.identifier('useDictionary');\n serverSpecifiers.push(spec);\n continue;\n }\n\n const newIdentifier = helperMap[importedName];\n\n if (newIdentifier) {\n // Keep the local alias intact (so calls remain `useIntlayer` /\n // `getIntlayer`), but rewrite the imported identifier so it\n // points to our helper implementation.\n spec.imported = t.identifier(newIdentifier);\n }\n }\n\n if (serverSpecifiers.length > 0 && serverSource) {\n // Move the helper to the /server entry, keeping any other\n // specifiers (useLocale, …) on the original import.\n path.insertAfter(\n t.importDeclaration(\n serverSpecifiers,\n t.stringLiteral(serverSource)\n )\n );\n path.node.specifiers = path.node.specifiers.filter(\n (spec) =>\n !serverSpecifiers.includes(\n spec as BabelTypes.ImportSpecifier\n )\n );\n if (path.node.specifiers.length === 0) {\n path.remove();\n }\n }\n },\n\n /* Replace calls: useIntlayer(\"foo\") → useDictionary(_hash) or useDictionaryDynamic(_hash, \"foo\") */\n CallExpression(path) {\n const callee = path.node.callee;\n\n if (!t.isIdentifier(callee)) return;\n\n // Compat caller rewrite, e.g. (mirroring the SWC plugin):\n // static: useTranslation('about.counter', opts)\n // → useDictionary(_hash, 'counter', opts)\n // dynamic: useTranslation('about.counter', opts)\n // → useDictionaryDynamic(_hash_dyn, 'about', 'counter', opts)\n // option: useI18n({ namespace: 'about' })\n // → useDictionary(_hash, {})\n // fixed: useLingui() → useDictionary(_hash)\n const compatDescriptor = state._compatCallerMap?.get(callee.name);\n if (compatDescriptor) {\n const callArguments = path.node.arguments;\n const namespaceMatch = resolveCompatNamespaceMatch(\n t,\n callArguments,\n compatDescriptor\n );\n if (!namespaceMatch) return; // filtered by the pre-pass — stay safe\n\n state._hasValidImport = true;\n\n const { dictionaryKey, keyPrefix } = splitNamespace(\n namespaceMatch.fullNamespace\n );\n const compatOverrideMode =\n state.opts.dictionaryModeMap?.[dictionaryKey];\n\n // The import specifier serves every call in the file, so a\n // dynamic file receives a dynamic loader for every call.\n let compatCallMode: ImportMode = 'static';\n if (compatUseDynamicHelpers) {\n if (\n compatOverrideMode === 'dynamic' ||\n compatOverrideMode === 'fetch'\n ) {\n compatCallMode = compatOverrideMode;\n } else if (\n state.opts.importMode === 'dynamic' ||\n state.opts.importMode === 'fetch'\n ) {\n compatCallMode = state.opts.importMode;\n } else {\n compatCallMode = 'dynamic';\n }\n }\n\n let dictionaryIdent: BabelTypes.Identifier;\n if (compatCallMode === 'static') {\n let staticIdent = state._newStaticImports?.get(dictionaryKey);\n if (!staticIdent) {\n staticIdent = makeIdent(dictionaryKey, t);\n state._newStaticImports?.set(dictionaryKey, staticIdent);\n }\n dictionaryIdent = staticIdent;\n } else {\n let dynamicIdent =\n state._newDynamicImports?.get(dictionaryKey);\n if (!dynamicIdent) {\n const hash = getPathHash(dictionaryKey);\n const suffix = compatCallMode === 'fetch' ? 'fetch' : 'dyn';\n dynamicIdent = t.identifier(`_${hash}_${suffix}`);\n state._newDynamicImports?.set(dictionaryKey, dynamicIdent);\n }\n dictionaryIdent = dynamicIdent;\n }\n\n if (namespaceMatch.argumentIndex !== undefined) {\n // Positional namespace: replace the string with the\n // dictionary, then (dynamic) key and (nested) prefix.\n callArguments[namespaceMatch.argumentIndex] = t.identifier(\n dictionaryIdent.name\n );\n const insertAt = namespaceMatch.argumentIndex + 1;\n const insertedArguments: BabelTypes.Expression[] = [];\n if (compatCallMode !== 'static') {\n insertedArguments.push(t.stringLiteral(dictionaryKey));\n }\n if (keyPrefix) {\n insertedArguments.push(t.stringLiteral(keyPrefix));\n }\n callArguments.splice(insertAt, 0, ...insertedArguments);\n } else if (compatCallMode !== 'static') {\n // Fixed / option namespace, dynamic helper: prepend the\n // loader and the dictionary key.\n callArguments.unshift(\n t.identifier(dictionaryIdent.name),\n t.stringLiteral(dictionaryKey)\n );\n } else {\n // Fixed / option namespace, static helper: prepend the\n // dictionary object.\n callArguments.unshift(t.identifier(dictionaryIdent.name));\n }\n\n // Option namespace: leave only the key-prefix remainder in the\n // options object (or drop the property for a plain namespace),\n // so the runtime helper does not re-apply the dictionary key\n // as a lookup prefix.\n if (\n namespaceMatch.optionProperty &&\n namespaceMatch.optionsObject\n ) {\n if (keyPrefix) {\n namespaceMatch.optionProperty.value =\n t.stringLiteral(keyPrefix);\n } else {\n namespaceMatch.optionsObject.properties =\n namespaceMatch.optionsObject.properties.filter(\n (property) => property !== namespaceMatch.optionProperty\n );\n }\n }\n\n return;\n }\n\n const originalImportedName = state._callerMap?.get(callee.name);\n if (!originalImportedName) return;\n\n // Ensure we ultimately emit helper imports for files that *invoke*\n // the hooks, even if they didn't import them directly (edge cases with\n // re-exports).\n state._hasValidImport = true;\n\n const key = getKeyFromArgument(path.node.arguments[0], t);\n if (!key) return;\n\n const callerPackage = state._callerPackageMap?.get(callee.name);\n const importMode = state.opts.importMode;\n const isUseIntlayer = originalImportedName === 'useIntlayer';\n const dictionaryOverrideMode =\n state.opts.dictionaryModeMap?.[key];\n const helperPlan =\n callerPackage === undefined\n ? 'static'\n : getHelperPlan(callerPackage);\n\n // Decide per-call mode: 'static' | 'dynamic' | 'fetch'.\n let perCallMode: ImportMode = 'static';\n\n if (isUseIntlayer && helperPlan === 'dynamic') {\n if (dictionaryOverrideMode) {\n perCallMode = dictionaryOverrideMode;\n } else if (importMode === 'dynamic' || importMode === 'fetch') {\n perCallMode = importMode;\n }\n } else if (isUseIntlayer && helperPlan === 'static') {\n // The global mode is static, but a per-dictionary override can\n // still force dynamic/fetch for this specific call.\n if (\n dictionaryOverrideMode === 'dynamic' ||\n dictionaryOverrideMode === 'fetch'\n ) {\n perCallMode = dictionaryOverrideMode;\n }\n }\n\n let ident: BabelTypes.Identifier;\n\n if (perCallMode === 'fetch') {\n // Use fetch dictionaries entry for selected keys\n let dynamicIdent = state._newDynamicImports?.get(key);\n\n if (!dynamicIdent) {\n const hash = getPathHash(key);\n dynamicIdent = t.identifier(`_${hash}_fetch`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Helper: first argument is the dictionary entry, second is the key\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else if (perCallMode === 'dynamic') {\n // Use dynamic dictionaries entry\n let dynamicIdent = state._newDynamicImports?.get(key);\n\n if (!dynamicIdent) {\n // Create a unique identifier for dynamic imports by appending a suffix\n const hash = getPathHash(key);\n dynamicIdent = t.identifier(`_${hash}_dyn`);\n state._newDynamicImports?.set(key, dynamicIdent);\n }\n ident = dynamicIdent;\n\n // Dynamic helper: first argument is the dictionary, second is the key.\n path.node.arguments = [\n t.identifier(ident.name),\n ...path.node.arguments,\n ];\n } else {\n // Use static imports for getIntlayer or useIntlayer when not using dynamic helpers\n let staticIdent = state._newStaticImports?.get(key);\n\n if (!staticIdent) {\n staticIdent = makeIdent(key, t);\n state._newStaticImports?.set(key, staticIdent);\n }\n ident = staticIdent;\n\n // Static helper (useDictionary / getDictionary): replace key with ident.\n // After the splice above the key is always at index 0.\n path.node.arguments[0] = t.identifier(ident.name);\n }\n },\n });\n\n // Early-out if we touched nothing\n\n if (!state._hasValidImport) return;\n\n const file = state.file.opts.filename!;\n const dictionariesDir = state.opts.dictionariesDir;\n const dynamicDictionariesDir = state.opts.dynamicDictionariesDir;\n const fetchDictionariesDir = state.opts.fetchDictionariesDir;\n const imports: BabelTypes.ImportDeclaration[] = [];\n\n const nestingDictionaryKeys = new Set(\n state.opts.nestingDictionaryKeys ?? []\n );\n\n // Generate static JSON imports (getIntlayer always uses JSON dictionaries)\n for (const [key, ident] of state._newStaticImports!) {\n // Dictionaries holding `nest()` references are imported through\n // their companion module, which re-exports them with the nest\n // targets attached.\n const hasNestedDictionaries = nestingDictionaryKeys.has(key);\n\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n 'static',\n hasNestedDictionaries\n );\n\n const importDeclarationNode = t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n );\n\n // Add 'type: json' attribute for JSON files\n if (!hasNestedDictionaries) {\n importDeclarationNode.attributes = [\n t.importAttribute(\n t.identifier('type'),\n t.stringLiteral('json')\n ),\n ];\n }\n\n imports.push(importDeclarationNode);\n }\n\n // Generate dynamic/fetch imports (for useIntlayer when using dynamic/fetch helpers)\n for (const [key, ident] of state._newDynamicImports!) {\n const modeForThisIdent: 'dynamic' | 'fetch' = ident.name.endsWith(\n '_fetch'\n )\n ? 'fetch'\n : 'dynamic';\n\n const rel = computeImport(\n file,\n dictionariesDir,\n dynamicDictionariesDir,\n fetchDictionariesDir,\n key,\n modeForThisIdent\n );\n imports.push(\n t.importDeclaration(\n [t.importDefaultSpecifier(t.identifier(ident.name))],\n t.stringLiteral(rel)\n )\n );\n }\n\n if (!imports.length) return;\n\n /* Keep \"use client\" / \"use server\" directives at the very top. */\n const bodyPaths = programPath.get(\n 'body'\n ) as NodePath<BabelTypes.Statement>[];\n let insertPos = 0;\n for (const stmtPath of bodyPaths) {\n const stmt = stmtPath.node;\n\n if (\n t.isExpressionStatement(stmt) &&\n t.isStringLiteral(stmt.expression) &&\n !stmt.expression.value.startsWith('import') &&\n !stmt.expression.value.startsWith('require')\n ) {\n insertPos += 1;\n } else {\n break;\n }\n }\n\n programPath.node.body.splice(insertPos, 0, ...imports);\n },\n },\n },\n };\n};\n"],"mappings":";;;;;;;;AAWA,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,cAAc,CAAC,eAAe,aAAa;;;;AAKjD,MAAM,uBAAuB;CAC3B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,yBAAyB;CAC7B,aAAa;CACb,aAAa;AACf;AAEA,MAAM,0BAA0B,EAC9B,aAAa,uBACf;;AAGA,MAAM,qBAA6C;CACjD,GAAG;CACH,GAAG;AACL;;;;;;;;AASA,MAAM,2BAA4D,EAChE,kBAAkB,wBACpB;;;;;;AA4HA,MAAM,aACJ,KACA,MAC0B;CAC1B,MAAM,WAAOA,oCAAY,GAAG;CAC5B,OAAO,EAAE,WAAW,IAAI,MAAM;AAChC;;;;;;AAOA,MAAM,uBAAuB,UAAkB,eAA+B;CAE5E,MAAM,mBAAeC,0CAAcC,wBAASC,mBAAQ,QAAQ,GAAG,UAAU,CAAC;CAG1E,IAAI,CAAC,aAAa,WAAW,IAAI,KAAK,CAAC,aAAa,WAAW,KAAK,GAClE,OAAO,KAAK;CAGd,OAAO;AACT;;;;;;AAOA,MAAM,6BAA6B;AAEnC,MAAM,iBACJ,UACA,iBACA,wBACA,sBACA,KACA,YACA,wBAAwB,UACb;CAGX,IAAI,iBAAiB,4BACjBC,gBAAK,iBAAiB,4BAA4B,GAAG,IAAI,KAAK,QAC9DA,gBAAK,iBAAiB,GAAG,IAAI,MAAM;CAEvC,IAAI,eAAe,SACjB,qBAAiBA,gBAAK,sBAAsB,GAAG,IAAI,KAAK;CAG1D,IAAI,eAAe,WACjB,qBAAiBA,gBAAK,wBAAwB,GAAG,IAAI,KAAK;CAG5D,OAAO,oBAAoB,UAAU,cAAc;AACrD;AAEA,MAAM,sBACJ,KACA,MACuB;CACvB,IAAI,OAAO,EAAE,gBAAgB,GAAG,GAC9B,OAAO,IAAI;CAGb,IACE,OACA,EAAE,kBAAkB,GAAG,KACvB,IAAI,YAAY,WAAW,KAC3B,IAAI,OAAO,WAAW,GAEtB,OAAO,IAAI,OAAO,EAAE,EAAE,MAAM,UAAU,IAAI,OAAO,EAAE,EAAE,MAAM;AAI/D;AAEA,MAAM,gBAAgB,SACpB,YAAY,SAAS,IAAkB;;;;;;;;;AAUzC,MAAM,kBACJ,cACiD;CACjD,MAAM,cAAc,UAAU,QAAQ,GAAG;CACzC,IAAI,gBAAgB,IAAI,OAAO;EAAE,eAAe;EAAW,WAAW;CAAG;CACzE,OAAO;EACL,eAAe,UAAU,MAAM,GAAG,WAAW;EAC7C,WAAW,UAAU,MAAM,cAAc,CAAC;CAC5C;AACF;;;;;;;;;AA4BA,MAAM,+BACJ,GACA,eACA,eACqC;CACrC,KAAK,MAAM,UAAU,WAAW,kBAAkB;EAChD,IAAI,OAAO,SAAS,SAClB,OAAO,EAAE,eAAe,OAAO,MAAM;EAGvC,IAAI,OAAO,SAAS,YAAY;GAC9B,MAAM,YAAY,mBAAmB,cAAc,OAAO,QAAQ,CAAC;GACnE,IAAI,cAAc,QAChB,OAAO;IAAE,eAAe;IAAW,eAAe,OAAO;GAAM;GAEjE;EACF;EAEA,IAAI,OAAO,SAAS,UAAU;GAC5B,MAAM,kBAAkB,cAAc,OAAO;GAC7C,IAAI,CAAC,mBAAmB,CAAC,EAAE,mBAAmB,eAAe,GAAG;GAEhE,KAAK,MAAM,YAAY,gBAAgB,YAAY;IACjD,IAAI,CAAC,EAAE,iBAAiB,QAAQ,GAAG;IAMnC,IAAI,EAJD,EAAE,aAAa,SAAS,GAAG,KAC1B,SAAS,IAAI,SAAS,OAAO,YAC9B,EAAE,gBAAgB,SAAS,GAAG,KAC7B,SAAS,IAAI,UAAU,OAAO,WACjB;IAEjB,MAAM,YAAY,mBAAmB,SAAS,OAAO,CAAC;IACtD,IAAI,cAAc,QAChB,OAAO;KACL,eAAe;KACf,gBAAgB;KAChB,eAAe;IACjB;GAEJ;EACF;CACF;AAGF;AAEA,MAAM,oBACJ,gBAEA,qBAAqB,SACnB,WACF;;;;;;;;;AAoBF,MAAM,qBACJ,aACA,YACA,UACA,uBACA,wBACsB;CACtB,IAAI,CAAC,iBAAiB,WAAW,GAAG,OAAO;CAE3C,IAAI,eAAe,WAAW,qBAAqB,OAAO;CAE1D,IAAI,eAAe,aAAa,uBAC9B,OAAO,aAAa,OAAO,cAAc;CAG3C,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoFA,MAAa,+BAA+B,UAEjB;CACzB,MAAM,EAAE,OAAO,MAAM;CAErB,OAAO;EACL,MAAM;EAEN,MAAM;GACJ,KAAK,oCAAoB,IAAI,IAAI;GACjC,KAAK,qCAAqB,IAAI,IAAI;GAClC,KAAK,6BAAa,IAAI,IAAI;GAC1B,KAAK,oCAAoB,IAAI,IAAI;GACjC,KAAK,mCAAmB,IAAI,IAAI;GAChC,KAAK,cAAc;GACnB,KAAK,kBAAkB;GACvB,KAAK,eAAe;GAGpB,IAAI,KAAK,KAAK,aAAa,OAAO;IAChC,KAAK,cAAc;IACnB;GACF;GAGA,MAAM,WAAW,KAAK,KAAK,KAAK,eAC5BH,sCAAc,KAAK,KAAK,KAAK,QAAQ,IACrC;GACJ,IAAI,KAAK,KAAK,aAAa,UAKzB;QAAI,CAJeI,sDAA0B,KAAK,KAAK,SAAS,CAAC,CAAC,IAChE,QAGY,GAAG;KAEf,KAAK,cAAc;KACnB;IACF;;EAEJ;EAEA,SAAS,EAEP,SAAS;GACP,MAAM,aAAa,OAAO;IAExB,MAAM,WAAW,MAAM,KAAK,KAAK,eAC7BJ,sCAAc,MAAM,KAAK,KAAK,QAAQ,IACtC;IACJ,MAAM,wBAAwB,MAAM,KAAK,4BACrCA,sCAAc,MAAM,KAAK,qBAAqB,IAC9C;IAIJ,IACE,MAAM,KAAK,0BACX,aAAa,uBACb;KACA,MAAM,eAAe;KAGrB,YAAY,SAAS;MAEnB,kBAAkB,MAAM;OACtB,KAAK,OAAO;MACd;MAGA,mBAAmB,MAAM;OAGvB,IAAI,EAAE,mBAAmB,KAAK,KAAK,IAAI,GAErC,KAAK,KAAK,KAAK,aAAa,CAAC;MAEjC;KACF,CAAC;IAIH;GACF;;;;;;;;;GAUA,KAAK,aAAa,OAAO;IACvB,IAAI,MAAM,cAAc;IAExB,IAAI,CAAC,MAAM,aAAa;IAIxB,MAAM,8BAA0BK,+CAC9B,MAAM,KAAK,iBAAiB,CAAC,CAC/B;IAIA,YAAY,SAAS,EAEnB,kBAAkB,MAAM;KACtB,MAAM,MAAM,KAAK,KAAK,OAAO;KAE7B,MAAM,kBAAkB,aAAa,SAAS,GAAG;KACjD,MAAM,yBAAyB,wBAAwB,QACpD,eAAe,WAAW,cAAc,SAAS,GAAG,CACvD;KAEA,IAAI,CAAC,mBAAmB,uBAAuB,WAAW,GACxD;KAGF,MAAM,kBAAkB;KAExB,KAAK,MAAM,QAAQ,KAAK,KAAK,YAAY;MACvC,IAAI,CAAC,EAAE,kBAAkB,IAAI,GAAG;MAEhC,MAAM,eAAe,EAAE,aAAa,KAAK,QAAQ,IAC7C,KAAK,SAAS,OACb,KAAK,SAAsC;MAEhD,IAAI,mBAAmB,aAAa,YAAY,GAAG;OACjD,MAAM,YAAY,IAAI,KAAK,MAAM,MAAM,YAAY;OACnD,MAAM,mBAAmB,IAAI,KAAK,MAAM,MAAM,GAAG;MACnD;MAEA,MAAM,mBAAmB,uBAAuB,MAC7C,eAAe,WAAW,eAAe,YAC5C;MACA,IAAI,kBACF,MAAM,kBAAkB,IACtB,KAAK,MAAM,MACX,gBACF;KAEJ;IACF,EACF,CAAC;IAKD,MAAM,0CAA0B,IAAI,IAAY;IAChD,MAAM,wCAAwB,IAAI,IAAY;IAC9C,IAAI,uBAAuB;IAC3B,MAAM,+CAA+B,IAAI,IAAY;IACrD,YAAY,SAAS,EACnB,eAAe,MAAM;KACnB,MAAM,SAAS,KAAK,KAAK;KAEzB,IAAI,CAAC,EAAE,aAAa,MAAM,GAAG;KAE7B,MAAM,mBAAmB,MAAM,kBAAkB,IAAI,OAAO,IAAI;KAChE,IAAI,kBAAkB;MACpB,MAAM,iBAAiB,4BACrB,GACA,KAAK,KAAK,WACV,gBACF;MAEA,IAAI,CAAC,gBAAgB;OAKnB,6BAA6B,IAAI,OAAO,IAAI;OAC5C;MACF;MAEA,MAAM,EAAE,kBAAkB,eACxB,eAAe,aACjB;MACA,MAAM,qBACJ,MAAM,KAAK,oBAAoB;MACjC,IACE,uBAAuB,aACvB,uBAAuB,SAEvB,uBAAuB;MAEzB;KACF;KAGA,IAD6B,MAAM,YAAY,IAAI,OAAO,IAAI,MACjC,eAAe;KAE5C,MAAM,gBAAgB,MAAM,mBAAmB,IAAI,OAAO,IAAI;KAC9D,IAAI,CAAC,eAAe;KAEpB,MAAM,MAAM,mBAAmB,KAAK,KAAK,UAAU,IAAI,CAAC;KACxD,IAAI,CAAC,KAAK;KAEV,MAAM,yBACJ,MAAM,KAAK,oBAAoB;KAEjC,IAAI,2BAA2B,WAC7B,wBAAwB,IAAI,aAAa;UACpC,IAAI,2BAA2B,SACpC,sBAAsB,IAAI,aAAa;IAE3C,EACF,CAAC;IAED,KAAK,MAAM,aAAa,8BACtB,MAAM,kBAAkB,OAAO,SAAS;IAG1C,MAAM,iBAAiB,gBACrB,kBACE,aACA,MAAM,KAAK,YACX,MAAM,KAAK,UACX,wBAAwB,IAAI,WAAW,GACvC,sBAAsB,IAAI,WAAW,CACvC;IAMF,MAAM,0BACJ,MAAM,KAAK,eAAe,aAC1B,MAAM,KAAK,eAAe,WAC1B;IAEF,YAAY,SAAS;KACnB,kBAAkB,MAAM;MACtB,MAAM,MAAM,KAAK,KAAK,OAAO;MAO7B,KAAK,MAAM,QAAQ,KAAK,KAAK,YAAY;OACvC,IAAI,CAAC,EAAE,kBAAkB,IAAI,GAAG;OAEhC,MAAM,mBAAmB,MAAM,kBAAkB,IAC/C,KAAK,MAAM,IACb;OACA,IAAI,CAAC,kBAAkB;OACvB,IAAI,CAAC,iBAAiB,cAAc,SAAS,GAAG,GAAG;OAEnD,KAAK,WAAW,EAAE,WAChB,0BACI,iBAAiB,qBACjB,iBAAiB,iBACvB;MACF;MAEA,IAAI,CAAC,aAAa,SAAS,GAAG,GAAG;MAKjC,MAAM,aAAa,cAAc,GAAG;MACpC,MAAM,eACJ,eAAe,cACX,yBAAyB,OACzB;MAEN,MAAM,YACJ,eAAe,YACX,qBACA;MAEN,MAAM,mBAAiD,CAAC;MAExD,KAAK,MAAM,QAAQ,KAAK,KAAK,YAAY;OACvC,IAAI,CAAC,EAAE,kBAAkB,IAAI,GAAG;OAEhC,MAAM,eAAe,EAAE,aAAa,KAAK,QAAQ,IAC7C,KAAK,SAAS,OACb,KAAK,SAAsC;OAEhD,IAAI,CAAC,aAAa,YAAY,GAAG;OAEjC,IAAI,gBAAgB,iBAAiB,eAAe;QAClD,KAAK,WAAW,EAAE,WAAW,eAAe;QAC5C,iBAAiB,KAAK,IAAI;QAC1B;OACF;OAEA,MAAM,gBAAgB,UAAU;OAEhC,IAAI,eAIF,KAAK,WAAW,EAAE,WAAW,aAAa;MAE9C;MAEA,IAAI,iBAAiB,SAAS,KAAK,cAAc;OAG/C,KAAK,YACH,EAAE,kBACA,kBACA,EAAE,cAAc,YAAY,CAC9B,CACF;OACA,KAAK,KAAK,aAAa,KAAK,KAAK,WAAW,QACzC,SACC,CAAC,iBAAiB,SAChB,IACF,CACJ;OACA,IAAI,KAAK,KAAK,WAAW,WAAW,GAClC,KAAK,OAAO;MAEhB;KACF;KAGA,eAAe,MAAM;MACnB,MAAM,SAAS,KAAK,KAAK;MAEzB,IAAI,CAAC,EAAE,aAAa,MAAM,GAAG;MAU7B,MAAM,mBAAmB,MAAM,kBAAkB,IAAI,OAAO,IAAI;MAChE,IAAI,kBAAkB;OACpB,MAAM,gBAAgB,KAAK,KAAK;OAChC,MAAM,iBAAiB,4BACrB,GACA,eACA,gBACF;OACA,IAAI,CAAC,gBAAgB;OAErB,MAAM,kBAAkB;OAExB,MAAM,EAAE,eAAe,cAAc,eACnC,eAAe,aACjB;OACA,MAAM,qBACJ,MAAM,KAAK,oBAAoB;OAIjC,IAAI,iBAA6B;OACjC,IAAI,yBAAyB;QAC3B,IACE,uBAAuB,aACvB,uBAAuB,SAEvB,iBAAiB;aACZ,IACL,MAAM,KAAK,eAAe,aAC1B,MAAM,KAAK,eAAe,SAE1B,iBAAiB,MAAM,KAAK;aAE5B,iBAAiB;OAErB;OAEA,IAAI;OACJ,IAAI,mBAAmB,UAAU;QAC/B,IAAI,cAAc,MAAM,mBAAmB,IAAI,aAAa;QAC5D,IAAI,CAAC,aAAa;SAChB,cAAc,UAAU,eAAe,CAAC;SACxC,MAAM,mBAAmB,IAAI,eAAe,WAAW;QACzD;QACA,kBAAkB;OACpB,OAAO;QACL,IAAI,eACF,MAAM,oBAAoB,IAAI,aAAa;QAC7C,IAAI,CAAC,cAAc;SACjB,MAAM,WAAON,oCAAY,aAAa;SACtC,MAAM,SAAS,mBAAmB,UAAU,UAAU;SACtD,eAAe,EAAE,WAAW,IAAI,KAAK,GAAG,QAAQ;SAChD,MAAM,oBAAoB,IAAI,eAAe,YAAY;QAC3D;QACA,kBAAkB;OACpB;OAEA,IAAI,eAAe,kBAAkB,QAAW;QAG9C,cAAc,eAAe,iBAAiB,EAAE,WAC9C,gBAAgB,IAClB;QACA,MAAM,WAAW,eAAe,gBAAgB;QAChD,MAAM,oBAA6C,CAAC;QACpD,IAAI,mBAAmB,UACrB,kBAAkB,KAAK,EAAE,cAAc,aAAa,CAAC;QAEvD,IAAI,WACF,kBAAkB,KAAK,EAAE,cAAc,SAAS,CAAC;QAEnD,cAAc,OAAO,UAAU,GAAG,GAAG,iBAAiB;OACxD,OAAO,IAAI,mBAAmB,UAG5B,cAAc,QACZ,EAAE,WAAW,gBAAgB,IAAI,GACjC,EAAE,cAAc,aAAa,CAC/B;YAIA,cAAc,QAAQ,EAAE,WAAW,gBAAgB,IAAI,CAAC;OAO1D,IACE,eAAe,kBACf,eAAe,eACf;QACA,IAAI,WACF,eAAe,eAAe,QAC5B,EAAE,cAAc,SAAS;aAE3B,eAAe,cAAc,aAC3B,eAAe,cAAc,WAAW,QACrC,aAAa,aAAa,eAAe,cAC5C;OAEN;OAEA;MACF;MAEA,MAAM,uBAAuB,MAAM,YAAY,IAAI,OAAO,IAAI;MAC9D,IAAI,CAAC,sBAAsB;MAK3B,MAAM,kBAAkB;MAExB,MAAM,MAAM,mBAAmB,KAAK,KAAK,UAAU,IAAI,CAAC;MACxD,IAAI,CAAC,KAAK;MAEV,MAAM,gBAAgB,MAAM,mBAAmB,IAAI,OAAO,IAAI;MAC9D,MAAM,aAAa,MAAM,KAAK;MAC9B,MAAM,gBAAgB,yBAAyB;MAC/C,MAAM,yBACJ,MAAM,KAAK,oBAAoB;MACjC,MAAM,aACJ,kBAAkB,SACd,WACA,cAAc,aAAa;MAGjC,IAAI,cAA0B;MAE9B,IAAI,iBAAiB,eAAe,WAAW;OAC7C,IAAI,wBACF,cAAc;YACT,IAAI,eAAe,aAAa,eAAe,SACpD,cAAc;MAElB,OAAO,IAAI,iBAAiB,eAAe,UAGzC;WACE,2BAA2B,aAC3B,2BAA2B,SAE3B,cAAc;MAChB;MAGF,IAAI;MAEJ,IAAI,gBAAgB,SAAS;OAE3B,IAAI,eAAe,MAAM,oBAAoB,IAAI,GAAG;OAEpD,IAAI,CAAC,cAAc;QACjB,MAAM,WAAOA,oCAAY,GAAG;QAC5B,eAAe,EAAE,WAAW,IAAI,KAAK,OAAO;QAC5C,MAAM,oBAAoB,IAAI,KAAK,YAAY;OACjD;OACA,QAAQ;OAGR,KAAK,KAAK,YAAY,CACpB,EAAE,WAAW,MAAM,IAAI,GACvB,GAAG,KAAK,KAAK,SACf;MACF,OAAO,IAAI,gBAAgB,WAAW;OAEpC,IAAI,eAAe,MAAM,oBAAoB,IAAI,GAAG;OAEpD,IAAI,CAAC,cAAc;QAEjB,MAAM,WAAOA,oCAAY,GAAG;QAC5B,eAAe,EAAE,WAAW,IAAI,KAAK,KAAK;QAC1C,MAAM,oBAAoB,IAAI,KAAK,YAAY;OACjD;OACA,QAAQ;OAGR,KAAK,KAAK,YAAY,CACpB,EAAE,WAAW,MAAM,IAAI,GACvB,GAAG,KAAK,KAAK,SACf;MACF,OAAO;OAEL,IAAI,cAAc,MAAM,mBAAmB,IAAI,GAAG;OAElD,IAAI,CAAC,aAAa;QAChB,cAAc,UAAU,KAAK,CAAC;QAC9B,MAAM,mBAAmB,IAAI,KAAK,WAAW;OAC/C;OACA,QAAQ;OAIR,KAAK,KAAK,UAAU,KAAK,EAAE,WAAW,MAAM,IAAI;MAClD;KACF;IACF,CAAC;IAID,IAAI,CAAC,MAAM,iBAAiB;IAE5B,MAAM,OAAO,MAAM,KAAK,KAAK;IAC7B,MAAM,kBAAkB,MAAM,KAAK;IACnC,MAAM,yBAAyB,MAAM,KAAK;IAC1C,MAAM,uBAAuB,MAAM,KAAK;IACxC,MAAM,UAA0C,CAAC;IAEjD,MAAM,wBAAwB,IAAI,IAChC,MAAM,KAAK,yBAAyB,CAAC,CACvC;IAGA,KAAK,MAAM,CAAC,KAAK,UAAU,MAAM,mBAAoB;KAInD,MAAM,wBAAwB,sBAAsB,IAAI,GAAG;KAE3D,MAAM,MAAM,cACV,MACA,iBACA,wBACA,sBACA,KACA,UACA,qBACF;KAEA,MAAM,wBAAwB,EAAE,kBAC9B,CAAC,EAAE,uBAAuB,EAAE,WAAW,MAAM,IAAI,CAAC,CAAC,GACnD,EAAE,cAAc,GAAG,CACrB;KAGA,IAAI,CAAC,uBACH,sBAAsB,aAAa,CACjC,EAAE,gBACA,EAAE,WAAW,MAAM,GACnB,EAAE,cAAc,MAAM,CACxB,CACF;KAGF,QAAQ,KAAK,qBAAqB;IACpC;IAGA,KAAK,MAAM,CAAC,KAAK,UAAU,MAAM,oBAAqB;KACpD,MAAM,mBAAwC,MAAM,KAAK,SACvD,QACF,IACI,UACA;KAEJ,MAAM,MAAM,cACV,MACA,iBACA,wBACA,sBACA,KACA,gBACF;KACA,QAAQ,KACN,EAAE,kBACA,CAAC,EAAE,uBAAuB,EAAE,WAAW,MAAM,IAAI,CAAC,CAAC,GACnD,EAAE,cAAc,GAAG,CACrB,CACF;IACF;IAEA,IAAI,CAAC,QAAQ,QAAQ;IAGrB,MAAM,YAAY,YAAY,IAC5B,MACF;IACA,IAAI,YAAY;IAChB,KAAK,MAAM,YAAY,WAAW;KAChC,MAAM,OAAO,SAAS;KAEtB,IACE,EAAE,sBAAsB,IAAI,KAC5B,EAAE,gBAAgB,KAAK,UAAU,KACjC,CAAC,KAAK,WAAW,MAAM,WAAW,QAAQ,KAC1C,CAAC,KAAK,WAAW,MAAM,WAAW,SAAS,GAE3C,aAAa;UAEb;IAEJ;IAEA,YAAY,KAAK,KAAK,OAAO,WAAW,GAAG,GAAG,OAAO;GACvD;EACF,EACF;CACF;AACF"}