<commit_before>define(["moment", "numeral", "tablesort", "tablesort.numeric"],
  function (moment, numeral, Tablesort) {
  function showGeoURI(d) {
    function showLatitude(d) {
      var suffix = Math.sign(d) > -1 ? "' N" : "' S"
      d = Math.abs(d)
      var a = Math.floor(d)
      var min = (d * 60) % 60
      a = (a < 10 ? "0" : "") + a

      return a + "° " + numeral(min).format("0.000") + suffix
    }

    function showLongitude(d) {
      var suffix = Math.sign(d) > -1 ? "' E" : "' W"
      d = Math.abs(d)
      var a = Math.floor(d)
      var min = (d * 60) % 60
      a = (a < 100 ? "0" + (a < 10 ? "0" : "") : "") + a

      return a + "° " + numeral(min).format("0.000") + suffix
    }

    if (!has_location(d))
      return undefined

    return function (el) {
      var latitude = d.nodeinfo.location.latitude
      var longitude = d.nodeinfo.location.longitude
      var a = document.createElement("a")
      a.textContent = showLatitude(latitude) + " " +
                      showLongitude(longitude)

      a.href = "geo:" + latitude + "," + longitude
      el.appendChild(a)
    }
  }

  function showStatus(d) {
    return function (el) {
      el.classList.add(d.flags.unseen ? "unseen" : (d.flags.online ? "online" : "offline"))
      if (d.flags.online)
        el.textContent = "online, letzte Nachricht " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY,  H:mm:ss") + ")"
      else
        el.textContent = "offline, letzte Nachricht " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY,  H:mm:ss") + ")"
    }
  }

  function showFirmware(d) {
    var release = dictGet(d.nodeinfo, ["software", "firmware", "release"])
    var base = dictGet(d.nodeinfo, ["software", "firmware", "base"])

    if (release === null || base === null)
      return undefined

    return release + " / " + base
  }

  function showSite(d, config) {
    var site = dictGet(d.nodeinfo, ["system", "site_code"])
    var rt = site
    if (config.siteNames)
      config.siteNames.forEach( function (t) {
        if(site === t.site)
          rt = t.name
      })
    return rt
  }

  function showUptime(d) {
    if (!("uptime" in d.statistics))
      return undefined

    return moment.duration(d.statistics.uptime, "seconds").humanize()
  }

  function showFirstseen(d) {
    if (!("firstseen" in d))
      return undefined

    return d.firstseen.fromNow(true)
  }

  function showClients(d) {
    if (!d.flags.online)
      return undefined

    var meshclients = getMeshClients(d)
    resetMeshClients(d)
    var before = "     ("
    var after = " in der lokalen Wolke)"
    return function (el) {
      el.appendChild(document.createTextNode(d.statistics.clients.total > 0 ? d.statistics.clients.total : "keine"))
      el.appendChild(document.createTextNode(before))
      el.appendChild(document.createTextNode(meshclients > 0 ? meshclients : "keine"))
      el.appendChild(document.createTextNode(after))
      el.appendChild(document.createElement("br"))

      var clientTypes = getClients(d.statistics)
      for (var clientsNum in clientTypes) {
        var clients = clientTypes[clientsNum]
        var span = document.createElement("span")
        span.classList.add("clients")
        span.textContent = " ".repeat(clients.count)
        span.style.color = clients.color
        el.appendChild(span)
      }

      var spanmesh = document.createElement("span")
      spanmesh.classList.add("clientsMesh")
      spanmesh.textContent = " ".repeat(meshclients - d.statistics.clients.total)
      el.appendChild(spanmesh)
    }
  }

  function getMeshClients(node) {
    var meshclients = 0
    if (node.statistics && node.statistics.clients && !isNaN(node.statistics.clients.total))
      meshclients = node.statistics.clients.total

    if (!node)
      return 0

    if (node.parsed)
      return 0

    node.parsed = 1
    node.neighbours.forEach(function (neighbour) {
      if (!neighbour.link.isVPN && neighbour.node)
        meshclients += getMeshClients(neighbour.node)
    })

    return meshclients
  }

  function resetMeshClients(node) {
    if (!node.parsed)
      return

    node.parsed = 0

    node.neighbours.forEach(function (neighbour) {<commit_msg>fix crash with empty statistics (2)<commit_after>define(["moment", "numeral", "tablesort", "tablesort.numeric"],
  function (moment, numeral, Tablesort) {
  function showGeoURI(d) {
    function showLatitude(d) {
      var suffix = Math.sign(d) > -1 ? "' N" : "' S"
      d = Math.abs(d)
      var a = Math.floor(d)
      var min = (d * 60) % 60
      a = (a < 10 ? "0" : "") + a

      return a + "° " + numeral(min).format("0.000") + suffix
    }

    function showLongitude(d) {
      var suffix = Math.sign(d) > -1 ? "' E" : "' W"
      d = Math.abs(d)
      var a = Math.floor(d)
      var min = (d * 60) % 60
      a = (a < 100 ? "0" + (a < 10 ? "0" : "") : "") + a

      return a + "° " + numeral(min).format("0.000") + suffix
    }

    if (!has_location(d))
      return undefined

    return function (el) {
      var latitude = d.nodeinfo.location.latitude
      var longitude = d.nodeinfo.location.longitude
      var a = document.createElement("a")
      a.textContent = showLatitude(latitude) + " " +
                      showLongitude(longitude)

      a.href = "geo:" + latitude + "," + longitude
      el.appendChild(a)
    }
  }

  function showStatus(d) {
    return function (el) {
      el.classList.add(d.flags.unseen ? "unseen" : (d.flags.online ? "online" : "offline"))
      if (d.flags.online)
        el.textContent = "online, letzte Nachricht " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY,  H:mm:ss") + ")"
      else
        el.textContent = "offline, letzte Nachricht " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY,  H:mm:ss") + ")"
    }
  }

  function showFirmware(d) {
    var release = dictGet(d.nodeinfo, ["software", "firmware", "release"])
    var base = dictGet(d.nodeinfo, ["software", "firmware", "base"])

    if (release === null || base === null)
      return undefined

    return release + " / " + base
  }

  function showSite(d, config) {
    var site = dictGet(d.nodeinfo, ["system", "site_code"])
    var rt = site
    if (config.siteNames)
      config.siteNames.forEach( function (t) {
        if(site === t.site)
          rt = t.name
      })
    return rt
  }

  function showUptime(d) {
    if (!("uptime" in d.statistics))
      return undefined

    return moment.duration(d.statistics.uptime, "seconds").humanize()
  }

  function showFirstseen(d) {
    if (!("firstseen" in d))
      return undefined

    return d.firstseen.fromNow(true)
  }

  function showClients(d) {
    if (!d.flags.online)
      return undefined

    var meshclients = getMeshClients(d)
    resetMeshClients(d)
    var before = "     ("
    var after = " in der lokalen Wolke)"
    return function (el) {
      const totalClients = d.statistics && d.statistics.clients && !Number.isNaN(d.statistics.clients.total) ? d.statistics.clients.total : 0
      el.appendChild(document.createTextNode(totalClients > 0 ? totalClients : "keine"))
      el.appendChild(document.createTextNode(before))
      el.appendChild(document.createTextNode(meshclients > 0 ? meshclients : "keine"))
      el.appendChild(document.createTextNode(after))
      el.appendChild(document.createElement("br"))

      var clientTypes = getClients(d.statistics)
      for (var clientsNum in clientTypes) {
        var clients = clientTypes[clientsNum]
        var span = document.createElement("span")
        span.classList.add("clients")
        span.textContent = " ".repeat(clients.count)
        span.style.color = clients.color
        el.appendChild(span)
      }

      var spanmesh = document.createElement("span")
      spanmesh.classList.add("clientsMesh")
      spanmesh.textContent = " ".repeat(meshclients - totalClients)
      el.appendChild(spanmesh)
    }
  }

  function getMeshClients(node) {
    var meshclients = 0
    if (node.statistics && node.statistics.clients && !isNaN(node.statistics.clients.total))
      meshclients = node.statistics.clients.total

    if (!node)
      return 0

    if (node.parsed)
      return 0

    node.parsed = 1
    node.neighbours.forEach(function (neighbour) {
      if (!neighbour.link.isVPN && neighbour.node)
        meshclients += getMeshClients(neighbour.node)
    })

    return meshclients
  }

  function resetMeshClients(node) {
    if (!node.parsed)
      return

    node.parsed = 0

    node.neighbours.forEach(function (neighbour) {
{'fraction_non_alphanumeric': 0.14647525676937442, 'fraction_numerical': 0.008403361344537815, 'mean_word_length': 2.611040876527602, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7087546', 'n_tokens_mistral': 2987, 'n_tokens_neox': 2848, 'n_words': 588}