awalon / Ingress Mission Authoring Tool - Sort and Count

// ==UserScript==
// @name         Ingress Mission Authoring Tool - Sort and Count
// @namespace    http://tampermonkey.net/
// @version      0.8.5
// @description  Ingress Mission Authoring Tool (IMAT): Sort and count all missions
// @author       Awalon
// @licence      MIT
// @match        https://mission-author-dot-betaspike.appspot.com/
// @grant        none
// ==/UserScript==
// Source: https://openuserjs.org/scripts/awalon/Ingress_Mission_Authoring_Tool_-_Sort_and_Count
// Based on the idea of https://openuserjs.org/scripts/marcin348gmail.com/Sort_missions
// ###################################################################################################################
// Attention: New version with mosaic preview available...
//            https://openuserjs.org/install/awalon/Ingress_Mission_Authoring_Tool_-_Sort,_Count_and_Preview.user.js
// ###################################################################################################################

(function () {
    'use strict';
    var msum = 0;

    function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    var pad = function(no, size) {
        var s = String(no);
        while (s.length < (size || 2)) {s = "0" + s;}
        return s;
    };

    function sortMissionList (draftFirst) {
        var $published = $("div.mission-list-item-published");
        var $submitted = $("div.mission-list-item-submitted");
        var $submitted_published = $("div.mission-list-item-submitted_and_published");
        var $drafts = $("div.mission-list-item-draft");

        // normalize mission name (extract numbers and move them to the end, for grouping)
        var mName = function (m, o) {
            // - extract number
            var no_re  = /(?:(\d+)(?:(?:(?:[/-])|(?:\s*?(?:of|von)\s*?))+(\d+))?)/;
            var no_str = "$2|$1";
            var no     = m.match(no_re);
            var no_all = no ? (no.length > 1 ? no[2] : 0) : 0;
            var no_cur = no ? (no.length > 0 ? no[1] : 0) : 0;
            // - remove number from name
            var name   = m.replace(no_re, "").trim().toLowerCase();
            var idx    = pad(no_all, 4) + "|" + pad(no_cur, 4);
            var id     = name  + "#" + idx;
            //console.log (id);
            return id;
        };


        var published_sorted = $published.sort(function (a, b) {
            var aTitle = mName($(a).find(".mission-title-published").text());
            var bTitle = mName($(b).find(".mission-title-published").text());
            return aTitle.localeCompare(bTitle);
        });

        var submitted_sorted = $submitted.sort(function (a, b) {
            var aTitle = mName($(a).find(".mission-title-submitted").text());
            var bTitle = mName($(b).find(".mission-title-submitted").text());
            return aTitle.localeCompare(bTitle);
        });
        
        var submitted_published_sorted = $submitted_published.sort(function (a, b) {
            var aTitle = mName($(a).find(".mission-title-submitted_and_published").text(), a);
            var bTitle = mName($(b).find(".mission-title-submitted_and_published").text(), b);
            return aTitle.localeCompare(bTitle);
        });

        var drafts_sorted = $drafts.sort(function (a, b) {
            var aTitle = mName($(a).find(".mission-title-draft").text());
            var bTitle = mName($(b).find(".mission-title-draft").text());
            return aTitle.localeCompare(bTitle);
        });

        if (draftFirst) {
            drafts_sorted.appendTo(".missions-list");
            submitted_published_sorted.appendTo(".missions-list");
            submitted_sorted.appendTo(".missions-list");
            published_sorted.appendTo(".missions-list");
        } else {
            published_sorted.appendTo(".missions-list");
            submitted_sorted.appendTo(".missions-list");
            submitted_published_sorted.appendTo(".missions-list");
            drafts_sorted.appendTo(".missions-list");
        }

        // stats
            msum  = drafts_sorted.length + submitted_sorted.length + submitted_published_sorted.length + published_sorted.length;
        var mleft = 150 - (submitted_sorted.length + submitted_published_sorted.length + published_sorted.length);
        var stats = msum + ' Missions (' + drafts_sorted.length + " Draft, " + submitted_published_sorted.length + " Review, " + submitted_sorted.length + " Submitted, " + published_sorted.length + " Published), " + mleft + " Remains";
        $("#mcounter").text(stats);

    }

    // navbar-header vs. navbar-fixed-top
    $(".navbar-header").append("<button style='margin-top:6px;' id='sort_draft'>Sort (Drafts first)</button>");
    $(".navbar-header").append("<button style='margin-top:6px;' id='sort_published'>Sort (Drafts last)</button>");
    $(".navbar-header").append("<button style='margin-top:6px;background-color:black;' id='mcounter'>Missions</button>");
    $(".navbar-header").append("&nbsp;&nbsp;<a style='margin-top:6px;background-color:black;' id='newversion' href='https://openuserjs.org/install/awalon/Ingress_Mission_Authoring_Tool_-_Sort,_Count_and_Preview.user.js'> New Version with Mosaic Preview</a>");

    $('#sort_draft').on('click', function () { sortMissionList (true); });
    $('#sort_published').on('click', function () { sortMissionList (false); });

    for (var i = 0; i < 20; i++) {
        if (msum == 0) {
            sleep(2000).then( () => { sortMissionList (true); } );
        }
    }
})();