MediaWiki:Common.js: различия между версиями

Материал из Space Station 14 Вики
мНет описания правки
мНет описания правки
Строка 1: Строка 1:
const currentURL = window.location.href;
const currentURL = window.location.href;
const serversStatus = [{
const serversStatus = [{
name: "server-main",
  name: "server-main",
connect: "https://game2.station14.ru/main/server/status",
  connect: "https://game2.station14.ru/main/server/status",
serverconnect: "game2.station14.ru/main/server"
  serverconnect: "game2.station14.ru/main/server"
}, {
}, {
name: "server-nova",
  name: "server-nova",
connect: "https://game2.station14.ru/nova/server/status",
  connect: "https://game2.station14.ru/nova/server/status",
serverconnect: "game2.station14.ru/nova/server"
  serverconnect: "game2.station14.ru/nova/server"
}, {
}, {
name: "server-athara",
  name: "server-athara",
connect: "https://game2.station14.ru/athara/server/status",
  connect: "https://game2.station14.ru/athara/server/status",
serverconnect: "game2.station14.ru/athara/server"
  serverconnect: "game2.station14.ru/athara/server"
}, {
}, {
name: "server-solaris",
  name: "server-solaris",
connect: "https://game2.station14.ru/solaris/server/status",
  connect: "https://game2.station14.ru/solaris/server/status",
serverconnect: "game2.station14.ru/solaris/server"
  serverconnect: "game2.station14.ru/solaris/server"
}, {
}, {
name: "server-echo",
  name: "server-echo",
connect: "https://game2.station14.ru/echo/server/status",
  connect: "https://game2.station14.ru/echo/server/status",
serverconnect: "game2.station14.ru/echo/server"
  serverconnect: "game2.station14.ru/echo/server"
}, {
}, {
name: "server-elysium",
  name: "server-elysium",
connect: "https://game2.station14.ru/elysium/server/status",
  connect: "https://game2.station14.ru/elysium/server/status",
serverconnect: "game2.station14.ru/elysium/server"
  serverconnect: "game2.station14.ru/elysium/server"
}, {
}, {
name: "server-nebula",
  name: "server-nebula",
connect: "https://game2.station14.ru/nebula/server/status",
  connect: "https://game2.station14.ru/nebula/server/status",
serverconnect: "game2.station14.ru/nebula/server"
  serverconnect: "game2.station14.ru/nebula/server"
}, {
}, {
name: "server-wl",
  name: "server-wl",
connect: "https://game2.station14.ru/wl/server/status",
  connect: "https://game2.station14.ru/wl/server/status",
serverconnect: "game2.station14.ru/wl/server"
  serverconnect: "game2.station14.ru/wl/server"
}, {
}, {
name: "server-frontier",
  name: "server-frontier",
connect: "https://api.codetabs.com/v1/proxy/?quest=https://arles.station14.ru/frontier-main/server/status",
  connect: "https://api.codetabs.com/v1/proxy/?quest=https://arles.station14.ru/frontier-main/server/status",
serverconnect: "arles.station14.ru/frontier-main/server"
  serverconnect: "arles.station14.ru/frontier-main/server"
}, {
}, {
name: "server-fallout",
  name: "server-fallout",
connect: "https://api.codetabs.com/v1/proxy/?quest=http://188.92.78.98:1221/status",
  connect: "https://api.codetabs.com/v1/proxy/?quest=http://188.92.78.98:1221/status",
serverconnect: "188.92.78.98:1221"
  serverconnect: "188.92.78.98:1221"
}, {
}, {
name: "server-marines",
  name: "server-marines",
connect: "https://game1.station14.ru/marines-main/server/status",
  connect: "https://game1.station14.ru/marines-main/server/status",
serverconnect: "game1.station14.ru/marines-main/server"
  serverconnect: "game1.station14.ru/marines-main/server"
}, {
}, {
name: "server-stalker",
  name: "server-stalker",
connect: "https://api.codetabs.com/v1/proxy/?quest=https://game.stalkers14.xyz/status",
  connect: "https://api.codetabs.com/v1/proxy/?quest=https://game.stalkers14.xyz/status",
serverconnect: "game.stalkers14.xyz"
  serverconnect: "game.stalkers14.xyz"
}];
}];


function getXHRInfo(url) {
function getXHRInfo(url) {
return new Promise(function(resolve, reject) {
  return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
    var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
    xhr.open('GET', url, true);
xhr.onload = function() {
    xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
      if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.responseText));
        resolve(JSON.parse(xhr.responseText));
} else {
      } else {
reject('Ошибка при выполнении запроса: ' + xhr.status);
        reject('Ошибка при выполнении запроса: ' + xhr.status);
}
      }
};
    };
xhr.onerror = function() {
    xhr.onerror = function() {
reject('Ошибка при выполнении запроса');
      reject('Ошибка при выполнении запроса');
};
    };
xhr.send();
    xhr.send();
});
  });
}
}


function updateServerInfoByConnect(connect, name) {
function updateServerInfoByConnect(connect, name) {
getServerTime().then(function(currentUnixTime) {
  getServerTime().then(function(currentUnixTime) {
return getXHRInfo(connect).then(function(serverData) {
    return getXHRInfo(connect).then(function(serverData) {
var unixStartRound = getUnixTime(serverData.round_start_time);
      var unixStartRound = getUnixTime(serverData.round_start_time);
var timeDisplay = unixStartRound ? secondsToDHM(currentUnixTime -
      var timeDisplay = unixStartRound ? secondsToDHM(currentUnixTime -
unixStartRound) : "–";
        unixStartRound) : "–";
var currentPlayers = serverData.players;
      var currentPlayers = serverData.players;
var maxPlayers = serverData.soft_max_players;
      var maxPlayers = serverData.soft_max_players;
// Вычисляем процент
      // Вычисляем процент
var percentage = maxPlayers > 0 ? Math.round((currentPlayers /
      var percentage = maxPlayers > 0 ? Math.round((currentPlayers /
maxPlayers) * 100) : 0;
        maxPlayers) * 100) : 0;
// Форматируем строку с количеством игроков
      // Форматируем строку с количеством игроков
var playersDisplay = currentPlayers && maxPlayers ? currentPlayers + '/' +
      var playersDisplay = currentPlayers && maxPlayers ? currentPlayers + '/' +
maxPlayers : "–";
        maxPlayers : "–";
// Функция для проверки на пустые данные
      // Функция для проверки на пустые данные
function checkValue(value) {
      function checkValue(value) {
return value ? value : "–";
        return value ? value : "–";
}
      }
var serverInfo = {
      var serverInfo = {
name: checkValue(serverData.name),
        name: checkValue(serverData.name),
round: checkValue(serverData.round_id),
        round: checkValue(serverData.round_id),
status: checkValue(serverData.run_level),
        status: checkValue(serverData.run_level),
map: checkValue(serverData.map),
        map: checkValue(serverData.map),
time: timeDisplay,
        time: timeDisplay,
players: playersDisplay,
        players: playersDisplay,
preset: checkValue(serverData.preset),
        preset: checkValue(serverData.preset),
percentage: percentage
        percentage: percentage
};
      };
updateServerInfo(serverInfo, name);
      updateServerInfo(serverInfo, name);
//console.log("serverInfo", serverInfo, "currentUnixTime", currentUnixTime,"unixStartRound", unixStartRound);
      //console.log("serverInfo", serverInfo, "currentUnixTime", currentUnixTime,"unixStartRound", unixStartRound);
});
    });
}).catch(function(error) {
  }).catch(function(error) {
console.error(error);
    console.error(error);
});
  });
}
}


function getUnixTime(dateString) {
function getUnixTime(dateString) {
return Math.floor(new Date(dateString).getTime() / 1000); // Делим на 1000, чтобы получить секунды
  return Math.floor(new Date(dateString).getTime() / 1000); // Делим на 1000, чтобы получить секунды
}
}


function secondsToDHM(seconds) {
function secondsToDHM(seconds) {
var days = Math.floor(seconds / 86400);
  var days = Math.floor(seconds / 86400);
var hours = Math.floor((seconds % 86400) / 3600);
  var hours = Math.floor((seconds % 86400) / 3600);
var minutes = Math.floor((seconds % 3600) / 60);
  var minutes = Math.floor((seconds % 3600) / 60);
var result = "";
  var result = "";
if (days > 0) result += days + " дн, ";
  if (days > 0) result += days + " дн, ";
if (hours > 0) result += hours + " ч ";
  if (hours > 0) result += hours + " ч ";
// Проверка на наличие минут
  // Проверка на наличие минут
if (minutes > 0) {
  if (minutes > 0) {
result += minutes + " мин";
    result += minutes + " мин";
} else {
  } else {
result += "–"; // Символ ожидания, если минут нет
    result += "–"; // Символ ожидания, если минут нет
}
  }
return result.trim();
  return result.trim();
}
}


function getServerTime() {
function getServerTime() {
return fetch(
  return fetch(
'https://station14.ru/api.php?action=query&meta=siteinfo&siprop=general&format=json'
    'https://station14.ru/api.php?action=query&meta=siteinfo&siprop=general&format=json'
).then(function(response) {
  ).then(function(response) {
return response.json();
    return response.json();
}).then(function(data) {
  }).then(function(data) {
return getUnixTime(data.query.general.time);
    return getUnixTime(data.query.general.time);
});
  });
}
}


function updateServerInfo(serverObj, serverName) {
function updateServerInfo(serverObj, serverName) {
var serverStatusFrame = document.getElementById(serverName);
  var serverStatusFrame = document.getElementById(serverName);
var statusText = {
  var statusText = {
0: "Лобби",
    0: "Лобби",
1: "Раунд идёт",
    1: "Раунд идёт",
2: "Завершение"
    2: "Завершение"
};
  };
serverStatusFrame.querySelector(".serverInfoRoundSet").textContent = "#" +
  serverStatusFrame.querySelector(".serverInfoRoundSet").textContent = "#" +
serverObj.round;
    serverObj.round;
serverStatusFrame.querySelector(".serverStatusSet").textContent = statusText[
  serverStatusFrame.querySelector(".serverStatusSet").textContent = statusText[
serverObj.status] || "Неизвестный статус";
    serverObj.status] || "Неизвестный статус";
serverStatusFrame.querySelector(".serverMapSet").textContent = serverObj.map;
  serverStatusFrame.querySelector(".serverMapSet").textContent = serverObj.map;
serverStatusFrame.querySelector(".serverTimeSet").textContent = serverObj.time;
  serverStatusFrame.querySelector(".serverTimeSet").textContent = serverObj.time;
serverStatusFrame.querySelector(".serverPlayersSet").textContent = serverObj.players;
  serverStatusFrame.querySelector(".serverPlayersSet").textContent = serverObj.players;
serverStatusFrame.querySelector(".serverPresetSet").textContent = serverObj.preset;
  serverStatusFrame.querySelector(".serverPresetSet").textContent = serverObj.preset;
// Получаем строку подключения из serversStatus
  // Получаем строку подключения из serversStatus
const serverData = serversStatus.find(function(server) {
  const serverData = serversStatus.find(function(server) {
return server.name === serverName;
    return server.name === serverName;
});
  });
var connectionStringElement = serverStatusFrame.querySelector(
  var connectionStringElement = serverStatusFrame.querySelector(
".serverConnectSet");
    ".serverConnectSet");
if (connectionStringElement) {
  if (connectionStringElement) {
connectionStringElement.textContent = serverData ? serverData.serverconnect :
    connectionStringElement.textContent = serverData ? serverData.serverconnect :
'-'; // Устанавливаем строку подключения
      '-'; // Устанавливаем строку подключения
}
  }
// Обновляем прогресс-бар
  // Обновляем прогресс-бар
var progressBar = serverStatusFrame.querySelector(".progressBar"); // Предполагаем, что у вас есть элемент для прогресс-бара
  var progressBar = serverStatusFrame.querySelector(".progressBar"); // Предполагаем, что у вас есть элемент для прогресс-бара
if (progressBar) {
  if (progressBar) {
progressBar.style.width = serverObj.percentage + '%'; // Устанавливаем ширину прогресс-бара
    progressBar.style.width = serverObj.percentage + '%'; // Устанавливаем ширину прогресс-бара
}
  }
// Обновляем отображение процента
  // Обновляем отображение процента
var percentageDisplay = serverStatusFrame.querySelector(".percentageDisplay"); // Элемент для отображения процента
  var percentageDisplay = serverStatusFrame.querySelector(".percentageDisplay"); // Элемент для отображения процента
if (percentageDisplay) {
  if (percentageDisplay) {
percentageDisplay.textContent = serverObj.percentage + '%'; // Устанавливаем текст с процентом
    percentageDisplay.textContent = serverObj.percentage + '%'; // Устанавливаем текст с процентом
}
  }
}
}


function updateAllServersInfo() {
function updateAllServersInfo() {
serversStatus.forEach(function(server) {
  serversStatus.forEach(function(server) {
updateServerInfoByConnect(server.connect, server.name);
    updateServerInfoByConnect(server.connect, server.name);
});
  });
}
}


function copyToClipboard(connectUrl) {
function copyToClipboard(connectUrl) {
const copyIcons = document.querySelectorAll('.copy-icon');
  const copyIcons = document.querySelectorAll('.copy-icon');
copyIcons.forEach(function(icon) {
  copyIcons.forEach(function(icon) {
icon.addEventListener('click', function() {
    icon.addEventListener('click', function() {
// Находим предыдущий элемент
      // Находим предыдущий элемент
const previousElement = this.previousElementSibling;
      const previousElement = this.previousElementSibling;
if (previousElement) {
      if (previousElement) {
// Получаем текстовое содержимое
        // Получаем текстовое содержимое
const textToCopy = previousElement.textContent;
        const textToCopy = previousElement.textContent;
const tempInput = document.createElement('input');
        const tempInput = document.createElement('input');
tempInput.value = textToCopy;
        tempInput.value = textToCopy;
document.body.appendChild(tempInput);
        document.body.appendChild(tempInput);
tempInput.select();
        tempInput.select();
document.execCommand('copy');
        document.execCommand('copy');
document.body.removeChild(tempInput);
        document.body.removeChild(tempInput);
// Визуальный эффект
        // Визуальный эффект
this.style.opacity = '0.5'; // Сменяем прозрачность
        this.style.opacity = '0.5'; // Сменяем прозрачность
setTimeout(function() {
        setTimeout(function() {
this.style.opacity = '1'; // Возвращаем прозрачность
          this.style.opacity = '1'; // Возвращаем прозрачность
}.bind(this), 200); // Через 1 секунду
        }.bind(this), 200); // Через 1 секунду
}
      }
});
    });
});
  });
}
}


function customCSS(textCSS) {
function customCSS(textCSS) {
const styleSheet = document.createElement("style");
  const styleSheet = document.createElement("style");
styleSheet.textContent = textCSS;
  styleSheet.textContent = textCSS;
//console.log(textCSS);
  //console.log(textCSS);
document.head.appendChild(styleSheet);
  document.head.appendChild(styleSheet);
}
 
function parseCustomAttributes(attributesString) {
  const attributes = {};
  const regex = /(\w+)=&quot;([^&]+)&quot;/g;
  var match;
 
  while ((match = regex.exec(attributesString)) !== null) {
    attributes[match[1]] = match[2];
  }
 
  return attributes;
}
}


function createIframeFromSrc(element) {
function createIframeFromSrc(element) {
   var src = element.getAttribute('data-customIframeSrc');
   const src = element.getAttribute('data-customIframeSrc');
  var customAttributesString = element.getAttribute('data-customattributes');
 
   if (src) {
   if (src) {
     var iframe = document.createElement('iframe');
     const iframe = document.createElement('iframe');
     iframe.src = src;
     iframe.src = src;
    // Добавляем атрибуты из data-customattributes
    if (customAttributesString) {
      const customAttributes = parseCustomAttributes(customAttributesString);
      for (var key in customAttributes) {
        if (customAttributes.hasOwnProperty(key)) {
          iframe.setAttribute(key, customAttributes[key]);
        }
      }
    }
     iframe.classList.add('customIframe');
     iframe.classList.add('customIframe');
     element.insertAdjacentElement('afterend', iframe);
     element.insertAdjacentElement('afterend', iframe);
Строка 245: Строка 220:


function createIframeFromSrcdoc(element) {
function createIframeFromSrcdoc(element) {
   var srcdoc = element.getAttribute('data-customIframeSrcdoc');
   const srcdoc = element.getAttribute('data-customIframeSrcdoc');
  var customAttributesString = element.getAttribute('data-customattributes');
 
   if (srcdoc) {
   if (srcdoc) {
     var iframe = document.createElement('iframe');
     const iframe = document.createElement('iframe');
     iframe.srcdoc = srcdoc;
     iframe.srcdoc = srcdoc;
    // Добавляем атрибуты из data-customattributes
    if (customAttributesString) {
      const customAttributes = parseCustomAttributes(customAttributesString);
      for (var key in customAttributes) {
        if (customAttributes.hasOwnProperty(key)) {
          iframe.setAttribute(key, customAttributes[key]);
        }
      }
    }
     iframe.classList.add('customIframeSrcdoc');
     iframe.classList.add('customIframeSrcdoc');
     element.insertAdjacentElement('afterend', iframe);
     element.insertAdjacentElement('afterend', iframe);
Строка 269: Строка 231:




$(document).ready(function() {
  var serversStatus = document.querySelectorAll('.serversStatus');
  if (serversStatus.length > 0) {
    updateAllServersInfo();
    // Перезапускать каждую минуту (60000 мс)
    setInterval(updateAllServersInfo, 60000);
  }


$(document).ready(function() {
  var cssEls = document.querySelectorAll('.customCSS');
var serversStatus = document.querySelectorAll('.serversStatus');
  if (cssEls.length > 0) {
if (serversStatus.length > 0) {
    for (var i = 0; i < cssEls.length; i++) {
updateAllServersInfo();
      const textCSS = cssEls[i].textContent;
// Перезапускать каждую минуту (60000 мс)
      //console.log(textCSS);
setInterval(updateAllServersInfo, 60000);
      customCSS(textCSS);
}
    }
  }
  const copyServerConnectionIcon = document.querySelectorAll(
    '.copyServerConnectionIcon');
  copyServerConnectionIcon.forEach(function(icon) {
    icon.addEventListener('click', function() {
      const connectUrl = this.getAttribute('data-connect');
      copyToClipboard(connectUrl);
    });
  });
  copyToClipboard();
 
 
  const srcElements = document.querySelectorAll('[data-customIframeSrc]');
  const srcdocElements = document.querySelectorAll('[data-customIframeSrcdoc]');


var cssEls = document.querySelectorAll('.customCSS');
  srcElements.forEach(createIframeFromSrc);
if (cssEls.length > 0) {
  srcdocElements.forEach(createIframeFromSrcdoc);
for (var i = 0; i < cssEls.length; i++) {
const textCSS = cssEls[i].textContent;
//console.log(textCSS);
customCSS(textCSS);
}
}
const copyServerConnectionIcon = document.querySelectorAll(
'.copyServerConnectionIcon');
copyServerConnectionIcon.forEach(function(icon) {
icon.addEventListener('click', function() {
const connectUrl = this.getAttribute('data-connect');
copyToClipboard(connectUrl);
});
});
copyToClipboard();
var srcElements = document.querySelectorAll('[data-customIframeSrc]');
var srcdocElements = document.querySelectorAll('[data-customIframeSrcdoc]');
Array.prototype.forEach.call(srcElements, function(element) {
createIframeFromSrc(element);
});
Array.prototype.forEach.call(srcdocElements, function(element) {
createIframeFromSrcdoc(element);
});
});
});
/*WikiEditor/Викификатор*/
/*WikiEditor/Викификатор*/
if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) !== -1) {
if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) !== -1) {
mw.loader.load(
  mw.loader.load(
'//ru.wikipedia.org/w/index.php?title=MediaWiki:Gadget-wikificator.js&action=raw&ctype=text/javascript'
    '//ru.wikipedia.org/w/index.php?title=MediaWiki:Gadget-wikificator.js&action=raw&ctype=text/javascript'
);
  );
}
}
var customizeToolbar = function() {
var customizeToolbar = function() {
$('#wpTextbox1').wikiEditor('addToToolbar', {
  $('#wpTextbox1').wikiEditor('addToToolbar', {
'section': 'advanced',
    'section': 'advanced',
'group': 'format',
    'group': 'format',
'tools': {
    'tools': {
'wikify': {
      'wikify': {
label: 'Викификатор',
        label: 'Викификатор',
type: 'button',
        type: 'button',
icon: '//upload.wikimedia.org/wikipedia/commons/0/06/Wikify-toolbutton.png',
        icon: '//upload.wikimedia.org/wikipedia/commons/0/06/Wikify-toolbutton.png',
action: {
        action: {
type: 'callback',
          type: 'callback',
execute: function(context) {
          execute: function(context) {
Wikify();
            Wikify();
}
          }
}
        }
}
      }
}
    }
});
  });
};
};
if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) !== -1) {
if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) !== -1) {
mw.loader.using('user.options', function() {
  mw.loader.using('user.options', function() {
if (mw.user.options.get('usebetatoolbar')) {
    if (mw.user.options.get('usebetatoolbar')) {
mw.loader.using('ext.wikiEditor.toolbar', function() {
      mw.loader.using('ext.wikiEditor.toolbar', function() {
$(document).ready(customizeToolbar);
        $(document).ready(customizeToolbar);
});
      });
}
    }
});
  });
}
}
/**
/**
Строка 349: Строка 303:
/* Variables for interface text used throughout the script, for ease of translating */
/* Variables for interface text used throughout the script, for ease of translating */
var i18n = {
var i18n = {
// Collapsible elements and page loader
  // Collapsible elements and page loader
hideText: 'скрыть',
  hideText: 'скрыть',
showText: 'показать',
  showText: 'показать',
// Page loader
  // Page loader
loadErrorTitle: 'Возникла ошибка при загрузке содержимого'
  loadErrorTitle: 'Возникла ошибка при загрузке содержимого'
};
};
var mcw = window.mcw = {};
var mcw = window.mcw = {};
Строка 360: Строка 314:
/* Fired whenever wiki content is added. (#mw-content-text, live preview, load page, etc.) */
/* Fired whenever wiki content is added. (#mw-content-text, live preview, load page, etc.) */
mw.hook('wikipage.content').add(function($wikipageContent) {
mw.hook('wikipage.content').add(function($wikipageContent) {
/**
  /**
* Page loader
  * Page loader
*
  *
* Allows a page to be downloaded and displayed on demand.
  * Allows a page to be downloaded and displayed on demand.
* Use with Template:LoadPage and Template:LoadBox
  * Use with Template:LoadPage and Template:LoadBox
*/
  */
(function() {
  (function() {
var $loadPage = $wikipageContent.find('.load-page');
    var $loadPage = $wikipageContent.find('.load-page');
if (!$loadPage.length) {
    if (!$loadPage.length) {
return;
      return;
}
    }
// We need the spinner to show loading is happening, but we don't want
    // We need the spinner to show loading is happening, but we don't want
// to have a delay while the module downloads, so we'll load this now,
    // to have a delay while the module downloads, so we'll load this now,
// regardless of if something is clicked
    // regardless of if something is clicked
mw.loader.load('jquery.spinner');
    mw.loader.load('jquery.spinner');
// Create button starting with hide text
    // Create button starting with hide text
// Will be changed to the show text while calculating the maximum button size
    // Will be changed to the show text while calculating the maximum button size
var $buttonTemplate = $('<span>').addClass(
    var $buttonTemplate = $('<span>').addClass(
'mw-editsection-like load-page-button').append('[ ', $('<span>').addClass(
      'mw-editsection-like load-page-button').append('[ ', $('<span>').addClass(
'jslink').text(i18n.hideText), ' ]');
      'jslink').text(i18n.hideText), ' ]');
var extractList = function($contentContainer, listClass) {
    var extractList = function($contentContainer, listClass) {
var $content = $contentContainer.find('.mw-parser-output > ul > li > ul')
      var $content = $contentContainer.find('.mw-parser-output > ul > li > ul')
.children(':not(.nbttree-inherited)');
        .children(':not(.nbttree-inherited)');
if (listClass) {
      if (listClass) {
$content.addClass(listClass);
        $content.addClass(listClass);
}
      }
return $content;
      return $content;
};
    };
$loadPage.each(function() {
    $loadPage.each(function() {
var $body = $(this);
      var $body = $(this);
var page = $body.data('page');
      var page = $body.data('page');
if (!page) {
      if (!page) {
return;
        return;
}
      }
var template = $body.data('template');
      var template = $body.data('template');
var treeview = $body.data('treeview');
      var treeview = $body.data('treeview');
var treeviewClass = $body.data('treeviewclass');
      var treeviewClass = $body.data('treeviewclass');
var $heading;
      var $heading;
var $contentContainer;
      var $contentContainer;
var $content;
      var $content;
var $button = $buttonTemplate.clone();
      var $button = $buttonTemplate.clone();
var $buttonLink = $button.find('.jslink');
      var $buttonLink = $button.find('.jslink');
if (treeview) {
      if (treeview) {
$heading = $body;
        $heading = $body;
$contentContainer = $('<div>');
        $contentContainer = $('<div>');
} else {
      } else {
$heading = $body.children().first();
        $heading = $body.children().first();
$contentContainer = $body.find('.load-page-content');
        $contentContainer = $body.find('.load-page-content');
}
      }
// Add the button
      // Add the button
$heading.append($button);
      $heading.append($button);
// Move the edit button to the right spot
      // Move the edit button to the right spot
$contentContainer.find('.mw-editsection, .mw-editsection-like').insertAfter(
      $contentContainer.find('.mw-editsection, .mw-editsection-like').insertAfter(
$button);
        $button);
// Find max button width, and set its min-width to it
      // Find max button width, and set its min-width to it
var hideWidth = $button.width();
      var hideWidth = $button.width();
$buttonLink.text(i18n.showText);
      $buttonLink.text(i18n.showText);
var showWidth = $button.width();
      var showWidth = $button.width();
if (hideWidth !== showWidth) {
      if (hideWidth !== showWidth) {
$button.css('min-width', hideWidth > showWidth ? hideWidth : showWidth);
        $button.css('min-width', hideWidth > showWidth ? hideWidth : showWidth);
}
      }
$buttonLink.click(function() {
      $buttonLink.click(function() {
if ($body.hasClass('pageloader-contentloaded')) {
        if ($body.hasClass('pageloader-contentloaded')) {
if ($buttonLink.text() === i18n.showText) {
          if ($buttonLink.text() === i18n.showText) {
if (treeview) {
            if (treeview) {
$content.insertAfter($body);
              $content.insertAfter($body);
} else {
            } else {
$contentContainer.show();
              $contentContainer.show();
}
            }
$buttonLink.text(i18n.hideText);
            $buttonLink.text(i18n.hideText);
} else {
          } else {
if (treeview) {
            if (treeview) {
$content.detach();
              $content.detach();
} else {
            } else {
$contentContainer.hide();
              $contentContainer.hide();
}
            }
$buttonLink.text(i18n.showText);
            $buttonLink.text(i18n.showText);
}
          }
return;
          return;
}
        }
// See if this was loaded elsewhere before making a request
        // See if this was loaded elsewhere before making a request
var gotContent;
        var gotContent;
$('.pageloader-contentloaded').each(function() {
        $('.pageloader-contentloaded').each(function() {
var $fLoader = $(this);
          var $fLoader = $(this);
if ($fLoader.data('page') === page && $fLoader.data(
          if ($fLoader.data('page') === page && $fLoader.data(
'pageloader-content')) {
              'pageloader-content')) {
$contentContainer.html($fLoader.data('pageloader-content')).removeClass(
            $contentContainer.html($fLoader.data('pageloader-content')).removeClass(
'noscript');
              'noscript');
mw.hook('wikipage.content').fire($contentContainer);
            mw.hook('wikipage.content').fire($contentContainer);
if (treeview) {
            if (treeview) {
$body.find('.noscript').remove();
              $body.find('.noscript').remove();
$content = extractList($contentContainer, treeviewClass);
              $content = extractList($contentContainer, treeviewClass);
$content.insertAfter($body);
              $content.insertAfter($body);
}
            }
$buttonLink.text(i18n.hideText);
            $buttonLink.text(i18n.hideText);
$body.addClass('pageloader-contentloaded');
            $body.addClass('pageloader-contentloaded');
gotContent = true;
            gotContent = true;
return false;
            return false;
}
          }
});
        });
if (gotContent) {
        if (gotContent) {
return;
          return;
}
        }
// Just in-case the spinner module is still not ready yet
        // Just in-case the spinner module is still not ready yet
var $spinner = $();
        var $spinner = $();
mw.loader.using('jquery.spinner', function() {
        mw.loader.using('jquery.spinner', function() {
// $spinner will be false if the content somehow loaded before the module did
          // $spinner will be false if the content somehow loaded before the module did
if ($spinner) {
          if ($spinner) {
$spinner = $.createSpinner().addClass('mw-editsection-like').css(
            $spinner = $.createSpinner().addClass('mw-editsection-like').css(
'min-width', $button.css('min-width'));
              'min-width', $button.css('min-width'));
$button.hide().after($spinner);
            $button.hide().after($spinner);
}
          }
});
        });
var requestData = {
        var requestData = {
action: 'parse',
          action: 'parse',
prop: 'text'
          prop: 'text'
};
        };
if (template) {
        if (template) {
requestData.page = page;
          requestData.page = page;
} else {
        } else {
requestData.title = mw.config.get('wgPageName');
          requestData.title = mw.config.get('wgPageName');
requestData.text = '{' + '{:' + page + '}}';
          requestData.text = '{' + '{:' + page + '}}';
}
        }
new mw.Api().get(requestData).done(function(data) {
        new mw.Api().get(requestData).done(function(data) {
var html = data.parse.text['*'];
          var html = data.parse.text['*'];
$contentContainer.html(html).removeClass('noscript');
          $contentContainer.html(html).removeClass('noscript');
// Resolve self-links
          // Resolve self-links
if (template) {
          if (template) {
var curPage = '/' + mw.config.get('wgPageName');
            var curPage = '/' + mw.config.get('wgPageName');
$contentContainer.find('a').each(function() {
            $contentContainer.find('a').each(function() {
var $link = $(this);
              var $link = $(this);
if ($link.attr('href') === curPage) {
              if ($link.attr('href') === curPage) {
$link.replaceWith($('<strong>').addClass('selflink').append(
                $link.replaceWith($('<strong>').addClass('selflink').append(
$link.contents()));
                  $link.contents()));
}
              }
});
            });
html = $contentContainer.html();
            html = $contentContainer.html();
}
          }
$body.data('pageloader-content', html);
          $body.data('pageloader-content', html);
// Fire content hook on the new content, running all this stuff again and more :)
          // Fire content hook on the new content, running all this stuff again and more :)
mw.hook('wikipage.content').fire($contentContainer);
          mw.hook('wikipage.content').fire($contentContainer);
if (treeview) {
          if (treeview) {
$body.find('.noscript').remove();
            $body.find('.noscript').remove();
$content = extractList($contentContainer, treeviewClass);
            $content = extractList($contentContainer, treeviewClass);
$content.insertAfter($body);
            $content.insertAfter($body);
}
          }
$spinner.remove();
          $spinner.remove();
$spinner = false;
          $spinner = false;
$buttonLink.text(i18n.hideText);
          $buttonLink.text(i18n.hideText);
$button.show();
          $button.show();
$body.addClass('pageloader-contentloaded');
          $body.addClass('pageloader-contentloaded');
}).fail(function(_, error) {
        }).fail(function(_, error) {
$spinner.remove();
          $spinner.remove();
$spinner = false;
          $spinner = false;
$button.show();
          $button.show();
var errorText = '';
          var errorText = '';
if (error.textStatus) {
          if (error.textStatus) {
errorText = error.textStatus;
            errorText = error.textStatus;
} else if (error.error) {
          } else if (error.error) {
errorText = error.error.info;
            errorText = error.error.info;
}
          }
mw.notify(errorText, {
          mw.notify(errorText, {
title: i18n.loadErrorTitle,
            title: i18n.loadErrorTitle,
autoHide: false
            autoHide: false
});
          });
});
        });
});
      });
});
    });
}());
  }());
/**
  /**
* Element animator
  * Element animator
*
  *
* Will cycle the active class on any child elements
  * Will cycle the active class on any child elements
* within an element with the animated class.
  * within an element with the animated class.
*/
  */
(function() {
  (function() {
if (!mcw.animate) {
    if (!mcw.animate) {
mcw.animate = setInterval(function() {
      mcw.animate = setInterval(function() {
$('.animated').each(function() {
        $('.animated').each(function() {
var $elem = $(this);
          var $elem = $(this);
var $current = $elem.children('.active');
          var $current = $elem.children('.active');
var $next = $current.nextAll(':not(.skip):first');
          var $next = $current.nextAll(':not(.skip):first');
// Loop back to the start
          // Loop back to the start
if (!$next.length) {
          if (!$next.length) {
$next = $elem.children(':not(.skip):first');
            $next = $elem.children(':not(.skip):first');
}
          }
$current.removeClass('active');
          $current.removeClass('active');
$next.addClass('active');
          $next.addClass('active');
});
        });
}, 2000);
      }, 2000);
}
    }
}());
  }());
});
});
// SS220 import end
// SS220 import end

Версия от 17:58, 22 августа 2024

const currentURL = window.location.href;
const serversStatus = [{
  name: "server-main",
  connect: "https://game2.station14.ru/main/server/status",
  serverconnect: "game2.station14.ru/main/server"
}, {
  name: "server-nova",
  connect: "https://game2.station14.ru/nova/server/status",
  serverconnect: "game2.station14.ru/nova/server"
}, {
  name: "server-athara",
  connect: "https://game2.station14.ru/athara/server/status",
  serverconnect: "game2.station14.ru/athara/server"
}, {
  name: "server-solaris",
  connect: "https://game2.station14.ru/solaris/server/status",
  serverconnect: "game2.station14.ru/solaris/server"
}, {
  name: "server-echo",
  connect: "https://game2.station14.ru/echo/server/status",
  serverconnect: "game2.station14.ru/echo/server"
}, {
  name: "server-elysium",
  connect: "https://game2.station14.ru/elysium/server/status",
  serverconnect: "game2.station14.ru/elysium/server"
}, {
  name: "server-nebula",
  connect: "https://game2.station14.ru/nebula/server/status",
  serverconnect: "game2.station14.ru/nebula/server"
}, {
  name: "server-wl",
  connect: "https://game2.station14.ru/wl/server/status",
  serverconnect: "game2.station14.ru/wl/server"
}, {
  name: "server-frontier",
  connect: "https://api.codetabs.com/v1/proxy/?quest=https://arles.station14.ru/frontier-main/server/status",
  serverconnect: "arles.station14.ru/frontier-main/server"
}, {
  name: "server-fallout",
  connect: "https://api.codetabs.com/v1/proxy/?quest=http://188.92.78.98:1221/status",
  serverconnect: "188.92.78.98:1221"
}, {
  name: "server-marines",
  connect: "https://game1.station14.ru/marines-main/server/status",
  serverconnect: "game1.station14.ru/marines-main/server"
}, {
  name: "server-stalker",
  connect: "https://api.codetabs.com/v1/proxy/?quest=https://game.stalkers14.xyz/status",
  serverconnect: "game.stalkers14.xyz"
}];

function getXHRInfo(url) {
  return new Promise(function(resolve, reject) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.onload = function() {
      if (xhr.status >= 200 && xhr.status < 300) {
        resolve(JSON.parse(xhr.responseText));
      } else {
        reject('Ошибка при выполнении запроса: ' + xhr.status);
      }
    };
    xhr.onerror = function() {
      reject('Ошибка при выполнении запроса');
    };
    xhr.send();
  });
}

function updateServerInfoByConnect(connect, name) {
  getServerTime().then(function(currentUnixTime) {
    return getXHRInfo(connect).then(function(serverData) {
      var unixStartRound = getUnixTime(serverData.round_start_time);
      var timeDisplay = unixStartRound ? secondsToDHM(currentUnixTime -
        unixStartRound) : "–";
      var currentPlayers = serverData.players;
      var maxPlayers = serverData.soft_max_players;
      // Вычисляем процент
      var percentage = maxPlayers > 0 ? Math.round((currentPlayers /
        maxPlayers) * 100) : 0;
      // Форматируем строку с количеством игроков
      var playersDisplay = currentPlayers && maxPlayers ? currentPlayers + '/' +
        maxPlayers : "–";
      // Функция для проверки на пустые данные
      function checkValue(value) {
        return value ? value : "–";
      }
      var serverInfo = {
        name: checkValue(serverData.name),
        round: checkValue(serverData.round_id),
        status: checkValue(serverData.run_level),
        map: checkValue(serverData.map),
        time: timeDisplay,
        players: playersDisplay,
        preset: checkValue(serverData.preset),
        percentage: percentage
      };
      updateServerInfo(serverInfo, name);
      //console.log("serverInfo", serverInfo, "currentUnixTime", currentUnixTime,"unixStartRound", unixStartRound);
    });
  }).catch(function(error) {
    console.error(error);
  });
}

function getUnixTime(dateString) {
  return Math.floor(new Date(dateString).getTime() / 1000); // Делим на 1000, чтобы получить секунды
}

function secondsToDHM(seconds) {
  var days = Math.floor(seconds / 86400);
  var hours = Math.floor((seconds % 86400) / 3600);
  var minutes = Math.floor((seconds % 3600) / 60);
  var result = "";
  if (days > 0) result += days + " дн, ";
  if (hours > 0) result += hours + " ч ";
  // Проверка на наличие минут
  if (minutes > 0) {
    result += minutes + " мин";
  } else {
    result += "–"; // Символ ожидания, если минут нет
  }
  return result.trim();
}

function getServerTime() {
  return fetch(
    'https://station14.ru/api.php?action=query&meta=siteinfo&siprop=general&format=json'
  ).then(function(response) {
    return response.json();
  }).then(function(data) {
    return getUnixTime(data.query.general.time);
  });
}

function updateServerInfo(serverObj, serverName) {
  var serverStatusFrame = document.getElementById(serverName);
  var statusText = {
    0: "Лобби",
    1: "Раунд идёт",
    2: "Завершение"
  };
  serverStatusFrame.querySelector(".serverInfoRoundSet").textContent = "#" +
    serverObj.round;
  serverStatusFrame.querySelector(".serverStatusSet").textContent = statusText[
    serverObj.status] || "Неизвестный статус";
  serverStatusFrame.querySelector(".serverMapSet").textContent = serverObj.map;
  serverStatusFrame.querySelector(".serverTimeSet").textContent = serverObj.time;
  serverStatusFrame.querySelector(".serverPlayersSet").textContent = serverObj.players;
  serverStatusFrame.querySelector(".serverPresetSet").textContent = serverObj.preset;
  // Получаем строку подключения из serversStatus
  const serverData = serversStatus.find(function(server) {
    return server.name === serverName;
  });
  var connectionStringElement = serverStatusFrame.querySelector(
    ".serverConnectSet");
  if (connectionStringElement) {
    connectionStringElement.textContent = serverData ? serverData.serverconnect :
      '-'; // Устанавливаем строку подключения
  }
  // Обновляем прогресс-бар
  var progressBar = serverStatusFrame.querySelector(".progressBar"); // Предполагаем, что у вас есть элемент для прогресс-бара
  if (progressBar) {
    progressBar.style.width = serverObj.percentage + '%'; // Устанавливаем ширину прогресс-бара
  }
  // Обновляем отображение процента
  var percentageDisplay = serverStatusFrame.querySelector(".percentageDisplay"); // Элемент для отображения процента
  if (percentageDisplay) {
    percentageDisplay.textContent = serverObj.percentage + '%'; // Устанавливаем текст с процентом
  }
}

function updateAllServersInfo() {
  serversStatus.forEach(function(server) {
    updateServerInfoByConnect(server.connect, server.name);
  });
}

function copyToClipboard(connectUrl) {
  const copyIcons = document.querySelectorAll('.copy-icon');
  copyIcons.forEach(function(icon) {
    icon.addEventListener('click', function() {
      // Находим предыдущий элемент
      const previousElement = this.previousElementSibling;
      if (previousElement) {
        // Получаем текстовое содержимое
        const textToCopy = previousElement.textContent;
        const tempInput = document.createElement('input');
        tempInput.value = textToCopy;
        document.body.appendChild(tempInput);
        tempInput.select();
        document.execCommand('copy');
        document.body.removeChild(tempInput);
        // Визуальный эффект
        this.style.opacity = '0.5'; // Сменяем прозрачность
        setTimeout(function() {
          this.style.opacity = '1'; // Возвращаем прозрачность
        }.bind(this), 200); // Через 1 секунду
      }
    });
  });
}

function customCSS(textCSS) {
  const styleSheet = document.createElement("style");
  styleSheet.textContent = textCSS;
  //console.log(textCSS);
  document.head.appendChild(styleSheet);
}

function createIframeFromSrc(element) {
  const src = element.getAttribute('data-customIframeSrc');
  if (src) {
    const iframe = document.createElement('iframe');
    iframe.src = src;
    iframe.classList.add('customIframe');
    element.insertAdjacentElement('afterend', iframe);
  }
}

function createIframeFromSrcdoc(element) {
  const srcdoc = element.getAttribute('data-customIframeSrcdoc');
  if (srcdoc) {
    const iframe = document.createElement('iframe');
    iframe.srcdoc = srcdoc;
    iframe.classList.add('customIframeSrcdoc');
    element.insertAdjacentElement('afterend', iframe);
  }
}



$(document).ready(function() {
  var serversStatus = document.querySelectorAll('.serversStatus');
  if (serversStatus.length > 0) {
    updateAllServersInfo();
    // Перезапускать каждую минуту (60000 мс)
    setInterval(updateAllServersInfo, 60000);
  }

  var cssEls = document.querySelectorAll('.customCSS');
  if (cssEls.length > 0) {
    for (var i = 0; i < cssEls.length; i++) {
      const textCSS = cssEls[i].textContent;
      //console.log(textCSS);
      customCSS(textCSS);
    }
  }
  const copyServerConnectionIcon = document.querySelectorAll(
    '.copyServerConnectionIcon');
  copyServerConnectionIcon.forEach(function(icon) {
    icon.addEventListener('click', function() {
      const connectUrl = this.getAttribute('data-connect');
      copyToClipboard(connectUrl);
    });
  });
  copyToClipboard();


  const srcElements = document.querySelectorAll('[data-customIframeSrc]');
  const srcdocElements = document.querySelectorAll('[data-customIframeSrcdoc]');

  srcElements.forEach(createIframeFromSrc);
  srcdocElements.forEach(createIframeFromSrcdoc);
});
/*WikiEditor/Викификатор*/
if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) !== -1) {
  mw.loader.load(
    '//ru.wikipedia.org/w/index.php?title=MediaWiki:Gadget-wikificator.js&action=raw&ctype=text/javascript'
  );
}
var customizeToolbar = function() {
  $('#wpTextbox1').wikiEditor('addToToolbar', {
    'section': 'advanced',
    'group': 'format',
    'tools': {
      'wikify': {
        label: 'Викификатор',
        type: 'button',
        icon: '//upload.wikimedia.org/wikipedia/commons/0/06/Wikify-toolbutton.png',
        action: {
          type: 'callback',
          execute: function(context) {
            Wikify();
          }
        }
      }
    }
  });
};
if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) !== -1) {
  mw.loader.using('user.options', function() {
    if (mw.user.options.get('usebetatoolbar')) {
      mw.loader.using('ext.wikiEditor.toolbar', function() {
        $(document).ready(customizeToolbar);
      });
    }
  });
}
/**
 * Taken from https://wiki.ss220.space/index.php?title=MediaWiki:Common.js&oldid=35626
 */
/* Variables for interface text used throughout the script, for ease of translating */
var i18n = {
  // Collapsible elements and page loader
  hideText: 'скрыть',
  showText: 'показать',
  // Page loader
  loadErrorTitle: 'Возникла ошибка при загрузке содержимого'
};
var mcw = window.mcw = {};
/* Keep track of delegated events on dynamic content */
mcw.events = {};
/* Fired whenever wiki content is added. (#mw-content-text, live preview, load page, etc.) */
mw.hook('wikipage.content').add(function($wikipageContent) {
  /**
   * Page loader
   *
   * Allows a page to be downloaded and displayed on demand.
   * Use with Template:LoadPage and Template:LoadBox
   */
  (function() {
    var $loadPage = $wikipageContent.find('.load-page');
    if (!$loadPage.length) {
      return;
    }
    // We need the spinner to show loading is happening, but we don't want
    // to have a delay while the module downloads, so we'll load this now,
    // regardless of if something is clicked
    mw.loader.load('jquery.spinner');
    // Create button starting with hide text
    // Will be changed to the show text while calculating the maximum button size
    var $buttonTemplate = $('<span>').addClass(
      'mw-editsection-like load-page-button').append('[ ', $('<span>').addClass(
      'jslink').text(i18n.hideText), ' ]');
    var extractList = function($contentContainer, listClass) {
      var $content = $contentContainer.find('.mw-parser-output > ul > li > ul')
        .children(':not(.nbttree-inherited)');
      if (listClass) {
        $content.addClass(listClass);
      }
      return $content;
    };
    $loadPage.each(function() {
      var $body = $(this);
      var page = $body.data('page');
      if (!page) {
        return;
      }
      var template = $body.data('template');
      var treeview = $body.data('treeview');
      var treeviewClass = $body.data('treeviewclass');
      var $heading;
      var $contentContainer;
      var $content;
      var $button = $buttonTemplate.clone();
      var $buttonLink = $button.find('.jslink');
      if (treeview) {
        $heading = $body;
        $contentContainer = $('<div>');
      } else {
        $heading = $body.children().first();
        $contentContainer = $body.find('.load-page-content');
      }
      // Add the button
      $heading.append($button);
      // Move the edit button to the right spot
      $contentContainer.find('.mw-editsection, .mw-editsection-like').insertAfter(
        $button);
      // Find max button width, and set its min-width to it
      var hideWidth = $button.width();
      $buttonLink.text(i18n.showText);
      var showWidth = $button.width();
      if (hideWidth !== showWidth) {
        $button.css('min-width', hideWidth > showWidth ? hideWidth : showWidth);
      }
      $buttonLink.click(function() {
        if ($body.hasClass('pageloader-contentloaded')) {
          if ($buttonLink.text() === i18n.showText) {
            if (treeview) {
              $content.insertAfter($body);
            } else {
              $contentContainer.show();
            }
            $buttonLink.text(i18n.hideText);
          } else {
            if (treeview) {
              $content.detach();
            } else {
              $contentContainer.hide();
            }
            $buttonLink.text(i18n.showText);
          }
          return;
        }
        // See if this was loaded elsewhere before making a request
        var gotContent;
        $('.pageloader-contentloaded').each(function() {
          var $fLoader = $(this);
          if ($fLoader.data('page') === page && $fLoader.data(
              'pageloader-content')) {
            $contentContainer.html($fLoader.data('pageloader-content')).removeClass(
              'noscript');
            mw.hook('wikipage.content').fire($contentContainer);
            if (treeview) {
              $body.find('.noscript').remove();
              $content = extractList($contentContainer, treeviewClass);
              $content.insertAfter($body);
            }
            $buttonLink.text(i18n.hideText);
            $body.addClass('pageloader-contentloaded');
            gotContent = true;
            return false;
          }
        });
        if (gotContent) {
          return;
        }
        // Just in-case the spinner module is still not ready yet
        var $spinner = $();
        mw.loader.using('jquery.spinner', function() {
          // $spinner will be false if the content somehow loaded before the module did
          if ($spinner) {
            $spinner = $.createSpinner().addClass('mw-editsection-like').css(
              'min-width', $button.css('min-width'));
            $button.hide().after($spinner);
          }
        });
        var requestData = {
          action: 'parse',
          prop: 'text'
        };
        if (template) {
          requestData.page = page;
        } else {
          requestData.title = mw.config.get('wgPageName');
          requestData.text = '{' + '{:' + page + '}}';
        }
        new mw.Api().get(requestData).done(function(data) {
          var html = data.parse.text['*'];
          $contentContainer.html(html).removeClass('noscript');
          // Resolve self-links
          if (template) {
            var curPage = '/' + mw.config.get('wgPageName');
            $contentContainer.find('a').each(function() {
              var $link = $(this);
              if ($link.attr('href') === curPage) {
                $link.replaceWith($('<strong>').addClass('selflink').append(
                  $link.contents()));
              }
            });
            html = $contentContainer.html();
          }
          $body.data('pageloader-content', html);
          // Fire content hook on the new content, running all this stuff again and more :)
          mw.hook('wikipage.content').fire($contentContainer);
          if (treeview) {
            $body.find('.noscript').remove();
            $content = extractList($contentContainer, treeviewClass);
            $content.insertAfter($body);
          }
          $spinner.remove();
          $spinner = false;
          $buttonLink.text(i18n.hideText);
          $button.show();
          $body.addClass('pageloader-contentloaded');
        }).fail(function(_, error) {
          $spinner.remove();
          $spinner = false;
          $button.show();
          var errorText = '';
          if (error.textStatus) {
            errorText = error.textStatus;
          } else if (error.error) {
            errorText = error.error.info;
          }
          mw.notify(errorText, {
            title: i18n.loadErrorTitle,
            autoHide: false
          });
        });
      });
    });
  }());
  /**
   * Element animator
   *
   * Will cycle the active class on any child elements
   * within an element with the animated class.
   */
  (function() {
    if (!mcw.animate) {
      mcw.animate = setInterval(function() {
        $('.animated').each(function() {
          var $elem = $(this);
          var $current = $elem.children('.active');
          var $next = $current.nextAll(':not(.skip):first');
          // Loop back to the start
          if (!$next.length) {
            $next = $elem.children(':not(.skip):first');
          }
          $current.removeClass('active');
          $next.addClass('active');
        });
      }, 2000);
    }
  }());
});
// SS220 import end