@verbaly/compiler 0.15.0 → 0.17.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.
package/dist/index.d.ts CHANGED
@@ -92,6 +92,7 @@ interface ResolvedConfig {
92
92
  declare function resolveConfig(config?: VerbalyConfig): ResolvedConfig;
93
93
  declare function findConfigFile(root: string): string | undefined;
94
94
  declare function loadConfigFile(root: string): Promise<VerbalyConfig>;
95
+ declare function targetLocales(cfg: ResolvedConfig, override?: string[]): string[];
95
96
  declare function loadConfig(root: string, overrides?: VerbalyConfig): Promise<ResolvedConfig>;
96
97
  //#endregion
97
98
  //#region src/catalog.d.ts
@@ -137,6 +138,15 @@ declare function generateLocaleModule(catalog: Catalog): string;
137
138
  declare function generateDts(entries: Map<string, string>): string;
138
139
  declare function writeDts(cfg: ResolvedConfig, entries: Map<string, string>): void;
139
140
  //#endregion
141
+ //#region src/plugin.d.ts
142
+ declare const RESOLVED_VIRTUAL_ID: string;
143
+ declare const LOCALE_MODULE_PREFIX = "\0virtual:verbaly/locale/";
144
+ declare const SOURCE_FILE_RE: RegExp;
145
+ declare function resolveVirtualId(id: string): string | undefined;
146
+ declare function loadVirtualModule(id: string, cfg: ResolvedConfig, catalogs: Catalogs): string | undefined;
147
+ declare function isTransformTarget(id: string): boolean;
148
+ declare function runBuildGate(cfg: ResolvedConfig, registry: MessageRegistry): void;
149
+ //#endregion
140
150
  //#region src/doctor.d.ts
141
151
  interface DoctorEntry {
142
152
  level: 'ok' | 'warn' | 'error';
@@ -279,5 +289,5 @@ interface TransformResult {
279
289
  }
280
290
  declare function transformCode(code: string, file: string, analysis?: Analysis): TransformResult | null;
281
291
  //#endregion
282
- export { type Alternate, type Analysis, type Catalog, type Catalogs, type CheckResult, type ClaudeProviderOptions, type DoctorEntry, type DoctorResult, type ExchangeFormat, type ExportOptions, type ExportResult, type ExportedFile, type ImportOptions, type ImportResult, type InitOptions, type InitResult, MessageRegistry, type MissingEntry, PSEUDO_LOCALE, type ParamType, type RenderConfig, type RenderHtmlOptions, type RenderHtmlResult, type RenderSiteOptions, type RenderSiteResult, type ResolvedConfig, type SyncResult, type TaggedMessage, type TaggedParam, type TransComponent, type TransformResult, type TranslateConfig, type TranslateOptions, type TranslateProvider, type TranslateRequest, type TranslateResult, type UnknownEntry, type UsedKey, VIRTUAL_ID, type VerbalyConfig, analyze, catalogPath, check, claudeProvider, collectParams, detectBundler, doctor, exportCatalogs, extractProject, findConfigFile, formatCheckResult, generateDts, generateLocaleModule, generateRuntimeModule, importCatalogs, init, loadCatalogs, loadConfig, loadConfigFile, parseExchangeFile, pruneCatalogs, pseudoCatalogs, pseudoLocalize, readCatalog, renderHtml, renderParamType, renderSite, resolveConfig, serializeCatalog, stableKey, structureMatches, syncCatalogs, transformCode, translateCatalogs, writeCatalog, writeDts };
292
+ export { type Alternate, type Analysis, type Catalog, type Catalogs, type CheckResult, type ClaudeProviderOptions, type DoctorEntry, type DoctorResult, type ExchangeFormat, type ExportOptions, type ExportResult, type ExportedFile, type ImportOptions, type ImportResult, type InitOptions, type InitResult, LOCALE_MODULE_PREFIX, MessageRegistry, type MissingEntry, PSEUDO_LOCALE, type ParamType, RESOLVED_VIRTUAL_ID, type RenderConfig, type RenderHtmlOptions, type RenderHtmlResult, type RenderSiteOptions, type RenderSiteResult, type ResolvedConfig, SOURCE_FILE_RE, type SyncResult, type TaggedMessage, type TaggedParam, type TransComponent, type TransformResult, type TranslateConfig, type TranslateOptions, type TranslateProvider, type TranslateRequest, type TranslateResult, type UnknownEntry, type UsedKey, VIRTUAL_ID, type VerbalyConfig, analyze, catalogPath, check, claudeProvider, collectParams, detectBundler, doctor, exportCatalogs, extractProject, findConfigFile, formatCheckResult, generateDts, generateLocaleModule, generateRuntimeModule, importCatalogs, init, isTransformTarget, loadCatalogs, loadConfig, loadConfigFile, loadVirtualModule, parseExchangeFile, pruneCatalogs, pseudoCatalogs, pseudoLocalize, readCatalog, renderHtml, renderParamType, renderSite, resolveConfig, resolveVirtualId, runBuildGate, serializeCatalog, stableKey, structureMatches, syncCatalogs, targetLocales, transformCode, translateCatalogs, writeCatalog, writeDts };
283
293
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -148,7 +148,7 @@ function buildTransMessage(code, children) {
148
148
  text += escapeText(expr.value);
149
149
  continue;
150
150
  }
151
- if (expr.type === "TaggedTemplateExpression") return void 0;
151
+ if (containsTaggedT(expr)) return void 0;
152
152
  const source = code.slice(expr.start, expr.end);
153
153
  const name = uniqueName(deriveName(expr, params.length), source, takenParams);
154
154
  params.push({
@@ -201,6 +201,15 @@ function selfClosedSource(code, opening) {
201
201
  const src = code.slice(opening.start, opening.end);
202
202
  return src.endsWith("/>") ? src : `${src.slice(0, -1).trimEnd()} />`;
203
203
  }
204
+ function containsTaggedT(node) {
205
+ let found = false;
206
+ walk(node, (n) => {
207
+ if (n.type !== "TaggedTemplateExpression") return;
208
+ const tag = n.tag;
209
+ if (isTReference(tag) || explicitId(tag)) found = true;
210
+ });
211
+ return found;
212
+ }
204
213
  function isTReference(node) {
205
214
  if (node.type === "Identifier") return node.name === "t";
206
215
  if (node.type === "MemberExpression" && !node.computed) {
@@ -218,6 +227,7 @@ function buildMessage(code, quasi) {
218
227
  for (let i = 0; i < expressions.length; i++) {
219
228
  const expr = expressions[i];
220
229
  if (!expr) return void 0;
230
+ if (containsTaggedT(expr)) return void 0;
221
231
  const source = code.slice(expr.start, expr.end);
222
232
  const name = uniqueName(deriveName(expr, i), source, taken);
223
233
  params.push({
@@ -402,18 +412,34 @@ const VIRTUAL_ID = "virtual:verbaly";
402
412
  function generateRuntimeModule(cfg) {
403
413
  const others = cfg.locales.filter((locale) => locale !== cfg.sourceLocale);
404
414
  const src = JSON.stringify(cfg.sourceLocale);
405
- const loaders = others.map((locale) => ` ${JSON.stringify(locale)}: () => import('${VIRTUAL_ID}/locale/${locale}'),`).join("\n");
415
+ const loaders = others.map((locale) => ` ${JSON.stringify(locale)}: () => import('${VIRTUAL_ID}/locale/${locale}'),`).join("\n");
406
416
  return `import { createVerbaly } from 'verbaly';
407
417
  import source from '${VIRTUAL_ID}/locale/${cfg.sourceLocale}';
408
418
 
409
- const v = createVerbaly({
410
- locale: ${src},
411
- fallback: ${src},
412
- messages: { [${src}]: source },
413
- loaders: {
419
+ export const sourceLocale = ${src};
420
+ export const locales = ${JSON.stringify(cfg.locales)};
421
+
422
+ // per-request/per-instance factory (SSR) — the singleton below is browser/SPA-only
423
+ export function createInstance(options) {
424
+ return createVerbaly({
425
+ locale: ${src},
426
+ fallback: ${src},
427
+ messages: { [${src}]: source },
428
+ loaders: {
414
429
  ${loaders}
415
- },
416
- });
430
+ },
431
+ ...options,
432
+ });
433
+ }
434
+
435
+ // the no-FOUC contract in one call: fresh instance + catalog awaited before render
436
+ export async function createRequestInstance(locale) {
437
+ const instance = createInstance({ locale });
438
+ await instance.loadLocale(locale);
439
+ return instance;
440
+ }
441
+
442
+ const v = createInstance();
417
443
 
418
444
  export const verbaly = v;
419
445
  export const t = v.t;
@@ -454,6 +480,15 @@ ${lines.join("\n")}
454
480
 
455
481
  export const verbaly: import('verbaly').Verbaly<VerbalyKey>;
456
482
 
483
+ export const sourceLocale: string;
484
+ export const locales: string[];
485
+ export function createInstance(
486
+ options?: import('verbaly').VerbalyOptions<VerbalyKey>,
487
+ ): import('verbaly').Verbaly<VerbalyKey>;
488
+ export function createRequestInstance(
489
+ locale: string,
490
+ ): Promise<import('verbaly').Verbaly<VerbalyKey>>;
491
+
457
492
  export function t<K extends VerbalyKey>(
458
493
  key: K,
459
494
  ...args: [VerbalyMessages[K]] extends [never] ? [] : [VerbalyMessages[K]]
@@ -480,6 +515,125 @@ function writeDts(cfg, entries) {
480
515
  writeFileSync(join(cfg.root, "verbaly.d.ts"), generateDts(entries));
481
516
  }
482
517
  //#endregion
518
+ //#region src/pseudo.ts
519
+ const PSEUDO_LOCALE = "en-XA";
520
+ const ACCENTS = {
521
+ a: "á",
522
+ b: "ƀ",
523
+ c: "ç",
524
+ d: "đ",
525
+ e: "é",
526
+ f: "ƒ",
527
+ g: "ğ",
528
+ h: "ĥ",
529
+ i: "í",
530
+ j: "ĵ",
531
+ k: "ķ",
532
+ l: "ĺ",
533
+ m: "ɱ",
534
+ n: "ñ",
535
+ o: "ó",
536
+ p: "þ",
537
+ q: "ǫ",
538
+ r: "ŕ",
539
+ s: "š",
540
+ t: "ţ",
541
+ u: "ú",
542
+ v: "ṽ",
543
+ w: "ŵ",
544
+ x: "ẋ",
545
+ y: "ý",
546
+ z: "ž",
547
+ A: "Á",
548
+ B: "Ɓ",
549
+ C: "Ç",
550
+ D: "Đ",
551
+ E: "É",
552
+ F: "Ƒ",
553
+ G: "Ğ",
554
+ H: "Ĥ",
555
+ I: "Í",
556
+ J: "Ĵ",
557
+ K: "Ķ",
558
+ L: "Ĺ",
559
+ M: "Ḿ",
560
+ N: "Ñ",
561
+ O: "Ó",
562
+ P: "Þ",
563
+ Q: "Ǫ",
564
+ R: "Ŕ",
565
+ S: "Š",
566
+ T: "Ţ",
567
+ U: "Ú",
568
+ V: "Ṽ",
569
+ W: "Ŵ",
570
+ X: "Ẍ",
571
+ Y: "Ý",
572
+ Z: "Ž"
573
+ };
574
+ const TAG_AT = /<\/?[a-zA-Z][\w-]*\/?>/y;
575
+ function pseudoLocalize(message) {
576
+ let out = "";
577
+ let letters = 0;
578
+ let i = 0;
579
+ while (i < message.length) {
580
+ const two = message.slice(i, i + 2);
581
+ if (two === "{{" || two === "}}" || two === "||" || two === "##") {
582
+ out += two;
583
+ i += 2;
584
+ continue;
585
+ }
586
+ const ch = message[i];
587
+ if (ch === "{") {
588
+ const end = matchBrace(message, i);
589
+ out += message.slice(i, end);
590
+ i = end;
591
+ continue;
592
+ }
593
+ if (ch === "<") {
594
+ TAG_AT.lastIndex = i;
595
+ const m = TAG_AT.exec(message);
596
+ if (m) {
597
+ out += m[0];
598
+ i += m[0].length;
599
+ continue;
600
+ }
601
+ }
602
+ const mapped = ACCENTS[ch];
603
+ if (mapped) {
604
+ out += mapped;
605
+ letters += 1;
606
+ } else out += ch;
607
+ i += 1;
608
+ }
609
+ const pad = "~".repeat(Math.ceil(letters / 3));
610
+ return `⟦${out}${pad ? " " + pad : ""}⟧`;
611
+ }
612
+ function matchBrace(message, start) {
613
+ let depth = 0;
614
+ for (let i = start; i < message.length; i++) {
615
+ const two = message.slice(i, i + 2);
616
+ if (two === "{{" || two === "}}") {
617
+ i += 1;
618
+ continue;
619
+ }
620
+ const ch = message[i];
621
+ if (ch === "{") depth += 1;
622
+ else if (ch === "}") {
623
+ depth -= 1;
624
+ if (depth === 0) return i + 1;
625
+ }
626
+ }
627
+ return message.length;
628
+ }
629
+ function pseudoCatalogs(cfg, catalogs, locale = PSEUDO_LOCALE) {
630
+ const source = catalogs[cfg.sourceLocale] ?? {};
631
+ const target = {};
632
+ for (const [key, msg] of Object.entries(source)) target[key] = msg ? pseudoLocalize(msg) : "";
633
+ catalogs[locale] = target;
634
+ return Object.keys(target).filter((key) => target[key]);
635
+ }
636
+ //#endregion
483
637
  //#region src/config.ts
484
638
  function resolveConfig(config = {}) {
485
639
  const root = resolve(config.root ?? process.cwd());
@@ -487,7 +641,7 @@ function resolveConfig(config = {}) {
487
641
  const sourceLocale = config.sourceLocale ?? "en";
488
642
  const locales = /* @__PURE__ */ new Set([sourceLocale, ...config.locales ?? []]);
489
643
  if (existsSync(dir)) {
490
- for (const file of readdirSync(dir)) if (file.endsWith(".json")) locales.add(file.slice(0, -5));
644
+ for (const file of readdirSync(dir)) if (file.endsWith(".json") && file !== `en-XA.json`) locales.add(file.slice(0, -5));
491
645
  }
492
646
  return {
493
647
  root,
@@ -529,13 +683,16 @@ async function loadTsConfig(path) {
529
683
  const { mod } = await bundleRequire({ filepath: path });
530
684
  return mod.default ?? {};
531
685
  } catch (error) {
532
- if (isModuleNotFound$1(error, "esbuild")) throw new Error(`[verbaly] ${path} needs esbuild — install it: pnpm add -D esbuild`, { cause: error });
686
+ if (isModuleNotFound(error, "esbuild")) throw new Error(`[verbaly] ${path} needs esbuild — install it: pnpm add -D esbuild`, { cause: error });
533
687
  throw error;
534
688
  }
535
689
  }
536
- function isModuleNotFound$1(error, name) {
690
+ function isModuleNotFound(error, name) {
537
691
  return error instanceof Error && error.code === "ERR_MODULE_NOT_FOUND" && error.message.includes(name);
538
692
  }
693
+ function targetLocales(cfg, override) {
694
+ return (override ?? cfg.locales).filter((locale) => locale !== cfg.sourceLocale && cfg.locales.includes(locale));
695
+ }
539
696
  async function loadConfig(root, overrides = {}) {
540
697
  return resolveConfig({
541
698
  ...await loadConfigFile(root),
@@ -547,6 +704,25 @@ function definedOnly(config) {
547
704
  return Object.fromEntries(Object.entries(config).filter(([, value]) => value !== void 0));
548
705
  }
549
706
  //#endregion
707
+ //#region src/plugin.ts
708
+ const RESOLVED_VIRTUAL_ID = "\0virtual:verbaly";
709
+ const LOCALE_MODULE_PREFIX = `${RESOLVED_VIRTUAL_ID}/locale/`;
710
+ const SOURCE_FILE_RE = /\.[cm]?[jt]sx?$/;
711
+ function resolveVirtualId(id) {
712
+ if (id === "virtual:verbaly" || id.startsWith(`virtual:verbaly/`)) return "\0" + id;
713
+ }
714
+ function loadVirtualModule(id, cfg, catalogs) {
715
+ if (id === RESOLVED_VIRTUAL_ID) return generateRuntimeModule(cfg);
716
+ if (id.startsWith(LOCALE_MODULE_PREFIX)) return generateLocaleModule(catalogs[id.slice(LOCALE_MODULE_PREFIX.length)] ?? {});
717
+ }
718
+ function isTransformTarget(id) {
719
+ return SOURCE_FILE_RE.test(id) && !id.includes("node_modules") && !id.startsWith("\0");
720
+ }
721
+ function runBuildGate(cfg, registry) {
722
+ const result = check(cfg, loadCatalogs(cfg), registry);
723
+ if (!result.ok) throw new Error(`[verbaly] build blocked\n${formatCheckResult(result)}\nRun \`npx verbaly extract\` and fill the missing translations.`);
724
+ }
725
+ //#endregion
550
726
  //#region src/registry.ts
551
727
  var MessageRegistry = class {
552
728
  files = /* @__PURE__ */ new Map();
@@ -797,7 +973,7 @@ function readDeps(root) {
797
973
  //#region src/translate.ts
798
974
  async function translateCatalogs(cfg, catalogs, provider, options = {}) {
799
975
  const batchSize = options.batchSize ?? 20;
800
- const targets = (options.locales ?? cfg.locales).filter((locale) => locale !== cfg.sourceLocale && cfg.locales.includes(locale));
976
+ const targets = targetLocales(cfg, options.locales);
801
977
  const source = catalogs[cfg.sourceLocale] ?? {};
802
978
  const result = {
803
979
  translated: {},
@@ -856,7 +1032,7 @@ function exportCatalogs(cfg, catalogs, options = {}) {
856
1032
  const format = options.format ?? "xliff";
857
1033
  const dir = resolve(cfg.root, options.out ?? "verbaly-export");
858
1034
  const source = catalogs[cfg.sourceLocale] ?? {};
859
- const targets = (options.locales ?? cfg.locales).filter((locale) => locale !== cfg.sourceLocale && cfg.locales.includes(locale));
1035
+ const targets = targetLocales(cfg, options.locales);
860
1036
  const files = [];
861
1037
  mkdirSync(dir, { recursive: true });
862
1038
  for (const locale of targets) {
@@ -1081,128 +1257,6 @@ async function loadSdk(load = () => import("@anthropic-ai/sdk")) {
1081
1257
  throw error;
1082
1258
  }
1083
1259
  }
1084
- function isModuleNotFound(error, name) {
1085
- return error instanceof Error && error.code === "ERR_MODULE_NOT_FOUND" && error.message.includes(name);
1086
- }
1087
- //#endregion
1088
- //#region src/pseudo.ts
1089
- const PSEUDO_LOCALE = "en-XA";
1090
- const ACCENTS = {
1091
- a: "á",
1092
- b: "ƀ",
1093
- c: "ç",
1094
- d: "đ",
1095
- e: "é",
1096
- f: "ƒ",
1097
- g: "ğ",
1098
- h: "ĥ",
1099
- i: "í",
1100
- j: "ĵ",
1101
- k: "ķ",
1102
- l: "ĺ",
1103
- m: "ɱ",
1104
- n: "ñ",
1105
- o: "ó",
1106
- p: "þ",
1107
- q: "ǫ",
1108
- r: "ŕ",
1109
- s: "š",
1110
- t: "ţ",
1111
- u: "ú",
1112
- v: "ṽ",
1113
- w: "ŵ",
1114
- x: "ẋ",
1115
- y: "ý",
1116
- z: "ž",
1117
- A: "Á",
1118
- B: "Ɓ",
1119
- C: "Ç",
1120
- D: "Đ",
1121
- E: "É",
1122
- F: "Ƒ",
1123
- G: "Ğ",
1124
- H: "Ĥ",
1125
- I: "Í",
1126
- J: "Ĵ",
1127
- K: "Ķ",
1128
- L: "Ĺ",
1129
- M: "Ḿ",
1130
- N: "Ñ",
1131
- O: "Ó",
1132
- P: "Þ",
1133
- Q: "Ǫ",
1134
- R: "Ŕ",
1135
- S: "Š",
1136
- T: "Ţ",
1137
- U: "Ú",
1138
- V: "Ṽ",
1139
- W: "Ŵ",
1140
- X: "Ẍ",
1141
- Y: "Ý",
1142
- Z: "Ž"
1143
- };
1144
- const TAG_AT = /<\/?[a-zA-Z][\w-]*\/?>/y;
1145
- function pseudoLocalize(message) {
1146
- let out = "";
1147
- let letters = 0;
1148
- let i = 0;
1149
- while (i < message.length) {
1150
- const two = message.slice(i, i + 2);
1151
- if (two === "{{" || two === "}}" || two === "||" || two === "##") {
1152
- out += two;
1153
- i += 2;
1154
- continue;
1155
- }
1156
- const ch = message[i];
1157
- if (ch === "{") {
1158
- const end = matchBrace(message, i);
1159
- out += message.slice(i, end);
1160
- i = end;
1161
- continue;
1162
- }
1163
- if (ch === "<") {
1164
- TAG_AT.lastIndex = i;
1165
- const m = TAG_AT.exec(message);
1166
- if (m) {
1167
- out += m[0];
1168
- i += m[0].length;
1169
- continue;
1170
- }
1171
- }
1172
- const mapped = ACCENTS[ch];
1173
- if (mapped) {
1174
- out += mapped;
1175
- letters += 1;
1176
- } else out += ch;
1177
- i += 1;
1178
- }
1179
- const pad = "~".repeat(Math.ceil(letters / 3));
1180
- return `⟦${out}${pad ? " " + pad : ""}⟧`;
1181
- }
1182
- function matchBrace(message, start) {
1183
- let depth = 0;
1184
- for (let i = start; i < message.length; i++) {
1185
- const two = message.slice(i, i + 2);
1186
- if (two === "{{" || two === "}}") {
1187
- i += 1;
1188
- continue;
1189
- }
1190
- const ch = message[i];
1191
- if (ch === "{") depth += 1;
1192
- else if (ch === "}") {
1193
- depth -= 1;
1194
- if (depth === 0) return i + 1;
1195
- }
1196
- }
1197
- return message.length;
1198
- }
1199
- function pseudoCatalogs(cfg, catalogs, locale = PSEUDO_LOCALE) {
1200
- const source = catalogs[cfg.sourceLocale] ?? {};
1201
- const target = {};
1202
- for (const [key, msg] of Object.entries(source)) target[key] = msg ? pseudoLocalize(msg) : "";
1203
- catalogs[locale] = target;
1204
- return Object.keys(target).filter((key) => target[key]);
1205
- }
1206
1260
  //#endregion
1207
1261
  //#region src/render.ts
1208
1262
  const HREFLANG_OPEN = "<!--verbaly:hreflang-->";
@@ -1499,6 +1553,6 @@ function transformCode(code, file, analysis) {
1499
1553
  };
1500
1554
  }
1501
1555
  //#endregion
1502
- export { MessageRegistry, PSEUDO_LOCALE, VIRTUAL_ID, analyze, catalogPath, check, claudeProvider, collectParams, detectBundler, doctor, exportCatalogs, extractProject, findConfigFile, formatCheckResult, generateDts, generateLocaleModule, generateRuntimeModule, importCatalogs, init, loadCatalogs, loadConfig, loadConfigFile, parseExchangeFile, pruneCatalogs, pseudoCatalogs, pseudoLocalize, readCatalog, renderHtml, renderParamType, renderSite, resolveConfig, serializeCatalog, stableKey, structureMatches, syncCatalogs, transformCode, translateCatalogs, writeCatalog, writeDts };
1556
+ export { LOCALE_MODULE_PREFIX, MessageRegistry, PSEUDO_LOCALE, RESOLVED_VIRTUAL_ID, SOURCE_FILE_RE, VIRTUAL_ID, analyze, catalogPath, check, claudeProvider, collectParams, detectBundler, doctor, exportCatalogs, extractProject, findConfigFile, formatCheckResult, generateDts, generateLocaleModule, generateRuntimeModule, importCatalogs, init, isTransformTarget, loadCatalogs, loadConfig, loadConfigFile, loadVirtualModule, parseExchangeFile, pruneCatalogs, pseudoCatalogs, pseudoLocalize, readCatalog, renderHtml, renderParamType, renderSite, resolveConfig, resolveVirtualId, runBuildGate, serializeCatalog, stableKey, structureMatches, syncCatalogs, targetLocales, transformCode, translateCatalogs, writeCatalog, writeDts };
1503
1557
 
1504
1558
  //# sourceMappingURL=index.js.map