@lokascript/i18n 2.9.3 → 2.10.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.
Files changed (40) hide show
  1. package/dist/browser.cjs +74 -10
  2. package/dist/browser.cjs.map +1 -1
  3. package/dist/browser.d.cts +2 -2
  4. package/dist/browser.d.ts +2 -2
  5. package/dist/browser.js +74 -10
  6. package/dist/browser.js.map +1 -1
  7. package/dist/dictionaries/index.cjs +18 -10
  8. package/dist/dictionaries/index.cjs.map +1 -1
  9. package/dist/dictionaries/index.js +18 -10
  10. package/dist/dictionaries/index.js.map +1 -1
  11. package/dist/index.cjs +74 -10
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +1 -1
  14. package/dist/index.d.ts +1 -1
  15. package/dist/index.js +74 -10
  16. package/dist/index.js.map +1 -1
  17. package/dist/lokascript-i18n.min.js +1 -1
  18. package/dist/lokascript-i18n.min.js.map +1 -1
  19. package/dist/lokascript-i18n.mjs +110 -10
  20. package/dist/lokascript-i18n.mjs.map +1 -1
  21. package/dist/plugins/vite.cjs +18 -10
  22. package/dist/plugins/vite.cjs.map +1 -1
  23. package/dist/plugins/vite.js +18 -10
  24. package/dist/plugins/vite.js.map +1 -1
  25. package/dist/plugins/webpack.cjs +18 -10
  26. package/dist/plugins/webpack.cjs.map +1 -1
  27. package/dist/plugins/webpack.js +18 -10
  28. package/dist/plugins/webpack.js.map +1 -1
  29. package/dist/{transformer--W46PGaW.d.cts → transformer-CsOeqayN.d.cts} +18 -1
  30. package/dist/{transformer-FU06J6kG.d.ts → transformer-DWCTG1DQ.d.ts} +18 -1
  31. package/package.json +4 -4
  32. package/src/dictionaries/de.ts +3 -1
  33. package/src/dictionaries/es.ts +2 -2
  34. package/src/dictionaries/pl.ts +2 -1
  35. package/src/dictionaries/pt.ts +5 -2
  36. package/src/dictionaries/ru.ts +2 -2
  37. package/src/dictionaries/uk.ts +2 -2
  38. package/src/grammar/grammar.test.ts +87 -0
  39. package/src/grammar/transformer.ts +106 -0
  40. package/src/grammar/types.ts +4 -0
package/dist/browser.cjs CHANGED
@@ -591,12 +591,12 @@ var es = {
591
591
  events: {
592
592
  click: "clic",
593
593
  dblclick: "dobleclic",
594
- mousedown: "rat\xF3nabajo",
595
- mouseup: "rat\xF3narriba",
596
594
  mouseenter: "rat\xF3nentrar",
597
595
  mouseleave: "rat\xF3nsalir",
598
596
  // V3 Batch 2: fused forms split to the S5b/tokenizer-known forms (the fused
599
597
  // spellings captured event=expression:undefined — broken listeners)
598
+ mousedown: "rat\xF3n abajo",
599
+ mouseup: "rat\xF3n arriba",
600
600
  mouseover: "rat\xF3n encima",
601
601
  mouseout: "rat\xF3n fuera",
602
602
  mousemove: "rat\xF3nmover",
@@ -1280,7 +1280,9 @@ var de = {
1280
1280
  reset: "zur\xFCcksetzen",
1281
1281
  load: "laden",
1282
1282
  unload: "entladen",
1283
- resize: "gr\xF6\xDFe\xE4ndern",
1283
+ // 'größeändern' was a malformed compound: German either separates the verb
1284
+ // phrase ('Größe ändern') or compounds with the linking -n- ('Größenänderung').
1285
+ resize: "gr\xF6\xDFen\xE4nderung",
1284
1286
  scroll: "scrollen",
1285
1287
  touchstart: "ber\xFChrungstart",
1286
1288
  touchend: "ber\xFChrungend",
@@ -3119,12 +3121,15 @@ var pt = {
3119
3121
  events: {
3120
3122
  click: "clique",
3121
3123
  dblclick: "duploClique",
3122
- mousedown: "mouseBaixo",
3123
- mouseup: "mouseCima",
3124
3124
  mouseenter: "mouseEntrar",
3125
3125
  mouseleave: "mouseSair",
3126
3126
  // V3 Batch 2: camelCase forms split to the S5b/tokenizer-known forms (the
3127
3127
  // fused spellings captured event=expression:undefined — broken listeners)
3128
+ // pt-BR idiom is "pressionado"/"solto", not the spatial baixo/cima calque —
3129
+ // cf. MDN pt-BR ("um botão ... é pressionado") and Scratch pt-BR
3130
+ // ("mouse pressionado?"). The calques stay as profile parse alternatives.
3131
+ mousedown: "mouse pressionado",
3132
+ mouseup: "mouse solto",
3128
3133
  mouseover: "mouse sobre",
3129
3134
  mouseout: "mouse fora",
3130
3135
  mousemove: "mouseMover",
@@ -3802,7 +3807,8 @@ var pl = {
3802
3807
  // Batch 3: resetuj captured on.event as expression (broken listener) — profile word round-trips
3803
3808
  load: "za\u0142aduj",
3804
3809
  unload: "wy\u0142aduj",
3805
- resize: "zmie\u0144rozmiar",
3810
+ // 'zmieńrozmiar' was a fused two-word phrase; Polish writes 'zmiana rozmiaru'.
3811
+ resize: "zmiana rozmiaru",
3806
3812
  scroll: "przewi\u0144",
3807
3813
  touchstart: "dotykstart",
3808
3814
  touchend: "dotykkoniec",
@@ -3966,7 +3972,7 @@ var russianDictionary = {
3966
3972
  morph: "\u0442\u0440\u0430\u043D\u0441\u0444\u043E\u0440\u043C\u0438\u0440\u043E\u0432\u0430\u0442\u044C",
3967
3973
  settle: "\u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u0442\u044C",
3968
3974
  append: "\u0434\u043E\u043F\u0438\u0441\u0430\u0442\u044C",
3969
- // profile alternative; the compound splits and добавить parses as add
3975
+ // matches the ru profile primary
3970
3976
  exit: "\u0432\u044B\u0439\u0442\u0438",
3971
3977
  else: "\u0438\u043D\u0430\u0447\u0435",
3972
3978
  install: "\u0438\u043D\u0441\u0442\u0430\u043B\u043B\u0438\u0440\u043E\u0432\u0430\u0442\u044C",
@@ -3976,7 +3982,8 @@ var russianDictionary = {
3976
3982
  focus: "\u0441\u0444\u043E\u043A\u0443\u0441\u0438\u0440\u043E\u0432\u0430\u0442\u044C",
3977
3983
  blur: "\u0440\u0430\u0437\u043C\u044B\u0442\u044C",
3978
3984
  clone: "\u043A\u043B\u043E\u043D\u0438\u0440\u043E\u0432\u0430\u0442\u044C",
3979
- prepend: "\u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C_\u0432_\u043D\u0430\u0447\u0430\u043B\u043E",
3985
+ prepend: "\u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0432 \u043D\u0430\u0447\u0430\u043B\u043E",
3986
+ // natural form; the underscore compound was never natural Russian
3980
3987
  breakpoint: "\u0442\u043E\u0447\u043A\u0430-\u043E\u0441\u0442\u0430\u043D\u043E\u0432\u0430",
3981
3988
  clear: "\u043E\u0447\u0438\u0441\u0442\u0438\u0442\u044C",
3982
3989
  close: "\u0437\u0430\u043A\u0440\u044B\u0442\u044C",
@@ -4213,7 +4220,7 @@ var ukrainianDictionary = {
4213
4220
  morph: "\u0442\u0440\u0430\u043D\u0441\u0444\u043E\u0440\u043C\u0443\u0432\u0430\u0442\u0438",
4214
4221
  settle: "\u0441\u0442\u0430\u0431\u0456\u043B\u0456\u0437\u0443\u0432\u0430\u0442\u0438",
4215
4222
  append: "\u0434\u043E\u043F\u0438\u0441\u0430\u0442\u0438",
4216
- // profile alternative; the compound splits and додати parses as add
4223
+ // matches the uk profile primary
4217
4224
  exit: "\u0432\u0438\u0439\u0442\u0438",
4218
4225
  else: "\u0456\u043D\u0430\u043A\u0448\u0435",
4219
4226
  install: "\u0456\u043D\u0441\u0442\u0430\u043B\u044E\u0432\u0430\u0442\u0438",
@@ -4223,7 +4230,8 @@ var ukrainianDictionary = {
4223
4230
  focus: "\u0441\u0444\u043E\u043A\u0443\u0441\u0443\u0432\u0430\u0442\u0438",
4224
4231
  blur: "\u0440\u043E\u0437\u0444\u043E\u043A\u0443\u0441\u0443\u0432\u0430\u0442\u0438",
4225
4232
  clone: "\u043A\u043B\u043E\u043D\u0443\u0432\u0430\u0442\u0438",
4226
- prepend: "\u0434\u043E\u0434\u0430\u0442\u0438_\u043D\u0430_\u043F\u043E\u0447\u0430\u0442\u043E\u043A",
4233
+ prepend: "\u0434\u043E\u0434\u0430\u0442\u0438 \u043D\u0430 \u043F\u043E\u0447\u0430\u0442\u043E\u043A",
4234
+ // natural form; see ru.ts
4227
4235
  breakpoint: "\u0442\u043E\u0447\u043A\u0430-\u0437\u0443\u043F\u0438\u043D\u043A\u0438",
4228
4236
  clear: "\u043E\u0447\u0438\u0441\u0442\u0438\u0442\u0438",
4229
4237
  close: "\u0437\u0430\u043A\u0440\u0438\u0442\u0438",
@@ -8811,6 +8819,25 @@ function restoreCaretScopes(input, scopes) {
8811
8819
  (_m, n) => scopes[Number(n)] ?? ""
8812
8820
  );
8813
8821
  }
8822
+ var VIEW_TAIL_OPEN = "\uE002";
8823
+ var VIEW_TAIL_CLOSE = "\uE003";
8824
+ var VIEW_TAIL_RE = /\busing\s+view\b(?:\s+(?!then\b)[A-Za-z][\w-]*)?/gi;
8825
+ var VIEW_TAIL_TOKEN_RE = new RegExp(`^${VIEW_TAIL_OPEN}(\\d+)${VIEW_TAIL_CLOSE}$`);
8826
+ function maskViewTransitionTails(input) {
8827
+ const tails = [];
8828
+ const masked = input.replace(VIEW_TAIL_RE, (match) => {
8829
+ const idx = tails.length;
8830
+ tails.push(match);
8831
+ return `${VIEW_TAIL_OPEN}${idx}${VIEW_TAIL_CLOSE}`;
8832
+ });
8833
+ return tails.length > 0 ? { masked, tails } : null;
8834
+ }
8835
+ function restoreViewTransitionTails(input, tails) {
8836
+ return input.replace(
8837
+ new RegExp(`${VIEW_TAIL_OPEN}(\\d+)${VIEW_TAIL_CLOSE}`, "g"),
8838
+ (_m, n) => tails[Number(n)] ?? ""
8839
+ );
8840
+ }
8814
8841
  var GrammarTransformer = class {
8815
8842
  constructor(sourceLocale = "en", targetLocale) {
8816
8843
  const source = getProfile(sourceLocale);
@@ -8832,6 +8859,10 @@ var GrammarTransformer = class {
8832
8859
  return this.targetProfile.code === "he" ? repairHebrewFrontedAccusative(out) : out;
8833
8860
  }
8834
8861
  transformInternal(input) {
8862
+ const viewTails = maskViewTransitionTails(input);
8863
+ if (viewTails) {
8864
+ return restoreViewTransitionTails(this.transformInternal(viewTails.masked), viewTails.tails);
8865
+ }
8835
8866
  const caret = maskCaretScopes(input);
8836
8867
  if (caret) {
8837
8868
  return restoreCaretScopes(this.transform(caret.masked), caret.scopes);
@@ -8884,6 +8915,10 @@ var GrammarTransformer = class {
8884
8915
  if (setScope !== null) {
8885
8916
  return setScope;
8886
8917
  }
8918
+ const viewTail = this.transformWithViewTransitionTail(input);
8919
+ if (viewTail !== null) {
8920
+ return viewTail;
8921
+ }
8887
8922
  const parsed = parseStatement(input, this.sourceProfile.code);
8888
8923
  if (!parsed) {
8889
8924
  return input;
@@ -8907,6 +8942,35 @@ var GrammarTransformer = class {
8907
8942
  }
8908
8943
  return joinTokens(reordered.map((e) => e.translated || e.value));
8909
8944
  }
8945
+ /**
8946
+ * Clause carrying a masked `using view transition` tail: strip the opaque
8947
+ * token, transform the clause alone, and re-append the token at the very end.
8948
+ *
8949
+ * The tail is a clause-final modifier in every word order the corpus emits:
8950
+ * the semantic side matches it as the literal `using view` marker plus a value
8951
+ * word, and the SOV/VSO event-handler patterns admit it as an optional
8952
+ * TRAILING group (after the with-marked operand). So the target position is
8953
+ * "end of the transformed clause" for all 24 languages — no per-profile
8954
+ * placement decision, which is what makes this a passthrough rather than a
8955
+ * role.
8956
+ *
8957
+ * Returns null when the clause carries no masked tail, or when the token is
8958
+ * not clause-final (nothing to reposition — leaving it in place still restores
8959
+ * verbatim English).
8960
+ */
8961
+ transformWithViewTransitionTail(input) {
8962
+ const trimmed = input.trim();
8963
+ const tokens = trimmed.split(/\s+/);
8964
+ if (tokens.length < 2) {
8965
+ return null;
8966
+ }
8967
+ if (!VIEW_TAIL_TOKEN_RE.test(tokens[tokens.length - 1])) {
8968
+ return null;
8969
+ }
8970
+ const tail = tokens[tokens.length - 1];
8971
+ const head = tokens.slice(0, -1).join(" ");
8972
+ return `${this.transformSingle(head)} ${tail}`;
8973
+ }
8910
8974
  /**
8911
8975
  * `<command …> end` fragments: transform the command without its stranded
8912
8976
  * terminator, then re-append the translated terminator as a standalone