nuxt-i18n-micro 1.60.0 → 1.62.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import{_ as a,o as i,c as u,a as e,t as r,b as c,w as l,d,e as p}from"./C9njAg9E.js";import{u as f}from"./EwNUkbJF.js";const m={class:"antialiased bg-white dark:bg-black dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-black"},g={class:"max-w-520px text-center z-20"},h=["textContent"],b=["textContent"],x={class:"flex items-center justify-center w-full"},y={__name:"error-404",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},statusCode:{type:Number,default:404},statusMessage:{type:String,default:"Not Found"},description:{type:String,default:"Sorry, the page you are looking for could not be found."},backHome:{type:String,default:"Go back home"}},setup(t){const n=t;return f({title:`${n.statusCode} - ${n.statusMessage} | ${n.appName}`,script:[{children:`!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver((e=>{for(const o of e)if("childList"===o.type)for(const e of o.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)})).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;const r=function(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?r.credentials="include":"anonymous"===e.crossOrigin?r.credentials="omit":r.credentials="same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{children:'*,:after,:before{border-color:var(--un-default-border-color,#e5e7eb);border-style:solid;border-width:0;box-sizing:border-box}:after,:before{--un-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}h1{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}h1,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }'}]}),(k,o)=>{const s=p;return i(),u("div",m,[o[0]||(o[0]=e("div",{class:"fixed left-0 right-0 spotlight z-10"},null,-1)),e("div",g,[e("h1",{class:"font-medium mb-8 sm:text-10xl text-8xl",textContent:r(t.statusCode)},null,8,h),e("p",{class:"font-light leading-tight mb-16 px-8 sm:px-0 sm:text-4xl text-xl",textContent:r(t.description)},null,8,b),e("div",x,[c(s,{to:"/",class:"cursor-pointer gradient-border px-4 py-2 sm:px-6 sm:py-3 sm:text-xl text-md"},{default:l(()=>[d(r(t.backHome),1)]),_:1})])])])}}},v=a(y,[["__scopeId","data-v-3074ece5"]]);export{v as default};
1
+ import{_ as a,o as i,c as u,a as e,t as r,b as c,w as l,d,e as p}from"./Ddb0iCRU.js";import{u as f}from"./AXE8DZQI.js";const m={class:"antialiased bg-white dark:bg-black dark:text-white font-sans grid min-h-screen overflow-hidden place-content-center text-black"},g={class:"max-w-520px text-center z-20"},h=["textContent"],b=["textContent"],x={class:"flex items-center justify-center w-full"},y={__name:"error-404",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},statusCode:{type:Number,default:404},statusMessage:{type:String,default:"Not Found"},description:{type:String,default:"Sorry, the page you are looking for could not be found."},backHome:{type:String,default:"Go back home"}},setup(t){const n=t;return f({title:`${n.statusCode} - ${n.statusMessage} | ${n.appName}`,script:[{children:`!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver((e=>{for(const o of e)if("childList"===o.type)for(const e of o.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&r(e)})).observe(document,{childList:!0,subtree:!0})}function r(e){if(e.ep)return;e.ep=!0;const r=function(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?r.credentials="include":"anonymous"===e.crossOrigin?r.credentials="omit":r.credentials="same-origin",r}(e);fetch(e.href,r)}}();`}],style:[{children:'*,:after,:before{border-color:var(--un-default-border-color,#e5e7eb);border-style:solid;border-width:0;box-sizing:border-box}:after,:before{--un-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}h1{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}h1,p{margin:0}*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }'}]}),(k,o)=>{const s=p;return i(),u("div",m,[o[0]||(o[0]=e("div",{class:"fixed left-0 right-0 spotlight z-10"},null,-1)),e("div",g,[e("h1",{class:"font-medium mb-8 sm:text-10xl text-8xl",textContent:r(t.statusCode)},null,8,h),e("p",{class:"font-light leading-tight mb-16 px-8 sm:px-0 sm:text-4xl text-xl",textContent:r(t.description)},null,8,b),e("div",x,[c(s,{to:"/",class:"cursor-pointer gradient-border px-4 py-2 sm:px-6 sm:py-3 sm:text-xl text-md"},{default:l(()=>[d(r(t.backHome),1)]),_:1})])])])}}},v=a(y,[["__scopeId","data-v-c1463376"]]);export{v as default};
@@ -1 +1 @@
1
- {"id":"1bc37d11-ac0a-4cf4-9f49-6f1123ca70df","timestamp":1736853586767}
1
+ {"id":"c8228d06-262a-456f-a053-aa7994ec21bb","timestamp":1737022232581}
@@ -0,0 +1 @@
1
+ {"id":"c8228d06-262a-456f-a053-aa7994ec21bb","timestamp":1737022232581,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
@@ -0,0 +1 @@
1
+ .spotlight[data-v-c1463376]{background:linear-gradient(45deg,#00dc82,#36e4da 50%,#0047e1);bottom:-30vh;filter:blur(20vh);height:40vh}.gradient-border[data-v-c1463376]{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-radius:.5rem;position:relative}@media (prefers-color-scheme:light){.gradient-border[data-v-c1463376]{background-color:#ffffff4d}.gradient-border[data-v-c1463376]:before{background:linear-gradient(90deg,#e2e2e2,#e2e2e2 25%,#00dc82,#36e4da 75%,#0047e1)}}@media (prefers-color-scheme:dark){.gradient-border[data-v-c1463376]{background-color:#1414144d}.gradient-border[data-v-c1463376]:before{background:linear-gradient(90deg,#303030,#303030 25%,#00dc82,#36e4da 75%,#0047e1)}}.gradient-border[data-v-c1463376]:before{background-size:400% auto;border-radius:.5rem;bottom:0;content:"";left:0;-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:.5;padding:2px;position:absolute;right:0;top:0;transition:background-position .3s ease-in-out,opacity .2s ease-in-out;width:100%}.gradient-border[data-v-c1463376]:hover:before{background-position:-50% 0;opacity:1}.fixed[data-v-c1463376]{position:fixed}.left-0[data-v-c1463376]{left:0}.right-0[data-v-c1463376]{right:0}.z-10[data-v-c1463376]{z-index:10}.z-20[data-v-c1463376]{z-index:20}.grid[data-v-c1463376]{display:grid}.mb-16[data-v-c1463376]{margin-bottom:4rem}.mb-8[data-v-c1463376]{margin-bottom:2rem}.max-w-520px[data-v-c1463376]{max-width:520px}.min-h-screen[data-v-c1463376]{min-height:100vh}.w-full[data-v-c1463376]{width:100%}.flex[data-v-c1463376]{display:flex}.cursor-pointer[data-v-c1463376]{cursor:pointer}.place-content-center[data-v-c1463376]{place-content:center}.items-center[data-v-c1463376]{align-items:center}.justify-center[data-v-c1463376]{justify-content:center}.overflow-hidden[data-v-c1463376]{overflow:hidden}.bg-white[data-v-c1463376]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-4[data-v-c1463376]{padding-left:1rem;padding-right:1rem}.px-8[data-v-c1463376]{padding-left:2rem;padding-right:2rem}.py-2[data-v-c1463376]{padding-bottom:.5rem;padding-top:.5rem}.text-center[data-v-c1463376]{text-align:center}.text-8xl[data-v-c1463376]{font-size:6rem;line-height:1}.text-xl[data-v-c1463376]{font-size:1.25rem;line-height:1.75rem}.text-black[data-v-c1463376]{--un-text-opacity:1;color:rgb(0 0 0/var(--un-text-opacity))}.font-light[data-v-c1463376]{font-weight:300}.font-medium[data-v-c1463376]{font-weight:500}.leading-tight[data-v-c1463376]{line-height:1.25}.font-sans[data-v-c1463376]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.antialiased[data-v-c1463376]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (prefers-color-scheme:dark){.dark\:bg-black[data-v-c1463376]{--un-bg-opacity:1;background-color:rgb(0 0 0/var(--un-bg-opacity))}.dark\:text-white[data-v-c1463376]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media (min-width:640px){.sm\:px-0[data-v-c1463376]{padding-left:0;padding-right:0}.sm\:px-6[data-v-c1463376]{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-3[data-v-c1463376]{padding-bottom:.75rem;padding-top:.75rem}.sm\:text-4xl[data-v-c1463376]{font-size:2.25rem;line-height:2.5rem}.sm\:text-xl[data-v-c1463376]{font-size:1.25rem;line-height:1.75rem}}
@@ -0,0 +1 @@
1
+ .spotlight[data-v-05ddf355]{background:linear-gradient(45deg,#00dc82,#36e4da 50%,#0047e1);filter:blur(20vh)}.fixed[data-v-05ddf355]{position:fixed}.-bottom-1\/2[data-v-05ddf355]{bottom:-50%}.left-0[data-v-05ddf355]{left:0}.right-0[data-v-05ddf355]{right:0}.grid[data-v-05ddf355]{display:grid}.mb-16[data-v-05ddf355]{margin-bottom:4rem}.mb-8[data-v-05ddf355]{margin-bottom:2rem}.h-1\/2[data-v-05ddf355]{height:50%}.max-w-520px[data-v-05ddf355]{max-width:520px}.min-h-screen[data-v-05ddf355]{min-height:100vh}.place-content-center[data-v-05ddf355]{place-content:center}.overflow-hidden[data-v-05ddf355]{overflow:hidden}.bg-white[data-v-05ddf355]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-8[data-v-05ddf355]{padding-left:2rem;padding-right:2rem}.text-center[data-v-05ddf355]{text-align:center}.text-8xl[data-v-05ddf355]{font-size:6rem;line-height:1}.text-xl[data-v-05ddf355]{font-size:1.25rem;line-height:1.75rem}.text-black[data-v-05ddf355]{--un-text-opacity:1;color:rgb(0 0 0/var(--un-text-opacity))}.font-light[data-v-05ddf355]{font-weight:300}.font-medium[data-v-05ddf355]{font-weight:500}.leading-tight[data-v-05ddf355]{line-height:1.25}.font-sans[data-v-05ddf355]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.antialiased[data-v-05ddf355]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (prefers-color-scheme:dark){.dark\:bg-black[data-v-05ddf355]{--un-bg-opacity:1;background-color:rgb(0 0 0/var(--un-bg-opacity))}.dark\:text-white[data-v-05ddf355]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media (min-width:640px){.sm\:px-0[data-v-05ddf355]{padding-left:0;padding-right:0}.sm\:text-4xl[data-v-05ddf355]{font-size:2.25rem;line-height:2.5rem}}
@@ -1,12 +1,12 @@
1
1
  <!DOCTYPE html><html data-capo=""><head><meta charset="utf-8">
2
2
  <meta name="viewport" content="width=device-width, initial-scale=1">
3
3
  <link rel="stylesheet" href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/entry.B5pGkSSX.css" crossorigin>
4
- <link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/C9njAg9E.js">
4
+ <link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Ddb0iCRU.js">
5
5
  <link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/CG55hV0U.js">
6
- <link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.C8aNxDEl.css">
7
- <link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/BIRJeTBr.js">
8
- <link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/EwNUkbJF.js">
9
- <link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.C2JGrgZX.css">
10
- <link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/DuZjM2Ym.js">
11
- <script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/C9njAg9E.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1736853592173,false]</script>
12
- <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"1bc37d11-ac0a-4cf4-9f49-6f1123ca70df",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
6
+ <link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.vh32VtAd.css">
7
+ <link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Deg2o1hP.js">
8
+ <link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/AXE8DZQI.js">
9
+ <link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.EgQ3RNLZ.css">
10
+ <link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D9gx-VEt.js">
11
+ <script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Ddb0iCRU.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1737022239892,false]</script>
12
+ <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"c8228d06-262a-456f-a053-aa7994ec21bb",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-i18n-micro",
3
3
  "configKey": "i18n",
4
- "version": "1.60.0",
4
+ "version": "1.62.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "0.8.4",
7
7
  "unbuild": "2.0.0"
package/dist/module.mjs CHANGED
@@ -1,8 +1,10 @@
1
1
  import path, { resolve } from 'node:path';
2
2
  import * as fs from 'node:fs';
3
3
  import fs__default, { readFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
4
+ import { readFile } from 'node:fs/promises';
4
5
  import { useNuxt, defineNuxtModule, useLogger, createResolver, addTemplate, addImportsDir, addPlugin, addServerHandler, addComponentsDir, addTypeTemplate, extendPages, addPrerenderRoutes } from '@nuxt/kit';
5
6
  import { watch } from 'chokidar';
7
+ import { globby } from 'globby';
6
8
  import { fileURLToPath } from 'node:url';
7
9
  import { onDevToolsInitialized, extendServerRpc } from '@nuxt/devtools-kit';
8
10
  import sirv from 'sirv';
@@ -22,6 +24,9 @@ function setupDevToolsUI(options, resolve2) {
22
24
  if (clientDirExists) {
23
25
  nuxt.hook("vite:serverCreated", (server) => {
24
26
  const indexHtmlPath = path.join(clientDir, "index.html");
27
+ if (!fs.existsSync(indexHtmlPath)) {
28
+ return;
29
+ }
25
30
  const indexContent = fs.readFileSync(indexHtmlPath);
26
31
  const handleStatic = sirv(clientDir, {
27
32
  dev: true,
@@ -134,8 +139,8 @@ class PageManager {
134
139
  computeActiveLocaleCodes() {
135
140
  return this.locales.filter((locale) => locale.code !== this.defaultLocale.code || isPrefixAndDefaultStrategy(this.strategy) || isPrefixStrategy(this.strategy)).map((locale) => locale.code);
136
141
  }
137
- extendPages(pages, rootDir, customRegex, isCloudflarePages) {
138
- this.localizedPaths = this.extractLocalizedPaths(pages, rootDir);
142
+ extendPages(pages, customRegex, isCloudflarePages) {
143
+ this.localizedPaths = this.extractLocalizedPaths(pages);
139
144
  const additionalRoutes = [];
140
145
  pages.forEach((page) => {
141
146
  if (!page.name) {
@@ -165,16 +170,15 @@ class PageManager {
165
170
  }
166
171
  pages.push(...additionalRoutes);
167
172
  }
168
- extractLocalizedPaths(pages, rootDir, parentPath = "") {
173
+ extractLocalizedPaths(pages, parentPath = "") {
169
174
  const localizedPaths = {};
170
175
  pages.forEach((page) => {
171
176
  const pageName = buildRouteNameFromRoute(page.name, page.path);
172
177
  const globalLocalePath = this.globalLocaleRoutes[pageName];
173
178
  if (!globalLocalePath) {
174
179
  if (page.file) {
175
- const filePath = path.resolve(rootDir, page.file);
176
- const fileContent = readFileSync(filePath, "utf-8");
177
- const localeRoutes = extractLocaleRoutes(fileContent, filePath);
180
+ const fileContent = readFileSync(page.file, "utf-8");
181
+ const localeRoutes = extractLocaleRoutes(fileContent, page.file);
178
182
  if (localeRoutes) {
179
183
  const normalizedFullPath = normalizePath(path.join(parentPath, page.path));
180
184
  localizedPaths[normalizedFullPath] = localeRoutes;
@@ -186,7 +190,7 @@ class PageManager {
186
190
  }
187
191
  if (page.children?.length) {
188
192
  const parentFullPath = normalizePath(path.join(parentPath, page.path));
189
- Object.assign(localizedPaths, this.extractLocalizedPaths(page.children, rootDir, parentFullPath));
193
+ Object.assign(localizedPaths, this.extractLocalizedPaths(page.children, parentFullPath));
190
194
  }
191
195
  });
192
196
  return localizedPaths;
@@ -375,6 +379,34 @@ declare module '#app' {
375
379
 
376
380
  export {}`;
377
381
  }
382
+ function deepMerge(target, source) {
383
+ if (typeof source !== "object" || source === null) {
384
+ return target === void 0 ? source : target;
385
+ }
386
+ if (Array.isArray(target)) {
387
+ return target;
388
+ }
389
+ if (source instanceof Object) {
390
+ if (!(target instanceof Object) || Array.isArray(target)) {
391
+ target = {};
392
+ }
393
+ for (const key in source) {
394
+ if (key === "__proto__" || key === "constructor")
395
+ continue;
396
+ if (target !== null && typeof target[key] === "object" && target[key] !== null) {
397
+ target[key] = deepMerge(
398
+ target[key],
399
+ source[key]
400
+ );
401
+ } else {
402
+ if (target instanceof Object && !(key in target)) {
403
+ target[key] = source[key];
404
+ }
405
+ }
406
+ }
407
+ }
408
+ return target;
409
+ }
378
410
  const module = defineNuxtModule({
379
411
  meta: {
380
412
  name: "nuxt-i18n-micro",
@@ -413,6 +445,7 @@ const module = defineNuxtModule({
413
445
  customRegexMatcher: void 0
414
446
  },
415
447
  async setup(options, nuxt) {
448
+ const defaultLocale = process.env.DEFAULT_LOCALE ?? options.defaultLocale ?? "en";
416
449
  const isSSG = nuxt.options._generate;
417
450
  const isCloudflarePages = nuxt.options.nitro.preset === "cloudflare_pages" || process.env.NITRO_PRESET === "cloudflare-pages";
418
451
  const logger = useLogger("nuxt-i18n-micro");
@@ -427,7 +460,7 @@ const module = defineNuxtModule({
427
460
  const resolver = createResolver(import.meta.url);
428
461
  const rootDirs = nuxt.options._layers.map((layer) => layer.config.rootDir).reverse();
429
462
  const localeManager = new LocaleManager(options, rootDirs);
430
- const pageManager = new PageManager(localeManager.locales, options.defaultLocale, options.strategy, options.globalLocaleRoutes);
463
+ const pageManager = new PageManager(localeManager.locales, defaultLocale, options.strategy, options.globalLocaleRoutes);
431
464
  addTemplate({
432
465
  filename: "i18n.plural.mjs",
433
466
  write: true,
@@ -442,7 +475,7 @@ const module = defineNuxtModule({
442
475
  define: options.define ?? true,
443
476
  disableWatcher: options.disableWatcher ?? false,
444
477
  disableUpdater: options.disableUpdater ?? false,
445
- defaultLocale: options.defaultLocale ?? "en",
478
+ defaultLocale,
446
479
  translationDir: options.translationDir ?? "locales",
447
480
  localeCookie: options.localeCookie ?? "user-locale",
448
481
  autoDetectLanguage: options.autoDetectLanguage ?? true,
@@ -506,7 +539,7 @@ const module = defineNuxtModule({
506
539
  }
507
540
  addServerHandler({
508
541
  route: `/${apiBaseUrl}/:page/:locale/data.json`,
509
- handler: resolver.resolve("./runtime/server/middleware/i18n-loader")
542
+ handler: resolver.resolve("./runtime/server/routes/get")
510
543
  });
511
544
  await addComponentsDir({
512
545
  path: resolver.resolve("./runtime/components"),
@@ -520,27 +553,8 @@ const module = defineNuxtModule({
520
553
  });
521
554
  }
522
555
  extendPages((pages) => {
523
- if (isNoPrefixStrategy(options.strategy)) {
524
- return;
525
- }
526
- const pagesNames = pages.map((page) => page.name).filter((name) => name !== void 0 && (!options.routesLocaleLinks || !options.routesLocaleLinks[name]));
527
- if (!options.disableWatcher) {
528
- localeManager.ensureTranslationFilesExist(pagesNames, options.translationDir, nuxt.options.rootDir);
529
- }
530
- pageManager.extendPages(pages, nuxt.options.rootDir, options.customRegexMatcher, isCloudflarePages);
531
- if (isPrefixStrategy(options.strategy) && !isCloudflarePages) {
532
- const fallbackRoute = {
533
- path: "/:pathMatch(.*)*",
534
- name: "custom-fallback-route",
535
- file: resolver.resolve("./runtime/components/locale-redirect.vue"),
536
- meta: {
537
- globalLocaleRoutes: options.globalLocaleRoutes
538
- }
539
- };
540
- pages.push(fallbackRoute);
541
- }
542
- nuxt.options.generate.routes = Array.isArray(nuxt.options.generate.routes) ? nuxt.options.generate.routes : [];
543
556
  const prerenderRoutes = [];
557
+ const pagesNames = pages.map((page) => page.name).filter((name) => name !== void 0 && (!options.routesLocaleLinks || !options.routesLocaleLinks[name]));
544
558
  localeManager.locales.forEach((locale) => {
545
559
  if (!options.disablePageLocales) {
546
560
  pagesNames.forEach((name) => {
@@ -549,36 +563,61 @@ const module = defineNuxtModule({
549
563
  }
550
564
  prerenderRoutes.push(`/${apiBaseUrl}/general/${locale.code}/data.json`);
551
565
  });
552
- if (isCloudflarePages) {
553
- const processPageWithChildren = (page, parentPath = "") => {
554
- if (!page.path)
555
- return;
556
- const fullPath = path.posix.normalize(`${parentPath}/${page.path}`);
557
- const localeSegmentMatch = fullPath.match(/:locale\(([^)]+)\)/);
558
- if (localeSegmentMatch) {
559
- const availableLocales = localeSegmentMatch[1].split("|");
560
- localeManager.locales.forEach((locale) => {
561
- const localeCode = locale.code;
562
- if (availableLocales.includes(localeCode)) {
563
- let localizedPath = fullPath;
564
- localizedPath = localizedPath.replace(/:locale\([^)]+\)/, localeCode);
565
- prerenderRoutes.push(localizedPath);
566
- }
567
- });
568
- } else {
569
- prerenderRoutes.push(fullPath);
570
- }
571
- if (page.children && page.children.length) {
572
- page.children.forEach((childPage) => processPageWithChildren(childPage, fullPath));
573
- }
574
- };
575
- pages.forEach((page) => {
576
- processPageWithChildren(page);
577
- });
566
+ if (!isNoPrefixStrategy(options.strategy)) {
567
+ if (!options.disableWatcher) {
568
+ localeManager.ensureTranslationFilesExist(pagesNames, options.translationDir, nuxt.options.rootDir);
569
+ }
570
+ pageManager.extendPages(pages, options.customRegexMatcher, isCloudflarePages);
571
+ if (isPrefixStrategy(options.strategy) && !isCloudflarePages) {
572
+ const fallbackRoute = {
573
+ path: "/:pathMatch(.*)*",
574
+ name: "custom-fallback-route",
575
+ file: resolver.resolve("./runtime/components/locale-redirect.vue"),
576
+ meta: {
577
+ globalLocaleRoutes: options.globalLocaleRoutes
578
+ }
579
+ };
580
+ pages.push(fallbackRoute);
581
+ }
582
+ nuxt.options.generate.routes = Array.isArray(nuxt.options.generate.routes) ? nuxt.options.generate.routes : [];
583
+ if (isCloudflarePages) {
584
+ const processPageWithChildren = (page, parentPath = "") => {
585
+ if (!page.path)
586
+ return;
587
+ const fullPath = path.posix.normalize(`${parentPath}/${page.path}`);
588
+ const localeSegmentMatch = fullPath.match(/:locale\(([^)]+)\)/);
589
+ if (localeSegmentMatch) {
590
+ const availableLocales = localeSegmentMatch[1].split("|");
591
+ localeManager.locales.forEach((locale) => {
592
+ const localeCode = locale.code;
593
+ if (availableLocales.includes(localeCode)) {
594
+ let localizedPath = fullPath;
595
+ localizedPath = localizedPath.replace(/:locale\([^)]+\)/, localeCode);
596
+ prerenderRoutes.push(localizedPath);
597
+ }
598
+ });
599
+ } else {
600
+ prerenderRoutes.push(fullPath);
601
+ }
602
+ if (page.children && page.children.length) {
603
+ page.children.forEach((childPage) => processPageWithChildren(childPage, fullPath));
604
+ }
605
+ };
606
+ pages.forEach((page) => {
607
+ processPageWithChildren(page);
608
+ });
609
+ }
578
610
  }
579
611
  addPrerenderRoutes(prerenderRoutes);
580
612
  });
581
613
  nuxt.hook("nitro:config", (nitroConfig) => {
614
+ nitroConfig.bundledStorage = nitroConfig.bundledStorage || [];
615
+ nitroConfig.bundledStorage.push("i18n-locales");
616
+ nitroConfig.devStorage = nitroConfig.devStorage || {};
617
+ nitroConfig.devStorage["i18n-locales"] = {
618
+ driver: "fs",
619
+ base: path.join(nuxt.options.rootDir, "server/assets/i18n-locales")
620
+ };
582
621
  if (nitroConfig.imports) {
583
622
  nitroConfig.imports.presets = nitroConfig.imports.presets || [];
584
623
  nitroConfig.imports.presets.push({
@@ -593,7 +632,7 @@ const module = defineNuxtModule({
593
632
  nuxt.options.generate.routes = Array.isArray(nuxt.options.generate.routes) ? nuxt.options.generate.routes : [];
594
633
  const pages = nuxt.options.generate.routes || [];
595
634
  localeManager.locales.forEach((locale) => {
596
- if (locale.code !== options.defaultLocale || withPrefixStrategy(options.strategy)) {
635
+ if (locale.code !== defaultLocale || withPrefixStrategy(options.strategy)) {
597
636
  pages.forEach((page) => {
598
637
  if (!/\.[a-z0-9]+$/i.test(page)) {
599
638
  routes.push(`/${locale.code}${page}`);
@@ -617,6 +656,64 @@ const module = defineNuxtModule({
617
656
  }
618
657
  }
619
658
  });
659
+ nuxt.hook("nitro:init", async (nitro) => {
660
+ logger.debug("[nuxt-i18n-micro] clear storage cache");
661
+ await nitro.storage.clear("i18n-locales");
662
+ if (!await nitro.storage.hasItem(`i18n-locales:.gitignore`)) {
663
+ const dir = path.join(nuxt.options.rootDir, "server/assets/i18n-locales");
664
+ fs__default.mkdirSync(dir, { recursive: true });
665
+ fs__default.writeFileSync(`${dir}/.gitignore`, "*");
666
+ }
667
+ const translationDir = options.translationDir ?? "";
668
+ const fallbackLocale = options.fallbackLocale ?? null;
669
+ const translationsByLocale = {};
670
+ try {
671
+ for (const rootDir of rootDirs) {
672
+ const baseDir = path.resolve(rootDir, translationDir);
673
+ const files = await globby("**/*.json", { cwd: baseDir });
674
+ const promises = files.map(async (file) => {
675
+ const filePath = path.join(baseDir, file);
676
+ const content = await readFile(filePath, "utf-8");
677
+ const data = JSON.parse(content);
678
+ const parts = file.split("/");
679
+ const locale = parts.pop()?.replace(".json", "") || "";
680
+ const pageKey = parts.pop() || "general";
681
+ if (!translationsByLocale[locale]) {
682
+ translationsByLocale[locale] = {};
683
+ }
684
+ translationsByLocale[locale] = deepMerge({
685
+ [pageKey]: data
686
+ }, translationsByLocale[locale]);
687
+ });
688
+ await Promise.all(promises);
689
+ }
690
+ const savePromises = [];
691
+ for (const [locale, translations] of Object.entries(translationsByLocale)) {
692
+ for (const [key, value] of Object.entries(translations)) {
693
+ const storageKey = `i18n-locales:${locale}:${key}`;
694
+ const promise = (async () => {
695
+ let translation = value;
696
+ if (fallbackLocale) {
697
+ translation = deepMerge(
698
+ translation,
699
+ translationsByLocale[fallbackLocale][key] ?? {}
700
+ );
701
+ }
702
+ if (typeof translation === "object" && translation !== null) {
703
+ await nitro.storage.setItem(storageKey, translation);
704
+ if (options.debug) {
705
+ logger.log(`[nuxt-i18n-micro] Translation saved to Nitro storage with key: ${storageKey}`);
706
+ }
707
+ }
708
+ })();
709
+ savePromises.push(promise);
710
+ }
711
+ }
712
+ await Promise.all(savePromises);
713
+ } catch (err) {
714
+ logger.error("[nuxt-i18n-micro] Error processing translations:", err);
715
+ }
716
+ });
620
717
  if (!options.disableUpdater) {
621
718
  nuxt.hook("nitro:build:before", async (_nitro) => {
622
719
  const isProd = nuxt.options.dev === false;
@@ -624,7 +721,7 @@ const module = defineNuxtModule({
624
721
  const translationPath = path.resolve(nuxt.options.rootDir, options.translationDir);
625
722
  logger.log("\u2139 add file watcher: " + translationPath);
626
723
  const watcherEvent = async (path2) => {
627
- watcher.close();
724
+ await watcher.close();
628
725
  logger.log("\u21BB update store item: " + path2);
629
726
  nuxt.callHook("restart");
630
727
  };
@@ -644,7 +741,7 @@ const module = defineNuxtModule({
644
741
  routesSet.forEach((route) => {
645
742
  if (!/\.[a-z0-9]+$/i.test(route)) {
646
743
  localeManager.locales.forEach((locale) => {
647
- if (locale.code !== options.defaultLocale) {
744
+ if (locale.code !== defaultLocale) {
648
745
  if (route === "/") {
649
746
  additionalRoutes.add(`/${locale.code}`);
650
747
  } else {
@@ -15,6 +15,7 @@ export function useI18n() {
15
15
  $has: nuxtApp.$has,
16
16
  $tc: nuxtApp.$tc,
17
17
  $mergeTranslations: nuxtApp.$mergeTranslations,
18
+ $mergeGlobalTranslations: nuxtApp.$mergeGlobalTranslations,
18
19
  $setI18nRouteParams: nuxtApp.$setI18nRouteParams,
19
20
  $switchLocaleRoute: nuxtApp.$switchLocaleRoute,
20
21
  $switchLocalePath: nuxtApp.$switchLocalePath,
@@ -17,6 +17,7 @@ declare const _default: import("nuxt/app").Plugin<{
17
17
  tdr(value: Date | number | string, options?: Intl.RelativeTimeFormatOptions): string;
18
18
  has: (key: string) => boolean;
19
19
  mergeTranslations: (newTranslations: Translations) => void;
20
+ mergeGlobalTranslations: (newTranslations: Translations) => void;
20
21
  switchLocaleRoute: (toLocale: string) => string | import("vue-router").RouteLocationAsRelativeGeneric | import("vue-router").RouteLocationAsPathGeneric;
21
22
  switchLocalePath: (toLocale: string) => string;
22
23
  switchLocale: (toLocale: string) => void;
@@ -40,6 +41,7 @@ declare const _default: import("nuxt/app").Plugin<{
40
41
  tdr(value: Date | number | string, options?: Intl.RelativeTimeFormatOptions): string;
41
42
  has: (key: string) => boolean;
42
43
  mergeTranslations: (newTranslations: Translations) => void;
44
+ mergeGlobalTranslations: (newTranslations: Translations) => void;
43
45
  switchLocaleRoute: (toLocale: string) => string | import("vue-router").RouteLocationAsRelativeGeneric | import("vue-router").RouteLocationAsPathGeneric;
44
46
  switchLocalePath: (toLocale: string) => string;
45
47
  switchLocale: (toLocale: string) => void;
@@ -63,6 +65,7 @@ export interface PluginsInjections {
63
65
  $tdr: (value: Date | number | string, options?: Intl.DateTimeFormatOptions) => string;
64
66
  $has: (key: string) => boolean;
65
67
  $mergeTranslations: (newTranslations: Translations) => void;
68
+ $mergeGlobalTranslations: (newTranslations: Translations) => void;
66
69
  $switchLocaleRoute: (locale: string) => RouteLocationRaw;
67
70
  $switchLocalePath: (locale: string) => string;
68
71
  $switchLocale: (locale: string) => void;
@@ -244,8 +244,13 @@ export default defineNuxtPlugin(async (nuxtApp) => {
244
244
  return;
245
245
  }
246
246
  const locale = i18nHelper.getLocale();
247
- const url = `/${apiBaseUrl}/${fRouteName}/${locale}/data.json?v=${i18nConfig.dateBuild}`.replace(/\/{2,}/g, "/");
248
- const data = await $fetch(url, { baseURL: runtimeConfig.app.baseURL });
247
+ const url = `/${apiBaseUrl}/${fRouteName}/${locale}/data.json`.replace(/\/{2,}/g, "/");
248
+ const data = await $fetch(url, {
249
+ baseURL: runtimeConfig.app.baseURL,
250
+ params: {
251
+ v: i18nConfig.dateBuild
252
+ }
253
+ });
249
254
  await i18nHelper.loadPageTranslations(routeName, data ?? {});
250
255
  }
251
256
  } catch (_error) {
@@ -270,9 +275,12 @@ export default defineNuxtPlugin(async (nuxtApp) => {
270
275
  }
271
276
  if (!i18nHelper.hasGeneralTranslation()) {
272
277
  const locale = i18nHelper.getLocale();
273
- const url = `/${apiBaseUrl}/general/${locale}/data.json?v=${i18nConfig.dateBuild}`.replace(/\/{2,}/g, "/");
278
+ const url = `/${apiBaseUrl}/general/${locale}/data.json`.replace(/\/{2,}/g, "/");
274
279
  const data = await $fetch(url, {
275
- baseURL: runtimeConfig.app.baseURL
280
+ baseURL: runtimeConfig.app.baseURL,
281
+ params: {
282
+ v: i18nConfig.dateBuild
283
+ }
276
284
  });
277
285
  await i18nHelper.loadTranslations(data ?? {});
278
286
  }
@@ -355,6 +363,9 @@ export default defineNuxtPlugin(async (nuxtApp) => {
355
363
  const routeName = getRouteName(route2, locale);
356
364
  i18nHelper.mergeTranslation(routeName, newTranslations);
357
365
  },
366
+ mergeGlobalTranslations: (newTranslations) => {
367
+ i18nHelper.mergeGlobalTranslation(newTranslations, true);
368
+ },
358
369
  switchLocaleRoute: (toLocale) => {
359
370
  const route2 = router.currentRoute.value;
360
371
  return switchLocaleRoute(i18nHelper.getLocale(), toLocale, route2, router, i18nConfig, i18nRouteParams.value);
@@ -54,8 +54,8 @@ export default defineNuxtPlugin(async (_nuxtApp) => {
54
54
  if (Object.values(normalizedLocales).length) {
55
55
  if (normalizedLocales[currentLocale]) {
56
56
  const translation = normalizedLocales[currentLocale];
57
- const { $mergeTranslations } = useNuxtApp();
58
- $mergeTranslations(translation);
57
+ const { $mergeGlobalTranslations } = useNuxtApp();
58
+ $mergeGlobalTranslations(translation);
59
59
  }
60
60
  if (!normalizedLocales[currentLocale]) {
61
61
  let defaultRouteName = route.name?.toString().replace("localized-", "").replace(new RegExp(`-${currentLocale}$`), "");
@@ -0,0 +1,17 @@
1
+ import { defineEventHandler } from "h3";
2
+ import { createError, useRuntimeConfig, useStorage } from "#imports";
3
+ export default defineEventHandler(async (event) => {
4
+ const { page, locale } = event.context.params;
5
+ const config = useRuntimeConfig();
6
+ const { customRegexMatcher, locales } = config.public.i18nConfig;
7
+ if (customRegexMatcher && locales && !locales.map((l) => l.code).includes(locale)) {
8
+ throw createError({ statusCode: 404 });
9
+ }
10
+ const cacheKey = `${locale}:${page}`;
11
+ const serverStorage = useStorage("i18n-locales");
12
+ if (await serverStorage.hasItem(cacheKey)) {
13
+ const rawContent = await serverStorage.getItem(cacheKey) || {};
14
+ return typeof rawContent === "string" ? JSON.parse(rawContent) : rawContent;
15
+ }
16
+ return {};
17
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-i18n-micro",
3
- "version": "1.60.0",
3
+ "version": "1.62.0",
4
4
  "description": "Nuxt I18n Micro is a lightweight, high-performance internationalization module for Nuxt, designed to handle multi-language support with minimal overhead, fast build times, and efficient runtime performance.",
5
5
  "repository": "s00d/nuxt-i18n-micro",
6
6
  "license": "MIT",
@@ -48,31 +48,32 @@
48
48
  ],
49
49
  "dependencies": {
50
50
  "@nuxt/devtools-kit": "^1.7.0",
51
- "@nuxt/kit": "^3.15.1",
51
+ "@nuxt/kit": "^3.15.2",
52
52
  "chokidar": "^3.6.0",
53
+ "globby": "^14.0.2",
53
54
  "sirv": "^2.0.4",
54
55
  "ufo": "^1.5.4",
55
- "nuxt-i18n-micro-test-utils": "1.0.4",
56
- "nuxt-i18n-micro-core": "1.0.11"
56
+ "nuxt-i18n-micro-core": "1.0.11",
57
+ "nuxt-i18n-micro-test-utils": "1.0.4"
57
58
  },
58
59
  "devDependencies": {
59
- "@types/jest": "^29.5.14",
60
60
  "@nuxt/devtools": "^1.7.0",
61
61
  "@nuxt/devtools-ui-kit": "^1.7.0",
62
62
  "@nuxt/eslint-config": "0.7.4",
63
63
  "@nuxt/module-builder": "^0.8.4",
64
- "@nuxt/schema": "^3.15.1",
65
- "@nuxt/test-utils": "^3.15.1",
64
+ "@nuxt/schema": "^3.15.2",
65
+ "@nuxt/test-utils": "^3.15.4",
66
66
  "@playwright/test": "^1.49.1",
67
+ "@types/jest": "^29.5.14",
67
68
  "@types/node": "^20.17.10",
68
69
  "changelogen": "^0.5.7",
69
70
  "eslint": "^8.57.1",
70
- "nuxt": "^3.15.1",
71
+ "jest": "^29.7.0",
72
+ "nuxt": "^3.15.2",
73
+ "ts-jest": "^29.2.5",
71
74
  "typescript": "5.6.3",
72
75
  "vitepress": "^1.5.0",
73
76
  "vitest": "^2.1.8",
74
- "jest": "^29.7.0",
75
- "ts-jest": "^29.2.5",
76
77
  "vue-tsc": "2.1.10"
77
78
  },
78
79
  "optionalDependencies": {
@@ -1 +0,0 @@
1
- {"id":"1bc37d11-ac0a-4cf4-9f49-6f1123ca70df","timestamp":1736853586767,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
@@ -1 +0,0 @@
1
- .spotlight[data-v-3074ece5]{background:linear-gradient(45deg,#00dc82,#36e4da 50%,#0047e1);bottom:-30vh;filter:blur(20vh);height:40vh}.gradient-border[data-v-3074ece5]{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-radius:.5rem;position:relative}@media (prefers-color-scheme:light){.gradient-border[data-v-3074ece5]{background-color:#ffffff4d}.gradient-border[data-v-3074ece5]:before{background:linear-gradient(90deg,#e2e2e2,#e2e2e2 25%,#00dc82,#36e4da 75%,#0047e1)}}@media (prefers-color-scheme:dark){.gradient-border[data-v-3074ece5]{background-color:#1414144d}.gradient-border[data-v-3074ece5]:before{background:linear-gradient(90deg,#303030,#303030 25%,#00dc82,#36e4da 75%,#0047e1)}}.gradient-border[data-v-3074ece5]:before{background-size:400% auto;border-radius:.5rem;bottom:0;content:"";left:0;-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:.5;padding:2px;position:absolute;right:0;top:0;transition:background-position .3s ease-in-out,opacity .2s ease-in-out;width:100%}.gradient-border[data-v-3074ece5]:hover:before{background-position:-50% 0;opacity:1}.fixed[data-v-3074ece5]{position:fixed}.left-0[data-v-3074ece5]{left:0}.right-0[data-v-3074ece5]{right:0}.z-10[data-v-3074ece5]{z-index:10}.z-20[data-v-3074ece5]{z-index:20}.grid[data-v-3074ece5]{display:grid}.mb-16[data-v-3074ece5]{margin-bottom:4rem}.mb-8[data-v-3074ece5]{margin-bottom:2rem}.max-w-520px[data-v-3074ece5]{max-width:520px}.min-h-screen[data-v-3074ece5]{min-height:100vh}.w-full[data-v-3074ece5]{width:100%}.flex[data-v-3074ece5]{display:flex}.cursor-pointer[data-v-3074ece5]{cursor:pointer}.place-content-center[data-v-3074ece5]{place-content:center}.items-center[data-v-3074ece5]{align-items:center}.justify-center[data-v-3074ece5]{justify-content:center}.overflow-hidden[data-v-3074ece5]{overflow:hidden}.bg-white[data-v-3074ece5]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-4[data-v-3074ece5]{padding-left:1rem;padding-right:1rem}.px-8[data-v-3074ece5]{padding-left:2rem;padding-right:2rem}.py-2[data-v-3074ece5]{padding-bottom:.5rem;padding-top:.5rem}.text-center[data-v-3074ece5]{text-align:center}.text-8xl[data-v-3074ece5]{font-size:6rem;line-height:1}.text-xl[data-v-3074ece5]{font-size:1.25rem;line-height:1.75rem}.text-black[data-v-3074ece5]{--un-text-opacity:1;color:rgb(0 0 0/var(--un-text-opacity))}.font-light[data-v-3074ece5]{font-weight:300}.font-medium[data-v-3074ece5]{font-weight:500}.leading-tight[data-v-3074ece5]{line-height:1.25}.font-sans[data-v-3074ece5]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.antialiased[data-v-3074ece5]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (prefers-color-scheme:dark){.dark\:bg-black[data-v-3074ece5]{--un-bg-opacity:1;background-color:rgb(0 0 0/var(--un-bg-opacity))}.dark\:text-white[data-v-3074ece5]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media (min-width:640px){.sm\:px-0[data-v-3074ece5]{padding-left:0;padding-right:0}.sm\:px-6[data-v-3074ece5]{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-3[data-v-3074ece5]{padding-bottom:.75rem;padding-top:.75rem}.sm\:text-4xl[data-v-3074ece5]{font-size:2.25rem;line-height:2.5rem}.sm\:text-xl[data-v-3074ece5]{font-size:1.25rem;line-height:1.75rem}}
@@ -1 +0,0 @@
1
- .spotlight[data-v-44593346]{background:linear-gradient(45deg,#00dc82,#36e4da 50%,#0047e1);filter:blur(20vh)}.fixed[data-v-44593346]{position:fixed}.-bottom-1\/2[data-v-44593346]{bottom:-50%}.left-0[data-v-44593346]{left:0}.right-0[data-v-44593346]{right:0}.grid[data-v-44593346]{display:grid}.mb-16[data-v-44593346]{margin-bottom:4rem}.mb-8[data-v-44593346]{margin-bottom:2rem}.h-1\/2[data-v-44593346]{height:50%}.max-w-520px[data-v-44593346]{max-width:520px}.min-h-screen[data-v-44593346]{min-height:100vh}.place-content-center[data-v-44593346]{place-content:center}.overflow-hidden[data-v-44593346]{overflow:hidden}.bg-white[data-v-44593346]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-8[data-v-44593346]{padding-left:2rem;padding-right:2rem}.text-center[data-v-44593346]{text-align:center}.text-8xl[data-v-44593346]{font-size:6rem;line-height:1}.text-xl[data-v-44593346]{font-size:1.25rem;line-height:1.75rem}.text-black[data-v-44593346]{--un-text-opacity:1;color:rgb(0 0 0/var(--un-text-opacity))}.font-light[data-v-44593346]{font-weight:300}.font-medium[data-v-44593346]{font-weight:500}.leading-tight[data-v-44593346]{line-height:1.25}.font-sans[data-v-44593346]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.antialiased[data-v-44593346]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (prefers-color-scheme:dark){.dark\:bg-black[data-v-44593346]{--un-bg-opacity:1;background-color:rgb(0 0 0/var(--un-bg-opacity))}.dark\:text-white[data-v-44593346]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media (min-width:640px){.sm\:px-0[data-v-44593346]{padding-left:0;padding-right:0}.sm\:text-4xl[data-v-44593346]{font-size:2.25rem;line-height:2.5rem}}