<commit_before>"use strict";

var Config = {
  supportsHistory : !!(window.history && history.pushState),
  inMaintenanceMode : false,

  treeName: 'mozilla-central',
  hgBaseURL: "https://hg.mozilla.org/",
  hgURL: "https://hg.mozilla.org/mozilla-central/",
  hgRevURL: "https://hg.mozilla.org/mozilla-central/rev/",
  hgPushlogURL: "https://hg.mozilla.org/mozilla-central/pushloghtml?changeset=",
  hgMCURL: "https://hg.mozilla.org/mozilla-central/",
  hgMCRevURL: "https://hg.mozilla.org/mozilla-central/rev/",
  hgMCPushlogURL: "https://hg.mozilla.org/mozilla-central/pushloghtml?changeset=",
  showBugURL: "https://bugzilla.mozilla.org/show_bug.cgi?id=",
  versionURL: "php/getVersion.php",

  // Here be dragons
  versionRE: /^mozilla\d+$/i,
  csetInputRE: /^(tip|[\da-f]{12,40})$/i,
  csetIDRE: /\b([\da-f]{12,40})\b/ig,
  leaveOpenRE: /leave(?:-|\s+)open/i,
  bugNumRE: /\b(\d{4,7})\b/g,
  strictBugNumRE: /^(\d{4,7})$/,
  mergeRE: /\bmerg(ed?|ing)\b/i,
  backoutRE: /back(ing|ed)?\s*out/i,
  revertRE: /revert(ing)?/i,
  partialRevertRE: /(?:from|in)(?:\s+(?:rev(?:ision)?|c(?:hange)?set))?\s+([\da-f]{12,40})/i,
  partialTestRE: /test\s+for/i,
  revertRangeRE: /revert(?:ing)?\s+(?:\S+\s+)?to(?:\s+(?:rev(?:ision)?|c(?:hange)set))?\s+([\da-f]{12,40})/i,
  csetRangeRE: /\b([\da-f]{12,40})\s*(?:to|:|-|through)\s*([\da-f]{12,40})/i,
  hgRevRE: /https?:\/\/hg.mozilla.org\/mozilla-central\/rev\//ig,
  hgRevFullRE: /https?:\/\/hg.mozilla.org\/mozilla-central\/rev\/[\da-f]{12}/ig,
  hgPushlogRE: /https?:\/\/hg.mozilla.org\/mozilla-central\/pushloghtml\?changeset=/ig,
  hgMCRevRE: /https?:\/\/hg.mozilla.org\/mozilla-central\/rev\//ig,
  hgMCRevFullRE: /https?:\/\/hg.mozilla.org\/mozilla-central\/rev\/[\da-f]{12}/ig,
  hgMCPushlogRE: /https?:\/\/hg.mozilla.org\/mozilla-central\/pushloghtml\?changeset=/ig,
  emailRE: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,   // I'm not looking for RFC 822 compliance here!

  // The many ways bug numbers are specified
  bugRE1: /b(?:ug)?=(\d{4,7})\b/i,                       // e.g. b=XXXXXX
  bugRE2: /^fix(?:es)?\s*(?:for\s*)?(\d{4,7})\b/i,                         // Fix is sometimes used as a synonym for bug
  bugRE3: /to\s+fix\s+bug\s+(\d{4,7})/i,
  bugRE4: /\((\d{4,7}), r=/i,                          // e.g. JS-team style (XXXXXX, r=foo)
  bugRE5: /but\s*(\d{4,7})/i,                          // The typo but XXXXXX happens quite often
  bugRE6: /\bb(?:u?g(?:zilla)?)?:?\s*#?(\d{4,7})\b/i,  // The catchall
  bugRE7: /^(\d{4,7})\b/i,                              // e.g. XXXXXX,

  repoMergeRE: "\\s+(&|and|with|<->|<>|-?->|(in|on)?to)\\s+",

  mcSynonyms: ["mozilla-central", "central", "m-c", "mc", "mozilla central"],

  rewriteTrees: {
    "thunderbird-trunk": "comm-central",
    "thunderbird-aurora": "comm-aurora",
    "thunderbird-beta": "comm-beta",
    "thunderbird-release": "comm-release",
    "thunderbird-esr10": "comm-esr10",
  },

  treeInfo: {
    "mozilla-inbound": {
      repo: "integration/mozilla-inbound",
      trackedTree: false,
      synonyms: ["mozilla-inbound", "inbound", "m-i", "mi"]
    },
    "mozilla-aurora": {
      repo: "releases/mozilla-aurora",
      trackedTree: true,
      synonyms: ["releases/mozilla-aurora", "mozilla-aurora"]
    },
    "mozilla-beta": {
      repo: "releases/mozilla-beta",
      trackedTree: true,
      synonyms: ["releases/mozilla-beta", "mozilla-beta"]
    },
    "mozilla-release": {
      repo: "releases/mozilla-release",
      trackedTree: true,
      synonyms: ["releases/mozilla-release", "mozilla-release"]
    },
    "mozilla-esr10": {
      repo: "releases/mozilla-esr10",
      trackedTree: true,
      synonyms: ["esr10", "releases/mozilla-esr10", "mozilla-esr10"]
    },
    "mozilla-esr17": {
      repo: "releases/mozilla-esr17",
      trackedTree: true,
      synonyms: ["esr17", "releases/mozilla-esr17", "mozilla-esr17"]
    },
    "jetpack": {
      repo: "projects/addon-sdk",
      trackedTree: false,
      synonyms: ["projects/addon-sdk", "addon-sdk"]
    },
    "build-system": {
      repo: "projects/build-system",
      trackedTree: false,
      synonyms: ["build-system", "b-s", "bs"]
    },
    "fx-team": {
      repo: "integration/fx-team",
      trackedTree: false,
      synonyms: ["fx-team"],
      additions: "[fixed-in-fx-team]"
    },
    "graphics": {
      repo: "projects/graphics",
      trackedTree: false,
      synonyms: ["projects/graphics", "graphics"]
    },
    "ionmonkey": {
      repo: "projects/ionmonkey",
      trackedTree: false,
      synonyms: ["projects/ionmonkey", "ionmonkey", "im"]
    },
    "jaegermonkey": {
      repo: "projects/jaegermonkey",
      trackedTree: false,
      synonyms: ["projects/jaegermonkey", "jm"]
    },
    "profiling": {
      repo: "projects/profiling",
      trackedTree: false,
      synonyms: ["profiling", "projects/profiling"]
    },
    "services-central": {
      repo: "services/services-central",
      trackedTree: false,
      synonyms: ["services-central", "s-c", "sc", "services/services-central"],
      additions: "[fixed in services]"
    },
    "ux": {
      repo: "projects/ux",
      synonyms: ["ux", "projects/ux"]
    },
    "alder": {
      repo: "projects/alder",
      trackedTree: false,
      synonyms: ["alder", "projects/alder"]
    },
    "ash": {
      repo: "projects/ash",
      trackedTree: false,
      synonyms: ["ash", "projects/ash"]
    },
    "birch": {
      repo: "projects/birch",
      trackedTree: false,
      synonyms: ["projects/birch", "birch"]
    },
    "cedar": {
      repo: "projects/cedar",
      trackedTree: false,
      synonyms: ["projects/cedar", "cedar"]
    },
    "elm": {
      repo: "projects/elm",
      trackedTree: false,
      synonyms: ["projects/elm", "elm"]
    },
    "holly": {
      repo: "projects/holly",
      trackedTree: false,
      synonyms: ["projects/holly", "holly"]
    },
    "larch": {
      repo: "projects/larch",
      trackedTree: false,
      synonyms: ["projects/larch", "larch"]
    },
    "maple": {
      repo: "projects/maple",
      trackedTree: false,
      synonyms: ["projects/maple", "maple"]
    },
    "oak": {
      repo: "projects/oak",
      trackedTree: false,
      synonyms: ["projects/oak", "oak"]
    },
    "pine": {
      repo: "projects/pine",
      trackedTree: false,
      synonyms: ["projects/pine", "pine"]
    },
    "accessibility": {
      repo: "projects/accessibility",
      trackedTree: false,
      synonyms: ["projects/accessibility", "accessibility"]
    },
    "devtools": {
      repo: "projects/devtools",
      trackedTree: false,
      synonyms: ["projects/devtools", "devtools"]
    },
    "electrolysis": {
      repo: "projects/electrolysis",
      trackedTree: false,
      synonyms: ["projects/electrolysis", "electrolysis", "e10s"]
    },
    "places": {
      repo: "projects/places",
      trackedTree: false,
      synonyms: ["projects/places", "places"]
    },
    "comm-central": {
      repo: "comm-central",
      trackedTree: false,
      synonyms: ["comm-central", "c-c"]
    },
    "comm-aurora": {
      repo: "releases/comm-aurora",
      trackedTree: true,
      synonyms: ["releases/comm-aurora", "comm-aurora"]
    },
    "comm-beta": {
      repo: "releases/comm-beta",
      trackedTree: true,
      synonyms: ["releases/comm-beta", "comm-beta"]
    },
    "comm-release": {
      repo: "releases/comm-release",
      trackedTree: true,
      synonyms: ["releases/comm-release", "comm-release"]
    },
    "comm-esr10": {
      repo: "releases/comm-esr10",
      trackedTree: true,
      synonyms: ["releases/comm-esr10", "comm-esr10"]
    },
    "comm-esr17": {
      repo: "releases/comm-esr17",
      trackedTree: true,
      synonyms: ["releases/comm-esr17", "comm-esr17"]
    }
  }
};

Config.bugNumberREs = [Config.bugRE1, Config.bugRE2, Config.bugRE3,
                       Config.bugRE4, Config.bugRE5, Config.bugRE6, Config.bugRE7];

(function () {
  var base = Config.hgBaseURL;
  for (var treeName in Config.treeInfo) {
    var repo = Config.treeInfo[treeName].repo;
    Config.treeInfo[treeName]['hgURL'] = base + repo + '/';
    Config.treeInfo[treeName]['hgRevURL'] = base + repo + '/rev/';
    Config.treeInfo[treeName]['hgPushlogURL'] = base + repo + '/pushloghtml?changeset=';
    Config.treeInfo[treeName]['hgRevRE'] = new RegExp('https?:\/\/hg.mozilla.org\/' + repo + '\/rev\/');
    Config.treeInfo[treeName]['hgRevFullRE'] = new RegExp('https?:\/\/hg.mozilla.org\/' + repo + '\/rev\/[\\da-f]{12}', 'ig');
    Config.treeInfo[treeName]['hgPushlogRE'] = new RegExp('https?:\/\/hg.mozilla.org\/' + repo + '\/pushloghtml\\?changeset=', 'ig');
  }
})();

// Detect input type="email" support
$(document).ready(function() {
  Config.needsValidation = $('#username').prop('type') != 'email';
});
<commit_msg>Consider keep as a synonym for leave when testing for 'leave open' bugs<commit_after>"use strict";

var Config = {
  supportsHistory : !!(window.history && history.pushState),
  inMaintenanceMode : false,

  treeName: 'mozilla-central',
  hgBaseURL: "https://hg.mozilla.org/",
  hgURL: "https://hg.mozilla.org/mozilla-central/",
  hgRevURL: "https://hg.mozilla.org/mozilla-central/rev/",
  hgPushlogURL: "https://hg.mozilla.org/mozilla-central/pushloghtml?changeset=",
  hgMCURL: "https://hg.mozilla.org/mozilla-central/",
  hgMCRevURL: "https://hg.mozilla.org/mozilla-central/rev/",
  hgMCPushlogURL: "https://hg.mozilla.org/mozilla-central/pushloghtml?changeset=",
  showBugURL: "https://bugzilla.mozilla.org/show_bug.cgi?id=",
  versionURL: "php/getVersion.php",

  // Here be dragons
  versionRE: /^mozilla\d+$/i,
  csetInputRE: /^(tip|[\da-f]{12,40})$/i,
  csetIDRE: /\b([\da-f]{12,40})\b/ig,
  leaveOpenRE: /(?:leave|keep)(?:-|\s+)open/i,
  bugNumRE: /\b(\d{4,7})\b/g,
  strictBugNumRE: /^(\d{4,7})$/,
  mergeRE: /\bmerg(ed?|ing)\b/i,
  backoutRE: /back(ing|ed)?\s*out/i,
  revertRE: /revert(ing)?/i,
  partialRevertRE: /(?:from|in)(?:\s+(?:rev(?:ision)?|c(?:hange)?set))?\s+([\da-f]{12,40})/i,
  partialTestRE: /test\s+for/i,
  revertRangeRE: /revert(?:ing)?\s+(?:\S+\s+)?to(?:\s+(?:rev(?:ision)?|c(?:hange)set))?\s+([\da-f]{12,40})/i,
  csetRangeRE: /\b([\da-f]{12,40})\s*(?:to|:|-|through)\s*([\da-f]{12,40})/i,
  hgRevRE: /https?:\/\/hg.mozilla.org\/mozilla-central\/rev\//ig,
  hgRevFullRE: /https?:\/\/hg.mozilla.org\/mozilla-central\/rev\/[\da-f]{12}/ig,
  hgPushlogRE: /https?:\/\/hg.mozilla.org\/mozilla-central\/pushloghtml\?changeset=/ig,
  hgMCRevRE: /https?:\/\/hg.mozilla.org\/mozilla-central\/rev\//ig,
  hgMCRevFullRE: /https?:\/\/hg.mozilla.org\/mozilla-central\/rev\/[\da-f]{12}/ig,
  hgMCPushlogRE: /https?:\/\/hg.mozilla.org\/mozilla-central\/pushloghtml\?changeset=/ig,
  emailRE: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,   // I'm not looking for RFC 822 compliance here!

  // The many ways bug numbers are specified
  bugRE1: /b(?:ug)?=(\d{4,7})\b/i,                       // e.g. b=XXXXXX
  bugRE2: /^fix(?:es)?\s*(?:for\s*)?(\d{4,7})\b/i,                         // Fix is sometimes used as a synonym for bug
  bugRE3: /to\s+fix\s+bug\s+(\d{4,7})/i,
  bugRE4: /\((\d{4,7}), r=/i,                          // e.g. JS-team style (XXXXXX, r=foo)
  bugRE5: /but\s*(\d{4,7})/i,                          // The typo but XXXXXX happens quite often
  bugRE6: /\bb(?:u?g(?:zilla)?)?:?\s*#?(\d{4,7})\b/i,  // The catchall
  bugRE7: /^(\d{4,7})\b/i,                              // e.g. XXXXXX,

  repoMergeRE: "\\s+(&|and|with|<->|<>|-?->|(in|on)?to)\\s+",

  mcSynonyms: ["mozilla-central", "central", "m-c", "mc", "mozilla central"],

  rewriteTrees: {
    "thunderbird-trunk": "comm-central",
    "thunderbird-aurora": "comm-aurora",
    "thunderbird-beta": "comm-beta",
    "thunderbird-release": "comm-release",
    "thunderbird-esr10": "comm-esr10",
  },

  treeInfo: {
    "mozilla-inbound": {
      repo: "integration/mozilla-inbound",
      trackedTree: false,
      synonyms: ["mozilla-inbound", "inbound", "m-i", "mi"]
    },
    "mozilla-aurora": {
      repo: "releases/mozilla-aurora",
      trackedTree: true,
      synonyms: ["releases/mozilla-aurora", "mozilla-aurora"]
    },
    "mozilla-beta": {
      repo: "releases/mozilla-beta",
      trackedTree: true,
      synonyms: ["releases/mozilla-beta", "mozilla-beta"]
    },
    "mozilla-release": {
      repo: "releases/mozilla-release",
      trackedTree: true,
      synonyms: ["releases/mozilla-release", "mozilla-release"]
    },
    "mozilla-esr10": {
      repo: "releases/mozilla-esr10",
      trackedTree: true,
      synonyms: ["esr10", "releases/mozilla-esr10", "mozilla-esr10"]
    },
    "mozilla-esr17": {
      repo: "releases/mozilla-esr17",
      trackedTree: true,
      synonyms: ["esr17", "releases/mozilla-esr17", "mozilla-esr17"]
    },
    "jetpack": {
      repo: "projects/addon-sdk",
      trackedTree: false,
      synonyms: ["projects/addon-sdk", "addon-sdk"]
    },
    "build-system": {
      repo: "projects/build-system",
      trackedTree: false,
      synonyms: ["build-system", "b-s", "bs"]
    },
    "fx-team": {
      repo: "integration/fx-team",
      trackedTree: false,
      synonyms: ["fx-team"],
      additions: "[fixed-in-fx-team]"
    },
    "graphics": {
      repo: "projects/graphics",
      trackedTree: false,
      synonyms: ["projects/graphics", "graphics"]
    },
    "ionmonkey": {
      repo: "projects/ionmonkey",
      trackedTree: false,
      synonyms: ["projects/ionmonkey", "ionmonkey", "im"]
    },
    "jaegermonkey": {
      repo: "projects/jaegermonkey",
      trackedTree: false,
      synonyms: ["projects/jaegermonkey", "jm"]
    },
    "profiling": {
      repo: "projects/profiling",
      trackedTree: false,
      synonyms: ["profiling", "projects/profiling"]
    },
    "services-central": {
      repo: "services/services-central",
      trackedTree: false,
      synonyms: ["services-central", "s-c", "sc", "services/services-central"],
      additions: "[fixed in services]"
    },
    "ux": {
      repo: "projects/ux",
      synonyms: ["ux", "projects/ux"]
    },
    "alder": {
      repo: "projects/alder",
      trackedTree: false,
      synonyms: ["alder", "projects/alder"]
    },
    "ash": {
      repo: "projects/ash",
      trackedTree: false,
      synonyms: ["ash", "projects/ash"]
    },
    "birch": {
      repo: "projects/birch",
      trackedTree: false,
      synonyms: ["projects/birch", "birch"]
    },
    "cedar": {
      repo: "projects/cedar",
      trackedTree: false,
      synonyms: ["projects/cedar", "cedar"]
    },
    "elm": {
      repo: "projects/elm",
      trackedTree: false,
      synonyms: ["projects/elm", "elm"]
    },
    "holly": {
      repo: "projects/holly",
      trackedTree: false,
      synonyms: ["projects/holly", "holly"]
    },
    "larch": {
      repo: "projects/larch",
      trackedTree: false,
      synonyms: ["projects/larch", "larch"]
    },
    "maple": {
      repo: "projects/maple",
      trackedTree: false,
      synonyms: ["projects/maple", "maple"]
    },
    "oak": {
      repo: "projects/oak",
      trackedTree: false,
      synonyms: ["projects/oak", "oak"]
    },
    "pine": {
      repo: "projects/pine",
      trackedTree: false,
      synonyms: ["projects/pine", "pine"]
    },
    "accessibility": {
      repo: "projects/accessibility",
      trackedTree: false,
      synonyms: ["projects/accessibility", "accessibility"]
    },
    "devtools": {
      repo: "projects/devtools",
      trackedTree: false,
      synonyms: ["projects/devtools", "devtools"]
    },
    "electrolysis": {
      repo: "projects/electrolysis",
      trackedTree: false,
      synonyms: ["projects/electrolysis", "electrolysis", "e10s"]
    },
    "places": {
      repo: "projects/places",
      trackedTree: false,
      synonyms: ["projects/places", "places"]
    },
    "comm-central": {
      repo: "comm-central",
      trackedTree: false,
      synonyms: ["comm-central", "c-c"]
    },
    "comm-aurora": {
      repo: "releases/comm-aurora",
      trackedTree: true,
      synonyms: ["releases/comm-aurora", "comm-aurora"]
    },
    "comm-beta": {
      repo: "releases/comm-beta",
      trackedTree: true,
      synonyms: ["releases/comm-beta", "comm-beta"]
    },
    "comm-release": {
      repo: "releases/comm-release",
      trackedTree: true,
      synonyms: ["releases/comm-release", "comm-release"]
    },
    "comm-esr10": {
      repo: "releases/comm-esr10",
      trackedTree: true,
      synonyms: ["releases/comm-esr10", "comm-esr10"]
    },
    "comm-esr17": {
      repo: "releases/comm-esr17",
      trackedTree: true,
      synonyms: ["releases/comm-esr17", "comm-esr17"]
    }
  }
};

Config.bugNumberREs = [Config.bugRE1, Config.bugRE2, Config.bugRE3,
                       Config.bugRE4, Config.bugRE5, Config.bugRE6, Config.bugRE7];

(function () {
  var base = Config.hgBaseURL;
  for (var treeName in Config.treeInfo) {
    var repo = Config.treeInfo[treeName].repo;
    Config.treeInfo[treeName]['hgURL'] = base + repo + '/';
    Config.treeInfo[treeName]['hgRevURL'] = base + repo + '/rev/';
    Config.treeInfo[treeName]['hgPushlogURL'] = base + repo + '/pushloghtml?changeset=';
    Config.treeInfo[treeName]['hgRevRE'] = new RegExp('https?:\/\/hg.mozilla.org\/' + repo + '\/rev\/');
    Config.treeInfo[treeName]['hgRevFullRE'] = new RegExp('https?:\/\/hg.mozilla.org\/' + repo + '\/rev\/[\\da-f]{12}', 'ig');
    Config.treeInfo[treeName]['hgPushlogRE'] = new RegExp('https?:\/\/hg.mozilla.org\/' + repo + '\/pushloghtml\\?changeset=', 'ig');
  }
})();

// Detect input type="email" support
$(document).ready(function() {
  Config.needsValidation = $('#username').prop('type') != 'email';
});
<|endoftext|>


<commit_before>//based loosely on bostock's example and
//http://bl.ocks.org/d3noob/5141278

var nodes = data.nodes
var links = data.links
var count = 0
for (i in links) {
   if (count<links[i].value) count = links[i].value
}

var ele = document.getElementById("vis"),
    //width = ele.offsetWidth+1200
    //height = ele.offsetHeight+1200
    width = ele.clientWidth,
    height= ele.clientHeight;

var force = d3.layout.force()
    .charge([-250])
    .linkDistance([75])
    .size([width, height])
    .nodes(nodes)
    .links(links)
    .start();

var drag = force.drag();
drag.on("dragstart",dragstart);

var defaultColors = d3.scale.category20(); //10 or 20

var svg = d3.select("#vis").append("svg")
    .attr("width", "100%")
    .attr("height", "100%")
    .append("g")
	.call(d3.behavior.zoom().scaleExtent([0.5,5]).on("zoom",zoomHandler)).on("dblclick.zoom",null).on("mousedown.zoom",null);

var outer_box = svg.append("rect")
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("id","outer_box")    //.attr("fill","none")
    	.attr("fill", "grey")
    	.attr("opacity", 0.1)
    .attr("pointer-events","all");

console.log(outer_box);

svg.append("svg:defs").selectAll("marker")
    .data(["end"])// Different path types defined here
    .enter().append("svg:marker")
    .attr("id", String)
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 15)
    .attr("refY", 0)
    .attr("markerUnits", "userSpaceOnUse")
    .style("fill", function (d) {
        return d.color || "black"
    })
    .style("opacity", function(d) {
        return d.opacity || 1
    })
    .attr("markerWidth", 10)
    .attr("markerHeight", 10)
    .attr("orient", "auto")
    .append("svg:path")
    .attr("d", "M0,-5L10,0L0,5");

var link = svg.append("svg:g").selectAll("path")
    .data(links)
    .enter().append("svg:path")
    .attr("class", "link")
    .attr("marker-end", "url(#end)")
    .style("stroke-width", function (d) {
        return d.width || "1.5"
    })
    .style("stroke", function (d) {
        return d.color || "black"
    })
    .style("opacity", function(d) {
        return d.opacity || 1
    })
    .style("stroke-dasharray", function(d) {
        return d.dasharray || ""
    })
    .style("fill", "none")

//scale values between 1 and 100 to a reasonable range
var scaleSize = d3.scale.linear()
    .domain([1,100])
    .range([80,4000]);

//outer node
var node = svg.selectAll(".node")
    .data(nodes)
    .enter().append("g")
    .on("mouseover", mouseover)
    .on("mouseout", mouseout)
    .on("dblclick", dblclick)
    .call(force.drag)

//inner nodes
node
    .append('path')
    .attr("class", "node")
    .attr("d", d3.svg.symbol()
        .type(function(d) { return d.shape || "circle"; })
        .size(function(d) {return scaleSize(d.size || 1); })
    )
    .style("fill", function(d, i) {
        return d.color || defaultColors(i);
    })
    .style("opacity", function(d) {
        return d.opacity || 1
    })

//inner nodes
node
    .append("text")
    .attr("x", 12)
    .attr("dy", ".35em")
    .style("color",'black')
    .style("display", "none")
    .text(function(d) {
        return d.name;
    });

// Function to add line breaks to node labels/names
var insertLineBreaks = function(d) {
	var el = d3.select(this);
	var words = d3.select(this).text().split('\n');
	el.text('');

	for (var i = 0; i < words.length; i++) {
	    var tspan = el.append('tspan').text(words[i]);
	    if (i > 0)
		tspan.attr('x',0).attr('dy','15');
	}
}

// Add line breaks to node labels
svg.selectAll('text').each(insertLineBreaks);

force.on("tick", function() {
    link
        .attr("d", function(d) {
            var dx = d.target.x - d.source.x,
                dy = d.target.y - d.source.y,
                dr = Math.sqrt(dx * dx + dy * dy);
            return "M" +
                d.source.x + "," +
                d.source.y + "A" +
                dr + "," + dr + " 0 0,1 " +
                d.target.x + "," +
                d.target.y;
        });

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

function mouseover() {

    d3.select(this).select("text").transition()
        .duration(750)
        .style("display","block")
    d3.select(this).select("path").transition()
        .duration(750)
        .attr('d', function (d) {
            return d3.svg.symbol().type(d.shape||"circle")
                    .size(scaleSize(40))()
        })
}

function mouseout() {

    d3.select(this).select("text").transition()
        .duration(750)
        .style("display","none")
    d3.select(this).select("path").transition()
        .duration(750)
        .attr('d', function (d) {
            return d3.svg.symbol().type(d.shape||"circle")
                    .size(scaleSize(d.size||1))()
        })

}

// zoom function
function zoomHandler() {
    svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
    d3.select("#outer_box").attr("width","100%")
    .attr("height","100%");//outter_box.attr("width","100%");
}

// Handle doubleclick on node path (shape)
function dblclick(d) {
    //console.log(this, d);
    d3.select(this).classed("fixed", d.fixed = false);
    //d3.select(this).attr("d", d3.svg.symbol()
	//		.type(function(d) { return d.shape || "circle"; })
	//		.size(function(d) { return scaleSize(d.size * 2 || 2); })
	//);
}

// Handle dragstart on force.drag()
function dragstart(d) {
    //console.log(this, d);
    d3.select(this).classed("fixed", d.fixed = true);
    //d3.select(this).attr("d", d3.svg.symbol()
		//.type(function(d) { return d.shape || "circle"; })
		//.size(function(d) { return scaleSize(d.size || 1); })
	//);
}

<commit_msg>fixed a semicolon<commit_after>//based loosely on bostock's example and
//http://bl.ocks.org/d3noob/5141278

var nodes = data.nodes
var links = data.links
var count = 0
for (i in links) {
   if (count<links[i].value) count = links[i].value
}

var ele = document.getElementById("vis"),
    //width = ele.offsetWidth+1200
    //height = ele.offsetHeight+1200
    width = ele.clientWidth,
    height= ele.clientHeight;

var force = d3.layout.force()
    .charge([-250])
    .linkDistance([75])
    .size([width, height])
    .nodes(nodes)
    .links(links)
    .start();

var drag = force.drag();
drag.on("dragstart",dragstart);

var defaultColors = d3.scale.category20(); //10 or 20

var svg = d3.select("#vis").append("svg")
    .attr("width", "100%")
    .attr("height", "100%")
    .append("g")
	.call(d3.behavior.zoom().scaleExtent([0.5,5]).on("zoom",zoomHandler)).on("dblclick.zoom",null).on("mousedown.zoom",null);

var outer_box = svg.append("rect")
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("id","outer_box")    //.attr("fill","none")
    	.attr("fill", "grey")
    	.attr("opacity", 0.1)
    .attr("pointer-events","all");

console.log(outer_box);

svg.append("svg:defs").selectAll("marker")
    .data(["end"])// Different path types defined here
    .enter().append("svg:marker")
    .attr("id", String)
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 15)
    .attr("refY", 0)
    .attr("markerUnits", "userSpaceOnUse")
    .style("fill", function (d) {
        return d.color || "black"
    })
    .style("opacity", function(d) {
        return d.opacity || 1
    })
    .attr("markerWidth", 10)
    .attr("markerHeight", 10)
    .attr("orient", "auto")
    .append("svg:path")
    .attr("d", "M0,-5L10,0L0,5");

var link = svg.append("svg:g").selectAll("path")
    .data(links)
    .enter().append("svg:path")
    .attr("class", "link")
    .attr("marker-end", "url(#end)")
    .style("stroke-width", function (d) {
        return d.width || "1.5"
    })
    .style("stroke", function (d) {
        return d.color || "black"
    })
    .style("opacity", function(d) {
        return d.opacity || 1
    })
    .style("stroke-dasharray", function(d) {
        return d.dasharray || ""
    })
    .style("fill", "none")

//scale values between 1 and 100 to a reasonable range
var scaleSize = d3.scale.linear()
    .domain([1,100])
    .range([80,4000]);

//outer node
var node = svg.selectAll(".node")
    .data(nodes)
    .enter().append("g")
    .on("mouseover", mouseover)
    .on("mouseout", mouseout)
    .on("dblclick", dblclick)
    .call(force.drag)

//inner nodes
node
    .append('path')
    .attr("class", "node")
    .attr("d", d3.svg.symbol()
        .type(function(d) { return d.shape || "circle"; })
        .size(function(d) {return scaleSize(d.size || 1); })
    )
    .style("fill", function(d, i) {
        return d.color || defaultColors(i);
    })
    .style("opacity", function(d) {
        return d.opacity || 1
    })

//inner nodes
node
    .append("text")
    .attr("x", 12)
    .attr("dy", ".35em")
    .style("color",'black')
    .style("display", "none")
    .text(function(d) {
        return d.name;
    });

// Function to add line breaks to node labels/names
var insertLineBreaks = function(d) {
	var el = d3.select(this);
	var words = d3.select(this).text().split('\n');
	el.text('');

	for (var i = 0; i < words.length; i++) {
	    var tspan = el.append('tspan').text(words[i]);
	    if (i > 0)
		tspan.attr('x',0).attr('dy','15');
	}
}

// Add line breaks to node labels
svg.selectAll('text').each(insertLineBreaks);

force.on("tick", function() {
    link
        .attr("d", function(d) {
            var dx = d.target.x - d.source.x,
                dy = d.target.y - d.source.y,
                dr = Math.sqrt(dx * dx + dy * dy);
            return "M" +
                d.source.x + "," +
                d.source.y + "A" +
                dr + "," + dr + " 0 0,1 " +
                d.target.x + "," +
                d.target.y;
        });

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

function mouseover() {

    d3.select(this).select("text").transition()
        .duration(750)
        .style("display","block")
    d3.select(this).select("path").transition()
        .duration(750)
        .attr('d', function (d) {
            return d3.svg.symbol().type(d.shape||"circle")
                    .size(scaleSize(40))()
        })
}

function mouseout() {

    d3.select(this).select("text").transition()
        .duration(750)
        .style("display","none")
    d3.select(this).select("path").transition()
        .duration(750)
        .attr('d', function (d) {
            return d3.svg.symbol().type(d.shape||"circle")
                    .size(scaleSize(d.size||1))()
        })

}

// zoom function
function zoomHandler() {
    svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
    d3.select("#outer_box").attr("width",width)
    .attr("height",height);//outter_box.attr("width","100%");
}

// Handle doubleclick on node path (shape)
function dblclick(d) {
    //console.log(this, d);
    d3.select(this).classed("fixed", d.fixed = false);
    //d3.select(this).attr("d", d3.svg.symbol()
	//		.type(function(d) { return d.shape || "circle"; })
	//		.size(function(d) { return scaleSize(d.size * 2 || 2); })
	//);
}

// Handle dragstart on force.drag()
function dragstart(d) {
    //console.log(this, d);
    d3.select(this).classed("fixed", d.fixed = true);
    //d3.select(this).attr("d", d3.svg.symbol()
		//.type(function(d) { return d.shape || "circle"; })
		//.size(function(d) { return scaleSize(d.size || 1); })
	//);
}

<|endoftext|>


<commit_before>var queue = 0;
var toBeLoaded = 0;
var loaded = 0;

function setTitle() {
  $('#title').html(config.title);
  document.title = config.title;
}

function setNavbar() {
  for (var i = 0; i < config.navbar.length; i++) {
    var dom = '' + config.navbar[i].text + '';
    if (i != 0)
      $(' • ').appendTo('#navbar');
    $(dom).appendTo('#navbar');
  }
}

function createPlaceholders() {
  for (var i = 0; i < config.atOnce; i++) {
    if (toBeLoaded != config.posts.length) {
      var dom = '

';
      $(dom).appendTo('#posts');
      toBeLoaded++;
    } else
      break;
  }
}

function loadPosts() {
  $('#loader').show();
  for (;loaded < toBeLoaded; loaded++) {
    queue ++;
    $.get('https://api.github.com/gists/' + config.posts[loaded], function (data) {
      var gist = '';
      for (var j in data.files)
        gist = gist + marked.parse(data.files[j].content);
      var dom = '
' +
                '
' + gist + '
' +
                '' + new Date(data.updated_at) + '' +
                ' • Posted by ' + data.user.login + '' +
                '

';
      $(dom).appendTo('#post' + data.id);
    }, 'json').done(function() {
      queue --;
      if (queue == 0)
        $('#loader').hide();
    });
  }
}

function loadFooter() {
  $('#footer-text').html(config.footerText);
}

function loadOlder() {
  createPlaceholders();
  loadPosts();
  if (toBeLoaded == config.posts.length)
    $('#old-posts').hide();
}

$('#loader').hide();
setTitle();
setNavbar();
loadFooter();
$('#old-posts').bind('click', loadOlder);
createPlaceholders();
loadPosts();
if (toBeLoaded == config.posts.length)
  $('#old-posts').hide();
<commit_msg>add load links method<commit_after>var queue = 0;
var toBeLoaded = 0;
var loaded = 0;

function setTitle() {
  $('#title').html(config.title);
  document.title = config.title;
}

function setNavbar() {
  for (var i = 0; i < config.navbar.length; i++) {
    var dom = '' + config.navbar[i].text + '';
    if (i != 0)
      $(' • ').appendTo('#navbar');
    $(dom).appendTo('#navbar');
  }
}

function createPlaceholders() {
  for (var i = 0; i < config.atOnce; i++) {
    if (toBeLoaded != config.posts.length) {
      var dom = '

';
      $(dom).appendTo('#posts');
      toBeLoaded++;
    } else
      break;
  }
}

function loadPosts() {
  $('#loader').show();
  for (;loaded < toBeLoaded; loaded++) {
    queue ++;
    $.get('https://api.github.com/gists/' + config.posts[loaded], function (data) {
      var gist = '';
      for (var j in data.files)
        gist = gist + marked.parse(data.files[j].content);
      var dom = '
' +
                '
' + gist + '
' +
                '' + new Date(data.updated_at) + '' +
                ' • Posted by ' + data.user.login + '' +
                '

';
      $(dom).appendTo('#post' + data.id);
    }, 'json').done(function() {
      queue --;
      if (queue == 0)
        $('#loader').hide();
    });
  }
}

function loadLink(gist_id) {
  $.get('https://api.github.com/gists/' + gist_id, function (data) {
    var gist = '';
    for (var j in data.files)
      gist = gist + marked.parse(data.files[j].content);
      title = data.files[j].filename;
      updated_at = new Date(data.updated_at);
    var dom = '
' + title + ' •  last changed at ' +
              '' + updated_at.toDateString() + '' +
              ' • posted by ' + data.user.login + '' +
              '
';
    $(dom).appendTo('#post' + data.id);
    }, 'json').done(function() {
  });
}

function loadAllLinks() {
  $('#loader').show();
  for (;loaded < toBeLoaded; loaded++) {
    queue ++;
    $.get('https://api.github.com/gists/' + config.posts[loaded], function (data) {
      // var gist = '';
      // for (var j in data.files)
      //   gist = gist + marked.parse(data.files[j].content);
      //   title = data.files[j].filename;
      //   updated_at = new Date(data.updated_at);
      // var dom = '
' + title + ' •  ' +
      //           '' + updated_at.toDateString() + '' +
      //           ' • Posted by ' + data.user.login + '' +
      //           '
';
      // $(dom).appendTo('#post' + data.id);
      gist_id = data.id
      loadLink(gist_id);
    }, 'json').done(function() {
      queue --;
      if (queue == 0)
        $('#loader').hide();
    });
  }
}

function loadFooter() {
  $('#footer-text').html(config.footerText);
}

function loadOlder() {
  createPlaceholders();
  loadPosts();
  if (toBeLoaded == config.posts.length)
    $('#old-posts').hide();
}

$('#loader').hide();
setTitle();
setNavbar();
loadFooter();
$('#old-posts').bind('click', loadOlder);
createPlaceholders();
loadAllLinks();
if (toBeLoaded == config.posts.length)
  $('#old-posts').hide();
<|endoftext|>


<commit_before>// Copyright 2002-2013, University of Colorado Boulder

/**
 * Lightweight event & listener abstraction.
 * @author Sam Reid
 */
define( function( require ) {
  'use strict';

  var axon = require( 'AXON/axon' );

  /**
   * @class Events
   * @constructor
   * @param values an object hash with the initial values for the properties
   */
  axon.Events = function Events() {
    this._eventListeners = {}; // @private
    this._staticEventListeners = {}; // @private
  };

  axon.Events.prototype = {

    /////////////////////////////////////////////
    // Below this point are the functions for event handling, basically orthogonal to property value change notifications

    /**
     * Register a listener when the specified eventName is triggered. Use off() to remove.
     * Concurrent modification of listeners (on/off) from within the callback is acceptable.
     * @param eventName {String} the name for the event channel
     * @param callback {Function}
     */
    on: function( eventName, callback ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );
      assert && assert( typeof callback === 'function', 'callback should be a function' );

      phetAllocation && phetAllocation( 'Array' );
      this._eventListeners[eventName] = this._eventListeners[eventName] || [];
      this._eventListeners[eventName].push( callback );
    },

    /**
     * Register a listener when the specified eventName is triggered. Listener should be "static", meaning:
     *   1. It shall not add/remove any "static" listeners (including itself) while it is being called (as any type of side-effect), and
     *   2. "static" listeners should not be added while a non-static listener (on the same object) is being called.
     * These restrictions allow us to guarantee that all listeners attached when an event is triggered are called.
     * Since static listeners are stored separately, use offStatic() to remove listeners added with onStatic()
     * @param eventName {String} the name for the event channel
     * @param callback {Function}
     */
    onStatic: function( eventName, callback ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );
      assert && assert( typeof callback === 'function', 'callback should be a function' );

      phetAllocation && phetAllocation( 'Array' );
      this._staticEventListeners[eventName] = this._staticEventListeners[eventName] || [];
      this._staticEventListeners[eventName].push( callback );
    },

    /**
     * Adds a function which will only be called back once, after which it is removed as a listener.
     * If you need to remove a function added with 'once' you will have to remove its handle, which is returned by the function.
     * NOTE: Listeners added with once() cannot be removed with off()!
     * @param eventName {String} the name for the event channel
     * @param callback function to be called back once (if at all)
     */
    once: function( eventName, callback ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );
      assert && assert( typeof callback === 'function', 'callback should be a function' );

      var events = this;
      var wrappedCallback = function() {
        events.off( eventName, wrappedCallback );

        //If no arguments being passed through, call back without processing arguments, for possible speed
        if ( arguments.length === 0 ) {
          callback();
        }
        else {

          //General case of passing events through to the wrapped callback function
          callback.apply( this, Array.prototype.slice.call( arguments, 0 ) );
        }
      };
      this.on( eventName, wrappedCallback );

      //Return the handle in case it needs to be removed.
      return wrappedCallback;
    },

    /**
     * Remove a listener added with on() from the specified event type.  Does nothing if the listener did not exist.
     * @param eventName {String} the name for the event channel
     * @param callback {Function}
     */
    off: function( eventName, callback ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );
      assert && assert( typeof callback === 'function', 'callback should be a function' );

      var index = -1;
      if ( this._eventListeners[eventName] ) {
        index = this._eventListeners[eventName].indexOf( callback );
        if ( index !== -1 ) {
          this._eventListeners[eventName].splice( index, 1 );
        }
      }

      return index; // so we can tell if we actually removed a listener
    },

    /**
     * Remove a listener added with onStatic() from the specified event type.  Does nothing if the listener did not exist.
     * @param eventName {String} the name for the event channel
     * @param callback {Function}
     */
    offStatic: function( eventName, callback ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );
      assert && assert( typeof callback === 'function', 'callback should be a function' );

      var index = -1;
      if ( this._staticEventListeners[eventName] ) {
        index = this._staticEventListeners[eventName].indexOf( callback );
        if ( index !== -1 ) {
          this._staticEventListeners[eventName].splice( index, 1 );
        }
      }

      return index; // so we can tell if we actually removed a listener
    },

    /**
     * Checks for the existence of a specific listener, attached to a specific event name. Doesn't check for static listeners
     * @param eventName {String} the name for the event channel
     * @param callback {Function}
     * @returns {Boolean}
     */
    hasListener: function( eventName, callback ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );
      assert && assert( typeof callback === 'function', 'callback should be a function' );

      var array = this._eventListeners[eventName];
      return !!array && array.indexOf( callback ) >= 0;
    },

    /**
     * Checks for the existence of a specific static listener, attached to a specific event name. Doesn't check for non-static listeners
     * @param eventName {String} the name for the event channel
     * @param callback {Function}
     * @returns {Boolean}
     */
    hasStaticListener: function( eventName, callback ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );
      assert && assert( typeof callback === 'function', 'callback should be a function' );

      var array = this._staticEventListeners[eventName];
      return !!array && array.indexOf( callback ) >= 0;
    },

    /**
     * Trigger an event with the specified name and arguments.
     * @param eventName {String} the name for the event channel
     * @param args... optional arguments to pass to the listeners
     */
    trigger: function( eventName ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );

      var listeners = this._eventListeners[eventName];
      var staticListeners = this._staticEventListeners[eventName];

      // listener quantities for normal and static
      var count = listeners ? listeners.length : 0;
      var staticCount = staticListeners ? staticListeners.length : 0;

      // only compute our arguments suffix once, instead of in our inner loop
      var suffix;
      var hasNoArguments = arguments.length === 1;
      if ( !hasNoArguments && ( count > 0 || staticCount > 0 ) ) {
        phetAllocation && phetAllocation( 'Array' );
        suffix = Array.prototype.slice.call( arguments, 1 );
      }

      // make a copy of non-static listeners, in case callback removes listener
      if ( count > 0 ) {
        listeners = listeners.slice();
      }

      var i;

      for ( i = 0; i < count; i++ ) {
        var listener = listeners[i];

        //Simple case of no arguments, call it separately for improved performance in case it is faster (untested)
        if ( hasNoArguments ) {
          listener( arguments );
        }
        else {
          listener.apply( this, suffix );
        }

        assert && assert( !staticListeners || staticListeners.length === staticCount, 'Concurrent modifications of static listeners from within non-static listeners are forbidden' );
      }

      for ( i = 0; i < staticCount; i++ ) {
        var staticListener = staticListeners[i];

        //Simple case of no arguments, call it separately for improved performance in case it is faster (untested)
        if ( hasNoArguments ) {
          staticListener( arguments );
        }
        else {
          staticListener.apply( this, suffix );
        }

        assert && assert( staticListeners.length === staticCount, 'Concurrent modifications from static listeners are forbidden' );
      }
    },

    /**
     * Trigger an event with the specified name, with no arguments. Should get optimized in browsers better than trigger, so we have code duplication for now.
     * @param eventName {String} the name for the event channel
     */
    trigger0: function( eventName ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );

      var listeners = this._eventListeners[eventName];
      var staticListeners = this._staticEventListeners[eventName];

      // listener quantities for normal and static
      var count = listeners ? listeners.length : 0;
      var staticCount = staticListeners ? staticListeners.length : 0;

      // make a copy of non-static listeners, in case callback removes listener
      if ( count > 0 ) {
        listeners = listeners.slice();
      }

      var i;

      for ( i = 0; i < count; i++ ) {
        listeners[i]();

        assert && assert( !staticListeners || staticListeners.length === staticCount, 'Concurrent modifications of static listeners from within non-static listeners are forbidden' );
      }

      for ( i = 0; i < staticCount; i++ ) {
        staticListeners[i]();

        assert && assert( staticListeners.length === staticCount, 'Concurrent modifications from static listeners are forbidden' );
      }
    },

    /**
     * Trigger an event with the specified name, with a single arguments. Should get optimized in browsers better than trigger, so we have code duplication for now.
     * @param eventName {String} the name for the event channel
     */
    trigger1: function( eventName, param1 ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );

      var listeners = this._eventListeners[eventName];
      var staticListeners = this._staticEventListeners[eventName];

      // listener quantities for normal and static
      var count = listeners ? listeners.length : 0;
      var staticCount = staticListeners ? staticListeners.length : 0;

      // make a copy of non-static listeners, in case callback removes listener
      if ( count > 0 ) {
        listeners = listeners.slice();
      }

      var i;

      for ( i = 0; i < count; i++ ) {
        listeners[i]( param1 );

        assert && assert( !staticListeners || staticListeners.length === staticCount, 'Concurrent modifications of static listeners from within non-static listeners are forbidden' );
      }

      for ( i = 0; i < staticCount; i++ ) {
        staticListeners[i]( param1 );

        assert && assert( staticListeners.length === staticCount, 'Concurrent modifications from static listeners are forbidden' );
      }
    }
  };

  return axon.Events;
} );
<commit_msg>Removing comment<commit_after>// Copyright 2002-2013, University of Colorado Boulder

/**
 * Lightweight event & listener abstraction.
 * @author Sam Reid
 */
define( function( require ) {
  'use strict';

  var axon = require( 'AXON/axon' );

  /**
   * @class Events
   * @constructor
   * @param values an object hash with the initial values for the properties
   */
  axon.Events = function Events() {
    this._eventListeners = {}; // @private
    this._staticEventListeners = {}; // @private
  };

  axon.Events.prototype = {

    /////////////////////////////////////////////
    // Below this point are the functions for event handling, basically orthogonal to property value change notifications

    /**
     * Register a listener when the specified eventName is triggered. Use off() to remove.
     * Concurrent modification of listeners (on/off) from within the callback is acceptable.
     * @param eventName {String} the name for the event channel
     * @param callback {Function}
     */
    on: function( eventName, callback ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );
      assert && assert( typeof callback === 'function', 'callback should be a function' );

      phetAllocation && phetAllocation( 'Array' );
      this._eventListeners[eventName] = this._eventListeners[eventName] || [];
      this._eventListeners[eventName].push( callback );
    },

    /**
     * Register a listener when the specified eventName is triggered. Listener should be "static", meaning:
     *   1. It shall not add/remove any "static" listeners (including itself) while it is being called (as any type of side-effect), and
     *   2. "static" listeners should not be added while a non-static listener (on the same object) is being called.
     * These restrictions allow us to guarantee that all listeners attached when an event is triggered are called.
     * Since static listeners are stored separately, use offStatic() to remove listeners added with onStatic()
     * @param eventName {String} the name for the event channel
     * @param callback {Function}
     */
    onStatic: function( eventName, callback ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );
      assert && assert( typeof callback === 'function', 'callback should be a function' );

      phetAllocation && phetAllocation( 'Array' );
      this._staticEventListeners[eventName] = this._staticEventListeners[eventName] || [];
      this._staticEventListeners[eventName].push( callback );
    },

    /**
     * Adds a function which will only be called back once, after which it is removed as a listener.
     * If you need to remove a function added with 'once' you will have to remove its handle, which is returned by the function.
     * @param eventName {String} the name for the event channel
     * @param callback function to be called back once (if at all)
     */
    once: function( eventName, callback ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );
      assert && assert( typeof callback === 'function', 'callback should be a function' );

      var events = this;
      var wrappedCallback = function() {
        events.off( eventName, wrappedCallback );

        //If no arguments being passed through, call back without processing arguments, for possible speed
        if ( arguments.length === 0 ) {
          callback();
        }
        else {

          //General case of passing events through to the wrapped callback function
          callback.apply( this, Array.prototype.slice.call( arguments, 0 ) );
        }
      };
      this.on( eventName, wrappedCallback );

      //Return the handle in case it needs to be removed.
      return wrappedCallback;
    },

    /**
     * Remove a listener added with on() from the specified event type.  Does nothing if the listener did not exist.
     * @param eventName {String} the name for the event channel
     * @param callback {Function}
     */
    off: function( eventName, callback ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );
      assert && assert( typeof callback === 'function', 'callback should be a function' );

      var index = -1;
      if ( this._eventListeners[eventName] ) {
        index = this._eventListeners[eventName].indexOf( callback );
        if ( index !== -1 ) {
          this._eventListeners[eventName].splice( index, 1 );
        }
      }

      return index; // so we can tell if we actually removed a listener
    },

    /**
     * Remove a listener added with onStatic() from the specified event type.  Does nothing if the listener did not exist.
     * @param eventName {String} the name for the event channel
     * @param callback {Function}
     */
    offStatic: function( eventName, callback ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );
      assert && assert( typeof callback === 'function', 'callback should be a function' );

      var index = -1;
      if ( this._staticEventListeners[eventName] ) {
        index = this._staticEventListeners[eventName].indexOf( callback );
        if ( index !== -1 ) {
          this._staticEventListeners[eventName].splice( index, 1 );
        }
      }

      return index; // so we can tell if we actually removed a listener
    },

    /**
     * Checks for the existence of a specific listener, attached to a specific event name. Doesn't check for static listeners
     * @param eventName {String} the name for the event channel
     * @param callback {Function}
     * @returns {Boolean}
     */
    hasListener: function( eventName, callback ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );
      assert && assert( typeof callback === 'function', 'callback should be a function' );

      var array = this._eventListeners[eventName];
      return !!array && array.indexOf( callback ) >= 0;
    },

    /**
     * Checks for the existence of a specific static listener, attached to a specific event name. Doesn't check for non-static listeners
     * @param eventName {String} the name for the event channel
     * @param callback {Function}
     * @returns {Boolean}
     */
    hasStaticListener: function( eventName, callback ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );
      assert && assert( typeof callback === 'function', 'callback should be a function' );

      var array = this._staticEventListeners[eventName];
      return !!array && array.indexOf( callback ) >= 0;
    },

    /**
     * Trigger an event with the specified name and arguments.
     * @param eventName {String} the name for the event channel
     * @param args... optional arguments to pass to the listeners
     */
    trigger: function( eventName ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );

      var listeners = this._eventListeners[eventName];
      var staticListeners = this._staticEventListeners[eventName];

      // listener quantities for normal and static
      var count = listeners ? listeners.length : 0;
      var staticCount = staticListeners ? staticListeners.length : 0;

      // only compute our arguments suffix once, instead of in our inner loop
      var suffix;
      var hasNoArguments = arguments.length === 1;
      if ( !hasNoArguments && ( count > 0 || staticCount > 0 ) ) {
        phetAllocation && phetAllocation( 'Array' );
        suffix = Array.prototype.slice.call( arguments, 1 );
      }

      // make a copy of non-static listeners, in case callback removes listener
      if ( count > 0 ) {
        listeners = listeners.slice();
      }

      var i;

      for ( i = 0; i < count; i++ ) {
        var listener = listeners[i];

        //Simple case of no arguments, call it separately for improved performance in case it is faster (untested)
        if ( hasNoArguments ) {
          listener( arguments );
        }
        else {
          listener.apply( this, suffix );
        }

        assert && assert( !staticListeners || staticListeners.length === staticCount, 'Concurrent modifications of static listeners from within non-static listeners are forbidden' );
      }

      for ( i = 0; i < staticCount; i++ ) {
        var staticListener = staticListeners[i];

        //Simple case of no arguments, call it separately for improved performance in case it is faster (untested)
        if ( hasNoArguments ) {
          staticListener( arguments );
        }
        else {
          staticListener.apply( this, suffix );
        }

        assert && assert( staticListeners.length === staticCount, 'Concurrent modifications from static listeners are forbidden' );
      }
    },

    /**
     * Trigger an event with the specified name, with no arguments. Should get optimized in browsers better than trigger, so we have code duplication for now.
     * @param eventName {String} the name for the event channel
     */
    trigger0: function( eventName ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );

      var listeners = this._eventListeners[eventName];
      var staticListeners = this._staticEventListeners[eventName];

      // listener quantities for normal and static
      var count = listeners ? listeners.length : 0;
      var staticCount = staticListeners ? staticListeners.length : 0;

      // make a copy of non-static listeners, in case callback removes listener
      if ( count > 0 ) {
        listeners = listeners.slice();
      }

      var i;

      for ( i = 0; i < count; i++ ) {
        listeners[i]();

        assert && assert( !staticListeners || staticListeners.length === staticCount, 'Concurrent modifications of static listeners from within non-static listeners are forbidden' );
      }

      for ( i = 0; i < staticCount; i++ ) {
        staticListeners[i]();

        assert && assert( staticListeners.length === staticCount, 'Concurrent modifications from static listeners are forbidden' );
      }
    },

    /**
     * Trigger an event with the specified name, with a single arguments. Should get optimized in browsers better than trigger, so we have code duplication for now.
     * @param eventName {String} the name for the event channel
     */
    trigger1: function( eventName, param1 ) {
      assert && assert( typeof eventName === 'string', 'eventName should be a string' );

      var listeners = this._eventListeners[eventName];
      var staticListeners = this._staticEventListeners[eventName];

      // listener quantities for normal and static
      var count = listeners ? listeners.length : 0;
      var staticCount = staticListeners ? staticListeners.length : 0;

      // make a copy of non-static listeners, in case callback removes listener
      if ( count > 0 ) {
        listeners = listeners.slice();
      }

      var i;

      for ( i = 0; i < count; i++ ) {
        listeners[i]( param1 );

        assert && assert( !staticListeners || staticListeners.length === staticCount, 'Concurrent modifications of static listeners from within non-static listeners are forbidden' );
      }

      for ( i = 0; i < staticCount; i++ ) {
        staticListeners[i]( param1 );

        assert && assert( staticListeners.length === staticCount, 'Concurrent modifications from static listeners are forbidden' );
      }
    }
  };

  return axon.Events;
} );
<|endoftext|>


<commit_before>JPLoad = {
    _doRequest : function (url, callback) {
        var _this = this,
            xhr;

        if (typeof XMLHttpRequest !== 'undefined') {
            xhr = new XMLHttpRequest();
        } else {
            var versions = [
                "MSXML2.XmlHttp.5.0",
                "MSXML2.XmlHttp.4.0",
                "MSXML2.XmlHttp.3.0",
                "MSXML2.XmlHttp.2.0",
                "Microsoft.XmlHttp"
            ];

            for (var i = 0, len = versions.length; i < len; i++) {
                try {
                    xhr = new ActiveXObject(versions[i]);
                    break;
                }
                catch(e){
                    console.log('Error when trying to initiate an Ajax Call');
                }
             }
        }

        xhr.onreadystatechange = safeRead;

        function safeRead () {
            if (xhr.readyState < 4) {
                return;
            }
            if (xhr.status !== 200) {
                return;
            }
            if (xhr.readyState === 4) {
                callback(xhr.responseText);
            }
        }
        xhr.open('GET', url, true);
        xhr.send('');
    },

    getView : function (templateURL, callback) {
        this._doRequest(templateURL, function (response) {
            if (response)
                callback(response);
        });
    },

    _escapeRegExp: function (str) {
        return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
    },

    _injectData : function (templateData, find, replace) {
        return templateData.replace(new RegExp(this._escapeRegExp(find), 'g'), replace);
    },

    _parseObject : function (pObject, htmlData, elementID, appendFlag, callback) {
        var _this = this,
            elementsInData = Object.keys(pObject).length,
            counted = 0;

        var _waitForIt = function () {
            for (var key in pObject) {
                htmlData = _this._injectData(htmlData, '{{' + key + '}}', pObject[key]);
                counted++;
            }
            if (counted >= elementsInData) {
                if (appendFlag) {
                    var divHelper = document.createElement('div');
                    divHelper.innerHTML = htmlData;

                    document.getElementById(elementID).appendChild(divHelper.firstChild);
                    callback(true);
                } else {
                    document.getElementById(elementID).innerHTML = htmlData;
                    callback(true);
                }
            } else {
                setTimeout(function () {
                    _waitForIt();
                },20);
            }
        };
        _waitForIt();
    },
    loadView : function (htmlData, elementID, oData, callback) {
        if (oData !== undefined) {
            this._parseObject(oData, htmlData, elementID, false, function (response) {
                if (response) {
                    if (callback)
                        callback(true);
                }
            });
        } else {
            document.getElementById(elementID).innerHTML = htmlData;
            if (callback)
                callback(true);
        }
    },

    appendView : function (htmlData, elementID, oData, callback) {
        if (oData !== undefined) {
            this._parseObject(oData, htmlData, elementID, true, function (response) {
                if (response) {
                    if (callback)
                        callback(true);
                }
            });
        } else {
            var divHelper = document.createElement('div');

            divHelper.innerHTML = htmlData;
            document.getElementById(elementID).appendChild(divHelper);
            if (callback)
                callback(true);
        }
    },
};<commit_msg>removed ghost div when append<commit_after>JPLoad = {
    _doRequest : function (url, callback) {
        var _this = this,
            xhr;

        if (typeof XMLHttpRequest !== 'undefined') {
            xhr = new XMLHttpRequest();
        } else {
            var versions = [
                "MSXML2.XmlHttp.5.0",
                "MSXML2.XmlHttp.4.0",
                "MSXML2.XmlHttp.3.0",
                "MSXML2.XmlHttp.2.0",
                "Microsoft.XmlHttp"
            ];

            for (var i = 0, len = versions.length; i < len; i++) {
                try {
                    xhr = new ActiveXObject(versions[i]);
                    break;
                }
                catch(e){
                    console.log('Error when trying to initiate an Ajax Call');
                }
             }
        }

        xhr.onreadystatechange = safeRead;

        function safeRead () {
            if (xhr.readyState < 4) {
                return;
            }
            if (xhr.status !== 200) {
                return;
            }
            if (xhr.readyState === 4) {
                callback(xhr.responseText);
            }
        }
        xhr.open('GET', url, true);
        xhr.send('');
    },

    getView : function (templateURL, callback) {
        this._doRequest(templateURL, function (response) {
            if (response)
                callback(response);
        });
    },

    _escapeRegExp: function (str) {
        return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
    },

    _injectData : function (templateData, find, replace) {
        return templateData.replace(new RegExp(this._escapeRegExp(find), 'g'), replace);
    },

    _parseObject : function (pObject, htmlData, elementID, appendFlag, callback) {
        var _this = this,
            elementsInData = Object.keys(pObject).length,
            counted = 0;

        var _waitForIt = function () {
            for (var key in pObject) {
                htmlData = _this._injectData(htmlData, '{{' + key + '}}', pObject[key]);
                counted++;
            }
            if (counted >= elementsInData) {
                if (appendFlag) {
                    var divHelper = document.createElement('div');
                    divHelper.innerHTML = htmlData;

                    document.getElementById(elementID).appendChild(divHelper.firstChild);
                    callback(true);
                } else {
                    document.getElementById(elementID).innerHTML = htmlData;
                    callback(true);
                }
            } else {
                setTimeout(function () {
                    _waitForIt();
                },20);
            }
        };
        _waitForIt();
    },
    loadView : function (htmlData, elementID, oData, callback) {
        if (oData !== undefined) {
            this._parseObject(oData, htmlData, elementID, false, function (response) {
                if (response) {
                    if (callback)
                        callback(true);
                }
            });
        } else {
            document.getElementById(elementID).innerHTML = htmlData;
            if (callback)
                callback(true);
        }
    },

    appendView : function (htmlData, elementID, oData, callback) {
        if (oData !== undefined) {
            this._parseObject(oData, htmlData, elementID, true, function (response) {
                if (response) {
                    if (callback)
                        callback(true);
                }
            });
        } else {
            var divHelper = document.createElement('div');

            divHelper.innerHTML = htmlData;
            document.getElementById(elementID).appendChild(divHelper.firstChild);
            if (callback)
                callback(true);
        }
    },
};<|endoftext|>


<commit_before>/* eslint-env mocha, browser */
/* global proclaim */

it('has correct instance', function () {
	proclaim.isInstanceOf(Array.prototype.find, Function);
});

it('has correct name', function () {
	function nameOf(fn) {
		return Function.prototype.toString.call(fn).match(/function\s*([^\s]*)\s*\(/)[1];
	}
	proclaim.equal(nameOf(Array.prototype.find), 'find');
});

it('has correct argument length', function () {
	proclaim.equal(Array.prototype.find.length, 1);
});

describe('callback', function () {
	it('has correct argument length', function () {
		[0].find(function () {
			proclaim.equal(arguments.length, 3);
		});
	});
});

describe('applies callback correctly with', function () {
	function isPrime(element) {
		var start = 1;

		while (++start <= Math.sqrt(element)) {
			if (element % start < 1) {
				return false;
			}
		}

		return element > 1;
	}

	it('arrays', function () {
		proclaim.equal([4, 6, 7, 12].find(isPrime), 7);
		proclaim.equal([4, 6, 8, 12].find(isPrime), undefined);
	});

	it('array-like objects', function () {
		var
		// 4: 13 is ignored because length omits it
		objectA = { 0: 4, 1: 6, 2: 7, 3: 12, 4: 13, length: 4 },
		objectB = { 0: 4, 1: 6, 2: 8, 3: 12, 4: 13, length: 4 };

		proclaim.equal(Array.prototype.find.call(objectA, isPrime), 7);
		proclaim.equal(Array.prototype.find.call(objectB, isPrime), undefined);
	});
});
<commit_msg>improve test coverage for Array.prototype.find (#1610)<commit_after>/* eslint-env mocha */
/* globals proclaim */

it('is a function', function () {
	proclaim.isFunction(Array.prototype.find);
});

it('has correct arity', function () {
	proclaim.arity(Array.prototype.find, 1);
});

it('has correct name', function () {
	proclaim.hasName(Array.prototype.find, 'find');
});

it('is not enumerable', function () {
	proclaim.nonEnumerable(Array.prototype, 'find');
});

describe('callback', function () {
	it('has correct argument length', function () {
		[0].find(function () {
			proclaim.equal(arguments.length, 3);
		});
	});
});

describe('applies callback correctly with', function () {
	function isPrime(element) {
		var start = 1;

		while (++start <= Math.sqrt(element)) {
			if (element % start < 1) {
				return false;
			}
		}

		return element > 1;
	}

	it('arrays', function () {
		proclaim.equal([4, 6, 7, 12].find(isPrime), 7);
		proclaim.equal([4, 6, 8, 12].find(isPrime), undefined);
	});

	it('array-like objects', function () {
		var
		// 4: 13 is ignored because length omits it
		objectA = { 0: 4, 1: 6, 2: 7, 3: 12, 4: 13, length: 4 },
		objectB = { 0: 4, 1: 6, 2: 8, 3: 12, 4: 13, length: 4 };

		proclaim.equal(Array.prototype.find.call(objectA, isPrime), 7);
		proclaim.equal(Array.prototype.find.call(objectB, isPrime), undefined);
	});
});
<|endoftext|>


<commit_before>import React from 'react';

import Analyzer, { SELECTED_PLAYER } from 'parser/core/Analyzer';
import SPELLS from 'common/SPELLS';
import SpellLink from 'common/SpellLink';
import SpellIcon from 'common/SpellIcon';
import { formatPercentage } from 'common/format';
import StatisticBox, { STATISTIC_ORDER } from 'interface/others/StatisticBox';
import Enemies from 'parser/shared/modules/Enemies';
import { i18n } from '@lingui/core';
import { t } from '@lingui/macro';
import Events from 'parser/core/Events';

/**
 * Find Weakness
 * Your Shadowstrike and Cheap Shot abilities reveal a flaw in your target's defenses, causing all your attacks to bypass 30%  of that enemy's armor for 18 sec.
 */
class FindWeakness extends Analyzer {
  static dependencies = {
    enemies: Enemies,
  };

  badVanishCasts = 0;

  constructor(options){
    super(options);
    this.addEventListener(Events.cast.by(SELECTED_PLAYER).spell(SPELLS.VANISH), this.onCast);
    this.addEventListener(Events.refreshdebuff.by(SELECTED_PLAYER).spell(SPELLS.FIND_WEAKNESS), this.onRefreshDebuff);
  }

  onCast(event) {
    const spellId = event.ability.guid;
    if (spellId === SPELLS.VANISH.id) {
      this.handleVanish(event);
    }
  }

  latestTs = 0;
  onRefreshDebuff(event) {
    this.latestTs = event.timestamp;
  }

  handleVanish(event) {
    const entities = this.enemies.getEntities();
    const hasDebuff = Object.values(entities)
      .filter(enemy => enemy.hasBuff(SPELLS.FIND_WEAKNESS.id))
      .map(enemy => enemy.getBuff(SPELLS.FIND_WEAKNESS.id).timestamp);

    //For now does not support target switching, just makes sure that enough time has passed since the last application
    if (Math.max(...hasDebuff, this.latestTs) > event.timestamp - 8000) {
      this.badVanishCasts += 1;
      event.meta = event.meta || {};
      event.meta.isInefficientCast = true;
      event.meta.inefficientCastReason = `Use Vanish only when Find Weakness is not up or is about to run out.`;
    }
  }

  get vanishThresholds() {
    return {
      actual: this.badVanishCasts,
      isGreaterThan: {
        minor: 0,
        average: 0,
        major: 0,
      },
      style: 'number',
    };
  }

  suggestions(when) {
    when(this.vanishThresholds)
      .addSuggestion((suggest, actual, recommended) => suggest(<>Use <SpellLink id={SPELLS.VANISH.id} /> only when you do not have <SpellLink id={SPELLS.FIND_WEAKNESS_TALENT.id} /> applied to your target </>)
        .icon(SPELLS.VANISH.icon)
        .actual(i18n._(t('rogue.subtlety.suggestions.findWeakness.alreadyApplied')`You used Vanish ${this.badVanishCasts} times when Find Weakness was already applied`))
        .recommended(`${recommended} is recommended`));
  }

  statistic() {
    const uptime = this.enemies.getBuffUptime(SPELLS.FIND_WEAKNESS.id) / this.owner.fightDuration;
    return (
      <StatisticBox
        position={STATISTIC_ORDER.OPTIONAL(40)}
        icon={<SpellIcon id={SPELLS.FIND_WEAKNESS.id} />}
        value={`${formatPercentage(uptime)} %`}
        label={`${SPELLS.FIND_WEAKNESS.name} uptime`}
      />
    );
  }
}

export default FindWeakness;
<commit_msg>cleanup<commit_after>import React from 'react';

import Analyzer, { SELECTED_PLAYER } from 'parser/core/Analyzer';
import SPELLS from 'common/SPELLS';
import SpellLink from 'common/SpellLink';
import SpellIcon from 'common/SpellIcon';
import { formatPercentage } from 'common/format';
import StatisticBox, { STATISTIC_ORDER } from 'interface/others/StatisticBox';
import Enemies from 'parser/shared/modules/Enemies';
import { i18n } from '@lingui/core';
import { t } from '@lingui/macro';
import Events from 'parser/core/Events';

/**
 * Find Weakness
 * Your Shadowstrike and Cheap Shot abilities reveal a flaw in your target's defenses, causing all your attacks to bypass 30%  of that enemy's armor for 18 sec.
 */
class FindWeakness extends Analyzer {
  static dependencies = {
    enemies: Enemies,
  };

  badVanishCasts = 0;

  constructor(options){
    super(options);
    this.addEventListener(Events.cast.by(SELECTED_PLAYER).spell(SPELLS.VANISH), this.handleVanish);
    this.addEventListener(Events.refreshdebuff.by(SELECTED_PLAYER).spell(SPELLS.FIND_WEAKNESS), this.onRefreshDebuff);
  }

  latestTs = 0;
  onRefreshDebuff(event) {
    this.latestTs = event.timestamp;
  }

  handleVanish(event) {
    const entities = this.enemies.getEntities();
    const hasDebuff = Object.values(entities)
      .filter(enemy => enemy.hasBuff(SPELLS.FIND_WEAKNESS.id))
      .map(enemy => enemy.getBuff(SPELLS.FIND_WEAKNESS.id).timestamp);

    //For now does not support target switching, just makes sure that enough time has passed since the last application
    if (Math.max(...hasDebuff, this.latestTs) > event.timestamp - 8000) {
      this.badVanishCasts += 1;
      event.meta = event.meta || {};
      event.meta.isInefficientCast = true;
      event.meta.inefficientCastReason = `Use Vanish only when Find Weakness is not up or is about to run out.`;
    }
  }

  get vanishThresholds() {
    return {
      actual: this.badVanishCasts,
      isGreaterThan: {
        minor: 0,
        average: 0,
        major: 0,
      },
      style: 'number',
    };
  }

  suggestions(when) {
    when(this.vanishThresholds)
      .addSuggestion((suggest, actual, recommended) => suggest(<>Use <SpellLink id={SPELLS.VANISH.id} /> only when you do not have <SpellLink id={SPELLS.FIND_WEAKNESS_TALENT.id} /> applied to your target </>)
        .icon(SPELLS.VANISH.icon)
        .actual(i18n._(t('rogue.subtlety.suggestions.findWeakness.alreadyApplied')`You used Vanish ${this.badVanishCasts} times when Find Weakness was already applied`))
        .recommended(`${recommended} is recommended`));
  }

  statistic() {
    const uptime = this.enemies.getBuffUptime(SPELLS.FIND_WEAKNESS.id) / this.owner.fightDuration;
    return (
      <StatisticBox
        position={STATISTIC_ORDER.OPTIONAL(40)}
        icon={<SpellIcon id={SPELLS.FIND_WEAKNESS.id} />}
        value={`${formatPercentage(uptime)} %`}
        label={`${SPELLS.FIND_WEAKNESS.name} uptime`}
      />
    );
  }
}

export default FindWeakness;
<|endoftext|>