MediaWiki:SCalScript.js

From Istaria Lexica

Revision as of 03:15, 19 June 2022 by Maintenance script (talk | contribs) (Too large code import)

Note: After saving, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
/**
 * Skeleton Key Calculator V 0.1
 * Elteria Shadowhand
 */
$(document).ready(function() {
  if (document.getElementById('SCalMain')) {
    let baseResources; // Collection of the needed base resources. To be filled.
    let initialKeyCount = 1;
    let maxKeyCount = 5000;
    let maxSkillCount = 2000;
    let skills = new Map();// a list of all skills needed.

    // let's add some relevant information.
    // needed amounts default to optimum skills
    let products = new Map(); 
    products.set('Skeleton Key', { subs: new Map(), skill:'Tinkering', minCount: 1, maxCount: 1, minSkill: 1100, maxSkill: 1425, type: 'Product' });
    products.get('Skeleton Key').subs
      .set('Enchanted Adamantium-Mithril Bar', { subs: new Map(), skill:'Tinkering', minCount: 3, maxCount: 6, minSkill: 1100, maxSkill: 1425, type: 'Product' });
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .set('Gozar\'s Blessing', { subs: new Map(), skill:'Scribing', minCount: 2, maxCount: 4, minSkill: 1100, maxSkill: 1425, type: 'Product' });
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .set('Meltanis\' Prayer', { subs: new Map(), skill:'Spellcraft', minCount: 1, maxCount: 3, minSkill: 1100, maxSkill: 1425, type: 'Product' });
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Meltanis\' Prayer').subs
            .set('Travertine Spell Shard', { subs: new Map(), skill:'Spellcraft', minCount: 1, maxCount: 5, minSkill: 1100, maxSkill: 1425, type: 'RefinedResource' });
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Meltanis\' Prayer').subs
            .get('Travertine Spell Shard').subs
              .set('Travertine Brick', { subs: new Map(), skill:'Stoneworking', minCount: 2, maxCount: 5, minSkill: 1000, maxSkill: 1325, type: 'RefinedResource' });
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Meltanis\' Prayer').subs
            .get('Travertine Spell Shard').subs
              .get('Travertine Brick').subs
                .set('Travertine Slab', { skill:'Stoneworking', minCount: 2, maxCount: 5, minSkill: 1000, maxSkill: 1325 });
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Meltanis\' Prayer').subs
            .set('Radiant Essence Orb', { subs: new Map(), skill:'Essence Shaping', minCount: 4, maxCount: 10, minSkill: 1000, maxSkill: 1325, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Meltanis\' Prayer').subs
            .get('Radiant Essence Orb').subs
              .set('Radiant Essence', { skill:'Essence Shaping', minCount: 2, maxCount: 5, minSkill: 1000, maxSkill: 1325});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .set('Primal Burst III', { subs: new Map(), skill:'Spellcraft', minCount: 1, maxCount: 3, minSkill: 930, maxSkill: 1130, type: 'Product'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Primal Burst III').subs
            .set('Marble Spell Shard', { subs: new Map(), skill:'Spellcraft', minCount: 5, maxCount: 5, minSkill: 930, maxSkill: 1130, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Primal Burst III').subs
            .get('Marble Spell Shard').subs
              .set('Marble Brick', { subs: new Map(), skill:'Stoneworking', minCount: 2, maxCount: 5, minSkill: 800, maxSkill: 1100, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Primal Burst III').subs
            .get('Marble Spell Shard').subs
              .get('Marble Brick').subs
                .set('Marble Slab', { skill:'Stoneworking', minCount: 2, maxCount: 5, minSkill: 800, maxSkill: 1100});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Primal Burst III').subs
            .set('Shining Essence Orb', { subs: new Map(), skill:'Essence Shaping', minCount: 9, maxCount: 18, minSkill: 800, maxSkill: 1100, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Primal Burst III').subs
            .get('Shining Essence Orb').subs
              .set('Shining Essence', { skill:'Essence Shaping', minCount: 2, maxCount: 5, minSkill: 800, maxSkill: 1100});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .set('Energy Strike V', { subs: new Map(), skill:'Spellcraft', minCount: 1, maxCount: 3, minSkill: 850, maxSkill: 1050, type: 'Product'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Energy Strike V').subs
            .set('Marble Spell Shard', { subs: new Map(), skill:'Spellcraft', minCount: 4, maxCount: 4, minSkill: 800, maxSkill: 1100, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Energy Strike V').subs
            .get('Marble Spell Shard').subs
              .set('Marble Brick', { subs: new Map(), skill:'Stoneworking', minCount: 2, maxCount: 5, minSkill: 800, maxSkill: 1100, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Energy Strike V').subs
            .get('Marble Spell Shard').subs
              .get('Marble Brick').subs
                .set('Marble Slab', { skill:'Stoneworking', minCount: 2, maxCount: 5, minSkill: 800, maxSkill: 1100});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Energy Strike V').subs
            .set('Shining Essence Orb', { subs: new Map(), skill:'Essence Shaping', minCount: 7, maxCount: 14, minSkill: 800, maxSkill: 1100, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Energy Strike V').subs
            .get('Shining Essence Orb').subs
              .set('Shining Essence', { skill:'Essence Shaping', minCount: 2, maxCount: 5, minSkill: 800, maxSkill: 1100});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .set('Ice Bomb V', { subs: new Map(), skill:'Spellcraft', minCount: 1, maxCount: 3, minSkill: 920, maxSkill: 1120, type: 'Product'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Ice Bomb V').subs
            .set('Marble Spell Shard', { subs: new Map(), skill:'Spellcraft', minCount: 5, maxCount: 5, minSkill: 800, maxSkill: 1100, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Ice Bomb V').subs
            .get('Marble Spell Shard').subs
              .set('Marble Brick', { subs: new Map(), skill:'Stoneworking', minCount: 2, maxCount: 5, minSkill: 800, maxSkill: 1100, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Ice Bomb V').subs
            .get('Marble Spell Shard').subs
              .get('Marble Brick').subs
                .set('Marble Slab', { skill:'Stoneworking', minCount: 2, maxCount: 5, minSkill: 800, maxSkill: 1100});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Ice Bomb V').subs
            .set('Shining Essence Orb', { subs: new Map(), skill:'Essence Shaping', minCount: 9, maxCount: 18, minSkill: 800, maxSkill: 1100, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Ice Bomb V').subs
            .get('Shining Essence Orb').subs
              .set('Shining Essence', { skill:'Essence Shaping', minCount: 2, maxCount: 5, minSkill: 800, maxSkill: 1100});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .set('Fiery Strike V', { subs: new Map(), skill:'Spellcraft', minCount: 1, maxCount: 3, minSkill: 980, maxSkill: 1180, type: 'Product'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Fiery Strike V').subs
            .set('Marble Spell Shard', { subs: new Map(), skill:'Spellcraft', minCount: 6, maxCount: 6, minSkill: 800, maxSkill: 1100, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Fiery Strike V').subs
            .get('Marble Spell Shard').subs
              .set('Marble Brick', { subs: new Map(), skill:'Stoneworking', minCount: 2, maxCount: 5, minSkill: 800, maxSkill: 1100, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Fiery Strike V').subs
            .get('Marble Spell Shard').subs
              .get('Marble Brick').subs
                .set('Marble Slab', { skill:'Stoneworking', minCount: 2, maxCount: 5, minSkill: 800, maxSkill: 1100});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Fiery Strike V').subs
            .set('Shining Essence Orb', { subs: new Map(), skill:'Essence Shaping', minCount: 11, maxCount: 22, minSkill: 800, maxSkill: 1100, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Fiery Strike V').subs
            .get('Shining Essence Orb').subs
              .set('Shining Essence', { skill:'Essence Shaping', minCount: 2, maxCount: 5, minSkill: 800, maxSkill: 1100});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .set('Gold Papyrus Sheet', { subs: new Map(), skill:'Papermaking', minCount: 2, maxCount: 5, minSkill: 1000, maxSkill: 1325, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Gozar\'s Blessing').subs
          .get('Gold Papyrus Sheet').subs
            .set('Gold Papyrus Stem', { skill:'Papermaking', minCount: 2, maxCount: 5, minSkill: 1000, maxSkill: 1325});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .set('Hardened Adamantium-Mithril Bar', { subs: new Map(), skill:'Tinkering', minCount: 2, maxCount: 5, minSkill: 1100, maxSkill: 1425, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Hardened Adamantium-Mithril Bar').subs
          .set('Solution of Majorita', { subs: new Map(), skill:'Alchemy', minCount: 2, maxCount: 5, minSkill: 1100, maxSkill: 1425, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Hardened Adamantium-Mithril Bar').subs
          .get('Solution of Majorita').subs
            .set('Thornwood Bowl', { subs: new Map(), skill:'Alchemy', minCount: 1, maxCount: 3, minSkill: 1100, maxSkill: 1425, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Hardened Adamantium-Mithril Bar').subs
          .get('Solution of Majorita').subs
            .get('Thornwood Bowl').subs
              .set('Thornwood Sap', { skill:'Papermaking', minCount: 3, maxCount: 6, minSkill: 1100, maxSkill: 1425});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Hardened Adamantium-Mithril Bar').subs
          .get('Solution of Majorita').subs
            .get('Thornwood Bowl').subs
              .set('Thornwood Board', { subs: new Map(), skill:'Lumbering', minCount: 5, maxCount: 10, minSkill: 1000, maxSkill: 1325, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Hardened Adamantium-Mithril Bar').subs
          .get('Solution of Majorita').subs
            .get('Thornwood Bowl').subs
              .get('Thornwood Board').subs
                .set('Thornwood Log', { skill:'Lumbering', minCount: 2, maxCount: 5, minSkill: 1000, maxSkill: 1325});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Hardened Adamantium-Mithril Bar').subs
          .get('Solution of Majorita').subs
            .set('Crystallized Travertine Brick', { subs: new Map(), skill:'Stoneworking', minCount: 5, maxCount: 10, minSkill: 1000, maxSkill: 1325, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Hardened Adamantium-Mithril Bar').subs
          .get('Solution of Majorita').subs
            .get('Crystallized Travertine Brick').subs
              .set('Unfocused Violet Azulyte Crystal', { skill:'Stoneworking', minCount: 1, maxCount: 5, minSkill: 1000, maxSkill: 1325});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Hardened Adamantium-Mithril Bar').subs
          .get('Solution of Majorita').subs
            .get('Crystallized Travertine Brick').subs
              .set('Travertine Slab', { skill:'Stoneworking', minCount: 1, maxCount: 5, minSkill: 1000, maxSkill: 1325});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Hardened Adamantium-Mithril Bar').subs
          .get('Solution of Majorita').subs
            .set('Purified Radiant Essence Orb', { subs: new Map(), skill:'Enchanting', minCount: 1, maxCount: 4, minSkill: 1100, maxSkill: 1325, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Hardened Adamantium-Mithril Bar').subs
          .get('Solution of Majorita').subs
            .get('Purified Radiant Essence Orb').subs
              .set('Radiant Essence Orb', { subs: new Map(), skill:'Essence Shaping', minCount: 1, maxCount: 4, minSkill: 1100, maxSkill: 1325, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Hardened Adamantium-Mithril Bar').subs
          .get('Solution of Majorita').subs
            .get('Purified Radiant Essence Orb').subs
              .get('Radiant Essence Orb').subs
                .set('Radiant Essence', { skill:'Essence Shaping', minCount: 2, maxCount: 5, minSkill: 1000, maxSkill: 1325});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Hardened Adamantium-Mithril Bar').subs
          .get('Solution of Majorita').subs
            .set('Water', { skill:'Alchemy', minCount: 15, maxCount: 30, minSkill: 1100, maxSkill: 1425});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Hardened Adamantium-Mithril Bar').subs
          .set('Adamantium-Mithril Bar', { subs: new Map(), skill:'Smelting', minCount: 1, maxCount: 1, minSkill: 1100, maxSkill: 1425, type: 'RefinedResource'});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Hardened Adamantium-Mithril Bar').subs
          .get('Adamantium-Mithril Bar').subs
            .set('Mithril Ore', { skill:'Smelting', minCount: 3, maxCount: 6, minSkill: 1100, maxSkill: 1425});
    products.get('Skeleton Key').subs
      .get('Enchanted Adamantium-Mithril Bar').subs
        .get('Hardened Adamantium-Mithril Bar').subs
          .get('Adamantium-Mithril Bar').subs
            .set('Adamantium Ore', { skill:'Smelting', minCount: 3, maxCount: 6, minSkill: 1100, maxSkill: 1425});
    products.get('Skeleton Key').subs
      .set('Skeleton Key Mold', { subs: new Map(), skill:'Earthencraft', minCount: 1, maxCount: 1, minSkill: 1100, maxSkill: 1425, type: 'Product'});
    products.get('Skeleton Key').subs
      .get('Skeleton Key Mold').subs
        .set('Skeleton Key Pattern', { skill:'Earthencraft', minCount: 1, maxCount: 1, minSkill: 1100, maxSkill: 1425});
    products.get('Skeleton Key').subs
      .get('Skeleton Key Mold').subs
        .set('Porcelain Clay Chunk', { skill:'Earthencraft', minCount: 2, maxCount: 5, minSkill: 1100, maxSkill: 1425});

    printHeader();

    $('#SCalMain').append('<center><table>'
      + '<tr valign="top">'
      + '<td id="SCalResourcesrow1"></td>'
      + '<td id="SCalResourcesrow2"></td>'
      + '</tr>'
      + '</table></center>'
    );

    $('#SCalResourcesrow1').append('<div id="SCalResources"></div>');

    printLists();

    mw.loader.using('jquery.tablesorter', function() {
      $('table.sortable').tablesorter({ sortList: [{ 0: 'asc' }] })
    });

    //FUNCTIONS:
    function printHeader() {
      $('#SCalMain').append('<h1 id="SCalH1">The Calculator</h1>');
      $('#SCalMain').append('<center><label for="SCalCountInput" id="SCalCountInputLbl">How much Skeleton Keys would you want to create?</label></center>');
      $('#SCalMain').append('<center><input type="number" id="SCalCountInput" name="SCalCountInput" value="' + initialKeyCount + '" size="6"></center>');
      $('#SCalMain').append('<br />');
      $('#SCalMain').append('<hr />');
      $('#SCalMain').append('<center>Please enter your current skills in the fields below. Defaults to optimal skills.</center>');
      $('#SCalMain').append('<center><input type="button" id="SCalMaxSkillsBtn" value="Reset to optimal skills"></center>');
      $('#SCalMain').append('<center><input type="button" id="SCalMinSkillsBtn" value="Reset to minimal skills"></center>');
      $('#SCalMain').append('<center><div id="SCalSkills" style="column-count:3; width:fit-content; text-align:left"></div></center>');
      $('#SCalMain').append('<br />');
      $('#SCalMain').append('<center><input type="button" id="SCalCountBtn" value="Calculate now!"></center>');
      $('#SCalMain').append('<div id="SCalErrorText"></div>');
      $('#SCalMain').append('<hr />');

      $('#SCalMaxSkillsBtn').click(function() {
        for (var v of skills.values()) {
          $('#SCalSkill' + v + 'Input').val(maxSkillCount);
        };
      });

      $('#SCalCountBtn').click(function() {
        printLists();
      });

      $('#SCalCountInput').keypress(function(event) {
        if (event.key === 'Enter') printLists();
      });

      printSkillInputs();
    }

    function printLists() {
      baseResources = new Map();
      
      if(validateInputs()) { // check if the input fields contain valid entries
      
        $('#SCalResources').html('');
        $('#SCalResources').append('<h2>Tree of needed products</h2>');
        products = recursiveCalculateNeedEffectives(products, parseInt($('#SCalCountInput').val()));
        var html = recursivePrintTreeProduct(products);
        $('#SCalResources').append(html);
  
        printBaseResources();
      }
    }

    function printSkillInputs() {
      recursiveDetermineSkills(products);
      for (var [key, value] of skills.entries()) {
        $('#SCalSkills').append('<input type="number" id="SCalSkill' + value + 'Input" name="SCalSkill' + value + '" value="' + maxSkillCount + '" size="6"><label for="SCalSkill' + value + '">&nbsp;&nbsp;' + key + '</label><br />');
        $('#SCalSkill' + value + 'Input').keypress(function(event) {
          if (event.key === 'Enter') printLists();
        });
      }
    }

    function recursiveDetermineSkills(product) {
      product.forEach((obj) => {
        if(typeof obj.skill != 'undefined') {
          skills.set(obj.skill, obj.skill.replace(/\s/, ''));
        }
        
        if(obj.subs instanceof Map) {
          recursiveDetermineSkills(obj.subs);
        }
      }); 
    }
    
    function recursivePrintTreeProduct(product) {
      var html = '';
      product.forEach((obj, value) => {
        html += '<ul>';
        html += '<li>';
        html += value + ': ' + obj.neededCount;
        if(obj.subs instanceof Map) {
          html += recursivePrintTreeProduct(obj.subs);
        }
        html += '</ul>';
        html += '</li>'
      });
      return html;
    }

    function recursiveCalculateNeedEffectives(product, previousCount) {
      product.forEach((value,key) => {
        var currentSkill;
        if(typeof value.skill != 'undefined') { // if we found a skill, use the value of the input field
          currentSkill = $('#SCalSkill' + skills.get(value.skill) + 'Input').val();
        } else {
          currentSkill = maxSkillCount;
        }
        var percent = (currentSkill - value.minSkill) / (value.maxSkill - value.minSkill);
        var needEffective = value.maxCount - ((value.maxCount - value.minCount) * percent);
        needEffective = Math.ceil(needEffective);
  
        if (needEffective < value.minCount) needEffective = value.minCount;
        if (needEffective > value.maxCount) needEffective = value.maxCount;
        
        value.neededCount = needEffective * previousCount;

        if(!(value.subs instanceof Map)) { // we assume that a product without subs is a base resource
          if(baseResources.has(key)) {
            baseResources.set(key, value.neededCount + baseResources.get(key));
          } else {
            baseResources.set(key, value.neededCount);
          }
        }

        if(value.subs instanceof Map) {
          recursiveCalculateNeedEffectives(value.subs, value.neededCount);
        }
      });

      return product;
    }

    function printBaseResources() {
      baseResources = new Map([...baseResources.entries()].sort());

      $('#SCalResourcesrow2').html('');
      $('#SCalResourcesrow2').append('<h2><span id="mw-headline">Overview of base resources</span></h2>');
      $('#SCalResourcesrow2').append('<table id="SCalBaseResourceTable" class="wikitable sortable"><thead>'
        + '<tr>'
        + '<th align="left">Resource</th>'
        + '<th align="left">Need</th>'
        + '</tr></thead>'
      );

      var tablecontent = '<tbody>';

      baseResources.forEach(function(value, key) {
        tablecontent += '<tr>'
          + '<td><a href="' + mw.util.getUrl(key) + '">' + key + '</a></td>'
          + '<td>' + value + '</td>'
          + '</tr>';
      });

      tablecontent += '</tbody)';
      $('#SCalBaseResourceTable').append(tablecontent);
      $('#SCalResources').append('</table>');
    }

    function validateInputs() {
      var ready = true;
      //reset the error textfield
      $('#SCalErrorText').html('');

      // check the keycounter value
      $('#SCalCountInput').removeClass('SCalErroreousInput');
      var value = $('#SCalCountInput').val();
      if (!(!isNaN(value) &&
        parseInt(Number(value)) == value &&
        !isNaN(parseInt(value, 10)))) {
        $('#SCalErrorText').append('<center>Amount of keys: this was not a number!</center>');
        $('#SCalCountInput').addClass('SCalErroreousInput');
        ready = false;
      } else {
        if (value < 1 || value > maxKeyCount) {
          $('#SCalErrorText').append('<center>Amount of keys: please provide a number between 1 and ' + maxKeyCount + '</center>');
          $('#SCalCountInput').addClass('SCalErroreousInput');
          ready = false;
        }
      }

      //check the skills counters
      for (var [skill, id] of skills) {
        $('#SCalSkill' + id + 'Input').removeClass('SCalErroreousInput');
        number = $('#SCalSkill' + id + 'Input').val();

        if (!(!isNaN(number) &&
          parseInt(Number(number)) == number &&
          !isNaN(parseInt(number, 10)))) {
          $('#SCalErrorText').append('<center>' + skill + ': this was not a number!</center>');
          $('#SCalSkill' + id + 'Input').addClass('SCalErroreousInput');
          ready = false;
        } else {
          if (number < 1 || number > maxSkillCount) {
            $('#SCalErrorText').append('<center>' + skill + ': please provide a number between 1 and ' + maxSkillCount + '</center>');
            $('#SCalSkill' + id + 'Input').addClass('SCalErroreousInput');
            ready = false;
          }
        }
      }
      return ready;
    }
  }
});