<commit_before>var Graph = Class.create({

    initialize: function() {
        this.hoverModeZones = editor.getPaper().set();
        this._placeHolderNodes = [];
        this._partnershipNodes = [];
        this._pregnancyNodes = [];
        this._personGroupNodes = [];
        this._personNodes = [];
        this.idCount = 1;

        var w = editor.getWorkspace().getWidth();
        var h = editor.getWorkspace().getHeight();
        this._proband = this.addPerson(w/2, h/2, 'M', this.generateID());

        this._currentHoveredNode = null;
        this._currentDraggable = null;
    },

    getCurrentHoveredNode: function() {
        return this._currentHoveredNode;
    },

    setCurrentHoveredNode: function(node) {
        this._currentHoveredNode = node;
    },

    getCurrentDraggable: function() {
        return this._currentDraggable;
    },

    setCurrentDraggable: function(draggable) {
        this._currentDraggable = draggable;
    },

    generateID: function() {
        return this.idCount++;
    },

    getProband: function() {
        return this._proband;
    },

    addPartnership : function(x, y, node1, node2) {
        var partnership = new Partnership(x, y, node1, node2);
        editor.getNodeIndex()._addNode(partnership, true);
        this._partnershipNodes.push(partnership);
        return partnership;
    },

    removePartnership: function(partnership) {
        this._partnershipNodes = this._partnershipNodes.without(partnership);
    },

    getPregnancyNodes: function() {
        return this._pregnancyNodes;
    },

    getPersonNodes: function() {
        return this._personNodes;
    },

    getPlaceHolderNodes: function() {
        return this._placeHolderNodes;
    },

    getPartnershipNodes: function() {
        return this._partnershipNodes;
    },

    getPersonGroupNodes: function() {
        return this._personGroupNodes;
    },

    addPerson: function(x, y, gender, id) {
        var isProband = this.getPersonNodes().length == 0;
        if(!isProband) {
        }
        var node = new Person(x, y, gender, id, isProband);
        this.getPersonNodes().push(node);
        editor.getNodeIndex()._addNode(node, true);
        return node;
    },

    removePerson: function(person) {
        this._personNodes = this._personNodes.without(person);
    },

    addPlaceHolder: function(x, y, gender, id) {
        var node = new PlaceHolder(x, y, gender, id);
        this.getPlaceHolderNodes().push(node);
        editor.getNodeIndex()._addNode(node, true);
        return node;
    },

    removePlaceHolder: function(placeholder) {
        this._placeHolderNodes = this._placeHolderNodes.without(placeholder);
    },

    addPersonGroup: function(x, y, id) {
        var node = new PersonGroup(x, y, id);
        this.getPersonGroupNodes().push(node);
        editor.getNodeIndex()._addNode(node, true);
        return node;
    },

    removePersonGroup: function(groupNode) {
        this._personGroupNodes = this._personGroupNodes.without(groupNode);
    },

    addPregnancy: function(x, y, partnership, id) {
        var node = new Pregnancy(x, y, partnership, id);
        this.getPregnancyNodes().push(node);
        editor.getNodeIndex()._addNode(node, true);
        return node;
    },

    removePregnancy: function(pregnancy) {
        this._pregnancyNodes = this._pregnancyNodes.without(pregnancy);
    },

    // HOVER MODE
    enterHoverMode: function(sourceNode, hoverTypes) {
        if(this.getCurrentDraggable().getType() == "parent") {
            this.getPartnershipNodes().each(function(partnershipBubble) {
                partnershipBubble.getGraphics().grow();
            })
        }
        var me = this,
            color,
            hoverNodes = [];
        hoverTypes.each(function(type) {
            hoverNodes = hoverNodes.concat(me["get" + type + "Nodes"]())
        });
        hoverNodes.without(sourceNode).each(function(node) {
            var hoverModeZone = node.getGraphics().getHoverBox().getHoverZoneMask().clone().toFront();
            hoverModeZone.attr("cursor", "pointer");
            hoverModeZone.hover(
                function() {
                    me._currentHoveredNode = node;
                    node.getGraphics().getHoverBox().setHovered(true);
                    node.getGraphics().getHoverBox().getBoxOnHover().attr(editor.attributes.boxOnHover);

                    if(me.getCurrentDraggable().getType() == 'PlaceHolder' && me.getCurrentDraggable().canMergeWith(node)) {
                        me.getCurrentDraggable().validHoveredNode = node;
                        color = "green";
                    }
                    else if(me.getCurrentDraggable().getType() == "partner" && sourceNode.canPartnerWith(node)) {
                        node.validPartnerSelected = true;
                        color = "green";
                    }
                    else if(me.getCurrentDraggable().getType() == "child" && sourceNode.canBeParentOf(node)) {
                        node.validChildSelected = true;
                        color = "green";
                    }
                    else if(me.getCurrentDraggable().getType() == "parent" && node.canBeParentOf(sourceNode)) {
                        if(node.getType() == 'Person') {
                            node.validParentSelected = true;
                        }
                        else {
                            node.validParentsSelected = true;
                        }
                        color = "green";
                    }
                    else {
                        color = "red";
                    }
                    node.getGraphics().getHoverBox().getBoxOnHover().attr("fill", color);
                },
                function() {
                    me.getCurrentDraggable() && (me.getCurrentDraggable().validHoveredNode = null);
                    node.getGraphics().getHoverBox().setHovered(false);
                    node.getGraphics().getHoverBox().getBoxOnHover().attr(editor.attributes.boxOnHover).attr('opacity', 0);
                    me._currentHoveredNode = null;
                    node.validPartnerSelected = node.validChildSelected =  node.validParentSelected = node.validParentsSelected = false;
                });
            me.hoverModeZones.push(hoverModeZone);
        });
    },

    exitHoverMode: function() {
        this.hoverModeZones.remove();
        this.getPartnershipNodes().each(function(partnership) {
            partnership.getGraphics().area && partnership.getGraphics().area.remove();
        });
    }
});<commit_msg>added NodeMap to track existing nodes<commit_after>var Graph = Class.create({

    initialize: function() {
        this.hoverModeZones = editor.getPaper().set();
        this._placeHolderNodes = [];
        this._partnershipNodes = [];
        this._pregnancyNodes = [];
        this._personGroupNodes = [];
        this._personNodes = [];
        this.idCount = 1;
        this._nodeMap = {};

        var w = editor.getWorkspace().getWidth();
        var h = editor.getWorkspace().getHeight();
        this._proband = this.addPerson(w/2, h/2, 'M', this.generateID());

        this._currentHoveredNode = null;
        this._currentDraggable = null;
    },

    getNodeMap: function() {
        return this._nodeMap;
    },

    getCurrentHoveredNode: function() {
        return this._currentHoveredNode;
    },

    setCurrentHoveredNode: function(node) {
        this._currentHoveredNode = node;
    },

    getCurrentDraggable: function() {
        return this._currentDraggable;
    },

    setCurrentDraggable: function(draggable) {
        this._currentDraggable = draggable;
    },

    generateID: function() {
        return this.idCount++;
    },

    getProband: function() {
        return this._proband;
    },

    addPartnership : function(x, y, node1, node2, id) {
        var partnership = new Partnership(x, y, node1, node2, id);
        this.getNodeMap()[partnership.getID()] = partnership;
        editor.getNodeIndex()._addNode(partnership, true);
        this._partnershipNodes.push(partnership);
        return partnership;
    },

    removePartnership: function(partnership) {
        this._partnershipNodes = this._partnershipNodes.without(partnership);
    },

    getPregnancyNodes: function() {
        return this._pregnancyNodes;
    },

    getPersonNodes: function() {
        return this._personNodes;
    },

    getPlaceHolderNodes: function() {
        return this._placeHolderNodes;
    },

    getPartnershipNodes: function() {
        return this._partnershipNodes;
    },

    getPersonGroupNodes: function() {
        return this._personGroupNodes;
    },

    addPerson: function(x, y, gender, id) {
        var isProband = this.getPersonNodes().length == 0;
        if(!isProband) {
        }
        var node = new Person(x, y, gender, id, isProband);
        this.getPersonNodes().push(node);
        this.getNodeMap()[node.getID()] = node;
        editor.getNodeIndex()._addNode(node, true);
        return node;
    },

    removePerson: function(person) {
        this._personNodes = this._personNodes.without(person);
    },

    addPlaceHolder: function(x, y, gender, id) {
        var node = new PlaceHolder(x, y, gender, id);
        this.getPlaceHolderNodes().push(node);
        this.getNodeMap()[node.getID()] = node;
        editor.getNodeIndex()._addNode(node, true);
        return node;
    },

    removePlaceHolder: function(placeholder) {
        this._placeHolderNodes = this._placeHolderNodes.without(placeholder);
    },

    addPersonGroup: function(x, y, id) {
        var node = new PersonGroup(x, y, id);
        this.getPersonGroupNodes().push(node);
        this.getNodeMap()[node.getID()] = node;
        editor.getNodeIndex()._addNode(node, true);
        return node;
    },

    removePersonGroup: function(groupNode) {
        this._personGroupNodes = this._personGroupNodes.without(groupNode);
    },

    addPregnancy: function(x, y, partnership, id) {
        var node = new Pregnancy(x, y, partnership, id);
        this.getPregnancyNodes().push(node);
        this.getNodeMap()[node.getID()] = node;
        editor.getNodeIndex()._addNode(node, true);
        return node;
    },

    removePregnancy: function(pregnancy) {
        this._pregnancyNodes = this._pregnancyNodes.without(pregnancy);
    },

    // HOVER MODE
    enterHoverMode: function(sourceNode, hoverTypes) {
        if(this.getCurrentDraggable().getType() == "parent") {
            this.getPartnershipNodes().each(function(partnershipBubble) {
                partnershipBubble.getGraphics().grow();
            })
        }
        var me = this,
            color,
            hoverNodes = [];
        hoverTypes.each(function(type) {
            hoverNodes = hoverNodes.concat(me["get" + type + "Nodes"]())
        });
        hoverNodes.without(sourceNode).each(function(node) {
            var hoverModeZone = node.getGraphics().getHoverBox().getHoverZoneMask().clone().toFront();
            hoverModeZone.attr("cursor", "pointer");
            hoverModeZone.hover(
                function() {
                    me._currentHoveredNode = node;
                    node.getGraphics().getHoverBox().setHovered(true);
                    node.getGraphics().getHoverBox().getBoxOnHover().attr(editor.attributes.boxOnHover);

                    if(me.getCurrentDraggable().getType() == 'PlaceHolder' && me.getCurrentDraggable().canMergeWith(node)) {
                        me.getCurrentDraggable().validHoveredNode = node;
                        color = "green";
                    }
                    else if(me.getCurrentDraggable().getType() == "partner" && sourceNode.canPartnerWith(node)) {
                        node.validPartnerSelected = true;
                        color = "green";
                    }
                    else if(me.getCurrentDraggable().getType() == "child" && sourceNode.canBeParentOf(node)) {
                        node.validChildSelected = true;
                        color = "green";
                    }
                    else if(me.getCurrentDraggable().getType() == "parent" && node.canBeParentOf(sourceNode)) {
                        if(node.getType() == 'Person') {
                            node.validParentSelected = true;
                        }
                        else {
                            node.validParentsSelected = true;
                        }
                        color = "green";
                    }
                    else {
                        color = "red";
                    }
                    node.getGraphics().getHoverBox().getBoxOnHover().attr("fill", color);
                },
                function() {
                    me.getCurrentDraggable() && (me.getCurrentDraggable().validHoveredNode = null);
                    node.getGraphics().getHoverBox().setHovered(false);
                    node.getGraphics().getHoverBox().getBoxOnHover().attr(editor.attributes.boxOnHover).attr('opacity', 0);
                    me._currentHoveredNode = null;
                    node.validPartnerSelected = node.validChildSelected =  node.validParentSelected = node.validParentsSelected = false;
                });
            me.hoverModeZones.push(hoverModeZone);
        });
    },

    exitHoverMode: function() {
        this.hoverModeZones.remove();
        this.getPartnershipNodes().each(function(partnership) {
            partnership.getGraphics().area && partnership.getGraphics().area.remove();
        });
    }
});
{'fraction_non_alphanumeric': 0.12372270822612659, 'fraction_numerical': 0.0013232375211350436, 'mean_word_length': 2.0037535879885184, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '3324748', 'n_tokens_mistral': 3770, 'n_tokens_neox': 3626, 'n_words': 572}