<commit_before>function getOffset( el ) {
  var _x = 0, _y = 0

  while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
    _x += el.offsetLeft - el.scrollLeft
    _y += el.offsetTop - el.scrollTop
    el = el.offsetParent
  }
  return { top: _y, left: _x }
}

var offset = getOffset(document.getElementById('chart'))

var w = window.innerWidth - offset.left,
    h = window.innerHeight - offset.top

var cp = d3.select("#chart").append("div")
           .attr("id", "controlpanel")

var updated_at = cp.append("p")

cp.append("button")
    .attr("class", "btn")
    .attr("value", "reload")
    .text("Aktualisieren")
    .on("click", reload)

var btns = cp.append("div")
           .attr("class", "btn-group")

btns.append("button")
    .attr("class", "btn active left")
    .attr("value", "clients")
    .text("Clients")
    .on("click", update_graph)

btns.append("button")
    .attr("class", "btn active right")
    .attr("value", "vpn")
    .text("VPN")
    .on("click", update_graph)

cp.append("label")
  .text("Knoten hervorheben:")

cp.append("br")

cp.append("input")
  .on("keyup", function(){show_node(this.value)})
  .on("change", function(){show_node(this.value)})

function show_node(mac) {
  d3.selectAll("#chart .node")
    .classed("marked", false)

  if (mac.length == 0)
    return

  d3.selectAll("#chart .node")
    .each( function(d) {
      if (d.id == mac) 
        d3.select(this)
          .classed("marked", true)
    })
}

var hashstr = window.location.hash.substring(1)

function isConnected(a, b) {
  return linkedByIndex[a.index + "," + b.index] ||
         linkedByIndex[b.index + "," + a.index] ||
         a.index == b.index
}

function fade(opacity) {
  return function(d) {
    vis.selectAll("g.node")
       .style("stroke-opacity", function(o) {
         var connected = isConnected(d, o)

         if (connected && opacity != 1)
           d3.select(this)
             .classed("highlight", true)
         else
           d3.select(this)
             .classed("highlight", false)

         thisOpacity = connected?1:opacity
         this.setAttribute('fill-opacity', thisOpacity)
         return thisOpacity
       })

    vis.selectAll(".link *")
       .style("stroke-opacity", function(o) {
         return o.source === d || o.target === d ? 1 : opacity
       })
  }
} 

function show_node_info(d) {
  d3.selectAll("#nodeinfo").remove()

  nodeinfo = d3.select("#chart")
               .append("div")
               .attr("id", "nodeinfo")
  nodeinfo.append("button")
          .attr("class", "close")
          .text("x")
          .on("click", function(d) {
             nodeinfo.remove()
          })

  nodeinfo.append("h1")
          .text(d.name + " / " + d.id)

  nodeinfo.append("p")
          .append("label")
          .text("macs: " + d.macs)

  if (d.geo) {
    nodeinfo.append("h2").text("Geodaten")

    nodeinfo.append("p")
            .text(d.geo)

    url = GMaps.staticMapURL({
      size: [300, 100],
      lat: d.geo[0],
      lng: d.geo[1],
      markers: [
        {lat: d.geo[0], lng: d.geo[1]}
      ]
    })

    nodeinfo.append("img")
            .attr("src", url)
  }
}

function update_graph() {
  jQuery(this).toggleClass("active")
  var value = jQuery(this).val()
  visible[value] = jQuery(this).hasClass("active")
  update()
}

var vis = d3.select("#chart").append("svg")
            .attr("width", w)
            .attr("height", h)

vis.append("g").attr("class", "links")

vis.append("g").attr("class", "nodes")

var linkedByIndex

var force = d3.layout.force()
              .charge(-100)
              .gravity(0.02)
              .friction(0.75)
              .theta(0.1)
              .size([w, h])
              .linkDistance(function (d) {
                switch (d.type) {
                  case "vpn": return 150
                  case "client": return 20
                  default: return 70
                }
              })
              .linkStrength(function (d) {
                switch (d.type) {
                  case "vpn": return 0.15
                  case "client": return 1
                  default: return 0.5
                }
              })

force.on("tick", function() {
  var size = force.size()
  var nodes = force.nodes()
  var n = nodes.length
  for (i = 0; i < n; i++) {
    var o = nodes[i]
    if (!o.fixed) {
      node = d3.select(document.getElementById(o.id))[0][0]
      box = bounding_box(node)
      if (o.x < box.rx) o.x = box.rx
      if (o.x > size[0] - box.rx) o.x = size[0] - box.rx
      if (o.y < box.ry) o.y = box.ry
      if (o.y > size[1] - box.ry) o.y = size[1] - box.ry
    }
  }

  var link = vis.selectAll(".link")

  link.selectAll("line")
      .attr("x1", function(d) { return d.source.x })
      .attr("y1", function(d) { return d.source.y })
      .attr("x2", function(d) { return d.target.x })
      .attr("y2", function(d) { return d.target.y })

  link.selectAll(".label")
      .attr("transform", function(d) { 
        π = Math.PI
        Δx = d.source.x - d.target.x
        Δy = d.source.y - d.target.y
        m = Δy/Δx
        α = Math.atan(m)
        α += Δx<0?π:0
        sin = Math.sin(α)
        cos = Math.cos(α)
        x = (Math.min(d.source.x, d.target.x) + Math.abs(Δx) / 2)
        y = (Math.min(d.source.y, d.target.y) + Math.abs(Δy) / 2)
        return "matrix(" + [cos, sin, -sin, cos, x, y].join(",") + ")"
      })

  vis.selectAll(".node").attr("transform", function(d) { 
    return "translate(" + d.x + "," + d.y + ")";
  })
})

var data

var visible = {clients: true, vpn: true}

function reload() {
  d3.json("nodes.json", function(json) {
    // update existing nodes with new info
    // XXX inefficient data structure
    json.nodes.forEach(function(d, i) {
      var n
      force.nodes().forEach(function(x) {if (x.id == d.id) n = x})
      if (n) {
        for (var key in d)
          if (d.hasOwnProperty(key))
            n[key] = d[key]

        json.nodes[i] = n
      }
    })

    json.links.forEach(function(d, i) {
      var n
      force.links().forEach(function(x) {if (x.id == d.id) n = x})
      if (n) {
        for (var key in d)
          if (d.hasOwnProperty(key))
            n[key] = d[key]

        json.links[i] = n
      }
    })

    // replace indices with real objects
    json.links.forEach( function(d) {
      if (typeof d.source == "number") d.source = json.nodes[d.source];
      if (typeof d.target == "number") d.target = json.nodes[d.target];
    })

    // count uplinks
    json.nodes.forEach(function(d) {
      d.uplinks = undefined
    })

    json.links.forEach(function(d) {
      var node, other

      if (d.source.flags.vpn) {
        node = d.target;
        other = d.source;
      }

      if (d.target.flags.vpn) {
        node = d.source;
        other = d.target;
      }

      if (node) {
        if (node.uplinks === undefined)
          node.uplinks = new Array();

        node.uplinks.push(other);
      }
    })

    data = json

    updated_at.text(d3.time.format("%X")(new Date()))

    update()
  })
}

function update() {
  var links = data.links
                   .filter(function (d) {
                     if (!visible.clients && (d.source.flags.client || d.target.flags.client))
                       return false 

                     if (!visible.vpn && (d.source.flags.vpn || d.target.flags.vpn))
                       return false 

                     return true
                   })

  var link = vis.select("g.links")
                .selectAll("g.link")
                .data(links, function(d) {
                    return d.id
                })

  var linkEnter = link.enter().append("g")
                      .attr("class", "link")

  linkEnter.append("line")

  link.selectAll("line")
      .style("stroke-width", function(d) {
        return Math.max(1, d.strength * 2)
      })

  link.selectAll("path.label")
      .remove()

  link.filter(function (d) {
        return d.quality != "TT" && d.quality != "1.000"
      })
      .append("path")
      .attr("class", "label")
      .attr("d", d3.svg.zigzag()
                       .amplitude(function (d) {
                         return Math.pow((1 - 1/d.quality), 0.5) * 8;
                       })
                       .len(30)
                       .angularFrequency(4)<commit_msg>remove dead code<commit_after>function getOffset( el ) {
  var _x = 0, _y = 0

  while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
    _x += el.offsetLeft - el.scrollLeft
    _y += el.offsetTop - el.scrollTop
    el = el.offsetParent
  }
  return { top: _y, left: _x }
}

var offset = getOffset(document.getElementById('chart'))

var w = window.innerWidth - offset.left,
    h = window.innerHeight - offset.top

var cp = d3.select("#chart").append("div")
           .attr("id", "controlpanel")

var updated_at = cp.append("p")

cp.append("button")
    .attr("class", "btn")
    .attr("value", "reload")
    .text("Aktualisieren")
    .on("click", reload)

var btns = cp.append("div")
           .attr("class", "btn-group")

btns.append("button")
    .attr("class", "btn active left")
    .attr("value", "clients")
    .text("Clients")
    .on("click", update_graph)

btns.append("button")
    .attr("class", "btn active right")
    .attr("value", "vpn")
    .text("VPN")
    .on("click", update_graph)

cp.append("label")
  .text("Knoten hervorheben:")

cp.append("br")

cp.append("input")
  .on("keyup", function(){show_node(this.value)})
  .on("change", function(){show_node(this.value)})

function show_node(mac) {
  d3.selectAll("#chart .node")
    .classed("marked", false)

  if (mac.length == 0)
    return

  d3.selectAll("#chart .node")
    .each( function(d) {
      if (d.id == mac) 
        d3.select(this)
          .classed("marked", true)
    })
}

var hashstr = window.location.hash.substring(1)

function isConnected(a, b) {
  return linkedByIndex[a.index + "," + b.index] ||
         linkedByIndex[b.index + "," + a.index] ||
         a.index == b.index
}

function fade(opacity) {
  return function(d) {
    vis.selectAll("g.node")
       .style("stroke-opacity", function(o) {
         var connected = isConnected(d, o)

         if (connected && opacity != 1)
           d3.select(this)
             .classed("highlight", true)
         else
           d3.select(this)
             .classed("highlight", false)

         thisOpacity = connected?1:opacity
         this.setAttribute('fill-opacity', thisOpacity)
         return thisOpacity
       })

    vis.selectAll(".link *")
       .style("stroke-opacity", function(o) {
         return o.source === d || o.target === d ? 1 : opacity
       })
  }
} 

function show_node_info(d) {
  d3.selectAll("#nodeinfo").remove()

  nodeinfo = d3.select("#chart")
               .append("div")
               .attr("id", "nodeinfo")
  nodeinfo.append("button")
          .attr("class", "close")
          .text("x")
          .on("click", function(d) {
             nodeinfo.remove()
          })

  nodeinfo.append("h1")
          .text(d.name + " / " + d.id)

  nodeinfo.append("p")
          .append("label")
          .text("macs: " + d.macs)

  if (d.geo) {
    nodeinfo.append("h2").text("Geodaten")

    nodeinfo.append("p")
            .text(d.geo)

    url = GMaps.staticMapURL({
      size: [300, 100],
      lat: d.geo[0],
      lng: d.geo[1],
      markers: [
        {lat: d.geo[0], lng: d.geo[1]}
      ]
    })

    nodeinfo.append("img")
            .attr("src", url)
  }
}

function update_graph() {
  jQuery(this).toggleClass("active")
  var value = jQuery(this).val()
  visible[value] = jQuery(this).hasClass("active")
  update()
}

var vis = d3.select("#chart").append("svg")
            .attr("width", w)
            .attr("height", h)

vis.append("g").attr("class", "links")

vis.append("g").attr("class", "nodes")

var linkedByIndex

var force = d3.layout.force()
              .charge(-100)
              .gravity(0.02)
              .friction(0.75)
              .theta(0.1)
              .size([w, h])
              .linkDistance(function (d) {
                switch (d.type) {
                  case "vpn": return 150
                  case "client": return 20
                  default: return 70
                }
              })
              .linkStrength(function (d) {
                switch (d.type) {
                  case "vpn": return 0.15
                  case "client": return 1
                  default: return 0.5
                }
              })

force.on("tick", function() {
  var size = force.size()
  var nodes = force.nodes()
  var n = nodes.length
  for (i = 0; i < n; i++) {
    var o = nodes[i]
    if (!o.fixed) {
      node = d3.select(document.getElementById(o.id))[0][0]
      box = bounding_box(node)
      if (o.x < box.rx) o.x = box.rx
      if (o.x > size[0] - box.rx) o.x = size[0] - box.rx
      if (o.y < box.ry) o.y = box.ry
      if (o.y > size[1] - box.ry) o.y = size[1] - box.ry
    }
  }

  var link = vis.selectAll(".link")

  link.selectAll("line")
      .attr("x1", function(d) { return d.source.x })
      .attr("y1", function(d) { return d.source.y })
      .attr("x2", function(d) { return d.target.x })
      .attr("y2", function(d) { return d.target.y })

  link.selectAll(".label")
      .attr("transform", function(d) { 
        π = Math.PI
        Δx = d.source.x - d.target.x
        Δy = d.source.y - d.target.y
        m = Δy/Δx
        α = Math.atan(m)
        α += Δx<0?π:0
        sin = Math.sin(α)
        cos = Math.cos(α)
        x = (Math.min(d.source.x, d.target.x) + Math.abs(Δx) / 2)
        y = (Math.min(d.source.y, d.target.y) + Math.abs(Δy) / 2)
        return "matrix(" + [cos, sin, -sin, cos, x, y].join(",") + ")"
      })

  vis.selectAll(".node").attr("transform", function(d) { 
    return "translate(" + d.x + "," + d.y + ")";
  })
})

var data

var visible = {clients: true, vpn: true}

function reload() {
  d3.json("nodes.json", function(json) {
    // update existing nodes with new info
    // XXX inefficient data structure
    json.nodes.forEach(function(d, i) {
      var n
      force.nodes().forEach(function(x) {if (x.id == d.id) n = x})
      if (n) {
        for (var key in d)
          if (d.hasOwnProperty(key))
            n[key] = d[key]

        json.nodes[i] = n
      }
    })

    json.links.forEach(function(d, i) {
      var n
      force.links().forEach(function(x) {if (x.id == d.id) n = x})
      if (n) {
        for (var key in d)
          if (d.hasOwnProperty(key))
            n[key] = d[key]

        json.links[i] = n
      }
    })

    // replace indices with real objects
    json.links.forEach( function(d) {
      if (typeof d.source == "number") d.source = json.nodes[d.source];
      if (typeof d.target == "number") d.target = json.nodes[d.target];
    })

    // count uplinks
    json.nodes.forEach(function(d) {
      d.uplinks = undefined
    })

    json.links.forEach(function(d) {
      var node, other

      if (d.source.flags.vpn) {
        node = d.target;
        other = d.source;
      }

      if (d.target.flags.vpn) {
        node = d.source;
        other = d.target;
      }

      if (node) {
        if (node.uplinks === undefined)
          node.uplinks = new Array();

        node.uplinks.push(other);
      }
    })

    data = json

    updated_at.text(d3.time.format("%X")(new Date()))

    update()
  })
}

function update() {
  var links = data.links
                   .filter(function (d) {
                     if (!visible.clients && (d.source.flags.client || d.target.flags.client))
                       return false 

                     if (!visible.vpn && (d.source.flags.vpn || d.target.flags.vpn))
                       return false 

                     return true
                   })

  var link = vis.select("g.links")
                .selectAll("g.link")
                .data(links, function(d) {
                    return d.id
                })

  var linkEnter = link.enter().append("g")
                      .attr("class", "link")

  linkEnter.append("line")

  link.selectAll("path.label")
      .remove()

  link.filter(function (d) {
        return d.quality != "TT" && d.quality != "1.000"
      })
      .append("path")
      .attr("class", "label")
      .attr("d", d3.svg.zigzag()
                       .amplitude(function (d) {
                         return Math.pow((1 - 1/d.quality), 0.5) * 8;
                       })
                       .len(30)
                       .angularFrequency(4)
{'fraction_non_alphanumeric': 0.17492428831011508, 'fraction_numerical': 0.01029678982434888, 'mean_word_length': 1.7763578274760383, 'pattern_counts': {'":': 8, '<': 11, '<?xml version=': 0, '>': 7, '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': '6148045', 'n_tokens_mistral': 5875, 'n_tokens_neox': 5614, 'n_words': 1124}