@lokascript/i18n 1.0.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 (96) hide show
  1. package/README.md +286 -0
  2. package/dist/browser.cjs +7669 -0
  3. package/dist/browser.cjs.map +1 -0
  4. package/dist/browser.d.cts +50 -0
  5. package/dist/browser.d.ts +50 -0
  6. package/dist/browser.js +7592 -0
  7. package/dist/browser.js.map +1 -0
  8. package/dist/hyperfixi-i18n.min.js +2 -0
  9. package/dist/hyperfixi-i18n.min.js.map +1 -0
  10. package/dist/hyperfixi-i18n.mjs +8558 -0
  11. package/dist/hyperfixi-i18n.mjs.map +1 -0
  12. package/dist/index.cjs +14205 -0
  13. package/dist/index.cjs.map +1 -0
  14. package/dist/index.d.cts +947 -0
  15. package/dist/index.d.ts +947 -0
  16. package/dist/index.js +14095 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/transformer-Ckask-yw.d.cts +1041 -0
  19. package/dist/transformer-Ckask-yw.d.ts +1041 -0
  20. package/package.json +84 -0
  21. package/src/browser.ts +122 -0
  22. package/src/compatibility/browser-tests/grammar-demo.spec.ts +169 -0
  23. package/src/constants.ts +366 -0
  24. package/src/dictionaries/ar.ts +233 -0
  25. package/src/dictionaries/bn.ts +156 -0
  26. package/src/dictionaries/de.ts +233 -0
  27. package/src/dictionaries/derive.ts +515 -0
  28. package/src/dictionaries/en.ts +237 -0
  29. package/src/dictionaries/es.ts +233 -0
  30. package/src/dictionaries/fr.ts +233 -0
  31. package/src/dictionaries/hi.ts +270 -0
  32. package/src/dictionaries/id.ts +233 -0
  33. package/src/dictionaries/index.ts +238 -0
  34. package/src/dictionaries/it.ts +233 -0
  35. package/src/dictionaries/ja.ts +233 -0
  36. package/src/dictionaries/ko.ts +233 -0
  37. package/src/dictionaries/ms.ts +276 -0
  38. package/src/dictionaries/pl.ts +239 -0
  39. package/src/dictionaries/pt.ts +237 -0
  40. package/src/dictionaries/qu.ts +233 -0
  41. package/src/dictionaries/ru.ts +270 -0
  42. package/src/dictionaries/sw.ts +233 -0
  43. package/src/dictionaries/th.ts +156 -0
  44. package/src/dictionaries/tl.ts +276 -0
  45. package/src/dictionaries/tr.ts +233 -0
  46. package/src/dictionaries/uk.ts +270 -0
  47. package/src/dictionaries/vi.ts +210 -0
  48. package/src/dictionaries/zh.ts +233 -0
  49. package/src/enhanced-i18n.test.ts +454 -0
  50. package/src/enhanced-i18n.ts +713 -0
  51. package/src/examples/new-languages.ts +326 -0
  52. package/src/formatting.test.ts +213 -0
  53. package/src/formatting.ts +416 -0
  54. package/src/grammar/direct-mappings.ts +353 -0
  55. package/src/grammar/grammar.test.ts +1053 -0
  56. package/src/grammar/index.ts +59 -0
  57. package/src/grammar/profiles/index.ts +860 -0
  58. package/src/grammar/transformer.ts +1318 -0
  59. package/src/grammar/types.ts +630 -0
  60. package/src/index.ts +202 -0
  61. package/src/new-languages.test.ts +389 -0
  62. package/src/parser/analyze-conflicts.test.ts +229 -0
  63. package/src/parser/ar.ts +40 -0
  64. package/src/parser/create-provider.ts +309 -0
  65. package/src/parser/de.ts +36 -0
  66. package/src/parser/es.ts +31 -0
  67. package/src/parser/fr.ts +31 -0
  68. package/src/parser/id.ts +34 -0
  69. package/src/parser/index.ts +50 -0
  70. package/src/parser/ja.ts +36 -0
  71. package/src/parser/ko.ts +37 -0
  72. package/src/parser/locale-manager.test.ts +198 -0
  73. package/src/parser/locale-manager.ts +197 -0
  74. package/src/parser/parser-integration.test.ts +439 -0
  75. package/src/parser/pt.ts +37 -0
  76. package/src/parser/qu.ts +37 -0
  77. package/src/parser/sw.ts +37 -0
  78. package/src/parser/tr.ts +38 -0
  79. package/src/parser/types.ts +113 -0
  80. package/src/parser/zh.ts +38 -0
  81. package/src/plugins/vite.ts +224 -0
  82. package/src/plugins/webpack.ts +124 -0
  83. package/src/pluralization.test.ts +197 -0
  84. package/src/pluralization.ts +393 -0
  85. package/src/runtime.ts +441 -0
  86. package/src/ssr-integration.ts +225 -0
  87. package/src/test-setup.ts +195 -0
  88. package/src/translation-validation.test.ts +171 -0
  89. package/src/translator.test.ts +252 -0
  90. package/src/translator.ts +297 -0
  91. package/src/types.ts +209 -0
  92. package/src/utils/locale.ts +190 -0
  93. package/src/utils/tokenizer-adapter.ts +469 -0
  94. package/src/utils/tokenizer.ts +19 -0
  95. package/src/validators/index.ts +174 -0
  96. package/src/validators/schema.ts +129 -0
@@ -0,0 +1,860 @@
1
+ /**
2
+ * Language Profiles Index
3
+ *
4
+ * Concrete implementations of LanguageProfile for supported languages.
5
+ * Each profile inherits from a language family default and adds
6
+ * language-specific markers and rules.
7
+ */
8
+
9
+ import type { LanguageProfile } from '../types';
10
+
11
+ // =============================================================================
12
+ // English (Reference Language)
13
+ // =============================================================================
14
+
15
+ export const englishProfile: LanguageProfile = {
16
+ code: 'en',
17
+ name: 'English',
18
+
19
+ wordOrder: 'SVO',
20
+ adpositionType: 'preposition',
21
+ morphology: 'fusional',
22
+ direction: 'ltr',
23
+
24
+ canonicalOrder: [
25
+ 'event',
26
+ 'action',
27
+ 'patient',
28
+ 'source',
29
+ 'destination',
30
+ 'quantity',
31
+ 'duration',
32
+ 'method',
33
+ 'style',
34
+ ],
35
+
36
+ markers: [
37
+ { form: 'on', role: 'event', position: 'preposition', required: true },
38
+ { form: 'to', role: 'destination', position: 'preposition', required: false },
39
+ { form: 'into', role: 'destination', position: 'preposition', required: false },
40
+ { form: 'from', role: 'source', position: 'preposition', required: false },
41
+ { form: 'with', role: 'style', position: 'preposition', required: false },
42
+ { form: 'by', role: 'quantity', position: 'preposition', required: false },
43
+ { form: 'as', role: 'method', position: 'preposition', required: false },
44
+ { form: 'over', role: 'duration', position: 'preposition', required: false },
45
+ { form: 'for', role: 'duration', position: 'preposition', required: false },
46
+ ],
47
+ };
48
+
49
+ // =============================================================================
50
+ // Japanese (SOV, Postpositions)
51
+ // =============================================================================
52
+
53
+ export const japaneseProfile: LanguageProfile = {
54
+ code: 'ja',
55
+ name: '日本語',
56
+
57
+ wordOrder: 'SOV',
58
+ adpositionType: 'postposition',
59
+ morphology: 'agglutinative',
60
+ direction: 'ltr',
61
+
62
+ // Japanese: Object comes before verb, markers follow nouns
63
+ // "on click increment #count" → "#count を クリック で 増加"
64
+ canonicalOrder: ['patient', 'event', 'action'],
65
+
66
+ markers: [
67
+ // Particles (postpositions)
68
+ { form: 'を', role: 'patient', position: 'postposition', required: true },
69
+ { form: 'に', role: 'destination', position: 'postposition', required: true },
70
+ { form: 'から', role: 'source', position: 'postposition', required: true },
71
+ { form: 'で', role: 'event', position: 'postposition', required: true },
72
+ { form: 'で', role: 'style', position: 'postposition', required: false },
73
+ { form: 'と', role: 'style', position: 'postposition', required: false },
74
+ { form: 'へ', role: 'destination', position: 'postposition', required: false },
75
+ ],
76
+
77
+ rules: [
78
+ {
79
+ name: 'event-handler',
80
+ description: 'Transform event handlers to Japanese SOV order',
81
+ priority: 100,
82
+ match: {
83
+ commands: ['on'],
84
+ requiredRoles: ['event', 'action'],
85
+ optionalRoles: ['patient'],
86
+ },
87
+ transform: {
88
+ // #count を クリック で 増加
89
+ roleOrder: ['patient', 'event', 'action'],
90
+ insertMarkers: true,
91
+ },
92
+ },
93
+ {
94
+ name: 'put-into',
95
+ description: 'Transform put X into Y to Japanese order',
96
+ priority: 90,
97
+ match: {
98
+ commands: ['put', '置く'],
99
+ requiredRoles: ['action', 'patient', 'destination'],
100
+ },
101
+ transform: {
102
+ // X を Y に 置く
103
+ roleOrder: ['patient', 'destination', 'action'],
104
+ insertMarkers: true,
105
+ },
106
+ },
107
+ ],
108
+ };
109
+
110
+ // =============================================================================
111
+ // Korean (SOV, Postpositions - similar to Japanese)
112
+ // =============================================================================
113
+
114
+ export const koreanProfile: LanguageProfile = {
115
+ code: 'ko',
116
+ name: '한국어',
117
+
118
+ wordOrder: 'SOV',
119
+ adpositionType: 'postposition',
120
+ morphology: 'agglutinative',
121
+ direction: 'ltr',
122
+
123
+ canonicalOrder: ['patient', 'event', 'action'],
124
+
125
+ markers: [
126
+ // Korean particles (with vowel harmony variants)
127
+ { form: '를', role: 'patient', position: 'postposition', required: true, alternatives: ['을'] },
128
+ { form: '에', role: 'destination', position: 'postposition', required: true },
129
+ { form: '에서', role: 'source', position: 'postposition', required: true },
130
+ {
131
+ form: '로',
132
+ role: 'style',
133
+ position: 'postposition',
134
+ required: false,
135
+ alternatives: ['으로'],
136
+ },
137
+ { form: '와', role: 'style', position: 'postposition', required: false, alternatives: ['과'] },
138
+ {
139
+ form: '로',
140
+ role: 'method',
141
+ position: 'postposition',
142
+ required: false,
143
+ alternatives: ['으로'],
144
+ }, // "as" - same as instrument
145
+ ],
146
+
147
+ rules: [
148
+ {
149
+ name: 'event-handler',
150
+ description: 'Transform event handlers to Korean SOV order',
151
+ priority: 100,
152
+ match: {
153
+ commands: ['on'],
154
+ requiredRoles: ['event', 'action'],
155
+ },
156
+ transform: {
157
+ roleOrder: ['patient', 'event', 'action'],
158
+ insertMarkers: true,
159
+ },
160
+ },
161
+ ],
162
+ };
163
+
164
+ // =============================================================================
165
+ // Chinese (SVO, Topic-Prominent)
166
+ // =============================================================================
167
+
168
+ export const chineseProfile: LanguageProfile = {
169
+ code: 'zh',
170
+ name: '中文',
171
+
172
+ wordOrder: 'SVO', // But topic-prominent allows flexibility
173
+ adpositionType: 'preposition',
174
+ morphology: 'isolating',
175
+ direction: 'ltr',
176
+
177
+ // Chinese typically uses topic-comment structure
178
+ // Can front the object for emphasis: "#count 在 点击时 增加"
179
+ canonicalOrder: ['event', 'action', 'patient', 'destination'],
180
+
181
+ markers: [
182
+ { form: '当', role: 'event', position: 'preposition', required: true },
183
+ { form: '时', role: 'event', position: 'postposition', required: true }, // Circumfix with 当
184
+ { form: '把', role: 'patient', position: 'preposition', required: false }, // BA construction
185
+ { form: '到', role: 'destination', position: 'preposition', required: false },
186
+ { form: '从', role: 'source', position: 'preposition', required: false },
187
+ { form: '用', role: 'style', position: 'preposition', required: false },
188
+ { form: '的', role: 'method', position: 'postposition', required: false },
189
+ ],
190
+
191
+ rules: [
192
+ {
193
+ name: 'event-handler-standard',
194
+ description: 'Standard event handler: 当 X 时 Y',
195
+ priority: 100,
196
+ match: {
197
+ // Don't match commands - match by statement type having event role
198
+ requiredRoles: ['event', 'action'],
199
+ },
200
+ transform: {
201
+ // 当 点击 时 增加 #count
202
+ roleOrder: ['event', 'action', 'patient'],
203
+ insertMarkers: true,
204
+ custom: (parsed, _profile) => {
205
+ // Handle 当...时 circumfix
206
+ const event = parsed.roles.get('event');
207
+ const action = parsed.roles.get('action');
208
+ const patient = parsed.roles.get('patient');
209
+
210
+ const parts = ['当', event?.translated || event?.value, '时'];
211
+ parts.push(action?.translated || action?.value || '');
212
+ if (patient) {
213
+ parts.push(patient.translated || patient.value);
214
+ }
215
+
216
+ return parts.filter(Boolean).join(' ');
217
+ },
218
+ },
219
+ },
220
+ {
221
+ name: 'ba-construction',
222
+ description: 'BA construction for object-fronting: 把 X Y',
223
+ priority: 80,
224
+ match: {
225
+ commands: ['put', 'set', 'move'],
226
+ requiredRoles: ['action', 'patient', 'destination'],
227
+ },
228
+ transform: {
229
+ // 把 X 放 到 Y
230
+ roleOrder: ['patient', 'action', 'destination'],
231
+ insertMarkers: true,
232
+ },
233
+ },
234
+ ],
235
+ };
236
+
237
+ // =============================================================================
238
+ // Arabic (VSO, RTL)
239
+ // =============================================================================
240
+
241
+ export const arabicProfile: LanguageProfile = {
242
+ code: 'ar',
243
+ name: 'العربية',
244
+
245
+ wordOrder: 'VSO',
246
+ adpositionType: 'preposition',
247
+ morphology: 'fusional', // Root-pattern morphology
248
+ direction: 'rtl',
249
+
250
+ // Arabic VSO: Verb first, then subject, then object
251
+ canonicalOrder: ['action', 'agent', 'patient', 'destination', 'source'],
252
+
253
+ markers: [
254
+ { form: 'عند', role: 'event', position: 'preposition', required: true },
255
+ { form: 'إلى', role: 'destination', position: 'preposition', required: false },
256
+ { form: 'في', role: 'destination', position: 'preposition', required: false },
257
+ { form: 'من', role: 'source', position: 'preposition', required: false },
258
+ // بـ- notation: trailing hyphen indicates prefix that attaches without space
259
+ { form: 'بـ-', role: 'style', position: 'preposition', required: false },
260
+ { form: 'مع', role: 'style', position: 'preposition', required: false },
261
+ // كـ- notation: "as/like" prefix for manner
262
+ { form: 'كـ-', role: 'method', position: 'preposition', required: false },
263
+ ],
264
+
265
+ rules: [
266
+ {
267
+ name: 'event-handler-vso',
268
+ description: 'VSO event handler: VERB TARGET عند EVENT',
269
+ priority: 100,
270
+ match: {
271
+ commands: ['on'],
272
+ requiredRoles: ['event', 'action'],
273
+ },
274
+ transform: {
275
+ // زِد #count عند النقر (increment #count on click)
276
+ roleOrder: ['action', 'patient', 'event'],
277
+ insertMarkers: true,
278
+ },
279
+ },
280
+ ],
281
+ };
282
+
283
+ // =============================================================================
284
+ // Turkish (SOV, Agglutinative)
285
+ // =============================================================================
286
+
287
+ export const turkishProfile: LanguageProfile = {
288
+ code: 'tr',
289
+ name: 'Türkçe',
290
+
291
+ wordOrder: 'SOV',
292
+ adpositionType: 'postposition',
293
+ morphology: 'agglutinative',
294
+ direction: 'ltr',
295
+
296
+ canonicalOrder: ['patient', 'event', 'action'],
297
+
298
+ markers: [
299
+ // Turkish case suffixes (simplified - real Turkish has vowel harmony)
300
+ {
301
+ form: '-i',
302
+ role: 'patient',
303
+ position: 'postposition',
304
+ required: true,
305
+ alternatives: ['-ı', '-u', '-ü'],
306
+ },
307
+ {
308
+ form: '-e',
309
+ role: 'destination',
310
+ position: 'postposition',
311
+ required: true,
312
+ alternatives: ['-a'],
313
+ },
314
+ {
315
+ form: '-den',
316
+ role: 'source',
317
+ position: 'postposition',
318
+ required: true,
319
+ alternatives: ['-dan'],
320
+ },
321
+ { form: '-de', role: 'event', position: 'postposition', required: true, alternatives: ['-da'] },
322
+ { form: 'ile', role: 'style', position: 'postposition', required: false },
323
+ { form: 'olarak', role: 'method', position: 'postposition', required: false },
324
+ ],
325
+
326
+ rules: [
327
+ {
328
+ name: 'event-handler-sov',
329
+ description: 'SOV event handler',
330
+ priority: 100,
331
+ match: {
332
+ commands: ['on'],
333
+ requiredRoles: ['event', 'action'],
334
+ },
335
+ transform: {
336
+ roleOrder: ['patient', 'event', 'action'],
337
+ insertMarkers: true,
338
+ },
339
+ },
340
+ ],
341
+ };
342
+
343
+ // =============================================================================
344
+ // Spanish (SVO, Romance)
345
+ // =============================================================================
346
+
347
+ export const spanishProfile: LanguageProfile = {
348
+ code: 'es',
349
+ name: 'Español',
350
+
351
+ wordOrder: 'SVO',
352
+ adpositionType: 'preposition',
353
+ morphology: 'fusional',
354
+ direction: 'ltr',
355
+
356
+ canonicalOrder: ['event', 'action', 'patient', 'destination'],
357
+
358
+ markers: [
359
+ // Event: "En hacer clic" or "Al hacer clic"
360
+ { form: 'en', role: 'event', position: 'preposition', required: true },
361
+ // Destination: Prioritize 'a' over 'en' to avoid collision with event marker
362
+ { form: 'a', role: 'destination', position: 'preposition', required: false },
363
+ { form: 'hacia', role: 'destination', position: 'preposition', required: false }, // "Towards"
364
+ { form: 'de', role: 'source', position: 'preposition', required: false },
365
+ { form: 'con', role: 'style', position: 'preposition', required: false },
366
+ { form: 'por', role: 'quantity', position: 'preposition', required: false },
367
+ { form: 'como', role: 'method', position: 'preposition', required: false },
368
+ ],
369
+ };
370
+
371
+ // =============================================================================
372
+ // German (SVO, Germanic)
373
+ // =============================================================================
374
+
375
+ export const germanProfile: LanguageProfile = {
376
+ code: 'de',
377
+ name: 'Deutsch',
378
+
379
+ wordOrder: 'SVO', // V2 in main clauses, but SVO for our purposes
380
+ adpositionType: 'preposition',
381
+ morphology: 'fusional',
382
+ direction: 'ltr',
383
+
384
+ canonicalOrder: ['event', 'action', 'patient', 'destination'],
385
+
386
+ markers: [
387
+ { form: 'bei', role: 'event', position: 'preposition', required: true },
388
+ { form: 'zu', role: 'destination', position: 'preposition', required: false },
389
+ { form: 'in', role: 'destination', position: 'preposition', required: false },
390
+ { form: 'von', role: 'source', position: 'preposition', required: false },
391
+ { form: 'aus', role: 'source', position: 'preposition', required: false },
392
+ { form: 'mit', role: 'style', position: 'preposition', required: false },
393
+ { form: 'um', role: 'quantity', position: 'preposition', required: false },
394
+ { form: 'als', role: 'method', position: 'preposition', required: false },
395
+ ],
396
+ };
397
+
398
+ // =============================================================================
399
+ // French (SVO, Romance)
400
+ // =============================================================================
401
+
402
+ export const frenchProfile: LanguageProfile = {
403
+ code: 'fr',
404
+ name: 'Français',
405
+
406
+ wordOrder: 'SVO',
407
+ adpositionType: 'preposition',
408
+ morphology: 'fusional',
409
+ direction: 'ltr',
410
+
411
+ canonicalOrder: ['event', 'action', 'patient', 'destination'],
412
+
413
+ markers: [
414
+ { form: 'sur', role: 'event', position: 'preposition', required: true },
415
+ { form: 'à', role: 'destination', position: 'preposition', required: false },
416
+ { form: 'dans', role: 'destination', position: 'preposition', required: false },
417
+ { form: 'de', role: 'source', position: 'preposition', required: false },
418
+ { form: 'avec', role: 'style', position: 'preposition', required: false },
419
+ { form: 'par', role: 'quantity', position: 'preposition', required: false },
420
+ { form: 'comme', role: 'method', position: 'preposition', required: false },
421
+ ],
422
+ };
423
+
424
+ // =============================================================================
425
+ // Portuguese (SVO, Romance)
426
+ // =============================================================================
427
+
428
+ export const portugueseProfile: LanguageProfile = {
429
+ code: 'pt',
430
+ name: 'Português',
431
+
432
+ wordOrder: 'SVO',
433
+ adpositionType: 'preposition',
434
+ morphology: 'fusional',
435
+ direction: 'ltr',
436
+
437
+ canonicalOrder: ['event', 'action', 'patient', 'destination'],
438
+
439
+ markers: [
440
+ { form: 'em', role: 'event', position: 'preposition', required: true },
441
+ { form: 'para', role: 'destination', position: 'preposition', required: false },
442
+ { form: 'em', role: 'destination', position: 'preposition', required: false },
443
+ { form: 'de', role: 'source', position: 'preposition', required: false },
444
+ { form: 'com', role: 'style', position: 'preposition', required: false },
445
+ { form: 'por', role: 'quantity', position: 'preposition', required: false },
446
+ { form: 'como', role: 'method', position: 'preposition', required: false },
447
+ ],
448
+ };
449
+
450
+ // =============================================================================
451
+ // Indonesian (SVO, Austronesian)
452
+ // =============================================================================
453
+
454
+ export const indonesianProfile: LanguageProfile = {
455
+ code: 'id',
456
+ name: 'Bahasa Indonesia',
457
+
458
+ wordOrder: 'SVO',
459
+ adpositionType: 'preposition',
460
+ morphology: 'agglutinative',
461
+ direction: 'ltr',
462
+
463
+ canonicalOrder: ['event', 'action', 'patient', 'destination'],
464
+
465
+ markers: [
466
+ { form: 'pada', role: 'event', position: 'preposition', required: true },
467
+ { form: 'ke', role: 'destination', position: 'preposition', required: false },
468
+ { form: 'dari', role: 'source', position: 'preposition', required: false },
469
+ { form: 'dengan', role: 'style', position: 'preposition', required: false },
470
+ { form: 'sebagai', role: 'method', position: 'preposition', required: false },
471
+ ],
472
+ };
473
+
474
+ // =============================================================================
475
+ // Quechua (SOV, Quechuan)
476
+ // =============================================================================
477
+
478
+ export const quechuaProfile: LanguageProfile = {
479
+ code: 'qu',
480
+ name: 'Runasimi',
481
+
482
+ wordOrder: 'SOV',
483
+ adpositionType: 'postposition',
484
+ morphology: 'agglutinative', // Actually polysynthetic
485
+ direction: 'ltr',
486
+
487
+ canonicalOrder: ['patient', 'source', 'destination', 'event', 'action'],
488
+
489
+ markers: [
490
+ { form: '-ta', role: 'patient', position: 'postposition', required: true },
491
+ { form: '-man', role: 'destination', position: 'postposition', required: true },
492
+ { form: '-manta', role: 'source', position: 'postposition', required: true },
493
+ { form: '-pi', role: 'event', position: 'postposition', required: true },
494
+ { form: '-wan', role: 'style', position: 'postposition', required: false },
495
+ { form: 'hina', role: 'method', position: 'postposition', required: false }, // "as/like"
496
+ ],
497
+ };
498
+
499
+ // =============================================================================
500
+ // Swahili (SVO, Bantu)
501
+ // =============================================================================
502
+
503
+ export const swahiliProfile: LanguageProfile = {
504
+ code: 'sw',
505
+ name: 'Kiswahili',
506
+
507
+ wordOrder: 'SVO',
508
+ adpositionType: 'preposition',
509
+ morphology: 'agglutinative',
510
+ direction: 'ltr',
511
+
512
+ canonicalOrder: ['event', 'action', 'patient', 'destination'],
513
+
514
+ markers: [
515
+ { form: 'kwenye', role: 'event', position: 'preposition', required: true },
516
+ { form: 'kwa', role: 'destination', position: 'preposition', required: false },
517
+ { form: 'kutoka', role: 'source', position: 'preposition', required: false },
518
+ { form: 'na', role: 'style', position: 'preposition', required: false },
519
+ { form: 'kama', role: 'method', position: 'preposition', required: false }, // "as/like"
520
+ ],
521
+ };
522
+
523
+ // =============================================================================
524
+ // Bengali (SOV, Postpositions - similar to Japanese/Korean)
525
+ // =============================================================================
526
+
527
+ export const bengaliProfile: LanguageProfile = {
528
+ code: 'bn',
529
+ name: 'বাংলা',
530
+
531
+ wordOrder: 'SOV',
532
+ adpositionType: 'postposition',
533
+ morphology: 'agglutinative',
534
+ direction: 'ltr',
535
+
536
+ // Bengali: Object comes before verb, postpositions follow nouns
537
+ // "on click increment #count" → "#count কে ক্লিক এ বৃদ্ধি"
538
+ canonicalOrder: ['patient', 'event', 'action'],
539
+
540
+ markers: [
541
+ // Postpositions
542
+ { form: 'কে', role: 'patient', position: 'postposition', required: true },
543
+ { form: 'তে', role: 'destination', position: 'postposition', required: true },
544
+ { form: 'এ', role: 'event', position: 'postposition', required: true },
545
+ { form: 'থেকে', role: 'source', position: 'postposition', required: true },
546
+ { form: 'দিয়ে', role: 'style', position: 'postposition', required: false },
547
+ { form: 'জন্য', role: 'duration', position: 'postposition', required: false },
548
+ ],
549
+
550
+ rules: [
551
+ {
552
+ name: 'event-handler',
553
+ description: 'Transform event handlers to Bengali SOV order',
554
+ priority: 100,
555
+ match: {
556
+ commands: ['on'],
557
+ requiredRoles: ['event', 'action'],
558
+ optionalRoles: ['patient'],
559
+ },
560
+ transform: {
561
+ // #count কে ক্লিক এ বৃদ্ধি
562
+ roleOrder: ['patient', 'event', 'action'],
563
+ insertMarkers: true,
564
+ },
565
+ },
566
+ ],
567
+ };
568
+
569
+ // =============================================================================
570
+ // Italian (SVO, Romance)
571
+ // =============================================================================
572
+
573
+ export const italianProfile: LanguageProfile = {
574
+ code: 'it',
575
+ name: 'Italiano',
576
+
577
+ wordOrder: 'SVO',
578
+ adpositionType: 'preposition',
579
+ morphology: 'fusional',
580
+ direction: 'ltr',
581
+
582
+ canonicalOrder: ['event', 'action', 'patient', 'destination'],
583
+
584
+ markers: [
585
+ { form: 'su', role: 'event', position: 'preposition', required: true },
586
+ { form: 'in', role: 'destination', position: 'preposition', required: false },
587
+ { form: 'a', role: 'destination', position: 'preposition', required: false },
588
+ { form: 'da', role: 'source', position: 'preposition', required: false },
589
+ { form: 'di', role: 'source', position: 'preposition', required: false },
590
+ { form: 'con', role: 'style', position: 'preposition', required: false },
591
+ { form: 'come', role: 'method', position: 'preposition', required: false },
592
+ ],
593
+ };
594
+
595
+ // =============================================================================
596
+ // Russian (SVO, Slavic)
597
+ // =============================================================================
598
+
599
+ export const russianProfile: LanguageProfile = {
600
+ code: 'ru',
601
+ name: 'Русский',
602
+
603
+ wordOrder: 'SVO',
604
+ adpositionType: 'preposition',
605
+ morphology: 'fusional',
606
+ direction: 'ltr',
607
+
608
+ canonicalOrder: ['event', 'action', 'patient', 'destination'],
609
+
610
+ markers: [
611
+ { form: 'при', role: 'event', position: 'preposition', required: true },
612
+ { form: 'в', role: 'destination', position: 'preposition', required: false },
613
+ { form: 'на', role: 'destination', position: 'preposition', required: false },
614
+ { form: 'к', role: 'destination', position: 'preposition', required: false },
615
+ { form: 'из', role: 'source', position: 'preposition', required: false },
616
+ { form: 'от', role: 'source', position: 'preposition', required: false },
617
+ { form: 'с', role: 'source', position: 'preposition', required: false },
618
+ { form: 'с', role: 'style', position: 'preposition', required: false },
619
+ { form: 'со', role: 'style', position: 'preposition', required: false },
620
+ { form: 'как', role: 'method', position: 'preposition', required: false },
621
+ ],
622
+ };
623
+
624
+ // =============================================================================
625
+ // Ukrainian (SVO, Slavic)
626
+ // =============================================================================
627
+
628
+ export const ukrainianProfile: LanguageProfile = {
629
+ code: 'uk',
630
+ name: 'Українська',
631
+
632
+ wordOrder: 'SVO',
633
+ adpositionType: 'preposition',
634
+ morphology: 'fusional',
635
+ direction: 'ltr',
636
+
637
+ canonicalOrder: ['event', 'action', 'patient', 'destination'],
638
+
639
+ markers: [
640
+ { form: 'при', role: 'event', position: 'preposition', required: true },
641
+ { form: 'в', role: 'destination', position: 'preposition', required: false },
642
+ { form: 'на', role: 'destination', position: 'preposition', required: false },
643
+ { form: 'до', role: 'destination', position: 'preposition', required: false },
644
+ { form: 'з', role: 'source', position: 'preposition', required: false },
645
+ { form: 'від', role: 'source', position: 'preposition', required: false },
646
+ { form: 'із', role: 'source', position: 'preposition', required: false },
647
+ { form: 'з', role: 'style', position: 'preposition', required: false },
648
+ { form: 'із', role: 'style', position: 'preposition', required: false },
649
+ { form: 'як', role: 'method', position: 'preposition', required: false },
650
+ ],
651
+ };
652
+
653
+ // =============================================================================
654
+ // Vietnamese (SVO, Isolating)
655
+ // =============================================================================
656
+
657
+ export const vietnameseProfile: LanguageProfile = {
658
+ code: 'vi',
659
+ name: 'Tiếng Việt',
660
+
661
+ wordOrder: 'SVO',
662
+ adpositionType: 'preposition',
663
+ morphology: 'isolating',
664
+ direction: 'ltr',
665
+
666
+ canonicalOrder: ['event', 'action', 'patient', 'destination'],
667
+
668
+ markers: [
669
+ { form: 'khi', role: 'event', position: 'preposition', required: true },
670
+ { form: 'vào', role: 'destination', position: 'preposition', required: false },
671
+ { form: 'cho', role: 'destination', position: 'preposition', required: false },
672
+ { form: 'đến', role: 'destination', position: 'preposition', required: false },
673
+ { form: 'từ', role: 'source', position: 'preposition', required: false },
674
+ { form: 'khỏi', role: 'source', position: 'preposition', required: false },
675
+ { form: 'với', role: 'style', position: 'preposition', required: false },
676
+ { form: 'như', role: 'method', position: 'preposition', required: false },
677
+ ],
678
+ };
679
+
680
+ // =============================================================================
681
+ // Hindi (SOV, Postpositions)
682
+ // =============================================================================
683
+
684
+ export const hindiProfile: LanguageProfile = {
685
+ code: 'hi',
686
+ name: 'हिन्दी',
687
+
688
+ wordOrder: 'SOV',
689
+ adpositionType: 'postposition',
690
+ morphology: 'fusional',
691
+ direction: 'ltr',
692
+
693
+ // Hindi: Object comes before verb, postpositions follow nouns
694
+ // "on click increment #count" → "#count को क्लिक पर बढ़ाएं"
695
+ canonicalOrder: ['patient', 'event', 'action'],
696
+
697
+ markers: [
698
+ { form: 'को', role: 'patient', position: 'postposition', required: true },
699
+ { form: 'में', role: 'destination', position: 'postposition', required: true },
700
+ { form: 'पर', role: 'destination', position: 'postposition', required: false },
701
+ { form: 'पर', role: 'event', position: 'postposition', required: true },
702
+ { form: 'से', role: 'source', position: 'postposition', required: true },
703
+ { form: 'से', role: 'style', position: 'postposition', required: false },
704
+ { form: 'साथ', role: 'style', position: 'postposition', required: false },
705
+ { form: 'के रूप में', role: 'method', position: 'postposition', required: false },
706
+ ],
707
+
708
+ rules: [
709
+ {
710
+ name: 'event-handler',
711
+ description: 'Transform event handlers to Hindi SOV order',
712
+ priority: 100,
713
+ match: {
714
+ commands: ['on'],
715
+ requiredRoles: ['event', 'action'],
716
+ optionalRoles: ['patient'],
717
+ },
718
+ transform: {
719
+ // #count को क्लिक पर बढ़ाएं
720
+ roleOrder: ['patient', 'event', 'action'],
721
+ insertMarkers: true,
722
+ },
723
+ },
724
+ ],
725
+ };
726
+
727
+ // =============================================================================
728
+ // Tagalog (VSO, Prepositions)
729
+ // =============================================================================
730
+
731
+ export const tagalogProfile: LanguageProfile = {
732
+ code: 'tl',
733
+ name: 'Tagalog',
734
+
735
+ wordOrder: 'VSO',
736
+ adpositionType: 'preposition',
737
+ morphology: 'agglutinative',
738
+ direction: 'ltr',
739
+
740
+ // Tagalog VSO: Verb first, then subject, then object
741
+ canonicalOrder: ['action', 'agent', 'patient', 'destination', 'source'],
742
+
743
+ markers: [
744
+ { form: 'kapag', role: 'event', position: 'preposition', required: true },
745
+ { form: 'sa', role: 'destination', position: 'preposition', required: false },
746
+ { form: 'mula sa', role: 'source', position: 'preposition', required: false },
747
+ { form: 'nang', role: 'style', position: 'preposition', required: false },
748
+ { form: 'bilang', role: 'method', position: 'preposition', required: false },
749
+ ],
750
+
751
+ rules: [
752
+ {
753
+ name: 'event-handler-vso',
754
+ description: 'VSO event handler: VERB TARGET kapag EVENT',
755
+ priority: 100,
756
+ match: {
757
+ commands: ['on'],
758
+ requiredRoles: ['event', 'action'],
759
+ },
760
+ transform: {
761
+ // palitan #count kapag click (toggle #count on click)
762
+ roleOrder: ['action', 'patient', 'event'],
763
+ insertMarkers: true,
764
+ },
765
+ },
766
+ ],
767
+ };
768
+
769
+ // =============================================================================
770
+ // Thai (SVO, Isolating, No Spaces)
771
+ // =============================================================================
772
+
773
+ export const thaiProfile: LanguageProfile = {
774
+ code: 'th',
775
+ name: 'ไทย',
776
+
777
+ wordOrder: 'SVO',
778
+ adpositionType: 'preposition',
779
+ morphology: 'isolating',
780
+ direction: 'ltr',
781
+
782
+ canonicalOrder: ['event', 'action', 'patient', 'destination'],
783
+
784
+ markers: [
785
+ { form: 'เมื่อ', role: 'event', position: 'preposition', required: true },
786
+ { form: 'ใน', role: 'destination', position: 'preposition', required: false },
787
+ { form: 'ไปยัง', role: 'destination', position: 'preposition', required: false },
788
+ { form: 'จาก', role: 'source', position: 'preposition', required: false },
789
+ { form: 'ด้วย', role: 'style', position: 'preposition', required: false },
790
+ { form: 'เป็น', role: 'method', position: 'preposition', required: false },
791
+ ],
792
+ };
793
+
794
+ // =============================================================================
795
+ // Polish (SVO, Fusional, Imperative)
796
+ // =============================================================================
797
+
798
+ export const polishProfile: LanguageProfile = {
799
+ code: 'pl',
800
+ name: 'Polski',
801
+
802
+ wordOrder: 'SVO',
803
+ adpositionType: 'preposition',
804
+ morphology: 'fusional',
805
+ direction: 'ltr',
806
+
807
+ canonicalOrder: ['event', 'action', 'patient', 'destination'],
808
+
809
+ markers: [
810
+ { form: 'gdy', role: 'event', position: 'preposition', required: true },
811
+ { form: 'przy', role: 'event', position: 'preposition', required: false },
812
+ { form: 'do', role: 'destination', position: 'preposition', required: false },
813
+ { form: 'w', role: 'destination', position: 'preposition', required: false },
814
+ { form: 'na', role: 'destination', position: 'preposition', required: false },
815
+ { form: 'z', role: 'source', position: 'preposition', required: false },
816
+ { form: 'od', role: 'source', position: 'preposition', required: false },
817
+ { form: 'ze', role: 'source', position: 'preposition', required: false },
818
+ { form: 'z', role: 'style', position: 'preposition', required: false },
819
+ { form: 'ze', role: 'style', position: 'preposition', required: false },
820
+ { form: 'jako', role: 'method', position: 'preposition', required: false },
821
+ ],
822
+ };
823
+
824
+ // =============================================================================
825
+ // Profile Registry
826
+ // =============================================================================
827
+
828
+ export const profiles: Record<string, LanguageProfile> = {
829
+ en: englishProfile,
830
+ ja: japaneseProfile,
831
+ ko: koreanProfile,
832
+ zh: chineseProfile,
833
+ ar: arabicProfile,
834
+ tr: turkishProfile,
835
+ es: spanishProfile,
836
+ de: germanProfile,
837
+ fr: frenchProfile,
838
+ pt: portugueseProfile,
839
+ id: indonesianProfile,
840
+ qu: quechuaProfile,
841
+ sw: swahiliProfile,
842
+ bn: bengaliProfile,
843
+ // New profiles
844
+ it: italianProfile,
845
+ ru: russianProfile,
846
+ uk: ukrainianProfile,
847
+ vi: vietnameseProfile,
848
+ hi: hindiProfile,
849
+ tl: tagalogProfile,
850
+ th: thaiProfile,
851
+ pl: polishProfile,
852
+ };
853
+
854
+ export function getProfile(locale: string): LanguageProfile | undefined {
855
+ return profiles[locale];
856
+ }
857
+
858
+ export function getSupportedLocales(): string[] {
859
+ return Object.keys(profiles);
860
+ }