Raw Source
walex6221gmail.com / CW: Shed

// ==UserScript==
// @name         CW: Shed
// @version      1.2.3
// @description  Сборник небольших дополнений к игре CatWar
// @author       ReiReiRei
// @copyright    2020, Ленивый (https://catwar.su/cat930302)
// @license      MIT; https://opensource.org/licenses/MIT
// @updateURL    https://openuserjs.org/meta/ReiReiRei/CWShed.meta.js
// @include      https://catwar.su/*
// @grant        GM_xmlhttpRequest
// @grant        GM.xmlHttpRequest
// @require      https://code.jquery.com/jquery-3.4.1.min.js
// @require https://code.jquery.com/ui/1.12.1/jquery-ui.js
// ==/UserScript==

(function (win, $) {
  'use strict';
  if (typeof $ === 'undefined') return;
  /*
  Изменения 1.2.3
  1. Фикс опускания котов вниз клетки на телефонах
  
  Изменения 1.2.2
  1. Возможность включить сокращенный лог бр - вместо "Я => Имя (хвост) Я => Имя (хвост)" будет показывать "Я => Имя (хвост) (х2)".

  Изменения 1.2.1
  1. Возможность перетаскивать лог бр можно выключить (на телефонах из-за неё слишком близко Т+3 к кнопке атаки)

  Изменения 1.2
  1. Возможность перетаскивать лог бр за ярлычок слева от замочка блока.
  2. Новые звуки на большинство уведомлений (точнее на все, кроме нападения. На новые ЛС/Чат поставлен варовский звук нового сообщения в чате)
  3. Возможность ставить до 3 ников в чате, которые будут выделяться так, будто вас позвали по имени. Регистр не важен. Возможно, добавит лагов при спаме в чат.
  4. Возможность опустить котов в нижний левый угол клетки. Стрелки опускаются вместе с котами, но области удара - нет, поэтому у мелких горло будет в районе морды, а у крупных - на животе. (я не знаю, зачем оно вообще нужно, бесполезная штука...)
  5. Фикс ЛС (раньше звук был, когда меняется количество новых ЛС/Чата, теперь только когда это количество становится больше)
  */
  //Настройки + умолчания глобальные
  const globals = {}; //Настройки
  globals.on_actNotif = getSettings('on_actNotif') === null ? false : getSettings('on_actNotif'); //Выключены по умолчанию: уведомления на действия (из-за конфликта с Варомодом)
  globals.on_newDM = getSettings('on_newDM') === null ? false : getSettings('on_newDM'); //Выключены по умолчанию: уведомления на новые лс
  globals.on_newChat = getSettings('on_newChat') === null ? false : getSettings('on_newChat'); //Выключены по умолчанию: уведомления на новое соо в чате (не игровой)
  globals.on_chatMention = getSettings('on_chatMention') === null ? false : getSettings('on_chatMention'); //Выключены по умолчанию: уведомления на упоминание имени в чате
  globals.on_idDM = getSettings('on_idDM') === null ? true : getSettings('on_idDM'); //Включены по умолчанию: ID в личных сообщениях+++
  globals.on_idProf = getSettings('on_idProf') === null ? true : getSettings('on_idProf'); //Включены по умолчанию: ID в профилях+++
  globals.on_idCatMouth = getSettings('on_idCatMouth') === null ? true : getSettings('on_idCatMouth'); //Включены по умолчанию: ID котов во рту при выборе+++
  globals.on_idItemMouth = getSettings('on_idItemMouth') === null ? true : getSettings('on_idItemMouth'); //Включены по умолчанию: ID предметов (и уникальные, и обычные) + инфо+++
  globals.on_idChat = getSettings('on_idChat') === null ? true : getSettings('on_idChat'); //Включены по умолчанию: ID в чате Игровой+++
  globals.on_teamFights = getSettings('on_teamFights') === null ? false : getSettings('on_teamFights'); //Выключены по умолчанию: Команды в боережиме
  globals.on_huntText = getSettings('on_huntText') === null ? true : getSettings('on_huntText'); //Включена по умолчанию: Охота с текстом движения дичи
  globals.on_huntMobile = getSettings('on_huntMobile') === null ? true : getSettings('on_huntMobile'); //Включен по умолчанию: Стиль, фиксящий охоту на телефонах
  globals.on_cleanerHistory = getSettings('on_cleanerHistory') === null ? false : getSettings('on_cleanerHistory'); //Выключен по умолчанию: лог чистки
  globals.on_charChange = getSettings('on_charChange') === null ? false : getSettings('on_charChange'); //Выключен по умолчанию: список персонажей
  globals.on_catsDown = getSettings('on_catsDown') === null ? false : getSettings('on_catsDown'); //Выключен по умолчанию: коты внизу клетки
  globals.on_nickHighlight = getSettings('on_nickHighlight') === null ? false : getSettings('on_nickHighlight'); //Выключен по умолчанию: подсвечивание (кастомных) имен в чате
  globals.on_moveFightLog = getSettings('on_moveFightLog') === null ? false : getSettings('on_moveFightLog'); //Выключен по умолчанию: кнопка (и возможность) перемещения лога бр
  globals.on_shortFightLog = getSettings('on_shortFightLog') === null ? false : getSettings('on_shortFightLog'); //Выключен по умолчанию: сокращение лога бр
  //Звуки
  globals.sound_notifEaten = getSettings('sound_notifEaten') === null ? 0.2 : getSettings('sound_notifEaten'); //Звук, когда тебя подняли
  globals.sound_notifBeaten = getSettings('sound_notifBeaten') === null ? 0.2 : getSettings('sound_notifBeaten'); //Звук, когда тебя атакуют
  globals.sound_notifEndAct = getSettings('sound_notifEndAct') === null ? 0.1 : getSettings('sound_notifEndAct'); //Звук, когда заканчивается действие + текст действия
  globals.sound_newDM = getSettings('sound_newDM') === null ? 0.1 : getSettings('sound_newDM'); //Звук при получении ЛС
  globals.sound_newChat = getSettings('sound_newChat') === null ? 0.1 : getSettings('sound_newChat'); //Звук при получении соо в Чате
  globals.sound_chatMention = getSettings('sound_chatMention') === null ? 0.3 : getSettings('sound_chatMention'); //Звук при упоминании имени игрока в чате (жёлтым)
  //Настройки лога чистки
  globals.clean_id = getSettings('clean_id') === null ? true : getSettings('clean_id'); //Писать в логе ID поднятого
  globals.clean_location = getSettings('clean_location') === null ? true : getSettings('clean_location'); //Писать в логе локацию, где подняли и где отпустили
  globals.clean_action = getSettings('clean_action') === null ? false : getSettings('clean_action'); //Писать в логе ВСЕ действия, которые можно совершить с котом (проверка на действие)
  //Массивы
  globals.charListArray = getSettings('charListArray') === null ? [] : JSON.parse(getSettings('charListArray')); //Список персонажей игрока в игровой
  globals.cm_blocked = getSettings('cm_blocked') === null ? [] : JSON.parse(getSettings('cm_blocked')); //Список игроков, от которых не получать уведомления на упоминание в чате
  globals.nickListArray = getSettings('nickListArray') === null ? [] : JSON.parse(getSettings('nickListArray')); //Список персонажей игрока в игровой
  //Настройки команд в БР
  globals.tf_max_height = getSettings('tf_max_height') === null ? 100 : getSettings('tf_max_height'); //макс высота блока с командами
  globals.fight_log_max_height = getSettings('fight_log_max_height') === null ? 70 : getSettings('fight_log_max_height'); //макс высота блока с командами
  globals.tf_color_g_team2 = getSettings('tf_color_g_team2') === null ? "#429dde" : getSettings('tf_color_g_team2'); //зелёный цвет команды 2 в командах бр
  globals.tf_color_g_team3 = getSettings('tf_color_g_team3') === null ? "#f6c739" : getSettings('tf_color_g_team3'); //зелёный цвет команды 3 в командах бр
  globals.tf_color_g_team4 = getSettings('tf_color_g_team4') === null ? "#ee91d7" : getSettings('tf_color_g_team4'); //зелёный цвет команды 4 в командах бр
  globals.tf_color_r_team2 = getSettings('tf_color_r_team2') === null ? "#cd4141" : getSettings('tf_color_r_team2'); //красный цвет команды 2 в командах бр
  globals.tf_color_r_team3 = getSettings('tf_color_r_team3') === null ? "#cd4141" : getSettings('tf_color_r_team3'); //красный цвет команды 3 в командах бр
  globals.tf_color_r_team4 = getSettings('tf_color_r_team4') === null ? "#cd4141" : getSettings('tf_color_r_team4'); //красный цвет команды 4 в командах бр
  //Умолчания действий (УВЕДОМЛЕНИЯ)
  globals.notif_eaten = getSettings('notif_eaten') === null ? true : getSettings('notif_eaten'); //Уведомлять, когда тебя съели
  globals.notif_attack = getSettings('notif_attack') === null ? false : getSettings('notif_attack'); //Уведомлять, когда тебя ввели в БР через Т2/Т3
  //Умолчания действий - ЗВУК
  globals.snd_act_move = getSettings('snd_act_move') === null ? true : getSettings('snd_act_move'); //Переход
  globals.snd_act_eat = getSettings('snd_act_eat') === null ? false : getSettings('snd_act_eat'); //Еда
  globals.snd_act_need = getSettings('snd_act_need') === null ? true : getSettings('snd_act_need'); //Нужда
  globals.snd_act_drink = getSettings('snd_act_drink') === null ? true : getSettings('snd_act_drink'); //Жажда
  globals.snd_act_dig = getSettings('snd_act_dig') === null ? true : getSettings('snd_act_dig'); //Копать
  globals.snd_act_sleep = getSettings('snd_act_sleep') === null ? true : getSettings('snd_act_sleep'); //Спать
  globals.snd_act_sniff = getSettings('snd_act_sniff') === null ? true : getSettings('snd_act_sniff'); //Нюхать
  globals.snd_act_digin = getSettings('snd_act_digin') === null ? true : getSettings('snd_act_digin'); //Закапывать
  globals.snd_act_clean = getSettings('snd_act_clean') === null ? true : getSettings('snd_act_clean'); //Вылизывать(ся)
  globals.snd_act_swim = getSettings('snd_act_swim') === null ? true : getSettings('snd_act_swim'); //Поплавать
  globals.snd_act_murr = getSettings('snd_act_murr') === null ? true : getSettings('snd_act_murr'); //Помурлыкать
  globals.snd_act_tails = getSettings('snd_act_tails') === null ? false : getSettings('snd_act_tails'); //Переплести хвосты
  globals.snd_act_cheek = getSettings('snd_act_cheek') === null ? false : getSettings('snd_act_cheek'); //Потереться щекой о щёку
  globals.snd_act_ground = getSettings('snd_act_ground') === null ? false : getSettings('snd_act_ground'); //Повалять по земле
  globals.snd_act_rub = getSettings('snd_act_rub') === null ? false : getSettings('snd_act_rub'); //Потереться носом о нос
  globals.snd_act_calm = getSettings('snd_act_calm') === null ? false : getSettings('snd_act_calm'); //Выход из бр
  //Умолчания действий - ТЕКСТ
  globals.txt_act_move = getSettings('txt_act_move') === null ? true : getSettings('txt_act_move'); //Переход
  globals.txt_act_eat = getSettings('txt_act_eat') === null ? true : getSettings('txt_act_eat'); //Еда
  globals.txt_act_need = getSettings('txt_act_need') === null ? true : getSettings('txt_act_need'); //Нужда
  globals.txt_act_drink = getSettings('txt_act_drink') === null ? true : getSettings('txt_act_drink'); //Жажда
  globals.txt_act_dig = getSettings('txt_act_dig') === null ? true : getSettings('txt_act_dig'); //Копать
  globals.txt_act_sleep = getSettings('txt_act_sleep') === null ? true : getSettings('txt_act_sleep'); //Спать
  globals.txt_act_sniff = getSettings('txt_act_sniff') === null ? true : getSettings('txt_act_sniff'); //Нюхать
  globals.txt_act_digin = getSettings('txt_act_digin') === null ? true : getSettings('txt_act_digin'); //Закапывать
  globals.txt_act_clean = getSettings('txt_act_clean') === null ? true : getSettings('txt_act_clean'); //Вылизывать(ся)
  globals.txt_act_swim = getSettings('txt_act_swim') === null ? true : getSettings('txt_act_swim'); //Поплавать
  globals.txt_act_murr = getSettings('txt_act_murr') === null ? true : getSettings('txt_act_murr'); //Помурлыкать
  globals.txt_act_tails = getSettings('txt_act_tails') === null ? true : getSettings('txt_act_tails'); //Переплести хвосты
  globals.txt_act_cheek = getSettings('txt_act_cheek') === null ? true : getSettings('txt_act_cheek'); //Потереться щекой о щёку
  globals.txt_act_ground = getSettings('txt_act_ground') === null ? true : getSettings('txt_act_ground'); //Повалять по земле
  globals.txt_act_rub = getSettings('txt_act_rub') === null ? true : getSettings('txt_act_rub'); //Потереться носом о нос
  globals.txt_act_calm = getSettings('txt_act_calm') === null ? false : getSettings('txt_act_calm'); //Выход из бр

  const sounds = {};
  sounds.new_message = 'https://catwar.su/new_message.mp3';
  sounds.action_notif = 'https://abstract-shed.site/cwm_catalog/action_end.mp3';
  sounds.chat_mention = 'https://abstract-shed.site/cwm_catalog/chat_mention.mp3';
  sounds.alert_attacked = 'https://d.zaix.ru/ihrv.mp3';

  function getSettings(key) { //Получение настроек
    let setting = 'cws_sett_' + key;
    let val = win.localStorage.getItem(setting);
    switch (val) {
      case null:
        return null;
      case 'true':
        return true;
      case 'false':
        return false;
      default:
        return val;
    }
  }

  function addCSS(css) {
    $('head').append(`<style>${css}</style>`);
  }
  //Проверка URL (чтобы не подключать ID в ЛС на Игровую, зачем тебе ЛС в Игровой, там нет ЛС, очнись)
  const pageurl = window.location.href;
  const isCW3 = (/^https:\/\/catwar.su\/cw3(?!(\/kns|\/jagd))/.test(pageurl));
  const isProfile = (/^https:\/\/catwar.su\/cat(\d+|\/.+)/.test(pageurl));
  const isDM = (/^https:\/\/catwar.su\/ls/.test(pageurl));
  const isHunt = (/^https:\/\/catwar.su\/cw3\/jagd/.test(pageurl));
  const isSett = (pageurl === 'https://catwar.su/cwshedmod');
  const isMyCat = (pageurl === 'https://catwar.su/');

  function footerLink() {
    $("#footer").ready(function () {
      if ($("#footer").length) {
        $(`<span> | <a href="/cwshedmod">CW:Shed</a></span>`).insertAfter($("#footer > a[href='/mobile']"));
      }
    });
  }
  try {
    footerLink();
    if (isCW3) cw3();
    if (isProfile) profile();
    if (isDM) dm();
    if (isSett) sett();
    if (isHunt) hunt();
    if (isMyCat) myCat();
  }
  catch (err) {
    win.console.error('CW:Shed error: ', err);
  }

  function cw3() { //Игровая
    if (globals.on_catsDown) { //опускаем котов вниз вместе со стрелами
      $(document).ready(function () {
        $('head').append(`<style>
.d, .d div {
  background-position: left bottom;
}
.catWithArrow {
  display: flex;
  flex-direction: column;
}
.catWithArrow > .cat {
  order: -1;
}
.catWithArrow > div {
  top: 10px;
}
.mouth {
  max-width: 160px;
}</style>`);
        $("body").on('DOMSubtreeModified DOMNodeInserted', '.catWithArrow', function (e) {
          let $arrow = $(this).find('.arrow');
          let topval = $arrow.css('top');
          if (topval) {
            let int_topval = parseInt(topval.replace('px', ''));
            if (int_topval > 0) {
              $arrow.css('bottom', topval);
              $arrow.css('top', '');
            }
          }
        });
      });
    }
    $('.small').first().append(` | <a href="https://catwar.su/cwshedmod">CW:Shed</a>`); //Настройки мода
    if (globals.on_charChange && globals.charListArray.length) {
      let CCArray = [];
      $.each(globals.charListArray, function (index, obj) {
        CCArray.push(`<a href="/login2?id=${obj.id}">${obj.name}</a>`);
      });
      $('.small').first().append(` | Персонажи: <span style="background: rgba(255, 255, 255, 0.25);">${CCArray.join(' | ')} </span>`);
    }
    if (globals.on_newDM) {
      let newDM = 0;
      $('body').on('DOMSubtreeModified', '#newls', function () {
        let newDMtmp = $(this).html();
        if (newDMtmp !== undefined) {
          newDMtmp = (newDMtmp === '') ? 0 : parseInt(newDMtmp.replace(/\D/gi, ''));
          if (newDMtmp > newDM) {
            let audio = new Audio();
            audio.src = sounds.new_message;
            audio.volume = globals.sound_newDM;
            audio.play();
          }
          newDM = newDMtmp;
        }
      });
    }
    if (globals.on_newChat) {
      let newChat = 0;
      $('body').on('DOMSubtreeModified', '#newchat', function () {
        let newChattmp = $(this).html();
        if (newChattmp !== undefined) {
          newChattmp = (newChattmp === '') ? 0 : parseInt(newChattmp.replace(/\D/gi, ''));
          if (newChattmp > newChat) {
            let audio = new Audio();
            audio.src = sounds.new_message;
            audio.volume = globals.sound_newChat;
            audio.play();
          }
          newChat = newChattmp;
        }
      });
    }
    if (globals.on_chatMention || globals.on_nickHighlight) {
      let myname_count = 0;
      $(document).ready(function () {
        $("#chat_msg").on('DOMNodeInserted', function (e) {
          if (e.target.children !== undefined && e.target.children.length == 2) {
            if (globals.on_nickHighlight) {
              $('#chat_msg .chat_text > span:first-child').each(function () {
                let html = $(this).html();
                let changed = false;
                $.each(globals.nickListArray, function (index, key) {
                  let expr = new RegExp('^(' + key + ')[^А-ЯЁёA-Za-z0-9]|[^А-ЯЁёA-Za-z0-9>](' + key + ')[^А-ЯЁёA-Za-z0-9<]|[^А-ЯЁёA-Za-z0-9](' + key + ')$|^(' + key + ')$', "ig");
                  if (html.match(expr)) { //есть имя и оно ещё не внутри тега
                    changed = true;
                    let matchAll = html.matchAll(expr);
                    matchAll = Array.from(matchAll); // теперь массив
                    $.each(matchAll, function (index, value) {
                      let replacer = value[1] || value[2] || value[3] || value[4]; //То, что было найдено
                      html = html.replace(value[0], value[0].replace(replacer, '<span class=myname>' + replacer + '</span>'));
                    });
                  }
                });
                if (changed) $(this).html(html);
              });
            }
            if (globals.on_chatMention) {
              if (myname_count < $('.myname').length) {
                myname_count = $('.myname').length;
                let caller = $('.myname').first().closest('tr').find('td:last-child a:first-child').attr('href') || 0;
                caller = parseInt(caller.replace(/\D/g, ''));
                let is_bot = $('.myname').first().closest('tr').find('i').length;
                if (jQuery.inArray(caller, globals.cm_blocked) == -1 && !is_bot) { //ЕСЛИ НЕ В МАССИВЕ ИГНОРИРУЕМЫХ и не бот
                  let audio = new Audio();
                  audio.src = sounds.chat_mention;
                  audio.volume = globals.sound_chatMention;
                  audio.play();
                }
              }
            }
          }
        });
      });
    }
    if (globals.on_idChat) { //Включена опция
      let i_chat = 0;
      let myname_count = $('.myname').length;
      $(document).ready(function () { // ДОБАВЛЕНИЕ АЙДИ ПОСЛЕ ИМЕН В ЧАТЕ ИГРОВОЙ
        $("#chat_msg").on('DOMNodeInserted', function (e) {
          if (e.target.children !== undefined && e.target.children.length == 2) {
            if (i_chat != $('#chat_msg > span').length) {
              $('#chat_msg > span').each(function () {
                let id = "[" + $(this).find('a[href*="/cat"]').attr('href').slice(4) + "]";
                if (!$(this).find('.mod_id').length && !$(this).hasClass('mod_id')) { //Если надписи еще нет (второе для ботов, т.к. там b ник + span кому говорит .nick:not([style*='italic'])
                  $(`<span class=mod_id_wrap> <i class=mod_id>${id}</i></span>`).insertAfter($(this).find('.nick:not([style*="italic"])'));
                  //только на последнее сообщение / сгенерированные при загрузке стр/локи / не "молчаливый" бот
                }
                else if ($(this).find('.mod_id').html() !== (id)) {
                  if ($(this).find('.nick[style*="italic"]').length) { //не "молчаливый" бот
                    id = "";
                  }
                  $(this).find('.mod_id').html(id);
                }
              });
            }
            i_chat = $('#chat_msg > span').length; //Убирает дубли, потому что система добавления нового сообщения на варе очень хорошая
          }
        });
      });
    }
    if (globals.on_idItemMouth) {
      let item_names_json = {};
      $.post("https://abstract-shed.site/cwm_catalog/item_names.json?" + Date.now(), {}, function (response) { //Подгрузка имен предметов из json файла с сервера сайта
        item_names_json = response;
      });
      $(document).ready(function () {
        $("#thdey > ul").append('<li>Название предмета: <span id=item_name_ide>[ Неизвестно ]</span> [<span id=item_id_ide>?</span>]</li><li>Уникальный ID: <span id=item_uq_id_ide>[ Неизвестно ]</span></li>');
        $("body").on('click', "#itemList .itemInMouth", function () {
          if (!$(this).hasClass("active_thing")) {
            let uq_id = $(this).attr('id');
            $("#item_uq_id_ide").html(uq_id);
            let item_id = $(this).find("img").attr("src").replace(/\D/g, "");
            let name = item_names_json[item_id] || "[ Неизвестно ]";
            $("#item_name_ide").html(name);
            $("#item_id_ide").html(item_id);
          }
        });
      });
    }
    if (globals.on_idCatMouth) {
      $(document).ready(function () {
        $("#ctdey > ul").append('<li>ID кота: <span id=cat_id_ide>[ Не определено ]</span></li>');
        $("body").on('click', "#itemList .catrot", function () {
          if (!$(this).hasClass("active_thing")) {
            $("#cat_id_ide").html($(this).attr('id'));
          }
        });
      });
    }
    if (globals.on_actNotif) {
      function which_action(text) {
        let wh_act = {
          txt: null,
          snd: false
        };
        if (text.indexOf("Переход") !== -1) {
          if (globals.txt_act_move) wh_act.txt = "Переход";
          if (globals.snd_act_move) wh_act.snd = true;
          return wh_act;
        }
        if (text.indexOf(" дичь") !== -1) {
          if (globals.txt_act_eat) wh_act.txt = "Поедание дичи";
          if (globals.snd_act_eat) wh_act.snd = true;
          return wh_act;
        }
        if (text.indexOf("Делаем свои дела") !== -1) {
          if (globals.txt_act_need) wh_act.txt = "Справление нужды";
          if (globals.snd_act_need) wh_act.snd = true;
          return wh_act;
        }
        if (text.indexOf("Пьём ещё") !== -1) {
          if (globals.txt_act_drink) wh_act.txt = "Питьё";
          if (globals.snd_act_drink) wh_act.snd = true;
          return wh_act;
        }
        if (text.indexOf("Копать") !== -1) {
          if (globals.txt_act_dig) wh_act.txt = "Копание";
          if (globals.snd_act_dig) wh_act.snd = true;
          return wh_act;
        }
        if (text.indexOf("Сон") !== -1) {
          if (globals.txt_act_sleep) wh_act.txt = "Сон";
          if (globals.snd_act_sleep) wh_act.snd = true;
          return wh_act;
        }
        if (text.indexOf("нюх") !== -1) {
          if (globals.txt_act_sniff) wh_act.txt = "Нюх";
          if (globals.snd_act_sniff) wh_act.snd = true;
          return wh_act;
        }
        if (text.indexOf("Закапывать") !== -1) {
          if (globals.txt_act_digin) wh_act.txt = "Закапывание";
          if (globals.snd_act_digin) wh_act.snd = true;
          return wh_act;
        }
        if (text.indexOf("Вылизывать") !== -1) {
          if (globals.txt_act_clean) wh_act.txt = "Вылизывание";
          if (globals.snd_act_clean) wh_act.snd = true;
          return wh_act;
        }
        if (text.indexOf("Плавать") !== -1) {
          if (globals.txt_act_swim) wh_act.txt = "Плавание";
          if (globals.snd_act_swim) wh_act.snd = true;
          return wh_act;
        }
        if (text.indexOf("Мурлыкать") !== -1) {
          if (globals.txt_act_murr) wh_act.txt = "Мурлыкаем";
          if (globals.snd_act_murr) wh_act.snd = true;
          return wh_act;
        }
        if (text.indexOf("Переплетаем хвосты") !== -1) {
          if (globals.txt_act_tails) wh_act.txt = "Переплетаем хвосты";
          if (globals.snd_act_tails) wh_act.snd = true;
          return wh_act;
        }
        if (text.indexOf("Трёмся щекой") !== -1) {
          if (globals.txt_act_cheek) wh_act.txt = "Трёмся щекой";
          if (globals.snd_act_cheek) wh_act.snd = true;
          return wh_act;
        }
        if (text.indexOf("Валяем по земле") !== -1) {
          if (globals.txt_act_ground) wh_act.txt = "Валяем по земле";
          if (globals.snd_act_ground) wh_act.snd = true;
          return wh_act;
        }
        if (text.indexOf("Тереться носом о нос") !== -1) {
          if (globals.txt_act_rub) wh_act.txt = "Трёмся носом о нос";
          if (globals.snd_act_rub) wh_act.snd = true;
          return wh_act;
        }
        if (text.indexOf("Успокаиваться") !== -1) {
          if (globals.txt_act_calm) wh_act.txt = "Выход из боевой стойки";
          if (globals.snd_act_calm) wh_act.snd = true;
          return wh_act;
        }
        return wh_act;
      }
      let rang = false;
      let move_ok = false; // можно проигрывать звук
      let action = which_action($("#block_mess").html());

      $("body").on('DOMSubtreeModified', "#block_mess", function () { //На изменении блока-сообщения о времени действия или переносе твоего зада куда-то
        if ($('#sek').text().length) { //Если текст #sek существует
          let time = $('#sek').text();
          action = which_action($("#block_mess").html());
          if (time == '7 с' || time == '6 с') move_ok = true; //Действие длится хотя бы 7 секунд -С МОМЕНТА ОТКРЫТИЯ ИГРОВОЙ-
          if (action.txt !== null) $('title').text(time + " / " + action.txt); //Сменить титульник, если текст на это действие включен
          if (!action.snd) rang = true; //Реагировать только на нужные навыки ("звук был" = да)
          if ((time === '2 с' || time === '1 с') && !rang && move_ok) { //Свернутая вкладка обновляется каждые 2 секунды, F // До конца действия 1-2 сек, звука ещё не было/звук включен, звук можно проигрывать
            let audio = new Audio();
            audio.src = sounds.action_notif;
            audio.volume = globals.sound_notifEndAct;
            audio.play();
            rang = true;
            move_ok = false;
          }
        }
        if ($("#block_mess").html() === "") { //Если пуст, действий нет
          $('title').text('Игровая / CatWar');
          rang = false;
          move_ok = false;
        }
      });
    }
    if (globals.notif_eaten) { //Уведомления, когда вас поднимают
      $("body").on('DOMSubtreeModified', "#block_mess", function () {
        if ($("#block_mess").html().indexOf("Вы не сможете выбраться") !== -1) {
          $('title').text("Во рту");
          let audio = new Audio();
          audio.src = globals.sound_notifEndAct;
          audio.volume = globals.sound_notifEaten;
          audio.play();
        }
        if ($("#block_mess").html() === "" && !globals.on_actNotif) { //Если пуст, действий нет (нужно, если нет уведомлений на действия)
          $('title').text('Игровая / CatWar');
        }
      });
    }
    if (globals.notif_attack) {
      $(document).ready(function () {
        $("#ist").on('DOMNodeInserted', function () {
          let last_ist = $("#ist").html().split('.');
          last_ist.pop();
          last_ist = last_ist.pop();
          if (last_ist.indexOf("в боережим, поскольку на меня напал") !== -1) { //На меня напали
            let audio = new Audio();
            audio.src = sounds.alert_attacked;
            audio.volume = globals.sound_notifBeaten;
            audio.play();
          }
        });
      });
    }
    if (globals.on_moveFightLog) {
      $('#app').ready(function () { //Возможность перетаскивать панель лога боя
        $('head').append(`<style>#fightPanelHandle {
                                display:inline-block;
                                height:16px;
                                width:16px;
                                background: url(http://abstract-shed.site/cwm_catalog/untargeted.png) center no-repeat;
                                background-color: #ccc;
                                margin-right:4px;
                                border-radius: 5px;
                                padding: 1px;
                                position: relative;
                                top: 5px;
                                left: 3px;
                            }
                            #fightPanelHandle:active {
                                background: url(http://abstract-shed.site/cwm_catalog/targeted.png) center no-repeat;
                                background-color: #ccc;
                            }</style>`);
        $("#fightPanel").prepend(`<a id="fightPanelHandle"></a>`);
        $("#fightPanel").draggable({
          handle: "#fightPanelHandle"
        });
      });
    }
    if (globals.fight_log_max_height != 70) {
      $('#fightLog').css('height', globals.fight_log_max_height);
    }
    if (globals.on_shortFightLog) {
      $(document).ready(function () {
        let prev_log = '';
        let prev_class = '';
        $("#fightLog").on('DOMNodeInserted', 'span:not(.cws-hit-count)', function (e) {
          let this_log = $(this).html();
          let this_class = $(this).attr('class');
          if (this_log == prev_log && prev_class == this_class) {
            $(this).remove();
            $('#fightLog > br:first-child').remove(); //чистка
            let $to_change = $('.cws-hit-count').first();
            let count = parseInt($to_change.attr('count'));
            count++;
            $to_change.attr('count', count);
            $to_change.html(' (х' + count + ')');
          }
          else { //новый удар
            $('<span class="cws-hit-count ' + this_class + '" count=1></span>').insertAfter($(this));
          }
          prev_log = this_log;
          prev_class = this_class;
        });
      });
    }
    if (globals.on_teamFights) {
      let ids = [];
      $('head').append(`<style>
label.team-1 {
  background: #41CD70;
color: #41CD70;
}
.arrow_green.team-2, label.team-2 {
  background: ${globals.tf_color_g_team2};
color: ${globals.tf_color_g_team2};
}
.arrow_green.team-3, label.team-3 {
  background: ${globals.tf_color_g_team3};
  color: ${globals.tf_color_g_team3};
}
.arrow_green.team-4, label.team-4 {
  background: ${globals.tf_color_g_team4};
  color: ${globals.tf_color_g_team4};
}
.arrow_red.team-2 {
  background: ${globals.tf_color_r_team2};
}
.arrow_red.team-3 {
  background: ${globals.tf_color_r_team3};
}
.arrow_red.team-4 {
  background: ${globals.tf_color_r_team4};
}
#fteams-table {width: 100%; background-color: #ccccccd7;}
#fteams-table input[type="radio"] {display:none;}
#fteams-table td, #fteams-table th {
  border: 1px solid black;
  text-align: center;
  vertical-align: middle;
}

.lbl {width: 25px;}
.team {
  text-align: center;
  display: block;
  width: 20px;
  height: 15px;
  margin: 2px;
  border: 2px solid transparent;
}
input:checked + .team {
  border: 2px solid black;
  font-weight: bold;
  color: black;
}
#fightPanel {height: max-content;}
#fteams-wrap {
  margin: 5px 0;
  max-height: ${globals.tf_max_height}px;
  overflow-y: scroll;
}
#refresh-team {width: 100%;}
.tf-color {color:black;}
</style>`);

      $("#app").ready(function () {

        $("#fightPanel").append(`<div id=fteams-wrap>
                                 <table id=fteams-table>
                                   <thead>
                                     <th class="tf-color">Имя</th>
                                     <th class="tf-color" colspan=4>Команда</th>
                                   </thead>
                                   <tbody id=fightColors></tbody>
                                 </table>
                                 <button id=refresh-team>Обновить список</button>
                               </div>`);

        $("#refresh-team").on("click", function () {
          $('.arrow').each(function () {
            let id = $(this).attr('id').match(/\d+/)[0];
            if ($.inArray(id, ids) === -1) { //Если имени ещё не существует в списке
              ids.push(id);
              let name = $(".cat_tooltip a[href='/cat" + id + "']").html();
              $("#fightColors").append(`<tr id=team_member_${id}><td class="tf-color">${name}</td>
<td class=lbl><input type="radio" name="chk${id}" checked value="team-1" id="chk${id}-team-1"><label class="team team-1" for="chk${id}-team-1">*</label></td>
<td class=lbl><input type="radio" name="chk${id}" value="team-2" id="chk${id}-team-2"><label class="team team-2" for="chk${id}-team-2">*</label></td>
<td class=lbl><input type="radio" name="chk${id}" value="team-3" id="chk${id}-team-3"><label class="team team-3" for="chk${id}-team-3">*</label></td>
<td class=lbl><input type="radio" name="chk${id}" value="team-4" id="chk${id}-team-4"><label class="team team-4" for="chk${id}-team-4">*</label></td>
</tr>`);
            }
          });
          $('#fightColors > tr').each(function () {
            let id = $(this).attr('id').match(/\d+/)[0];
            if (!$("#arrow" + id).length) { //если не существует кота из списка в боережиме
              $("#team_member_" + id).remove();
              ids.splice(ids.indexOf(id), 1);
            }
          });
        });

        $(".cage_items").on('DOMNodeInserted', ".catWithArrow", function () { //Каждый раз, когда кто-то появляется на локе или кто-то переходит на соседнюю клетку
          if ($("#fightPanel").attr("style").indexOf("display: none") === -1) {
            let a = $(this).find(".arrow").attr("id");
            if (a !== undefined) { //Если чел со стрелкой
              let id = $(this).find(".cat_tooltip a[href*='/cat']").attr("href").match(/\d+/)[0];
              if ($.inArray(id, ids) === -1) { //Adding a new one
                ids.push(id);
                let name = $(".cat_tooltip a[href='/cat" + id + "']").html();
                $("#fightColors").append(`<tr id=team_member_${id}><td class="tf-color">${name}</td>
                                                    <td class=lbl><input type="radio" name="chk${id}" checked value="team-1" id="chk${id}-team-1"><label class="team team-1" for="chk${id}-team-1">*</label></td>
                                                    <td class=lbl><input type="radio" name="chk${id}" value="team-2" id="chk${id}-team-2"><label class="team team-2" for="chk${id}-team-2">*</label></td>
                                                    <td class=lbl><input type="radio" name="chk${id}" value="team-3" id="chk${id}-team-3"><label class="team team-3" for="chk${id}-team-3">*</label></td>
                                                    <td class=lbl><input type="radio" name="chk${id}" value="team-4" id="chk${id}-team-4"><label class="team team-4" for="chk${id}-team-4">*</label></td>
                                                    </tr>`);
              }
              //And then each time when someone moves/returns
              let b = $("#team_member_" + a.match(/\d+/)[0] + " input:checked");
              $("#" + a + " .arrow_green").addClass(b.val());
              $("#" + a + " .arrow_red").addClass(b.val());
            }
          }
        });
        $(document).on('click', 'input[type=radio]', function () { //Изменение команды при клике
          let id = $(this).attr('id').match(/\d+/)[0];
          $("#arrow" + id + " .arrow_green").attr('class', $("#arrow" + id + " .arrow_green").attr('class').replace(/ team-\d/g, ''));
          $("#arrow" + id + " .arrow_green").addClass($(this).val());
          $("#arrow" + id + " .arrow_red").attr('class', $("#arrow" + id + " .arrow_red").attr('class').replace(/ team-\d/g, ''));
          $("#arrow" + id + " .arrow_red").addClass($(this).val());
        });
      });
    }
    if (globals.on_cleanerHistory) {
      let cl_history = (win.localStorage.getItem('cws_cleaner_history_log') !== null) ? win.localStorage.getItem('cws_cleaner_history_log') : 'История очищена.';
      let clean_id;
      $("#ist").ready(function () {
        // ДОБАВЛЕНИЕ ЛОГА ЧИСТИЛЬЩИКОВ
        $('<hr><h2><a href=\"#\" id=cleaner class=toggle>Деятельность в чистильщиках:</a></h2><span id=cleaner_block>' + cl_history + '</span><br><a id=erase_cleaner href=#>Очистить историю чистки</a>').insertAfter("#history_clean");
        $(document).on("click", ".catrot, .itemInMouth", function () {
          clean_id = $(this).attr('id'); //Если опускаешь
        });
        let prev_ist = undefined;
        let prev_prev_ist = undefined;
        $("#ist").on('DOMNodeInserted', function () {
          let last_ist = $("#ist").html().split('.')[$("#ist").html().split('.').length - 2].trim();
          if (((last_ist.indexOf("Поднял") !== -1) || (last_ist.indexOf("Опустил") !== -1)) && ((last_ist.indexOf("кота") !== -1) || (last_ist.indexOf("кошку") !== -1))) { //Если есть "поднял(а)/опустил(а) кота/кошку"
            if (last_ist.indexOf("Поднял") !== -1) { //Если поднимаешь
              clean_id = $(".catrot:last-child").attr("id");
            }
            let hist_str = ' ' + last_ist;
            if (globals.clean_id) {
              hist_str += ' (' + clean_id + ')';
            } //Записать ID
            if (globals.clean_location) {
              hist_str += ' в локации «' + $("#location").html() + '»';
            } //Записать локацию
            hist_str += '.';
            if ((globals.clean_action) && (prev_prev_ist !== undefined) && ((prev_prev_ist.indexOf("Обнюхал") !== -1) ||
                (prev_prev_ist.indexOf("Потёрлись носом о нос") !== -1) ||
                (prev_prev_ist.indexOf("Помурлыкал") !== -1) ||
                (prev_prev_ist.indexOf("Вылизал") !== -1) ||
                (prev_prev_ist.indexOf("Потёрлись щекой о щёку") !== -1) ||
                (prev_prev_ist.indexOf("Переплели хвосты") !== -1) ||
                (prev_prev_ist.indexOf("Повалял") !== -1)) &&
              (prev_prev_ist.indexOf("по имени") !== -1)) {
              let clean_curr_name = last_ist.match(/ по имени ([А-Яа-яЁё ]+)/u) || ['', ''];
              let clean_check_name = prev_prev_ist.match(/ по имени ([А-Яа-яЁё ]+)/u) || ['', ''];
              if (clean_check_name[1] !== '' && clean_check_name[1] == clean_curr_name[1]) { //Имя проверенного и имя поднятого одинаковые
                let their_pol = (last_ist.indexOf("кошку") !== -1) ? 'кошку' : 'кота'; //Вообще-то пронаунс это ОЧЕНЬ важно
                let ur_pol = (last_ist.indexOf("Подняла") !== -1) ? 'Проверила' : 'Проверил'; //хаххаахаххахаха
                hist_str = ' ' + ur_pol + ' ' + their_pol + ' по имени ' + clean_check_name[1] + '.' + hist_str;
              }
            }
            if (clean_id !== undefined) { //Сюда, потому что если только что зашёл и поднял кого-то, то не сработает условие !== undefined
              $('#cleaner_block').append(hist_str);
              win.localStorage.setItem('cws_cleaner_history_log', $('#cleaner_block').html());
            }
          }
          prev_prev_ist = prev_ist;
          prev_ist = last_ist;
        });
        $('#erase_cleaner').on('click', function () {
          $('#cleaner_block').html("История очищена.");
          win.localStorage.setItem('cws_cleaner_history_log', 'История очищена.');
        });
      });
    }
  }

  function myCat() {
    if (!globals.charListArray.length) { //Если массив ни разу не заполнялся
      $(document).ready(function () {
        let autoCCArr = [];
        $('a[href*="/login2?"]').each(function () {
          let id = $(this).attr('href').split('=')[1];
          let name = $(this).html();
          if (id && name) autoCCArr.push({
            'id': id,
            'name': name
          });
        });
        let id = $('#pr a[href*="cat"] > b').html();
        let name = $('#pr > big').html();
        if (id && name) autoCCArr.push({
          'id': id,
          'name': name
        });
        win.localStorage.setItem('cws_sett_charListArray', JSON.stringify(autoCCArr));
      });
    }
  }

  function profile() { //Профиль игрока
    if (globals.on_idProf) {
      $(document).ready(function () {
        let id = $('p[data-cat]').attr('data-cat');
        $('<span style="display:flex;align-items:center;margin-top:2px;"><img src="img/icon_id.png"><b style="padding-left:9px;">' + id + '</b></span>').insertBefore('#info');
      });
    }

  }

  function dm() { //ЛС игрока
    if (globals.on_idDM) {
      $(document).ready(function () {
        $('#main').bind("DOMSubtreeModified", function () {
          if (!$('#msg_id').length) {
            let id = $('#msg_login').attr('href');
            if (id !== undefined) {
              id = id.slice(3);
              $('<i id=msg_id> [' + id + ']</i>').insertAfter($('#msg_login'));
            }
          }
        });
      });
    }
  }

  function hunt() {
    if ($('meta[name=viewport]').length && globals.on_huntMobile) { //Добавить CSS только когда мобильная версия и включен фикс охоты
      addCSS(`#select_type {
                margin-left: 69%;
                margin-top: 18%;
                transform: scale(2);
            }
            input {
                height: 2em;
                font-size: 3.5em;
                top: 51%;
                width: 160%;
            }
            #b2 {
                top: 91%;
            }
            #b3 {
                top: 131%;
            }
            body {
                position: fixed;
                transform: scale(.5);
                height: 100%;
                width: 100%;
                top: -25%;
                left: -25%;
            }
            #smell {
                width: 17em;
                height: 15em;
                bottom: -95%;
            }
            #smell > span {
                font-size: 2em;
                padding: .5em;
            }
.mod_btn {
  position: fixed;
  z-index: 9999;
  font-family: Verdana;
  font-size: 2.5em;
  height: 2em;
  width: 2em;
  border-radius: 5em;
  background-size: 75% !important;
  background: #333 center no-repeat;
  color: white;
  opacity: .8;
  bottom:0;right:0;
  user-select: none;
  text-align: center;
  -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
}
#w_btn {
  top: .2em;
  left: 3em;
  background-image: url('https://i.imgur.com/y0e39Ai.png');
}
#a_btn {
  top: 3.5em;
  left: .5em;
  background-image: url('https://i.imgur.com/JgywWPS.png');
}
#s_btn {
  top: 6.8em;
  left: 3em;
  background-image: url('https://i.imgur.com/BPRewfC.png');
}
#d_btn {
  top: 3.5em;
  left: 5.5em;
  background-image: url('https://i.imgur.com/g6WcMvn.png');
}
#q_btn {
  top: 1em;
  left: .75em;
  background-image: url('https://i.imgur.com/JgywWPS.png');
}
#e_btn {
  top: 1em;
  left: 5.25em;
  background-image: url('https://i.imgur.com/y0e39Ai.png');
}
#z_btn {
  top: 6em;
  left: .75em;
  background-image: url('https://i.imgur.com/BPRewfC.png');
}
#x_btn {
  top: 6em;
  left: 5.25em;
  background-image: url('https://i.imgur.com/g6WcMvn.png');
}
#q_btn, #e_btn, #x_btn, #z_btn {transform: rotate(45deg);}
#oben, #links, #rechts, #unten {display: none;}
.hunt_txt {
  width: 100%;
}`);
      $("#main").ready(function () {
        $("#main").append(`<button class="mod_btn" data-code="81" id="q_btn"></button>
                                 <button class="mod_btn" data-code="87" id="w_btn"></button>
                                 <button class="mod_btn" data-code="69" id="e_btn"></button>
                                 <button class="mod_btn" data-code="65" id="a_btn"></button>
                                 <button class="mod_btn" data-code="83" id="s_btn"></button>
                                 <button class="mod_btn" data-code="68" id="d_btn"></button>
                                 <button class="mod_btn" data-code="90" id="z_btn"></button>
                                 <button class="mod_btn" data-code="88" id="x_btn"></button>`);
        $('.mod_btn').on("mousedown touchstart", function (e) {
          e.preventDefault();
          let code = $(this).data('code');
          $('#main').trigger(
            jQuery.Event('keydown', {
              keyCode: code,
              which: code
            })
          );
        });
        $('.mod_btn').on("mouseup touchend", function (e) {
          e.preventDefault();
          let code = $(this).data('code');
          $('#main').trigger(
            jQuery.Event('keyup', {
              keyCode: code,
              which: code
            })
          );
        });
      });
    }
    if (globals.on_huntText) {
      addCSS(`#smell {
                     text-align: center;
                     display:flex;
                     align-items:center;
                     justify-content:center;
                 }
                 #smell > span {
                     background-color: white;
                 }`);

      let color_old = -1;
      setInterval(function () {
        if ($('#smell').attr('style')) {
          let color_new = parseInt($('#smell').attr('style').split('#').pop().slice(0, 2), 16);
          let a = color_new - color_old
          if (color_old != -1) {
            let text = (a < 0) ? "<span class=hunt_txt>Дичь удаляется</span>" : "<span class=hunt_txt>Дичь приближается</span>";
            text = (color_new === 0) ? "<span class=hunt_txt>Дичь слишком далеко</span>" : text;
            if ((a !== 0) || (color_new === 0)) $('#smell').html(text);
          }
          color_old = color_new;
        }
      }, 100);
    }
  }

  function sett() { //Сделать подпункты через ul li
    $('title').text('Настройки уведомлений');
    $('head').append(`<meta http-equiv="Content-Type" content="text/html; Charset=UTF-8">
                      <meta name="viewport" content="width=device-width">
                      <style>
                      #cwa_sett {
                          margin: auto;
                          max-width: 800px;
                          /*border: 1px solid black;*/
                          border-radius: 1em;
                      }
                      body {
                          color: #111;
                          background-color: #ffdead;
                          font-size: .9em;
                          font-family: Verdana;
                      }
                      .bl_in{
                          display: inline-block;
                          margin-left:20px;
                      }
                      h3 {
                          background: #9a561b;
                          padding: 10px 0 10px 15px;
                          border-radius: 12px 12px 0px 0px;
                          color: white;
                      }
                      #cwa_sett > div {
                          margin: .6em 0;
                      }


#color_pick td, #color_pick th{
padding: .1em .25em;
}
#cat_box {
    padding: .6em .3em;
}
#fight_bg {
border-radius: 1em;
background: url(https://abstract-shed.site/pic/5.jpg) center center no-repeat;
width: 320px;
height: 160px;
max-width: calc(100% - 1.2em);
}
.color-pick-wrapper {
display: inline-block;
max-width: 30%;
}
.arrow {
    height: 8px;
    position: absolute;
    margin: 0;
    padding: 3px 0 0 11px;
    z-index: 2;
}
.arrow-paws {background: url(/cw3/symbole/arrow_paws.png) 0 0 no-repeat;}
.arrow-claws {background: url(/cw3/symbole/arrow_claws.png) 0 0 no-repeat;}
.arrow-teeth {background: url(/cw3/symbole/arrow_teeth.png) 0 0 no-repeat;}
.arrow table, .arrow td {
    height: 5px !important;
    padding: 0;
    margin: 0;
}
.arrow_red {
    background: #CD4141;
}
.d, .d div {
    width: 100px;
    height: 150px;
}
table {
    border-collapse: collapse;
}
.custom-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 25px;
  height: 25px;
  border-radius: 1em;
  background: #622906;
  cursor: pointer;
}
.custom-range {
-webkit-appearance: none;
appearance: none;
width: 200px;
height: 15px;
background: #fff1dc;
outline: none;
border-style: solid;
border-width: 1px;
border-color: #62290640;
}
.custom-range::-moz-range-thumb {
  width: 25px;
  height: 25px;
  background: #622906;
  cursor: pointer;
}
#action_table, #action_table td, #action_table th, #CCTbl, #CCTbl td, #CCTbl th, #color_pick, #color_pick td, #color_pick th{
  border: 1px solid #97663b70;
}
#action_table td, #action_table th, #charChangeTbl th{
  padding: 0 .5em;
}
.cc-delete {
  cursor: pointer;
  font-weight: bold;
  padding: 0 .1em;
  font-size: 1.2em;
}
.cc-name {
  width: 220px;
}
.cc-id {
  width: 80px;
}
@media(max-width:500px){/*smol*/
  #CCTbl tr > :first-child, .cc-id {
    width: 60px;
  }
  .cc-name {
    width: 98.5%;
  }
  #CCTbl tr > :last-child, .cc-delete {
    width: 19px;
  }
  #CCTbl {
    width: 100%;
  }
}
button {
    border-width: 2px;
    border-radius: 5px;
    padding: 3px 10px;
    background-color: #fff6e9;
}
button:disabled {
    background-color: #fff6e996;
  border-color: rgba(240,240,240,0.5);
}
.volume-table td:first-child {
  vertical-align: top;
  padding-top:3px;
}
#CCAdd, #nickAdd {
  margin-top: .25em;
}
#cm_blocked {
font-size: inherit; font-family:inherit;
resize:none;
width:99%;
height:50px;}
@media(max-width:500px){/*smol*/
#cm_blocked {
height:90px;}
}
</style>`);

    let action_group_dis = (globals.on_actNotif) ? '' : ' disabled';
    let tf_group_dis = (globals.on_teamFights) ? '' : ' disabled';
    let clean_group_dis = (globals.on_cleanerHistory) ? '' : ' disabled';
    let cc_group_dis = (globals.on_charChange) ? '' : ' disabled';
    let chatment_group_dis = (globals.on_chatMention) ? '' : ' disabled';
    let nick_group_dis = (globals.on_nickHighlight) ? '' : ' disabled';
    let CCArray = '';
    $.each(globals.charListArray, function (index, obj) {
      if (obj.id && obj.name) {
        CCArray += `<tr><td><input class="cc-id" min=0 pattern="[0-9]{1,7}" type="number" group="char-change" value="${obj.id}" ${cc_group_dis}></td>
                        <td><input class="cc-name" maxlength="30" group="char-change" type="text" value="${obj.name}" ${cc_group_dis}></td>
                        <td><span class="cc-delete">×</span></td></tr>`;
      }
    });
    if (!CCArray.length) {
      CCArray = `<tr><td><input class="cc-id" min=0 pattern="[0-9]{1,7}" type="number" group="char-change" ${cc_group_dis}></td>
                    <td><input class="cc-name" maxlength="30" group="char-change" type="text" ${cc_group_dis}></td>
                    <td><span class="cc-delete">×</span></td></tr>`;
    }
    let nickArray = '';
    $.each(globals.nickListArray, function (index, obj) {
      if (obj) {
        nickArray += `<tr><td><input class="nick-name" maxlength="30" minlength="2" group="nick-highlight" placeholder="имя" type="text" value="${obj}" ${nick_group_dis}></td>
                        <td><span class="cc-delete">×</span></td></tr>`;
      }
    });
    if (!nickArray.length) {
      nickArray = `<tr><td><input class="nick-name" maxlength="30" minlength="2" group="nick-highlight" type="text"${nick_group_dis}></td>
                   <td><span class="cc-delete">×</span></td></tr>`;
    }
    let html = `<div id="cwa_sett"><h2 align=center>Настройки CW:Shed</h2>
<div><i><small>! Большинство изменений применяются автоматически. Для того, чтобы изменения вступили в силу, обновите Игровую (страницу с ЛС, профиль).</small></i></div>
<h3>ID</h3>
    <div><input class="cwa-chk" id="on_idDM" type="checkbox"${globals.on_idDM?' checked':''}><label for="on_idDM">Включить отображение ID в личных сообщениях</label></div>
    <div><input class="cwa-chk" id="on_idProf" type="checkbox"${globals.on_idProf?' checked':''}><label for="on_idProf">Включить отображение ID в профилях игроков</label></div>
    <div><input class="cwa-chk" id="on_idCatMouth" type="checkbox"${globals.on_idCatMouth?' checked':''}><label for="on_idCatMouth">Включить отображение ID котов, находящихся во рту</label></div>
    <div><input class="cwa-chk" id="on_idItemMouth" type="checkbox"${globals.on_idItemMouth?' checked':''}><label for="on_idItemMouth">Включить отображение ID и названий предметов, находящихся во рту</label></div>
    <div><input class="cwa-chk" id="on_idChat" type="checkbox"${globals.on_idChat?' checked':''}><label for="on_idChat">Включить отображение ID в чате Игровой</label></div>
<h3>Уведомления</h3>
    <div><input class="cwa-chk" id="on_newDM" type="checkbox"${globals.on_newDM?' checked':''}><label for="on_newDM">Уведомлять о новом ЛС, когда я в Игровой</label></div>
    <table class="volume-table"><tr>
        <td>Громкость:</td>
        <td><input type="range" class="custom-range" step="0.01" max="1" min="0.05" data-bind="sound_newDM" id="sound_newDM" value="${globals.sound_newDM}"></td>
        <td><button data-bind="sound_newDM" sound-src="${sounds.new_message}" class="sound-test">Тест</button></td>
    </tr></table>
    <hr>
    <div><input class="cwa-chk" id="on_newChat" type="checkbox"${globals.on_newChat?' checked':''}><label for="on_newChat">Уведомлять о новом сообщении в Чате, когда я в Игровой</label></div>
    <table class="volume-table"><tr>
        <td>Громкость:</td>
        <td><input type="range" class="custom-range" step="0.01" max="1" min="0.05" data-bind="sound_newChat" id="sound_newChat" value="${globals.sound_newChat}"></td>
        <td><button data-bind="sound_newChat" sound-src="${sounds.new_message}" class="sound-test">Тест</button></td>
    </tr></table>
    <hr>
    <div><input class="cwa-chk group-switch" id="on_nickHighlight" group-header="nick-highlight" type="checkbox"${globals.on_nickHighlight?' checked':''}><label for="on_nickHighlight">Выделять следующие строчки как моё имя в Игровой</label></div>
<form id="nickForm">
<table border=1 id="nickTbl">
<thead><th>Кличка</th><th></th></thead>
<tbody id="nickList">
${nickArray}
</tbody>
</table>
</form>
<button id="nickAdd" group="nick-highlight"${nick_group_dis}>Добавить новое поле</button>
<div><button group="nick-highlight" form="nickForm"${nick_group_dis}>Сохранить</button></div>
<div><b>*</b> Из-за того, как устроен чат на Варе, эта функция может добавлять лагов, особенно когда за несколько секунд приходит много сообщений. Чем больше Вы установите себе кличек, тем большая будет нагрузка.</div>
    <div><input class="cwa-chk group-switch" id="on_chatMention" group-header="chat-mention" type="checkbox"${globals.on_chatMention?' checked':''}><label for="on_chatMention">Уведомлять, когда моё имя упоминают в чате Игровой</label></div>
    <table class="volume-table"><tr>
        <td>Громкость:</td>
        <td><input type="range" class="custom-range" step="0.01" max="1" min="0.05" data-bind="sound_chatMention" id="sound_chatMention" value="${globals.sound_chatMention}"></td>
        <td><button data-bind="sound_chatMention" sound-src="${sounds.chat_mention}" class="sound-test">Тест</button></td>
    </tr></table>
    <div>Айди персонажей, от которых игнорировать уведомления (<i>через пробел</i>):</div>
<form id="form_cm_blocked">
    <textarea id="cm_blocked" group="chat-mention" ${chatment_group_dis} pattern="[0-9 ]+" placeholder="420020 930302">${globals.cm_blocked.join(' ')}</textarea>
<button group="chat-mention" ${chatment_group_dis}>Запомнить</button>
</form>
    <hr>
    <div><input class="cwa-chk" id="notif_eaten" type="checkbox"${globals.notif_eaten?' checked':''}><label for="notif_eaten">Уведомлять, если меня кто-то поднял</label></div>
    <table class="volume-table"><tr>
        <td>Громкость:</td>
        <td><input type="range" class="custom-range" step="0.01" max="1" min="0.05" data-bind="sound_notifEaten" id="sound_notifEaten" value="${globals.sound_notifEaten}"></td>
        <td><button data-bind="sound_notifEaten" sound-src="${sounds.action_notif}" class="sound-test">Тест</button></td>
    </tr></table>
    <hr>
    <div><input class="cwa-chk" id="notif_attack" type="checkbox"${globals.notif_attack?' checked':''}><label for="notif_attack">Уведомлять, если меня ввели в боевую стойку через Т+2 или Т+3</label></div>
    <table class="volume-table"><tr>
        <td>Громкость:</td>
        <td><input type="range" class="custom-range" step="0.01" max="1" min="0.05" data-bind="sound_notifBeaten" id="sound_notifBeaten" value="${globals.sound_notifBeaten}"></td>
        <td><button data-bind="sound_notifBeaten" sound-src="${sounds.alert_attacked}" class="sound-test">Тест</button></td>
    </tr></table>
    <hr>
    <div><input class="cwa-chk group-switch" id="on_actNotif" group-header="action-notif" type="checkbox"${globals.on_actNotif?' checked':''}><label for="on_actNotif">Уведомлять об окончании действий</label></div>
    <table class="volume-table"><tr>
        <td>Громкость:</td>
        <td><input type="range" class="custom-range" step="0.01" max="1" min="0.05" data-bind="sound_notifEndAct" id="sound_notifEndAct" value="${globals.sound_notifEndAct}"></td>
        <td><button data-bind="sound_notifEndAct" sound-src="${sounds.action_notif}" class="sound-test">Тест</button></td>
    </tr></table>
    <div style="font-size: 12px"><b>На которые действия реагировать:</b></div>
<block class="bl_in">
<table id="action_table" border=1>
<thead><th>Текст</th><th>Звук</th><th>Описание</th></thead>
<tbody>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_move" type="checkbox"${globals.txt_act_move?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_move" type="checkbox"${globals.snd_act_move?' checked':''}></td>
    <td>Переход (дольше 5 секунд)</td>
</tr>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_rub" type="checkbox"${globals.txt_act_rub?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_rub" type="checkbox"${globals.snd_act_rub?' checked':''}></td>
    <td>Поедание дичи</td>
</tr>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_need" type="checkbox"${globals.txt_act_need?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_need" type="checkbox"${globals.snd_act_need?' checked':''}></td>
    <td>Пополнение нужды</td>
</tr>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_drink" type="checkbox"${globals.txt_act_drink?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_drink" type="checkbox"${globals.snd_act_drink?' checked':''}></td>
    <td>Питьё</td>
</tr>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_dig" type="checkbox"${globals.txt_act_dig?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_dig" type="checkbox"${globals.snd_act_dig?' checked':''}></td>
    <td>Копание</td></tr>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_digin" type="checkbox"${globals.txt_act_digin?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_digin" type="checkbox"${globals.snd_act_digin?' checked':''}></td>
    <td>Закапывание</td></tr>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_clean" type="checkbox"${globals.txt_act_clean?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_clean" type="checkbox"${globals.snd_act_clean?' checked':''}></td>
    <td>Вылизывание</td></tr>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_sleep" type="checkbox"${globals.txt_act_sleep?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_sleep" type="checkbox"${globals.snd_act_sleep?' checked':''}></td>
    <td>Сон</td></tr>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_sniff" type="checkbox"${globals.txt_act_sniff?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_sniff" type="checkbox"${globals.snd_act_sniff?' checked':''}></td>
    <td>Нюх</td>
</tr>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_swim" type="checkbox"${globals.txt_act_swim?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_swim" type="checkbox"${globals.snd_act_swim?' checked':''}></td>
    <td>Плавание</td>
</tr>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_murr" type="checkbox"${globals.txt_act_murr?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_murr" type="checkbox"${globals.snd_act_murr?' checked':''}></td>
    <td>Мурлыкание</td>
</tr>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_tails" type="checkbox"${globals.txt_act_tails?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_tails" type="checkbox"${globals.snd_act_tails?' checked':''}></td>
    <td>Переплетание хвостов</td>
</tr>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_cheek" type="checkbox"${globals.txt_act_cheek?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_cheek" type="checkbox"${globals.snd_act_cheek?' checked':''}></td>
    <td>Трение щёками</td>
</tr>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_ground" type="checkbox"${globals.txt_act_ground?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_ground" type="checkbox"${globals.snd_act_ground?' checked':''}></td>
    <td>Валяние по земле</td>
</tr>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_rub" type="checkbox"${globals.txt_act_rub?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_rub" type="checkbox"${globals.snd_act_rub?' checked':''}></td>
    <td>Трение носами</td>
</tr>
<tr>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="txt_act_calm" type="checkbox"${globals.txt_act_calm?' checked':''}></td>
    <td align=center><input class="cwa-chk" group="action-notif"${action_group_dis} id="snd_act_calm" type="checkbox"${globals.snd_act_calm?' checked':''}></td>
    <td>Выход из боевой стойки</td>
</tr>
</tbody>
</table>
</block>
<h3>Разное</h3>
<div><input class="cwa-chk group-switch" id="on_cleanerHistory" group-header="cleaner-log" type="checkbox"${globals.on_cleanerHistory?' checked':''}><label for="on_cleanerHistory">Лог деятельности в чистильщиках</label></div>
<div style="font-size: 12px"><b>Записывать</b></div>
<block class="bl_in">
<div><input class="cwa-chk" group="cleaner-log"${clean_group_dis} id="clean_id" type="checkbox"${globals.clean_id?' checked':''}><label for="clean_id">ID поднятого/опущенного</label></div>
<div><input class="cwa-chk" group="cleaner-log"${clean_group_dis} id="clean_location" type="checkbox"${globals.clean_location?' checked':''}><label for="clean_location">Локацию, в которой кот был поднят/опущен</label></div>
<div><input class="cwa-chk" group="cleaner-log"${clean_group_dis} id="clean_action" type="checkbox"${globals.clean_action?' checked':''}><label for="clean_action">Проверка на действие*.</label>
<div>* Работает так: отписывает вместе с <i>"Поднял кота..."</i> ещё и <i>"Проверил на действие кота по имени ..."</i>, но только И ТОЛЬКО при условии, что проверка была за два действия до поднятия (и между проверкой и поднятием не была перезагружена Игровая). Пример:
<ul>
    <li><i>"Потёрлись носом о нос с котом по имени Хвостогривик. Отменил действие. Поднял кота по имени Хвостогривик."</i> - засчитывается за проверку.</li>
    <li><i>"Потёрлись носом о нос с котом по имени Хвостогривик. Поднял кота по имени Хвостогривик."</i> - <b>не</b> засчитывается за проверку (проверка не была отменена).</li>
    <li><i>"Потёрлись носом о нос с котом по имени Лапкоусик. Отменил действие. Поднял кота по имени Хвостогривик."</i> - <b>не</b> засчитывается за проверку (проверка была на другом коте).</li>
    <li><i>"Потёрлись носом о нос с котом по имени Хвостогривик. Отменил действие. Обнюхал землю. Поднял кота по имени Хвостогривик."</i> - <b>не</b> засчитывается за проверку (проверка была слишком "давно").</li>
</ul>
</div>
</div></block>
<hr>
<div><input class="cwa-chk" id="on_huntText" type="checkbox"${globals.on_huntText?' checked':''}><label for="on_huntText">Охота: словесное отображение того, отдаляется дичь или приближается</label></div>
<div><input class="cwa-chk" id="on_huntMobile" type="checkbox"${globals.on_huntMobile?' checked':''}><label for="on_huntMobile">Охота: удобные кнопки и стабильное окно на мобильных устройствах</label></div>
<hr>
<div><input class="cwa-chk" id="on_catsDown" type="checkbox"${globals.on_catsDown?' checked':''}><label for="on_catsDown">Ставить котов внизу клетки (несовместимо с активными боями, т.к. не видно правильного места горла/шеи оппонента)</label></div>
<hr>
<div><input class="cwa-chk group-switch" id="on_charChange" group-header="char-change" type="checkbox"${globals.on_charChange?' checked':''}><label for="on_charChange">Список ваших персонажей в Игровой</label></div>
Включает переход на душевых/игровых персонажей прямо из Игровой. Список заполнится <b>автоматически</b>, если зайти на страницу "Мой кот/Моя кошка".
<form id="CCForm">
<table border=1 id="CCTbl">
<thead><th>ID</th><th>Отображаемое имя</th><th></th></thead>
<tbody id="CCList">
${CCArray}
</tbody>
</table>
</form>
<button group="char-change" id="CCAdd"${cc_group_dis}>Добавить новое поле</button>
<div><button group="char-change" form="CCForm"${cc_group_dis}>Сохранить</button></div>
<hr>
<div>Высота окошка лога боережима (конфликтует с варомодом. 70 = "выключено", значение по умолчанию): <input type=number id="fight_log_max_height" class="cws-number" min=50 max=500 value="${globals.fight_log_max_height}"> px</div>
<hr>
<div><input class="cwa-chk" id="on_moveFightLog" type="checkbox"${globals.on_moveFightLog?' checked':''}><label for="on_moveFightLog">Возможность перетаскивать лог бр ("прицел" слева от замочка блокировки)</label></div>
<div><input class="cwa-chk" id="on_shortFightLog" type="checkbox"${globals.on_shortFightLog?' checked':''}><label for="on_shortFightLog">Сокращения повторяющихся ударов ("Я =&gt; Гривохвостик (лапы) (х4)")</label></div>

<div><input class="cwa-chk group-switch" id="on_teamFights" group-header="team-fights" type="checkbox"${globals.on_teamFights?' checked':''}><label for="on_teamFights">Команды в боевом режиме</label></div>
<div>
<div>Максимальная высота окошка с распределением команд: <input type=number id="tf_max_height" class="cws-number" group="team-fights" min=100 max=500 value="${globals.tf_max_height}"> px</div>
<table align=center id=color_pick border=1 style="text-align: center;">
<tr><th>Команда:</th><th>1</th><th>2</th><th>3</th><th>4</th></tr>
<tr><th>"Зелёный"</th>
    <td>Нет</td>
    <td><input type="color" class="team-color-pick" group="team-fights"${tf_group_dis} data-bind=cat0g id="tf_color_g_team2" value="${globals.tf_color_g_team2}"></td>
    <td><input type="color" class="team-color-pick" group="team-fights"${tf_group_dis} data-bind=cat1g id="tf_color_g_team3" value="${globals.tf_color_g_team3}"></td>
    <td><input type="color" class="team-color-pick" group="team-fights"${tf_group_dis} data-bind=cat2g id="tf_color_g_team4" value="${globals.tf_color_g_team4}"></td>
</tr>
<tr><th>"Красный"</th>
    <td>Нет</td>
    <td><input type="color" class="team-color-pick" group="team-fights"${tf_group_dis} data-bind=cat0r id="tf_color_r_team2" value="${globals.tf_color_r_team2}"></td>
    <td><input type="color" class="team-color-pick" group="team-fights"${tf_group_dis} data-bind=cat1r id="tf_color_r_team3" value="${globals.tf_color_r_team3}"></td>
    <td><input type="color" class="team-color-pick" group="team-fights"${tf_group_dis} data-bind=cat2r id="tf_color_r_team4" value="${globals.tf_color_r_team4}"></td>
</tr>
</table>
</div>
<div id=fight_bg style="margin: auto;">
<div id=cat_box>
    <div class="color-pick-wrapper"><div style="position: relative;">
    <div class="arrow arrow-paws" style="top: 75px; transform: rotate(157deg); opacity: 1;">
    <table style="width: 100px;"><tbody><tr><td class="arrow-color" style="width: 25px; background: ${globals.tf_color_r_team2};" data-bind=cat0r></td><td class="arrow-color" style="width: 25px; background: ${globals.tf_color_g_team2};" data-bind=cat0g></td><td style="width: 50px;"></td></tr></tbody></table></div></div>
    <span class="cat"><div style="background-image:url('https://abstract-shed.site/pic/catmodel1.png');" class="d"></div></span></div>
    <div class="color-pick-wrapper"><div style="position: relative;">
    <div class="arrow arrow-teeth" style="top: 75px; transform: rotate(41deg); opacity: 1;">
    <table style="width: 100px;"><tbody><tr><td class="arrow-color" style="width: 13px; background: ${globals.tf_color_r_team3};" data-bind=cat1r></td><td class="arrow-color" style="width: 37px; background: ${globals.tf_color_g_team3};" data-bind=cat1g></td><td style="width: 50px;"></td></tr></tbody></table></div></div>
    <span class="cat"><div style="background-image:url('https://abstract-shed.site/pic/catmodel2.png');" class="d"></div></span></div>
    <div class="color-pick-wrapper"><div style="position: relative;">
    <div class="arrow arrow-claws" style="top: 75px; transform: rotate(378deg); opacity: 1;">
    <table style="width: 100px;"><tbody><tr><td class="arrow-color" style="width: 19px; background: ${globals.tf_color_r_team4};" data-bind=cat2r></td><td class="arrow-color" style="width: 31px; background: ${globals.tf_color_g_team4};" data-bind=cat2g></td><td style="width: 50px;"></td></tr></tbody></table></div></div>
    <span class="cat"><div style="background-image:url('https://abstract-shed.site/pic/catmodel3.png');" class="d"></div></span></div>
</div>
</div>
</div>`;
    $('body').html(html);
    $('body').on('submit', '#nickForm', function (e) {
      e.preventDefault();
      let nickArr = [];
      $('#nickList > tr').each(function () {
        let name = $(this).find('.nick-name').val();
        if (name) {
          nickArr.push(name);
        }
      });
      win.localStorage.setItem('cws_sett_nickListArray', JSON.stringify(nickArr));
    });
    $('body').on('submit', '#CCForm', function (e) {
      e.preventDefault(); /* 4111 */
      let CCArr = [];
      $('#CCList > tr').each(function () {
        let id = $(this).find('.cc-id').val();
        let name = $(this).find('.cc-name').val();
        if (id && name) {
          CCArr.push({
            'id': id,
            'name': name
          });
        }
      });
      win.localStorage.setItem('cws_sett_charListArray', JSON.stringify(CCArr));
    });
    $('body').on('submit', '#form_cm_blocked', function (e) {
      e.preventDefault();
      let arr = $('#cm_blocked').val().split(' ');
      $.each(arr, function (index, value) {
        arr[index] = parseInt(value.trim());
      });
      arr = jQuery.grep(arr, function (a) {
        return a; //Оставить только числа и не 0
      });
      win.localStorage.setItem('cws_sett_cm_blocked', JSON.stringify(arr));
    });
    $('body').on('click', '#CCAdd', function () {
      if ($('.cc-id').length < 5) {
        $('#CCList').append(`<tr><td><input class="cc-id" min=0 pattern="[0-9]{1,7}" type="number"></td><td><input class="cc-name" maxlength="30" type="text"></td><td><span class="cc-delete">×</span></td></tr>`);
      }
    });
    $('body').on('click', '#nickAdd', function () {
      if ($('.nick-name').length < 3) {
        $('#nickList').append(`<tr><td><input class="nick-name" maxlength="30" minlength="2" group="char-change" type="text"></td><td><span class="cc-delete">×</span></td></tr>`);
      }
    });

    $('body').on('click', '.cc-delete', function () {
      if ($(this).closest('tbody').find('tr').length != 1) {
        $(this).closest('tr').remove();
      }
    });
    let audio = new Audio();
    $('body').on('click', '.sound-test', function () {
      audio.pause();
      audio.currentTime = 0;
      audio.src = $(this).attr('sound-src');
      audio.volume = $('.custom-range[data-bind=' + $(this).attr('data-bind') + ']').val();
      audio.play();
    });
    $('body').on('change', '.custom-range', function () {
      let volume = $(this).val();
      let id = $(this).attr('id');
      win.localStorage.setItem('cws_sett_' + id, volume);
      globals[id] = volume;
      console.log('globals.' + id + " = " + volume); //Delete later
    });
    $('body').on('change', '.cwa-chk', function () {
      let id = $(this).attr('id');
      let ischkd = $(this).prop('checked');
      win.localStorage.setItem('cws_sett_' + id, ischkd);
      globals[id] = ischkd;
      console.log('globals.' + id + " = " + ischkd); //Delete later
    });
    $('body').on('change paste focusout keyup', '.cws-number', function () {
      let val = parseInt($(this).val());
      if (val >= $(this).attr('min') && val <= $(this).attr('max')) {
        win.localStorage.setItem('cws_sett_' + $(this).attr('id'), val);
        console.log('globals.cws_sett_' + $(this).attr('id') + ' = ' + val); //Delete later
      }
    });
    $('body').on('change', '.group-switch', function () {
      let group = $(this).attr('group-header');
      let ischkd = $(this).prop('checked');
      $(':input[group=' + group + '], button[group=' + group + ']').prop('disabled', !ischkd);
    });
    $('body').on('change', '.team-color-pick', function () {
      let id = $(this).attr('id');
      let val = $(this).val();
      $('.arrow-color[data-bind=' + $(this).attr('data-bind') + ']').css('background', val);
      win.localStorage.setItem('cws_sett_' + id, val);
    });
  }
})(window, jQuery);