MediaWiki:Common.js: Difference between revisions

From Official Factorio Wiki
Jump to navigation Jump to search
(added req tech updating)
(expanded tab headers to 11)
 
(134 intermediate revisions by 3 users not shown)
Line 1: Line 1:
/* Any JavaScript here will be loaded for all users on every page load. */
/* Any JavaScript here will be loaded for all users on every page load. */
/* Infobox updating */


var NoInfobox = ["Basic oil processing", "Advanced oil processing", "Coal liquefaction", "Empty barrel", "Heavy oil cracking", "Light oil cracking", "Solid fuel from heavy oil", "Solid fuel from light oil", "Solid fuel from petroleum gas", "Water barrel", "Crude oil barrel", "Heavy oil barrel", "Sulfuric acid barrel", "Light oil barrel", "Petroleum gas barrel", "Lubricant barrel", "Empty crude oil barrel", "Empty heavy oil barrel", "Empty light oil barrel", "Empty lubricant barrel", "Empty petroleum gas barrel", "Empty sulfuric acid barrel", "Empty water barrel", "Fill crude oil barrel", "Fill heavy oil barrel", "Fill light oil barrel", "Fill lubricant barrel", "Fill petroleum gas barrel", "Fill sulfuric acid barrel", "Fill water barrel"]
var apiUrl = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + "/api.php"
var version = "0.15.12";


/* Script in here will be executed when the page is "ready" */
$(document).ready(function() {
getNumberOfActiveUsers();
var elem = document.getElementById("evoChecker");
if(elem != null) {
elem.innerHTML =
'Alternatively, enter an evolution factor below to see the chances.<br>' +
'<input style="margin-bottom:10px" type="number" id="evoInput" min=0 max=1 step=0.01 placeholder="Evolution" onchange="calcEvo()"></input><br>' +
'<table style="float:left;margin-right:10px" class="wikitable" id="evoOutputBiter"></table>' +
'<table class="wikitable" id="evoOutputSpitter"></table>';
calcEvo();
}
});
/* show correct number of active users on the main page */


var Para = "";
function getNumberOfActiveUsers() {
function getInputPara(Item, Search, Length, Name, ItemName) {
if (document.getElementById("active-users")) {
var ParaStart = Item.search(Search) + Length; //finds the beginning of the para, is after para-name
$.ajax({
if (ParaStart < Length) {
url: apiUrl,
console.log(ItemName + ": No " + Name + " found.");
data: {
Para = "";
format: 'json',
} else {
action: 'query',
var ParaCut = Item.slice(ParaStart);  //lets the string begin after the parameter name
list: 'allusers',
var ParaEnd = ParaCut.search(/\||}}/); //finds the end of the parameter definition
aulimit: 500,
if (ParaEnd < 1) { //Para ends at para-end if it exists
auactiveusers: true
Para = ParaCut;
},
} else {
dataType: 'json',
Para = ParaCut.slice(0, ParaEnd);
type: 'GET',
}
success: function(data) {
document.getElementById("active-users").innerHTML = data.query.allusers.length.toString();
},
error: function(xhr) {
console.log( 'Error: Request failed.' );
}
});
}
}
return Para;
};
};


/* Collapsible list on [[Prototype definitions]] */
$(".prototype-tree li").each(function (index, element) {
  if ( $( element ).children("ul").length > 0 ) {
    $( element ).addClass("prototype-tree-parent");
  };
});
$(".prototype-tree li.prototype-tree-parent").on("click", function(event) {
// only collapse if I clicked a li or the direct child of a li that is not another list or a link
  if ( $( event.currentTarget ).children("ul").length > 0 && $( event.target ).get(0).tagName != "UL" && $( event.target ).get(0).tagName != "A" && ($( event.target ).hasClass("prototype-tree-parent") || $( event.target ).parent().hasClass("prototype-tree-parent")) ) {
    $( event.currentTarget ).children("ul")[0].classList.toggle("hidden");
    $( event.currentTarget ).toggleClass("prototype-tree-parent-collapsed");
    return false; // prevents further event bubbling
  }
});
/* Evolution calc */
//values are in the form [evolution, weight]
const biterSpawner = [
["Small Biter",    [[0.0, 0.3], [0.6, 0.0]]],
["Medium Biter",  [[0.2, 0.0], [0.6, 0.3], [0.7, 0.1]]],
["Big Biter",      [[0.5, 0.0], [1.0, 0.4]]],
["Behemoth Biter", [[0.9, 0.0], [1.0, 0.3]]]
];
const spitterSpawner = [
["Small Biter",      [[0.0, 0.3], [0.35, 0.0]]],
["Small Spitter",    [[0.25, 0.0], [0.5, 0.3], [0.7, 0.0]]],
["Medium Spitter",  [[0.4, 0.0], [0.7, 0.3], [0.9, 0.1]]],
["Big Spitter",      [[0.5, 0.0], [1.0, 0.4]]],
["Behemoth Spitter", [[0.9, 0.0], [1.0, 0.3]]]
];
//calculates the interpolated value
function lerp(low, high, pos) {
const s = high[0] - low[0];
const l = (pos - low[0]) / s;
return (low[1] * (1-l)) + (high[1] * l);
};


var PagePara = "";
//gets the weight list
function getOldPara(Content, PageParaStart, Length, Name, ItemName) {
function getValues(map, evo) {
if (PageParaStart < Length) { //if the start is less than the length of the para name (Name) then the search was unsuccessful
var result = {};
console.log(ItemName + ": No " + Name + " found on page.");
var sum = 0;
PagePara = "";
map.forEach(function(data) {
} else {
const list = data[1];
var PageParaCut = Content.slice(PageParaStart);
var low = list[0];
PageParaStart = PageParaCut.search(/\w/);
var high = list[list.length-1];
PageParaCut = PageParaCut.slice(PageParaStart); //removes anything before the parameter that does not belong there, like = and \s
list.forEach(function(val) {
var PageParaEnd = PageParaCut.search(/\||}}/); //finds the end of the parameter definition
if(val[0] <= evo && val[0] >  low[0])  low = val;
if (PageParaEnd < 1) { //Para ends at para-end if it exists
if(val[0] >= evo && val[0] < high[0]) high = val;
PagePara = PageParaCut;
});
} else {
var val = null;
PagePara = PageParaCut.slice(0, PageParaEnd);
if(evo <= low[0]) val = low[1];
}
else if(evo >= high[0]) val = high[1];
}
else val = lerp(low, high, evo);
return PagePara;
sum += val;
result[data[0]] = val;
});
Object.keys(result).forEach(function(data, index) {
result[data] = result[data] / sum;
});
return result;
};
};


var Summary = "";
function calcEvo() {
var NewContent = "";
const evo = document.getElementById("evoInput").value;
function UpdatePara(Content, Para, PagePara, Name, NewPageParaStart, Length, ItemName) { //also needs version, Summary, changes NewContent and Summary
genTable(getValues(biterSpawner, evo), document.getElementById("evoOutputBiter"), "Biter's Nest");
if (PagePara.length > 0) {
genTable(getValues(spitterSpawner, evo), document.getElementById("evoOutputSpitter"), "Spitter's Nest");
var NewPageParaCut = Content.slice(NewPageParaStart); //lets the string being after the parameter name
var NewPageParaEnd = NewPageParaCut.search(/\||}}/) + NewPageParaStart; //finds the end of the parameter definition, with added parastart so that it's relative to the start of the entire string, not the parameter string
if (Para.length > 0) {
NewContent = Content.slice(0, NewPageParaStart) + " = " + Para + "\n" + Content.slice(NewPageParaEnd);
console.log("Replaced " + ItemName + " " + Name + ".");
Summary = Summary + "Updated " + Name + " to " + version + ". ";
} else {
NewPageParaStart = NewPageParaStart - Length; //makes it so that the start of the para string if before the name, so that the name also gets deleted
NewContent = Content.slice(0, NewPageParaStart) + Content.slice(NewPageParaEnd); //removes what is between parastart and paraend from newcontent
console.log("Removed " + ItemName + " " + Name + ". ");
Summary = Summary + "Removed " + Name + ". ";
}
} else if (Para.length > 0) {
var InfoboxStart = Content.search(/{{Infobox/i) + 9; //finds the start of the infobox, excludes {{infobox from the resulting string
NewContent = Content.slice(0, InfoboxStart) + "\n|" + Name + " = " + Para + Content.slice(InfoboxStart);
console.log("Added " + ItemName + " " + Name + ". ");
Summary = Summary + "Added " + Name + ". ";
}
};
};


function percentile(value) {
return (value*100).toFixed(2) + "%";
};


function EditPage(Title, ItemName) { //also uses Summary, globalToken, NewContent
function genTable(data, tableElem, title) {
$.ajax({
var html = '<tr><th>'+title+'</th><th>Chance</th>';
url: 'https://wiki.factorio.com/api.php',
Object.keys(data).forEach(function(value) {
data: {
html += '<tr><td>'+value+'</td><td>'+percentile(data[value])+'</td>';
format: 'json',
action: 'edit',
title: Title,
text: NewContent,
token: globalToken,
summary: Summary,
bot: true,
nocreate: true
},
dataType: 'json',
type: 'POST',
success: function( data ) {
  console.log("Updated " + ItemName);
},
error: function( xhr ) {
console.log("Failed to update " + ItemName);
}
});
});
tableElem.innerHTML = html;
};
};


/* Template:Inventory tooltips */


$("#RecipeUpdate").click(function(){
var lastTouchTime = 0;
    getRecipes();
document.addEventListener('touchstart', updateLastTouchTime, true);
function updateLastTouchTime() {
  lastTouchTime = new Date();
}
 
$(".tab-head").mousemove(function(e) {
  if (e.buttons > 0) return;
  if (new Date() - lastTouchTime < 500) return;
  var countCssRules = document.styleSheets[0].cssRules.length;
  var newRule = '.tab-head:hover:after{display: block; left: ' + (e.offsetX + 20) + 'px; top: ' + (e.offsetY + 20) + 'px;}';
  document.styleSheets[0].insertRule(newRule, countCssRules);
});
});


function getRecipes() {
$(".tab .factorio-icon").mousemove(function(e) {
getUserGroup();
  if (e.buttons > 0) return;
if (UserGroup.some(isBot) == true) {
  if (new Date() - lastTouchTime < 500) return;
var RecipeInput = prompt("Please enter the recipes");
  var countCssRules = document.styleSheets[0].cssRules.length;
if (RecipeInput != null) {
  $(e.currentTarget).children("a").attr("title", "");
getToken();
  var text = $(e.currentTarget).children("a").children("img").attr("alt");
var Items = RecipeInput.split(/\s\s/g);
  var newRule = '.tab .factorio-icon:hover:after{display: block; ' + "content: '" + text + "'}";
console.log(Items.length + " Items detected");
  document.styleSheets[0].insertRule(newRule, countCssRules);
Items.forEach(RemoveDuplicateRecipesAndUpdateInfobox);
});
}
}
};


/* Template:BlueprintString */


function RemoveDuplicateRecipesAndUpdateInfobox(Recipes) {
$(".bps-box").click(function(event) {
var ItemNameEnd = Recipes.search("\\|");
var copyTarget = document.createElement("input");
var ItemName = Recipes.slice(0, ItemNameEnd);
copyTarget.setAttribute("value", $( event.target ).children("p").html());
ItemName = ItemName.trim();
document.body.appendChild(copyTarget);
copyTarget.select();
//Remove Itemnames if the item does not have a page on the wiki, so that the item is removed from the output
document.execCommand("copy");
NoInfobox.forEach(function(InfoboxName) {
document.body.removeChild(copyTarget);
if (ItemName == InfoboxName) {
});
console.log("Removed " + ItemName + " from output.");
 
ItemName = "";
/* Template:Inventory */
}
})
if (ItemName.length == 0) {
return;
}
var Recipe = getInputPara(Recipes, "\\|recipe = ", 10, "recipe", ItemName);
var TotalRaw = getInputPara(Recipes, "\\|total-raw = ", 13, "total-raw", ItemName);
var ExpRecipe = getInputPara(Recipes, "\\|expensive-recipe = ", 20, "expensive-recipe", ItemName);
var ExpTotalRaw = getInputPara(Recipes, "\\|expensive-total-raw = ", 23, "expensive-total-raw", ItemName);
//remove whitespace
Recipe = Recipe.trim();
TotalRaw = TotalRaw.trim();
ExpRecipe = ExpRecipe.trim();
ExpTotalRaw = ExpTotalRaw.trim();
//remove duplicate recipes, but only if the recipe actually exists
if ((ExpTotalRaw == ExpRecipe) && (ExpTotalRaw.length > 0)) {
ExpTotalRaw = "";
console.log(ItemName + ": Removed expensive-total-raw because it was a duplicate of expensive-recipe.");
} else if ((ExpTotalRaw == TotalRaw) && (ExpTotalRaw.length > 0)) {
ExpTotalRaw = "";
console.log(ItemName + ": Removed expensive-total-raw because it was a duplicate of total-raw.");
}
if ((ExpRecipe == Recipe) && (ExpRecipe.length > 0)) {
ExpRecipe = "";
console.log(ItemName + ": Removed expensive-recipe because it was a duplicate of recipe.");
}
if ((TotalRaw == Recipe) && (TotalRaw.length > 0)) {
TotalRaw = "";
console.log(ItemName + ": Removed total-raw because it was a duplicate of recipe.");
}
//get page content of the item -> OldContent
var OldContent = "";
$.ajax({
url: 'https://wiki.factorio.com/api.php',
data: {
format: 'json',
action: 'query',
titles: ItemName + '/infobox',
prop: 'revisions',
rvprop: 'content'
},
async: false,
dataType: 'json',
type: 'GET',
success: function( data ) {
var pages = data.query.pages;
var revisions = pages[Object.keys(pages)[0]].revisions[0];
OldContent = revisions[Object.keys(revisions)[2]];
var title = pages[Object.keys(pages)[0]].title;
},
error: function( xhr ) {
alert( 'Error: Request failed.' );
OldContent = "";
}
});
if (OldContent.length = 0) {
console.log("No " + ItemName + " page found.");
return;
}
//find recipes in page (OldContent)
var PageRecipeStart = OldContent.search(/(\s|\|)recipe/) + 7;
var PageRecipe = getOldPara(OldContent, PageRecipeStart, 7, "recipe", ItemName);


var PageTotalRawStart = OldContent.search(/(\s|\|)total-raw/) + 10;
$(".tab-head-1").click(function() {
var PageTotalRaw = getOldPara(OldContent, PageTotalRawStart, 10, "total-raw", ItemName);
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
var PageExpRecipeStart = OldContent.search(/(\s|\|)expensive-recipe/) + 17;
$(".tab").hide();
var PageExpRecipe = getOldPara(OldContent, PageExpRecipeStart, 17, "expensive-recipe", ItemName);
$(".tab-1").show();
});


var PageExpTotalRawStart = OldContent.search(/(\s|\|)expensive-total-raw/) + 20;
$(".tab-head-2").click(function() {
var PageExpTotalRaw = getOldPara(OldContent, PageExpTotalRawStart, 20, "expensive-total-raw", ItemName);
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
$(".tab").hide();
$(".tab-2").show();
});


$(".tab-head-3").click(function() {
//remove whitespace
$(".tab-head").removeClass("tab-head-active");
PageRecipe = PageRecipe.trim();
$(this).addClass("tab-head-active");
PageTotalRaw = PageTotalRaw.trim();
$(".tab").hide();
PageExpRecipe = PageExpRecipe.trim();
$(".tab-3").show();
PageExpTotalRaw = PageExpTotalRaw.trim();
});
Summary = "";
//change page if anything is different (this INCLUDES different formatting)
NewContent = "";
if ((PageRecipe == Recipe) && (PageTotalRaw == TotalRaw) && (PageExpRecipe == ExpRecipe) && (PageExpTotalRaw == ExpTotalRaw)) {
console.log(ItemName + " page was not changed.")
} else {
if (PageRecipe != Recipe) {
NewContent = OldContent;
var NewPageRecipeStart = NewContent.search(/(\s|\|)recipe/) + 7;
UpdatePara(NewContent, Recipe, PageRecipe, "recipe", NewPageRecipeStart, 7, ItemName);
}
if (PageTotalRaw != TotalRaw) {
if (NewContent.length == 0) {
NewContent = OldContent
}
var NewPageTotalRawStart = NewContent.search(/(\s|\|)total-raw/) + 10;
UpdatePara(NewContent, TotalRaw, PageTotalRaw, "total-raw", NewPageTotalRawStart, 10, ItemName);
}
if (PageExpRecipe != ExpRecipe) {
if (NewContent.length == 0) {
NewContent = OldContent
}
var NewPageExpRecipeStart = NewContent.search(/(\s|\|)expensive-recipe/) + 17;
UpdatePara(NewContent, ExpRecipe, PageExpRecipe, "expensive-recipe", NewPageExpRecipeStart, 17, ItemName);
}
if (PageExpTotalRaw != ExpTotalRaw) {
if (NewContent.length == 0) {
NewContent = OldContent
}
var NewPageExpTotalRawStart = NewContent.search(/(\s|\|)expensive-total-raw/) + 20;
UpdatePara(NewContent, ExpTotalRaw, PageExpTotalRaw, "expensive-total-raw", NewPageExpTotalRawStart, 20, ItemName);
}
}
//alright, NewContent should be defined, change page:
if (NewContent.length > 0) {
EditPage(ItemName + "/infobox", ItemName);
}
}


$("#ConsumerUpdate").click(function(){
$(".tab-head-4").click(function() {
    getConsumersAndStackSize();
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
$(".tab").hide();
$(".tab-4").show();
});
});


function getConsumersAndStackSize() {
$(".tab-head-5").click(function() {
getUserGroup();
$(".tab-head").removeClass("tab-head-active");
if (UserGroup.some(isBot) == false) {
$(this).addClass("tab-head-active");
return;
$(".tab").hide();
}
$(".tab-5").show();
var ItemInput = prompt("Please enter the consumers and the stack-sizes");
});
if (ItemInput != null) {
getToken();
var Items = ItemInput.split(/\s\s/g);
console.log(Items.length + " Items detected");
Items.forEach(UpdateInfoboxWithConsumersAndStackSize);
}
};


function UpdateInfoboxWithConsumersAndStackSize(Item) {
$(".tab-head-6").click(function() {
var ItemNameEnd = Item.search("\\|");
$(".tab-head").removeClass("tab-head-active");
var ItemName = Item.slice(0, ItemNameEnd);
$(this).addClass("tab-head-active");
ItemName = ItemName.trim();
$(".tab").hide();
$(".tab-6").show();
//Remove Items that don't have Infoboxes on the wiki
});
NoInfobox.forEach(function(InfoboxName) {
if (ItemName == InfoboxName) {
console.log("Removed " + ItemName + " from output.");
ItemName = "";
}
})
if (ItemName.length == 0) {
return;
}
var Consumers = getInputPara(Item, "\\|consumers = ", 13, "consumers", ItemName);
var StackSize = getInputPara(Item, "\\|stack-size = ", 14, "stack-size", ItemName);


Consumers = Consumers.trim();
$(".tab-head-7").click(function() {
StackSize = StackSize.trim();
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
$(".tab").hide();
//get page content of the item -> OldContent
$(".tab-7").show();
var OldContent = "";
});
$.ajax({
url: 'https://wiki.factorio.com/api.php',
data: {
format: 'json',
action: 'query',
titles: ItemName + '/infobox',
prop: 'revisions',
rvprop: 'content'
},
async: false,
dataType: 'json',
type: 'GET',
success: function( data ) {
var pages = data.query.pages;
var revisions = pages[Object.keys(pages)[0]].revisions[0];
OldContent = revisions[Object.keys(revisions)[2]];
var title = pages[Object.keys(pages)[0]].title;
},
error: function( xhr ) {
alert( 'Error: Request failed.' );
OldContent = "";
}
});
if (OldContent.length = 0) {
console.log("No " + ItemName + " page found.");
return;
}
//find recipes in page (OldContent)
var PageConsumersStart = OldContent.search(/(\s|\|)consumers/) + 10;
var PageConsumers = getOldPara(OldContent, PageConsumersStart, 10, "consumers", ItemName);
var PageStackSizeStart = OldContent.search(/(\s|\|)stack-size/) + 11;
var PageStackSize = getOldPara(OldContent, PageStackSizeStart, 11, "stack-size", ItemName);
PageConsumers = PageConsumers.trim();
PageStackSize = PageStackSize.trim();
Summary = "";
//change page if anything is different (this INCLUDES different formatting)
NewContent = "";
if ((PageConsumers == Consumers) && (PageStackSize == StackSize)) {
console.log(ItemName + " page was not changed.")
} else {
if (PageConsumers != Consumers) {
NewContent = OldContent;
var NewPageConsumersStart = NewContent.search(/(\s|\|)consumers/) + 10;
UpdatePara(NewContent, Consumers, PageConsumers, "consumers", NewPageConsumersStart, 10, ItemName);
}
if (PageStackSize != StackSize) {
if (NewContent.length == 0) {
NewContent = OldContent;
}
var NewPageStackSizeStart = NewContent.search(/(\s|\|)stack-size/) + 11;
UpdatePara(NewContent, StackSize, PageStackSize, "stack-size", NewPageStackSizeStart, 11, ItemName);
}
}
//alright, NewContent should be defined, change page:
if (NewContent.length > 0) {
EditPage(ItemName + "/infobox", ItemName);
}
}


$("#TechUpdate").click(function(){
$(".tab-head-8").click(function() {
    getTechnologies();
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
$(".tab").hide();
$(".tab-8").show();
});
});


function getTechnologies() {
$(".tab-head-9").click(function() {
getUserGroup();
$(".tab-head").removeClass("tab-head-active");
if (UserGroup.some(isBot) == false) {
$(this).addClass("tab-head-active");
return;
$(".tab").hide();
}
$(".tab-9").show();
var TechInput = prompt("Please enter the technologies");
});
if (TechInput != null) {
getToken();
var Techs = TechInput.split(/\s\s/g);
console.log(Techs.length + " Techs detected");
Techs.forEach(UpdateTechnologyInfobox);
}
}


function UpdateTechnologyInfobox(Tech) {
$(".tab-head-10").click(function() {
var TechNameEnd = Tech.search("\\|");
$(".tab-head").removeClass("tab-head-active");
var TechName = Tech.slice(0, TechNameEnd);
$(this).addClass("tab-head-active");
TechName = TechName.trim();
$(".tab").hide();
$(".tab-10").show();
});
var Cost = getInputPara(Tech, "\\|cost = ", 8, "cost", TechName);
var CostMulti = getInputPara(Tech, "\\|cost-multiplier = ", 19, "cost-multiplier", TechName);
var ExpCostMulti = getInputPara(Tech, "\\|expensive-cost-multiplier = ", 29, "expensive-cost-multiplier", TechName);
var ReqTech = getInputPara(Tech, "\\|required-technologies = ", 25, "required-technologies", TechName);
var Allows = getInputPara(Tech, "\\|allows = ", 10, "allows", TechName);
var Effects = getInputPara(Tech, "\\|effects = ", 11, "effects", TechName);


$(".tab-head-11").click(function() {
Cost = Cost.trim();
$(".tab-head").removeClass("tab-head-active");
CostMulti = CostMulti.trim();
$(this).addClass("tab-head-active");
ExpCostMulti = ExpCostMulti.trim();
$(".tab").hide();
ReqTech = ReqTech.trim();
$(".tab-11").show();
Allows = Allows.trim();
});
Effects = Effects.trim();
//get page content of the tech -> OldContent
var OldContent = "";
$.ajax({
url: 'https://wiki.factorio.com/api.php',
data: {
format: 'json',
action: 'query',
titles: TechName + ' (research)/infobox',
prop: 'revisions',
rvprop: 'content'
},
async: false,
dataType: 'json',
type: 'GET',
success: function( data ) {
var pages = data.query.pages;
var revisions = pages[Object.keys(pages)[0]].revisions[0];
OldContent = revisions[Object.keys(revisions)[2]];
var title = pages[Object.keys(pages)[0]].title;
},
error: function( xhr ) {
alert( 'Error: Request failed.' );
OldContent = "";
}
});
if (OldContent.length = 0) {
console.log("No " + TechName + " page found.");
return;
}
//find costs etc in page (OldContent)
var PageCostStart = OldContent.search(/(\s|\|)cost(\s|=)/) + 6;
var PageCost = getOldPara(OldContent, PageCostStart, 6, "cost", TechName);
var PageCostMultiStart = OldContent.search(/(\s|\|)cost-multiplier/) + 16;
var PageCostMulti = getOldPara(OldContent, PageCostMultiStart, 16, "cost-multiplier", TechName);
var PageExpCostMultiStart = OldContent.search(/(\s|\|)expensive-cost-multiplier/) + 26;
var PageExpCostMulti = getOldPara(OldContent, PageExpCostMultiStart, 26, "expensive-cost-multiplier", TechName);
var PageReqTechStart = OldContent.search(/(\s|\|)required-technologies/) + 22;
var PageReqTech = getOldPara(OldContent, PageReqTechStart, 22, "required-technologies", TechName);
var PageAllowsStart = OldContent.search(/(\s|\|)allows/) + 7;
var PageAllows = getOldPara(OldContent, PageAllowsStart, 7, "allows", TechName);
var PageEffectsStart = OldContent.search(/(\s|\|)effects/) + 8;
var PageEffects = getOldPara(OldContent, PageEffectsStart, 8, "effects", TechName);


//*** Language template ***//
PageCost = PageCost.trim();
if($(".languages-flags .flag").length == 0) {
PageCostMulti = PageCostMulti.trim();
console.log("Not showing languages bar because there's no other language's version of this page.");
PageExpCostMulti = PageExpCostMulti.trim();
$(".languages-container").hide();
PageReqTech = PageReqTech.trim();
PageAllows = PageAllows.trim();
PageEffects = PageEffects.trim();
Summary = "";
NewContent = "";
//change page if anything is different (this INCLUDES different formatting)
if ((PageCost == Cost) && (PageCostMulti == CostMulti) && (PageExpCostMulti == ExpCostMulti) && (PageReqTech == ReqTech) && (PageAllows == Allows) && (PageEffects == Effects)) {
console.log(TechName + " page was not changed.")
} else {
if (PageCost != Cost) {
NewContent = OldContent;
var NewPageCostStart = NewContent.search(/(\s|\|)cost(\s|=)/) + 6;
UpdatePara(NewContent, Cost, PageCost, "cost", NewPageCostStart, 6, TechName);
}
if (PageCostMulti != CostMulti) {
if (NewContent.length == 0) {
NewContent = OldContent;
}
var NewPageCostMultiStart = NewContent.search(/(\s|\|)cost-multiplier/) + 16;
UpdatePara(NewContent, CostMulti, PageCostMulti, "cost-multiplier", NewPageCostMultiStart, 16, TechName);
}
if (PageExpCostMulti != ExpCostMulti) {
if (NewContent.length == 0) {
NewContent = OldContent;
}
var NewPageExpCostMultiStart = NewContent.search(/(\s|\|)expensive-cost-multiplier/) + 26;
UpdatePara(NewContent, ExpCostMulti, PageExpCostMulti, "expensive-cost-multiplier", NewPageExpCostMultiStart, 26, TechName);
}
if (PageReqTech != ReqTech) {
if (NewContent.length == 0) {
NewContent = OldContent;
}
var NewPageReqTechStart = NewContent.search(/(\s|\|)required-technologies/) + 22;
UpdatePara(NewContent, ReqTech, PageReqTech, "required-technologies", NewPageReqTechStart, 22, TechName);
}
if (PageAllows != Allows) {
if (NewContent.length == 0) {
NewContent = OldContent;
}
var NewPageAllowsStart = NewContent.search(/(\s|\|)allows/) + 7;
UpdatePara(NewContent, Allows, PageAllows, "allows", NewPageAllowsStart, 7, TechName);
}
if (PageEffects != Effects) {
if (NewContent.length == 0) {
NewContent = OldContent;
}
var NewPageEffectsStart = NewContent.search(/(\s|\|)effects/) + 8;
UpdatePara(NewContent, Effects, PageEffects, "effects", NewPageEffectsStart, 8, TechName);
}
}
//alright, NewContent should be defined, change page:
if (NewContent.length > 0) {
EditPage(TechName + " (research)/infobox", TechName);
}
}
}


 
//Spoiler template
$("#ReqTechUpdate").click(function(){
$(".spoiler-container .button").click(function() {
    getReqTech();
$(this).siblings(".text").toggle("slow");
});
});


function getReqTech() {
//* General/generic functions *//
getUserGroup();
if (UserGroup.some(isBot) == false) {
return;
}
var Input = prompt("Please enter the required technologies");
if (Input != null) {
getToken();
var Items = Input.split(/\s\s/g);
console.log(Items.length + " Items detected");
Items.forEach(UpdateReqTechsInfobox);
}
}
 
function UpdateReqTechsInfobox(Item) {
var ItemNameEnd = Item.search("\\|");
var ItemName = Item.slice(0, ItemNameEnd);
ItemName = ItemName.trim();
//Remove Items that don't have Infoboxes on the wiki
NoInfobox.forEach(function(InfoboxName) {
if (ItemName == InfoboxName) {
console.log("Removed " + ItemName + " from output.");
ItemName = "";
}
})
if (ItemName.length == 0) {
return;
}
var ReqTech = getInputPara(Item, "\\|required-technologies = ", 25, "required-technologies", ItemName);
ReqTech = ReqTech.trim();
//get page content of the item -> OldContent
var OldContent = "";
$.ajax({
url: 'https://wiki.factorio.com/api.php',
data: {
format: 'json',
action: 'query',
titles: ItemName + '/infobox',
prop: 'revisions',
rvprop: 'content'
},
async: false,
dataType: 'json',
type: 'GET',
success: function( data ) {
var pages = data.query.pages;
var revisions = pages[Object.keys(pages)[0]].revisions[0];
OldContent = revisions[Object.keys(revisions)[2]];
var title = pages[Object.keys(pages)[0]].title;
},
error: function( xhr ) {
alert( 'Error: Request failed.' );
OldContent = "";
}
});
if (OldContent.length = 0) {
console.log("No " + ItemName + " page found.");
return;
}
//find recipes in page (OldContent)
var PageReqTechStart = OldContent.search(/(\s|\|)required-technologies/) + 22;
var PageReqTech = getOldPara(OldContent, PageReqTechStart, 22, "required-technologies", ItemName);
PageReqTech = PageReqTech.trim();
Summary = "";
NewContent = "";
if (PageReqTech == ReqTech) {
console.log(ItemName + " page was not changed.")
} else {
var NewPageReqTechStart = OldContent.search(/(\s|\|)required-technologies/) + 22;
UpdatePara(OldContent, ReqTech, PageReqTech, "required-technologies", NewPageReqTechStart, 22, ItemName);
}
//alright, NewContent should be defined, change page:
if (NewContent.length > 0) {
EditPage(TechName + " (research)/infobox", TechName);
}
}


/* User is bot if UserGroup.some(isBot) == true */
/* User is bot if userGroup.some(isBot) == true */


var UserGroup = "";
var userGroup = "";


function getUserGroup() {
function getUserGroup() {
$.ajax({
$.ajax({
url: 'https://wiki.factorio.com/api.php',
url: apiUrl,
data: {
data: {
format: 'json',
format: 'json',
Line 617: Line 272:
type: 'GET',
type: 'GET',
success: function(data) {
success: function(data) {
UserGroup = data.query.userinfo.groups
userGroup = data.query.userinfo.groups
},
},
});
});
Line 625: Line 280:
return group == "bot";
return group == "bot";
}
}
/* Get token of this session */


var globalToken;
var globalToken;
Line 630: Line 287:
function getToken() {
function getToken() {
     $.ajax({
     $.ajax({
         url: 'https://wiki.factorio.com/api.php',
         url: apiUrl,
         data: {
         data: {
             format: 'json',
             format: 'json',
Line 644: Line 301:
         },
         },
         error: function( xhr ) {
         error: function( xhr ) {
             console.log("Failed to perform null edit");
             console.log("Failed to get token.");
         }
         }
     });
     });
}
}


/*** Language template ***/
if($(".languages-flags .flag").length == 0) {
console.log("Not showing languages bar because there's no other language's version of this page.");
$(".languages-container").hide();
}


//Spoiler template JavaScript
function genericEditPage(title, content, summary) {
$(".spoiler-container .button").click(function() {
$.ajax({
  $(this).siblings(".text").toggle("slow");
url: apiUrl,
});
data: {
 
format: 'json',
var wantedPagesListsLocation = "User:TheWombatGuru/WantedPages"
action: 'edit',
$("#create-wanted-pages-list").click(function(){
title: title,
    getToken();
text: content,
    createWantedPagesLists();
token: globalToken,
});
summary: summary,
 
bot: true,
function createWantedPagesLists() {
nocreate: true
    getUserGroup();
},
    if (UserGroup.some(isBot) == false) {
dataType: 'json',
      return;
type: 'POST',
    }
success: function( data ) {
    var wantedPages = getWantedPages();
console.log("Edited " + title);
    wantedPages = wantedPages.sort(compare);
},
    splitWantedPagesIntoDifferentLanguages(wantedPages);
error: function( xhr ) {
alert("Failed to edit " + title);
}
});
};
};


function splitWantedPagesIntoDifferentLanguages(wantedPages) {
  var czechWantedPages = [];
  var germanWantedPages = [];
  var spanishWantedPages = [];
  var frenchWantedPages = [];
  var italianWantedPages = [];
  var japaneseWantedPages = [];
  var dutchWantedPages = [];
  var polishWantedPages = [];
  var portugueseWantedPages = [];
  var russianWantedPages = [];
  var swedishWantedPages = [];
  var ukrainianWantedPages = [];
  var chineseWantedPages = [];
  var turkishWantedPages = [];
  var wantedFiles = [];
  var wantedTemplates = [];
  var otherWantedPages = [];


  for (var i = 0; i < wantedPages.length; i++) {
function createPage(pageTitle, content, summary) {
     switch (wantedPages[i].title.slice(-3)) {//"/cs", "/de", "/es", "/fr", "/it", "/ja", "/nl", "/pl", "/-br", "/ru", "/sv", "/uk", "/zh", "/tr"
     $.ajax({
      case "/cs": czechWantedPages.push(wantedPages[i]); break;
        url: apiUrl,
      case "/de": germanWantedPages.push(wantedPages[i]); break;
        data: {
      case "/es": spanishWantedPages.push(wantedPages[i]); break;
format: 'json',
      case "/fr": frenchWantedPages.push(wantedPages[i]); break;
action: 'edit',
      case "/it": italianWantedPages.push(wantedPages[i]); break;
title: pageTitle,
      case "/ja": japaneseWantedPages.push(wantedPages[i]); break;
text: content,
      case "/nl": dutchWantedPages.push(wantedPages[i]); break;
token: globalToken,
      case "/pl": polishWantedPages.push(wantedPages[i]); break;
summary: summary,
      case "-br": portugueseWantedPages.push(wantedPages[i]); break;
bot: true
      case "/ru": russianWantedPages.push(wantedPages[i]); break;
        },
      case "/sv": swedishWantedPages.push(wantedPages[i]); break;
        async: false,
      case "/uk": ukrainianWantedPages.push(wantedPages[i]); break;
        dataType: 'json',
      case "/zh": chineseWantedPages.push(wantedPages[i]); break;
        type: 'POST',
      case "/tr": turkishWantedPages.push(wantedPages[i]); break;
        success: function( data ) {
      default: if (wantedPages[i].title.slice(0, 5) == "File:") {wantedFiles.push(wantedPages[i])} else if (wantedPages[i].title.slice(0, 9) == "Template:") {wantedTemplates.push(wantedPages[i])} else {otherWantedPages.push(wantedPages[i])}; break;
console.log("Created page: " + pageTitle);
    }
        },
  }
        error: function( xhr ) {
 
console.log("Failed to create page");
  createWantedPagesPage("cs", czechWantedPages, "Czech");
        }
  createWantedPagesPage("de", germanWantedPages, "German");
    });
  createWantedPagesPage("es", spanishWantedPages, "Spanish");
  createWantedPagesPage("fr", frenchWantedPages, "French");
  createWantedPagesPage("it", italianWantedPages, "Italian");
  createWantedPagesPage("ja", japaneseWantedPages, "Japanese");
  createWantedPagesPage("nl", dutchWantedPages, "Dutch");
  createWantedPagesPage("pl", polishWantedPages, "Polish");
  createWantedPagesPage("pt-br", portugueseWantedPages, "Portuguese");
  createWantedPagesPage("ru", russianWantedPages, "Russian");
  createWantedPagesPage("sv", swedishWantedPages, "Swedish");
  createWantedPagesPage("uk", ukrainianWantedPages, "Ukrainian");
  createWantedPagesPage("zh", chineseWantedPages, "Chinese");
  createWantedPagesPage("tr", turkishWantedPages, "Turkish");
 
  createWantedPagesPage("file", wantedFiles, "Files");
  createWantedPagesPage("template", wantedTemplates, "Templates");
  createWantedPagesPage("other", otherWantedPages, "Other");
}
}


function createWantedPagesPage(location, wantedPages, language) {
function getBacklinks(page) {
  var formattedWantedPages = "Number of wanted pages in " + language + ": " + wantedPages.length + "\n{|class=wikitable\n!#\n!Page\n!Links to this page";
var backlinks = [];
$.ajax({
url: apiUrl,
data: {
format: 'json',
action: 'query',
list: 'backlinks',
bltitle: page,
bllimit: 1000,
},
async: false,
type: 'GET',
success: function( data ) {
backlinks = data.query.backlinks;
},
error: function( xhr ) {
alert( 'Error: Backlinks request failed.' );
}
});
return backlinks;
};


  for (var i = 0; i < wantedPages.length; i++) {
function getFileUsage(file) {
    formattedWantedPages = formattedWantedPages.concat("\n|-\n|" + (i + 1) + "\n|[https://wiki.factorio.com/index.php?title=" + encodeURI(wantedPages[i].title) + " " + wantedPages[i].title + "]\n|[https://wiki.factorio.com/index.php?title=Special:WhatLinksHere/" + encodeURI(wantedPages[i].title) + " " + wantedPages[i].value + "]");
var imageusage = [];
  }
$.ajax({
 
url: apiUrl,
  formattedWantedPages = formattedWantedPages.concat("\n|}");
data: {
 
format: 'json',
  createPage(wantedPagesListsLocation + "/" + location, formattedWantedPages, "(BOT) - Update the list of wanted pages for " + language + ".");
action: 'query',
}
list: 'imageusage',
iutitle: file,
iulimit: 1000
},
async: false,
type: 'GET',
success: function( data ) {
imageusage = data.query.imageusage;
},
error: function( xhr ) {
alert( 'Error: Imageusage request failed.' );
}
});
return imageusage;
};


function performNullEdit(pageTitle, summary) {
function performNullEdit(pageTitle, summary) {
     $.ajax({
     $.ajax({
         url: 'https://wiki.factorio.com/api.php',
         url: apiUrl,
         data: {
         data: {
             format: 'json',
             format: 'json',
Line 774: Line 429:
function purgeWhatLinksHere(pageTitle) {
function purgeWhatLinksHere(pageTitle) {
     $.ajax({
     $.ajax({
         url: 'https://wiki.factorio.com/api.php',
         url: apiUrl,
         data: {
         data: {
             format: "json",
             format: "json",
Line 799: Line 454:
function purgePage(pageTitle) {
function purgePage(pageTitle) {
     $.ajax({
     $.ajax({
         url: 'https://wiki.factorio.com/api.php',
         url: apiUrl,
         data: {
         data: {
             action: 'purge',
             action: 'purge',
Line 817: Line 472:
     });
     });
}
}
function compare(a,b) {
  if (parseInt(a.value) > parseInt(b.value))
    return -1;
  if (parseInt(a.value) < parseInt(b.value))
    return 1;
  if (a.title < b.title)
    return -1;
  if (a.title > b.title)
    return 1;
  return 0;
}
function createPage(pageTitle, content, summary) {
    $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'edit',
            title: pageTitle,
            text: content,
            token: globalToken,
            summary: summary,
            bot: true
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
          console.log("created page");
        },
        error: function( xhr ) {
            console.log("failed to create page");
        }
    });
}
function getWantedPages() {
  var wantedPages = [];
  $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'query',
            list: 'querypage',
            qppage: 'Wantedpages',
            qplimit: '5000',
        },
        async: false,
        dataType: 'json',
        type: 'GET',
        success: function( data ) {
            var results = data.query.querypage.results;
            for (var i = 0; i < results.length; i++) {
              var pageObject = new WantedPage(results[i].title, results[i].value);
              var alreadyInArray = false;
              for (var j = 0; j < wantedPages.length; j++) {
                if (wantedPages[j].title == pageObject.title) {
                    alreadyInArray = true;
                }
              }
              if (!alreadyInArray) {
                wantedPages.push(pageObject);
              }
              if (pageObject.title == "Rocket defense/it") {
              }
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed. Category' );
        }
  });
$.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'query',
            list: 'querypage',
            qppage: 'Wantedpages',
            qplimit: '5000',
            qpoffset: '3000',
        },
        async: false,
        dataType: 'json',
        type: 'GET',
        success: function( data ) {
            var results = data.query.querypage.results;
            for (var i = 0; i < results.length; i++) {
              var pageObject = new WantedPage(results[i].title, results[i].value);
              var alreadyInArray = false;
              for (var j = 0; j < wantedPages.length; j++) {
                if (wantedPages[j].title == pageObject.title) {
                    alreadyInArray = true;
                }
              }
              if (!alreadyInArray) {
                wantedPages.push(pageObject);
              }
              if (pageObject.title == "Rocket defense/it") {
              }
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed. Category' );
        }
  });
  return wantedPages;
};
function WantedPage(pageTitle, pageValue) {
  this.title = pageTitle;
  this.value = pageValue;
}
/* OLD INFOBOX CONVERSION TOOLS */
/*function targetAllPagesInCategory(category) {
    var languageSuffixes = ["/fr", "/ru", "/de"]; //, "/cs", "/de", "/es", "/fr", "/it", "/nl", "/pl", "/pt-br", "/ru", "/sv", "/uk", "/zh", ""];
    for (var j = 0; j < languageSuffixes.length; j++) {
      $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'query',
            list: 'categorymembers',
            cmtitle: (category + languageSuffixes[j]),
            cmlimit: 500
        },
        dataType: 'json',
        type: 'GET',
        success: function( data ) {
            var pages = data.query.categorymembers;
            for (var i = 0; i < pages.length; i++) {
                    //purgePage(pages[i].title);
                    extractPageInfo(pages[i].title, "9c28a1344a20bf189fda7d58339e518257f2dd9b+\\");
               
            }
            if ( data && data.query && data.query.result == 'Success' ) {
                window.location.reload(); // reload page if edit was successful
            } else if ( data && data.error ) {
                //alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info + 'Category' );
            } else {
                //alert( 'Error: Unknown result from API. Category' );
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed. Category' );
        }
    });
  }
}
function extractPageInfo(pageTitle, token) {
    $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'query',
            titles: pageTitle,
            prop: 'revisions',
            rvprop: 'content'
        },
        async: false,
        dataType: 'json',
        type: 'GET',
        success: function( data ) {
            var pages = data.query.pages;
            var revisions = pages[Object.keys(pages)[0]].revisions[0];
            var content = revisions[Object.keys(revisions)[2]]
            var title = pages[Object.keys(pages)[0]].title;
            createNewInfoboxPage(title, content, token);
            if ( data && data.query && data.query.result == 'Success' ) {
                window.location.reload(); // reload page if edit was successful
            } else if ( data && data.error ) {
                //alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info );
            } else {
                //alert( 'Error: Unknown result from API.' );
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed.' );
        }
    });
}
function createNewInfoboxPage(page, contentOfMainPage, token) {
    var infoboxText = getInfoboxFromFullPageContent(contentOfMainPage);
    var infoboxPageTitle = page.replace(/\/(de|fr|nl|it|es|ru|pt\-br|cs|pl|sv|uk|zh)/g, function(piece) {return "";}).concat("/infobox");
    var oldPageRevisedText = getOldPageRevisedText(page, contentOfMainPage, infoboxPageTitle);
    removeInfoboxFromMain(page, oldPageRevisedText, token);
    if (infoboxText != null) {
      if (/\/(de|fr|nl|it|es|ru|pt\-br|cs|pl|sv|uk|zh)/g.test(page)) {
        return;
      }
      var newPageTitle = page.concat("/infobox");
      var convertedInfoboxText = convertInfobox(infoboxText, token);
      createPage(newPageTitle, convertedInfoboxText, token, page, contentOfMainPage);
    }
}
function getOldPageRevisedText(pageTitle, content, infoboxPageTitle) {
    content = content.replace(/{{\bCombat\b(\s+(\||{).+)+\s}}/gi, function (piece) {
        return "{{:" + infoboxPageTitle + "}}";
    });
    return content;
}
function removeInfoboxFromMain(pageTitle, content, token) {
    $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'edit',
            title: pageTitle,
            text: content,
            bot: true,
            token: token,
            summary: "(BOT) - Replaced old infobox with a link to the /infobox subpage"
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
            if ( data && data.edit && data.edit.result == 'Success' ) {
                window.location.reload(); // reload page if edit was successful
            } else if ( data && data.error ) {
                //alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info );
            } else {
                //alert( 'Error: Unknown result from API.' );
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed.' );
        }
    })
};
function getInfoboxFromFullPageContent(contentOfPage) {
    var matches = contentOfPage.match(/{{\bCombat\b(\s+\|.+)+\s}}/gi);
if (matches != null && matches.length > 0) {
infoboxText = matches[0];
} else {
infoboxText = null;
}
    return infoboxText;
}
function convertInfobox(text) {
    text = text.replace(/{{(\w+)/g, function (piece, $1) {
        var returnText = "{{Infobox\n| category = ";
        $1 = $1.toLowerCase();
        switch ($1) {
            case "item":
                returnText = returnText.concat("Items");
                break;
            case "machinery":
                returnText = returnText.concat("Machinery");
                break;
            case "combat":
                returnText = returnText.concat("Combat");
                break;
            case "technology":
                returnText = returnText.concat("Technology");
        }
        switch ($1) {
            case "machinery":
                returnText = returnText.concat("\n| category-name = Machine");
                break;
            case "item":
                returnText = returnText.concat("\n| category-name = Item");
                break;
        }
        return returnText;
    });
    text = text.replace("stack_size", "stack-size");
    text = text.replace("poweroutput", "power-output");
    text = text.replace("input", "recipe");
    text = text.replace("raw", "total-raw");
    text = text.replace("technologies", "required-technologies");
    text = text.replace("costmultiplier", "cost-multiplier");
    text = text.replace("requirements", "required-technologies");
    text = text.replace("walkingspeed", "walking-speed");
    text = text.replace("storagesize", "storage-size");
    text = text.replace("gridsize", "grid-size");
    text = text.replace("shootingspeed", "shooting-speed");
    text = text.replace("damagebonus", "damage-bonus");
    text = text.replace("clustersize", "cluster-size");
    text = text.replace("aoesize", "area-of-effect-size");
    text = text.replace("magazinesize", "magazine-size");
    text = text.replace("recharge", "robot-recharge-rate");
    text = text.replace("rechargebuffer", "internal-buffer-recharge-rate");
    text = text.replace("wirereach", "wire-reach");
    text = text.replace("craftingspeed", "crafting-speed");
    text = text.replace("smeltingspeed", "smelting-speed");
    text = text.replace("miningpower", "mining-power");
    text = text.replace("miningspeed", "mining-speed");
    text = text.replace("miningarea", "mining-area");
    text = text.replace("supplyarea", "supply-area");
    text = text.replace("constructionarea", "construction-area");
    text = text.replace("lifetime", "lifespan");
    text = text.replace("inventorysizebonus", "inventory-size-bonus");
    text = text.replace("gridsize", "grid-size");
    text = text.replace("boosttechs", "boosting-technologies");
    text = text.replace("allowstech", "allows");
    text = text.replace("storage", "storage-size");
    text = text.replace(/\|\s*\brecipe\b\s*=\s*(.+)\n\|\s*\boutput\b\s*=\s*(.+)/g, function (piece, $1, $2) {
        return "| recipe = " + $1 + " = " + $2;
    });
    text = text.concat("<noinclude>[[Category:Infobox page]]</noinclude>");
    return text;
}
function createPage(pageTitle, content, token, page, contentOfMainPage) {
    $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'edit',
            title: pageTitle,
            text: content,
            bot: true,
            createonly: true,
            token: token,
            summary: "(BOT) - Created infobox sub page for " + page
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
         
            if ( data && data.edit && data.edit.result == 'Success' ) {
                window.location.reload(); // reload page if edit was successful
            } else if ( data && data.error ) {
                //alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info );
            } else {
                //alert( 'Error: Unknown result from API.' );
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed.' );
        }
    });
}*/
/* END OF OLD INFOBOX CONVERSION TOOL */

Latest revision as of 07:44, 21 October 2024

/* Any JavaScript here will be loaded for all users on every page load. */

var apiUrl = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + "/api.php"

/* Script in here will be executed when the page is "ready" */
$(document).ready(function() {
	getNumberOfActiveUsers();
	var elem = document.getElementById("evoChecker");
	if(elem != null) {
		elem.innerHTML =
		'Alternatively, enter an evolution factor below to see the chances.<br>' +
		'<input style="margin-bottom:10px" type="number" id="evoInput" min=0 max=1 step=0.01 placeholder="Evolution" onchange="calcEvo()"></input><br>' +
		'<table style="float:left;margin-right:10px" class="wikitable" id="evoOutputBiter"></table>' +
		'<table class="wikitable" id="evoOutputSpitter"></table>';
		calcEvo();
	}
});

/* show correct number of active users on the main page */

function getNumberOfActiveUsers() {
	if (document.getElementById("active-users")) {
		$.ajax({
			url: apiUrl,
			data: {
				format: 'json',
				action: 'query',
				list: 'allusers',
				aulimit: 500,
				auactiveusers: true
			},
			dataType: 'json',
			type: 'GET',
			success: function(data) {
				document.getElementById("active-users").innerHTML = data.query.allusers.length.toString();
			},
			error: function(xhr) {
				console.log( 'Error: Request failed.' );
			}
		});
	}
};

/* Collapsible list on [[Prototype definitions]] */

$(".prototype-tree li").each(function (index, element) {
  if ( $( element ).children("ul").length > 0 ) {
    $( element ).addClass("prototype-tree-parent");
  };
});

$(".prototype-tree li.prototype-tree-parent").on("click", function(event) {
 // only collapse if I clicked a li or the direct child of a li that is not another list or a link
  if ( $( event.currentTarget ).children("ul").length > 0 && $( event.target ).get(0).tagName != "UL" && $( event.target ).get(0).tagName != "A" && ($( event.target ).hasClass("prototype-tree-parent") || $( event.target ).parent().hasClass("prototype-tree-parent")) ) {
    $( event.currentTarget ).children("ul")[0].classList.toggle("hidden");
    $( event.currentTarget ).toggleClass("prototype-tree-parent-collapsed");
    return false; // prevents further event bubbling
  }
});

/* Evolution calc */

//values are in the form [evolution, weight]
const biterSpawner = [
	["Small Biter",    [[0.0, 0.3], [0.6, 0.0]]],
	["Medium Biter",   [[0.2, 0.0], [0.6, 0.3], [0.7, 0.1]]],
	["Big Biter",      [[0.5, 0.0], [1.0, 0.4]]],
	["Behemoth Biter", [[0.9, 0.0], [1.0, 0.3]]]
];
const spitterSpawner = [
	["Small Biter",      [[0.0, 0.3], [0.35, 0.0]]],
	["Small Spitter",    [[0.25, 0.0], [0.5, 0.3], [0.7, 0.0]]],
	["Medium Spitter",   [[0.4, 0.0], [0.7, 0.3], [0.9, 0.1]]],
	["Big Spitter",      [[0.5, 0.0], [1.0, 0.4]]],
	["Behemoth Spitter", [[0.9, 0.0], [1.0, 0.3]]]
];

//calculates the interpolated value
function lerp(low, high, pos) {
	const s = high[0] - low[0];
	const l = (pos - low[0]) / s;
	return (low[1] * (1-l)) + (high[1] * l);
};

//gets the weight list
function getValues(map, evo) {
	var result = {};
	var sum = 0;
	map.forEach(function(data) {
		const list = data[1];
		var low = list[0];
		var high = list[list.length-1];
		list.forEach(function(val) {
			if(val[0] <= evo && val[0] >  low[0])  low = val;
			if(val[0] >= evo && val[0] < high[0]) high = val;
		});
		var val = null;
		if(evo <= low[0]) val = low[1];
		else if(evo >= high[0]) val = high[1];
		else val = lerp(low, high, evo);
		sum += val;
		result[data[0]] = val;
	});
	Object.keys(result).forEach(function(data, index) {
		result[data] = result[data] / sum;
	});
	return result;
};

function calcEvo() {
	const evo = document.getElementById("evoInput").value;
	genTable(getValues(biterSpawner, evo), document.getElementById("evoOutputBiter"), "Biter's Nest");
	genTable(getValues(spitterSpawner, evo), document.getElementById("evoOutputSpitter"), "Spitter's Nest");
};

function percentile(value) {
	return (value*100).toFixed(2) + "%";
};

function genTable(data, tableElem, title) {
	var html = '<tr><th>'+title+'</th><th>Chance</th>';
	Object.keys(data).forEach(function(value) {
		html += '<tr><td>'+value+'</td><td>'+percentile(data[value])+'</td>';
	});
	tableElem.innerHTML = html;
};

/* Template:Inventory tooltips */

var lastTouchTime = 0;
document.addEventListener('touchstart', updateLastTouchTime, true);
function updateLastTouchTime() {
  lastTouchTime = new Date();
}

$(".tab-head").mousemove(function(e) {
  if (e.buttons > 0) return;
  if (new Date() - lastTouchTime < 500) return;
  var countCssRules = document.styleSheets[0].cssRules.length;
  var newRule = '.tab-head:hover:after{display: block; left: ' + (e.offsetX + 20) + 'px; top: ' + (e.offsetY + 20) + 'px;}';
  document.styleSheets[0].insertRule(newRule, countCssRules);
});

$(".tab .factorio-icon").mousemove(function(e) {
  if (e.buttons > 0) return;
  if (new Date() - lastTouchTime < 500) return;
  var countCssRules = document.styleSheets[0].cssRules.length;
  $(e.currentTarget).children("a").attr("title", "");
  var text = $(e.currentTarget).children("a").children("img").attr("alt");
  var newRule = '.tab .factorio-icon:hover:after{display: block; ' + "content: '" + text + "'}";
  document.styleSheets[0].insertRule(newRule, countCssRules);
});

/* Template:BlueprintString */

$(".bps-box").click(function(event) {
	var copyTarget = document.createElement("input");
	copyTarget.setAttribute("value", $( event.target ).children("p").html());
	document.body.appendChild(copyTarget);
	copyTarget.select();
	document.execCommand("copy");
	document.body.removeChild(copyTarget);
});

/* Template:Inventory */

$(".tab-head-1").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-1").show();
});

$(".tab-head-2").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-2").show();
});

$(".tab-head-3").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-3").show();
});

$(".tab-head-4").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-4").show();
});

$(".tab-head-5").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-5").show();
});

$(".tab-head-6").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-6").show();
});

$(".tab-head-7").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-7").show();
});

$(".tab-head-8").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-8").show();
});

$(".tab-head-9").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-9").show();
});

$(".tab-head-10").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-10").show();
});

$(".tab-head-11").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-11").show();
});

//*** Language template ***//
if($(".languages-flags .flag").length == 0) {
	console.log("Not showing languages bar because there's no other language's version of this page.");
	$(".languages-container").hide();
}

//Spoiler template
$(".spoiler-container .button").click(function() {
	$(this).siblings(".text").toggle("slow");
});

//* General/generic functions *//

/* User is bot if userGroup.some(isBot) == true */

var userGroup = "";

function getUserGroup() {
	$.ajax({
		url: apiUrl,
		data: {
			format: 'json',
			action: 'query',
			meta: 'userinfo',
			uiprop: 'groups',
		},
		async: false,
		dataType: 'json',
		type: 'GET',
		success: function(data) {
			userGroup = data.query.userinfo.groups
		},
	});
};

function isBot(group) {
	return group == "bot";
}

/* Get token of this session */

var globalToken;

function getToken() {
    $.ajax({
        url: apiUrl,
        data: {
            format: 'json',
            action: 'query',
            meta: 'tokens',
            bot: true
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
           globalToken = data.query.tokens.csrftoken;
        },
        error: function( xhr ) {
            console.log("Failed to get token.");
        }
    });
}


function genericEditPage(title, content, summary) {
	$.ajax({
		url: apiUrl,
		data: {
			format: 'json',
			action: 'edit',
			title: title,
			text: content,
			token: globalToken,
			summary: summary,
			bot: true,
			nocreate: true
		},
		dataType: 'json',
		type: 'POST',
		success: function( data ) {
			console.log("Edited " + title);
		},
		error: function( xhr ) {
			alert("Failed to edit " + title);
		}
	});
};


function createPage(pageTitle, content, summary) {
    $.ajax({
        url: apiUrl,
        data: {
			format: 'json',
			action: 'edit',
			title: pageTitle,
			text: content,
			token: globalToken,
			summary: summary,
			bot: true
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
			console.log("Created page: " + pageTitle);
        },
        error: function( xhr ) {
			console.log("Failed to create page");
        }
    });
}

function getBacklinks(page) {
	var backlinks = [];
	$.ajax({
		url: apiUrl,
		data: {
			format: 'json',
			action: 'query',
			list: 'backlinks',
			bltitle: page,
			bllimit: 1000,
		},
		async: false,
		type: 'GET',
		success: function( data ) {
			backlinks = data.query.backlinks;
		},
		error: function( xhr ) {
			alert( 'Error: Backlinks request failed.' );
		}
	});
	return backlinks;
};

function getFileUsage(file) {
	var imageusage = [];
	$.ajax({
		url: apiUrl,
		data: {
			format: 'json',
			action: 'query',
			list: 'imageusage',
			iutitle: file,
			iulimit: 1000
		},
		async: false,
		type: 'GET',
		success: function( data ) {
			imageusage = data.query.imageusage;
		},
		error: function( xhr ) {
			alert( 'Error: Imageusage request failed.' );
		}
	});
	return imageusage;
};

function performNullEdit(pageTitle, summary) {
    $.ajax({
        url: apiUrl,
        data: {
            format: 'json',
            action: 'edit',
            title: pageTitle,
            section: 0,
            text: "",
            token: globalToken,
            summary: summary,
            bot: true
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
           console.log("Performed null edit");
        },
        error: function( xhr ) {
            console.log("Failed to perform null edit");
        }
    });
}

function purgeWhatLinksHere(pageTitle) {
    $.ajax({
        url: apiUrl,
        data: {
            format: "json",
            action: 'query',
            list: "backlinks",
            bltitle: pageTitle,
            bllimit: 500
        },
        async: true,
        type: 'GET',
        success: function( data ) {
            console.log(data);
            for (var i = 0; i < data.query.backlinks.length; i++) {
                purgePage(data.query.backlinks[i].title);
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed.' );
            console.log("Failed purging");
        }
    });
}

function purgePage(pageTitle) {
    $.ajax({
        url: apiUrl,
        data: {
            action: 'purge',
            forcelinkupdate: true,
            titles: pageTitle,
            prop: "info"
        },
        async: true,
        type: 'GET',
        success: function( data ) {
            console.log("purging " + pageTitle);
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed.' );
            console.log("Failed purging");
        }
    });
}