Marti / uso - Count Issues

(function () {
  "use strict";

// ==UserScript==
// @name          uso - Count Issues
// @namespace     http://userscripts.org/users/37004
// @description   Counts issues on USO
// @copyright     2010+, Marti Martz (http://userscripts.org/users/37004)
// @contributor   sizzlemctwizzle (http://userscripts.org/users/27715)
// @license       CC-BY-NC-SA-4.0; https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
// @license       GPL-3.0-or-later; http://www.gnu.org/licenses/gpl-3.0.txt
// @version       1.0.5.1eol
// @icon          https://raw.githubusercontent.com/Martii/UserScripts/master/src/uso/Count%20Issues/res/icon48.png

// @supportURL http://userscripts.org/topics/46432
// @homepageURL https://github.com/Martii/UserScripts/tree/master/src/uso/Count%20Issues
// @homepageURL https://openuserjs.org/scripts/Marti/uso_-_Count_Issues
// @homepageURL http://userscripts.org/scripts/show/69307

// @include   /^https?://userscripts\.org(?::\d{1,5})?/scripts//
// @include   /^https?://userscripts\.org(?::\d{1,5})?/topics//
// @include   /^https?://userscripts\.org(?::\d{1,5})?/reviews//

// @exclude   /^https?://userscripts\.org(?::\d{1,5})?/scripts/diff//
// @exclude   /^https?://userscripts\.org(?::\d{1,5})?/scripts/version//

// @include   http://userscripts.org/scripts/*/*
// @include   http://userscripts.org/topics/*
// @include   http://userscripts.org/reviews/*

// @include   https://userscripts.org/scripts/*/*
// @include   https://userscripts.org/topics/*
// @include   https://userscripts.org/reviews/*

// @exclude   http://userscripts.org/scripts/diff/*
// @exclude   http://userscripts.org/scripts/version/*

// @exclude   https://userscripts.org/scripts/diff/*
// @exclude   https://userscripts.org/scripts/version/*

// @include   http://userscripts.org:8080/scripts/*/*
// @include   http://userscripts.org:8080/topics/*
// @include   http://userscripts.org:8080/reviews/*

// @exclude   http://userscripts.org:8080/scripts/diff/*
// @exclude   http://userscripts.org:8080/scripts/version/*

// @require https://raw.githubusercontent.com/Martii/UserScripts/dc7d27fef916db3bea640139bd852b2c75a08ff8/lib/GM_setStyle/GM_setStyle.js
// @require https://raw.githubusercontent.com/Martii/GM_config/a0d0066ffaefb5fbb3402c3d46ac705e8b4124d8/gm_config.js
// @require https://raw.githubusercontent.com/einars/js-beautify/master/js/lib/beautify.js
// @require https://raw.githubusercontent.com/w35l3y/userscripts/4d5f3987e5c8213eb824f352e318a1cc13977d7a/includes/87269.user.js

// @resource icon   https://raw.githubusercontent.com/Martii/UserScripts/master/src/uso/Count%20Issues/res/icon32.png
// @resource reload https://raw.githubusercontent.com/Martii/UserScripts/master/src/uso/Count%20Issues/res/reload16.png
// @resource gmc    https://raw.githubusercontent.com/sizzlemctwizzle/GM_config/master/gm_config_icon.png

// @grant GM_getResourceURL
// @grant GM_getValue
// @grant GM_log
// @grant GM_openInTab
// @grant GM_setValue
// @grant GM_xmlhttpRequest

// ==/UserScript==

  if (!document || !document.body || location.hash == "#posts-last")
    return;

  /**
   *
   */
  function getScript_nameNode() {
    let xpr = document.evaluate(
    "//h2[contains(concat(' ', normalize-space(@class), ' '), ' title ')]/a|//h2[contains(concat(' ', normalize-space(@class), ' '), ' title ')]",
      document.body,
      null,
      XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
      null
    );

    return (xpr.snapshotItem((xpr.snapshotLength > 1) ? 1 : 0));
  }

  /**
   *
   */
  function getScript_summaryNodes() {
    let xpr = document.evaluate(
    "//div[contains(concat(' ', normalize-space(@class), ' '), ' script_summary ')]",
      document.body,
      null,
      XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
      null
    );
    if (xpr) {
      let nodes = [];
      for (let i = 0, thisNode; thisNode = xpr.snapshotItem(i++);)
        nodes.push(thisNode);

      return (nodes.length) ? nodes : undefined;
    }
  }

  /**
   *
   */
  function getScriptid() {
    let scriptid = location.pathname.match(/\/scripts\/.+\/(\d+)/i);
    if (!scriptid) {
      if (script_nameNode && script_nameNode.pathname)
        scriptid = script_nameNode.pathname.match(/\/scripts\/show\/(\d+)/i);
    }
    return (scriptid) ? scriptid[1] : undefined;
  }

  /**
   *
   */
  function countIssues(aNodeHook, aNodeSpan, aDoc) {
    if (aNodeHook.firstChild.nodeType == 1)
      aNodeHook.firstChild.textContent += " ";
    else
      aNodeHook.textContent += " ";

      if (aDoc) {
        let
          countYes = 0,
          countNo = 0
        ;

        [
          "broken_votes",
          "copy_votes",
          "harmful_votes",
          "spam_votes",
          "vague_votes"
        ].forEach(function (e, i, a) {
          let xpr = aDoc.evaluate(
            "//a[contains(@href,'/scripts/issues/" + scriptid + "#" + e + "')]",
            aDoc.body,
            null,
            XPathResult.FIRST_ORDERED_NODE_TYPE,
            null
          );
          if (xpr && xpr.singleNodeValue) {
            let thisNode = xpr.singleNodeValue;

            let matches = thisNode.textContent.match(/(\d+) of (\d+) voted yes/i);
            if (matches) {
              countYes += parseInt(matches[1]);
              countNo += parseInt(matches[2]) - parseInt(matches[1]);
            }
          }
        });

        aNodeSpan.textContent = countYes;
        if (countYes > countNo)
          aNodeSpan.classList.add("blah");
      }
      else
        aNodeSpan.classList.add("blah");

    if (aNodeHook.firstChild.nodeType == 1)
      aNodeHook.firstChild.appendChild(aNodeSpan);
    else
      aNodeHook.appendChild(aNodeSpan);
  }

  /**
   *
   */
  function firstValueOf(aMb, aKey, aPrefix) {
    if (aPrefix) {
      if (aMb[aPrefix] && aMb[aPrefix][aKey])
        return ((typeof aMb[aPrefix][aKey] == "string") ? aMb[aPrefix][aKey] : aMb[aPrefix][aKey][0]);
    }
    else {
      if (aMb[aKey])
        return ((typeof aMb[aKey] == "string") ? aMb[aKey] : aMb[aKey][0]);
    }

    return undefined;
  }

  /**
   *
   */
  function lastValueOf(aMb, aKey, aPrefix) {
    if (aPrefix) {
      if (aMb[aPrefix] && aMb[aPrefix][aKey])
        return ((typeof aMb[aPrefix][aKey] == "string") ? aMb[aPrefix][aKey] : aMb[aPrefix][aKey][aMb[aPrefix][aKey].length - 1]);
    }
    else {
      if (aMb[aKey])
        return ((typeof aMb[aKey] == "string") ? aMb[aKey] : aMb[aKey][aMb[aKey].length - 1]);
    }

    return undefined;
  }

  /**
   *
   */
  function parseMeta(aString) {
    aString = aString.toString();
    let
        re = /\/\/ @(\S+)(?:\s+(.*))?/,
        headers = {},
        name, prefix, header, key, value,
        lines = aString.split(/[\r\n]+/).filter(function (e, i, a) {
          return (e.match(re));
        })
    ;
    for (let line in lines) {
      [, name, value] = lines[line].replace(/\s+$/, "").match(re);
      switch (name) {
        case "licence":
          name = "license";
          break;
      }
      [key, prefix] = name.split(/:/).reverse();
      if (key) {
        if (prefix) {
          if (!headers[prefix])
            headers[prefix] = new Object;
          header = headers[prefix];
        }
        else
          header = headers;

        if (header[key]) {
          if (!(header[key] instanceof Array))
            header[key] = new Array(header[key]);
          header[key].push(value || "");
        }
        else
          header[key] = value || "";
      }
    }
    if (headers["license"])
      headers["licence"] = headers["license"];

    return (headers.toSource() != "({})") ? headers : undefined;
  }

  /**
   *
   */
  function simpleTranscodeDotNotation(aLine, aCounter, aLoop) { // NOTE: Fuzzy
    let matched =  aLine.match(/\[\"(\w+)\"\]/);
    if (matched) {
      aLine = aLine.replace(matched[0], "." + matched[1]);
      ++aCounter;
      return [aLine, aCounter, true];
    }
    else
      return [aLine, aCounter, false];
  }

  function simpleTranscodeURLdecode(aLine, aCounter, aLoop) { // NOTE: Fuzzy
    let matched = aLine.match(/\%([\d(?:A-F|a-f)]{2})/);
    if (matched) {
      aLine = aLine.replace(matched[0], String.fromCharCode(parseInt("0x" + matched[1], 16)), "");
      ++aCounter;
      return [aLine, aCounter, true];
    }
    else
      return [aLine, aCounter, false];
  }

  function simpleTranscodeHex(aLine, aCounter, aLoop) { // NOTE: Fuzzy
    let matched = aLine.match(/\\x([\d(?:A-F|a-f)]{2})/);
    if (matched) {
      aLine = aLine.replace(matched[0], String.fromCharCode(parseInt("0x" + matched[1], 16)), "");
      ++aCounter;
      return [aLine, aCounter, true];
    }
    else
      return [aLine, aCounter, false];
  }

  function simpleTranscode(aSource, aCounter) {
    aSource = js_beautify(aSource.replace(/[“”]/g, '"'), {indent_size: 1, indent_char: '\t'});

    let dummy = 0;

    let lines = aSource.split(/[\r\n]/);
    for (let i = 0, loop; i < lines.length; i++) {
      loop = true;
      while (loop)
        [lines[i], aCounter, loop] = simpleTranscodeHex(lines[i], aCounter, loop);

      loop = true;
      while (loop)
        [lines[i], dummy, loop] = simpleTranscodeDotNotation(lines[i], dummy, loop);

      loop = true;
      while (loop)
        [lines[i], dummy, loop] = simpleTranscodeURLdecode(lines[i], dummy, loop);
    }
    aSource = lines.join("\n");

    return [aSource, aCounter];
  }

  /**
   *
   */
  function displayValueResource(aNodeUl, aNodeLi, aResourceName, aTextContent, aTitle, aHref, aForced) {

    if (aResourceName) {
      let nodeSpan = document.createElement("span");
      nodeSpan.classList.add("resourceName");
      nodeSpan.textContent = aResourceName;

      aNodeLi.appendChild(nodeSpan);
    }

    let nodeA;
    if (aHref) {
      nodeA = document.createElement("a");
      nodeA.href = aHref;
      nodeA.rel = "nofollow";
      nodeA.textContent = aTextContent;
      if (aForced)
        nodeA.classList.add("blah");

      aNodeLi.appendChild(nodeA);
    }

    if (!aResourceName || !aHref) {
      aNodeLi.textContent = aTextContent;
      if (aForced)
        aNodeLi.classList.add("blah");
    }

    if (aTitle)
      aNodeLi.title = aTitle;

    aNodeUl.appendChild(aNodeLi);

    return nodeA;
  }

  /**
   *
   */
  function checkUSOValue(aNodeA, aScriptid) {
    GM_xmlhttpRequest({
      retry: 5,
      method: "HEAD",
      url: "/scripts/show/" + aScriptid,
      onload: function(xhr) {
        switch (xhr.status) {
          case 500:
          case 502:
          case 503:
            if (this.retry-- > 0)
              setTimeout(GM_xmlhttpRequest, delayRetryMin + Math.round(Math.random() * (delayRetryMax - delayRetryMin)), this);
            else
              aNodeA.classList.add("unknown");
            break;
          case 200:
            aNodeA.classList.add("checked");
            break;
          case 404:
            if (!halt404) {
              if (this.retry-- > 0) {
                setTimeout(GM_xmlhttpRequest, delayRetryMin + Math.round(Math.random() * (delayRetryMax - delayRetryMin)), this);
                break;
              }
            }
          default:
            aNodeA.classList.add("blah");
            break;
        }
    }});
  }

  /**
   *
   */
  function displayValue(aNodeUl, aNodeLi, aTextContent, aTitle, aHref, aForced) {
    let nodeA;
    if (aHref) {
      nodeA = document.createElement("a");
      nodeA.href = aHref;
      nodeA.rel = "nofollow";
      nodeA.textContent = aTextContent;
      if (aForced)
        nodeA.classList.add("blah");

      aNodeLi.appendChild(nodeA);
    }
    else {
      aNodeLi.textContent = aTextContent;
      if (aForced)
        aNodeLi.classList.add("blah");
    }

    if (aTitle)
      aNodeLi.title = aTitle;

    aNodeUl.appendChild(aNodeLi);

    return nodeA;
  }

  /**
   *
   */
  function displayName(aHookNode, aName, aValues, aForced) {
    if (typeof aValues == "string")
      aValues = new Array(aValues);

    let nodeImg = document.createElement("img");
    nodeImg.src = GM_getResourceURL("icon");
    nodeImg.title = "uso - Count Issues";
    nodeImg.alt = "Count Issues";

    let homepageNodeA = document.createElement("a");
    homepageNodeA.href = "/scripts/show/69307";

    homepageNodeA.appendChild(nodeImg);

    let nodeSpan = document.createElement("span");
    nodeSpan.textContent = (aValues) ? aValues.length : "0";
    if (aForced)
      nodeSpan.classList.add("blah");

    let nodeA = document.createElement("a");
    nodeA.href = protocol + "//sf.net/apps/mediawiki/greasemonkey/index.php?title=Metadata_Block#.40" + aName;
    nodeA.textContent = "@" + aName;

    let nodeH6 = document.createElement("h6");
    nodeH6.appendChild(nodeA);
    nodeH6.appendChild(document.createTextNode(" "));
    nodeH6.appendChild(nodeSpan);
    nodeH6.appendChild(homepageNodeA);

    aHookNode.appendChild(nodeH6);

    if (aValues) {
      let nodeUl = document.createElement("ul");

      let matches, re;

      for (let value in aValues) {
        let valued = aValues[value];

        let nodeLi = document.createElement("li");

        switch (aName) {
          case "downloadURL":
          case "installURL":
            re = new RegExp("^(?:https?:\\/\\/userscripts\\.org(?:\\:\\d{1,5})?\\/scripts\\/source\\/)?(\\d+)\\.user\\.js", "i");
            matches = valued.match(re);
            if (matches && matches[1] == scriptid) {
              let itemNode = displayValue(nodeUl, nodeLi, valued, valued, "/scripts/show/" + matches[1]);
              if (gmcHome.get("checkAgainstHomepageUSO"))
                checkUSOValue(itemNode, matches[1]);
            }
            else {
              re = new RegExp("^file:", "i");
              matches = valued.match(re);
              if (matches)
                displayValue(nodeUl, nodeLi, valued, valued);
              else {
                nodeSpan.classList.add("blah");
                displayValue(nodeUl, nodeLi, valued, valued, valued, true);
              }
            }
            break;
          case "icon":
            matches = valued.match(/^(https?:\/\/.*)/i);
            if (matches)
              displayValue(nodeUl, nodeLi, matches[1], matches[1], matches[1]);
            else {
              matches = valued.match(/^(data:image\/(\S+?);?\w+?,.*)/i);
              if (matches && matches[2].toLowerCase() != "svg+xml" && matches[2].toLowerCase() != "x-svg") {
                let nodeImg = document.createElement("img");
                nodeImg.src = matches[1];
                nodeImg.classList.add("aoicon");
                nodeImg.title = "~" + parseInt(matches[1].length / 1024 * 10) / 10 + "K " + matches[1].match(/^data:(?:\w+\/\S+?;?\w+?,)?/i) + "\u2026";
                nodeLi.appendChild(nodeImg);

                nodeUl.appendChild(nodeLi);
              }
              else
                displayValue(nodeUl, nodeLi, valued);
            }
            break;
          case "namespace":
            matches = valued.match(/^(https?:\/\/.*)/i);
            if (matches)
              displayValue(nodeUl, nodeLi, matches[1], matches[1], matches[1]);
            else
              displayValue(nodeUl, nodeLi, valued, valued);
            break;
          case "require":
            re = new RegExp("^(?:https?:\\/\\/(?:www\\.|greasefire\\.)?userscripts\\.org(?:\\:\\d{1,5})?\\/scripts\\/(?:source|version)\\/)?(\\d+)(?:\\/\\d+)?\\.(?:user|meta)\\.js", "i");
            matches = valued.match(re);
            if (matches) {
              let itemNode = displayValue(nodeUl, nodeLi, valued, valued, "/scripts/show/" + matches[1]);
              if (gmcHome.get("checkAgainstHomepageUSO"))
                checkUSOValue(itemNode, matches[1]);
            }
            else
              displayValue(nodeUl, nodeLi, valued, valued, valued);
            break;
          case "resource":
            matches = valued.match(/^(\S+)\s+(https?:\/\/.*)/i);
            if (matches && matches.length > 2) {
              let
                resourceName = matches[1],
                url = matches[2]
              ;
              re = new RegExp("^(?:https?:\\/\\/(?:www\\.|greasefire\\.)?userscripts\\.org(?:\\:\\d{1,5})?\\/scripts\\/(?:source|version)\\/)?(\\d+)(?:\\/\\d+)?\\.(?:user|meta)\\.js", "i");
              matches = url.match(re);
              if (matches) {
                let itemNode = displayValueResource(nodeUl, nodeLi, resourceName, url, url, "/scripts/show/" + matches[1]);
                if (gmcHome.get("checkAgainstHomepageUSO"))
                  checkUSOValue(itemNode, matches[1]);
              }
              else
                displayValueResource(nodeUl, nodeLi, resourceName, url, url, url);
            }
            else {
              displayValueResource(nodeUl, nodeLi, null, valued, valued, null, true);
            }
            break;
          case "updateURL":
            re = new RegExp("^(?:https?:\\/\\/userscripts\\.org(?:\\:\\d{1,5})?\\/scripts\\/source\\/)?(\\d+)\\.meta\\.js", "i");
            matches = valued.match(re);
            if (matches && matches[1] == scriptid) {
              let itemNode = displayValue(nodeUl, nodeLi, valued, valued, "/scripts/show/" + matches[1]);
              if (gmcHome.get("checkAgainstHomepageUSO"))
                checkUSOValue(itemNode, matches[1]);
            }
            else {
              re = new RegExp("^(?:about:|file:)", "i");
              matches = valued.match(re);
              if (matches)
                displayValue(nodeUl, nodeLi, valued, valued);
              else {
                nodeSpan.classList.add("blah");
                displayValue(nodeUl, nodeLi, valued, valued, valued, true);
              }
            }
            break;
          default:
            displayValue(nodeUl, nodeLi, valued);
            break;
        }

      }

      aHookNode.appendChild(nodeUl);
    }
  }

  /**
   *
   */
  function displayFound(aHookNode, aObj) {

    let nodeUl = document.createElement("ul");
    nodeUl.classList.add("finds");

    let counter = 0;
    for (let [name, value] in Iterator(aObj)) { // NOTE: Watchpoint

      let nodeLi = document.createElement("li");
      if (counter % 2)
        nodeLi.classList.add("bar");
      nodeLi.title = name;

      let nodeSpan = document.createElement("span");
      nodeSpan.textContent = value;

      nodeLi.appendChild(nodeSpan);
      nodeLi.appendChild(document.createTextNode(name));
      nodeUl.appendChild(nodeLi);

      counter++;
    }

    let xpr = document.evaluate(
      ".//span",
      aHookNode,
      null,
      XPathResult.FIRST_ORDERED_NODE_TYPE,
      null
    );
    if (xpr && xpr.singleNodeValue) {
      let thisNode = xpr.singleNodeValue;

      if (thisNode.textContent == "")
        thisNode.textContent = counter;
      else
        thisNode.textContent = counter + ":" + thisNode.textContent;
    }
    aHookNode.parentNode.insertBefore(nodeUl, aHookNode.nextSibling);
  }

  /**
   *
   */
  function unitSizer(aNumber) {
    if (typeof aNumber == "string")
      aNumber = parseInt(aNumber);

    return (
      (aNumber >= 1024)
          ? (aNumber >= 1048576)
              ? parseInt(aNumber / 1024 / 1024 * 10) / 10 + " MiB"
              : parseInt(aNumber / 1024 * 10) / 10 + " KiB"
          : aNumber + " B"
    );
  }

  /**
   *
   */
  function onClickHunt(ev) {
    let hookNode = ev.target;
    hookNode.removeEventListener("click", onClickHunt, false);

    hookNode.classList.add("throb");
    GM_xmlhttpRequest({
      retry: 5,
      url: "/scripts/version/" + scriptid + "/" + lastValueOf(mb, "version", "uso") + ".user.js",
      method: "GET",
      onload: function (xhr) {
        switch (xhr.status) {
          case 404:
            if (halt404)
              this.retry = 0;
          case 500:
          case 502:
          case 503:
            if (this.retry-- > 0)
              setTimeout(GM_xmlhttpRequest, delayRetryMin + Math.round(Math.random() * (delayRetryMax - delayRetryMin)), this);
            else
              hookNode.classList.remove("throb");
            break;
          case 200:
            let responseText = xhr.responseText;

            if (gmcHome.get("showSize")) {
              let xpr = document.evaluate(
              "//li/a[starts-with(., 'Source')]",
                document.body,
                null,
                XPathResult.FIRST_ORDERED_NODE_TYPE,
                null
              );
              if (xpr && xpr.singleNodeValue) {
                let thisNode = xpr.singleNodeValue;

                thisNode.textContent += " ";
                let nodeSpan = document.createElement("span");
                nodeSpan.textContent = unitSizer(responseText.length);
                thisNode.appendChild(nodeSpan);
              }
            }

            /** Pre deob **/
            let findspre = {};

            let res = gmcHome.get("showStringsStringPre").split("\n");
            for (let re in res) {
              let rez = res[re].trim();
              if (rez) {
                let matches = responseText.match(new RegExp(rez, "gm"));
                for (let match in matches)
                  findspre[matches[match]] = (matches[match] in findspre) ? findspre[matches[match]] + 1 : 1;
              }
            }

            if (gmcHome.get("deobJsCode")) {
              try {
                responseText = JsCode.deobfuscate(responseText);
              }
              catch (e) {
                let msg = 'Aborting JsCode\n' + e.name + '\n' + e.message;
                console.warn(msg);
              }
            }

            let hexCount;
            if (gmcHome.get("deobST")) {
              try {
                [responseText, hexCount] = simpleTranscode(responseText, 0);
              }
              catch(e) {
                let msg = 'Aborting Simple Transcode\n' + e.name + '\n' + e.message;
                console.warn(msg);
              }
            }

            /** Post deob **/
            let postfinds = {};

            res = gmcHome.get("showStringsString").split("\n");
            for (let re in res) {
              let rez = res[re].trim();
              if (rez) {
                let matches = responseText.match(new RegExp(res[re], "gm"));
                for (let match in matches)
                  postfinds[matches[match]] = (matches[match] in postfinds) ? postfinds[matches[match]] + 1 : 1;
              }
            }

            document.evaluate(
              ".//span",
              hookNode,
              null,
              XPathResult.FIRST_ORDERED_NODE_TYPE,
              xpr
            );
            if (xpr && xpr.singleNodeValue) {
              let thisNode = xpr.singleNodeValue;

              if (postfinds.toSource() != "({})")
                displayFound(hookNode, postfinds);
              else
                thisNode.textContent = "0";

              if (findspre.toSource() != "({})")
                displayFound(hookNode, findspre);
              else
                thisNode.textContent = "0:" + thisNode.textContent;
            }

            hookNode.classList.remove("throb");
            hookNode.classList.remove("lost");
            hookNode.classList.add("found");

            break;
        }
      }
    });

  }

  /**
   *
   */
  function renumber(aHookNode) {
    let numberNode = document.getElementById("number");

    if (numberNode.hasChildNodes())
      while (numberNode.hasChildNodes())
        numberNode.removeChild(numberNode.firstChild);

    numberNode.classList.remove("err");

    // Calculate width of numbers
    let newlines = aHookNode.textContent.match(/\n/g);
    if (newlines)
      newlines = newlines.length;
    else
      newlines = 0;

    let digits = (parseInt(newlines) + 1).toString().length;
    let textWidth = parseInt(getComputedStyle(aHookNode, null).getPropertyValue("font-size").replace(/px/, "") / 1.5); // NOTE: Fuzzy

    numberNode.style.setProperty("width", (textWidth * digits) + "px", "");

    // Create numbers
    let line = 1;
    do {
      let nodeA = document.createElement("a");
      nodeA.id = "line-" + line;
      nodeA.href = "#line-" + line;
      nodeA.textContent = line;
      if (line % 10 == 0 || line == 1)
        nodeA.classList.add("surge");

      let nodeDiv = document.createElement("div");

      nodeDiv.appendChild(nodeA);
      numberNode.appendChild(nodeDiv);
    } while (line++ <= newlines);

    // Show numbers
    numberNode.classList.remove("HID");

    aHookNode.parentNode.insertBefore(numberNode, aHookNode);
    aHookNode.style.setProperty("margin-left", numberNode.offsetWidth + "px", "");
  }

  /**
   *
   */
  function onMouseoverVersion(ev) {
    let targetNode = ev.target;

    if (!targetNode.title && !targetNode.classList.contains("throb")) {
      targetNode.classList.add("throb");

      let matches = targetNode.href.match(/\/(\d+)\.user\.js$/);
      if (!matches) {
        let msg = 'Fatal error... Unable to locate diffid... Aborting this try';
        console.error(msg);
      }

      let diffid = matches[1];

      GM_xmlhttpRequest({
        method: "GET",
        url: "/scripts/version/" + scriptid + "/" + diffid + ".meta.js",
        onload: function (xhr) {
          targetNode.classList.remove("throb");
          switch (xhr.status) {
            case 200:
              targetNode.removeEventListener("mouseover", onMouseoverVersion, false);

              let
                  diffMb = parseMeta(xhr.responseText),
                  title = ""
              ;

              let names = gmcHome.get("showVersionsKeysString").split(",");
              for (let name in names) {
                let prefix, key;
                [key, prefix] = names[name].split(/:/).reverse();

                if (!prefix && typeof diffMb[key] != "undefined")
                  title += '@' + key + ' ' + diffMb[key] + '\n';
                else if (prefix && diffMb[prefix][key])
                  title += '@' + prefix + ":" + key + ' ' + diffMb[prefix][key] + '\n';
              }

              if (title != "")
                targetNode.title = title;

              if (gmcHome.get("archiveMode")) {

                let dateid = "";
                if (gmcHome.get("archiveDate")) {
                  let utc = new Date(diffMb["uso"]["timestamp"]);
                  dateid = utc.toLocaleFormat(".%Y%m%d%H%M.%S"); // NOTE: Watchpoint
                }

                let hashid = "";
                if (gmcHome.get("archiveHash")) {
                  hashid = "." + diffMb["uso"]["hash"];
                }

                let thatNode = targetNode.previousSibling.previousSibling;
                if (gmcHome.get("archiveVersionLast")) {
                  thatNode.setAttribute("download", thatNode.getAttribute("download").replace(/\.(\d+)\.user\.js$/, dateid + hashid + ".$1.user.js"));
                  thatNode.title = thatNode.title.replace(/\.(\d+)\.user\.js$/, dateid + hashid + ".$1.user.js");
                }
                else {
                  thatNode.setAttribute("download", thatNode.getAttribute("download").replace(/\.user\.js$/, dateid + hashid + ".user.js"));
                  thatNode.title = thatNode.title.replace(/\.user\.js$/, dateid + hashid + ".user.js");
                }
              }

              break;

            default:
              console.log('Untrapped status code of : ' + xhr.status);
              break;
          }
        }
      });
    }
  }

  /**
   *
   */
  function getVersions(aUrl, aPreviousVersionsNode) {
    GM_xmlhttpRequest({
      retry: 5,
      method: "GET",
      url: aUrl,
      onload: function (xhr) {
        switch (xhr.status) {
          case 404:
            if (halt404)
              this.retry = 0;
          case 500:
          case 502:
          case 503:
            if (this.retry-- > 0)
              setTimeout(GM_xmlhttpRequest, delayRetryMin + Math.round(Math.random() * (delayRetryMax - delayRetryMin)), this);
            else {
              if (aPreviousVersionsNode)
                aPreviousVersionsNode.parentNode.classList.remove("throb");

              let msg = 'Unable to retrieve the versions page at ' + aUrl;
              console.warn(msg);
            }
            break;
          case 200:
            let
                parser = new DOMParser(),
                doc = parser.parseFromString(xhr.responseText, "text/html")
            ;

            // ** Nab pagination **
            let paginationNode;
            let xpr = doc.evaluate(
              "//div[contains(concat(' ', normalize-space(@class), ' '), ' pagination ')]",
              doc.body,
              null,
              XPathResult.FIRST_ORDERED_NODE_TYPE,
              null
            );
            if (xpr && xpr.singleNodeValue) {
              let thisNode = xpr.singleNodeValue;

              paginationNode = thisNode.cloneNode(true);
            }

            // ** Nab versions **
            let versionsNode;
            doc.evaluate(
              "//div[@id='root']/div[contains(concat(' ', normalize-space(@class), ' '), ' container ')]/div[@id='content']/ul[not(@id)]/li",
              doc.body,
              null,
              XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
              xpr
            );

            if (xpr) {
              let nodeUl = document.createElement("ul");
              for (let i = 0, thisNode; thisNode = xpr.snapshotItem(i++);) {
                let
                    dateNode = thisNode.firstChild,
                    diffNode = thisNode.firstChild.nextSibling
                ;

                let dateid = dateNode.textContent.replace(/\n\[/, "").trim();

                if (gmcHome.get("showVersionsLocale")) {
                  // Adjust only if logged out
                  let xpr = doc.evaluate(
                    "//ul[contains(concat(' ', normalize-space(@class), ' '), ' login_status ')]//a[starts-with(@href, '/login')]",
                    doc.body,
                    null,
                    XPathResult.FIRST_ORDERED_NODE_TYPE,
                    null
                  );
                  if (xpr && xpr.singleNodeValue) {
                    let utc = new Date(dateid + " UTC");
                    dateid = utc.toLocaleFormat("%b %d, %Y %H:%M"); // NOTE: Watchpoint
                  }
                }

                let matches = diffNode.getAttribute("href").match(/\/scripts\/version\/\d+\/(\d+)\.user\.js/);
                if (!matches) {
                  let msg = 'Fatal error in determining diffid... Aborting?';
                  console.error(msg);
                  return; // die from this function
                }

                let diffid = matches[1];

                  let installNodeA = document.createElement("a");
                  installNodeA.href = "/scripts/version/" + scriptid + "/" + diffid + ".user.js";
                  installNodeA.textContent = dateid;

                  if (gmcHome.get("showVersionsKeys"))
                    installNodeA.addEventListener("mouseover", onMouseoverVersion, false);

                  let downloadNodeA;
                  if (gmcHome.get("archiveMode")) {
                    downloadNodeA = document.createElement("a");
                    downloadNodeA.href = "/scripts/version/" + scriptid + "/" + diffid + ".user.js#";
                    downloadNodeA.textContent = "download";
                    downloadNodeA.title = scriptid + "." + diffid + ".user.js";
                    downloadNodeA.setAttribute("download", scriptid + "." + diffid + ".user.js");
                  }

                  let diffNodeA = document.createElement("a");
                  diffNodeA.href = "/scripts/diff/" + scriptid + "/" + diffid;
                  diffNodeA.textContent = "changes";
                  diffNodeA.title = "\u2206 symmetric difference";
                  diffNodeA.addEventListener("click", function (ev) {
                    ev.preventDefault();
                    ev.target.parentNode.classList.add("throb");

                    let targetNode = ev.target;
                    GM_xmlhttpRequest({
                      retry: 5,
                      method: "GET",
                      url: targetNode.pathname,
                      onload: function (xhr) {
                        switch (xhr.status) {
                          case 404:
                            if (halt404)
                              this.retry = 0;
                          case 500:
                          case 502:
                          case 503:
                            if (this.retry-- > 0)
                              setTimeout(GM_xmlhttpRequest, delayRetryMin + Math.round(Math.random() * (delayRetryMax - delayRetryMin)), this);
                            else {
                              // Clear retrieving Selection markers
                              let listNode = targetNode.parentNode.parentNode;

                              let itemNode = listNode.firstChild;
                              while (itemNode) {
                                itemNode.classList.remove("throb");
                                itemNode = itemNode.nextSibling;
                              }
                            }
                            break;
                          case 200:
                            let
                                parser = new DOMParser(),
                                doc = parser.parseFromString(xhr.responseText, "text/html")
                            ;

                            let xpr = doc.evaluate(
                              "//pre",
                              doc.body,
                              null,
                              XPathResult.FIRST_ORDERED_NODE_TYPE,
                              null
                            );
                            if (xpr && xpr.singleNodeValue) {
                              let sourceNode = document.getElementById("source");
                              sourceNode.innerHTML = xpr.singleNodeValue.innerHTML;

                              // Clear all Selection markers
                              let listNode = targetNode.parentNode.parentNode;

                              let itemNode = listNode.firstChild;
                              while (itemNode) {
                                itemNode.classList.remove("current");
                                itemNode.classList.remove("throb");
                                itemNode = itemNode.nextSibling;
                              }

                              // Set current selection marker
                              itemNode = targetNode.parentNode;
                              itemNode.classList.add("current");

                              enableCTTS();

                              // Hide numbering and reset margin for now if present
                              let numberNode = document.getElementById("number");
                              if (numberNode)
                                numberNode.classList.add("HID");

                              sourceNode.style.removeProperty("margin-left");
                            }

                            let currenturlNode = document.getElementById("currenturl");
                            if (currenturlNode)
                              currenturlNode.setAttribute("placeholder", targetNode.protocol + "//" + targetNode.hostname + targetNode.pathname);

                            break;
                        }
                      }
                    });
                  }, false);

                  let viewNodeA = document.createElement("a");
                  viewNodeA.href = "/scripts/version/" + scriptid + "/" + diffid + ".user.js#";
                  viewNodeA.textContent = "view";
                  viewNodeA.title = "\u2229 intersection";
                  viewNodeA.addEventListener("click", function (ev) {
                    ev.preventDefault();
                    ev.target.parentNode.classList.add("throb");

                    let targetNode = ev.target;
                    GM_xmlhttpRequest({
                      retry: 5,
                      method: "GET",
                      url: targetNode.pathname,
                      onload: function (xhr) {
                        switch (xhr.status) {
                          case 404:
                            if (halt404)
                              this.retry = 0;
                          case 500:
                          case 502:
                          case 503:
                            if (this.retry-- > 0)
                              setTimeout(GM_xmlhttpRequest, delayRetryMin + Math.round(Math.random() * (delayRetryMax - delayRetryMin)), this);
                            else {
                              // Clear retrieving Selection markers
                              let listNode = targetNode.parentNode.parentNode;

                              let itemNode = listNode.firstChild;
                              while (itemNode) {
                                itemNode.classList.remove("throb");
                                itemNode = itemNode.nextSibling;
                              }
                            }
                            break;
                          case 200:
                            let responseText = xhr.responseText;

                            if (responseText.match(/[\r\n]$/))
                              responseText = responseText.replace(/[\r\n]*$/, "");

                            let sourceNode = document.getElementById("source");
                            sourceNode.textContent = responseText;

                            // Clear all Selection markers
                            let listNode = targetNode.parentNode.parentNode;

                            let itemNode = listNode.firstChild;
                            while (itemNode) {
                              itemNode.classList.remove("current");
                              itemNode.classList.remove("throb");
                              itemNode = itemNode.nextSibling;
                            }

                            // Set current selection marker
                            listNode = targetNode.parentNode;
                            listNode.classList.add("current");

                            enableCTTS();

                            // If source is < 20KB then autohighlight just like USO does
                            if (xhr.responseText.length < 20480)
                              (wrappedJSObject || window).sh_highlightDocument();

                            if (gmcHome.get("showLineNumbers"))
                              renumber(sourceNode);

                            let currenturlNode = document.getElementById("currenturl");
                            if (currenturlNode)
                              currenturlNode.setAttribute("placeholder", targetNode.protocol + "//" + targetNode.hostname + targetNode.pathname);

                            break;
                        }
                      }
                    });
                  }, false);

                let nodeLi = document.createElement("li");
                nodeLi.appendChild(document.createTextNode("["));
                nodeLi.appendChild(viewNodeA);
                nodeLi.appendChild(document.createTextNode("|"));
                nodeLi.appendChild(diffNodeA);

                if (downloadNodeA) {
                  nodeLi.appendChild(document.createTextNode("|"));
                  nodeLi.appendChild(downloadNodeA)
                }

                nodeLi.appendChild(document.createTextNode("]"));
                nodeLi.appendChild(installNodeA);

                nodeUl.appendChild(nodeLi);

              } /** /for thisNode **/

              let versionsNodeDiv = document.getElementById("versions");
              if (versionsNodeDiv) {
                while (versionsNodeDiv.hasChildNodes())
                  versionsNodeDiv.removeChild(versionsNodeDiv.firstChild);
              }
              else {
                versionsNodeDiv = document.createElement("div");
                versionsNodeDiv.id = "versions";
                versionsNodeDiv.className = "pagetear";

                GM_setStyle({
                    node: gCSS,
                    data:
                      [
                        "#versions p  { margin: 0; }",
                        "#versions p > a { color: #000; font-weight: bold; margin-right: 0.25em; text-decoration: none; }",
                        "#versions p > span { color: #666; font-size: 0.8em; }",
                        "#versions ul { -moz-column-width: " + (!gmcHome.get("archiveMode") ? "19" : "22") + "em; column-width: " + (!gmcHome.get("archiveMode") ? "19" : "22") + "em; list-style: none; margin-bottom: 0.5em; }",
                        "#versions ul a { margin-left: 0.25em; margin-right: 0.25em; }",
                        "#versions ul a:last-child { color: #000; margin-left: 0.5em; text-decoration: none; }",
                        "#versions .current { background-color: #ddd; }",

                      ].join("\n")
                });
              }

              let sourceurlNode = document.getElementById("sourceurl");
              if (sourceurlNode)
                sourceurlNode.parentNode.insertBefore(versionsNodeDiv, sourceurlNode);
              else {
                let msg = 'Hook node for versions and diffs not found';
                console.error(msg);
                return; // die this function
              }

              /** Replace pagination **/
              if (paginationNode) {
                while (versionsNodeDiv.hasChildNodes())
                  versionsNodeDiv.removeChild(versionsNodeDiv.firstChild);

                versionsNodeDiv.appendChild(paginationNode);

                document.evaluate(
                  "//div[contains(concat(' ', normalize-space(@class), ' '), ' pagination ')]/a",
                  document.body,
                  null,
                  XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                  xpr
                );
                if (xpr)
                  for (let i = 0, thisNode; thisNode = xpr.snapshotItem(i++);) {
                    thisNode.addEventListener("click", function (ev) {
                      ev.preventDefault();

                      ev.target.classList.add("throb");
                      getVersions(ev.target.pathname + ev.target.search);
                    }, false);
                  }
              }

              /** (Re)create pseudo-header **/
              let nodeSpan = document.createElement("span");
              nodeSpan.textContent = countVersions;

              let nodeA = document.createElement("a");
              nodeA.href = "/scripts/versions/" + scriptid;
              nodeA.textContent = "Source versions and diffs:";

              let nodeP = document.createElement("p");

              nodeP.appendChild(nodeA);
              nodeP.appendChild(nodeSpan);

              if (paginationNode)
                versionsNodeDiv.insertBefore(nodeP, paginationNode);
              else
                versionsNodeDiv.appendChild(nodeP);

              versionsNodeDiv.appendChild(nodeUl);

              if (aPreviousVersionsNode)
                aPreviousVersionsNode.parentNode.parentNode.removeChild(aPreviousVersionsNode.parentNode);

            } /** /xpr existance **/

            break;

        } /** /switch xhr.status **/
      }
    });

  }

  /**
   *
   */
  function onClickVersions(ev) {
    ev.preventDefault();
    ev.target.removeEventListener("click", onClickVersions, false);

    let thisNode = ev.target;

    if (!countVersions) {
      let matches = thisNode.textContent.match(/^(\d+)/);
      if (matches)
        countVersions = parseInt(matches[1]) + 1;
      else
        countVersions = "?";
    }

    let noticeNode = thisNode.parentNode;
    noticeNode.classList.add("throb");

    getVersions("/scripts/versions/" + scriptid, thisNode);
  }

  /**
   *
   */
  function setUrlErr(aMsg) {
    let refreshurlNode = document.getElementById("refreshurl");
    if (refreshurlNode) {
      refreshurlNode.classList.remove("connecting");
      refreshurlNode.classList.remove("loading");
    }

    let urlbarNode = document.getElementById("urlbar");
    if (urlbarNode)
      urlbarNode.classList.add("err");

    if (aMsg)
      console.error(aMsg);
  }

  /**
   *
   */
  function clearUrlErr() {
    let urlbarNode = document.getElementById("urlbar");
    if (urlbarNode)
      urlbarNode.classList.remove("err");
  }

  /**
   *
   */
  function loadUrl(aUrl) {
      let refreshurlNode = document.getElementById("refreshurl");
      if (refreshurlNode)
        refreshurlNode.classList.add("connecting");

      try {
        GM_xmlhttpRequest({
          state: "connecting",
          retry: 5,
          method: "GET",
          url: aUrl,
          onabort: function (xhr) {
            this.state = "reload";
            setUrlErr('Error aborted ' + this.url + ' url');
          },
          onerror: function (xhr) {
            this.state = "reload";
            setUrlErr('Error retrieving ' + this.url + ' url');
          },
          ontimeout: function (xhr) {
            this.state = "reload";
            setUrlErr('Error timed out ' + this.url + ' url');
          },
          onprogress: function (xhr) {
            if (this.state == "connecting") {
              this.state = "loading";
              let refreshurlNode = document.getElementById("refreshurl")
              if (refreshurlNode)
                refreshurlNode.classList.add("loading");
            }
          },
          onload: function (xhr) {
            switch (xhr.status) {
              case 404:
                if (halt404)
                  this.retry = 0;
              case 500:
              case 502:
              case 503:
                if (this.retry-- > 0) {
                  this.state = "connecting";
                  let refreshurlNode = document.getElementById("refreshurl")
                  if (refreshurlNode)
                    refreshurlNode.classList.remove("loading");
                  setTimeout(GM_xmlhttpRequest, delayRetryMin + Math.round(Math.random() * (delayRetryMax - delayRetryMin)), this);
                }
                else {
                  this.state = "reload";
                  setUrlErr('Error retrying ' + xhr.finalUrl + ' url');
                }
                break;
              case 200:
                this.state = "processing";
                let refreshurlNode = document.getElementById("refreshurl")
                if (refreshurlNode)
                  refreshurlNode.classList.add("processing");

                // start twiddling
                let sourceNode = document.getElementById("source");

                while (sourceNode.hasChildNodes())
                  sourceNode.removeChild(sourceNode.firstChild);

                sourceNode.textContent = xhr.responseText.trim();

                enableCTTS();

                // If source is < 20KB then autohighlight just like USO does
                if (xhr.responseText.length < 20480)
                  (wrappedJSObject || window).sh_highlightDocument();

                if (gmcHome.get("showLineNumbers"))
                  renumber(sourceNode);

                let currenturlNode = document.getElementById("currenturl");
                if (currenturlNode) {
                  let finalUrl = xhr.finalUrl;

                  currenturlNode.setAttribute("placeholder", finalUrl);
                  currenturlNode.value = "";

                  let currenturlsNode = document.getElementById("currenturls");
                  if (currenturlsNode) {
                    let
                        found = false,
                        xpr = document.evaluate(
                          "./option",
                          currenturlsNode,
                          null,
                          XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                          null
                        )
                    ;
                    if (xpr)
                      for (let i = 0, thisNode; thisNode = xpr.snapshotItem(i++);)
                        if (thisNode.value == finalUrl) {
                          found = true;
                          break;
                        }

                    if (!found) {
                      let nodeOption = document.createElement("option");
                      nodeOption.value = finalUrl;

                      currenturlsNode.insertBefore(nodeOption, currenturlsNode.firstChild);
                    }
                  }
                }

                this.state = "reload";
                if (refreshurlNode) {
                  refreshurlNode.classList.remove("connecting");
                  refreshurlNode.classList.remove("loading");
                  refreshurlNode.classList.remove("processing");
                }

                break;
              default:
                this.state = "reload";
                setUrlErr('Error reponse ' + xhr.status + ' for ' + xhr.finalUrl + ' url');
                break;
            }
          }
        });
      }
      catch (e) {
        setUrlErr();
      }
    }

  function enableCTTS() {
    let xpr = document.evaluate(
      "//button[.='Change Tabs to Spaces']",
      document.body,
      null,
      XPathResult.FIRST_ORDERED_NODE_TYPE,
      null
    );
    if (xpr && xpr.singleNodeValue) {
      let thisNode = xpr.singleNodeValue;

      thisNode.removeAttribute("disabled");
      thisNode = thisNode.nextSibling;
      thisNode.removeAttribute("disabled");
    }
  }

  /**
   *    main()
   */
  let
      halt404 = true,
      delayRetryMin = 3000,
      delayRetryMax = 8000,
      delayFind = 0,
      protocol = "http" + (/^https:$/i.test(location.protocol) ? "s" : "") + ":",
      pathname = location.pathname,
      script_nameNode = getScript_nameNode(),
      script_summaryNodes = getScript_summaryNodes(),
      scriptid = getScriptid(),
      mb,
      gCSS = GM_setStyle({
        media: "screen, projection",
        data:
          [
            ".hid { display: none; }",
            ".HID { display: none !important }",

            ".throb { animation: 1s ease 0s alternate none infinite script-nav-throb; }",
            "@keyframes script-nav-throb { from { background-color: #ddd; } to { background-color: #fff; } }",
            ".blah { color: #f00 !important; }",

            ""
          ].join("\n")
      }),
      countVersions,
      gmcHome,
      gmcTextareas = [
        "hideNavTabString",
        "hideH6String",
        "showKeysString",
        "insertH6StringMd",
        "showStringsStringPre",
        "showStringsString",
        "insertH6StringFinds",
        "showVersionsKeysString"
      ],
      uac = false
  ;

  /** Detect UAC **/
  let xpr = document.evaluate(
    "//div[contains(concat(' ', normalize-space(@class), ' '), ' alt_topbottom ')]",
    document.body,
    null,
    XPathResult.FIRST_ORDERED_NODE_TYPE,
    null
  );
  if (xpr && xpr.singleNodeValue) {
    let thisNode = xpr.singleNodeValue;

    uac = true;

    // Nearest fix(es) for any glitches with UAC
    GM_setStyle({
      node: gCSS,
      data: [
        "#screenshots { width: 98% !important; }",
        "#activity, #topics { float: inherit !important; }" // Alternative: "h6 { clear: both; }",

      ].join("\n")
    });
  }

  if (typeof GM_configStruct == "undefined") {
    let msg = 'Fatal error. GM_config not found';
    console.error(msg);
    return;
  }

  // Let the GC know to remove some preallocated memory
  GM_config = undefined;

  /** Create data store and default UI **/
  gmcHome = new GM_configStruct();
  gmcHome.id = "gmc69307home";

  let full_descriptionNode = document.getElementById("full_description");
  if (full_descriptionNode && !full_descriptionNode.firstChild) {
    let nodeDiv = document.createElement("div");
    full_descriptionNode = divNode.appendChild(nodeDiv);
  }
  else {
    let nodeDiv = document.createElement("div");
    if (full_descriptionNode)
      full_descriptionNode = full_descriptionNode.insertBefore(nodeDiv, full_descriptionNode.firstChild);
    else
      full_descriptionNode = document.body.appendChild(nodeDiv);
  }

  gmcHome.init(
    full_descriptionNode,
    [
      '<img alt="Count Issues" title="uso &ndash; Count Issues" src="' + GM_getResourceURL("icon") + '" />',
      '<p>Preferences</p>',
      '<span>',
        '<a href="' + protocol + '//github.com/sizzlemctwizzle/GM_config/wiki/">',
            '<img alt="GM_config" title="Powered in part by GM_config" src="' + GM_getResourceURL("gmc") + '" />',
        '</a>',
      '</span>'

    ].join(""),

    GM_setStyle({
      node: null,
      data:
        [
          "@media screen, projection {",
                "#gmc69307home { position: static !important; z-index: 0 !important; width: auto !important; height: auto !important; max-height: none !important; max-width: none !important; margin: 0 0 0.5em 0 !important; border: 1px solid #ddd !important; clear: right !important; }",

                "#gmc69307home_header a { display: inline; }",
                "#gmc69307home_header img { vertical-align: middle; }",
                "#gmc69307home_header > img { height: 32px; margin-right: 0.25em; width: 32px; }",
                "#gmc69307home_header > p { display: inline; margin: 0; vertical-align: middle; }",
                "#gmc69307home_header span { float: right; }",
                "#gmc69307home_header span > a { display: inline; margin-left: 0.25em; }",
                "#gmc69307home_wrapper { background-color: #eee; padding-bottom: 0.25em; }",
                "#gmc69307home .config_header { background-color: #333; color: #fff; font-size: 1.57em; margin: 0; padding: 0 0.5em; text-align: left; }",
                "#gmc69307home .config_var { clear: both; margin: 0.33em; padding: 0; }",
                "#gmc69307home .field_label { color: #333; font-size: 100%; font-weight: normal; margin: 0 0.25em; position: relative; top: -0.2em; }",
                "#gmc69307home .section_header_holder { margin: 0.25em 1.5em !important; }",
                "#gmc69307home .section_desc { margin: 0.25em 1.5em !important; }",

                    ".gmc-yellownote { background-color: #ffd; font-size: 0.66em !important; }",
                    ".gmc69307home-invisilink { text-decoration: none; color: #000; }",
                    ".gmc69307home-invisilink:hover { color: #000; }",

                    "#gmc69307home_wrapper textarea,",
                    "#gmc69307home_wrapper input",
                    "{ font-size: 1em; }",

                    "#gmc69307home_wrapper input[type='text']",
                    "{ text-align: right; width: 2em; }",

                      "#gmc69307home_field_hideNavTabString,",
                      "#gmc69307home_field_hideH6String,",
                      "#gmc69307home_field_showKeysString,",
                      "#gmc69307home_field_insertH6StringMd,",
                      "#gmc69307home_field_showStringsStringPre,",
                      "#gmc69307home_field_showStringsString,",
                      "#gmc69307home_field_insertH6StringFinds,",
                      "#gmc69307home_field_showVersionsKeysString",
                      "{ margin-left: 1.7em; min-width: 95.1%; max-width: 95.1%; word-break: break-all; }",

                      "#gmc69307home_field_hideNavTabString,",
                      "#gmc69307home_field_hideH6String",
                      "{ max-height: 3em; }",

                      "#gmc69307home_field_showKeysString,",
                      "#gmc69307home_field_insertH6StringMd,",
                      "#gmc69307home_field_insertH6StringFinds,",
                      "#gmc69307home_field_showVersionsKeysString",
                      "{ max-height: 9em; }",

                      "#gmc69307home_maxHeightListMd_field_label,",
                      "#gmc69307home_maxHeightListFinds_field_label,",
                      "#gmc69307home_fontSize_field_label",
                      "{ position: static !important; top: auto !important; }",

                        "#gmc69307home_trimSourceCode_var,",

                        "#gmc69307home_hideH6Reinforce_var,",

                        "#gmc69307home_checkAgainstHomepageUSO_var,",
                        "#gmc69307home_insertH6Md_var,",
                        "#gmc69307home_insertH6StringMd_var,",
                        "#gmc69307home_limitMaxHeightMd_var,",

                        "#gmc69307home_showStringsAuto_var,",
                        "#gmc69307home_deobST_var,",
                        "#gmc69307home_deobJsCode_var,",
                        "#gmc69307home_showSize_var,",
                        "#gmc69307home_insertH6Finds_var,",
                        "#gmc69307home_insertH6StringFinds_var,",
                        "#gmc69307home_limitMaxHeightFinds_var,",
                        "#gmc69307home_maxHeightListFinds_var",

                        "#gmc69307home_showVersionsSource_var,",
                        "#gmc69307home_maxContainer_var,",
                        "#gmc69307home_showVersionsLocale_var,",
                        "#gmc69307home_showVersionsKeys_var,",
                        "#gmc69307home_showVersionsKeysString_var,",
                        "{ margin-left: 2em !important; }",

                        "#gmc69307home_archiveMode_var",
                        "{ margin-left: 2em !important; }",

                        "#gmc69307home_archiveVersionLast_var,",
                        "#gmc69307home_archiveDate_var,",
                        "#gmc69307home_archiveHash_var",
                        "{ margin-left: 3.5em !important; }",

                        "#gmc69307home_maxHeightListMd_var,",
                        "#gmc69307home_maxHeightListFinds_var",
                        "{ margin-left: 4em !important; }",

                        "#gmc69307home_hideNavTabString_field_label,",
                        "#gmc69307home_hideH6String_field_label,",
                        "#gmc69307home_showKeysString_field_label,",
                        "#gmc69307home_insertH6StringMd_field_label,",
                        "#gmc69307home_showStringsStringPre_field_label,",
                        "#gmc69307home_showStringsString_field_label,",
                        "#gmc69307home_insertH6StringFinds_field_label,",
                        "#gmc69307home_showVersionsKeysString_field_label",
                        "{ margin-left: 1.75em !important; }",

                "#gmc69307home .reset, #gmc69307home .reset a, #gmc69307home_buttons_holder { text-align: inherit; }",
                "#gmc69307home_buttons_holder { margin: 0.5em; }",
                "#gmc69307home_saveBtn { margin: 0.5em !important; padding: 0 3.0em !important; }",
                "#gmc69307home_resetLink { margin-right: 1.5em; }",
                "#gmc69307home_closeBtn { display: none; }",
          "}",

          "@media print {",
              "#gmc69307home { display: none !important; }",
          "}"

        ].join("\n")
    }),
    {
      'hideNavTab': {
          "section": [],
          "type": 'checkbox',
          "label": 'Hide navigation tab(s) if present',
          "default": false
      },
      'hideNavTabString': {
          "type": 'textarea',
          "label": '<em class="gmc-yellownote">use commas to separate tab names</em>',
          "default": "Share"
      },
      'trimSourceCode': {
          "type": 'checkbox',
          "label": 'Trim " Code" from the "Source Code" tab <em class="gmc-yellownote">useful for more screen real estate</em>',
          "default": false
      },

      'hideH6': {
          "section": [, ""],
          "type": 'checkbox',
          "label": 'Hide header(s) if present in sidebar',
          "default": false
      },
      'hideH6String': {
          "type": 'textarea',
          "label": '<em class="gmc-yellownote">use commas to separate headers</em>',
          "default": "Share"
      },
      'hideH6Reinforce': {
          "type": 'checkbox',
          "label": 'Reinforce hidden status',
          "default": true
      },

      'showKeys': {
          "section": [, ""],
          "type": 'checkbox',
          "label": 'Show metadata block key(s) if present or different than USO in sidebar',
          "default": true
      },
      'showKeysString': {
          "type": 'textarea',
          "label": '<em class="gmc-yellownote">use commas to separate keys</em>',
          "default": "name,icon,description,version,copyright,license,namespace,updateURL,downloadURL,installURL,grant,require,resource,run-at,include,match,exclude"
      },
      'checkAgainstHomepageUSO': {
          "type": 'checkbox',
          "label": 'Check USO script urls for homepage existence <em class="gmc-yellownote">Rate and Limiting may apply</em>',
          "default": false
      },
      'insertH6Md': {
          "type": 'checkbox',
          "label": 'Insert item types before these headers if present <em class="gmc-yellownote">leave blank for first - disable for last</em>',
          "default": false
      },
      'insertH6StringMd': {
          "type": 'textarea',
          "label": '<em class="gmc-yellownote">use commas to separate headers</em>',
          "default": "Groups,Admin for script,Tags,Other Scripts by Author"
      },
      'limitMaxHeightMd': {
          "type": 'checkbox',
          "label": 'Limit maximum height of all shown item types',
          "default": false
      },
      'maxHeightListMd': {
          "type": 'unsigned number',
          "label": 'em maximum height of all shown item types',
          "default": 10
      },

      'showStrings': {
          "section": [, ""],
          "type": 'checkbox',
          "label": 'Show Lost and Found in sidebar',
          "default": false
      },
      'showStringsStringPre': {
          "type": 'textarea',
          "label": '<em class="gmc-yellownote">use newlines to separate regular expression ready strings before deobfuscation is attempted</em>',
          "default": "p,a,c,k,e,[dr]\ncookie\nGM_xmlhttpRequest\nXMLHttpRequest\nlocation\nexport\n\\b(?:un)?eval\\b\n(?:https?:\\/\\/.*?\\.google\\.com)?\\/?blank\\.html?"
      },
      'showStringsString': {
          "type": 'textarea',
          "label": '<em class="gmc-yellownote">use newlines to separate regular expression ready strings after deobfuscate is attempted</em>',
          "default": "cookie\nGM_xmlhttpRequest\nXMLHttpRequest\nlocation\nexport\n\\b(?:un)?eval\\b\n(?:https?:\\/\\/.*?\\.google\\.com)?\\/?blank\\.html?"
      },
      'showStringsAuto': {
          "type": 'checkbox',
          "label": 'Auto show <em class="gmc-yellownote">WARNING: slower browsing experience and uses more immediate bandwidth</em>',
          "default": false
      },

      'deobST': {
          "type": 'checkbox',
          "label": 'Deobfuscate with Simple Transcode',
          "default": true
      },

      'deobJsCode': {
          "type": 'checkbox',
          "label": 'Deobfuscate with JsCode',
          "default": false
      },

      'showSize': {
          "type": 'checkbox',
          "label": 'Show approximate file size in script navigation bar',
          "default": false
      },
      'insertH6Finds': {
          "type": 'checkbox',
          "label": 'Insert item types before these headers if present <em class="gmc-yellownote">leave blank for first - disable for last</em>',
          "default": false
      },
      'insertH6StringFinds': {
          "type": 'textarea',
          "label": '<em class="gmc-yellownote">use commas to separate headers</em>',
          "default": "Groups,Admin for script,Tags,Other Scripts by Author"
      },
      'limitMaxHeightFinds': {
          "type": 'checkbox',
          "label": 'Limit maximum height of all shown item types',
          "default": false
      },
      'maxHeightListFinds': {
          "type": 'unsigned number',
          "label": 'em maximum height of all shown item types',
          "default": 10
      },

      'fontSize': {
          "section": [, ""],
          "type": 'unsigned number',
          "label": 'em font size for all items found under the specified item type',
          "default": 1
      },
      'showVersionsSource': {
          "section": [, ""],
          "type": 'checkbox',
          "label": 'Show inline Versions and Diffs on Source Code page',
          "default": true
      },
      'maxContainer': {
          "type": 'checkbox',
          "label": 'Use the maximum container width <em class="gmc-yellownote">active <a href="/scripts/show/34698">userscripts.org alternate CSS</a> required</em>',
          "default": false
      },
      'showVersionsLocale': {
          "type": 'checkbox',
          "label": 'Use Locale instead of UTC when logged out',
          "default": true
      },
      'showVersionsKeys': {
          "type": 'checkbox',
          "label": 'Show metadata block key(s) if present in tooltip',
          "default": false
      },
      'showVersionsKeysString': {
          "type": 'textarea',
          "label": '<em class="gmc-yellownote">use commas to separate keys</em>',
          "default": "name,namespace,version,uso:hash"
      },
      'archiveMode': {
          "type": 'checkbox',
          "label": 'Use archive mode',
          "default": false
      },
      'archiveVersionLast': {
          "type": 'checkbox',
          "label": 'Place version last in the filename before the extension <em class="gmc-yellownote">useful for automation when controlled sorting may not be available</em>',
          "default": false
      },
      'archiveDate': {
          "type": 'checkbox',
          "label": 'Include date stamp in the filename <em class="gmc-yellownote">hover over the visible dates to retrieve the full date from the meta.js</em>',
          "default": false
      },
      'archiveHash': {
          "type": 'checkbox',
          "label": 'Include file hash in the filename <em class="gmc-yellownote">hover over the visible dates to retrieve the sha1 hash from the meta.js</em>',
          "default": false
      },
      'showLineNumbers': {
          "type": 'checkbox',
          "label": 'Show line numbers on Source Code page <em class="gmc-yellownote">BETA</em>',
          "default": false
      },

      'hideNavTabStringHeight': { "type": 'hidden', "default": "16px" },
      'hideH6StringHeight': { "type": 'hidden', "default": "16px" },
      'showKeysStringHeight': { "type": 'hidden', "default": "16px" },
      'insertH6StringMdHeight': { "type": 'hidden', "default": "16px" },
      'showStringsStringPreHeight': { "type": 'hidden', "default": "96px" },
      'showStringsStringHeight': { "type": 'hidden', "default": "96px" },
      'insertH6StringFindsHeight': { "type": 'hidden', "default": "16px" },
      'showVersionsKeysStringHeight': { "type": 'hidden', "default": "16px" }
    }
  );

  gmcHome.onOpen = function () {
    gmcHome.fields["showStringsStringPre"].node.setAttribute("wrap", "off");
    gmcHome.fields["showStringsString"].node.setAttribute("wrap", "off");
  }

  gmcHome.onSave = function () {
    let
        write = false,
        open = false
    ;

    GM_setStyle({
        node: gCSS,
        data:
          [
            ".md ul { max-height: " + (gmcHome.get("limitMaxHeightMd") ? gmcHome.get("maxHeightListMd") + "em" : "none") + "; }"

          ].join("\n")
    });

    let names = gmcHome.get("showKeysString").split(",");
    for (let i = 0, len = names.length; i < len; ++i) {
      names[i] = names[i].trim();
    }
    names = names.join(",");

    if (names != gmcHome.get("showKeysString")) {
      gmcHome.set("showKeysString", names);
      write = open = true;
    }

    GM_setStyle({
        node: gCSS,
        data:
          [
            ".finds { max-height: " + (gmcHome.get("limitMaxHeightFinds") ? gmcHome.get("maxHeightListFinds") + "em" : "none") + "; }"

          ].join("\n")
    });


    gmcTextareas.forEach(function (e, i, a) {
      GM_setStyle({
          node: gCSS,
          data:
            [
              "textarea#gmc69307home_field_" + e + " { height: " + gmcHome.get(e + "Height") + "; }"

            ].join("\n")
      });

      let height = gmcHome.fields[e].node.clientHeight + "px";
      if (height != gmcHome.get(e + "Height")) {
        gmcHome.set(e + "Height", height);
        write = true;
      }
    });

    GM_setStyle({
        node: gCSS,
        data:
          [
            ".md li, .finds li { font-size: " + gmcHome.get("fontSize") + "em ; }"

          ].join("\n")
    });

    if (write) gmcHome.write();
    if (open) { gmcHome.close(); gmcHome.open(); }
  }

  if (/\/scripts\/show\/69307\/?$/.test(pathname)) {

    gmcTextareas.forEach(function (e, i, a) {
      GM_setStyle({
          node: gCSS,
          data:
            [
              "textarea#gmc69307home_field_" + e + " { height: " + gmcHome.get(e + "Height") + "; }"

            ].join("\n")
      })
    });

    gmcHome.open();

    document.getElementById("gmc69307home").removeAttribute("style");

    gmcTextareas.forEach(function (e, i, a) {
      gmcHome.fields[e].node.setAttribute("spellcheck", "false");
    });
  }

  /**
   *        Hide script-nav entries and optionally trim Source Code label while doing it
   */
  if (gmcHome.get("hideNavTab")) {
    let xpr = document.evaluate(
    "//ul[@id='script-nav']/li",
      document.body,
      null,
      XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
      null
    );
    if (xpr)
      for (let i = 0, thisNode; thisNode = xpr.snapshotItem(i++);) {

        let tabs = gmcHome.get("hideNavTabString").split(",");
        for (let tab in tabs) {
          let name = tabs[tab].trim();
          if (name) {
            let re = "\\s*" + name;
            if (thisNode.textContent.match(new RegExp(re, "")))
              thisNode.classList.add("hid");
          }
        }

        if (gmcHome.get("trimSourceCode")) {
          let xpr = document.evaluate(
            "..//*[starts-with(text(), 'Source Code')]",
            thisNode,
            null,
            XPathResult.FIRST_ORDERED_NODE_TYPE,
            null
          );
          if (xpr && xpr.singleNodeValue) {
            let thisNode = xpr.singleNodeValue;

            thisNode.textContent = "Source";
          }
        }
      }
  }

  /**
   *        Hide USO headers in sidebar if present
   */
  if (gmcHome.get("hideH6")) {
    let xpr = document.evaluate(
      "//div[@id='right']//h6",
      document.body,
      null,
      XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
      null
    );
    if (xpr)
      for (let i = 0, thisNode; thisNode = xpr.snapshotItem(i++);) {
        let headers = gmcHome.get("hideH6String").split(",");
        for (let header in headers) {
          let name = headers[header].trim();
          if (name) {
            let re = "\\s*" + name;
            if (thisNode.textContent.match(new RegExp(re, ""))) {
              thisNode.classList.add("hid");

              let thatNode = thisNode.nextSibling;
              let loop = true;
              while (loop) {
                if (thatNode.tagName)
                  if (thatNode.tagName.toLowerCase() != "h6")
                    switch (thatNode.tagName.toLowerCase()) {
                      case "script":
                        break;
                      default:
                        if (thatNode.id != "fans")
                          if (gmcHome.get("hideH6Reinforce"))
                            thatNode.classList.add("HID");
                          else
                            thatNode.classList.add("hid");
                        break;
                    }
                  else
                    loop = false;
                thatNode = thatNode.nextSibling;
                if (!thatNode)
                  loop = false;
              }
            }
          }
        }
      }
  }

  if (scriptid) {
    /**
    *    Count Issues
    */

    let xpr = document.evaluate(
      "//ul[@id='script-nav']/li[contains(., 'Issues')]",
      document.body,
      null,
      XPathResult.FIRST_ORDERED_NODE_TYPE,
      null
    );

    if (xpr && xpr.singleNodeValue) {
      let thisNode = xpr.singleNodeValue;

      let nodeSpan = document.createElement("span");
      nodeSpan.textContent = "?";

      let re = new RegExp("^\/scripts\/issues\/" + scriptid + "\/?$");
      if (re.test(location.pathname))
        countIssues(thisNode, nodeSpan, document);
      else {
        thisNode.classList.add("throb");

        GM_xmlhttpRequest({
          retry: 5,
          method: "GET",
          url: "/scripts/issues/" + scriptid,
          onload: function (xhr) {
            switch (xhr.status) {
              case 404:
                if (halt404)
                  this.retry = 0;
              case 500:
              case 502:
              case 503:
                if (this.retry-- > 0)
                  setTimeout(GM_xmlhttpRequest, delayRetryMin + Math.round(Math.random() * (delayRetryMax - delayRetryMin)), this);
                else {
                  nodeSpan.classList.add("blah");

                  countIssues(thisNode, nodeSpan);

                  thisNode.classList.remove("throb");
                }
                break;
              case 200:
                let
                    parser = new DOMParser(),
                    doc = parser.parseFromString(xhr.responseText, "text/html")
                ;

                countIssues(thisNode, nodeSpan, doc);

                thisNode.classList.remove("throb");
                break;
              default:
                countIssues(thisNode, nodeSpan);

                thisNode.classList.remove("throb");
                break;
            }
          }
        });
      }
    }

    /** A bunch of other stuff **/

    /**
     *          mb specific
     */
    GM_xmlhttpRequest({
      retry: 5,
      url: "/scripts/source/" + scriptid + ".meta.js",
      method: "GET",
      onload: function (xhr) {
        switch (xhr.status) {
          case 404:
            if (halt404)
              this.retry = 0;
          case 500:
          case 502:
          case 503:
            if (this.retry-- > 0)
              setTimeout(GM_xmlhttpRequest, delayRetryMin + Math.round(Math.random() * (delayRetryMax - delayRetryMin)), this);
            else {
              let msg = 'Unable to retrieve the metadata block';
              console.error(msg);
              return; // die this function
            }
            break;
          case 200:
            mb = parseMeta(xhr.responseText);
            if (!mb) {
              let msg = 'Metadata block is missing';
              console.error(msg);
              return; // die this function
            }

            /** Start twiddling **/

            /**
             *        name key validation on every page of script
             */
            let name = lastValueOf(mb, "name");
            if (name != script_nameNode.textContent.trim()) {
              script_nameNode.classList.add("blah");
              script_nameNode.title = "@name " + name;
            }


            /**
             *        Items specific to script homepage
             */
            if (/\/scripts\/show\//.test(pathname)) {

              /**
               *        If diffid is missing or differs abort
               */
              let xpr = document.evaluate(
                "//meta[@name='uso:version']",
                document.head,
                null,
                XPathResult.FIRST_ORDERED_NODE_TYPE,
                null
              );
              if (xpr && xpr.singleNodeValue) {
                let thisNode = xpr.singleNodeValue;

                if (lastValueOf(mb, "version", "uso") != thisNode.getAttribute("content")) {
                  let msg = 'Fatal error comparing current meta.js to page meta... Aborting';
                  console.error(msg);
                  return;
                }
              }
              else {
                let msg = 'Fatal error determining version... Aborting';
                console.error(msg);
                return;
              }

              /**
               *        Description, Version, etc. validation
               */

              script_summaryNodes.forEach(function (e, i, a) {
                let xpr = document.evaluate(
                "./p/b[.='Script Summary:' or .='Version:']/following-sibling::text()",
                  e,
                  null,
                  XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                  null
                );
                if (xpr) {
                  let nodes = [];
                  for (let i = 0, thisNode; thisNode = xpr.snapshotItem(i++);)
                    switch (thisNode.previousSibling.textContent.toLowerCase().trim()) {
                      case "script summary:":
                        if (mb["description"]) {
                          if (thisNode.textContent.trim() != lastValueOf(mb, "description")) {
                            thisNode.parentNode.classList.add("blah");
                            thisNode.parentNode.title = "@description " + lastValueOf(mb, "description");
                          }
                        }
                        else {
                          if (thisNode.textContent.trim() != "") {
                            thisNode.parentNode.classList.add("blah");
                            thisNode.parentNode.title = "undefined @description";
                          }
                        }
                        break;
                      case "version:":
                        if (thisNode.textContent.trim() != lastValueOf(mb, "version")) {
                          thisNode.parentNode.classList.add("blah");
                          thisNode.parentNode.title = "@version " + lastValueOf(mb, "version");
                        }
                        break;
                    }
                }
              });

              /**
               *        Sidebar stuff
               */

              let script_sidebarNode = document.getElementById("script_sidebar");
              if (script_sidebarNode) {
                /**
                 *       Metadata
                 */
                if (gmcHome.get("showKeys")) {
                  GM_setStyle({
                    node: gCSS,
                    data:
                      [
                        ".md { margin-bottom: 0.75em; }",
                        ".md h6 > a { color: #000; text-decoration: none; }",
                        ".md h6 > a:hover { color: #000; }",
                        ".md h6 span { color: #666; font-size: 0.7em; }",
                        ".md h6 a:last-child { float: right; opacity: 0; }",
                        ".md h6 a:hover { opacity: 1; }",
                        ".md h6 img { max-height: 1.5em; }",
                        ".md .blah { color: #f00 !important; }",
                        ".md .blah:hover { color: #ff4500; }",
                        ".md .checked { color: #006400 !important; }",
                        ".md .checked:hover { color: #008000; }",
                        ".md .unknown { color: #000 !important; }",
                        ".md .unknown:hover { color: #808080; }",
                        ".md ul { border-width: 0; font-size: x-small; margin: 0; overflow: auto; padding: 0 !important; width: 100%; }",
                        ".md li { color: #808080; white-space: nowrap; }",

                        ".aoicon { max-height: 48px; max-width: 48px; }",
                        ".resourceName { margin-right: 0.5em; }",

                        ""
                      ].join("\n")
                  });

                  if (gmcHome.get("limitMaxHeightMd"))
                    GM_setStyle({
                        node: gCSS,
                        data:
                          [
                            ".md ul { max-height: " + gmcHome.get("maxHeightListMd") + "em; }"

                          ].join("\n")
                    });

                  GM_setStyle({
                      node: gCSS,
                      data:
                        [
                          ".md li, .finds li { font-size: " + gmcHome.get("fontSize") + "em ; }"

                        ].join("\n")
                  });

                  let nodeDiv = document.createElement("div");
                  nodeDiv.classList.add("md");

                  let names = gmcHome.get("showKeysString").split(",");
                  for (let name in names) {

                    let
                        named = names[name],
                        mbNamed = mb[named]
                    ;

                    switch (named) {
                      case "name":
                        if (mbNamed)
                          if (typeof mbNamed == "string") {
                            if (mbNamed != script_nameNode.textContent)
                              displayName(nodeDiv, named, mbNamed, true);
                          }
                          else
                            displayName(nodeDiv, named, mbNamed, true);
                        else
                          console.error('Fatal error... @name should always exist in meta.js');
                        break;
                      case "namespace":
                        if (mbNamed)
                          if (typeof mbNamed == "string")
                            displayName(nodeDiv, named, mbNamed);
                          else
                            displayName(nodeDiv, named, mbNamed, true);
                        else
                          displayName(nodeDiv, named, null, true);
                        break;
                      case "description":
                        if (/\/scripts\/show\//.test(pathname))
                          script_summaryNodes.forEach(function (e, i, a) {
                            let xpr = document.evaluate(
                            "./p/b[.='Script Summary:']/following-sibling::text()",
                              e,
                              null,
                              XPathResult.FIRST_ORDERED_NODE_TYPE,
                              null
                            );
                            if (xpr && xpr.singleNodeValue) {
                              let thisNode = xpr.singleNodeValue;

                              if (mbNamed)
                                if (typeof mbNamed == "string") {
                                  if (mbNamed != thisNode.textContent.trim())
                                    displayName(nodeDiv, named, mbNamed, true);
                                }
                                else
                                  displayName(nodeDiv, named, mbNamed, true);
                            }

                          });
                        else {
                          if (mbNamed)
                            if (typeof mbNamed == "string")
                              displayName(nodeDiv, named, mbNamed);
                            else
                              displayName(nodeDiv, named, mbNamed, true);
                        }
                        break;
                      case "version":
                        if (/\/scripts\/show\//.test(pathname))
                          script_summaryNodes.forEach(function (e, i, a) {
                            let xpr = document.evaluate(
                            "./p/b[.='Version:']/following-sibling::text()",
                              e,
                              null,
                              XPathResult.FIRST_ORDERED_NODE_TYPE,
                              null
                            );
                            if (xpr && xpr.singleNodeValue) {
                              let thisNode = xpr.singleNodeValue;

                              if (mbNamed)
                                if (typeof mbNamed == "string") {
                                  if (mbNamed != thisNode.textContent.trim())
                                    displayName(nodeDiv, named, mbNamed, true);
                                }
                                else
                                  displayName(nodeDiv, named, mbNamed, true);
                            }

                          });
                        else {
                          if (mbNamed)
                            if (typeof mbNamed == "string")
                              displayName(nodeDiv, named, mbNamed);
                            else
                              displayName(nodeDiv, named, mbNamed, true);
                        }
                        break;
                      case "include":
                        let
                          notify = true,
                          mbEXCLUDE = mb["exclude"];
                        ;

                        if (mbEXCLUDE) {
                          let excludes = (typeof mbEXCLUDE == "string") ? [mbEXCLUDE] : mbEXCLUDE;
                          for (let exclude in excludes)
                            if (excludes[exclude] == "*") {
                              notify = false;
                              break;
                            }
                        }

                        if (mbNamed)
                          displayName(nodeDiv, named, mbNamed);
                        else
                          displayName(nodeDiv, named, null, notify);

                        break;
                      case "updateURL":
                      case "installURL":
                      case "downloadURL":
                      case "run-at":
                      case "icon":
                        if (mbNamed)
                          if (typeof mbNamed == "string")
                            displayName(nodeDiv, named, mbNamed);
                          else
                            displayName(nodeDiv, named, mbNamed, true);
                        break;
                      default:
                        if (mbNamed)
                          displayName(nodeDiv, named, mbNamed);
                        else {
                          let key, prefix;
                          [key, prefix] = names[name].split(/:/).reverse();

                          if (prefix && mb[prefix] && mb[prefix][key])
                            displayName(nodeDiv, prefix + ":" + key, mb[prefix][key]);
                        }
                        break;
                    }
                  }

                  if (gmcHome.get("insertH6Md")) {
                    let items = gmcHome.get("insertH6StringMd").split(","), xpe;
                    for (let i = 0, len = items.length; i < len; ++i) {
                      if (i == 0)
                        xpe = "//div[@id='script_sidebar']//h6[contains(., '" + items[i]+ "')]";
                      else
                        xpe += "|//div[@id='script_sidebar']//h6[contains(., '" + items[i]+ "')]";
                    }

                    let xpr = document.evaluate(
                      xpe,
                      document.body,
                      null,
                      XPathResult.FIRST_ORDERED_NODE_TYPE,
                      null
                    );
                    if (xpr && xpr.singleNodeValue) {
                      let thisNode = xpr.singleNodeValue;

                      if (thisNode.parentNode.id == "script_sidebar")
                        script_sidebarNode.insertBefore(nodeDiv, thisNode);
                      else
                        script_sidebarNode.insertBefore(nodeDiv, thisNode.parentNode);
                    }
                    else
                      script_sidebarNode.appendChild(nodeDiv);
                  }
                  else
                    script_sidebarNode.appendChild(nodeDiv);

                }

                /**
                 *       Lost and Found
                 */

                if (gmcHome.get("showStrings")) {
                  GM_setStyle({
                    node: gCSS,
                    data:
                      [
                        ".lost span, .found span { color: #666; font-size: 0.7em; }",

                        ".lost { background-image: linear-gradient(to top, #ddd, rgba(255,255,255,0)); border: thin solid #aaa !important; border-radius: 0.25em 0.25em; cursor: default; font-family: sans-serif; font-weight: normal !important; padding: 0.25em 0.75em; text-align: left; width: auto; }",
                        ".lost:hover { background-image: linear-gradient(to top, #bfe1ff, rgba(237,249,255,0)); }",
                        ".lost a { margin-top: -0.0625em; position: absolute; right: 0.5em; }",
                        ".lost img { max-height: 1.5em; }",

                        ".found {}",
                        ".found a { margin-top: -0.0625em; position: absolute; right: 0.5em; }",
                        ".found img { float: right; max-height: 1.5em; }",
                        ".found a:last-child { float: right; opacity: 0; }",
                        ".found a:hover { opacity: 1; }",

                        ".finds { border-width: 0; font-size: x-small; margin: 0; margin-bottom: 1em; overflow: auto; padding: 0 !important; width: 100%; word-break: break-all; }",
                        ".finds li { color: #666; padding-left: 0.5em; text-align: left; }",
                        ".finds span { background-color: #f80; border-radius: 1.3em 0 0 1.3em; color: #fff; float: right; font-family: serif; font-size: 0.9em; font-weight: bold; margin-left: 0.25em; margin-right: 0.5em; padding-left: 0.7em; padding-right: 0.5em; text-align: right; }",
                        ".finds .bar { background-color: #eee; }",

                        ""
                      ].join("\n")
                  });

                  if (gmcHome.get("limitMaxHeightFinds"))
                    GM_setStyle({
                        node: gCSS,
                        data:
                          [
                            ".finds { max-height: " + gmcHome.get("maxHeightListFinds") + "em; }"

                          ].join("\n")
                    });

                  GM_setStyle({
                      node: gCSS,
                      data:
                        [
                          ".md li, .finds li { font-size: " + gmcHome.get("fontSize") + "em ; }"

                        ].join("\n")
                  });

                  let nodeImg = document.createElement("img");
                  nodeImg.src = GM_getResourceURL("icon");
                  nodeImg.title = "uso - Count Issues";
                  nodeImg.alt = "Count Issues";

                  let nodeA = document.createElement("a");
                  nodeA.href = "/scripts/show/69307";

                  let nodeSpan = document.createElement("span");

                  let nodeH6 = document.createElement("h6");
                  nodeH6.textContent = "Lost and Found ";
                  nodeH6.classList.add("lost");
                  nodeH6.addEventListener("click", onClickHunt, false);

                  nodeA.appendChild(nodeImg);

                  nodeH6.appendChild(nodeSpan);
                  nodeH6.appendChild(nodeA);



                  if (gmcHome.get("insertH6Finds")) {
                    let items = gmcHome.get("insertH6StringFinds").split(","), xpe;
                    for (let i = 0, len = items.length; i < len; ++i) {
                      if (i == 0)
                        xpe = "//div[@id='script_sidebar']//h6[contains(., '" + items[i]+ "')]";
                      else
                        xpe += "|//div[@id='script_sidebar']//h6[contains(., '" + items[i]+ "')]";
                    }

                    let xpr = document.evaluate(
                      xpe,
                      document.body,
                      null,
                      XPathResult.FIRST_ORDERED_NODE_TYPE,
                      null
                    );
                    if (xpr && xpr.singleNodeValue) {
                      let thisNode = xpr.singleNodeValue;

                      if (thisNode.parentNode.id == "script_sidebar")
                        script_sidebarNode.insertBefore(nodeH6, thisNode);
                      else
                        script_sidebarNode.insertBefore(nodeH6, thisNode.parentNode);
                    }
                    else
                      script_sidebarNode.appendChild(nodeH6);
                  }
                  else
                    script_sidebarNode.appendChild(nodeH6);


                  if (gmcHome.get("showStringsAuto")) {
                    let e = new CustomEvent("click");
                    nodeH6.dispatchEvent(e);
                  }

                }
              }
            }

            /**
             *        Items specific to source homepage
             */

            if (/\/scripts\/review\//.test(pathname)) {

              let xpr = document.evaluate(
                "//div[@id='section']//div[contains(concat(' ', normalize-space(@class), ' '), ' container ')]",
                document.body,
                null,
                XPathResult.FIRST_ORDERED_NODE_TYPE,
                null
              );
              if (xpr && xpr.singleNodeValue) {
                let hookNode = xpr.singleNodeValue;

                GM_setStyle({
                    node: gCSS,
                    data:
                      [
                        "#fans_content { border-bottom: 1px dotted #ddd !important; margin-bottom: 0 !important; }",
                        ".pagetear { background-color: #fff; border-bottom: 1px dotted #ddd; font-size: 13px; padding: 10px;}",
                        "#sourceurl { margin-bottom: 0.9em; }",
                        "#sourceurl div { border: 1px solid #ccc; border-radius: 3px; margin: 0; }",
                        "#sourceurl #currenturl { background-color: transparent; border-style: none; color: #999; margin: 0 3px; width: 98%; }",
                        "#sourceurl #refreshurl { background-color: transparent; height: 16px; margin-top: 0.4em; position: absolute; right: 1.5em; width: 16px; }",

                        ".reload { background-image: url(" + GM_getResourceURL("reload") + "); }",
                        ".connecting { background-image: url(chrome://browser/skin/tabbrowser/connecting.png); }",
                        ".loading { background-image: url(chrome://browser/skin/tabbrowser/loading.png); }",
                        ".processing { background-image: url(chrome://global/skin/icons/loading_16.png); }",

                        ".err { background-color: #fdd !important; border-color: #dbb !important; }",
                        "#currenturls { display: none; }"

                      ].join("\n")
                });

                let imageNodeInput = document.createElement("input");
                imageNodeInput.type = "image";
                imageNodeInput.id = "refreshurl";
                imageNodeInput.src = "data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
                imageNodeInput.classList.add("reload");
                imageNodeInput.alt = "refresh";
                imageNodeInput.addEventListener("click", function (ev) {
                  if (!ev.target.previousSibling.value && ev.target.previousSibling.placeholder != "Load url")
                    loadUrl(ev.target.previousSibling.placeholder, ev.target);
                }, false);

                let nodeDatalist = document.createElement("datalist");
                nodeDatalist.id = "currenturls";

                [
                  "http://userscripts.org/scripts/source/",
                  "https://userscripts.org/scripts/source/",
                  "http://",
                  "https://"

                ].forEach(function (e, i, a) {
                  let nodeOption = document.createElement("option");
                  nodeOption.value = e;

                  nodeDatalist.appendChild(nodeOption);
                });

                let urlNodeInput = document.createElement("input");
                urlNodeInput.type = "text";
                urlNodeInput.placeholder = "Load url";
                urlNodeInput.id = "currenturl";
                urlNodeInput.setAttribute("list", "currenturls");
                urlNodeInput.addEventListener("keypress", function (ev) {
                  clearUrlErr();

                  if (ev.keyCode == 13)
                    if (ev.target.value)
                      loadUrl(ev.target.value, imageNodeInput);
                }, false);

                let nodeDiv = document.createElement("div");
                nodeDiv.id = "urlbar";

                let containerNodeDiv = document.createElement("div");
                containerNodeDiv.id = "sourceurl";
                containerNodeDiv.className = "pagetear";

                nodeDiv.appendChild(urlNodeInput);
                nodeDiv.appendChild(imageNodeInput);
                nodeDiv.appendChild(nodeDatalist);

                containerNodeDiv.appendChild(nodeDiv);

                hookNode.appendChild(containerNodeDiv);
              }

              GM_setStyle({
                  node: gCSS,
                  data:
                    [
                      "div.toolbar_menu li, div.toolbar_menu li div { display: inline; margin-right: 0.25em; }"

                    ].join("\n")
              });

              document.evaluate(
                "//pre[@id='source']",
                document.body,
                null,
                XPathResult.FIRST_ORDERED_NODE_TYPE,
                xpr
              );
              if (xpr && xpr.singleNodeValue) {
                let hookNode = xpr.singleNodeValue;

                if (!hookNode.hasChildNodes()) // NOTE: Caching issue encountered on USO so reload until it is present
                  location.reload();

                /** Create standardized div framing **/
                let toolbarBottomNode = document.createElement("div");
                toolbarBottomNode.classList.add("toolbar_menu");

                let toolbarTopNode = document.createElement("div");
                toolbarTopNode.classList.add("toolbar_menu");

                let rightNode = document.createElement("div");
                rightNode.classList.add("right");

                let leftNode = document.createElement("div");
                leftNode.id = "left";
                GM_setStyle({
                    node: gCSS,
                    data:
                      [
                          "#left { float: left; }"

                      ].join("\n")
                });

                let topNode = document.createElement("div");

                let subcontentNode = document.createElement("div");

                subcontentNode.appendChild(topNode);
                subcontentNode.appendChild(leftNode);
                subcontentNode.appendChild(rightNode);

                hookNode.parentNode.insertBefore(subcontentNode, hookNode);

                rightNode.appendChild(toolbarTopNode);
                rightNode.appendChild(hookNode);
                rightNode.appendChild(toolbarBottomNode);

                /** Check for UAC buttons and modify them **/

                let wrapNodes = [];
                document.evaluate(
                  "//button[@id='wrap-button1' or @id='wrap-button2']",
                  document.body,
                  null,
                  XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                  xpr
                );
                if (xpr) {
                  if (xpr.snapshotLength > 0)
                    GM_setStyle({
                        node: gCSS,
                        data:
                          [
                            ".wrap-button { width: 11.5em; }"

                          ].join("\n")
                    });

                  for (let i = 0, thisNode; thisNode = xpr.snapshotItem(i++);) {
                    thisNode.removeAttribute("style");
                    thisNode.classList.add("wrap-button");

                    let nodeDiv = document.createElement("div");
                    let nodeLi = document.createElement("li");

                    nodeDiv.appendChild(thisNode);
                    nodeLi.appendChild(nodeDiv);

                    wrapNodes.push(nodeLi);
                  }
                }

                let cttsNodes = [];
                document.evaluate(
                  "//button[.='Change Tabs to Spaces']",
                  document.body,
                  null,
                  XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                  xpr
                );
                if (xpr) {
                  if (xpr.snapshotLength > 0)
                    GM_setStyle({
                        node: gCSS,
                        data:
                          [
                            ".changetabs-button { width: 13.5em; }",
                            ".changetabs-input { height: 1.3em; margin: 0 0 !important; margin-left: 0.3em !important; padding: 0 !important; position: relative; top: 0; width: 1.5em !important; }"

                          ].join("\n")
                    });

                  for (let i = 0, thisNode; thisNode = xpr.snapshotItem(i++);) {
                    thisNode.removeAttribute("style");
                    thisNode.classList.add("changetabs-button");

                    let nextSiblingNode = thisNode.nextSibling;
                    nextSiblingNode.removeAttribute("style");
                    nextSiblingNode.classList.add("changetabs-input");

                    let nodeDiv = document.createElement("div");
                    let nodeLi = document.createElement("li");

                    nodeDiv.appendChild(thisNode);
                    nodeDiv.appendChild(nextSiblingNode);
                    nodeLi.appendChild(nodeDiv);

                    cttsNodes.push(nodeLi);
                  }
                }

                if (wrapNodes[0])
                  toolbarTopNode.appendChild(wrapNodes[0]);
                if (cttsNodes[0])
                  toolbarTopNode.appendChild(cttsNodes[0]);

                /** Create beautify **/
                if (typeof js_beautify != "undefined") {

                  let nodeButton = document.createElement("button");
                  nodeButton.type = "button";
                  nodeButton.textContent = "Beautify";
                  nodeButton.addEventListener("click", function (ev) {
                    hookNode.textContent = js_beautify(hookNode.textContent.replace(/[“”]/g, '"'), { indent_size: 1, indent_char: '\t' });

                    if (gmcHome.get("showLineNumbers")) {
                      renumber(hookNode);
                      let numberNode = document.getElementById("number");
                      if (numberNode)
                        numberNode.classList.add("err");
                    }

                    // If source is < 20KB then autohighlight just like USO does
                    if (hookNode.textContent.length < 20480)
                      (wrappedJSObject || window).sh_highlightDocument();

                    enableCTTS();

                    ev.target.blur();
                  }, false);

                  let nodeDiv = document.createElement("div");

                  let nodeLi = document.createElement("li");

                  nodeDiv.appendChild(nodeButton);
                  nodeLi.appendChild(nodeDiv);

                  toolbarTopNode.appendChild(nodeLi);
                }
                else {
                  let msg = 'js_beautify Object is missing';
                  console.warn(msg);
                }

                /** Create deobfuscate **/
                let nodeButton = document.createElement("button");
                nodeButton.type = "button";
                nodeButton.textContent = "Deobfuscate";
                nodeButton.addEventListener("click", function (ev) {

                  let
                      textContent = hookNode.textContent,
                      diff = false
                  ;
                  if (gmcHome.get("deobJsCode")) {
                    try {
                      textContent = JsCode.deobfuscate(textContent);
                      diff = textContent != hookNode.textContent;
                    }
                    catch (e) {
                      let msg = 'Aborting JsCode\n' + e.name + '\n' + e.message;
                      console.warn(msg);
                    }
                  }

                  let hexCount;
                  if (gmcHome.get("deobST")) {
                    try {
                      [textContent, hexCount] = simpleTranscode(textContent, 0);
                      diff = textContent != hookNode.textContent;
                    }
                    catch(e) {
                      let msg = 'Aborting Simple Transcode\n' + e.name + '\n' + e.message;
                      console.warn(msg);
                    }
                  }

                  if (diff) {
                    hookNode.textContent = textContent;

                    if (gmcHome.get("showLineNumbers")) {
                      renumber(hookNode);
                      let numberNode = document.getElementById("number");
                      if (numberNode)
                        numberNode.classList.add("err");
                    }

                    // If source is < 20KB then autohighlight just like USO does
                    if (hookNode.textContent.length < 20480)
                      (wrappedJSObject || window).sh_highlightDocument();
                  }

                  enableCTTS();
                  ev.target.blur();
                }, false);

                let nodeDiv = document.createElement("div");
                let nodeLi = document.createElement("li");

                nodeDiv.appendChild(nodeButton);
                nodeLi.appendChild(nodeDiv);


                toolbarTopNode.appendChild(nodeLi);

                if (wrapNodes[1])
                  toolbarBottomNode.appendChild(wrapNodes[1]);

                /**  Move syntax highlight if present **/
                let syntax_highlight_select = document.getElementById("syntax-highlight-select");
                if (syntax_highlight_select) {
                  let copy_text_button =  document.getElementById("copy-text-button");
                  if (copy_text_button) {
                    GM_setStyle({
                        node: gCSS,
                        data:
                          [
                            ".copy-text { margin-left: 0 !important; }"

                          ].join("\n")
                    });

                    let nodeDiv = document.createElement("div");
                    let nodeLi = document.createElement("li");

                    nodeDiv.appendChild(copy_text_button);
                    nodeLi.appendChild(nodeDiv);

                    toolbarTopNode.appendChild(nodeLi);
                  }

                  let syntax_highlight_button = document.getElementById("syntax-highlight-button");

                  if (syntax_highlight_button) {
                    GM_setStyle({
                        node: gCSS,
                        data:
                          [
                            ".syntax-highlight { margin-left: 0 !important; }"

                          ].join("\n")
                    });

                    let nodeDiv = document.createElement("div");
                    let nodeLi = document.createElement("li");

                    nodeDiv.appendChild(syntax_highlight_select);
                    nodeDiv.appendChild(syntax_highlight_button);
                    nodeLi.appendChild(nodeDiv);

                    toolbarTopNode.appendChild(nodeLi);
                  }
                }

                /** Virtual link versions **/
                if (gmcHome.get("showVersionsSource")) {

                  if (gmcHome.get("maxContainer") && uac)
                    GM_setStyle({
                        node: gCSS,
                        data:
                          [
                            "#section > .container { width: 98.75% !important; }"

                          ].join("\n")
                    });

                  let contentNode = document.getElementById("content");
                  if (contentNode) {
                    document.evaluate(
                      ".//a[@href='/scripts/versions/" + scriptid + "']",
                      contentNode,
                      null,
                      XPathResult.FIRST_ORDERED_NODE_TYPE,
                      xpr
                    );
                    if (xpr) {
                      let thisNode;

                      if (!xpr.singleNodeValue) {
                        let nodeA = document.createElement("a");
                        nodeA.href = "/scripts/versions/" + scriptid;
                        nodeA.textContent = "0 previous versions";

                        let nodeP = document.createElement("p");
                        nodeP.classList.add("notice");

                        nodeP.appendChild(document.createTextNode("There are "));
                        nodeP.appendChild(nodeA);
                        nodeP.appendChild(document.createTextNode(" of this script."));

                        contentNode.insertBefore(nodeP, contentNode.firstChild);

                        thisNode = nodeA;
                      }
                      else
                        thisNode = xpr.singleNodeValue;

                      if (thisNode)
                        thisNode.addEventListener("click", onClickVersions, false);
                    }
                  }
                  else {
                    let msg = 'Content node not found for inline versions and diffs';
                    console.error(msg);
                    return; // NOTE: Watchpoint
                  }
                }

                /**
                *
                */
              }

              if (gmcHome.get("showLineNumbers")) {
                let xpr = document.evaluate(
                  "//pre[@id='source']",
                  document.body,
                  null,
                  XPathResult.FIRST_ORDERED_NODE_TYPE,
                  null
                );
                if (xpr && xpr.singleNodeValue) {
                  let sourceNode = xpr.singleNodeValue;

                  if (!sourceNode.hasChildNodes()) // NOTE: Caching issue encountered on USO so reload until it is present
                    location.reload();

                  let nodePre = document.createElement("pre");
                  nodePre.id = "number";
                  nodePre.classList.add("number");
                  nodePre.addEventListener("click", function (ev) {
                    let targetNode = ev.target;

                    if (targetNode.id.match(/line\-\d+/)) {
                      let xpr = document.evaluate(
                          "./div[contains(concat(' ', normalize-space(@class), ' '), ' active ')]",
                          nodePre,
                          null,
                          XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                          null
                      );

                      if (xpr) {
                        for (let i = 0, thisNode; thisNode = xpr.snapshotItem(i++);)
                          thisNode.classList.remove("active");

                        targetNode.parentNode.classList.add("active");
                      }
                    }
                  }, false);

                  nodePre.classList.add("HID"); // NOTE: Prevents flicker and render failure

                  // Copy once selector rules from #source element
                  let css = ".number { ";
                      let properties = getComputedStyle(sourceNode, null);
                      for (let property in properties)
                        css += (properties[property] + ":" + properties.getPropertyValue(properties[property]) + "; ");
                  css += " }";

                  GM_setStyle({
                      node: gCSS,
                      data: css
                  });

                  // Apply custom styling
                  GM_setStyle({
                      node: gCSS,
                      data:
                        [
                          ".number { background-color: #eee; border-right-style: none !important; display: inline; float: left; height: auto; margin: 0 !important; margin-top: 0 !important; overflow: hidden !important; padding-left: 2px; padding-right: 2px; text-align: right;  }",
                          ".number a { color: #666; font-size: 0.75em; padding-right: 2px; text-decoration: none; }",
                          ".number a.surge { color: #000; font-size: 1em; }",

                          ".number .entry { background-image: -moz-linear-gradient(center bottom , #999 5%, rgba(120, 120, 120, 0.7), #999 95%); box-shadow:0 0 50px 25px rgba(85, 85, 85, 0.7); }",
                          ".number .entry > a { color: #fff; }",

                          ".number .active { background-image: -moz-linear-gradient(center bottom , #7576a0 5%, rgba(0, 0, 120, 0.7), #7576a0 95%); box-shadow:0 0 50px 25px rgba(0, 0, 85, 0.7); }",
                          ".number .active > a { color: #fff; }",

                          "#content pre#source { margin-top: 0; }",
                          "#content pre#source[wrap='off'] { overflow-x: auto !important; white-space: pre; }",
                          "#content pre#source[wrap='on'] { margin-left: 0 !important; white-space: pre-wrap; word-break: break-all; }",

                          "#number[wrap='off'] { display: inline; }",
                          "#number[wrap='on'] { display: none; }"

                        ].join("\n")
                  });

                  let nodeDiv = document.createElement("div");

                  nodeDiv.appendChild(nodePre);

                  sourceNode.parentNode.insertBefore(nodeDiv, sourceNode);
                  nodeDiv.appendChild(sourceNode);

                  renumber(sourceNode);

                  let matches = location.hash.match(/^#(line-\d+)/);
                  if (matches) {
                    let xpr = document.evaluate(
                      "//a[@id='" + matches[1] + "']",
                      document.body,
                      null,
                      XPathResult.FIRST_ORDERED_NODE_TYPE,
                      null
                    );
                    if (xpr && xpr.singleNodeValue) {
                      let thisNode = xpr.singleNodeValue;

                      thisNode.parentNode.classList.add("entry");
                      thisNode.scrollIntoView();
                    }
                  }

                }
              }


            } /** /if on source code page test **/


            /**
             *
             */
            break; /** /case "200": **/

        } /** /switch (xhr.status) **/


      }
    });
  }

})();