<commit_before>
// Inspired by the Boost Graph Library (BGL)
// http://www.boost.org/doc/libs/1_55_0/libs/graph/doc/index.html
// http://en.wikipedia.org/wiki/Directed_graph

(function() {

    var DirectedGraph = (function() {

        function DirectedGraph() {
            var _this = this;
            // These are implementation details of the digraph container.
            // Prefer prototype methods over direct access and coupling to these details.
            this.vertexMap = {};
            this.rootMap = {};
            this.leafMap = {};
            this.edgeCount = 0;
        }

        DirectedGraph.prototype.import = function(json){
            if(typeof json === "string"){
                try{
                    json = JSON.parse(json);
                }catch(e){
                    throw new Error("Invalid import JSON string");
                }
            }
            this.vertexMap = json.vertexMap;
            this.rootMap = json.rootMap;
            this.leafMap = json.leafMap;
            this.edgeCount = json.edgeCount;
        };

        DirectedGraph.prototype.export = function(){
            return JSON.stringify({
                vertexMap: this.vertexMap,
                rootMap: this.rootMap,
                leafMap: this.leafMap,
                edgeCount: this.edgeCount
            });
        };

        DirectedGraph.prototype.type = "directed";

        DirectedGraph.prototype.getRootVertices = function() {
            var rootVertices = [];
            for (var vertexId in this.rootMap) {
                rootVertices.push(vertexId);
            }
            return rootVertices;
        };

        DirectedGraph.prototype.getLeafVertices = function() {
            var leafVertices = [];
            for (var vertexId in this.leafMap) {
                leafVertices.push(vertexId);
            }
            return leafVertices;
        };

        DirectedGraph.prototype.addVertex = function (vertexId_, properties_) {
            if ((vertexId_ === null) || !vertexId_) {
                throw new Error("Missing required input parameter.");
            }
            var vertex = this.vertexMap[vertexId_];
            if ((vertex === null) || !vertex) {
                vertex = this.vertexMap[vertexId_] = {};
                vertex.edges = {};
                vertex.edges.in = {};
                vertex.edges.out = {};
                vertex.properties = properties_;
                this.rootMap[vertexId_] = {};
                this.leafMap[vertexId_] = {};
            }
            return vertexId_;
        };

        DirectedGraph.prototype.removeVertex = function (vertexId_) {
            if ((vertexId_ === null) || !vertexId_) {
                throw new Error("Missing required input parameter.");
            }
            var vertexU = this.vertexMap[vertexId_];
            if ((vertexU === null) || !vertexU) {
                return true;
            }
            var vertexIdX;
            for (vertexIdX in vertexU.edges.out) {
                this.removeEdge(vertexId_, vertexIdX);
            }
            for (vertexIdX in vertexU.edges.in) {
                this.removeEdge(vertexIdX, vertexId_);
            }
            delete this.vertexMap[vertexId_];
            delete this.rootMap[vertexId_];
            delete this.leafMap[vertexId_];
            return true;
        };

        DirectedGraph.prototype.addEdge = function (vertexIdU_, vertexIdV_, properties_) {
            var vertexU = this.addVertex(vertexIdU_);
            var vertexV = this.addVertex(vertexIdV_);
            var outEdge = this.vertexMap[vertexU].edges.out[vertexIdV_];
            if ((outEdge === null) || !outEdge) {
                outEdge = this.vertexMap[vertexU].edges.out[vertexIdV_] = {};
                outEdge.properties = properties_;
                delete this.leafMap[vertexIdU_];
            }
            var inEdge = this.vertexMap[vertexV].edges.in[vertexIdU_];
            if ((inEdge === null) || !inEdge) {
                inEdge = this.vertexMap[vertexV].edges.in[vertexIdU_] = {};
                this.edgeCount++;
                delete this.rootMap[vertexIdV_];
            }
            return { u: vertexU, v: vertexV };
        };

        DirectedGraph.prototype.removeEdge = function(vertexIdU_, vertexIdV_) {
            var outEdgeMap = this.vertexMap[vertexIdU_].edges.out;
            delete outEdgeMap[vertexIdV_];
            if (!Object.keys(outEdgeMap).length) {
                this.leafMap[vertexIdU_] = {};
            }
            var inEdgeMap = this.vertexMap[vertexIdV_].edges.in;
            delete inEdgeMap[vertexIdU_];
            if (!Object.keys(inEdgeMap).length) {
                this.rootMap[vertexIdV_] = {};
            }
            if (this.edgeCount) {
                this.edgeCount--;
            }
            return true;
        };

        DirectedGraph.prototype.verticesCount = function() {
            return Object.keys(this.vertexMap).length;
        };

        DirectedGraph.prototype.edgesCount = function() {
            return this.edgeCount;
        };

        DirectedGraph.prototype.inEdges = function(vertexId_) {
            var result = [];
            var vertexIdV;
            for (vertexIdV in this.vertexMap[vertexId_].edges.in) {
                result.push({ u: vertexIdV, v: vertexId_});
            }
            return result;
        };

        DirectedGraph.prototype.outEdges = function(vertexId_) {
            var result = [];
            var vertexIdV;
            for (vertexIdV in this.vertexMap[vertexId_].edges.out) {
                result.push({ u: vertexId_, v: vertexIdV});
            }
            return result;
        };

        DirectedGraph.prototype.inDegree = function (vertexId_) {
            return Object.keys(this.vertexMap[vertexId_].edges.in).length;
        };

        DirectedGraph.prototype.outDegree = function (vertexId_) {
            return Object.keys(this.vertexMap[vertexId_].edges.out).length;
        };

        DirectedGraph.prototype.vertexPropertyObject = function(vertexId_) {
            return this.vertexMap[vertexId_].properties;
        };

        DirectedGraph.prototype.edgePropertyObject = function(vertexIdU_, vertexIdV_) {
            return this.vertexMap[vertexIdU_].edges.out[vertexIdV_].properties;
        };

        return DirectedGraph;

    })();

    module.exports = DirectedGraph;

})();<commit_msg>Stash some tinkering w/Alec's pull request.<commit_after>
// Inspired by the Boost Graph Library (BGL)
// http://www.boost.org/doc/libs/1_55_0/libs/graph/doc/index.html
// http://en.wikipedia.org/wiki/Directed_graph

(function() {

    var DirectedGraph = (function() {

        function DirectedGraph(json_) {
            var _this = this;

            // These are implementation details of the digraph container.
            // Please use prototype methods where possible to maintain this encapsulation
            // and disuade clients from taking a direct dependency on these details.
            //
            // TODO: Update this JSON I/O contract to onm v0.3 when stable.
            //
            if ( (json_ !== null) && json_ && (Object.prototype.toString.call(json_) === '[object String]') ) {
                try {
                    // This really isn't all that great.
                    this.state = JSON.parse(json_);
                } catch (exception_) {
                    throw new Error("jsgraph.DirectedGraph constructor failed: Invalid JSON input specified.");
                }
            } else {
                this.state = {
                    vertexMap: {},
                    rootMap: {},
                    leafMap: {},
                    edgeCount: 0
                };
            }

            this.vertexMap = {};
            this.rootMap = {};
            this.leafMap = {};
            this.edgeCount = 0;
        }

        DirectedGraph.prototype.type = "directed";

        DirectedGraph.prototype.getRootVertices = function() {
            var rootVertices = [];
            for (var vertexId in this.rootMap) {
                rootVertices.push(vertexId);
            }
            return rootVertices;
        };

        DirectedGraph.prototype.getLeafVertices = function() {
            var leafVertices = [];
            for (var vertexId in this.leafMap) {
                leafVertices.push(vertexId);
            }
            return leafVertices;
        };

        DirectedGraph.prototype.addVertex = function (vertexId_, properties_) {
            if ((vertexId_ === null) || !vertexId_) {
                throw new Error("Missing required input parameter.");
            }
            var vertex = this.vertexMap[vertexId_];
            if ((vertex === null) || !vertex) {
                vertex = this.vertexMap[vertexId_] = {};
                vertex.edges = {};
                vertex.edges.in = {};
                vertex.edges.out = {};
                vertex.properties = properties_;
                this.rootMap[vertexId_] = {};
                this.leafMap[vertexId_] = {};
            }
            return vertexId_;
        };

        DirectedGraph.prototype.removeVertex = function (vertexId_) {
            if ((vertexId_ === null) || !vertexId_) {
                throw new Error("Missing required input parameter.");
            }
            var vertexU = this.vertexMap[vertexId_];
            if ((vertexU === null) || !vertexU) {
                return true;
            }
            var vertexIdX;
            for (vertexIdX in vertexU.edges.out) {
                this.removeEdge(vertexId_, vertexIdX);
            }
            for (vertexIdX in vertexU.edges.in) {
                this.removeEdge(vertexIdX, vertexId_);
            }
            delete this.vertexMap[vertexId_];
            delete this.rootMap[vertexId_];
            delete this.leafMap[vertexId_];
            return true;
        };

        DirectedGraph.prototype.addEdge = function (vertexIdU_, vertexIdV_, properties_) {
            var vertexU = this.addVertex(vertexIdU_);
            var vertexV = this.addVertex(vertexIdV_);
            var outEdge = this.vertexMap[vertexU].edges.out[vertexIdV_];
            if ((outEdge === null) || !outEdge) {
                outEdge = this.vertexMap[vertexU].edges.out[vertexIdV_] = {};
                outEdge.properties = properties_;
                delete this.leafMap[vertexIdU_];
            }
            var inEdge = this.vertexMap[vertexV].edges.in[vertexIdU_];
            if ((inEdge === null) || !inEdge) {
                inEdge = this.vertexMap[vertexV].edges.in[vertexIdU_] = {};
                this.edgeCount++;
                delete this.rootMap[vertexIdV_];
            }
            return { u: vertexU, v: vertexV };
        };

        DirectedGraph.prototype.removeEdge = function(vertexIdU_, vertexIdV_) {
            var outEdgeMap = this.vertexMap[vertexIdU_].edges.out;
            delete outEdgeMap[vertexIdV_];
            if (!Object.keys(outEdgeMap).length) {
                this.leafMap[vertexIdU_] = {};
            }
            var inEdgeMap = this.vertexMap[vertexIdV_].edges.in;
            delete inEdgeMap[vertexIdU_];
            if (!Object.keys(inEdgeMap).length) {
                this.rootMap[vertexIdV_] = {};
            }
            if (this.edgeCount) {
                this.edgeCount--;
            }
            return true;
        };

        DirectedGraph.prototype.verticesCount = function() {
            return Object.keys(this.vertexMap).length;
        };

        DirectedGraph.prototype.edgesCount = function() {
            return this.edgeCount;
        };

        DirectedGraph.prototype.inEdges = function(vertexId_) {
            var result = [];
            var vertexIdV;
            for (vertexIdV in this.vertexMap[vertexId_].edges.in) {
                result.push({ u: vertexIdV, v: vertexId_});
            }
            return result;
        };

        DirectedGraph.prototype.outEdges = function(vertexId_) {
            var result = [];
            var vertexIdV;
            for (vertexIdV in this.vertexMap[vertexId_].edges.out) {
                result.push({ u: vertexId_, v: vertexIdV});
            }
            return result;
        };

        DirectedGraph.prototype.inDegree = function (vertexId_) {
            return Object.keys(this.vertexMap[vertexId_].edges.in).length;
        };

        DirectedGraph.prototype.outDegree = function (vertexId_) {
            return Object.keys(this.vertexMap[vertexId_].edges.out).length;
        };

        DirectedGraph.prototype.vertexPropertyObject = function(vertexId_) {
            return this.vertexMap[vertexId_].properties;
        };

        DirectedGraph.prototype.edgePropertyObject = function(vertexIdU_, vertexIdV_) {
            return this.vertexMap[vertexIdU_].edges.out[vertexIdV_].properties;
        };

        DirectedGraph.prototype.toJSON = function(replacer_, space_) {
            return JSON.stringify(this.state, replacer_, space_);
        };

        return DirectedGraph;

    })();

    module.exports = DirectedGraph;

})();
{'fraction_non_alphanumeric': 0.1097848399604653, 'fraction_numerical': 0.000988367672774272, 'mean_word_length': 1.6078509119746234, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '4067810', 'n_tokens_mistral': 3555, 'n_tokens_neox': 3416, 'n_words': 652}