ScriptedEngineer / Twitch Toolbox

// ==UserScript==
// @namespace     https://openuserjs.org/users/ScriptedEngineer
// @name          Twitch Toolbox
// @author        ScriptedEngineer
// @description   Auto channel points bonus and more
// @copyright     2020, ScriptedEngineer (https://openuserjs.org/users/ScriptedEngineer)
// @version       0.1.73
// @match         *://www.twitch.tv/*
// @include       *://*.twitch.tv/*
// @exclude       *://*.twitch.tv/*.html
// @exclude       *://*.twitch.tv/*.html?*
// @exclude       *://*.twitch.tv/*.htm
// @exclude       *://*.twitch.tv/*.htm?*
// @updateURL     https://openuserjs.org/meta/ScriptedEngineer/Twitch_Toolbox.meta.js
// @downloadURL   https://openuserjs.org/install/ScriptedEngineer/Twitch_Toolbox.user.js
// @grant         GM_getValue
// @grant         GM_setValue
// @grant         GM_deleteValue
// @license       GPL-3.0-or-later
// ==/UserScript==

// ==OpenUserJS==
// @author ScriptedEngineer
// ==/OpenUserJS==

"use strict";
setInterval(function() {
    var block = document.getElementsByClassName("tw-button--success")[0];
    if (AutoPoints && block) {
        block.click();
    }
}, 1000);
const chatObserver = new MutationObserver(mutations => {
    mutations.forEach(mutation => {
        if (mutation.type == 'childList'){
            //console.log(mutation.target);
            if(mutation.target.matches('div.chat-line__no-background')) {
                if (SaveDeleted && mutation.removedNodes.length > 0) {//Deleted Message Save
                    mutation.removedNodes.forEach(n => {
                        console.log(n);
                        if (n.matches("span.text-fragment") || n.matches('div.chat-line__message--emote-button')) {
                            var newSpan = document.createElement('span');
                            newSpan.classList.add("chat-line__message--deleted");//.setAttribute("class", "");chat-line__message--deleted-detailed
                            newSpan.classList.add("chat-line__message--deleted-detailed");
                            newSpan.innerHTML = n.outerHTML;
                            var msdltd = mutation.target.querySelector('span[class="chat-line__message--deleted-notice"]');
                            msdltd.parentNode.insertBefore(newSpan,msdltd);
                            var mewSpan = document.createElement('span');
                            mewSpan.innerText = " ";
                            msdltd.parentNode.insertBefore(mewSpan,msdltd);
                            msdltd.innerText = 'cообщение удалено.';//
                            try{
                                mutation.target.querySelector('span.twitchtoolbox-wronglayout').remove();
                            }catch(e){}
                        }
                    });
                }
            }else if(mutation.target.matches('span[style="margin-left: 0.5rem;"]')){
                mutation.target.childNodes.forEach(sfd=>{
                    //sfd.style.float = 'right';
                });
                mutation.addedNodes.forEach(n => {
                    if(n.matches('div[data-a-target="chat-badge"]')){
                        var tooltip = n.querySelector('div[data-a-target="tw-tooltip-label"]');
                        tooltip.classList.remove('tw-tooltip--align-left');
                        tooltip.classList.add('tw-tooltip--align-center');
                    }
                });
            }else if(mutation.target.matches('div.chat-scrollable-area__message-container')){
                mutation.addedNodes.forEach(n => {
                    var textns = n.querySelectorAll('span[class*="-fragment"]');
                    //console.log(textns);
                    var textn = textns[0];
                    setTimeout(() => {
                        if(textn){
                            var text = '';
                            textns.forEach(element => {text += element.innerText;});
                            var nickspan = n.querySelector('span[class="chat-author__display-name"]');
                            var nick = nickspan.innerText;
                            var color = GM_getValue("NickColor."+nick,false);
                            if(color){
                                nickspan.style.color = color;
                            }else if(encoding.check(text)){
                                var decoded = encoding.decrypt(text,encodekey);
                                if(decoded){
                                    textns.forEach(element => {
                                        element.innerText = "";
                                    });
                                    var anewSpan = document.createElement('span');
                                    anewSpan.classList.add("chat-line__message--deleted");
                                    anewSpan.classList.add("twitchtoolbox-wronglayout");
                                    anewSpan.innerHTML = '<div class="tw-inline tw-relative tw-tooltip-wrapper" style="float:right;"><div class="tw-align-center tw-inline-block">&#xA0;⌈🔑⌋</div><div class="tw-tooltip tw-tooltip--align-right tw-tooltip--up" data-a-target="tw-tooltip-label" role="tooltip">decoded</div></div>';
                                    anewSpan.style.cursor = 'pointer';
                                    anewSpan.title = text;
                                    textn.parentNode.prepend(anewSpan);
                                    textns[0].innerText = text = decoded;
                                }
                            }else if(brailebytes.check(text)){
                                var ddecoded = brailebytes.decrypt(text,encodekey);
                                if(ddecoded){
                                    textns.forEach(element => {
                                        element.innerText = "";
                                    });
                                    var sanewSpan = document.createElement('span');
                                    sanewSpan.classList.add("chat-line__message--deleted");
                                    sanewSpan.classList.add("twitchtoolbox-wronglayout");
                                    sanewSpan.innerHTML = '<div class="tw-inline tw-relative tw-tooltip-wrapper" style="float:right;"><div class="tw-align-center tw-inline-block">&#xA0;⌈<a style="color: red;">⣿</a>⌋</div><div class="tw-tooltip tw-tooltip--align-right tw-tooltip--up" data-a-target="tw-tooltip-label" role="tooltip">braille bytes</div></div>';
                                    sanewSpan.style.cursor = 'pointer';
                                    sanewSpan.title = text;
                                    textn.parentNode.prepend(sanewSpan);
                                    textns[0].innerText = text = ddecoded;
                                }
                            }
                            if(ruseng.check(text)){//textParams.RusEng
                                if(ChangeWrong)
                                {
                                    textns.forEach(element => {element.alt = ruseng.decrypt(element.innerText);});
                                }
                                else
                                {
                                    textns.forEach(element => {element.alt = element.innerText;});
                                }
                                var newSpan = document.createElement('span');
                                newSpan.classList.add("chat-line__message--deleted");
                                newSpan.classList.add("twitchtoolbox-wronglayout");
                                newSpan.innerHTML = '<div class="tw-inline tw-relative tw-tooltip-wrapper" style="float:right;"><div class="tw-align-center tw-inline-block">&#xA0;⌈en↔ru⌋</div><div class="tw-tooltip tw-tooltip--align-right tw-tooltip--up" data-a-target="tw-tooltip-label" role="tooltip">раскладка</div></div>';
                                newSpan.style.cursor = 'pointer';
                                newSpan.title = ChangeWrong?text:ruseng.decrypt(text);
                                newSpan.onclick = function(){
                                    textns.forEach(element => {element.innerText = ruseng.decrypt(element.innerText);});
                                    newSpan.title = ruseng.decrypt(newSpan.title);
                                }
                                textn.parentNode.prepend(newSpan);
                                if(ChangeWrong)
                                {
                                    textns.forEach(element => {element.innerText = ruseng.decrypt(element.innerText);});
                                }
                                //sendMessage(nick+" возможно хотел написать: "+ruseng.decrypt(text));
                            }/*else if(AutoTranslate && Russian && isEng(text.trim()) && text.length > 1 && !text.startsWith('!')){
                                setTimeout(() => {
                                    var translatedText = '';
                                    var isChanged = false;
                                    textns.forEach(element => {
                                        element.alt = element.innerText;
                                        TranslateTo(element.innerText, 'ru',(x)=>{
                                            translatedText += element.innerText = x.text || element.innerText;
                                            ChatLanguage = x.from;
                                        });
                                    });
                                    if(translatedText.trim() != text.trim()){
                                        var xnewSpan = document.createElement('span');
                                        xnewSpan.classList.add("chat-line__message--deleted");
                                        xnewSpan.classList.add("twitchtoolbox-wronglayout");
                                        xnewSpan.style.cursor = 'pointer';
                                        xnewSpan.innerHTML = '<div class="tw-inline tw-relative tw-tooltip-wrapper" style="float:right;"><div class="tw-align-center tw-inline-block">&#xA0;⌈🌐⌋</div><div class="tw-tooltip tw-tooltip--align-right tw-tooltip--up" data-a-target="tw-tooltip-label" role="tooltip">перевод</div></div>';
                                        xnewSpan.title = text;
                                        xnewSpan.onclick = function(){
                                            var sptitle = '';
                                            textns.forEach(element => {
                                                var intex = element.alt;
                                                sptitle += element.alt = element.innerText;
                                                element.innerText = intex;
                                            });
                                            xnewSpan.title = sptitle;
                                        }
                                        textn.parentNode.prepend(xnewSpan);
                                    }
                                }, 0);
                            }*/
                            var params = text.replace(/\@/g,'').trim().split(' ');
                            params[0] = params[0].toLowerCase();
                            switch(params[0]){
                                case "!play":
                                    if(AutoMOS){
                                        if((Date.now() - MOSP) < 60000){
                                            if(!plascmdcount.includes(nick))plascmdcount.push(nick);
                                        }else{
                                            MOSP = Date.now();
                                            plascmdcount = [];
                                        }
                                        var views = document.querySelector('div[data-a-target="tw-stat-value"]');
                                        if(!views)views = document.querySelector('p[data-a-target="animated-channel-viewers-count"]');
                                        var vievers = views.innerText;
                                        var needed = vievers > 50?Math.floor(vievers/12):(vievers > 6?Math.floor(vievers/6):1);
                                        if(plascmdcount.length >= needed){
                                            if((Date.now() - MOSP2) > 60000){
                                                sendMessage("!play");
                                            }
                                            MOSP2 = Date.now();
                                            plascmdcount = [];
                                        }
                                    }
                                    break;
                                case "!race":
                                    if(AutoMOS){
                                        if((Date.now() - MOSP) < 60000){
                                            if(!plascmdcount.includes(nick))plascmdcount.push(nick);
                                        }else{
                                            MOSP = Date.now();
                                            plascmdcount = [];
                                        }
                                        var vsiews = document.querySelector('div[data-a-target="tw-stat-value"]');
                                        if(!vsiews)vsiews = document.querySelector('p[data-a-target="animated-channel-viewers-count"]');
                                        var vwievers = vsiews.innerText;
                                        var nseeded = vwievers > 50?Math.floor(vwievers/12):(vwievers > 6?Math.floor(vwievers/6):1);
                                        if(plascmdcount.length >= nseeded){
                                            if((Date.now() - MOSP2) > 60000){
                                                sendMessage("!race");
                                            }
                                            MOSP2 = Date.now();
                                            plascmdcount = [];
                                        }
                                    }
                                    break;
                                default:

                                    break;
                            }
                        }

                    });
                    if(HideCheer){
                        n.querySelectorAll('img[class="chat-badge"]').forEach(x=>{
                            if(x.parentNode.href)
                            {
                                if(x.parentNode.href.includes('bits')){
                                    x.style.display = 'none';
                                }
                            }else if(x.alt.includes('cheer')){
                                x.style.display = 'none';
                            }
                        });
                    }
                    if(BetterChat){
                        if(BadgesRight){
                            var sfleft = n.querySelector('img[class="chat-badge"]');
                            if(sfleft){
                                sfleft = sfleft.parentNode;
                                if(sfleft.matches('a'))sfleft = sfleft.parentNode;
                                sfleft.style = 'margin-left: 0.5rem;';
                                //sfleft.classList.add('chat-line__username-container');
                                sfleft.childNodes.forEach(sfd=>{
                                    //sfd.style.float = 'right';
                                });
                                sfleft.parentNode.append(sfleft);
                            }
                        }
                        n.style.borderBottom = "1px dotted RGBA(127, 127, 127,0.5)";
                        n.classList.remove('tw-mg-y-05');
                        if(bettchtind)n.style.backgroundColor = "RGBA(177, 177, 177,0.1)";
                        else n.style.backgroundColor = "RGBA(77, 77, 77,0.1)";
                        bettchtind = !bettchtind;
                    }
                }, 0);
            }else if(mutation.target.matches('div.chat-settings') || mutation.target.matches('div.chat-settings__content')){
                try{
                    var emotemenu = document.querySelector('button[id="emote-menu-button"]');
                    document.querySelector('div[data-a-target="chat-settings-balloon"]').style.marginRight = "-"+(5.3+(emotemenu?3.5:0)+(EncodeButton?3.5:0)+(BrailleBytes?3.5:0))+"rem";
                }catch(e){}
                mutation.addedNodes.forEach(n => {
                    if(n.nodeType == 1){
                        var bttv = n.matches('div.bttv-chat-settings');
                        var chki = n.matches('div.tw-border-t') && !bttv;
                        if(n.matches('div.simplebar-scroll-content') || chki){
                            var befr = chki?n:Array.from(n.firstChild.firstChild.children).filter(function (sandwich) {return sandwich.matches('div.tw-border-t');})[0];//n.firstChild.firstChild.querySelector('div[class="tw-border-t tw-mg-t-1 tw-mg-x-05 tw-pd-b-1"]');
                            if(befr){
                                ReadGMValues();
                                var ndiv = document.createElement('div');
                                ndiv.innerHTML = '<div ext="TwitchToolbox"><div class="tw-border-t tw-mg-t-1 tw-mg-x-05 tw-pd-b-1"></div><div class="tw-mg-y-05 tw-pd-x-05"><p class="tw-c-text-alt-2 tw-font-size-6 tw-strong tw-upcase">'+(Russian?'Инструменты':'Tools')+'</p></div>'+
                                    '<div class="tw-full-width tw-relative"><button class="tw-block tw-border-radius-medium tw-full-width tw-interactable tw-interactable--alpha tw-interactable--hover-enabled tw-interactive" data-a-target="ttb-button" data-test-selector="ttb-button"><div class="tw-align-items-center tw-flex tw-pd-05 tw-relative"><div class="tw-flex-grow-1">'+(Russian?'Показать настройки':'Show settings')+'</div></div></button></div>'+
                                    '<div class="TTBSettings" style="transition: all .5s ease-out; height: 0px; opacity: 0; overflow: hidden;">'+
                                    '<div class="tw-pd-05"><div class="tw-align-items-center tw-flex"><label class="tw-drop-down-menu-input-item__label tw-flex-grow-1 tw-mg-r-2" for="TwitchToolbox-AutoPoints">'+(Russian?'Собирать баллы канала':'Collect channel points')+'</label><div class="tw-toggle"><input type="checkbox" id="TwitchToolbox-AutoPoints" label="0" class="tw-toggle__input" data-a-target="tw-toggle" '+(AutoPoints?'checked=""':"")+'><label for="TwitchToolbox-AutoPoints" class="tw-toggle__button"><p class="tw-hide-accessible">0</p></label></div></div></div>'+
                                    '<div class="tw-pd-05"><div class="tw-align-items-center tw-flex"><label class="tw-drop-down-menu-input-item__label tw-flex-grow-1 tw-mg-r-2" for="TwitchToolbox-AutoMos">'+(Russian?'Авто !play и !race':'Auto !play & !race')+'</label><div class="tw-toggle"><input type="checkbox" id="TwitchToolbox-AutoMos" label="1" class="tw-toggle__input" data-a-target="tw-toggle" '+(AutoMOS?'checked=""':"")+'><label for="TwitchToolbox-AutoMos" class="tw-toggle__button"><p class="tw-hide-accessible">1</p></label></div></div></div>'+
                                    '<div class="tw-pd-05"><div class="tw-align-items-center tw-flex"><label class="tw-drop-down-menu-input-item__label tw-flex-grow-1 tw-mg-r-2" for="TwitchToolbox-SaveDeleted">'+(Russian?'Сохранять удаленные сообщения':'Save deleted messages')+'</label><div class="tw-toggle"><input type="checkbox" id="TwitchToolbox-SaveDeleted" label="2" class="tw-toggle__input" data-a-target="tw-toggle" '+(SaveDeleted?'checked=""':"")+'><label for="TwitchToolbox-SaveDeleted" class="tw-toggle__button"><p class="tw-hide-accessible">2</p></label></div></div></div>'+
                                    '<div class="tw-pd-05"><div class="tw-align-items-center tw-flex"><label class="tw-drop-down-menu-input-item__label tw-flex-grow-1 tw-mg-r-2" for="TwitchToolbox-EncodeButton">'+(Russian?'Кнопка для шифрования':'Encode message button')+'</label><div class="tw-toggle"><input type="checkbox" id="TwitchToolbox-EncodeButton" label="6" class="tw-toggle__input" data-a-target="tw-toggle" '+(EncodeButton?'checked=""':"")+'><label for="TwitchToolbox-EncodeButton" class="tw-toggle__button"><p class="tw-hide-accessible">6</p></label></div></div></div>'+
                                    '<div class="tw-pd-05"><div class="tw-align-items-center tw-flex"><label class="tw-drop-down-menu-input-item__label tw-flex-grow-1 tw-mg-r-2" for="TwitchToolbox-BrailleBytes">'+(Russian?'Кнопка Braille байты':'Braille bytes button')+'</label><div class="tw-toggle"><input type="checkbox" id="TwitchToolbox-BrailleBytes" label="7" class="tw-toggle__input" data-a-target="tw-toggle" '+(BrailleBytes?'checked=""':"")+'><label for="TwitchToolbox-BrailleBytes" class="tw-toggle__button"><p class="tw-hide-accessible">7</p></label></div></div></div>'+
                                    (Russian?'<div class="tw-pd-05"><div class="tw-align-items-center tw-flex"><label class="tw-drop-down-menu-input-item__label tw-flex-grow-1 tw-mg-r-2" for="TwitchToolbox-ChangeWrong">Исправлять эльфийский</label><div class="tw-toggle"><input type="checkbox" id="TwitchToolbox-ChangeWrong" label="5" class="tw-toggle__input" data-a-target="tw-toggle" '+(ChangeWrong?'checked=""':"")+'><label for="TwitchToolbox-ChangeWrong" class="tw-toggle__button"><p class="tw-hide-accessible">5</p></label></div></div></div>'/*+
                                     '<div class="tw-pd-05"><div class="tw-align-items-center tw-flex"><label class="tw-drop-down-menu-input-item__label tw-flex-grow-1 tw-mg-r-2" for="TwitchToolbox-AutoTranslate">Автоматический перевод чата</label><div class="tw-toggle"><input type="checkbox" id="TwitchToolbox-AutoTranslate" label="9" class="tw-toggle__input" data-a-target="tw-toggle" '+(AutoTranslate?'checked=""':"")+'><label for="TwitchToolbox-AutoTranslate" class="tw-toggle__button"><p class="tw-hide-accessible">9</p></label></div></div></div>'*/:'')+
                                    '<div class="tw-pd-05"><div class="tw-align-items-center tw-flex"><label class="tw-drop-down-menu-input-item__label tw-flex-grow-1 tw-mg-r-2" for="TwitchToolbox-BetterChat">'+(Russian?'Улучшенный чат':'Better chat')+'</label><div class="tw-toggle"><input type="checkbox" id="TwitchToolbox-BetterChat" label="3" class="tw-toggle__input" data-a-target="tw-toggle" '+(BetterChat?'checked=""':"")+'><label for="TwitchToolbox-BetterChat" class="tw-toggle__button"><p class="tw-hide-accessible">3</p></label></div></div></div>'+
                                    '<div class="tw-pd-05"><div class="tw-align-items-center tw-flex"><label class="tw-drop-down-menu-input-item__label tw-flex-grow-1 tw-mg-r-2" for="TwitchToolbox-BadgesRight">'+(Russian?'Значки в чате справа':'Move badges to right')+'</label><div class="tw-toggle"><input type="checkbox" id="TwitchToolbox-BadgesRight" label="8" class="tw-toggle__input" data-a-target="tw-toggle" '+(BadgesRight?'checked=""':"")+'><label for="TwitchToolbox-BadgesRight" class="tw-toggle__button"><p class="tw-hide-accessible">8</p></label></div></div></div>'+
                                    '<div class="tw-pd-05"><div class="tw-align-items-center tw-flex"><label class="tw-drop-down-menu-input-item__label tw-flex-grow-1 tw-mg-r-2" for="TwitchToolbox-HideCheer">'+(Russian?'Скрыть Bits и рейтинг':'Hide Bits and top')+'</label><div class="tw-toggle"><input type="checkbox" id="TwitchToolbox-HideCheer" label="4" class="tw-toggle__input" data-a-target="tw-toggle" '+(HideCheer?'checked=""':"")+'><label for="TwitchToolbox-HideCheer" class="tw-toggle__button"><p class="tw-hide-accessible">4</p></label></div></div></div>'+
                                    '<div class="tw-pd-05"><div class="tw-align-items-center tw-flex"><label class="tw-drop-down-menu-input-item__label tw-flex-grow-1 tw-mg-r-2" for="TwitchToolbox-BTTV">'+(Russian?'Внедрить BetterTTV':'Embed BetterTTV')+'</label><div class="tw-toggle"><input type="checkbox" id="TwitchToolbox-BTTV" label="10" class="tw-toggle__input" data-a-target="tw-toggle" '+(IncludeBTTV?'checked=""':"")+'><label for="TwitchToolbox-BTTV" class="tw-toggle__button"><p class="tw-hide-accessible">10</p></label></div></div></div>'+
                                    '<div class="tw-pd-05"><div class="tw-align-items-center tw-flex"><label class="tw-drop-down-menu-input-item__label tw-flex-grow-1 tw-mg-r-2" for="TwitchToolbox-SaveInput">'+(Russian?'Сохранять текст в поле ввода':'Save text in the input field')+'</label><div class="tw-toggle"><input type="checkbox" id="TwitchToolbox-SaveInput" label="11" class="tw-toggle__input" data-a-target="tw-toggle" '+(SaveInput?'checked=""':"")+'><label for="TwitchToolbox-SaveInput" class="tw-toggle__button"><p class="tw-hide-accessible">11</p></label></div></div></div>'+
                                    "</div></div>";
                                if(chki)befr.parentNode.insertBefore(ndiv,befr); 
                                else if(n.firstChild.firstChild == befr.parentNode)n.firstChild.firstChild.insertBefore(ndiv,befr);
                                document.querySelector('button[data-a-target="ttb-button"]').addEventListener('click',function() {
                                    var sts = document.querySelector('div[class="TTBSettings"]');
                                    var button = document.querySelector('button[data-a-target="ttb-button"]');
                                    if(sts.style.height == "0px"){
                                        sts.style.height = sts.scrollHeight + "px";
                                        sts.style.opacity = "1";
                                        button.querySelector('div[class="tw-flex-grow-1"]').innerText = (Russian?'Скрыть настройки':'Hide settings');
                                        button.blur();
                                    }
                                    else {
                                        sts.style.height = "0px";
                                        sts.style.opacity = "0";
                                        button.querySelector('div[class="tw-flex-grow-1"]').innerText = (Russian?'Показать настройки':'Show settings');
                                        button.blur();
                                    }
                                },false);
                                document.querySelector('input[id="TwitchToolbox-AutoPoints"]').addEventListener('change',function() {
                                    AutoPoints = window.getComputedStyle(this.parentNode.querySelector('label[for="TwitchToolbox-AutoPoints"]'), ":before").content != "none";
                                    GM_setValue("AutoCPoints",AutoPoints);
                                },false);
                                document.querySelector('input[id="TwitchToolbox-SaveInput"]').addEventListener('change',function() {
                                    SaveInput = window.getComputedStyle(this.parentNode.querySelector('label[for="TwitchToolbox-SaveInput"]'), ":before").content != "none";
                                    GM_setValue("SaveInput",SaveInput);
                                },false);
                                document.querySelector('input[id="TwitchToolbox-BadgesRight"]').addEventListener('change',function() {
                                    BadgesRight = window.getComputedStyle(this.parentNode.querySelector('label[for="TwitchToolbox-BadgesRight"]'), ":before").content != "none";
                                    GM_setValue("BadgesRight",BadgesRight);
                                },false);
                                var cvdlskjfklsdj = document.querySelector('input[id="TwitchToolbox-ChangeWrong"]');
                                if(cvdlskjfklsdj){
                                    cvdlskjfklsdj.addEventListener('change',function() {
                                        ChangeWrong = window.getComputedStyle(this.parentNode.querySelector('label[for="TwitchToolbox-ChangeWrong"]'), ":before").content != "none";
                                        GM_setValue("ChangeWrong",ChangeWrong);
                                    },false);
                                }
                                document.querySelector('input[id="TwitchToolbox-AutoMos"]').addEventListener('change',function() {
                                    AutoMOS = window.getComputedStyle(this.parentNode.querySelector('label[for="TwitchToolbox-AutoMos"]'), ":before").content != "none";
                                    GM_setValue("AutoMOS",AutoMOS);
                                },false);
                                document.querySelector('input[id="TwitchToolbox-SaveDeleted"]').addEventListener('change',function() {
                                    SaveDeleted = window.getComputedStyle(this.parentNode.querySelector('label[for="TwitchToolbox-SaveDeleted"]'), ":before").content != "none";
                                    GM_setValue("SaveDeleted",SaveDeleted);
                                },false);
                                document.querySelector('input[id="TwitchToolbox-BetterChat"]').addEventListener('change',function() {
                                    BetterChat = window.getComputedStyle(this.parentNode.querySelector('label[for="TwitchToolbox-BetterChat"]'), ":before").content != "none";
                                    GM_setValue("BetterChat",BetterChat);
                                },false);
                                /*document.querySelector('input[id="TwitchToolbox-AutoTranslate"]').addEventListener('change',function() {
                                    AutoTranslate = window.getComputedStyle(this.parentNode.querySelector('label[for="TwitchToolbox-AutoTranslate"]'), ":before").content != "none";
                                    GM_setValue("AutoTranslate",AutoTranslate);
                                },false);*/
                                document.querySelector('input[id="TwitchToolbox-BTTV"]').addEventListener('change',function() {
                                    IncludeBTTV = window.getComputedStyle(this.parentNode.querySelector('label[for="TwitchToolbox-BTTV"]'), ":before").content != "none";
                                    GM_setValue("IncludeBTTV",IncludeBTTV);
                                    if(IncludeBTTV) betterttv();
                                    else location.reload();
                                },false);
                                document.querySelector('input[id="TwitchToolbox-HideCheer"]').addEventListener('change',function() {
                                    HideCheer = window.getComputedStyle(this.parentNode.querySelector('label[for="TwitchToolbox-HideCheer"]'), ":before").content != "none";
                                    GM_setValue("HideCheer",HideCheer);
                                    if(HideCheer){
                                        document.querySelector('button[data-a-target="bits-button"]').style.visibility = "hidden";
                                        document.querySelector('div.channel-leaderboard').parentNode.style = "height: 0px; overflow: hidden;";
                                        document.querySelector('button[data-a-target="top-nav-get-bits-button"]').parentNode.style = 'display: none;';
                                    }
                                    else{
                                        document.querySelector('button[data-a-target="bits-button"]').style.visibility = "visible";
                                        document.querySelector('div.channel-leaderboard').parentNode.style = "";
                                        document.querySelector('button[data-a-target="top-nav-get-bits-button"]').parentNode.style = 'display: inherit;';
                                    }
                                },false);
                                document.querySelector('input[id="TwitchToolbox-EncodeButton"]').addEventListener('change',function() {
                                    EncodeButton = window.getComputedStyle(this.parentNode.querySelector('label[for="TwitchToolbox-EncodeButton"]'), ":before").content != "none";
                                    GM_setValue("EncodeButton",EncodeButton);
                                    var butt = document.querySelector('button.Toolbox-EncodeButton');
                                    if(!EncodeButton){
                                        butt.style = 'visibility: hidden;width: 0px;margin-right: 0!important;';
                                    }
                                    else{
                                        butt.style = 'background-color: var(--color-background-button-primary-default);';
                                    }
                                    try{
                                        document.querySelector('div[data-a-target="chat-settings-balloon"]').style.marginRight = "-"+(5.3+(emotemenu?3.5:0)+(EncodeButton?3.5:0)+(BrailleBytes?3.5:0))+"rem";
                                    }catch(e){}
                                },false);
                                document.querySelector('input[id="TwitchToolbox-BrailleBytes"]').addEventListener('change',function() {
                                    BrailleBytes = window.getComputedStyle(this.parentNode.querySelector('label[for="TwitchToolbox-BrailleBytes"]'), ":before").content != "none";
                                    GM_setValue("BrailleBytes",BrailleBytes);
                                    var butt = document.querySelector('button.Toolbox-BraileBytesButton');
                                    if(!BrailleBytes){
                                        butt.style = 'visibility: hidden;width: 0px;margin-right: 0!important;';
                                    }
                                    else{
                                        butt.style = 'background-color: var(--color-background-button-primary-default);';
                                    }
                                    try{
                                        document.querySelector('div[data-a-target="chat-settings-balloon"]').style.marginRight = "-"+(5.3+(emotemenu?3.5:0)+(EncodeButton?3.5:0)+(BrailleBytes?3.5:0))+"rem";
                                    }catch(e){}
                                },false);
                                document.querySelector('div.chat-settings').style.overflow = 'hidden';
                            }
                        }else if(n.matches('div[data-a-target="chat-settings-mod-view"]')){
                            n.parentNode.querySelector('div[ext="TwitchToolbox"]').remove();
                        }else if(bttv){
                            try{
                                n.style = 'margin-top: 0 !important;padding-top: 0 !important; transition: all .5s ease-out; height: 0px; overflow: hidden; opacity: 0;';
                                if(Russian){
                                    n.querySelector('p.tw-upcase').innerText = "инструменты bttv"
                                    var translate = {'Set Blacklist Keywords':'Изменить черный список слов','Set Highlight Keywords':'Изменить слова которые выделять','Set Font':'Изменить шрифт','Set Font Size':'Изменить размер шрифта','Clear My Chat':'Очистить чат','BetterTTV Settings':'Настройки BetterTTV'};
                                    n.querySelectorAll('button.tw-interactive').forEach(b => {
                                        if(translate[b.innerText] !== undefined)b.innerText = translate[b.innerText];
                                    });
                                }
                                var stsgs = document.querySelector('div[class="TTBSettings"]');
                                document.querySelector('div.chat-settings').style.overflow = 'hidden';
                                if(!document.querySelector('button[data-a-target="ttb-bttv-button"]')){
                                    var n2div = document.createElement('div');
                                    n2div.classList.add("tw-full-width");
                                    n2div.classList.add("tw-relative");
                                    n2div.innerHTML = '<button class="tw-block tw-border-radius-medium tw-full-width tw-interactable tw-interactable--alpha tw-interactable--hover-enabled tw-interactive" data-a-target="ttb-bttv-button" data-test-selector="ttb-bttv-button"><div class="tw-align-items-center tw-flex tw-pd-05 tw-relative"><div class="tw-flex-grow-1">'+(Russian?'Показать BetterTTV':'Show BetterTTV')+'</div></div></button>';
                                    stsgs.parentNode.insertBefore(n2div,stsgs);
                                    document.querySelector('button[data-a-target="ttb-bttv-button"]').addEventListener('click',function() {
                                        var button = document.querySelector('button[data-a-target="ttb-bttv-button"]');
                                        var sts = document.querySelector('div.bttv-chat-settings');
                                        if(sts){
                                            if(sts.style.height == "0px"){
                                                sts.style = 'transition: all 0.5s ease-out 0s; height: '+(sts.scrollHeight+10)+'px; overflow: hidden; margin-top: 1rem !important; padding-top: 1rem !important; opacity: 1;';

                                                button.querySelector('div[class="tw-flex-grow-1"]').innerText = (Russian?'Скрыть BetterTTV':'Hide BetterTTV');
                                                button.blur();
                                            }
                                            else {
                                                sts.style = "transition: all 0.5s ease-out 0s; height: 0px; overflow: hidden; margin-top: 0 !important; padding-top: 0 !important; opacity: 0;";
                                                button.querySelector('div[class="tw-flex-grow-1"]').innerText = (Russian?'Показать BetterTTV':'Show BetterTTV');
                                                button.blur();
                                            }
                                        }else{
                                            button.remove();
                                        }
                                    },false);
                                }
                            }catch(e){
                                n.style = '';
                            }
                        }
                    }
                });
            }else if(mutation.target.matches('div[data-a-target="viewer-card-positioner"]')){
                mutation.addedNodes.forEach(n => {
                    if(n.matches('div[class="tw-full-height tw-full-width"]')){
                        var H4T = n.querySelector('h4[class="tw-c-text-overlay tw-ellipsis tw-line-clamp-2 tw-word-break-all"]');
                        var Nick = H4T.querySelector('a[target="_blank"]').innerText;
                        var dColor = GM_getValue("NickColor."+Nick,"");
                        var Ico = '<span class="tw-button-icon__icon"><svg x="0px" y="0px" class="changeColor" viewBox="0 0 1000 1000" height="16px" width="16px" style="fill: '+(dColor?dColor:"#ffffff")+';"><g><path d="M953.5,46.5c-48.7-48.7-127.7-48.7-176.4,0l-147,147L589.5,153c-21.3-21.3-55.9-21.3-77.2,0c-21.3,21.3-21.3,55.9,0,77.2l40.6,40.6l-452,452c-22.2,22.2-34.3,50.7-36.2,79.8c-0.8,11.8-3.8,33.8-7.3,57.6c-0.6,3.9-2.3,7.7-5.3,10.7l0,0l-33.8,33.8c-10.8,10.8-10.8,28.4,0,39.2l38,38c10.8,10.8,28.4,10.8,39.2,0l33.8-33.8c3-3,6.8-4.7,10.7-5.3c23.8-3.6,45.8-6.6,57.6-7.3c29.1-2,57.5-14,79.8-36.3l452-452l40.6,40.6c21.3,21.3,55.9,21.3,77.2,0c21.3-21.3,21.3-55.9,0-77.2L712.4,275.9L818,358.4l135.5-135.5C1002.2,174.2,1002.2,95.2,953.5,46.5z M663.9,421L440.3,644.6c-10.8,10.8-28.4,10.8-39.2,0L365.5,609c-10.8-10.8-28.4-10.8-39.2,0l-6.7,6.7l0,0L159.2,776c-3.7,3.7-8.9,4.4-11.7,1.6c-2.8-2.8-2.1-8.1,1.6-11.7l259.6-259.6l0,0L579,336.1c10.8-10.8,28.4-10.8,39.2,0l45.7,45.7C674.7,392.7,674.7,410.2,663.9,421z"></path></g></svg></span>';
                        var ndiv = document.createElement('button');
                        ndiv.innerHTML = Ico;
                        ndiv.style = "margin-top: -2px; float: right;";
                        ndiv.classList.add('tw-button-icon','tw-button-icon--overlay','TwitchToolbox-EditColor');
                        H4T.appendChild(ndiv);
                        var btttttt = document.querySelector('button.TwitchToolbox-EditColor');
                        btttttt.addEventListener('click',function() {
                            var dColor = GM_getValue("NickColor."+Nick,"");
                            var color = prompt('Введите название(white) или код(#ffffff) цвета для '+Nick+', для сброса оставьте пустым.',dColor);
                            if(color === ""){
                                GM_deleteValue("NickColor."+Nick);
                                btttttt.querySelector('svg.changeColor').style.fill = "#ffffff";
                            }else if(color != null){
                                GM_setValue("NickColor."+Nick,color);
                                btttttt.querySelector('svg.changeColor').style.fill = color;
                            }
                        });
                    }
                });
            }else if(mutation.target.matches('title')){
                initLoad();
            }else if(mutation.target.matches('div.chat-input')){
                if(HideCheer){
                    var cheer = document.querySelector('button[data-a-target="bits-button"]');
                    if(cheer)cheer.style.visibility = "hidden";
                }
                chat = document.querySelector('textarea[data-a-target="chat-input"]');
                if(!document.querySelector('button.Toolbox-EncodeButton')){
                    AddEncodeButtons();
                }
            }else if(mutation.target.matches('div.channel-leaderboard-header-first-entry')){
                if(HideCheer){
                    document.querySelector('div.channel-leaderboard').parentNode.style = "height: 0px; overflow: hidden;";
                }
            }else if(mutation.target.parentNode && mutation.target.parentNode.nodeType == Node.ELEMENT_NODE && mutation.target.parentNode.matches('div.top-bar')){
                mutation.addedNodes.forEach(n => {
                    if(CurrentGame != ""){
                        n.querySelector('a[data-a-target="player-info-game-name"]').innerText = CurrentGame;
                        n.querySelector('a[data-a-target="player-info-game-name"]').href = document.querySelector('a[data-a-target="stream-game-link"]').href;
                        n.querySelector('p[data-test-selector="stream-info-card-component__subtitle"]').innerText = document.querySelector('h2[data-a-target="stream-title"]').innerText;
                    }
                });
            }else if(mutation.target.matches('div.chat-room__content')){
                mutation.addedNodes.forEach(n => {
                    if(n.matches('div.tw-z-default') && HideCheer){
                        try{
                            document.querySelector('button[data-a-target="bits-button"]').style.visibility = "hidden";
                            document.querySelector('div.channel-leaderboard').parentNode.style = "height: 0px; overflow: hidden;";
                            document.querySelector('button[data-a-target="top-nav-get-bits-button"]').parentNode.style = 'display: none;';
                        }catch(e){}
                    }
                });
            }
        }else if (mutation.type == 'attributes'){
            if(mutation.target.matches('a[data-a-target="stream-game-link"]')){
                CurrentGame = mutation.target.innerText;
                var pg = document.querySelector('a[data-a-target="player-info-game-name"]');
                if(pg)pg.innerText = CurrentGame;
            }else if(mutation.target.matches('h2[data-a-target="stream-title"]')){
                var pt = document.querySelector('p[data-test-selector="stream-info-card-component__subtitle"]')
                if(pt)pt.innerText = mutation.target.innerText;
            }
        }
    })
})

chatObserver.observe(document.documentElement, {
    attributes: true,
    childList: true,
    subtree: true
})

var encodekey = "TEXT";//todo

var BadgesRight = false;
var BrailleBytes = false;
var EncodeButton = false;
var TranslateButton = false;
var ChangeWrong = true;
var AutoPoints = true;
var AutoMOS = false;
var SaveDeleted = true;
var BetterChat = true;
var HideCheer = false;
var AutoTranslate = false;
var IncludeBTTV = false;
var SaveInput = false;
ReadGMValues();

var bettchtind = false;
var MOSP = 0;
var MOSP2 = 0;
var plascmdcount = [];
var CurrentGame = "";
var Russian = false;
var ChatLanguage = "en";

function ReadGMValues(){
    BadgesRight = GM_getValue("BadgesRight",BadgesRight);
    BrailleBytes = GM_getValue("BrailleBytes",BrailleBytes);
    EncodeButton = GM_getValue("EncodeButton",EncodeButton);
    ChangeWrong = GM_getValue("ChangeWrong",ChangeWrong);
    AutoPoints = GM_getValue("AutoCPoints",AutoPoints);
    AutoMOS = GM_getValue("AutoMOS",AutoMOS);
    SaveDeleted = GM_getValue("SaveDeleted",SaveDeleted);
    BetterChat = GM_getValue("BetterChat",BetterChat);
    HideCheer = GM_getValue("HideCheer",HideCheer);
    AutoTranslate = GM_getValue("AutoTranslate",AutoTranslate);
    TranslateButton = GM_getValue("TranslateButton",TranslateButton);
    IncludeBTTV = GM_getValue("IncludeBTTV",IncludeBTTV);
    SaveInput = GM_getValue("SaveInput",SaveInput);
}
function sendMessage(message){
    var omsg = setInputValue(message);
    document.querySelector('button[data-a-target="chat-send-button"]').click();
    setInputValue(omsg);
}
function httpGet(theUrl)
{
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open( "GET", theUrl, false ); // false for synchronous request
    xmlHttp.send( null );
    return xmlHttp.responseText;
}
function httpPost(theUrl,theData, callback)
{
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open( "POST", theUrl, true ); // false for synchronous request
    xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xmlHttp.send( theData );
    xmlHttp.onreadystatechange = function() {
        if (this.readyState != 4) return;
        callback(xmlHttp.responseText);
    }
}

var chat;
window.onload = function () {
    initLoad();
}
function isEng(t){
    if(!t || 0 === t.length || t.startsWith('!'))return false;
    if(!/[А-я]+/.test(t))return true;
    return t.match(/[А-я]/g).length < (t.length * 0.1);
}
function TranslateTo(text,to, callback){
    httpPost('https://translate.googleapis.com/translate_a/single',
             'client=gtx&sl=auto&tl='+to+'&dt=t&q='+encodeURIComponent(text),
             (x)=>{
        var jsos = JSON.parse(x);
        callback({text:jsos[0][0][0],from:jsos[2]});
    },true);
}
var ruseng = {
    check:function(s){
        return s.match(/\'nj|^z\s|gjyb|^kjk|xt\,e|k\.\,k|\{jnm|gthdsq|bvftn|\svtyz\s|\,kb\;|\,hz\.|gjld|gjllth;bd|bqcr|qcrbq|rfhjxt|rkfc|fcyfz|buhf|sdftn|levf|\[hty|egbk|tplt|\;ty|vjq|pltcm|\,snm|vjukf|xnj|yfd|gjqv|bkb|^j\s|^c\s|^yt|ghj|rfr|dct|vfn|ujh|gjxtve|gjnjv|\]eq|nfr|ghbdtn|nmcz|ncz|djn|ytn|^lf|gjrf|pfxtv|relf|jnkbxyj|\[jhjij|ghfd|ntcn|\[f\[f/i)?s:0;
    },
    decrypt:function(t){
        var xn="qwertyuiop[]asdfghjkl;'zxcvbnm,.`QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>~",
            xt='йцукенгшщзхъфывапролджэячсмитьбюёЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮЁ',
            xo=Array.from(xn+xt),xu=Array.from(xt+xn);
        return Array.from(t).map(function(t){return xo[xu.indexOf(t)]||t}).join("");//xo[xu
    },
};
ruseng.encrypt = ruseng.decrypt;
var chatValue = "";
function initLoad(){
    chat = document.querySelector('textarea[data-a-target="chat-input"]');
    try{
        chat.addEventListener('input',function() {
            chatValue = chat.value;
            //console.log(chatValue);
            //setInputValue(chat_NaE_Value);
        },false);
        chat.addEventListener('focusin',function() {
            //chatValue = chat.value;
            //console.log("f:"+chatValue);
            if(SaveInput)setInputValue(chatValue);
        },false);
        chat.addEventListener('focusout',function() {
            chatValue = chat.value;
            //console.log("f:"+chatValue);
        },false);
    }catch(e){}

    if(chat){
        try {
            if(HideCheer){
                document.querySelector('button[data-a-target="bits-button"]').style.visibility = "hidden";
                document.querySelector('div.channel-leaderboard').parentNode.style = "height: 0px; overflow: hidden;";
                document.querySelector('button[data-a-target="top-nav-get-bits-button"]').parentNode.style = 'display: none;';
            }
        }catch (err) {}
        Russian = document.querySelector('h5[data-test-selector="chat-room-header-label"]').innerText == "ЧАТ ТРАНСЛЯЦИИ";
        ChangeWrong = GM_getValue("ChangeWrong",Russian);
        setTimeout(function () {
            var gamenode = document.querySelector('a[data-a-target="stream-game-link"]');
            if(gamenode)CurrentGame = gamenode.innerText;
        },1000);
        if(!document.querySelector('button.Toolbox-EncodeButton')){
            AddEncodeButtons();
        }
        if(IncludeBTTV && !document.querySelector('script[class="Toolbox-BetterTTV"]')) betterttv();
    }
    else setTimeout(initLoad,1000);
}
function AddEncodeButtons(){
    var csbutt = document.querySelector('button[data-a-target="chat-settings"]');
    var ndddd = document.createElement('button');
    var toins = csbutt.parentNode.parentNode.parentNode.parentNode.nextSibling;
    ndddd.classList.add("Toolbox-EncodeButton");//
    ndddd.classList.add("tw-core-button");ndddd.classList.add("tw-button-icon");
    ndddd.classList.add("tw-mg-r-05");ndddd.classList.add("tw-core-button--primary");ndddd.classList.add("tw-align-middle");
    ndddd.style = "background-color: var(--color-background-button-primary-default);";
    ndddd.innerHTML = '<span class="tw-button-icon__icon" style="width: 1.5rem; height: 1.5rem;">🔒</span>';
    //console.log(toins);
    toins.insertBefore(ndddd,toins.lastChild);
    ndddd.addEventListener('click',function() {
        if(chat.value != ""){
            setInputValue(encoding.encrypt(chat.value,encodekey));
            document.querySelector('button[data-a-target="chat-send-button"]').click();
        }
    },false);
    ndddd.addEventListener("mouseover", function() {
        if(encoding.encrypt(chat.value,encodekey).length > 500) document.querySelector('button.Toolbox-EncodeButton').disabled="something";
    },false);
    if(!EncodeButton){
        ndddd.style = 'visibility: hidden;width: 0px;margin-right: 0!important;';
    }
    ndddd = document.createElement('button');
    ndddd.classList.add("Toolbox-BraileBytesButton");//
    ndddd.classList.add("tw-core-button");ndddd.classList.add("tw-button-icon");
    ndddd.classList.add("tw-mg-r-05");ndddd.classList.add("tw-core-button--primary");ndddd.classList.add("tw-align-middle");
    ndddd.style = "background-color: var(--color-background-button-primary-default);";
    ndddd.innerHTML = '<span class="tw-button-icon__icon" style="width: 1.5rem; height: 1.5rem;color: red;">⣿</span>';
    toins.insertBefore(ndddd,toins.lastChild);
    ndddd.addEventListener('click',function() {
        if(chat.value != ""){
            setInputValue(brailebytes.encrypt(chat.value,encodekey));
            document.querySelector('button[data-a-target="chat-send-button"]').click();
        }
    },false);
    ndddd.addEventListener("mouseover", function() {
        if(brailebytes.encrypt(chat.value,encodekey).length > 500) document.querySelector('button.Toolbox-BraileBytesButton').disabled=true;
    },false);
    if(!BrailleBytes){
        ndddd.style = 'visibility: hidden;width: 0px;margin-right: 0!important;';
    }

    toins.addEventListener("mouseleave", function() {
        document.querySelector('button.Toolbox-EncodeButton').disabled=false;
        document.querySelector('button.Toolbox-BraileBytesButton').disabled=false;
    },false);
    /*ndddd = document.createElement('button');
    ndddd.classList.add("Toolbox-TranslateButton");//
    ndddd.classList.add("tw-core-button");ndddd.classList.add("tw-button-icon");
    ndddd.classList.add("tw-mg-r-05");ndddd.classList.add("tw-core-button--primary");ndddd.classList.add("tw-align-middle");
    ndddd.innerHTML = '<span class="tw-button-icon__icon" style="width: 1.5rem; height: 1.5rem;">🌐</span>';
    csbutt.parentNode.parentNode.parentNode.nextSibling.insertBefore(ndddd,csbutt.parentNode.parentNode.parentNode.nextSibling.lastChild);
    ndddd.addEventListener('click',function() {
        if(chat.value != ""){
            TranslateTo(chat.value,ChatLanguage,(x)=>{
                //console.log(x,chat.value);
                setInputValue(x.text);
                document.querySelector('button[data-a-target="chat-send-button"]').click();
            });
        }
    },false);
    if(!TranslateButton){
        //ndddd.style = 'visibility: hidden;width: 0px;margin-right: 0!important;';
    }*/
}
var encoding = {
    chars: ["̀","́","̂","̃","̄","̅","̆","̇","̈","̉","̊","̋","̌","̍","̎","̏","̐","̑","ͣ","ͤ","ͥ","ͦ","ͧ","ͨ","ͩ","ͪ","ͫ","ͬ","ͭ","ͮ","ͯ"],
    prefix:"ⁱₐ",
    separator:"′.,:;'₀ ",
    separators:"ҽɳƈσdҽd",
    check:function(t){
        return new RegExp("^\\"+encoding.prefix.split("").join('\\')+"(["+encoding.chars.join("")+encoding.separator.replace(" ","\\s")+encoding.separators.replace(" ","\\s")+"]*)$","gi").test(t);
    },
    decrypt:function(ta,key){
        try{
            var t = ta.substr(encoding.prefix.length).split(new RegExp("["+encoding.separator.replace(" ","\\s")+encoding.separators.replace(" ","\\s")+"\\w]")).clean("")
            .map(function(a){
                return ToNum(a,encoding.chars);//.split("")
            });
            t = decodeURIComponent(byteArrayToString(t));
            return (t);
        }catch(e){
            console.log(e);
            return false;
        }
    },
    encrypt:function(t,key){
        t = toUTF8Array(t)
            .map(function(a){
            return ToStr(a,encoding.chars);//.split("")
        });
        return encoding.prefix + t.map(function(elem, index){
            return elem + (index < encoding.separators.length?encoding.separators[index]:encoding.separator[getRandomInt(encoding.separator.length-1)]);
        }).join('');
    }
};
//console.log('⠀'.charCodeAt(0));

var brailebytes = {
    chars: ['⠀','⠁','⠂','⠃','⠄','⠅','⠆','⠇','⠈','⠉','⠊','⠋','⠌','⠍','⠎','⠏','⠐','⠑','⠒','⠓','⠔','⠕','⠖','⠗','⠘','⠙','⠚','⠛','⠜','⠝','⠞','⠟','⠠','⠡','⠢','⠣','⠤','⠥','⠦','⠧','⠨','⠩','⠪','⠫','⠬','⠭','⠮','⠯','⠰','⠱','⠲','⠳','⠴','⠵','⠶','⠷','⠸','⠹','⠺','⠻','⠼','⠽','⠾','⠿','⡀','⡁','⡂','⡃','⡄','⡅','⡆','⡇','⡈','⡉','⡊','⡋','⡌','⡍','⡎','⡏','⡐','⡑','⡒','⡓','⡔','⡕','⡖','⡗','⡘','⡙','⡚','⡛','⡜','⡝','⡞','⡟','⡠','⡡','⡢','⡣','⡤','⡥','⡦','⡧','⡨','⡩','⡪','⡫','⡬','⡭','⡮','⡯','⡰','⡱','⡲','⡳','⡴','⡵','⡶','⡷','⡸','⡹','⡺','⡻','⡼','⡽','⡾','⡿','⢀','⢁','⢂','⢃','⢄','⢅','⢆','⢇','⢈','⢉','⢊','⢋','⢌','⢍','⢎','⢏','⢐','⢑','⢒','⢓','⢔','⢕','⢖','⢗','⢘','⢙','⢚','⢛','⢜','⢝','⢞','⢟','⢠','⢡','⢢','⢣','⢤','⢥','⢦','⢧','⢨','⢩','⢪','⢫','⢬','⢭','⢮','⢯','⢰','⢱','⢲','⢳','⢴','⢵','⢶','⢷','⢸','⢹','⢺','⢻','⢼','⢽','⢾','⢿','⣀','⣁','⣂','⣃','⣄','⣅','⣆','⣇','⣈','⣉','⣊','⣋','⣌','⣍','⣎','⣏','⣐','⣑','⣒','⣓','⣔','⣕','⣖','⣗','⣘','⣙','⣚','⣛','⣜','⣝','⣞','⣟','⣠','⣡','⣢','⣣','⣤','⣥','⣦','⣧','⣨','⣩','⣪','⣫','⣬','⣭','⣮','⣯','⣰','⣱','⣲','⣳','⣴','⣵','⣶','⣷','⣸','⣹','⣺','⣻','⣼','⣽','⣾','⣿',],
    check: function(t){
        return new RegExp("^["+brailebytes.chars.join("")+"]*$","gi").test(t);
    },
    decrypt: function(ta,key){
        try{
            var t = ta.split("")
            .map(function(a){
                return brailebytes.chars.indexOf(a);//.split("")
            });
            t = decodeURIComponent(byteArrayToString(t));
            return (t);
        }catch(e){
            console.log(e);
            return false;
        }
    },
    encrypt: function(t,key){
        t = toUTF8Array(t)
            .map(function(a){
            return brailebytes.chars[a];//.split("")
        });
        return t.join('');
    }
};
function ToNum(a,cc){
    var n = 0;
    a = String(a);
    for(var i = 0;i < a.length;i++){
        n = n +(cc.indexOf(a.substr(a.length-i-1,1))*Math.pow(cc.length,i));
    };
    return n;
};
function ToStr(a,cc){
    var s = "";
    while(a > 0){
        s = String(s) + cc[a%(cc.length)];
        a = Math.floor(a/(cc.length));
    }
    return Array.from(s).reverse().join("");
};
function wordToByteArray(wordArray) {
    var byteArray = [], word, i, j;
    for (i = 0; i < wordArray.length; ++i) {
        word = wordArray[i];
        for (j = 3; j >= 0; --j) {
            byteArray.push((word >> 8 * j) & 0xFF);
        }
    }
    return byteArray;
}
function byteArrayToString(byteArray) {
    var str = "", i;
    for (i = 0; i < byteArray.length; ++i) {
        str += escape(String.fromCharCode(byteArray[i]));
    }
    return str;
}
function toUTF8Array(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;
}

function setInputValue(msg) {
    if(!chat){
        chat = document.querySelector('textarea[data-a-target="chat-input"]');
    }
    var omsg = chat.value;
    chat.focus();
    chat.value = msg;
    chat.dispatchEvent(new Event('input', {bubbles: true}));
    var reactInstance = getReactInstance(chat);
    if (!reactInstance) return;
    var props = reactInstance.memoizedProps;
    if (props && props.onChange) {
        props.onChange({target: chat});
    }
    return omsg;
}

function getReactInstance(element) {
    for (var key in element) {
        if (key.startsWith('__reactInternalInstance$')) {
            return element[key];
        }
    }

    return null;
}
function getRandomInt(max) {
    return Math.floor(Math.random() * Math.floor(max));
}
Array.prototype.clean = function(deleteValue) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] == deleteValue) {
            this.splice(i, 1);
            i--;
        }
    }
    return this;
};
function betterttv() {
    var script = document.createElement('script');
    //script.type = 'text/javascript';
    script.src = 'https://cdn.betterttv.net/betterttv.js';
    script.classList.add("Toolbox-BetterTTV");
    var head = document.getElementsByTagName('head')[0];
    if (!head) return;
    head.appendChild(script);
}
function setTwitchFont(fontName){
    var body = document.getElementsByTagName('body')[0];
    body.style = '--font-base: "'+fontName+'","Inter","Roobert","Helvetica Neue",Helvetica,Arial,sans-serif;';
}