<commit_before>iD.Map = function() {
    var connection, history,
        dimensions = [],
        dispatch = d3.dispatch('move'),
        selection = null, hover = null,
        translateStart,
        keybinding,
        projection = d3.geo.mercator(),
        zoom = d3.behavior.zoom()
            .translate(projection.translate())
            .scale(projection.scale())
            .scaleExtent([1024, 256 * Math.pow(2, 24)])
            .on('zoom', zoomPan),
        dblclickEnabled = true,
        dragEnabled = true,
        dragging,
        dragbehavior = d3.behavior.drag()
            .origin(function(entity) {
                if (!dragEnabled) return { x: 0, y: 0 };
                var p = projection(entity.loc);
                return { x: p[0], y: p[1] };
            })
            .on('drag', function(entity) {
                d3.event.sourceEvent.stopPropagation();

                if (!dragging) {
                    if (entity.accuracy) {
                        var way = history.graph().entity(entity.way),
                            index = entity.index;
                        entity = iD.Node(entity);
                        history.perform(iD.actions.AddWayNode(way, entity, index));
                    }

                    dragging = iD.util.trueObj([entity.id].concat(
                        _.pluck(history.graph().parentWays(entity.id), 'id')));
                    history.perform(iD.actions.Noop());
                }

                var to = projection.invert([d3.event.x, d3.event.y]);
                history.replace(iD.actions.Move(entity, to));
            })
            .on('dragend', function () {
                if (!dragEnabled || !dragging) return;
                dragging = undefined;
            }),
        background = iD.Background()
            .projection(projection)
            .scaleExtent([0, 20]),
        class_stroke = iD.Style.styleClasses('stroke'),
        class_fill = iD.Style.styleClasses('stroke'),
        class_area = iD.Style.styleClasses('area'),
        class_casing = iD.Style.styleClasses('casing'),
        transformProp = iD.util.prefixProperty('Transform'),
        support3d = (function() {
            // test for translate3d support. Based on https://gist.github.com/3794226 by lorenzopolidori and webinista
            var el = document.createElement('div'),
                has3d = false;
            document.body.insertBefore(el,null);
            if (el.style[transformProp] !== undefined) {
                el.style[transformProp] = 'translate3d(1px,1px,1px)';
                has3d = window.getComputedStyle(el).getPropertyValue(transformProp);
            }
            document.body.removeChild(el);
            return (has3d && has3d.length>0 && has3d!=="none");
        })(),
        supersurface, surface, defs, tilegroup, r, g, alength;

    function map() {
        supersurface = this.append('div').call(zoom);

        surface = supersurface.append('svg')
            .on('mouseup', resetTransform)
            .on('touchend', resetTransform);

        defs = surface.append('defs');
        defs.append('clipPath')
                .attr('id', 'clip')
            .append('rect')
                .attr('id', 'clip-rect')
                .attr({ x: 0, y: 0 });

        tilegroup = surface.append('g')
            .attr('id', 'tile-g')
            .attr('clip-path', 'url(#clip)');

        r = surface.append('g')
            .on('mouseover', hoverIn)
            .on('mouseout', hoverOut)
            .attr('clip-path', 'url(#clip)');

        g = ['fill', 'casing', 'stroke', 'text', 'hit', 'temp'].reduce(function(mem, i) {
            return (mem[i] = r.append('g').attr('class', 'layer-g')) && mem;
        }, {});

        var arrow = surface.append('text').text('►----');
        alength = arrow.node().getComputedTextLength();
        arrow.remove();

        map.size(this.size());
        map.surface = surface;
    }

    function pxCenter() { return [dimensions[0] / 2, dimensions[1] / 2]; }
    function classHover(d) { return d.id === hover; }
    function classActive(d) { return d.id === selection; }
    function getline(d) { return d._line; }
    function key(d) { return d.id; }
    function nodeline(d) {
        return 'M' + _.pluck(d.nodes, 'loc').map(projection).map(iD.util.geo.roundCoords).join('L');
    }

    function drawVector(only) {
        if (surface.style(transformProp) != 'none') return;
        var all = [], ways = [], areas = [], points = [], waynodes = [],
            extent = map.extent(),
            graph = history.graph();

        if (!only) {
            all = graph.intersects(extent);
        } else {
            for (var id in only) all.push(graph.fetch(id));
        }

        var filter = only ?
            function(d) { return only[d.id]; } : function() { return true; };

        if (all.length > 200000) return hideVector();

        for (var i = 0; i < all.length; i++) {
            var a = all[i];
            if (a.type === 'way') {
                a._line = nodeline(a);
                if (iD.Way.isArea(a)) areas.push(a);
                else ways.push(a);
            } else if (a._poi) {
                points.push(a);
            } else if (!a._poi && a.type === 'node' && a.intersects(extent)) {
                waynodes.push(a);
            }
        }
        var wayAccuracyHandles = ways.reduce(function(mem, w) {
            return mem.concat(accuracyHandles(w));
        }, []);
        drawHandles(waynodes, filter);
        drawAccuracyHandles(wayAccuracyHandles, filter);
        drawCasings(ways, filter);
        drawFills(areas, filter);
        drawStrokes(ways, filter);
        drawMarkers(points, filter);
    }

    function accuracyHandles(way) {
        var handles = [];
        for (var i = 0; i < way.nodes.length - 1; i++) {
            if (iD.util.geo.dist(way.nodes[i].loc, way.nodes[i + 1].loc) > 0.0001) {
                handles.push({
                    loc: iD.util.geo.interp(way.nodes[i].loc, way.nodes[i + 1].loc, 0.5),
                    way: way.id,
                    index: i + 1,
                    accuracy: true,
                    tags: { name: 'Improve way accuracy' }
                });
            }
        }
        return handles;
    }

    function drawHandles(waynodes, filter) {
        var handles = g.hit.selectAll('image.handle')
            .filter(filter)
            .data(waynodes, key);
        function olderOnTop(a, b) {
            return (+a.id.slice(1)) - (+b.id.slice(1));
        }
        handles.exit().remove();
        handles.enter().append('image')
            .attr({ width: 6, height: 6, 'class': 'handle', 'xlink:href': 'css/handle.png' })
            .call(dragbehavior);
        handles.attr('transform', function(entity) {
                var p = projection(entity.loc);
                return 'translate(' + [~~p[0], ~~p[1]] + ') translate(-3, -3) rotate(45, 3, 3)';
            })
            .classed('active', classActive)
            .sort(olderOnTop);
    }

    function drawAccuracyHandles(waynodes) {
        var handles = g.hit.selectAll('circle.accuracy-handle')
            .data(waynodes, key);
        handles.exit().remove();
        handles.enter().append('circle')
            .attr({ r: 2, 'class': 'accuracy-handle' })
            .call(dragbehavior);
        handles.attr('transform', function(entity) {
            var p = projection(entity.loc);
            return 'translate(' + [~~p[0], ~~p[1]] + ')';
        }).classed('active', classActive);
    }

    function hideVector() {
        surface.selectAll('.layer-g *').remove();
    }

    function drawLines(data, filter, group, class_gen) {
        var lines = group.selectAll('path')
            .filter(filter)
            .data(data, key);
        lines.exit().remove();
        lines.enter().append('path')
            .classed('active', classActive);
        lines
            .order()
            .attr('d', getline)
            .attr('class', class_gen)
            .classed('active', classActive);
        return lines;
    }

    function drawFills(areas, filter) {
        drawLines(areas, filter, g.fill, class_area);
    }

    function drawCasings(ways, filter) {
        drawLines(ways, filter, g.casing, class_casing);
    }

    function drawMarkers(points, filter) {
        var markers = g.hit.selectAll('g.marker')
            .filter(filter)
            .data(points, key);
        markers.exit().remove();
        var marker = markers.enter().append('g')
            .attr('class', 'marker')
            .call(dragbehavior);
        marker.append('circle')
            .attr({ r: 10, cx: 8, cy: 8 });
        marker.append('image')<commit_msg>Fix hover<commit_after>iD.Map = function() {
    var connection, history,
        dimensions = [],
        dispatch = d3.dispatch('move'),
        selection = null, hover = null,
        translateStart,
        keybinding,
        projection = d3.geo.mercator(),
        zoom = d3.behavior.zoom()
            .translate(projection.translate())
            .scale(projection.scale())
            .scaleExtent([1024, 256 * Math.pow(2, 24)])
            .on('zoom', zoomPan),
        dblclickEnabled = true,
        dragEnabled = true,
        dragging,
        dragbehavior = d3.behavior.drag()
            .origin(function(entity) {
                if (!dragEnabled) return { x: 0, y: 0 };
                var p = projection(entity.loc);
                return { x: p[0], y: p[1] };
            })
            .on('drag', function(entity) {
                d3.event.sourceEvent.stopPropagation();

                if (!dragging) {
                    if (entity.accuracy) {
                        var way = history.graph().entity(entity.way),
                            index = entity.index;
                        entity = iD.Node(entity);
                        history.perform(iD.actions.AddWayNode(way, entity, index));
                    }

                    dragging = iD.util.trueObj([entity.id].concat(
                        _.pluck(history.graph().parentWays(entity.id), 'id')));
                    history.perform(iD.actions.Noop());
                }

                var to = projection.invert([d3.event.x, d3.event.y]);
                history.replace(iD.actions.Move(entity, to));
            })
            .on('dragend', function () {
                if (!dragEnabled || !dragging) return;
                dragging = undefined;
            }),
        background = iD.Background()
            .projection(projection)
            .scaleExtent([0, 20]),
        class_stroke = iD.Style.styleClasses('stroke'),
        class_fill = iD.Style.styleClasses('stroke'),
        class_area = iD.Style.styleClasses('area'),
        class_casing = iD.Style.styleClasses('casing'),
        transformProp = iD.util.prefixProperty('Transform'),
        support3d = (function() {
            // test for translate3d support. Based on https://gist.github.com/3794226 by lorenzopolidori and webinista
            var el = document.createElement('div'),
                has3d = false;
            document.body.insertBefore(el,null);
            if (el.style[transformProp] !== undefined) {
                el.style[transformProp] = 'translate3d(1px,1px,1px)';
                has3d = window.getComputedStyle(el).getPropertyValue(transformProp);
            }
            document.body.removeChild(el);
            return (has3d && has3d.length>0 && has3d!=="none");
        })(),
        supersurface, surface, defs, tilegroup, r, g, alength;

    function map() {
        supersurface = this.append('div').call(zoom);

        surface = supersurface.append('svg')
            .on('mouseup', resetTransform)
            .on('touchend', resetTransform);

        defs = surface.append('defs');
        defs.append('clipPath')
                .attr('id', 'clip')
            .append('rect')
                .attr('id', 'clip-rect')
                .attr({ x: 0, y: 0 });

        tilegroup = surface.append('g')
            .attr('id', 'tile-g')
            .attr('clip-path', 'url(#clip)');

        r = surface.append('g')
            .on('mouseover', hoverIn)
            .on('mouseout', hoverOut)
            .attr('clip-path', 'url(#clip)');

        g = ['fill', 'casing', 'stroke', 'text', 'hit', 'temp'].reduce(function(mem, i) {
            return (mem[i] = r.append('g').attr('class', 'layer-g')) && mem;
        }, {});

        var arrow = surface.append('text').text('►----');
        alength = arrow.node().getComputedTextLength();
        arrow.remove();

        map.size(this.size());
        map.surface = surface;
    }

    function pxCenter() { return [dimensions[0] / 2, dimensions[1] / 2]; }
    function classHover(d) { return d.id === hover; }
    function classActive(d) { return d.id === selection; }
    function getline(d) { return d._line; }
    function key(d) { return d.id; }
    function nodeline(d) {
        return 'M' + _.pluck(d.nodes, 'loc').map(projection).map(iD.util.geo.roundCoords).join('L');
    }

    function drawVector(only) {
        if (surface.style(transformProp) != 'none') return;
        var all = [], ways = [], areas = [], points = [], waynodes = [],
            extent = map.extent(),
            graph = history.graph();

        if (!only) {
            all = graph.intersects(extent);
        } else {
            for (var id in only) all.push(graph.fetch(id));
        }

        var filter = only ?
            function(d) { return only[d.id]; } : function() { return true; };

        if (all.length > 200000) return hideVector();

        for (var i = 0; i < all.length; i++) {
            var a = all[i];
            if (a.type === 'way') {
                a._line = nodeline(a);
                if (iD.Way.isArea(a)) areas.push(a);
                else ways.push(a);
            } else if (a._poi) {
                points.push(a);
            } else if (!a._poi && a.type === 'node' && a.intersects(extent)) {
                waynodes.push(a);
            }
        }
        var wayAccuracyHandles = ways.reduce(function(mem, w) {
            return mem.concat(accuracyHandles(w));
        }, []);
        drawHandles(waynodes, filter);
        drawAccuracyHandles(wayAccuracyHandles, filter);
        drawCasings(ways, filter);
        drawFills(areas, filter);
        drawStrokes(ways, filter);
        drawMarkers(points, filter);
    }

    function accuracyHandles(way) {
        var handles = [];
        for (var i = 0; i < way.nodes.length - 1; i++) {
            if (iD.util.geo.dist(way.nodes[i].loc, way.nodes[i + 1].loc) > 0.0001) {
                handles.push({
                    loc: iD.util.geo.interp(way.nodes[i].loc, way.nodes[i + 1].loc, 0.5),
                    way: way.id,
                    index: i + 1,
                    accuracy: true,
                    tags: { name: 'Improve way accuracy' }
                });
            }
        }
        return handles;
    }

    function drawHandles(waynodes, filter) {
        var handles = g.hit.selectAll('image.handle')
            .filter(filter)
            .data(waynodes, key);
        function olderOnTop(a, b) {
            return (+a.id.slice(1)) - (+b.id.slice(1));
        }
        handles.exit().remove();
        handles.enter().append('image')
            .attr({ width: 6, height: 6, 'class': 'handle', 'xlink:href': 'css/handle.png' })
            .call(dragbehavior);
        handles.attr('transform', function(entity) {
                var p = projection(entity.loc);
                return 'translate(' + [~~p[0], ~~p[1]] + ') translate(-3, -3) rotate(45, 3, 3)';
            })
            .classed('active', classActive)
            .sort(olderOnTop);
    }

    function drawAccuracyHandles(waynodes) {
        var handles = g.hit.selectAll('circle.accuracy-handle')
            .data(waynodes, key);
        handles.exit().remove();
        handles.enter().append('circle')
            .attr({ r: 2, 'class': 'accuracy-handle' })
            .call(dragbehavior);
        handles.attr('transform', function(entity) {
            var p = projection(entity.loc);
            return 'translate(' + [~~p[0], ~~p[1]] + ')';
        }).classed('active', classActive);
    }

    function hideVector() {
        surface.selectAll('.layer-g *').remove();
    }

    function drawLines(data, filter, group, class_gen) {
        var lines = group.selectAll('path')
            .filter(filter)
            .data(data, key);
        lines.exit().remove();
        lines.enter().append('path')
            .classed('hover', classHover)
            .classed('active', classActive);
        lines
            .order()
            .attr('d', getline)
            .attr('class', class_gen)
            .classed('hover', classHover)
            .classed('active', classActive);
        return lines;
    }

    function drawFills(areas, filter) {
        drawLines(areas, filter, g.fill, class_area);
    }

    function drawCasings(ways, filter) {
        drawLines(ways, filter, g.casing, class_casing);
    }

    function drawMarkers(points, filter) {
        var markers = g.hit.selectAll('g.marker')
            .filter(filter)
            .data(points, key);
        markers.exit().remove();
        var marker = markers.enter().append('g')
            .attr('class', 'marker')
            .call(dragbehavior);
        marker.append('circle')
            .attr({ r: 10, cx: 8, cy: 8 });
        marker.append('image')
{'fraction_non_alphanumeric': 0.1579007546306883, 'fraction_numerical': 0.00994740452778413, 'mean_word_length': 1.7273152478952292, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 2, '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': '2932731', 'n_tokens_mistral': 5340, 'n_tokens_neox': 5107, 'n_words': 990}