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