echogarden 1.5.0 → 1.6.1

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 (151) hide show
  1. package/data/schemas/options.json +43 -6
  2. package/dist/alignment/DTWMfccSequenceAlignment.d.ts +1 -1
  3. package/dist/alignment/DTWMfccSequenceAlignment.js +5 -5
  4. package/dist/alignment/DTWSequenceAlignmentWindowed.js +1 -3
  5. package/dist/alignment/DTWSequenceAlignmentWindowed.js.map +1 -1
  6. package/dist/alignment/SemanticTextAlignment.js +1 -1
  7. package/dist/alignment/SemanticTextAlignment.js.map +1 -1
  8. package/dist/alignment/SpeechAlignment.d.ts +2 -2
  9. package/dist/alignment/SpeechAlignment.js +26 -3
  10. package/dist/alignment/SpeechAlignment.js.map +1 -1
  11. package/dist/api/API.d.ts +0 -1
  12. package/dist/api/Synthesis.d.ts +0 -1
  13. package/dist/api/TextTranslation.d.ts +21 -1
  14. package/dist/api/TextTranslation.js +101 -2
  15. package/dist/api/TextTranslation.js.map +1 -1
  16. package/dist/api/TimelineTranslationAlignment.js +1 -1
  17. package/dist/api/TimelineTranslationAlignment.js.map +1 -1
  18. package/dist/audio/AudioBufferConversion.d.ts +0 -1
  19. package/dist/audio/AudioPlayer.d.ts +0 -1
  20. package/dist/audio/AudioPlayer.js +62 -41
  21. package/dist/audio/AudioPlayer.js.map +1 -1
  22. package/dist/audio/AudioUtilities.d.ts +0 -1
  23. package/dist/cli/CLI.d.ts +1 -0
  24. package/dist/cli/CLI.js +61 -4
  25. package/dist/cli/CLI.js.map +1 -1
  26. package/dist/codecs/FFMpegTranscoder.d.ts +0 -1
  27. package/dist/codecs/TIMITCodec.d.ts +0 -1
  28. package/dist/codecs/WaveCodec.d.ts +0 -1
  29. package/dist/math/VectorMath.d.ts +4 -4
  30. package/dist/math/VectorMath.js +6 -6
  31. package/dist/nlp/ChineseSegmentation.js +4 -4
  32. package/dist/nlp/ChineseSegmentation.js.map +1 -1
  33. package/dist/nlp/IPA.d.ts +3 -3
  34. package/dist/nlp/Segmentation.d.ts +2 -2
  35. package/dist/nlp/Segmentation.js +20 -13
  36. package/dist/nlp/Segmentation.js.map +1 -1
  37. package/dist/recognition/OpenAICloudSTT.d.ts +2 -1
  38. package/dist/recognition/OpenAICloudSTT.js +30 -19
  39. package/dist/recognition/OpenAICloudSTT.js.map +1 -1
  40. package/dist/recognition/SileroSTT.d.ts +0 -1
  41. package/dist/recognition/WhisperCppSTT.d.ts +2 -2
  42. package/dist/recognition/WhisperCppSTT.js +19 -7
  43. package/dist/recognition/WhisperCppSTT.js.map +1 -1
  44. package/dist/recognition/WhisperSTT.d.ts +9 -6
  45. package/dist/recognition/WhisperSTT.js +224 -44
  46. package/dist/recognition/WhisperSTT.js.map +1 -1
  47. package/dist/server/Client.d.ts +0 -2
  48. package/dist/server/Worker.d.ts +0 -1
  49. package/dist/source-separation/MDXNetSourceSeparation.d.ts +0 -1
  50. package/dist/speech-embeddings/WavToVec2BertFeatureEmbeddings.d.ts +0 -1
  51. package/dist/speech-language-detection/SileroLanguageDetection.d.ts +0 -1
  52. package/dist/subtitles/Subtitles.js +2 -2
  53. package/dist/subtitles/Subtitles.js.map +1 -1
  54. package/dist/synthesis/GoogleCloudTTS.d.ts +0 -1
  55. package/dist/synthesis/GoogleTranslateTTS.d.ts +0 -1
  56. package/dist/synthesis/GoogleTranslateTTS.js +6 -21
  57. package/dist/synthesis/GoogleTranslateTTS.js.map +1 -1
  58. package/dist/synthesis/StreamlabsPollyTTS.d.ts +0 -1
  59. package/dist/synthesis/VitsTTS.d.ts +0 -1
  60. package/dist/synthesis/VitsTTS.js +30 -0
  61. package/dist/synthesis/VitsTTS.js.map +1 -1
  62. package/dist/text-translation/DeepLTextTranslation.d.ts +2 -0
  63. package/dist/text-translation/DeepLTextTranslation.js +67 -0
  64. package/dist/text-translation/DeepLTextTranslation.js.map +1 -0
  65. package/dist/text-translation/GoogleTranslateTextTranslation.d.ts +13 -0
  66. package/dist/text-translation/GoogleTranslateTextTranslation.js +556 -0
  67. package/dist/text-translation/GoogleTranslateTextTranslation.js.map +1 -0
  68. package/dist/text-translation/NLLBTextTranslation.d.ts +2 -1
  69. package/dist/text-translation/NLLBTextTranslation.js +248 -18
  70. package/dist/text-translation/NLLBTextTranslation.js.map +1 -1
  71. package/dist/utilities/BinaryArrayConversion.d.ts +0 -1
  72. package/dist/utilities/BrowserRequestHeaders.d.ts +6 -0
  73. package/dist/utilities/BrowserRequestHeaders.js +52 -0
  74. package/dist/utilities/BrowserRequestHeaders.js.map +1 -0
  75. package/dist/utilities/BufferFileReadStream.d.ts +20 -0
  76. package/dist/utilities/BufferFileReadStream.js +81 -0
  77. package/dist/utilities/BufferFileReadStream.js.map +1 -0
  78. package/dist/utilities/DynamicUint8Array.d.ts +9 -0
  79. package/dist/utilities/DynamicUint8Array.js +31 -0
  80. package/dist/utilities/DynamicUint8Array.js.map +1 -0
  81. package/dist/utilities/FileSystem.d.ts +0 -2
  82. package/dist/utilities/Hashing.d.ts +3 -10
  83. package/dist/utilities/Hashing.js +10 -127
  84. package/dist/utilities/Hashing.js.map +1 -1
  85. package/dist/utilities/LEB128.d.ts +15 -5
  86. package/dist/utilities/LEB128.js +199 -119
  87. package/dist/utilities/LEB128.js.map +1 -1
  88. package/dist/utilities/LPVarInt.d.ts +11 -0
  89. package/dist/utilities/LPVarInt.js +187 -0
  90. package/dist/utilities/LPVarInt.js.map +1 -0
  91. package/dist/utilities/OnnxUtilities.d.ts +0 -1
  92. package/dist/utilities/PVarInt.d.ts +4 -0
  93. package/dist/utilities/PVarInt.js +166 -0
  94. package/dist/utilities/PVarInt.js.map +1 -0
  95. package/dist/utilities/PackageManager.js +43 -22
  96. package/dist/utilities/PackageManager.js.map +1 -1
  97. package/dist/utilities/RandomGenerator.d.ts +3 -17
  98. package/dist/utilities/RandomGenerator.js +12 -81
  99. package/dist/utilities/RandomGenerator.js.map +1 -1
  100. package/dist/utilities/Timeline.d.ts +1 -0
  101. package/dist/utilities/Timeline.js +117 -20
  102. package/dist/utilities/Timeline.js.map +1 -1
  103. package/dist/utilities/Utilities.d.ts +1 -3
  104. package/dist/utilities/Utilities.js +30 -3
  105. package/dist/utilities/Utilities.js.map +1 -1
  106. package/dist/utilities/VarInt.d.ts +4 -0
  107. package/dist/utilities/VarInt.js +166 -0
  108. package/dist/utilities/VarInt.js.map +1 -0
  109. package/dist/utilities/VirtualFileReadStream.d.ts +20 -0
  110. package/dist/utilities/VirtualFileReadStream.js +79 -0
  111. package/dist/utilities/VirtualFileReadStream.js.map +1 -0
  112. package/dist/utilities/WebReader.js +7 -23
  113. package/dist/utilities/WebReader.js.map +1 -1
  114. package/dist/voice-activity-detection/SileroVAD.d.ts +0 -1
  115. package/docs/API.md +24 -0
  116. package/docs/Engines.md +8 -3
  117. package/docs/Options.md +21 -12
  118. package/docs/Tasklist.md +1 -13
  119. package/package.json +20 -24
  120. package/src/alignment/DTWMfccSequenceAlignment.ts +5 -5
  121. package/src/alignment/DTWSequenceAlignmentWindowed.ts +1 -3
  122. package/src/alignment/SemanticTextAlignment.ts +1 -1
  123. package/src/alignment/SpeechAlignment.ts +37 -6
  124. package/src/api/TextTranslation.ts +173 -2
  125. package/src/api/TimelineTranslationAlignment.ts +1 -1
  126. package/src/audio/AudioPlayer.ts +2 -0
  127. package/src/cli/CLI.ts +101 -7
  128. package/src/math/VectorMath.ts +6 -6
  129. package/src/nlp/ChineseSegmentation.ts +6 -4
  130. package/src/nlp/Segmentation.ts +18 -13
  131. package/src/recognition/OpenAICloudSTT.ts +47 -29
  132. package/src/recognition/WhisperCppSTT.ts +24 -9
  133. package/src/recognition/WhisperSTT.ts +364 -49
  134. package/src/subtitles/Subtitles.ts +2 -2
  135. package/src/synthesis/GoogleTranslateTTS.ts +7 -21
  136. package/src/synthesis/VitsTTS.ts +31 -3
  137. package/src/text-translation/DeepLTextTranslation.ts +88 -0
  138. package/src/text-translation/GoogleTranslateTextTranslation.ts +670 -0
  139. package/src/text-translation/NLLBTextTranslation.ts +260 -20
  140. package/src/typings/Fillers.d.ts +25 -2
  141. package/src/utilities/BrowserRequestHeaders.ts +59 -0
  142. package/src/utilities/DynamicUint8Array.ts +39 -0
  143. package/src/utilities/Hashing.ts +14 -167
  144. package/src/utilities/LEB128.ts +273 -148
  145. package/src/utilities/LPVarInt.ts +292 -0
  146. package/src/utilities/PackageManager.ts +45 -27
  147. package/src/utilities/RandomGenerator.ts +12 -113
  148. package/src/utilities/Timeline.ts +148 -23
  149. package/src/utilities/Utilities.ts +40 -3
  150. package/src/utilities/VirtualFileReadStream.ts +109 -0
  151. package/src/utilities/WebReader.ts +9 -23
@@ -0,0 +1,670 @@
1
+ import { request } from "gaxios"
2
+ import { Logger } from "../utilities/Logger.js"
3
+ import { Fragment, splitToFragments, splitToLines, splitToParagraphs, splitToSentences } from "../nlp/Segmentation.js"
4
+ import { TranslationPair } from "../api/TextTranslation.js"
5
+ import { getChromeOnWindowsHeaders, getChromeOnAndroidHeaders } from "../utilities/BrowserRequestHeaders.js"
6
+ import { logToStderr, splitAndPreserveSeparators } from "../utilities/Utilities.js"
7
+ import { getShortLanguageCode } from "../utilities/Locale.js"
8
+
9
+ const log = logToStderr
10
+
11
+ export async function translateText(text: string, sourceLanguage: string, targetLanguage: string, tld = 'com') {
12
+ const logger = new Logger()
13
+
14
+ const maxTextLengthPerRequest = 2000
15
+
16
+ //const paragraphs = splitAndPreserveSeparators(text, /(\r?\n)(\r?\n)/g)
17
+ const paragraphs = splitToParagraphs(text, 'double', 'preserve')
18
+
19
+ const fragmentsForParagraph: Fragment[][] = []
20
+
21
+ for (const paragraph of paragraphs) {
22
+ const fragments = await splitToFragments(paragraph, maxTextLengthPerRequest, getShortLanguageCode(sourceLanguage))
23
+
24
+ fragmentsForParagraph.push(fragments)
25
+ }
26
+
27
+ const fragmentBundles: Fragment[][] = [[]]
28
+
29
+ function totalLengthOfLastBundle() {
30
+ let total = 0
31
+
32
+ for (const fragment of fragmentBundles[fragmentBundles.length - 1]) {
33
+ total += fragment.length
34
+ }
35
+
36
+ return total
37
+ }
38
+
39
+ const fragmentToParagraphIndex = new Map<Fragment, number>()
40
+
41
+ for (let paragraphIndex = 0; paragraphIndex < paragraphs.length; paragraphIndex++) {
42
+ const fragments = fragmentsForParagraph[paragraphIndex]
43
+
44
+ for (const fragment of fragments) {
45
+ let lastBundle = fragmentBundles[fragmentBundles.length - 1]
46
+
47
+ if (totalLengthOfLastBundle() + fragment.length > maxTextLengthPerRequest) {
48
+ lastBundle = []
49
+ fragmentBundles.push(lastBundle)
50
+ }
51
+
52
+ lastBundle.push(fragment)
53
+
54
+ fragmentToParagraphIndex.set(fragment, paragraphIndex)
55
+ }
56
+ }
57
+
58
+ const translatedFragmentsForParagraphs = paragraphs.map(_ => [] as string[])
59
+
60
+ for (let fragmentBundleIndex = 0; fragmentBundleIndex < fragmentBundles.length; fragmentBundleIndex++) {
61
+ const bundle = fragmentBundles[fragmentBundleIndex]
62
+
63
+ const joinedBundle = bundle.map(x => x.text.replaceAll('|', ' ')).join(` | `)
64
+
65
+ logger.logTitledMessage(`\nTranslate part ${fragmentBundleIndex + 1} of ${fragmentBundles.length}`, joinedBundle)
66
+
67
+ logger.start(`Request translation from Google Translate`)
68
+ const fragmentTranslationPair = await translateText_MobileWeb(joinedBundle, sourceLanguage, targetLanguage)
69
+ logger.end()
70
+
71
+ const translatedTextForBundle = fragmentTranslationPair[0].translatedText
72
+
73
+ logger.logTitledMessage(`Translated part`, `"${translatedTextForBundle}"`)
74
+
75
+ const splitTranslation = translatedTextForBundle.split(`|`)
76
+
77
+ for (let fragmentIndex = 0; fragmentIndex < bundle.length; fragmentIndex++) {
78
+ const fragment = bundle[fragmentIndex]
79
+ const translatedFragment = splitTranslation[fragmentIndex].trim()
80
+
81
+ const paragraphIndex = fragmentToParagraphIndex.get(fragment)!
82
+
83
+ translatedFragmentsForParagraphs[paragraphIndex].push(translatedFragment)
84
+ }
85
+ }
86
+
87
+ const translationPairs: TranslationPair[] = []
88
+
89
+ for (let paragraphIndex = 0; paragraphIndex < paragraphs.length; paragraphIndex++) {
90
+ translationPairs.push({
91
+ sourceText: paragraphs[paragraphIndex],
92
+ translatedText: translatedFragmentsForParagraphs[paragraphIndex].join(' ')
93
+ })
94
+ }
95
+
96
+ const translatedText = translationPairs.map(pair => pair.translatedText).join('\n\n')
97
+
98
+ return { translationPairs, translatedText }
99
+ }
100
+
101
+ export async function translateText_MobileWeb(text: string, sourceLanguage: string, targetLanguage: string, tld = 'com') {
102
+ const logger = new Logger()
103
+
104
+ logger.start(`Request translation from Google Translate`)
105
+
106
+ const response = await request<string>({
107
+ method: 'GET',
108
+
109
+ url: `https://translate.google.${tld}/m`,
110
+
111
+ //proxy: 'http://localhost:8080',
112
+
113
+ params: {
114
+ 'sl': sourceLanguage,
115
+ 'tl': targetLanguage,
116
+ 'q': text,
117
+ },
118
+
119
+ headers: {
120
+ ...getChromeOnAndroidHeaders({
121
+ origin: `https://translate.google.${tld}`,
122
+ referrer: `https://translate.google.${tld}/m`
123
+ }),
124
+ },
125
+
126
+ responseType: 'text',
127
+ })
128
+
129
+ logger.start('Parse response')
130
+
131
+ const html = response.data
132
+
133
+ let translatedText: string
134
+
135
+ const useJsdom = false
136
+
137
+ if (useJsdom) {
138
+ const { JSDOM } = await import('jsdom')
139
+
140
+ const doc = new JSDOM(html, {})
141
+
142
+ const resultElement = doc.window.document.querySelector('.result-container')
143
+
144
+ translatedText = resultElement?.textContent || ''
145
+ } else {
146
+ const regex = /<div\s+class="result-container".*?<\/div>/is
147
+ const match = html.match(regex)
148
+
149
+ if (match) {
150
+ const { htmlToText } = await import('html-to-text')
151
+
152
+ translatedText = htmlToText(match[0], { wordwrap: Infinity }).trim()
153
+ } else {
154
+ translatedText = ''
155
+ }
156
+ }
157
+
158
+ logger.end()
159
+
160
+ return [{
161
+ sourceText: text,
162
+ translatedText: translatedText
163
+ }]
164
+ }
165
+
166
+ export async function translateText_WebAPI(text: string, sourceLanguage: string, targetLanguage: string, tld = 'com') {
167
+ const logger = new Logger()
168
+
169
+ logger.start(`Prepare request`)
170
+
171
+ const bodyFormParameters = [[text, sourceLanguage, targetLanguage, 1], []]
172
+
173
+ const requestForm = [[['MkEWBc', JSON.stringify(bodyFormParameters), null, 'generic']]]
174
+ const stringifiedForm = JSON.stringify(requestForm)
175
+ const requestBody =
176
+ `f.req=${encodeURIComponent(stringifiedForm)}&`// +
177
+
178
+ // Example:
179
+ //
180
+ // f.req: [[["MkEWBc","[[\"Hey there!\\n\\nHow are you doing today?\",\"en\",\"es\",1],[]]",null,"generic"]]]
181
+ // at: AFS6Qyg7vBwAdNvYB3ncQi_YvmYH:1717146157247
182
+
183
+ logger.start(`Request translation from Google Translate`)
184
+
185
+ const response = await request<string>({
186
+ method: 'POST',
187
+
188
+ url: `https://translate.google.${tld}/_/TranslateWebserverUi/data/batchexecute`,
189
+
190
+ params: {
191
+ 'rpcids': 'MkEWBc',
192
+ /*'source-path': '/',
193
+ 'f.sid': '4165351081036910547',
194
+ 'bl': 'boq_translate-webserver_20240528.08_p1',
195
+ 'hl': 'en-US',
196
+ 'soc-app': '1',
197
+ 'soc-platform': '1',
198
+ 'soc-device': '1',
199
+ '_reqid': '435214',
200
+ */
201
+ 'rt': 'c',
202
+ },
203
+
204
+ headers: {
205
+ ...getChromeOnWindowsHeaders({
206
+ origin: `https://translate.google.${tld}`,
207
+ referrer: `https://translate.google.${tld}/`
208
+ }),
209
+
210
+ 'Content-Type': 'application/x-www-form-urlencoded',
211
+ },
212
+
213
+ body: requestBody,
214
+
215
+ //proxy: 'http://localhost:8080',
216
+
217
+ responseType: 'text'
218
+ })
219
+
220
+ logger.start('Parse response')
221
+
222
+ const responseLines = splitToLines(response.data).filter(line => line.trim().length > 0)
223
+
224
+ const dataLine = responseLines[2]
225
+
226
+ const outerArray = JSON.parse(dataLine)
227
+ const innerArray = JSON.parse(outerArray[0][2])
228
+ const sentenceEntries: any[] = innerArray[1][0][0][5]
229
+
230
+ const translationsPairs = sentenceEntries.map<TranslationPair>((element: any) => {
231
+ const translationPair: TranslationPair = {
232
+ sourceText: element[6],
233
+ translatedText: element[0],
234
+ }
235
+
236
+ return translationPair
237
+ })
238
+
239
+ logger.end()
240
+
241
+ return translationsPairs
242
+ }
243
+
244
+ export async function translateText_OldWebAPI(text: string, sourceLanguage: string, targetLanguage: string, tld = 'com') {
245
+ const logger = new Logger()
246
+
247
+ logger.start(`Prepare request`)
248
+
249
+ const token = getToken(text)
250
+
251
+ logger.start(`Request translation from Google Translate`)
252
+
253
+ const response = await request<string>({
254
+ method: 'GET',
255
+
256
+ url: `https://translate.google.${tld}/translate_a/single`,
257
+
258
+ params: {
259
+ client: 't',
260
+ sl: normalizeLanguageCodeForGoogleTranslate(sourceLanguage),
261
+ tl: normalizeLanguageCodeForGoogleTranslate(targetLanguage),
262
+ hl: normalizeLanguageCodeForGoogleTranslate(targetLanguage),
263
+ dt: ['at', 'bd', 'ex', 'ld', 'md', 'qca', 'rw', 'rm', 'ss', 't'],
264
+ ie: 'UTF-8',
265
+ oe: 'UTF-8',
266
+ otf: 1,
267
+ ssel: 0,
268
+ tsel: 0,
269
+ kc: 7,
270
+ q: text,
271
+ tk: token,
272
+ },
273
+
274
+ headers: getChromeOnWindowsHeaders({
275
+ origin: `https://translate.google.${tld}`,
276
+ referrer: `https://translate.google.${tld}/`
277
+ }),
278
+
279
+ responseType: 'json'
280
+ })
281
+
282
+ const translationsPairs: TranslationPair[] = []
283
+
284
+ for (const element of response.data[0] as any as any[]) {
285
+ if (element == null || element[0] == null || element[1] == null) {
286
+ continue
287
+ }
288
+
289
+ translationsPairs.push({
290
+ sourceText: element[1],
291
+ translatedText: element[0],
292
+ })
293
+ }
294
+
295
+ logger.end()
296
+
297
+ return translationsPairs
298
+ }
299
+
300
+ function getToken(query: any) {
301
+ function shiftLeftOrRightThenSumOrXor(num: number, optString: any) {
302
+ for (let i = 0; i < optString.length - 2; i += 3) {
303
+ let acc = optString.charAt(i + 2)
304
+
305
+ if ('a' <= acc) {
306
+ acc = acc.charCodeAt(0) - 87
307
+ } else {
308
+ acc = Number(acc)
309
+ }
310
+
311
+ if (optString.charAt(i + 1) == '+') {
312
+ acc = num >>> acc
313
+ } else {
314
+ acc = num << acc
315
+ }
316
+
317
+ if (optString.charAt(i) == '+') {
318
+ num += acc & 4294967295
319
+ } else {
320
+ num ^= acc
321
+ }
322
+ }
323
+
324
+ return num
325
+ }
326
+
327
+ function transformQuery(query: any) {
328
+ const bytesArray: number[] = []
329
+
330
+ let idx: number = 0
331
+
332
+ for (let i = 0; i < query.length; i++) {
333
+ let charCode = query.charCodeAt(i)
334
+
335
+ if (128 > charCode) {
336
+ bytesArray[idx++] = charCode
337
+ } else {
338
+ if (2048 > charCode) {
339
+ bytesArray[idx++] = (charCode >> 6) | 192
340
+ } else {
341
+ if (
342
+ 55296 == (charCode & 64512) &&
343
+ i + 1 < query.length &&
344
+ 56320 == (query.charCodeAt(i + 1) & 64512)
345
+ ) {
346
+ charCode =
347
+ 65536 +
348
+ ((charCode & 1023) << 10) +
349
+ (query.charCodeAt(++i) & 1023)
350
+
351
+ bytesArray[idx++] = (charCode >> 18) | 240
352
+ bytesArray[idx++] = ((charCode >> 12) & 63) | 128
353
+ } else {
354
+ bytesArray[idx++] = (charCode >> 12) | 224
355
+ }
356
+
357
+ bytesArray[idx++] = ((charCode >> 6) & 63) | 128
358
+ }
359
+
360
+ bytesArray[idx++] = (charCode & 63) | 128
361
+ }
362
+ }
363
+
364
+ return bytesArray
365
+ }
366
+
367
+ function calcHash(query: any, windowTkk: any) {
368
+ const tkkSplited = windowTkk.split('.')
369
+ const tkkIndex = Number(tkkSplited[0]) || 0
370
+ const tkkKey = Number(tkkSplited[1]) || 0
371
+
372
+ const bytesArray = transformQuery(query)
373
+
374
+ let encondingRound = tkkIndex
375
+
376
+ for (let i = 0; i < bytesArray.length; i++) {
377
+ encondingRound += bytesArray[i]
378
+
379
+ encondingRound = shiftLeftOrRightThenSumOrXor(encondingRound, '+-a^+6')
380
+ }
381
+
382
+ encondingRound = shiftLeftOrRightThenSumOrXor(encondingRound, '+-3^+b+-f')
383
+
384
+ encondingRound ^= tkkKey
385
+
386
+ if (encondingRound <= 0) {
387
+ encondingRound = (encondingRound & 2147483647) + 2147483648
388
+ }
389
+
390
+ const normalizedResult = encondingRound % 1000000
391
+
392
+ return normalizedResult.toString() + '.' + (normalizedResult ^ tkkIndex)
393
+ }
394
+
395
+ // TKK value from https://github.com/FilipePS/Traduzir-paginas-web/blob/f3a4956a1aa96b7a9124864158a5200827694521/background/translationService.js
396
+ const googleTranslateTKK = '448487.932609646'
397
+
398
+ return calcHash(query, googleTranslateTKK)
399
+ }
400
+
401
+ function normalizeLanguageCodeForGoogleTranslate(languageCode: string) {
402
+ switch (languageCode) {
403
+ case 'zh': {
404
+ return 'zh-CN'
405
+ }
406
+
407
+ case 'he': {
408
+ return 'iw'
409
+ }
410
+
411
+ case 'jv': {
412
+ return 'jw'
413
+ }
414
+
415
+ default: {
416
+ return languageCode
417
+ }
418
+ }
419
+ }
420
+
421
+ export function supportsLanguage(langCode: string) {
422
+ return supportedLanguages.includes(normalizeLanguageCodeForGoogleTranslate(langCode))
423
+ }
424
+
425
+ // 243 Languages supported
426
+ export const supportedLanguages = [
427
+ 'ab', // Abkhaz
428
+ 'ace', // Acehnese
429
+ 'ach', // Acholi
430
+ 'aa', // Afar
431
+ 'af', // Afrikaans
432
+ 'sq', // Albanian
433
+ 'alz', // Alur
434
+ 'am', // Amharic
435
+ 'ar', // Arabic
436
+ 'hy', // Armenian
437
+ 'as', // Assamese
438
+ 'av', // Avar
439
+ 'awa', // Awadhi
440
+ 'ay', // Aymara
441
+ 'az', // Azerbaijani
442
+ 'ban', // Balinese
443
+ 'bal', // Baluchi
444
+ 'bm', // Bambara
445
+ 'bci', // Baoulé
446
+ 'ba', // Bashkir
447
+ 'eu', // Basque
448
+ 'btx', // Batak Karo
449
+ 'bts', // Batak Simalungun
450
+ 'bbc', // Batak Toba
451
+ 'be', // Belarusian
452
+ 'bem', // Bemba
453
+ 'bn', // Bengali
454
+ 'bew', // Betawi
455
+ 'bho', // Bhojpuri
456
+ 'bik', // Bikol
457
+ 'bs', // Bosnian
458
+ 'br', // Breton
459
+ 'bg', // Bulgarian
460
+ 'bua', // Buryat
461
+ 'yue', // Cantonese
462
+ 'ca', // Catalan
463
+ 'ceb', // Cebuano
464
+ 'ch', // Chamorro
465
+ 'ce', // Chechen
466
+ 'ny', // Chichewa
467
+ 'zh-CN', // Chinese (Simplified)
468
+ 'zh-TW', // Chinese (Traditional)
469
+ 'chk', // Chuukese
470
+ 'cv', // Chuvash
471
+ 'co', // Corsican
472
+ 'crh', // Crimean Tatar
473
+ 'hr', // Croatian
474
+ 'cs', // Czech
475
+ 'da', // Danish
476
+ 'fa-AF', // Dari
477
+ 'dv', // Dhivehi
478
+ 'din', // Dinka
479
+ 'doi', // Dogri
480
+ 'dov', // Dombe
481
+ 'nl', // Dutch
482
+ 'dyu', // Dyula
483
+ 'dz', // Dzongkha
484
+ 'en', // English
485
+ 'eo', // Esperanto
486
+ 'et', // Estonian
487
+ 'ee', // Ewe
488
+ 'fo', // Faroese
489
+ 'fj', // Fijian
490
+ 'tl', // Filipino
491
+ 'fi', // Finnish
492
+ 'fon', // Fon
493
+ 'fr', // French
494
+ 'fy', // Frisian
495
+ 'fur', // Friulian
496
+ 'ff', // Fulani
497
+ 'gaa', // Ga
498
+ 'gl', // Galician
499
+ 'ka', // Georgian
500
+ 'de', // German
501
+ 'el', // Greek
502
+ 'gn', // Guarani
503
+ 'gu', // Gujarati
504
+ 'ht', // Haitian Creole
505
+ 'cnh', // Hakha Chin
506
+ 'ha', // Hausa
507
+ 'haw', // Hawaiian
508
+ 'iw', // Hebrew
509
+ 'hil', // Hiligaynon
510
+ 'hi', // Hindi
511
+ 'hmn', // Hmong
512
+ 'hu', // Hungarian
513
+ 'hrx', // Hunsrik
514
+ 'iba', // Iban
515
+ 'is', // Icelandic
516
+ 'ig', // Igbo
517
+ 'ilo', // Ilocano
518
+ 'id', // Indonesian
519
+ 'ga', // Irish
520
+ 'it', // Italian
521
+ 'jam', // Jamaican Patois
522
+ 'ja', // Japanese
523
+ 'jw', // Javanese
524
+ 'kac', // Jingpo
525
+ 'kl', // Kalaallisut
526
+ 'kn', // Kannada
527
+ 'kr', // Kanuri
528
+ 'pam', // Kapampangan
529
+ 'kk', // Kazakh
530
+ 'kha', // Khasi
531
+ 'km', // Khmer
532
+ 'cgg', // Kiga
533
+ 'kg', // Kikongo
534
+ 'rw', // Kinyarwanda
535
+ 'ktu', // Kituba
536
+ 'trp', // Kokborok
537
+ 'kv', // Komi
538
+ 'gom', // Konkani
539
+ 'ko', // Korean
540
+ 'kri', // Krio
541
+ 'ku', // Kurdish (Kurmanji)
542
+ 'ckb', // Kurdish (Sorani)
543
+ 'ky', // Kyrgyz
544
+ 'lo', // Lao
545
+ 'ltg', // Latgalian
546
+ 'la', // Latin
547
+ 'lv', // Latvian
548
+ 'lij', // Ligurian
549
+ 'li', // Limburgish
550
+ 'ln', // Lingala
551
+ 'lt', // Lithuanian
552
+ 'lmo', // Lombard
553
+ 'lg', // Luganda
554
+ 'luo', // Luo
555
+ 'lb', // Luxembourgish
556
+ 'mk', // Macedonian
557
+ 'mad', // Madurese
558
+ 'mai', // Maithili
559
+ 'mak', // Makassar
560
+ 'mg', // Malagasy
561
+ 'ms', // Malay
562
+ 'ms-Arab', // Malay (Jawi)
563
+ 'ml', // Malayalam
564
+ 'mt', // Maltese
565
+ 'mam', // Mam
566
+ 'gv', // Manx
567
+ 'mi', // Maori
568
+ 'mr', // Marathi
569
+ 'mh', // Marshallese
570
+ 'mwr', // Marwadi
571
+ 'mfe', // Mauritian Creole
572
+ 'chm', // Meadow Mari
573
+ 'mni-Mtei', // Meiteilon (Manipuri)
574
+ 'min', // Minang
575
+ 'lus', // Mizo
576
+ 'mn', // Mongolian
577
+ 'my', // Myanmar (Burmese)
578
+ 'nhe', // Nahuatl (Eastern Huasteca)
579
+ 'ndc-ZW', // Ndau
580
+ 'nr', // Ndebele (South)
581
+ 'new', // Nepalbhasa (Newari)
582
+ 'ne', // Nepali
583
+ 'bm-Nkoo', // NKo
584
+ 'no', // Norwegian
585
+ 'nus', // Nuer
586
+ 'oc', // Occitan
587
+ 'or', // Odia (Oriya)
588
+ 'om', // Oromo
589
+ 'os', // Ossetian
590
+ 'pag', // Pangasinan
591
+ 'pap', // Papiamento
592
+ 'ps', // Pashto
593
+ 'fa', // Persian
594
+ 'pl', // Polish
595
+ 'pt', // Portuguese (Brazil)
596
+ 'pt-PT', // Portuguese (Portugal)
597
+ 'pa', // Punjabi (Gurmukhi)
598
+ 'pa-Arab', // Punjabi (Shahmukhi)
599
+ 'qu', // Quechua
600
+ 'kek', // Qʼeqchiʼ
601
+ 'rom', // Romani
602
+ 'ro', // Romanian
603
+ 'rn', // Rundi
604
+ 'ru', // Russian
605
+ 'se', // Sami (North)
606
+ 'sm', // Samoan
607
+ 'sg', // Sango
608
+ 'sa', // Sanskrit
609
+ 'sat-Latn', // Santali
610
+ 'gd', // Scots Gaelic
611
+ 'nso', // Sepedi
612
+ 'sr', // Serbian
613
+ 'st', // Sesotho
614
+ 'crs', // Seychellois Creole
615
+ 'shn', // Shan
616
+ 'sn', // Shona
617
+ 'scn', // Sicilian
618
+ 'szl', // Silesian
619
+ 'sd', // Sindhi
620
+ 'si', // Sinhala
621
+ 'sk', // Slovak
622
+ 'sl', // Slovenian
623
+ 'so', // Somali
624
+ 'es', // Spanish
625
+ 'su', // Sundanese
626
+ 'sus', // Susu
627
+ 'sw', // Swahili
628
+ 'ss', // Swati
629
+ 'sv', // Swedish
630
+ 'ty', // Tahitian
631
+ 'tg', // Tajik
632
+ 'ber-Latn', // Tamazight
633
+ 'ber', // Tamazight (Tifinagh)
634
+ 'ta', // Tamil
635
+ 'tt', // Tatar
636
+ 'te', // Telugu
637
+ 'tet', // Tetum
638
+ 'th', // Thai
639
+ 'bo', // Tibetan
640
+ 'ti', // Tigrinya
641
+ 'tiv', // Tiv
642
+ 'tpi', // Tok Pisin
643
+ 'to', // Tongan
644
+ 'ts', // Tsonga
645
+ 'tn', // Tswana
646
+ 'tcy', // Tulu
647
+ 'tum', // Tumbuka
648
+ 'tr', // Turkish
649
+ 'tk', // Turkmen
650
+ 'tyv', // Tuvan
651
+ 'ak', // Twi
652
+ 'udm', // Udmurt
653
+ 'uk', // Ukrainian
654
+ 'ur', // Urdu
655
+ 'ug', // Uyghur
656
+ 'uz', // Uzbek
657
+ 've', // Venda
658
+ 'vec', // Venetian
659
+ 'vi', // Vietnamese
660
+ 'war', // Waray
661
+ 'cy', // Welsh
662
+ 'wo', // Wolof
663
+ 'xh', // Xhosa
664
+ 'sah', // Yakut
665
+ 'yi', // Yiddish
666
+ 'yo', // Yoruba
667
+ 'yua', // Yucatec Maya
668
+ 'zap', // Zapotec
669
+ 'zu', // Zulu
670
+ ]