VirtualKimi commited on
Commit
e1b0939
·
verified ·
1 Parent(s): 01d29ea

Upload 21 files

Browse files
kimi-js/kimi-config.js CHANGED
@@ -94,7 +94,8 @@ window.KIMI_CONFIG = {
94
  de: "German",
95
  it: "Italian",
96
  ja: "Japanese",
97
- zh: "Chinese"
 
98
  }
99
  };
100
 
 
94
  de: "German",
95
  it: "Italian",
96
  ja: "Japanese",
97
+ zh: "Chinese",
98
+ "pt-br": "Portuguese (Brazil)"
99
  }
100
  };
101
 
kimi-js/kimi-constants.js CHANGED
@@ -208,6 +208,29 @@ window.KIMI_CONTEXT_KEYWORDS = {
208
  kiss: ["bacio", "baci", "abbracciare", "bacino", "abbraccio", "baciotto"],
209
  dancing: ["ballare", "girare", "muoversi", "scuotere"],
210
  listening: ["ascoltami", "fai attenzione", "presta orecchio", "concentrati", "ascolta", "parla", "domanda", "dimmi"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  }
212
  };
213
 
@@ -218,7 +241,8 @@ window.KIMI_CONTEXT_POSITIVE = {
218
  de: ["glücklich", "freude", "toll", "perfekt", "ausgezeichnet", "großartig", "wunderbar", "herrlich"],
219
  it: ["felice", "gioia", "fantastico", "perfetto", "eccellente", "magnifico", "meraviglioso", "ottimo"],
220
  ja: ["幸せ", "喜び", "素晴らしい", "完璧", "優秀", "壮大", "最高", "嬉しい"],
221
- zh: ["快乐", "喜悦", "很棒", "完美", "优秀", "壮丽", "太好了", "开心"]
 
222
  };
223
 
224
  window.KIMI_CONTEXT_NEGATIVE = {
@@ -332,7 +356,23 @@ window.KIMI_CONTEXT_NEGATIVE = {
332
  "puttana"
333
  ],
334
  ja: ["悲しい", "怒り", "失望", "問題", "悪い", "イライラ", "心配", "不満", "嫌い", "ばか", "くそ", "アホ"],
335
- zh: ["悲伤", "愤怒", "失望", "问题", "坏", "沮丧", "担心", "烦", "讨厌", "笨蛋", "傻", "婊子"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
  };
337
 
338
  // Personality keywords for trait analysis (multilingual)
@@ -743,6 +783,69 @@ window.KIMI_PERSONALITY_KEYWORDS = {
743
  kiss: ["吻", "亲吻", "拥抱", "亲"],
744
  dancing: ["跳舞", "舞蹈", "移动", "律动", "步伐"],
745
  listening: ["听", "听听", "倾听", "说", "说话", "问题", "提问", "告诉我"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
746
  }
747
  };
748
 
@@ -805,7 +908,8 @@ window.KIMI_NEGATORS = window.KIMI_NEGATORS || {
805
  de: ["nicht", "nie", "kein", "keine", "niemand", "nichts"],
806
  it: ["non", "mai", "nessuno", "niente"],
807
  ja: ["ない", "ません", "ず", "無い"],
808
- zh: ["不", "没", "没有", "从来没有"]
 
809
  };
810
 
811
  window.KIMI_NEGATION_WINDOW = window.KIMI_NEGATION_WINDOW || 3; // tokens to look back for negation
@@ -939,7 +1043,29 @@ window.KIMI_COMMON_WORDS = {
939
  "una"
940
  ],
941
  ja: ["の", "に", "は", "を", "た", "が", "で", "て", "と", "し", "れ", "さ", "ある", "いる", "も", "する", "から"],
942
- zh: ["的", "一", "是", "在", "不", "了", "有", "和", "人", "这", "中", "大", "为", "上", "个", "国", "我", "以", "要"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
943
  };
944
 
945
  // Build Set version for fast lookup (must be outside the object)
@@ -979,7 +1105,8 @@ window.KIMI_EMOTION_SENSITIVITY = {
979
  de: { romantic: 1.0, laughing: 1.0 },
980
  en: { romantic: 1.0, laughing: 1.0 },
981
  ja: { romantic: 1.0, laughing: 1.0 },
982
- zh: { romantic: 1.0, laughing: 1.0 }
 
983
  };
984
 
985
  // Personality trait adjustment multipliers
 
208
  kiss: ["bacio", "baci", "abbracciare", "bacino", "abbraccio", "baciotto"],
209
  dancing: ["ballare", "girare", "muoversi", "scuotere"],
210
  listening: ["ascoltami", "fai attenzione", "presta orecchio", "concentrati", "ascolta", "parla", "domanda", "dimmi"]
211
+ },
212
+ "pt-br": {
213
+ surprise: ["uau", "oh", "nossa", "incrível", "surpreendente", "não acredito", "sério?", "caramba"],
214
+ laughing: ["haha", "rsrs", "kkk", "rir", "engraçado", "hilário", "risada", "você está brincando"],
215
+ shy: ["tímido", "envergonhado", "corar", "constrangido", "intimidado", "reservado", "nervoso", "tímida"],
216
+ confident: ["confiança", "orgulhoso", "confiante", "forte", "determinado", "seguro", "corajoso", "líder"],
217
+ romantic: ["amor", "romântico", "carinho", "abraço", "beijo", "meu amor", "querido", "apaixonado", "coração"],
218
+ flirtatious: ["flerte", "provocar", "seduzir", "charme", "flertar", "piscadinha", "safado", "sedutor"],
219
+ goodbye: ["tchau", "adeus", "até logo", "até breve", "ciao", "cuide-se", "até mais", "falou"],
220
+ kiss: ["beijo", "beijar", "abraçar", "beijinho", "selinho", "abraço"],
221
+ dancing: ["dançar", "dança", "mexer", "ritmo", "passo", "girar", "rebolar", "balançar"],
222
+ listening: [
223
+ "escute",
224
+ "escutar",
225
+ "ouvir",
226
+ "fale",
227
+ "falar",
228
+ "pergunta",
229
+ "perguntar",
230
+ "me diga",
231
+ "preste atenção",
232
+ "concentre-se"
233
+ ]
234
  }
235
  };
236
 
 
241
  de: ["glücklich", "freude", "toll", "perfekt", "ausgezeichnet", "großartig", "wunderbar", "herrlich"],
242
  it: ["felice", "gioia", "fantastico", "perfetto", "eccellente", "magnifico", "meraviglioso", "ottimo"],
243
  ja: ["幸せ", "喜び", "素晴らしい", "完璧", "優秀", "壮大", "最高", "嬉しい"],
244
+ zh: ["快乐", "喜悦", "很棒", "完美", "优秀", "壮丽", "太好了", "开心"],
245
+ "pt-br": ["feliz", "alegria", "ótimo", "incrível", "perfeito", "excelente", "magnífico", "maravilhoso", "legal"]
246
  };
247
 
248
  window.KIMI_CONTEXT_NEGATIVE = {
 
356
  "puttana"
357
  ],
358
  ja: ["悲しい", "怒り", "失望", "問題", "悪い", "イライラ", "心配", "不満", "嫌い", "ばか", "くそ", "アホ"],
359
+ zh: ["悲伤", "愤怒", "失望", "问题", "坏", "沮丧", "担心", "烦", "讨厌", "笨蛋", "傻", "婊子"],
360
+ "pt-br": [
361
+ "triste",
362
+ "raiva",
363
+ "zangado",
364
+ "decepcionado",
365
+ "problema",
366
+ "ruim",
367
+ "frustrado",
368
+ "preocupado",
369
+ "chateado",
370
+ "irritado",
371
+ "ódio",
372
+ "idiota",
373
+ "burro",
374
+ "estúpido"
375
+ ]
376
  };
377
 
378
  // Personality keywords for trait analysis (multilingual)
 
783
  kiss: ["吻", "亲吻", "拥抱", "亲"],
784
  dancing: ["跳舞", "舞蹈", "移动", "律动", "步伐"],
785
  listening: ["听", "听听", "倾听", "说", "说话", "问题", "提问", "告诉我"]
786
+ },
787
+ "pt-br": {
788
+ humor: {
789
+ positive: [
790
+ "engraçado",
791
+ "divertido",
792
+ "piada",
793
+ "rir",
794
+ "hilário",
795
+ "humorístico",
796
+ "sorriso",
797
+ "espirituoso",
798
+ "brincalhão"
799
+ ],
800
+ negative: ["chato", "entediante", "triste", "sério", "frio", "seco", "deprimente", "sombrio"]
801
+ },
802
+ intelligence: {
803
+ positive: ["inteligente", "esperto", "brilhante", "lógico", "astuto", "sábio", "gênio", "pensativo", "perspicaz"],
804
+ negative: ["burro", "idiota", "tolo", "lento", "ingênuo", "ignorante", "simples"]
805
+ },
806
+ romance: {
807
+ positive: ["abraço", "amor", "romântico", "beijo", "ternura", "paixão", "charmoso", "adorável", "doce"],
808
+ negative: ["frio", "distante", "indiferente", "rejeição", "solidão", "término", "triste"]
809
+ },
810
+ affection: {
811
+ positive: ["afeto", "ternura", "próximo", "calor", "gentil", "carinhoso", "abraço", "amor", "adorar", "amável"],
812
+ negative: [
813
+ "mau",
814
+ "má",
815
+ "frio",
816
+ "indiferente",
817
+ "distante",
818
+ "rejeição",
819
+ "ódio",
820
+ "hostil",
821
+ "idiota",
822
+ "burro",
823
+ "estúpido"
824
+ ]
825
+ },
826
+ playfulness: {
827
+ positive: ["brincar", "jogo", "provocar", "travesso", "divertido", "lúdico", "piada", "brinquedo"],
828
+ negative: ["sério", "chato", "rigoroso", "rígido", "monótono", "tedioso"]
829
+ },
830
+ empathy: {
831
+ positive: ["ouvir", "entender", "empatia", "apoio", "ajudar", "conforto", "compaixão", "cuidado", "bondade"],
832
+ negative: ["indiferente", "frio", "egoísta", "ignorar", "desprezar", "hostil", "descuidado"]
833
+ },
834
+ goodbye: ["tchau", "adeus", "até logo", "até breve", "ciao", "cuide-se", "até mais", "falou"],
835
+ kiss: ["beijo", "beijar", "abraçar", "beijinho", "selinho", "abraço"],
836
+ dancing: ["dançar", "dança", "mexer", "ritmo", "passo", "girar", "rebolar", "balançar"],
837
+ listening: [
838
+ "escute",
839
+ "escutar",
840
+ "ouvir",
841
+ "fale",
842
+ "falar",
843
+ "pergunta",
844
+ "perguntar",
845
+ "me diga",
846
+ "preste atenção",
847
+ "concentre-se"
848
+ ]
849
  }
850
  };
851
 
 
908
  de: ["nicht", "nie", "kein", "keine", "niemand", "nichts"],
909
  it: ["non", "mai", "nessuno", "niente"],
910
  ja: ["ない", "ません", "ず", "無い"],
911
+ zh: ["不", "没", "没有", "从来没有"],
912
+ "pt-br": ["não", "nunca", "jamais", "nenhum", "nenhuma", "ninguém", "nada"]
913
  };
914
 
915
  window.KIMI_NEGATION_WINDOW = window.KIMI_NEGATION_WINDOW || 3; // tokens to look back for negation
 
1043
  "una"
1044
  ],
1045
  ja: ["の", "に", "は", "を", "た", "が", "で", "て", "と", "し", "れ", "さ", "ある", "いる", "も", "する", "から"],
1046
+ zh: ["的", "一", "是", "在", "不", "了", "有", "和", "人", "这", "中", "大", "为", "上", "个", "国", "我", "以", "要"],
1047
+ "pt-br": [
1048
+ "o",
1049
+ "a",
1050
+ "de",
1051
+ "e",
1052
+ "que",
1053
+ "do",
1054
+ "da",
1055
+ "em",
1056
+ "um",
1057
+ "para",
1058
+ "é",
1059
+ "com",
1060
+ "não",
1061
+ "uma",
1062
+ "os",
1063
+ "no",
1064
+ "se",
1065
+ "na",
1066
+ "por",
1067
+ "mais"
1068
+ ]
1069
  };
1070
 
1071
  // Build Set version for fast lookup (must be outside the object)
 
1105
  de: { romantic: 1.0, laughing: 1.0 },
1106
  en: { romantic: 1.0, laughing: 1.0 },
1107
  ja: { romantic: 1.0, laughing: 1.0 },
1108
+ zh: { romantic: 1.0, laughing: 1.0 },
1109
+ "pt-br": { romantic: 1.15, laughing: 1.0 }
1110
  };
1111
 
1112
  // Personality trait adjustment multipliers
kimi-js/kimi-llm-manager.js CHANGED
@@ -231,6 +231,10 @@ class KimiLLMManager {
231
  languageInstruction =
232
  "Your default language is Chinese. Always respond in Chinese unless the user specifically asks you to respond in another language (e.g., 'respond in English', '用法语回答', etc.).";
233
  break;
 
 
 
 
234
  default:
235
  languageInstruction =
236
  "Your default language is English. Always respond in English unless the user specifically asks you to respond in another language (e.g., 'respond in French', 'reply in Spanish', etc.).";
 
231
  languageInstruction =
232
  "Your default language is Chinese. Always respond in Chinese unless the user specifically asks you to respond in another language (e.g., 'respond in English', '用法语回答', etc.).";
233
  break;
234
+ case "pt-br":
235
+ languageInstruction =
236
+ "Your default language is Brazilian Portuguese. Always respond in Brazilian Portuguese unless the user specifically asks you to respond in another language (e.g., 'respond in English', 'responda em francês', etc.).";
237
+ break;
238
  default:
239
  languageInstruction =
240
  "Your default language is English. Always respond in English unless the user specifically asks you to respond in another language (e.g., 'respond in French', 'reply in Spanish', etc.).";
kimi-js/kimi-memory-system.js CHANGED
@@ -143,7 +143,12 @@ class KimiMemorySystem {
143
  // Chinese patterns
144
  /我叫([^,。!?!?,.]+)/i,
145
  /我的名字是([^,。!?!?,.]+)/i,
146
- /叫我([^,。!?!?,.]+)/i
 
 
 
 
 
147
  ],
148
  preferences: [
149
  // English patterns
@@ -156,7 +161,11 @@ class KimiMemorySystem {
156
  /(?:mon préféré|ma préférée) (?:est|sont) ([^,.!?]+)/i,
157
  // Explicit memory requests
158
  /(?:ajoute? (?:au|à la) (?:système? )?(?:de )?mémoire|retiens?|mémorise?) (?:que )?(.+)/i,
159
- /(?:add to memory|remember|memorize) (?:that )?(.+)/i
 
 
 
 
160
  ],
161
  relationships: [
162
  // English patterns
@@ -179,7 +188,10 @@ class KimiMemorySystem {
179
  /(?:私の(?:母|父|姉|妹|兄|弟|友達))は([^。!?!?、,.]+)(?:です|といいます)/i,
180
  // Chinese patterns
181
  /(?:我的(?:妻子|丈夫|女朋友|男朋友|伴侣))叫([^,。!?!?,.]+)/i,
182
- /(?:我的(?:妈妈|父亲|姐姐|妹妹|哥哥|弟弟|朋友))叫([^,。!?!?,.]+)/i
 
 
 
183
  ],
184
  activities: [
185
  // English patterns
@@ -202,7 +214,10 @@ class KimiMemorySystem {
202
  /趣味は([^。!?!?、,.]+)です/i,
203
  // Chinese patterns
204
  /(?:我玩|我做|我练习)([^,。!?!?,.]+)/i,
205
- /(?:我的爱好是)([^,。!?!?,.]+)/i
 
 
 
206
  ],
207
  goals: [
208
  // English patterns
@@ -225,7 +240,10 @@ class KimiMemorySystem {
225
  /(?:学んでいる|勉強している) ([^。!?!?、,.]+)/i,
226
  // Chinese patterns
227
  /(?:我想|我要|我的目标是)([^,。!?!?,.]+)/i,
228
- /(?:我在学习|我学习)([^,。!?!?,.]+)/i
 
 
 
229
  ],
230
  experiences: [
231
  // English patterns
@@ -267,7 +285,12 @@ class KimiMemorySystem {
267
  /我们在([^,。!?!?,.]+)认识/i,
268
  /我们去了([^,。!?!?,.]+)/i,
269
  /我们的纪念日是([^,。!?!?,.]+)/i,
270
- /我们一起搬家(?:是在)?([^,。!?!?,.]+)/i
 
 
 
 
 
271
  ],
272
  important: [
273
  // English patterns
@@ -290,7 +313,10 @@ class KimiMemorySystem {
290
  /覚えておいてほしいのは(.+)です/i,
291
  // Chinese patterns
292
  /重要的是(.+)/i,
293
- /请记住(.+)/i
 
 
 
294
  ]
295
  };
296
 
@@ -510,6 +536,13 @@ class KimiMemorySystem {
510
  /保存到记忆(?:里|中)(?:的是)?(.+)/i
511
  ];
512
 
 
 
 
 
 
 
 
513
  const allPatterns = [
514
  ...frenchPatterns,
515
  ...englishPatterns,
@@ -517,7 +550,8 @@ class KimiMemorySystem {
517
  ...italianPatterns,
518
  ...germanPatterns,
519
  ...japanesePatterns,
520
- ...chinesePatterns
 
521
  ];
522
 
523
  for (const pattern of allPatterns) {
 
143
  // Chinese patterns
144
  /我叫([^,。!?!?,.]+)/i,
145
  /我的名字是([^,。!?!?,.]+)/i,
146
+ /叫我([^,。!?!?,.]+)/i,
147
+ // Portuguese patterns
148
+ /(?:meu nome é|me chamo|sou|me chame de) ([^,.!?]+)/i,
149
+ /(?:eu tenho|tenho) (\d+) anos?/i,
150
+ /(?:eu moro em|eu vivo em|sou de) ([^,.!?]+)/i,
151
+ /(?:eu trabalho como|meu trabalho é|sou) ([^,.!?]+)/i
152
  ],
153
  preferences: [
154
  // English patterns
 
161
  /(?:mon préféré|ma préférée) (?:est|sont) ([^,.!?]+)/i,
162
  // Explicit memory requests
163
  /(?:ajoute? (?:au|à la) (?:système? )?(?:de )?mémoire|retiens?|mémorise?) (?:que )?(.+)/i,
164
+ /(?:add to memory|remember|memorize) (?:that )?(.+)/i,
165
+ // Portuguese patterns
166
+ /(?:eu amo|eu gosto|eu adoro|eu prefiro) ([^,.!?]+)/i,
167
+ /(?:eu odeio|eu não gosto) ([^,.!?]+)/i,
168
+ /(?:meu favorito|minha favorita) (?:é|são) ([^,.!?]+)/i
169
  ],
170
  relationships: [
171
  // English patterns
 
188
  /(?:私の(?:母|父|姉|妹|兄|弟|友達))は([^。!?!?、,.]+)(?:です|といいます)/i,
189
  // Chinese patterns
190
  /(?:我的(?:妻子|丈夫|女朋友|男朋友|伴侣))叫([^,。!?!?,.]+)/i,
191
+ /(?:我的(?:妈妈|父亲|姐姐|妹妹|哥哥|弟弟|朋友))叫([^,。!?!?,.]+)/i,
192
+ // Portuguese patterns
193
+ /(?:minha (?:esposa|namorada|parceira)|meu (?:marido|namorado|parceiro)) (?:é|se chama) ([^,.!?]+)/i,
194
+ /(?:minha (?:mãe|irmã)|meu (?:pai|irmão|amigo)) (?:é|se chama) ([^,.!?]+)/i
195
  ],
196
  activities: [
197
  // English patterns
 
214
  /趣味は([^。!?!?、,.]+)です/i,
215
  // Chinese patterns
216
  /(?:我玩|我做|我练习)([^,。!?!?,.]+)/i,
217
+ /(?:我的爱好是)([^,。!?!?,.]+)/i,
218
+ // Portuguese patterns
219
+ /(?:eu jogo|eu faço|eu pratico) ([^,.!?]+)/i,
220
+ /(?:meu hobby|meu passatempo) (?:é) ([^,.!?]+)/i
221
  ],
222
  goals: [
223
  // English patterns
 
240
  /(?:学んでいる|勉強している) ([^。!?!?、,.]+)/i,
241
  // Chinese patterns
242
  /(?:我想|我要|我的目标是)([^,。!?!?,.]+)/i,
243
+ /(?:我在学习|我学习)([^,。!?!?,.]+)/i,
244
+ // Portuguese patterns
245
+ /(?:eu quero|eu vou|meu objetivo é) ([^,.!?]+)/i,
246
+ /(?:estou aprendendo|eu estudo) ([^,.!?]+)/i
247
  ],
248
  experiences: [
249
  // English patterns
 
285
  /我们在([^,。!?!?,.]+)认识/i,
286
  /我们去了([^,。!?!?,.]+)/i,
287
  /我们的纪念日是([^,。!?!?,.]+)/i,
288
+ /我们一起搬家(?:是在)?([^,。!?!?,.]+)/i,
289
+ // Portuguese patterns
290
+ /nos conhecemos (?:em|no|na) ([^,.!?]+)/i,
291
+ /(?:nós )?fomos (?:para|a|ao) ([^,.!?]+)/i,
292
+ /nosso (?:primeiro encontro|primeiro beijo|aniversário) (?:foi|é|será) ([^,.!?]+)/i,
293
+ /(?:nós )?nos mudamos (?:juntos\s*)?(?:em|no|na)\s*([^,.!?]+)/i
294
  ],
295
  important: [
296
  // English patterns
 
313
  /覚えておいてほしいのは(.+)です/i,
314
  // Chinese patterns
315
  /重要的是(.+)/i,
316
+ /请记住(.+)/i,
317
+ // Portuguese patterns
318
+ /é importante (?:lembrar|que) (.+)/i,
319
+ /por favor (?:lembre|lembra) (.+)/i
320
  ]
321
  };
322
 
 
536
  /保存到记忆(?:里|中)(?:的是)?(.+)/i
537
  ];
538
 
539
+ // Portuguese (Brazilian) explicit memory requests
540
+ const portuguesePatterns = [
541
+ /(?:adicione|adiciona|lembre|lembra|memorize|memoriza|salve|salva)\s+(?:na|em|à)\s+memória\s+(?:que\s+)?(.+)/i,
542
+ /(?:pode|poderia|você\s+pode)?\s*(?:adicionar|lembrar|memorizar|salvar)\s+(?:que\s+)?(.+)\s+(?:na|em|à)\s+memória/i,
543
+ /(?:quero\s+que\s+)?(?:lembre|memorize|adicione)\s+(?:que\s+)?(.+)/i
544
+ ];
545
+
546
  const allPatterns = [
547
  ...frenchPatterns,
548
  ...englishPatterns,
 
550
  ...italianPatterns,
551
  ...germanPatterns,
552
  ...japanesePatterns,
553
+ ...chinesePatterns,
554
+ ...portuguesePatterns
555
  ];
556
 
557
  for (const pattern of allPatterns) {
kimi-js/kimi-utils.js CHANGED
@@ -195,7 +195,11 @@ window.KimiLanguageUtils = {
195
 
196
  // Auto-detect from browser
197
  const browserLang = navigator.language?.split("-")[0] || "en";
198
- const supportedLangs = ["en", "fr", "es", "de", "it", "ja", "zh"];
 
 
 
 
199
  return supportedLangs.includes(browserLang) ? browserLang : "en";
200
  },
201
 
@@ -207,6 +211,7 @@ window.KimiLanguageUtils = {
207
  if (/[äöüß]/i.test(text)) return "de";
208
  if (/[ñáéíóúü]/i.test(text)) return "es";
209
  if (/[àèìòù]/i.test(text)) return "it";
 
210
  if (/[\u3040-\u309f\u30a0-\u30ff\u4e00-\u9faf]/i.test(text)) return "ja";
211
  if (/[\u4e00-\u9fff]/i.test(text)) return "zh";
212
  return "en";
@@ -221,7 +226,17 @@ window.KimiLanguageUtils = {
221
  norm = parts[parts.length - 1];
222
  }
223
  norm = norm.replace("_", "-");
 
 
 
 
 
 
224
  if (norm.includes("-")) norm = norm.split("-")[0];
 
 
 
 
225
  return norm;
226
  } catch (e) {
227
  return "";
 
195
 
196
  // Auto-detect from browser
197
  const browserLang = navigator.language?.split("-")[0] || "en";
198
+ // Handle Brazilian Portuguese specifically
199
+ if (navigator.language?.toLowerCase().startsWith("pt")) {
200
+ return "pt-br";
201
+ }
202
+ const supportedLangs = ["en", "fr", "es", "de", "it", "ja", "zh", "pt-br"];
203
  return supportedLangs.includes(browserLang) ? browserLang : "en";
204
  },
205
 
 
211
  if (/[äöüß]/i.test(text)) return "de";
212
  if (/[ñáéíóúü]/i.test(text)) return "es";
213
  if (/[àèìòù]/i.test(text)) return "it";
214
+ if (/[ãõâêôçáéíóú]/i.test(text)) return "pt-br";
215
  if (/[\u3040-\u309f\u30a0-\u30ff\u4e00-\u9faf]/i.test(text)) return "ja";
216
  if (/[\u4e00-\u9fff]/i.test(text)) return "zh";
217
  return "en";
 
226
  norm = parts[parts.length - 1];
227
  }
228
  norm = norm.replace("_", "-");
229
+
230
+ // Special case for Brazilian Portuguese
231
+ if (norm === "pt-br" || norm === "pt_br" || norm.startsWith("pt-br") || norm.startsWith("pt_br")) {
232
+ return "pt-br";
233
+ }
234
+
235
  if (norm.includes("-")) norm = norm.split("-")[0];
236
+
237
+ // Map 'pt' to 'pt-br' by default
238
+ if (norm === "pt") return "pt-br";
239
+
240
  return norm;
241
  } catch (e) {
242
  return "";