Этот скрипт отвечает за инициацию процесса. Вместо прямого HTTP-запроса он запускает QuillBotBridge.ps1 через ActiveX. Данные передаются через временные переменные среды (Environment), чтобы избежать ограничений на длину командной строки Windows (где лимит равен 8191 символу).
 
Строки перевода кодируются в Base64 для безопасной передачи любых спецсимволов.
code JavaScript

// Глобальные конфигурационные переменные адресов сервиса QuillBot
var QUILLBOT_TRANSLATE_HOST = "https://quillbot.com";
var QUILLBOT_TRANSLATE_SITE_URL = QUILLBOT_TRANSLATE_HOST + "/translate";
var QUILLBOT_TRANSLATE_HOME_PATH = "/translate";
var QUILLBOT_TRANSLATE_MAX_SOURCE_LEN = 5E3; // Лимит QuillBot в 5000 символов
 
// Глобальные переменные состояния, куда сохраняются результаты выполнения внешнего моста
var QUILLBOT_BRIDGE_TRANSLATION = "";
var QUILLBOT_BRIDGE_SOURCE_LANGUAGE = UNKNOWN_LANGUAGE;
var QUILLBOT_BRIDGE_TARGET_LANGUAGE = ENGLISH_LANGUAGE;
var QUILLBOT_BRIDGE_ERROR = "";
 
/** Возвращает описание сервиса для QTranslate */
function serviceHeader() {
    return new ServiceHeader(
        113,  
        "QuillBot Translate",  
        "QuillBot web translator via portable WebSocket bridge." + Const.NL2 + quillbotSiteUrl(),  
        Capability.TRANSLATE | Capability.DETECT_LANGUAGE
    );
}
 
function serviceHost() {
    return quillbotHost();
}
 
/** Генерирует веб-ссылку на переводчик для открытия в браузере при клике на иконку сервиса */
function serviceLink(a, b, c) {
    var d = quillbotSiteUrl() + "?sl=" + encodeGetParam(quillbotQuerySourceCode(b)) + "&tl=" + encodeGetParam(quillbotQueryTargetCode(c || ENGLISH_LANGUAGE)) + "&tone=auto";
    a && (d += "&text=" + encodeGetParam(trimString(prepareSource(a))));
    return d;
}
 
// Таблица поддерживаемых языков. Индекс соответствует внутреннему ID QTranslate, значение - код языка для QuillBot
SupportedLanguages = [-1, "auto", "af", -1, -1, "ar", -1, -1, -1, -1, "ca", "zh-CN", -1, "hr", "cs", "da", "nl", "en", -1, "fi", "tl", "fr", -1, "de", "el", -1, "iw", "hi", "hu", -1, "id", "it", -1, "ja", -1, "ko", -1, -1, -1, "ms", -1, "no", "fa", "pl", "pt", "ro", "ru", "sr", -1, "sl", "es", -1, "sv", "th", "tr", "uk", "ur", "vi", -1, -1, -1, -1, -1, -1, -1, -1, -1, "te", -1, -1, "kn", "ta", "mr", "bn", -1];
 
/**  
 * Точка входа QTranslate для перевода текста.
 * Она не делает запрос в сеть сама, а вызывает мост.
 */
function serviceTranslateRequest(a, b, c) {
    var d = quillbotSourceText(a), // Очистка и обрезка текста
        // Вызов внешней функции запуска PowerShell скрипта:
        e = parseJsonSafe(quillbotBridgeExecute("translate", d, quillbotRequestLanguageCode(b, "auto"), quillbotRequestLanguageCode(c || ENGLISH_LANGUAGE, "en-US")));
     
    // Запись результатов парсинга в глобальные переменные состояния
    quillbotApplyBridgeState(e, b, c || ENGLISH_LANGUAGE);
     
    // Возвращаем фейковый локальный запрос. Он нужен QTranslate только для того,  
    // чтобы сработал таймер и вызвался метод 'serviceTranslateBridgeResponse'
    return new RequestData(HttpMethod.GET, QUILLBOT_TRANSLATE_HOME_PATH, null, quillbotPageHeaders(), null, "serviceTranslateBridgeResponse");
}
 
/** Callback для получения результата перевода */
function serviceTranslateBridgeResponse(a, b, c, d) {
    var e = QUILLBOT_BRIDGE_TRANSLATION,
        f = QUILLBOT_BRIDGE_ERROR,
        g = QUILLBOT_BRIDGE_SOURCE_LANGUAGE,
        h = QUILLBOT_BRIDGE_TARGET_LANGUAGE;
    resetQuillbotBridgeState(); // Очистка памяти
    if (f) return new ResponseData(f, g, h); // Если была ошибка, отдаем её текст
    return e ? new ResponseData(e, g, h) : new ResponseData("[E] QuillBot Translate: Empty translation", g, h);
}
 
/** Точка входа определения языка */
function serviceDetectLanguageRequest(a) {
    var b = parseJsonSafe(quillbotBridgeExecute("detect", quillbotSourceText(a), "auto", "en-US"));
    resetQuillbotBridgeState();
    if (!b) {
        QUILLBOT_BRIDGE_ERROR = "[E] QuillBot Translate: Invalid bridge response";
    } else if (b.error) {
        QUILLBOT_BRIDGE_ERROR = quillbotFormatBridgeError(b.error);
    } else if (b.sourceLanguage) {
        QUILLBOT_BRIDGE_SOURCE_LANGUAGE = quillbotLanguageFromCode(String(b.sourceLanguage));
    }
    return new RequestData(HttpMethod.GET, QUILLBOT_TRANSLATE_HOME_PATH, null, quillbotPageHeaders(), null, "serviceDetectBridgeResponse");
}
 
/** Callback для получения определенного языка */
function serviceDetectBridgeResponse(a) {
    var b = QUILLBOT_BRIDGE_SOURCE_LANGUAGE,
        c = QUILLBOT_BRIDGE_ERROR;
    resetQuillbotBridgeState();
    return c ? UNKNOWN_LANGUAGE : b;
}
 
/** Применение JSON-данных из моста в глобальные переменные JScript */
function quillbotApplyBridgeState(a, b, c) {
    resetQuillbotBridgeState();
    if (!a) {
        QUILLBOT_BRIDGE_ERROR = "[E] QuillBot Translate: Invalid bridge response";
        return;
    }
    if (a.error) {
        QUILLBOT_BRIDGE_ERROR = quillbotFormatBridgeError(a.error);
        return;
    }
    QUILLBOT_BRIDGE_TRANSLATION = trimString(String(a.translation || ""));
    QUILLBOT_BRIDGE_SOURCE_LANGUAGE = quillbotLanguageFromCode(a.sourceLanguage || b);
    QUILLBOT_BRIDGE_TARGET_LANGUAGE = quillbotLanguageFromCode(a.targetLanguage || c);
}
 
/**
 * ГЛАВНАЯ ФУНКЦИЯ ЗАПУСКА МОСТА POWERSHELL.
 * Она координирует создание файлов, вызов процесса и чтение ответов.
 */
function quillbotBridgeExecute(a, b, c, d) {
    var e = new ActiveXObject("WScript.Shell"), // Работа с процессами ОС
        f = new ActiveXObject("Scripting.FileSystemObject"), // Работа с файлами
        g = e.Environment("Process"), // Переменные окружения процесса
        h = quillbotResolveBridgePath(f, e), // Поиск пути к QuillBotBridge.ps1
        i = quillbotResolveBridgeTempPath(f, e, h), // Поиск пути к папке _temp
        j = quillbotBuildBridgeFilePath(f, i, ".json"), // Путь к будущему файлу ответа
        k = quillbotBuildBridgeFilePath(f, i, ".err"),  // Путь к файлу ошибок
        l = "",
        m = "",
        n = 0,
        o = {};
         
    if (!h) return stringifyJSON({ error: "Bridge script not found" });
     
    // Предварительная очистка мусорных файлов
    quillbotCleanupBridgeFiles(f, j, k);
     
    // Передача параметров через переменные окружения текущего процесса
    // Дочерний процесс PowerShell унаследует их автоматически
    g.Item("QTB_QUILLBOT_MODE") = a || "translate";
    g.Item("QTB_QUILLBOT_TEXT_B64") = quillbotBytesToBase64(quillbotStringToBytes(b || "")); // Текст в Base64
    g.Item("QTB_QUILLBOT_SOURCE") = c || "auto";
    g.Item("QTB_QUILLBOT_TARGET") = d || "en-US";
    g.Item("QTB_QUILLBOT_RESULT_FILE") = j;
    g.Item("QTB_QUILLBOT_TIMEOUT_MS") = String(quillbotBridgeTimeoutMs());
     
    try {
        // Попытка 1: Прямой запуск PowerShell (без вызова CMD)
        o = quillbotRunBridgeCommand(e, f, quillbotBuildDirectBridgeCommand(e, h), j, k);
        n = o.exitCode;
        l = o.resultText;
        m = o.errorText;
         
        // Попытка 2 (резервная): Если первый запуск не вернул данных, пробуем запуск через интерпретатор CMD (%ComSpec%)
        if (!l && !m) {
            o = quillbotRunBridgeCommand(e, f, quillbotBuildShellBridgeCommand(h, k), j, k);
            n = o.exitCode;
            l = o.resultText;
            m = o.errorText;
        }
    } catch (p) {
        m = trimString(String(p && p.message ? p.message : p || "Bridge execution failed"));
    }
     
    // Очистка за собой
    quillbotCleanupBridgeFiles(f, j, k);
    quillbotClearBridgeEnvironment(g);
     
    l = trimString(l);
    m = trimString(m);
     
    // Если есть текст ответа - отдаем его, иначе возвращаем ошибку в JSON
    return l || stringifyJSON({ error: m || "Bridge exit code " + n });
}
 
/** Запуск команды Windows и чтение результирующего файла */
function quillbotRunBridgeCommand(a, b, c, d, e) {
    var f = 0;
    quillbotCleanupBridgeFiles(b, d, e);
    // Параметр '0' скрывает окно консоли, 'true' заставляет JScript ждать завершения команды
    f = a.Run(c, 0, true);  
    return {
        exitCode: f,
        resultText: quillbotReadTextFile(b, d),
        errorText: quillbotReadTextFile(b, e)
    };
}
 
/** Строит команду прямого вызова PowerShell с обходом политики выполнения */
function quillbotBuildDirectBridgeCommand(a, b) {
    return '"' + quillbotResolvePowerShellPath(a) + '" -NoLogo -NoProfile -ExecutionPolicy Bypass -File "' + b + '"';
}
 
/** Строит резервную команду вызова через cmd.exe с перенаправлением ошибок в файл */
function quillbotBuildShellBridgeCommand(a, b) {
    return '%ComSpec% /d /c ""' + quillbotResolvePowerShellPath(new ActiveXObject("WScript.Shell")) + '" -NoLogo -NoProfile -ExecutionPolicy Bypass -File "' + a + '" 2> "' + b + '""';
}
 
/** Находит абсолютный путь к powershell.exe */
function quillbotResolvePowerShellPath(a) {
    var b = a.ExpandEnvironmentStrings("%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe");
    return trimString(b || "powershell.exe");
}
 
/** Сканирует папки для обнаружения QuillBotBridge.ps1 */
function quillbotResolveBridgePath(a, b) {
    var c = quillbotCandidateServiceRoots(a, b), d, e;
    for (d = 0; d < c.length; d++) {
        e = a.BuildPath(c[d], "QuillBotBridge.ps1");
        if (a.FileExists(e)) return quillbotAbsolutePath(a, e);
    }
    return a.FileExists("QuillBotBridge.ps1") ? quillbotAbsolutePath(a, "QuillBotBridge.ps1") : "";
}
 
/** Поиск или создание временной директории _temp для обмена JSON-файлами */
function quillbotResolveBridgeTempPath(a, b, c) {
    var d = [], e, f;
    c && d.push(a.BuildPath(a.GetParentFolderName(c), "_temp"));
    e = quillbotCandidateServiceRoots(a, b);
    for (f = 0; f < e.length; f++) d.push(a.BuildPath(e[f], "_temp"));
    d.push("_temp");
    for (f = 0; f < d.length; f++) {
        try {
            d[f] = quillbotAbsolutePath(a, d[f]);
            a.FolderExists(d[f]) || a.CreateFolder(d[f]);
            if (a.FolderExists(d[f])) return d[f];
        } catch (g) {}
    }
    return quillbotAbsolutePath(a, ".");
}
 
/** Собирает список возможных директорий, где может лежать скрипт сервиса */
function quillbotCandidateServiceRoots(a, b) {
    var c = [], d = "";
    try {
        d = b.CurrentDirectory || "";
    } catch (f) {}
    d && (
        c.push(a.BuildPath(d, "Services\\QuillBot Translate")),  
        c.push(a.BuildPath(d, ".\\Services\\QuillBot Translate")),  
        c.push(a.BuildPath(d, "QuillBot Translate"))
    );
    c.push("Services\\QuillBot Translate");
    c.push(".\\Services\\QuillBot Translate");
    c.push("QuillBot Translate");
    for (var e = 0; e < c.length; e++) c[e] = quillbotAbsolutePath(a, c[e]);
    return quillbotUniquePaths(c);
}
 
/** Удаление дублирующихся путей */
function quillbotUniquePaths(a) {
    var b = [], c = {}, d, e;
    for (d = 0; d < a.length; d++) {
        e = String(a[d] || "").toLowerCase();
        e && !c[e] && (c[e] = true, b.push(a[d]));
    }
    return b;
}
 
/** Генерация имени уникального временного файла */
function quillbotBuildBridgeFilePath(a, b, c) {
    return a.BuildPath(b, "qtranslate_quillbot_" + quillbotUuid() + c);
}
 
/**  
 * Чтение текстового файла в кодировке UTF-8.
 * Пытается использовать объект ADODB.Stream, так как встроенный Scripting.FileSystemObject
 * не умеет читать стандартный UTF-8 без BOM (он читает его как ANSI).
 */
function quillbotReadTextFile(a, b) {
    var c, d;
    try {
        if (!a.FileExists(b)) return "";
        c = new ActiveXObject("ADODB.Stream");
        c.Type = 2; // Текстовый режим
        c.Charset = "utf-8";
        c.Open();
        c.LoadFromFile(b);
        d = c.ReadText();
        c.Close();
        return trimString(String(d || "").replace(/^\uFEFF/, "")); // Вырезаем BOM маркер если он есть
    } catch (d) {
        // Резервный метод чтения через FSO в формате UTF-16 (-1)
        try {
            if (!a.FileExists(b)) return "";
            c = a.OpenTextFile(b, 1, false, -1);
            b = c.ReadAll();
            c.Close();
            return trimString(String(b || "").replace(/^\uFEFF/, ""));
        } catch (e) {
            return "";
        }
    }
}
 
/** Удаление временных файлов обмена */
function quillbotCleanupBridgeFiles(a, b, c) {
    try { a.FileExists(b) && a.DeleteFile(b, true); } catch (d) {}
    try { a.FileExists(c) && a.DeleteFile(c, true); } catch (e) {}
}
 
/** Очистка переменных окружения Windows после выполнения операции */
function quillbotClearBridgeEnvironment(a) {
    var envs = ["QTB_QUILLBOT_MODE", "QTB_QUILLBOT_TEXT_B64", "QTB_QUILLBOT_SOURCE", "QTB_QUILLBOT_TARGET", "QTB_QUILLBOT_RESULT_FILE", "QTB_QUILLBOT_TIMEOUT_MS"];
    for (var i = 0; i < envs.length; i++) {
        try { a.Remove(envs[i]); } catch (e) {}
    }
}
 
function quillbotAbsolutePath(a, b) {
    try { return a.GetAbsolutePathName(b); } catch (c) { return b; }
}
 
/** Генератор уникального ID запроса */
function quillbotUuid() {
    return (new Date).getTime() + "_" + Math.floor(1E6 * Math.random());
}
 
function quillbotSourceText(a) {
    return trimString(limitSource(prepareSource(a), QUILLBOT_TRANSLATE_MAX_SOURCE_LEN));
}
 
function quillbotBridgeTimeoutMs() {
    var a = Number(Options.QuillBotTimeoutMs) || 30000;
    return 1000 > a ? 1000 : a;
}
 
function quillbotPageHeaders() {
    return getHeader() + Const.NL + "Referer: " + quillbotSiteUrl() + Const.NL + "Origin: " + quillbotHost() + Const.NL + "Connection: keep-alive";
}
 
function quillbotHost() {
    return trimString(Options.QuillBotHost || QUILLBOT_TRANSLATE_HOST);
}
 
function quillbotSiteUrl() {
    return trimString(Options.QuillBotSiteUrl || QUILLBOT_TRANSLATE_SITE_URL);
}
 
/** Нормализация кодов языков под требования API QuillBot */
function quillbotRequestLanguageCode(a, b) {
    a = codeFromLanguage(a);
    if (a == UNKNOWN_LANGUAGE_CODE || !a) return b || "en-US";
    switch (a) {
        case "auto": return "auto";
        case "iw":
        case "he": return "he";
        case "zh-CN":
        case "zh-TW":
        case "zh-Hans":
        case "zh-Hant": return "zh";
        case "en": return "en-US";
        case "de": return "de-DE";
        case "pt":
        case "pt-BR": return "pt-PT";
        case "no":
        case "nb": return "no";
        case "tl":
        case "fil": return "tl";
        default: return a;
    }
}
 
function quillbotQuerySourceCode(a) {
    a = quillbotRequestLanguageCode(a, "auto");
    return a == "auto" ? "auto" : a;
}
 
function quillbotQueryTargetCode(a) {
    return quillbotRequestLanguageCode(a, "en-US");
}
 
/** Преобразование ответа Quillbot обратно в коды QTranslate */
function quillbotNormalizeDetectedCode(a) {
    a = trimString(String(a || ""));
    switch (a) {
        case "he":
        case "he-IL": return "iw";
        case "zh":
        case "zh-CN":
        case "zh-Hans": return "zh-CN";
        case "zh-TW":
        case "zh-Hant": return "zh-TW";
        case "en-US":
        case "en-GB":
        case "en": return "en";
        case "de-DE":
        case "de-CH":
        case "de": return "de";
        case "pt-PT":
        case "pt-BR": return "pt";
        case "nb": return "no";
        case "fil": return "tl";
        default: return a.indexOf("-") > 0 ? a.split("-")[0] : a;
    }
}
 
function quillbotLanguageFromCode(a) {
    var b = languageFromCode(quillbotNormalizeDetectedCode(String(a || "")));
    return isLanguage(b) ? b : UNKNOWN_LANGUAGE;
}
 
function quillbotFormatBridgeError(a) {
    a = trimString(String(a || ""));
    return "[E] QuillBot Translate: " + (a || "Bridge execution failed");
}
 
function resetQuillbotBridgeState() {
    QUILLBOT_BRIDGE_TRANSLATION = "";
    QUILLBOT_BRIDGE_SOURCE_LANGUAGE = UNKNOWN_LANGUAGE;
    QUILLBOT_BRIDGE_TARGET_LANGUAGE = ENGLISH_LANGUAGE;
    QUILLBOT_BRIDGE_ERROR = "";
}
 
function parseJsonSafe(a) {
    try { return parseJSON(a); } catch (b) { return null; }
}
 
/** Побайтовое преобразование строки в UTF-8 массив байт (для Base64) */
function quillbotStringToBytes(a) {
    var b = [], c = 0, d, e;
    a = a || "";
    for (d = 0; d < a.length; d++) {
        e = a.charCodeAt(d);
        if (128 > e) {
            b[c++] = e;
        } else {
            if (2048 > e) {
                b[c++] = e >> 6 | 192;
            } else {
                if (55296 == (e & 64512) && d + 1 < a.length && 56320 == (a.charCodeAt(d + 1) & 64512)) {
                    e = 65536 + ((e & 1023) << 10) + (a.charCodeAt(++d) & 1023);
                    b[c++] = e >> 18 | 240;
                    b[c++] = e >> 12 & 63 | 128;
                } else {
                    b[c++] = e >> 12 | 224;
                }
                b[c++] = e >> 6 & 63 | 128;
            }
            b[c++] = e & 63 | 128;
        }
    }
    return b;
}
 
/** Стандартный алгоритм Base64-кодирования массива байт */
function quillbotBytesToBase64(a) {
    var b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
        c = "", d = 0, e, f, g;
    for (d = 0; d < a.length; d += 3) {
        e = a[d];
        f = d + 1 < a.length ? a[d + 1] : NaN;
        g = d + 2 < a.length ? a[d + 2] : NaN;
        c += b.charAt(e >> 2);
        c += b.charAt((e & 3) << 4 | (f || 0) >> 4);
        c += isNaN(f) ? "=" : b.charAt((f & 15) << 2 | (g || 0) >> 6);
        c += isNaN(g) ? "=" : b.charAt(g & 63);
    }
    return c;
}