diff options
Diffstat (limited to 'node_modules/translatte')
-rwxr-xr-x | node_modules/translatte/LICENSE.txt | 21 | ||||
-rwxr-xr-x | node_modules/translatte/README.md | 200 | ||||
-rwxr-xr-x | node_modules/translatte/index.js | 406 | ||||
-rwxr-xr-x | node_modules/translatte/languages.js | 187 | ||||
-rwxr-xr-x | node_modules/translatte/logo.png | bin | 0 -> 23775 bytes | |||
-rwxr-xr-x | node_modules/translatte/package.json | 47 | ||||
-rwxr-xr-x | node_modules/translatte/token.js | 120 | ||||
-rwxr-xr-x | node_modules/translatte/translatte_lg.png | bin | 0 -> 449434 bytes | |||
-rwxr-xr-x | node_modules/translatte/translatte_md.png | bin | 0 -> 141215 bytes |
9 files changed, 981 insertions, 0 deletions
diff --git a/node_modules/translatte/LICENSE.txt b/node_modules/translatte/LICENSE.txt new file mode 100755 index 0000000..1f6d321 --- /dev/null +++ b/node_modules/translatte/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2019, ExtensionsApp <extensionsapp@gmail.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.
\ No newline at end of file diff --git a/node_modules/translatte/README.md b/node_modules/translatte/README.md new file mode 100755 index 0000000..03e4290 --- /dev/null +++ b/node_modules/translatte/README.md @@ -0,0 +1,200 @@ +# A free and unlimited translate for NodeJS. + +<p align="center"><img src="https://raw.githubusercontent.com/extensionsapp/translatte/master/translatte_md.png" alt="TRANSLATTE, npm package translate for NodeJS" title="TRANSLATTE, npm package translate for NodeJS"></p> + +### Installation +``` +npm i translatte +``` + +### Usage + +Translate string to German: + +```javascript +const translatte = require('translatte'); + +translatte('Do you speak Russian?', {to: 'de'}).then(res => { + console.log(res.text); +}).catch(err => { + console.error(err); +}); +// Ihr sprecht auf Russisch? +``` + +Translate string to English using proxy: + +```javascript +const translatte = require('translatte'); + +translatte('Вы говорите по-русски?', { + from: 'ru', + to: 'en', + agents: [ + 'Mozilla/5.0 (Windows NT 10.0; ...', + 'Mozilla/4.0 (Windows NT 10.0; ...', + 'Mozilla/5.0 (Windows NT 10.0; ...' + ], + proxies: [ + 'LOGIN:PASSWORD@192.0.2.100:12345', + 'LOGIN:PASSWORD@192.0.2.200:54321' + ] +}).then(res => { + console.log(res); +}).catch(err => { + console.error(err); +}); +// { text: 'Do you speak Russian?', +// from: { +// language: { +// didYouMean: false, +// iso: 'ru' +// }, +// text: { +// autoCorrected: false, +// value: '', +// didYouMean: false +// } +// }, +// raw: '' } +``` + +## API + +### translatte(text, options) + +#### text + +Type: `string` + +The text to be translated. + +#### options + +Type: `object` + +##### from + +Type: `string` Default: `auto` + +The `text` language. Must be `auto` or one of the codes/names (not case sensitive) contained in [languages.js](https://github.com/extensionsapp/translatte/blob/master/languages.js). + +##### to + +Type: `string` Default: `en` + +The language in which the text should be translated. Must be one of the codes/names (not case sensitive) contained in [languages.js](https://github.com/extensionsapp/translatte/blob/master/languages.js). + +##### raw + +Type: `boolean` Default: `false` + +If `true`, the returned object will have a `raw` property with the raw response (`string`) from Google Translate. + +##### agents + +Type: `array` Default: `[]` + +An `array` of strings specifying the user-agent `['Mozilla/5.0 ...', 'Mozilla/4.0 ...']`. One random result will be selected. + +##### proxies + +Type: `array` Default: `[]` + +An `array` of strings `LOGIN:PASSWORD@IP:PORT` specifying the proxies `['LOGIN:PASSWORD@192.0.2.100:12345', 'LOGIN:PASSWORD@192.0.2.200:54321']`. One random result will be selected. + +##### tld + +Type: `string` Default: `com` + +TLD for Google translate host to be used in API calls: `https://translate.google.[tld]` + +##### client + +Type: `string` Default: `t` + +Query parameter client used in API calls. Can be `t|gtx`. + +#### priority + +Type: `array` Default: `['google_free']` + +Array of priority services. + +#### services + +Type: `object` Default: `{"google_free": true}` + +Objects in order of priority, if one of the services does not perform the translation, it proceeds to the next. + +**Supported services:** +- `{"google_free": true}` + - <a href="https://translate.google.com/" target="_blank">Google Translate</a>, this service works by default. It is completely free and has no limits. +- `{"google_v3": {"project-id": "XXX", "token": "YYY"}}` + - <a href="https://cloud.google.com/translate/docs/quickstart-client-libraries-v3" target="_blank">Google Cloud</a>, requires registration and credit card details. 500,000 characters per month are issued free of charge, then $20 for every million characters. +- `{"microsoft_v3": {"key": "XXX", "location": "global"}}` + - <a href="https://azure.microsoft.com/en-us/pricing/details/cognitive-services/translator-text-api/" target="_blank">Microsoft Azure</a>, requires registration and credit card details. Free of charge 2,000,000 characters per month, then $10 for every million characters. +- `{"yandex_v1": {"key": "XXX"}}` + - <a href="https://translate.yandex.ru/developers/keys" target="_blank">Yandex Translate</a>, requires registration. Free of charge 10,000,000 characters per month. +- `{"yandex_v2": {"key": "XXX"}}` + - <a href="https://cloud.yandex.ru/docs/translate/" target="_blank">Yandex Cloud</a>, requires registration and credit card details. $15 for every million characters. + +### Returns an `object`: + +- `text` *(string)* – The translated text. +- `from` *(object)* + - `language` *(object)* + - `didYouMean` *(boolean)* - `true` if the API suggest a correction in the source language + - `iso` *(string)* - The [code of the language](https://github.com/extensionsapp/translatte/blob/master/languages.js) that the API has recognized in the `text` + - `text` *(object)* + - `autoCorrected` *(boolean)* – `true` if the API has auto corrected the `text` + - `value` *(string)* – The auto corrected `text` or the `text` with suggested corrections + - `didYouMean` *(boolean)* – `true` if the API has suggested corrections to the `text` +- `raw` *(string)* - If `options.raw` is true, the raw response from Google Translate servers. Otherwise, `''`. +- `proxy` *(string)* – The proxy that were used in the request. +- `agent` *(string)* – The agent that were used in the request. +- `service` *(object)* – The service that were used in the request. + +Note that `res.from.text` will only be returned if `from.text.autoCorrected` or `from.text.didYouMean` equals to `true`. In this case, it will have the corrections delimited with brackets (`[ ]`): + +``` js +translate('I spea Dutch').then(res => { + console.log(res.from.text.value); + //=> I [speak] Dutch +}).catch(err => { + console.error(err); +}); +``` +Otherwise, it will be an empty `string` (`''`). + +### Errors an `object`: + +Errors in the name of each `services`. + +```json +{ + "google_free": "Could not get token from google", + "google_v3": "Response code 403 (Forbidden)", + "microsoft_v3": "Response code 403 (Forbidden)", + "yandex_v1": "Response code 403 (Forbidden)", + "yandex_v2": "Response code 403 (Forbidden)" +} +``` + +If the proxy server `LOGIN:PASSWORD@192.0.2.100:12345` is inactive. + +```json +{ + "google_free": "LOGIN:PASSWORD@192.0.2.100:12345" +} +``` + +If the error is not related to `services`. + +```json +{ + "message": "The language «foo» is not supported" +} +``` + +**2020 ExtensionsApp**
\ No newline at end of file diff --git a/node_modules/translatte/index.js b/node_modules/translatte/index.js new file mode 100755 index 0000000..16083db --- /dev/null +++ b/node_modules/translatte/index.js @@ -0,0 +1,406 @@ +const querystring = require('querystring'); +const languages = require('./languages'); +const proxy_check = require('proxy-check'); +const tunnel = require('tunnel'); +const token = require('./token'); +const got = require('got'); + +const translatte = async (text, opts) => { + opts = opts || {}; + opts = JSON.parse(JSON.stringify(opts)); + + let result = { + text: '', + raw: '', + from: { + language: { + didYouMean: false, + iso: '' + }, + text: { + autoCorrected: false, + value: '', + didYouMean: false + } + }, + proxy: '', + agent: '', + service: {google_free: true} + }; + + let errors = [ + 'The language «[lang]» is not supported', + 'Text must not exceed 5000 bytes', + 'The server returned an empty response', + 'Could not get token from google', + 'Text translation request failed' + ]; + + if (opts.from && !languages.isSupported(opts.from)) { + return Promise.reject({message: errors[0].replace('[lang]', opts.from)}); + } + + if (opts.to && !languages.isSupported(opts.to)) { + return Promise.reject({message: errors[0].replace('[lang]', opts.to)}); + } + + let bytes = languages.utf8Length(text); + opts.client = opts.client || 't'; + opts.tld = opts.tld || 'com'; + opts.from = languages.getCode(opts.from || 'auto'); + opts.to = languages.getCode(opts.to || 'en'); + opts.services = opts.services || {google_free: true}; + let services = Object.keys(opts.services); + + opts.priority = opts.priority + ? typeof opts.priority === 'string' + ? [opts.priority] + : opts.priority.filter(p => services.indexOf(p) + 1) + : services; + + if (opts.priority.length > 1) { + let all_index = opts.priority.length - 1; + let err_services = {}; + return opts.priority.reduce((p, priority, index) => { + return p.then(prev => { + return new Promise((resolve, reject) => { + if (prev) return resolve(prev); + translatte(text, {...opts, priority}).then(t => { + if (!t || !t.text) { + err_services[priority] = errors[2]; + return all_index === index + ? reject(err_services) + : resolve(); + } + return resolve(t); + }).catch(e => { + err_services[priority] = typeof e === 'object' && (e[priority] || e.message) + ? e[priority] || e.message + : e; + return all_index === index + ? reject(err_services) + : resolve(); + }); + }); + }); + }, Promise.resolve()); + } + + let priority = opts.priority[0]; + + if (bytes > 5000) { + let chars = Math.ceil(text.length / Math.ceil(bytes / 4700)) + 100; + let plain = ' ' + text + ' '; + let texts = []; + let j = 0; + ['.', ',', ' '].forEach(separator => { + if (!plain) return; + let split = plain.split(separator); + for (let i = 0, l = split.length; i < l; i++) { + if (!texts[j]) texts[j] = []; + if ((texts[j].join(separator) + split[i]).length < chars) { + texts[j].push(split[i]); + plain = split.slice(i+1).join(separator); + } else { + if (!texts[j].length) break; + texts[j].push(''); + texts[++j] = []; + if ((texts[j].join(separator) + split[i]).length < chars) { + texts[j].push(split[i]); + plain = split.slice(i+1).join(separator); + } else { + break; + } + } + } + texts = texts.map(function (t) { + if (!t) return; + if (typeof t === 'object') { + return t.join(separator).trim(); + } else if (typeof t === 'string') { + return t.trim(); + } + }).filter(Boolean); + }); + if (!texts || !texts.length) return Promise.reject({[priority]: errors[1]}); + return texts.reduce((p, item) => { + return p.then(prev => { + return new Promise((resolve, reject) => { + setTimeout(() => { + translatte(item, opts).then(t => { + if (!t || !t.text) return reject(errors[2]); + t.text = prev && prev.text ? prev.text + ' ' + t.text : t.text; + return resolve(t); + }).catch(e => reject(e)); + }, 1000); + }); + }); + }, Promise.resolve()); + } + + if (priority === 'google_v3') { + if (Array.isArray(opts.services['google_v3'])) { + opts.services['google_v3'] = opts + .services['google_v3'][Math.floor(Math.random() * opts + .services['google_v3'].length)]; + } + result.service = {google_v3: opts.services['google_v3']}; + let url = 'https://translation.googleapis.com/v3beta1/projects/' + + opts.services['google_v3']['project-id'] + '/locations/global:translateText'; + try { + const {body} = await got(url, { + method: 'POST', + headers: { + 'Authorization': 'Bearer ' + opts.services['google_v3']['token'], + 'Content-type': 'application/json' + }, + body: { + source_language_code: opts.from, + target_language_code: opts.to, + contents: [text] + }, + json: true, + timeout: 10000, + retry: 0 + }); + for (const translation of body.translations) { + result.text += result.text + ? ' ' + translation.translations.translatedText + : translation.translations.translatedText; + } + } catch (e) { + return Promise.reject({google_v3: e.message || e}); + } + return Promise.resolve(result); + } + + if (priority === 'microsoft_v3') { + if (!opts.services['microsoft_v3']) return Promise.resolve(result); + if (Array.isArray(opts.services['microsoft_v3'])) { + opts.services['microsoft_v3'] = opts + .services['microsoft_v3'][Math.floor(Math.random() * opts + .services['microsoft_v3'].length)]; + } + result.service = {microsoft_v3: opts.services['microsoft_v3']}; + let url = 'https://api.cognitive.microsofttranslator.com/translate?' + + querystring.stringify({ + 'api-version': '3.0', + from: opts.from === 'auto' ? '' : opts.from, + to: opts.to + }); + try { + const {body} = await got(url, { + method: 'POST', + headers: { + 'Ocp-Apim-Subscription-Key': opts.services['microsoft_v3']['key'], + 'Ocp-Apim-Subscription-Region': opts.services['microsoft_v3']['location'] + ? opts.services['microsoft_v3']['location'].replace(/[^a-z]/ig, '').toLowerCase() + : 'global', + 'Content-type': 'application/json' + }, + body: [{text}], + json: true, + timeout: 10000, + retry: 0 + }); + for (const translation of body) { + if (translation.detectedLanguage && translation.detectedLanguage.language) { + result.from.language.iso = translation.detectedLanguage.language; + } + result.text += result.text + ? ' ' + translation.translations[0].text + : translation.translations[0].text; + } + } catch (e) { + return Promise.reject({microsoft_v3: e.message || e}); + } + return Promise.resolve(result); + } + + if (priority === 'yandex_v1') { + if (!opts.services['yandex_v1']) return Promise.resolve(result); + if (Array.isArray(opts.services['yandex_v1'])) { + opts.services['yandex_v1'] = opts + .services['yandex_v1'][Math.floor(Math.random() * opts + .services['yandex_v1'].length)]; + } + result.service = {yandex_v1: opts.services['yandex_v1']}; + let url = 'https://translate.yandex.net/api/v1.5/tr.json/translate?' + + querystring.stringify({ + key: opts.services['yandex_v1']['key'], + lang: opts.from && opts.from !== 'auto' + ? opts.from + '-' + opts.to + : opts.to, + text: text + }); + try { + const {body} = await got(url, {json: true, timeout: 10000, retry: 0}); + for (const translation of body.text) { + result.text += result.text + ? ' ' + translation + : translation; + } + } catch (e) { + return Promise.reject({yandex_v1: e.message || e}); + } + return Promise.resolve(result); + } + + if (priority === 'yandex_v2') { + if (!opts.services['yandex_v2']) return Promise.resolve(result); + if (Array.isArray(opts.services['yandex_v2'])) { + opts.services['yandex_v2'] = opts + .services['yandex_v2'][Math.floor(Math.random() * opts + .services['yandex_v2'].length)]; + } + result.service = {yandex_v2: opts.services['yandex_v2']}; + let url = 'https://translate.api.cloud.yandex.net/translate/v2/translate'; + try { + const {body} = await got(url, { + method: 'POST', + headers: { + 'Authorization': 'Api-Key ' + opts.services['yandex_v2']['key'], + 'Content-type': 'application/json' + }, + body: { + sourceLanguageCode: opts.from, + targetLanguageCode: opts.to, + texts: [text] + }, + json: true, + timeout: 10000, + retry: 0 + }); + for (const translation of body.translations) { + result.text += result.text + ? ' ' + translation.text + : translation.text; + } + } catch (e) { + return Promise.reject({yandex_v2: e.message || e}); + } + return Promise.resolve(result); + } + + let proxy = {}; + let translate = {}; + + opts.agents = opts.agents + ? typeof opts.agents === 'string' + ? opts.agents.split(',').map(p => p.trim()) + : opts.agents + : []; + opts.proxies = opts.proxies + ? typeof opts.proxies === 'string' + ? opts.proxies.split(',').map(p => p.trim()) + : opts.proxies + : []; + + if (opts.agents.length) { + let a = opts.agents[Math.floor(Math.random() * opts.agents.length)]; + result.agent = a; + opts.headers = { + 'User-Agent': a + }; + } + if (opts.proxies.length) { + let p = opts.proxies[Math.floor(Math.random() * opts.proxies.length)]; + result.proxy = p; + if (p.indexOf('@') + 1) { + proxy.proxyAuth = p.split('@')[0]; + proxy.host = (p.split('@')[1]).split(':')[0]; + proxy.port = (p.split('@')[1]).split(':')[1]; + } else { + proxy.host = p.split(':')[0]; + proxy.port = p.split(':')[1]; + } + } + + opts.proxy = proxy.host + ? opts.headers + ? {agent: tunnel.httpsOverHttp({proxy, headers: opts.headers})} + : {agent: tunnel.httpsOverHttp({proxy})} + : {}; + + const translate_string = () => { + return new Promise(async (resolve, reject) => { + let t = await token.get(text, opts); + + if (!t) return reject({google_free: errors[3]}); + + let url = 'https://translate.google.' + opts.tld + '/translate_a/single?' + + querystring.stringify({ + [t.name]: t.value, + client: opts.client, + sl: opts.from, + tl: opts.to, + hl: opts.to, + dt: ['at', 'bd', 'ex', 'ld', 'md', 'qca', 'rw', 'rm', 'ss', 't'], + ie: 'UTF-8', + oe: 'UTF-8', + otf: 1, + ssel: 0, + tsel: 0, + kc: 7, + q: text + }); + + try { + translate = await got(url, {...opts.proxy, json: true, timeout: 10000, headers: opts.headers, retry: 0}); + } catch (e) { + return reject({google_free: errors[4]}); + } + + result.raw = opts.raw + ? JSON.stringify(translate.body) + : ''; + + let body = translate.body; + + body[0].forEach(obj => { + if (obj[0]) { + result.text += obj[0]; + } + }); + + if (body[2] === body[8][0][0]) { + result.from.language.iso = body[2]; + } else { + result.from.language.didYouMean = true; + result.from.language.iso = body[8][0][0]; + } + + if (body[7] && body[7][0]) { + let str = body[7][0]; + + str = str.replace(/<b><i>/g, '['); + str = str.replace(/<\/i><\/b>/g, ']'); + + result.from.text.value = str; + + if (body[7][5] === true) { + result.from.text.autoCorrected = true; + } else { + result.from.text.didYouMean = true; + } + } + + return result.text + ? resolve(result) + : reject({google_free: errors[2]}); + }); + }; + + if (opts && opts.proxy && opts.proxy.agent) { + return proxy_check(result.proxy).then(() => { + return translate_string(); + }).catch(() => { + return Promise.reject({google_free: result.proxy}); + }); + } else { + return translate_string(); + } +}; + +module.exports = translatte; +module.exports.languages = languages;
\ No newline at end of file diff --git a/node_modules/translatte/languages.js b/node_modules/translatte/languages.js new file mode 100755 index 0000000..083714e --- /dev/null +++ b/node_modules/translatte/languages.js @@ -0,0 +1,187 @@ +/** + * + * Generated from https://translate.google.com + * + * The languages that Google Translate supports (as of 5/15/16) alongside with their ISO 639-1 codes + * See https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes + */ + +var langs = { + 'auto': 'Automatic', + 'af': 'Afrikaans', + 'sq': 'Albanian', + 'am': 'Amharic', + 'ar': 'Arabic', + 'hy': 'Armenian', + 'az': 'Azerbaijani', + 'eu': 'Basque', + 'be': 'Belarusian', + 'bn': 'Bengali', + 'bs': 'Bosnian', + 'bg': 'Bulgarian', + 'ca': 'Catalan', + 'ceb': 'Cebuano', + 'ny': 'Chichewa', + 'zh': 'Chinese (Simplified)', + 'zh-cn': 'Chinese (Simplified)', + 'zh-tw': 'Chinese (Traditional)', + 'co': 'Corsican', + 'hr': 'Croatian', + 'cs': 'Czech', + 'da': 'Danish', + 'nl': 'Dutch', + 'en': 'English', + 'eo': 'Esperanto', + 'et': 'Estonian', + 'tl': 'Filipino', + 'fi': 'Finnish', + 'fr': 'French', + 'fy': 'Frisian', + 'gl': 'Galician', + 'ka': 'Georgian', + 'de': 'German', + 'el': 'Greek', + 'gu': 'Gujarati', + 'ht': 'Haitian Creole', + 'ha': 'Hausa', + 'haw': 'Hawaiian', + 'he': 'Hebrew', + 'iw': 'Hebrew', + 'hi': 'Hindi', + 'hmn': 'Hmong', + 'hu': 'Hungarian', + 'is': 'Icelandic', + 'ig': 'Igbo', + 'id': 'Indonesian', + 'ga': 'Irish', + 'it': 'Italian', + 'ja': 'Japanese', + 'jw': 'Javanese', + 'kn': 'Kannada', + 'kk': 'Kazakh', + 'km': 'Khmer', + 'ko': 'Korean', + 'ku': 'Kurdish (Kurmanji)', + 'ky': 'Kyrgyz', + 'lo': 'Lao', + 'la': 'Latin', + 'lv': 'Latvian', + 'lt': 'Lithuanian', + 'lb': 'Luxembourgish', + 'mk': 'Macedonian', + 'mg': 'Malagasy', + 'ms': 'Malay', + 'ml': 'Malayalam', + 'mt': 'Maltese', + 'mi': 'Maori', + 'mr': 'Marathi', + 'mn': 'Mongolian', + 'my': 'Myanmar (Burmese)', + 'ne': 'Nepali', + 'no': 'Norwegian', + 'ps': 'Pashto', + 'fa': 'Persian', + 'pl': 'Polish', + 'pt': 'Portuguese', + 'pa': 'Punjabi', + 'ro': 'Romanian', + 'ru': 'Russian', + 'sm': 'Samoan', + 'gd': 'Scots Gaelic', + 'sr': 'Serbian', + 'st': 'Sesotho', + 'sn': 'Shona', + 'sd': 'Sindhi', + 'si': 'Sinhala', + 'sk': 'Slovak', + 'sl': 'Slovenian', + 'so': 'Somali', + 'es': 'Spanish', + 'su': 'Sundanese', + 'sw': 'Swahili', + 'sv': 'Swedish', + 'tg': 'Tajik', + 'ta': 'Tamil', + 'te': 'Telugu', + 'th': 'Thai', + 'tr': 'Turkish', + 'uk': 'Ukrainian', + 'ur': 'Urdu', + 'uz': 'Uzbek', + 'vi': 'Vietnamese', + 'cy': 'Welsh', + 'xh': 'Xhosa', + 'yi': 'Yiddish', + 'yo': 'Yoruba', + 'zu': 'Zulu' +}; +/** + * Returns the ISO 639-1 code of the desiredLang – if it is supported by Google Translate + * @param {string} desiredLang – the name or the code of the desired language + * @returns {string|boolean} The ISO 639-1 code of the language or false if the language is not supported + */ +function getCode(desiredLang) { + if (!desiredLang) { + return false; + } + desiredLang = desiredLang.toLowerCase(); + + if (langs[desiredLang]) { + return desiredLang; + } + + var keys = Object.keys(langs).filter(function (key) { + if (typeof langs[key] !== 'string') { + return false; + } + + return langs[key].toLowerCase() === desiredLang; + }); + + return keys[0] || false; +} + +/** + * Returns true if the desiredLang is supported by Google Translate and false otherwise + * @param desiredLang – the ISO 639-1 code or the name of the desired language + * @returns {boolean} + */ +function isSupported(desiredLang) { + return Boolean(getCode(desiredLang)); +} + +/** + * Returns utf8 length + * @param str – string + * @returns {number} + */ +function utf8Length(str) { + var utf8 = []; + for (var i = 0; i < str.length; i++) { + var charcode = str.charCodeAt(i); + if (charcode < 0x80) utf8.push(charcode); + else if (charcode < 0x800) { + utf8.push(0xc0 | (charcode >> 6), + 0x80 | (charcode & 0x3f)); + } else if (charcode < 0xd800 || charcode >= 0xe000) { + utf8.push(0xe0 | (charcode >> 12), + 0x80 | ((charcode >> 6) & 0x3f), + 0x80 | (charcode & 0x3f)); + } + else { + i++; + charcode = 0x10000 + (((charcode & 0x3ff) << 10) + | (str.charCodeAt(i) & 0x3ff)); + utf8.push(0xf0 | (charcode >> 18), + 0x80 | ((charcode >> 12) & 0x3f), + 0x80 | ((charcode >> 6) & 0x3f), + 0x80 | (charcode & 0x3f)); + } + } + return utf8.length; +} + +module.exports = langs; +module.exports.isSupported = isSupported; +module.exports.getCode = getCode; +module.exports.utf8Length = utf8Length;
\ No newline at end of file diff --git a/node_modules/translatte/logo.png b/node_modules/translatte/logo.png Binary files differnew file mode 100755 index 0000000..9a13d88 --- /dev/null +++ b/node_modules/translatte/logo.png diff --git a/node_modules/translatte/package.json b/node_modules/translatte/package.json new file mode 100755 index 0000000..96ea209 --- /dev/null +++ b/node_modules/translatte/package.json @@ -0,0 +1,47 @@ +{ + "name": "translatte", + "version": "3.0.1", + "description": "A free and unlimited translate for NodeJS", + "main": "index.js", + "repository": { + "type": "git", + "url": "https://github.com/extensionsapp/translatte.git" + }, + "keywords": [ + "translate", + "translator", + "google", + "google translate", + "api", + "free", + "language", + "proxy", + "translatte", + "microsoft", + "azure", + "microsoft azure", + "microsoft translate", + "azure translate", + "google cloud", + "google cloud translate", + "yandex", + "yandex cloud", + "yandex translate", + "yandex cloud translate" + ], + "author": { + "name": "ExtensionsApp", + "email": "extensionsapp@gmail.com" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/extensionsapp/translatte/issues" + }, + "homepage": "https://github.com/extensionsapp/translatte#readme", + "dependencies": { + "tunnel": "0.0.6", + "configstore": "4.0.0", + "proxy-check": "1.0.8", + "got": "9.6.0" + } +} diff --git a/node_modules/translatte/token.js b/node_modules/translatte/token.js new file mode 100755 index 0000000..71f360b --- /dev/null +++ b/node_modules/translatte/token.js @@ -0,0 +1,120 @@ +/** + * Last update: 2018/11/24 + * https://translate.google.com/translate/releases/twsfe_w_20160620_RC00/r/js/desktop_module_main.js + * + * Everything between 'BEGIN' and 'END' was copied from the url above. + */ + +var got = require('got'); +var Configstore = require('configstore'); + +/* eslint-disable */ +// BEGIN + +function sM(a) { + var b; + if (null !== yr) + b = yr; + else { + b = wr(String.fromCharCode(84)); + var c = wr(String.fromCharCode(75)); + b = [b(), b()]; + b[1] = c(); + b = (yr = window[b.join(c())] || "") || "" + } + var d = wr(String.fromCharCode(116)) + , c = wr(String.fromCharCode(107)) + , d = [d(), d()]; + d[1] = c(); + c = "&" + d.join("") + "="; + d = b.split("."); + b = Number(d[0]) || 0; + for (var e = [], f = 0, g = 0; g < a.length; g++) { + var l = a.charCodeAt(g); + 128 > l ? e[f++] = l : (2048 > l ? e[f++] = l >> 6 | 192 : (55296 === (l & 64512) && g + 1 < a.length && 56320 === (a.charCodeAt(g + 1) & 64512) ? (l = 65536 + ((l & 1023) << 10) + (a.charCodeAt(++g) & 1023), + e[f++] = l >> 18 | 240, + e[f++] = l >> 12 & 63 | 128) : e[f++] = l >> 12 | 224, + e[f++] = l >> 6 & 63 | 128), + e[f++] = l & 63 | 128) + } + a = b; + for (f = 0; f < e.length; f++) + a += e[f], + a = xr(a, "+-a^+6"); + a = xr(a, "+-3^+b+-f"); + a ^= Number(d[1]) || 0; + 0 > a && (a = (a & 2147483647) + 2147483648); + a %= 1E6; + return c + (a.toString() + "." + (a ^ b)) +} + +var yr = null; +var wr = function (a) { + return function () { + return a + } +} + , xr = function (a, b) { + for (var c = 0; c < b.length - 2; c += 3) { + var d = b.charAt(c + 2) + , d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d) + , d = "+" === b.charAt(c + 1) ? a >>> d : a << d; + a = "+" === b.charAt(c) ? a + d & 4294967295 : a ^ d + } + return a +}; + +// END +/* eslint-enable */ + +var config = new Configstore('google-translate-api'); + +var window = { + TKK: config.get('TKK') || '422854.923862967' +}; + +function updateTKK(opts) { + opts = opts || {tld: 'com', proxy: {}, headers: {}}; + return new Promise(function (resolve, reject) { + var now = Math.floor(Date.now() / 3600000); + + if (Number(window.TKK.split('.')[0]) === now) { + resolve(); + } else { + got('https://translate.google.' + opts.tld, {...opts.proxy, headers: opts.headers, timeout: 2000, retry: 0}).then(function (res) { + var code = res.body.match(/TKK='.*?';/g); + + if (code) { + eval(code[0]); + /* eslint-disable no-undef */ + if (typeof TKK !== 'undefined') { + window.TKK = TKK; + config.set('TKK', TKK); + } + /* eslint-enable no-undef */ + } + + /** + * Note: If the regex or the eval fail, there is no need to worry. The server will accept + * relatively old seeds. + */ + + resolve(); + }).catch(function () { + reject(); + }); + } + }); +} + +function get(text, opts) { + return updateTKK(opts).then(function () { + var tk = sM(text); + tk = tk.replace('&tk=', ''); + return {name: 'tk', value: tk}; + }).catch(function () { + return null; + }); +} + +module.exports.get = get;
\ No newline at end of file diff --git a/node_modules/translatte/translatte_lg.png b/node_modules/translatte/translatte_lg.png Binary files differnew file mode 100755 index 0000000..a544465 --- /dev/null +++ b/node_modules/translatte/translatte_lg.png diff --git a/node_modules/translatte/translatte_md.png b/node_modules/translatte/translatte_md.png Binary files differnew file mode 100755 index 0000000..c166c39 --- /dev/null +++ b/node_modules/translatte/translatte_md.png |