<commit_before>iD.Map = function() {
    var connection, history,
        dimensions = [],
        dispatch = d3.dispatch('move'),
        selection = null, hover = null,
        translateStart,
        keybinding = d3.keybinding(),
        projection = d3.geo.mercator().scale(1024),
        zoom = d3.behavior.zoom()
            .translate(projection.translate())
            .scale(projection.scale())
            .scaleExtent([1024, 256 * Math.pow(2, 24)])
            .on('zoom', zoomPan),
        dblclickEnabled = true,
        fastEnabled = true,
        notice,
        background = iD.Background()
            .projection(projection),
        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 = iD.util.support3d(),
        supersurface, surface, defs, tilegroup, r, g, alength;

    function map() {
        tilegroup = this.append('div')
            .attr('id', 'tile-g');

        supersurface = this.append('div')
            .style('position', 'absolute')
            .call(zoom);

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

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

        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 layer-' + i)) && mem;
        }, {});

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

        notice = iD.notice(supersurface
            .append('div')
            .attr('class', 'notice'));

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

        d3.select(document).call(keybinding);
    }

    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(difference) {
        if (surface.style(transformProp) != 'none') return;
        var filter, all, ways = [], lines = [], areas = [], points = [], waynodes = [],
            extent = map.extent(),
            graph = history.graph();

        if (!difference) {
            all = graph.intersects(extent);
            filter = d3.functor(true);
        } else {
            var only = {};
            difference.forEach(function (id) {
                only[id] = graph.fetch(id);
                graph.parentWays(id).forEach(function (parent) {
                    only[parent.id] = graph.fetch(parent.id);
                });
            });
            all = _.compact(_.values(only));
            filter = function(d) { return d.accuracy ? d.way in only : d.id in only; };
        }

        if (all.length > 10000) return editOff();
        else editOn();

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

    function hasTwoParents(d) { return parentStructure[d.id] > 1; }
    function drawHandles(waynodes, parentStructure, filter) {
        var handles = g.hit.selectAll('circle.handle')
            .filter(filter)
            .data(waynodes, key);

        handles.exit().remove();

        handles.enter().insert('circle', ':first-child')
            .attr({
                'class': 'handle'
            });

        handles.attr('transform', function(entity) {
                var p = projection(entity.loc);
                return 'translate(' + [~~p[0], ~~p[1]] +
                    ')';
            })
            .classed('active', classActive)
            .classed('two-parents', hasTwoParents)
            .classed('hover', classHover);

        handles.transition().duration(50).attr('r', function(d) {
                return d.id === hover ? 8: 4;
            });
    }

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

    function editOff() {
        notice.message('Zoom in to edit the map');
        surface.selectAll('.layer-g *').remove();
    }

    function editOn() {
        notice.message('');
    }

    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');
        marker.append('circle')
            .attr({ r: 10, cx: 8, cy: 8 });
        marker.append('image')
            .attr({ width: 16, height: 16 });
        markers.attr('transform', function(d) {
                var pt = projection(d.loc);
                return 'translate(' + [~~pt[0], ~~pt[1]] + ') translate(-8, -8)';
            })
            .classed('active', classActive);
        markers.classed('hover', classHover);
        markers.select('image').attr('xlink:href', iD.Style.markerimage);
    }

    function drawStrokes(ways, filter) {
        var strokes = drawLines(ways, filter, g.stroke, class_stroke);

        // Determine the lengths of oneway paths
        var lengths = {},
            oneways = strokes.filter(iD.Way.isOneWay).each(function(d) {
                lengths[d.id] = Math.floor(this.getTotalLength() / alength);
            }).data();

        var uses = defs.selectAll('path')
            .filter(filter)
            .data(oneways, key);
        uses.exit().remove();
        uses.enter().append('path');
        uses
            .attr('id', function(d) { return 'shadow-' + d.id; })
            .attr('d', getline);

        var labels = g.text.selectAll('text')
            .filter(filter)
            .data(oneways, key);
        labels.exit().remove();
        var tp = labels.enter()
            .append('text').attr({ 'class': 'oneway', dy: 4 })
            .append('textPath').attr('class', 'textpath');
        g.text.selectAll('.textpath')
            .filter(filter)
            .attr('xlink:href', function(d, i) { return '#shadow-' + d.id; })
            .text(function(d) {
                return (new Array(Math.floor(lengths[d.id]))).join('►----');
            });
    }

    function connectionLoad(err, result) {
        history.merge(result);
        redraw(Object.keys(result.entities));
    }

    function hoverIn() {
        var datum = d3.select(d3.event.target).datum();
        if (datum instanceof iD.Entity) {
            hover = datum.id;
            redraw([hover]);
            d3.select('.messages').text(datum.tags.name || '#' + datum.id);
        }
    }

    function hoverOut() {
        if (hover) {
            var oldHover = hover;
            hover = null;
            redraw([oldHover]);
            d3.select('.messages').text('');
        }
    }

    function zoomPan() {
        if (d3.event && d3.event.sourceEvent.type === 'dblclick') {
            if (!dblclickEnabled) {
                zoom.scale(projection.scale())
                    .translate(projection.translate());
                return d3.event.sourceEvent.preventDefault();
            }
        }
        var fast = (d3.event.scale === projection.scale() && fastEnabled);
        projection
            .translate(d3.event.translate)
            .scale(d3.event.scale);
        if (fast) {
            if (!translateStart) translateStart = d3.event.translate.slice();
            var a = d3.event.translate,
                b = translateStart;
            if (support3d) {
                tilegroup.style(transformProp,
                    'translate3d(' + ~~(a[0] - b[0]) + 'px,' + ~~(a[1] - b[1]) + 'px, 0px)');
                surface.style(transformProp,
                    'translate3d(' + ~~(a[0] - b[0]) + 'px,' + ~~(a[1] - b[1]) + 'px, 0px)');
            } else {
                tilegroup.style(transformProp,
                    'translate(' + ~~(a[0] - b[0]) + 'px,' + ~~(a[1] - b[1]) + 'px)');
                surface.style(transformProp,
                    'translate(' + ~~(a[0] - b[0]) + 'px,' + ~~(a[1] - b[1]) + 'px)');
            }
        } else {
            redraw();
            translateStart = null;
        }
    }

    function resetTransform() {
        if (!surface.style(transformProp)) return;
        translateStart = null;
        surface.style(transformProp, '');
        tilegroup.style(transformProp, '');
        redraw();
    }

    function redraw(difference) {
        dispatch.move(map);
        tilegroup.call(background);
        if (map.zoom() > 16) {
            connection.loadTiles(projection);
            drawVector(difference);
        } else {
            editOff();
        }
        return map;
    }

    function pointLocation(p) {
        var translate = projection.translate(),
            scale = projection.scale();
        return [(p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale];
    }

    function locationPoint(l) {
        var translate = projection.translate(),
            scale = projection.scale();
        return [l[0] * scale + translate[0], l[1] * scale + translate[1]];
    }

    map.mouseCoordinates = function() {
        return projection.invert(d3.mouse(surface.node()));
    };

    map.dblclickEnable = function(_) {
        if (!arguments.length) return dblclickEnabled;
        dblclickEnabled = _;
        return map;
    };

    map.fastEnable = function(_) {
        if (!arguments.length) return fastEnabled;
        fastEnabled = _;
        return map;
    };

    map.zoom = function(z) {
        if (!arguments.length) {
            return Math.max(Math.log(projection.scale()) / Math.LN2 - 8, 0);
        }
        var scale = 256 * Math.pow(2, z),
            center = pxCenter(),
            l = pointLocation(center);
        scale = Math.max(1024, Math.min(256 * Math.pow(2, 24), scale));
        projection.scale(scale);
        zoom.scale(projection.scale());
        var t = projection.translate();
        l = locationPoint(l);
        t[0] += center[0] - l[0];
        t[1] += center[1] - l[1];
        projection.translate(t);
        zoom.translate(projection.translate());
        return redraw();
    };

    map.size = function(_) {
        if (!arguments.length) return dimensions;
        dimensions = _;
        surface
            .size(dimensions)
            .selectAll('#clip-rect')
            .size(dimensions);
        background.size(dimensions);
        return redraw();
    };

    map.zoomIn = function() { return map.zoom(Math.ceil(map.zoom() + 1)); };
    map.zoomOut = function() { return map.zoom(Math.floor(map.zoom() - 1)); };

    map.center = function(loc) {
        if (!arguments.length) {
            return projection.invert(pxCenter());
        } else {
            var t = projection.translate(),
                c = pxCenter(),
                ll = projection(loc);
            projection.translate([
                t[0] - ll[0] + c[0],
                t[1] - ll[1] + c[1]]);
            zoom.translate(projection.translate());
            return redraw();
        }
    };

    map.extent = function() {
        return [projection.invert([0, 0]), projection.invert(dimensions)];
    };

    map.flush = function () {
        connection.flush();
        return map;
    };

    map.connection = function(_) {
        if (!arguments.length) return connection;
        connection = _;
        connection.on('load', connectionLoad);
        return map;
    };

    map.hint = function (_) {
        if (_ === false) {
            d3.select('div.inspector-wrap')
                .style('opacity', 0)
                .style('display', 'none');
        } else {
            d3.select('div.inspector-wrap')
                .html('')
                .style('display', 'block')
                .transition()
                .style('opacity', 1);
            d3.select('div.inspector-wrap')
                .append('div')
                .attr('class','inspector-inner')
                .text(_);
        }
    };

    map.history = function (_) {
        if (!arguments.length) return history;
        history = _;
        history.on('change.map', redraw);
        return map;
    };

    map.keybinding = function (_) {
        if (!arguments.length) return keybinding;
        keybinding = _;
        return map;
    };

    map.selection = function (_) {
        if (!arguments.length) return selection;
        selection = _;
        return redraw();
    };

    map.background = background;
    map.projection = projection;
    map.redraw = redraw;

    return d3.rebind(map, dispatch, 'on');
};
<commit_msg>Fix map<commit_after>iD.Map = function() {
    var connection, history,
        dimensions = [],
        dispatch = d3.dispatch('move'),
        selection = null, hover = null,
        translateStart,
        keybinding = d3.keybinding(),
        projection = d3.geo.mercator().scale(1024),
        zoom = d3.behavior.zoom()
            .translate(projection.translate())
            .scale(projection.scale())
            .scaleExtent([1024, 256 * Math.pow(2, 24)])
            .on('zoom', zoomPan),
        dblclickEnabled = true,
        fastEnabled = true,
        notice,
        background = iD.Background()
            .projection(projection),
        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 = iD.util.support3d(),
        supersurface, surface, defs, tilegroup, r, g, alength;

    function map() {
        tilegroup = this.append('div')
            .attr('id', 'tile-g');

        supersurface = this.append('div')
            .style('position', 'absolute')
            .call(zoom);

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

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

        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 layer-' + i)) && mem;
        }, {});

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

        notice = iD.notice(supersurface
            .append('div')
            .attr('class', 'notice'));

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

        d3.select(document).call(keybinding);
    }

    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(difference) {
        if (surface.style(transformProp) != 'none') return;
        var filter, all, ways = [], lines = [], areas = [], points = [], waynodes = [],
            extent = map.extent(),
            graph = history.graph();

        if (!difference) {
            all = graph.intersects(extent);
            filter = d3.functor(true);
        } else {
            var only = {};
            difference.forEach(function (id) {
                only[id] = graph.fetch(id);
                graph.parentWays(id).forEach(function (parent) {
                    only[parent.id] = graph.fetch(parent.id);
                });
            });
            all = _.compact(_.values(only));
            filter = function(d) { return d.accuracy ? d.way in only : d.id in only; };
        }

        if (all.length > 10000) return editOff();
        else editOn();

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

    function drawHandles(waynodes, parentStructure, filter) {
        function hasTwoParents(d) { return parentStructure[d.id] > 1; }

        var handles = g.hit.selectAll('circle.handle')
            .filter(filter)
            .data(waynodes, key);

        handles.exit().remove();

        handles.enter().insert('circle', ':first-child')
            .attr({
                'class': 'handle'
            });

        handles.attr('transform', function(entity) {
                var p = projection(entity.loc);
                return 'translate(' + [~~p[0], ~~p[1]] +
                    ')';
            })
            .classed('active', classActive)
            .classed('two-parents', hasTwoParents)
            .classed('hover', classHover);

        handles.transition().duration(50).attr('r', function(d) {
                return d.id === hover ? 8: 4;
            });
    }

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

    function editOff() {
        notice.message('Zoom in to edit the map');
        surface.selectAll('.layer-g *').remove();
    }

    function editOn() {
        notice.message('');
    }

    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');
        marker.append('circle')
            .attr({ r: 10, cx: 8, cy: 8 });
        marker.append('image')
            .attr({ width: 16, height: 16 });
        markers.attr('transform', function(d) {
                var pt = projection(d.loc);
                return 'translate(' + [~~pt[0], ~~pt[1]] + ') translate(-8, -8)';
            })
            .classed('active', classActive);
        markers.classed('hover', classHover);
        markers.select('image').attr('xlink:href', iD.Style.markerimage);
    }

    function drawStrokes(ways, filter) {
        var strokes = drawLines(ways, filter, g.stroke, class_stroke);

        // Determine the lengths of oneway paths
        var lengths = {},
            oneways = strokes.filter(iD.Way.isOneWay).each(function(d) {
                lengths[d.id] = Math.floor(this.getTotalLength() / alength);
            }).data();

        var uses = defs.selectAll('path')
            .filter(filter)
            .data(oneways, key);
        uses.exit().remove();
        uses.enter().append('path');
        uses
            .attr('id', function(d) { return 'shadow-' + d.id; })
            .attr('d', getline);

        var labels = g.text.selectAll('text')
            .filter(filter)
            .data(oneways, key);
        labels.exit().remove();
        var tp = labels.enter()
            .append('text').attr({ 'class': 'oneway', dy: 4 })
            .append('textPath').attr('class', 'textpath');
        g.text.selectAll('.textpath')
            .filter(filter)
            .attr('xlink:href', function(d, i) { return '#shadow-' + d.id; })
            .text(function(d) {
                return (new Array(Math.floor(lengths[d.id]))).join('►----');
            });
    }

    function connectionLoad(err, result) {
        history.merge(result);
        redraw(Object.keys(result.entities));
    }

    function hoverIn() {
        var datum = d3.select(d3.event.target).datum();
        if (datum instanceof iD.Entity) {
            hover = datum.id;
            redraw([hover]);
            d3.select('.messages').text(datum.tags.name || '#' + datum.id);
        }
    }

    function hoverOut() {
        if (hover) {
            var oldHover = hover;
            hover = null;
            redraw([oldHover]);
            d3.select('.messages').text('');
        }
    }

    function zoomPan() {
        if (d3.event && d3.event.sourceEvent.type === 'dblclick') {
            if (!dblclickEnabled) {
                zoom.scale(projection.scale())
                    .translate(projection.translate());
                return d3.event.sourceEvent.preventDefault();
            }
        }
        var fast = (d3.event.scale === projection.scale() && fastEnabled);
        projection
            .translate(d3.event.translate)
            .scale(d3.event.scale);
        if (fast) {
            if (!translateStart) translateStart = d3.event.translate.slice();
            var a = d3.event.translate,
                b = translateStart;
            if (support3d) {
                tilegroup.style(transformProp,
                    'translate3d(' + ~~(a[0] - b[0]) + 'px,' + ~~(a[1] - b[1]) + 'px, 0px)');
                surface.style(transformProp,
                    'translate3d(' + ~~(a[0] - b[0]) + 'px,' + ~~(a[1] - b[1]) + 'px, 0px)');
            } else {
                tilegroup.style(transformProp,
                    'translate(' + ~~(a[0] - b[0]) + 'px,' + ~~(a[1] - b[1]) + 'px)');
                surface.style(transformProp,
                    'translate(' + ~~(a[0] - b[0]) + 'px,' + ~~(a[1] - b[1]) + 'px)');
            }
        } else {
            redraw();
            translateStart = null;
        }
    }

    function resetTransform() {
        if (!surface.style(transformProp)) return;
        translateStart = null;
        surface.style(transformProp, '');
        tilegroup.style(transformProp, '');
        redraw();
    }

    function redraw(difference) {
        dispatch.move(map);
        tilegroup.call(background);
        if (map.zoom() > 16) {
            connection.loadTiles(projection);
            drawVector(difference);
        } else {
            editOff();
        }
        return map;
    }

    function pointLocation(p) {
        var translate = projection.translate(),
            scale = projection.scale();
        return [(p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale];
    }

    function locationPoint(l) {
        var translate = projection.translate(),
            scale = projection.scale();
        return [l[0] * scale + translate[0], l[1] * scale + translate[1]];
    }

    map.mouseCoordinates = function() {
        return projection.invert(d3.mouse(surface.node()));
    };

    map.dblclickEnable = function(_) {
        if (!arguments.length) return dblclickEnabled;
        dblclickEnabled = _;
        return map;
    };

    map.fastEnable = function(_) {
        if (!arguments.length) return fastEnabled;
        fastEnabled = _;
        return map;
    };

    map.zoom = function(z) {
        if (!arguments.length) {
            return Math.max(Math.log(projection.scale()) / Math.LN2 - 8, 0);
        }
        var scale = 256 * Math.pow(2, z),
            center = pxCenter(),
            l = pointLocation(center);
        scale = Math.max(1024, Math.min(256 * Math.pow(2, 24), scale));
        projection.scale(scale);
        zoom.scale(projection.scale());
        var t = projection.translate();
        l = locationPoint(l);
        t[0] += center[0] - l[0];
        t[1] += center[1] - l[1];
        projection.translate(t);
        zoom.translate(projection.translate());
        return redraw();
    };

    map.size = function(_) {
        if (!arguments.length) return dimensions;
        dimensions = _;
        surface
            .size(dimensions)
            .selectAll('#clip-rect')
            .size(dimensions);
        background.size(dimensions);
        return redraw();
    };

    map.zoomIn = function() { return map.zoom(Math.ceil(map.zoom() + 1)); };
    map.zoomOut = function() { return map.zoom(Math.floor(map.zoom() - 1)); };

    map.center = function(loc) {
        if (!arguments.length) {
            return projection.invert(pxCenter());
        } else {
            var t = projection.translate(),
                c = pxCenter(),
                ll = projection(loc);
            projection.translate([
                t[0] - ll[0] + c[0],
                t[1] - ll[1] + c[1]]);
            zoom.translate(projection.translate());
            return redraw();
        }
    };

    map.extent = function() {
        return [projection.invert([0, 0]), projection.invert(dimensions)];
    };

    map.flush = function () {
        connection.flush();
        return map;
    };

    map.connection = function(_) {
        if (!arguments.length) return connection;
        connection = _;
        connection.on('load', connectionLoad);
        return map;
    };

    map.hint = function (_) {
        if (_ === false) {
            d3.select('div.inspector-wrap')
                .style('opacity', 0)
                .style('display', 'none');
        } else {
            d3.select('div.inspector-wrap')
                .html('')
                .style('display', 'block')
                .transition()
                .style('opacity', 1);
            d3.select('div.inspector-wrap')
                .append('div')
                .attr('class','inspector-inner')
                .text(_);
        }
    };

    map.history = function (_) {
        if (!arguments.length) return history;
        history = _;
        history.on('change.map', redraw);
        return map;
    };

    map.keybinding = function (_) {
        if (!arguments.length) return keybinding;
        keybinding = _;
        return map;
    };

    map.selection = function (_) {
        if (!arguments.length) return selection;
        selection = _;
        return redraw();
    };

    map.background = background;
    map.projection = projection;
    map.redraw = redraw;

    return d3.rebind(map, dispatch, 'on');
};
<|endoftext|>


<commit_before>iD.svg.Vertices = function(projection, context) {
    var radiuses = {
        //       z16-, z17, z18+, tagged
        shadow: [6,    7.5,   7.5,  11.5],
        stroke: [2.5,  3.5,   3.5,  7],
        fill:   [1,    1.5,   1.5,  1.5]
    };

    var hover;

    function visibleVertices() {
        var visible = {};

        function addChildVertices(entity, klass) {
            var i;
            if (entity.type === 'way') {
                for (i = 0; i < entity.nodes.length; i++) {
                    visible[entity.nodes[i]] = klass;
                }
            } else if (entity.type === 'relation') {
                for (i = 0; i < entity.members.length; i++) {
                    var member = context.entity(entity.members[i].id);
                    if (member) {
                        addChildVertices(member, klass);
                    }
                }
            } else {
                visible[entity.id] = klass;
            }
        }

        function addSiblingAndChildVertices(id, klass) {
            var entity = context.entity(id);
            if (entity && entity.type === 'vertex') {
                visible[hover.id] = klass;
                context.parentWays(entity).forEach(function(entity) {
                    addChildVertices(entity, klass);
                });
            } else if (entity) {
                addChildVertices(entity, klass);
            }
        }

        if (hover) {
            addSiblingAndChildVertices(hover.id, 'vertex-hover');
        }

        context.selection().forEach(function(id) {
            addSiblingAndChildVertices(id, 'vertex-selected');
        });

        return visible;
    }

    function drawVertices(surface, graph, zoom) {
        var visible = visibleVertices();

        function rendered(entity) {
            if (entity.geometry(graph) !== 'vertex')
                return false;
            if (entity.id in visible)
                return true;
            if (entity.hasInterestingTags())
                return true;
        }

        var entities = context.intersects(context.map().extent()),
            vertices = [];

        for (var i = 0; i < entities.length; i++) {
            var entity = entities[i];
            if (rendered(entity)) {
                vertices.push(entity)
            }
        }

        var groups = surface.select('.layer-hit').selectAll('g.vertex')
            .data(vertices, iD.Entity.key);

        var group = groups.enter()
            .insert('g', ':first-child')
            .attr('class', 'node vertex');

        if (zoom < 17) {
            zoom = 0;
        } else if (zoom < 18) {
            zoom = 1;
        } else {
            zoom = 2;
        }

        group.append('circle')
            .attr('class', 'node vertex shadow');

        group.append('circle')
            .attr('class', 'node vertex stroke');

        groups.attr('transform', iD.svg.PointTransform(projection))
            .call(iD.svg.TagClasses())
            .call(iD.svg.MemberClasses(graph))
            .classed('vertex-hover', function(entity) { return visible[entity.id] === 'vertex-hover'; })
            .classed('vertex-selected', function(entity) { return visible[entity.id] === 'vertex-selected'; })
            .classed('tagged', function(entity) { return entity.hasInterestingTags(); })
            .classed('shared', function(entity) { return graph.isShared(entity); });

        function icon(entity) {
            return zoom !== 0 &&
                entity.hasInterestingTags() &&
                context.presets().match(entity, graph).icon;
        }

        function center(entity) {
            if (icon(entity)) {
                d3.select(this)
                    .attr('cx', 0.5)
                    .attr('cy', -0.5);
            } else {
                d3.select(this)
                    .attr('cy', 0)
                    .attr('cx', 0);
            }
        }

        groups.select('circle.shadow')
            .each(center)
            .attr('r', function(entity) {
                return radiuses.shadow[icon(entity) ? 3 : zoom];
            });

        groups.select('circle.stroke')
            .each(center)
            .attr('r', function(entity) {
                return radiuses.stroke[icon(entity) ? 3 : zoom];
            });

        // Each vertex gets either a circle or a use, depending
        // on if it has a icon or not.

        var fill = groups.selectAll('circle.fill')
            .data(function(entity) {
                return icon(entity) ? [] : [entity];
            }, iD.Entity.key);

        fill.enter().append('circle')
            .attr('class', 'node vertex fill')
            .each(center)
            .attr('r', radiuses.fill[zoom]);

        fill.exit()
            .remove();

        var use = groups.selectAll('use')
            .data(function(entity) {
                var i = icon(entity);
                return i ? [i] : [];
            }, function(d) {
                return d;
            });

        use.enter().append('use')
            .attr('transform', 'translate(-6, -6)')
            .attr('clip-path', 'url(#clip-square-12)')
            .attr('xlink:href', function(icon) { return '#maki-' + icon + '-12'; });

        use.exit()
            .remove();

        groups.exit()
            .remove();
    }

    drawVertices.hover = function(_) {
        if (!arguments.length) return hover;
        hover = _;
        return drawVertices;
    };

    return drawVertices;
};
<commit_msg>Fix child calculation<commit_after>iD.svg.Vertices = function(projection, context) {
    var radiuses = {
        //       z16-, z17, z18+, tagged
        shadow: [6,    7.5,   7.5,  11.5],
        stroke: [2.5,  3.5,   3.5,  7],
        fill:   [1,    1.5,   1.5,  1.5]
    };

    var hover;

    function visibleVertices() {
        var visible = {};

        function addChildVertices(entity, klass) {
            var i;
            if (entity.type === 'way') {
                for (i = 0; i < entity.nodes.length; i++) {
                    visible[entity.nodes[i]] = klass;
                }
            } else if (entity.type === 'relation') {
                for (i = 0; i < entity.members.length; i++) {
                    var member = context.entity(entity.members[i].id);
                    if (member) {
                        addChildVertices(member, klass);
                    }
                }
            } else {
                visible[entity.id] = klass;
            }
        }

        function addSiblingAndChildVertices(id, klass) {
            var entity = context.entity(id);
            if (entity && entity.type === 'node') {
                visible[entity.id] = klass;
                context.graph().parentWays(entity).forEach(function(entity) {
                    addChildVertices(entity, klass);
                });
            } else if (entity) {
                addChildVertices(entity, klass);
            }
        }

        if (hover) {
            addSiblingAndChildVertices(hover.id, 'vertex-hover');
        }

        context.selection().forEach(function(id) {
            addSiblingAndChildVertices(id, 'vertex-selected');
        });

        return visible;
    }

    function drawVertices(surface, graph, zoom) {
        var visible = visibleVertices();

        function rendered(entity) {
            if (entity.geometry(graph) !== 'vertex')
                return false;
            if (entity.id in visible)
                return true;
            if (entity.hasInterestingTags())
                return true;
        }

        var entities = context.intersects(context.map().extent()),
            vertices = [];

        for (var i = 0; i < entities.length; i++) {
            var entity = entities[i];
            if (rendered(entity)) {
                vertices.push(entity)
            }
        }

        var groups = surface.select('.layer-hit').selectAll('g.vertex')
            .data(vertices, iD.Entity.key);

        var group = groups.enter()
            .insert('g', ':first-child')
            .attr('class', 'node vertex');

        if (zoom < 17) {
            zoom = 0;
        } else if (zoom < 18) {
            zoom = 1;
        } else {
            zoom = 2;
        }

        group.append('circle')
            .attr('class', 'node vertex shadow');

        group.append('circle')
            .attr('class', 'node vertex stroke');

        groups.attr('transform', iD.svg.PointTransform(projection))
            .call(iD.svg.TagClasses())
            .call(iD.svg.MemberClasses(graph))
            .classed('vertex-hover', function(entity) { return visible[entity.id] === 'vertex-hover'; })
            .classed('vertex-selected', function(entity) { return visible[entity.id] === 'vertex-selected'; })
            .classed('tagged', function(entity) { return entity.hasInterestingTags(); })
            .classed('shared', function(entity) { return graph.isShared(entity); });

        function icon(entity) {
            return zoom !== 0 &&
                entity.hasInterestingTags() &&
                context.presets().match(entity, graph).icon;
        }

        function center(entity) {
            if (icon(entity)) {
                d3.select(this)
                    .attr('cx', 0.5)
                    .attr('cy', -0.5);
            } else {
                d3.select(this)
                    .attr('cy', 0)
                    .attr('cx', 0);
            }
        }

        groups.select('circle.shadow')
            .each(center)
            .attr('r', function(entity) {
                return radiuses.shadow[icon(entity) ? 3 : zoom];
            });

        groups.select('circle.stroke')
            .each(center)
            .attr('r', function(entity) {
                return radiuses.stroke[icon(entity) ? 3 : zoom];
            });

        // Each vertex gets either a circle or a use, depending
        // on if it has a icon or not.

        var fill = groups.selectAll('circle.fill')
            .data(function(entity) {
                return icon(entity) ? [] : [entity];
            }, iD.Entity.key);

        fill.enter().append('circle')
            .attr('class', 'node vertex fill')
            .each(center)
            .attr('r', radiuses.fill[zoom]);

        fill.exit()
            .remove();

        var use = groups.selectAll('use')
            .data(function(entity) {
                var i = icon(entity);
                return i ? [i] : [];
            }, function(d) {
                return d;
            });

        use.enter().append('use')
            .attr('transform', 'translate(-6, -6)')
            .attr('clip-path', 'url(#clip-square-12)')
            .attr('xlink:href', function(icon) { return '#maki-' + icon + '-12'; });

        use.exit()
            .remove();

        groups.exit()
            .remove();
    }

    drawVertices.hover = function(_) {
        if (!arguments.length) return hover;
        hover = _;
        return drawVertices;
    };

    return drawVertices;
};
<|endoftext|>


<commit_before>d3.combobox = function() {
    var event = d3.dispatch('accept'),
        id = d3.combobox.id ++,
        data = [];

    var fetcher = function(val, data, cb) {
        cb(data.filter(function(d) {
            return d.title
                .toString()
                .toLowerCase()
                .indexOf(val.toLowerCase()) !== -1;
        }));
    };

    var typeahead = function(input) {
        var idx = -1, container, shown = false;

        input
            .classed('combobox-input', true)
            .each(function() {
                var parent = this.parentNode,
                    sibling = this.nextSibling;
                d3.select(parent)
                    .insert('div', function() { return sibling; })
                    .attr('class', 'combobox-carat')
                    .on('mousedown', function () {
                        // prevent the form element from blurring. it blurs
                        // on mousedown
                        d3.event.stopPropagation();
                        d3.event.preventDefault();
                        mousedown();
                    });
            });

        function updateSize() {
            var rect = input.node().getBoundingClientRect();
            container.style({
                'left': rect.left + 'px',
                'width': rect.width + 'px',
                'top': rect.height + rect.top + 'px'
            });
        }

        function blur() {
            // hide the combobox whenever the input element
            // loses focus
            slowHide();
        }

        function show() {
            if (!shown) {
                container = d3.select(document.body)
                    .insert('div', ':first-child')
                    .attr('class', 'combobox')
                    .style({
                        position: 'absolute',
                        display: 'block',
                        left: '0px'
                    });

                shown = true;
            }
        }

        function hide() {
            if (shown) {
                idx = -1;
                container.remove();
                shown = false;
            }
        }

        function slowHide() {
            window.setTimeout(hide, 150);
        }
        function keydown() {
           if (!shown) return;
           switch (d3.event.keyCode) {
               // down arrow
               case 40:
                   next();
                   d3.event.preventDefault();
                   break;
               // up arrow
               case 38:
                   prev();
                   d3.event.preventDefault();
                   break;
               // escape, tab
               case 13:
                   d3.event.preventDefault();
                   break;
           }
           d3.event.stopPropagation();
        }

        function keyup() {
            switch (d3.event.keyCode) {
                // escape
                case 27:
                    hide();
                    break;
                // escape, tab
                case 9:
                case 13:
                    if (!shown) return;
                    accept();
                    break;
                default:
                    update();
                    d3.event.preventDefault();
            }
            d3.event.stopPropagation();
        }

        function accept() {
            if (container.select('a.selected').node()) {
                select(container.select('a.selected').datum());
            }
            hide();
        }

        function next() {
            var len = container.selectAll('a').data().length;
            idx = Math.min(idx + 1, len - 1);
            highlight();
        }

        function prev() {
            idx = Math.max(idx - 1, 0);
            highlight();
        }

        var prevValue, prevCompletion;

        function autocomplete(e, data) {

            var value = input.property('value'),
                match;

            for (var i = 0; i < data.length; i++) {
                if (data[i].value.toLowerCase().indexOf(value.toLowerCase()) === 0) {
                    match = data[i].value;
                    break;
                }
            }

            // backspace
            if (e.keyCode === 8) {
                prevValue = value;
                prevCompletion = '';

            } else if (value && match && value !== prevValue + prevCompletion) {
                prevValue = value;
                prevCompletion = match.substr(value.length);
                input.property('value', prevValue + prevCompletion);
                input.node().setSelectionRange(value.length, value.length + prevCompletion.length);
            }
        }

        function highlight() {
            container
                .selectAll('a')
                .classed('selected', function(d, i) { return i == idx; });
            var height = container.node().offsetHeight,
                top = container.select('a.selected').node().offsetTop,
                selectedHeight = container.select('a.selected').node().offsetHeight;
            if ((top + selectedHeight) < height) {
                container.node().scrollTop = 0;
            } else {
                container.node().scrollTop = top;
            }
        }

        function update(value) {

            if (typeof value === 'undefined') {
                value = input.property('value');
            }

            var e = d3.event;

            function render(data) {

                if (data.length &&
                    document.activeElement === input.node()) show();
                else return hide();

                autocomplete(e, data);

                updateSize();

                var options = container
                    .selectAll('a.combobox-option')
                    .data(data, function(d) { return d.value; });

                options.enter()
                    .append('a')
                    .text(function(d) { return d.value; })
                    .attr('class', 'combobox-option')
                    .attr('title', function(d) { return d.title; })
                    .on('click', select);

                options.exit().remove();

                options
                    .classed('selected', function(d, i) { return i == idx; })
                    .order();
            }

            fetcher.apply(input, [value, data, render]);
        }

        // select the choice given as d
        function select(d) {
            input
                .property('value', d.value)
                .trigger('change');
            event.accept(d);
            hide();
        }

        function mousedown() {

            if (shown) return hide();

            input.node().focus();
            update('');

            if (!container) return;

            var entries = container.selectAll('a'),
                height = container.node().scrollHeight / entries[0].length,
                w = d3.select(window);

            function getIndex(m) {
                return Math.floor((m[1] + container.node().scrollTop) / height);
            }

            function withinBounds(m) {
                var n = container.node();
                return m[0] >= 0 && m[0] < n.offsetWidth &&
                    m[1] >= 0 && m[1] < n.offsetHeight;
            }

            w.on('mousemove.typeahead', function() {
                var m = d3.mouse(container.node());
                var within = withinBounds(m);
                var n = getIndex(m);
                entries.classed('selected', function(d, i) { return within && i === n; });
            });

            w.on('mouseup.typeahead', function() {
                var m = d3.mouse(container.node());
                if (withinBounds(m)) select(d3.select(entries[0][getIndex(m)]).datum());
                entries.classed('selected', false);
                w.on('mouseup.typeahead', null);
                w.on('mousemove.typeahead', null);
            });
        }

        input
            .on('blur.typeahead', blur)
            .on('keydown.typeahead', keydown)
            .on('keyup.typeahead', keyup)
            .on('mousedown.typeahead', mousedown);

        d3.select(document.body).on('scroll.combo' + id, function() {
            if (shown) updateSize();
        }, true);
    };

    typeahead.fetcher = function(_) {
        if (!arguments.length) return fetcher;
        fetcher = _;
        return typeahead;
    };

    typeahead.data = function(_) {
        if (!arguments.length) return data;
        data = _;
        return typeahead;
    };

    return d3.rebind(typeahead, event, 'on');
};

d3.combobox.id = 0;
<commit_msg>Rename variable<commit_after>d3.combobox = function() {
    var event = d3.dispatch('accept'),
        id = d3.combobox.id ++,
        data = [];

    var fetcher = function(val, data, cb) {
        cb(data.filter(function(d) {
            return d.title
                .toString()
                .toLowerCase()
                .indexOf(val.toLowerCase()) !== -1;
        }));
    };

    var combobox = function(input) {
        var idx = -1, container, shown = false;

        input
            .classed('combobox-input', true)
            .each(function() {
                var parent = this.parentNode,
                    sibling = this.nextSibling;
                d3.select(parent)
                    .insert('div', function() { return sibling; })
                    .attr('class', 'combobox-carat')
                    .on('mousedown', function () {
                        // prevent the form element from blurring. it blurs
                        // on mousedown
                        d3.event.stopPropagation();
                        d3.event.preventDefault();
                        mousedown();
                    });
            });

        function updateSize() {
            var rect = input.node().getBoundingClientRect();
            container.style({
                'left': rect.left + 'px',
                'width': rect.width + 'px',
                'top': rect.height + rect.top + 'px'
            });
        }

        function blur() {
            // hide the combobox whenever the input element
            // loses focus
            slowHide();
        }

        function show() {
            if (!shown) {
                container = d3.select(document.body)
                    .insert('div', ':first-child')
                    .attr('class', 'combobox')
                    .style({
                        position: 'absolute',
                        display: 'block',
                        left: '0px'
                    });

                shown = true;
            }
        }

        function hide() {
            if (shown) {
                idx = -1;
                container.remove();
                shown = false;
            }
        }

        function slowHide() {
            window.setTimeout(hide, 150);
        }
        function keydown() {
           if (!shown) return;
           switch (d3.event.keyCode) {
               // down arrow
               case 40:
                   next();
                   d3.event.preventDefault();
                   break;
               // up arrow
               case 38:
                   prev();
                   d3.event.preventDefault();
                   break;
               // escape, tab
               case 13:
                   d3.event.preventDefault();
                   break;
           }
           d3.event.stopPropagation();
        }

        function keyup() {
            switch (d3.event.keyCode) {
                // escape
                case 27:
                    hide();
                    break;
                // escape, tab
                case 9:
                case 13:
                    if (!shown) return;
                    accept();
                    break;
                default:
                    update();
                    d3.event.preventDefault();
            }
            d3.event.stopPropagation();
        }

        function accept() {
            if (container.select('a.selected').node()) {
                select(container.select('a.selected').datum());
            }
            hide();
        }

        function next() {
            var len = container.selectAll('a').data().length;
            idx = Math.min(idx + 1, len - 1);
            highlight();
        }

        function prev() {
            idx = Math.max(idx - 1, 0);
            highlight();
        }

        var prevValue, prevCompletion;

        function autocomplete(e, data) {

            var value = input.property('value'),
                match;

            for (var i = 0; i < data.length; i++) {
                if (data[i].value.toLowerCase().indexOf(value.toLowerCase()) === 0) {
                    match = data[i].value;
                    break;
                }
            }

            // backspace
            if (e.keyCode === 8) {
                prevValue = value;
                prevCompletion = '';

            } else if (value && match && value !== prevValue + prevCompletion) {
                prevValue = value;
                prevCompletion = match.substr(value.length);
                input.property('value', prevValue + prevCompletion);
                input.node().setSelectionRange(value.length, value.length + prevCompletion.length);
            }
        }

        function highlight() {
            container
                .selectAll('a')
                .classed('selected', function(d, i) { return i == idx; });
            var height = container.node().offsetHeight,
                top = container.select('a.selected').node().offsetTop,
                selectedHeight = container.select('a.selected').node().offsetHeight;
            if ((top + selectedHeight) < height) {
                container.node().scrollTop = 0;
            } else {
                container.node().scrollTop = top;
            }
        }

        function update(value) {

            if (typeof value === 'undefined') {
                value = input.property('value');
            }

            var e = d3.event;

            function render(data) {

                if (data.length &&
                    document.activeElement === input.node()) show();
                else return hide();

                autocomplete(e, data);

                updateSize();

                var options = container
                    .selectAll('a.combobox-option')
                    .data(data, function(d) { return d.value; });

                options.enter()
                    .append('a')
                    .text(function(d) { return d.value; })
                    .attr('class', 'combobox-option')
                    .attr('title', function(d) { return d.title; })
                    .on('click', select);

                options.exit().remove();

                options
                    .classed('selected', function(d, i) { return i == idx; })
                    .order();
            }

            fetcher.apply(input, [value, data, render]);
        }

        // select the choice given as d
        function select(d) {
            input
                .property('value', d.value)
                .trigger('change');
            event.accept(d);
            hide();
        }

        function mousedown() {

            if (shown) return hide();

            input.node().focus();
            update('');

            if (!container) return;

            var entries = container.selectAll('a'),
                height = container.node().scrollHeight / entries[0].length,
                w = d3.select(window);

            function getIndex(m) {
                return Math.floor((m[1] + container.node().scrollTop) / height);
            }

            function withinBounds(m) {
                var n = container.node();
                return m[0] >= 0 && m[0] < n.offsetWidth &&
                    m[1] >= 0 && m[1] < n.offsetHeight;
            }

            w.on('mousemove.typeahead', function() {
                var m = d3.mouse(container.node());
                var within = withinBounds(m);
                var n = getIndex(m);
                entries.classed('selected', function(d, i) { return within && i === n; });
            });

            w.on('mouseup.typeahead', function() {
                var m = d3.mouse(container.node());
                if (withinBounds(m)) select(d3.select(entries[0][getIndex(m)]).datum());
                entries.classed('selected', false);
                w.on('mouseup.typeahead', null);
                w.on('mousemove.typeahead', null);
            });
        }

        input
            .on('blur.typeahead', blur)
            .on('keydown.typeahead', keydown)
            .on('keyup.typeahead', keyup)
            .on('mousedown.typeahead', mousedown);

        d3.select(document.body).on('scroll.combo' + id, function() {
            if (shown) updateSize();
        }, true);
    };

    combobox.fetcher = function(_) {
        if (!arguments.length) return fetcher;
        fetcher = _;
        return combobox;
    };

    combobox.data = function(_) {
        if (!arguments.length) return data;
        data = _;
        return combobox;
    };

    return d3.rebind(combobox, event, 'on');
};

d3.combobox.id = 0;
<|endoftext|>


<commit_before>d3.combobox = function() {
    var event = d3.dispatch('accept'),
        data = [];

    var fetcher = function(val, data, cb) {
        cb(data.filter(function(d) {
            return d.title
                .toString()
                .toLowerCase()
                .indexOf(val.toLowerCase()) !== -1;
        }));
    };

    var combobox = function(input) {
        var idx = -1,
            container = d3.select(document.body)
                .selectAll('div.combobox')
                .filter(function(d) { return d === input.node(); }),
            shown = !container.empty();

        input
            .classed('combobox-input', true)
            .each(function() {
                var parent = this.parentNode,
                    sibling = this.nextSibling;

                var carat = d3.select(parent).selectAll('.combobox-carat')
                    .filter(function(d) { return d === input.node(); })
                    .data([input.node()]);

                carat.enter().insert('div', function() { return sibling; })
                    .attr('class', 'combobox-carat');

                carat
                    .on('mousedown', function () {
                        // prevent the form element from blurring. it blurs
                        // on mousedown
                        d3.event.stopPropagation();
                        d3.event.preventDefault();
                        mousedown();
                    });
            });

        function updateSize() {
            var rect = input.node().getBoundingClientRect();
            container.style({
                'left': rect.left + 'px',
                'width': rect.width + 'px',
                'top': rect.height + rect.top + 'px'
            });
        }

        function blur() {
            // hide the combobox whenever the input element
            // loses focus
            slowHide();
        }

        function show() {
            if (!shown) {
                container = d3.select(document.body)
                    .insert('div', ':first-child')
                    .datum(input.node())
                    .attr('class', 'combobox')
                    .style({
                        position: 'absolute',
                        display: 'block',
                        left: '0px'
                    });

                d3.select(document.body)
                    .on('scroll.combobox', updateSize, true);

                shown = true;
            }
        }

        function hide() {
            if (shown) {
                idx = -1;
                container.remove();

                d3.select(document.body)
                    .on('scroll.combobox', null);

                shown = false;
            }
        }

        function slowHide() {
            window.setTimeout(hide, 150);
        }
        function keydown() {
           if (!shown) return;
           switch (d3.event.keyCode) {
               // down arrow
               case 40:
                   next();
                   d3.event.preventDefault();
                   break;
               // up arrow
               case 38:
                   prev();
                   d3.event.preventDefault();
                   break;
               // escape, tab
               case 13:
                   d3.event.preventDefault();
                   break;
           }
           d3.event.stopPropagation();
        }

        function keyup() {
            switch (d3.event.keyCode) {
                // escape
                case 27:
                    hide();
                    break;
                // escape, tab
                case 9:
                case 13:
                    if (!shown) return;
                    accept();
                    break;
                default:
                    update();
                    d3.event.preventDefault();
            }
            d3.event.stopPropagation();
        }

        function accept() {
            if (container.select('a.selected').node()) {
                select(container.select('a.selected').datum());
            }
            hide();
        }

        function next() {
            var len = container.selectAll('a').data().length;
            idx = Math.min(idx + 1, len - 1);
            highlight();
        }

        function prev() {
            idx = Math.max(idx - 1, 0);
            highlight();
        }

        var prevValue, prevCompletion;

        function highlight() {
            container
                .selectAll('a')
                .classed('selected', function(d, i) { return i == idx; });
            var height = container.node().offsetHeight,
                top = container.select('a.selected').node().offsetTop,
                selectedHeight = container.select('a.selected').node().offsetHeight;
            if ((top + selectedHeight) < height) {
                container.node().scrollTop = 0;
            } else {
                container.node().scrollTop = top;
            }
        }

        function update(value) {

            if (typeof value === 'undefined') {
                value = input.property('value');
            }

            var e = d3.event;

            function render(data) {

                if (data.length &&
                    document.activeElement === input.node()) show();
                else return hide();

                var match;

                for (var i = 0; i < data.length; i++) {
                    if (data[i].value.toLowerCase().indexOf(value.toLowerCase()) === 0) {
                        match = data[i].value;
                        break;
                    }
                }

                // backspace
                if (e.keyCode === 8) {
                    prevValue = value;
                    prevCompletion = '';
                } else if (value && match && value !== prevValue + prevCompletion) {
                    prevValue = value;
                    prevCompletion = match.substr(value.length);
                    input.property('value', prevValue + prevCompletion);
                    input.node().setSelectionRange(value.length, value.length + prevCompletion.length);
                }

                updateSize();

                var options = container
                    .selectAll('a.combobox-option')
                    .data(data, function(d) { return d.value; });

                options.enter().append('a')
                    .attr('class', 'combobox-option')
                    .text(function(d) { return d.value; });

                options
                    .attr('title', function(d) { return d.title; })
                    .classed('selected', function(d, i) { return i == idx; })
                    .on('click', select)
                    .order();

                options.exit()
                    .remove();
            }

            fetcher.apply(input, [value, data, render]);
        }

        // select the choice given as d
        function select(d) {
            input
                .property('value', d.value)
                .trigger('change');
            event.accept(d);
            hide();
        }

        function mousedown() {

            if (shown) return hide();

            input.node().focus();
            update('');

            if (container.empty()) return;

            var entries = container.selectAll('a'),
                height = container.node().scrollHeight / entries[0].length,
                w = d3.select(window);

            function getIndex(m) {
                return Math.floor((m[1] + container.node().scrollTop) / height);
            }

            function withinBounds(m) {
                var n = container.node();
                return m[0] >= 0 && m[0] < n.offsetWidth &&
                    m[1] >= 0 && m[1] < n.offsetHeight;
            }

            w.on('mousemove.typeahead', function() {
                var m = d3.mouse(container.node());
                var within = withinBounds(m);
                var n = getIndex(m);
                entries.classed('selected', function(d, i) { return within && i === n; });
            });

            w.on('mouseup.typeahead', function() {
                var m = d3.mouse(container.node());
                if (withinBounds(m)) select(d3.select(entries[0][getIndex(m)]).datum());
                entries.classed('selected', false);
                w.on('mouseup.typeahead', null);
                w.on('mousemove.typeahead', null);
            });
        }

        input
            .on('blur.typeahead', blur)
            .on('keydown.typeahead', keydown)
            .on('keyup.typeahead', keyup)
            .on('mousedown.typeahead', mousedown);
    };

    combobox.fetcher = function(_) {
        if (!arguments.length) return fetcher;
        fetcher = _;
        return combobox;
    };

    combobox.data = function(_) {
        if (!arguments.length) return data;
        data = _;
        return combobox;
    };

    return d3.rebind(combobox, event, 'on');
};

d3.combobox.id = 0;
<commit_msg>Remove unused<commit_after>d3.combobox = function() {
    var event = d3.dispatch('accept'),
        data = [];

    var fetcher = function(val, data, cb) {
        cb(data.filter(function(d) {
            return d.title
                .toString()
                .toLowerCase()
                .indexOf(val.toLowerCase()) !== -1;
        }));
    };

    var combobox = function(input) {
        var idx = -1,
            container = d3.select(document.body)
                .selectAll('div.combobox')
                .filter(function(d) { return d === input.node(); }),
            shown = !container.empty();

        input
            .classed('combobox-input', true)
            .each(function() {
                var parent = this.parentNode,
                    sibling = this.nextSibling;

                var carat = d3.select(parent).selectAll('.combobox-carat')
                    .filter(function(d) { return d === input.node(); })
                    .data([input.node()]);

                carat.enter().insert('div', function() { return sibling; })
                    .attr('class', 'combobox-carat');

                carat
                    .on('mousedown', function () {
                        // prevent the form element from blurring. it blurs
                        // on mousedown
                        d3.event.stopPropagation();
                        d3.event.preventDefault();
                        mousedown();
                    });
            });

        function updateSize() {
            var rect = input.node().getBoundingClientRect();
            container.style({
                'left': rect.left + 'px',
                'width': rect.width + 'px',
                'top': rect.height + rect.top + 'px'
            });
        }

        function blur() {
            // hide the combobox whenever the input element
            // loses focus
            slowHide();
        }

        function show() {
            if (!shown) {
                container = d3.select(document.body)
                    .insert('div', ':first-child')
                    .datum(input.node())
                    .attr('class', 'combobox')
                    .style({
                        position: 'absolute',
                        display: 'block',
                        left: '0px'
                    });

                d3.select(document.body)
                    .on('scroll.combobox', updateSize, true);

                shown = true;
            }
        }

        function hide() {
            if (shown) {
                idx = -1;
                container.remove();

                d3.select(document.body)
                    .on('scroll.combobox', null);

                shown = false;
            }
        }

        function slowHide() {
            window.setTimeout(hide, 150);
        }
        function keydown() {
           if (!shown) return;
           switch (d3.event.keyCode) {
               // down arrow
               case 40:
                   next();
                   d3.event.preventDefault();
                   break;
               // up arrow
               case 38:
                   prev();
                   d3.event.preventDefault();
                   break;
               // escape, tab
               case 13:
                   d3.event.preventDefault();
                   break;
           }
           d3.event.stopPropagation();
        }

        function keyup() {
            switch (d3.event.keyCode) {
                // escape
                case 27:
                    hide();
                    break;
                // escape, tab
                case 9:
                case 13:
                    if (!shown) return;
                    accept();
                    break;
                default:
                    update();
                    d3.event.preventDefault();
            }
            d3.event.stopPropagation();
        }

        function accept() {
            if (container.select('a.selected').node()) {
                select(container.select('a.selected').datum());
            }
            hide();
        }

        function next() {
            var len = container.selectAll('a').data().length;
            idx = Math.min(idx + 1, len - 1);
            highlight();
        }

        function prev() {
            idx = Math.max(idx - 1, 0);
            highlight();
        }

        var prevValue, prevCompletion;

        function highlight() {
            container
                .selectAll('a')
                .classed('selected', function(d, i) { return i == idx; });
            var height = container.node().offsetHeight,
                top = container.select('a.selected').node().offsetTop,
                selectedHeight = container.select('a.selected').node().offsetHeight;
            if ((top + selectedHeight) < height) {
                container.node().scrollTop = 0;
            } else {
                container.node().scrollTop = top;
            }
        }

        function update(value) {

            if (typeof value === 'undefined') {
                value = input.property('value');
            }

            var e = d3.event;

            function render(data) {

                if (data.length &&
                    document.activeElement === input.node()) show();
                else return hide();

                var match;

                for (var i = 0; i < data.length; i++) {
                    if (data[i].value.toLowerCase().indexOf(value.toLowerCase()) === 0) {
                        match = data[i].value;
                        break;
                    }
                }

                // backspace
                if (e.keyCode === 8) {
                    prevValue = value;
                    prevCompletion = '';
                } else if (value && match && value !== prevValue + prevCompletion) {
                    prevValue = value;
                    prevCompletion = match.substr(value.length);
                    input.property('value', prevValue + prevCompletion);
                    input.node().setSelectionRange(value.length, value.length + prevCompletion.length);
                }

                updateSize();

                var options = container
                    .selectAll('a.combobox-option')
                    .data(data, function(d) { return d.value; });

                options.enter().append('a')
                    .attr('class', 'combobox-option')
                    .text(function(d) { return d.value; });

                options
                    .attr('title', function(d) { return d.title; })
                    .classed('selected', function(d, i) { return i == idx; })
                    .on('click', select)
                    .order();

                options.exit()
                    .remove();
            }

            fetcher.apply(input, [value, data, render]);
        }

        // select the choice given as d
        function select(d) {
            input
                .property('value', d.value)
                .trigger('change');
            event.accept(d);
            hide();
        }

        function mousedown() {

            if (shown) return hide();

            input.node().focus();
            update('');

            if (container.empty()) return;

            var entries = container.selectAll('a'),
                height = container.node().scrollHeight / entries[0].length,
                w = d3.select(window);

            function getIndex(m) {
                return Math.floor((m[1] + container.node().scrollTop) / height);
            }

            function withinBounds(m) {
                var n = container.node();
                return m[0] >= 0 && m[0] < n.offsetWidth &&
                    m[1] >= 0 && m[1] < n.offsetHeight;
            }

            w.on('mousemove.typeahead', function() {
                var m = d3.mouse(container.node());
                var within = withinBounds(m);
                var n = getIndex(m);
                entries.classed('selected', function(d, i) { return within && i === n; });
            });

            w.on('mouseup.typeahead', function() {
                var m = d3.mouse(container.node());
                if (withinBounds(m)) select(d3.select(entries[0][getIndex(m)]).datum());
                entries.classed('selected', false);
                w.on('mouseup.typeahead', null);
                w.on('mousemove.typeahead', null);
            });
        }

        input
            .on('blur.typeahead', blur)
            .on('keydown.typeahead', keydown)
            .on('keyup.typeahead', keyup)
            .on('mousedown.typeahead', mousedown);
    };

    combobox.fetcher = function(_) {
        if (!arguments.length) return fetcher;
        fetcher = _;
        return combobox;
    };

    combobox.data = function(_) {
        if (!arguments.length) return data;
        data = _;
        return combobox;
    };

    return d3.rebind(combobox, event, 'on');
};
<|endoftext|>


<commit_before>var decodeMmtf=function(){"use strict";function r(r){function t(r){for(var t={},n=0;r>n;n++){var e=o();t[e]=o()}return t}function n(t){var n=r.subarray(i,i+t);return i+=t,n}function e(t){var n=r.subarray(i,i+t);i+=t;var e=65535;if(t>e){for(var a=[],o=0;o<n.length;o+=e)a.push(String.fromCharCode.apply(null,n.subarray(o,o+e)));return a.join("")}return String.fromCharCode.apply(null,n)}function a(r){for(var t=new Array(r),n=0;r>n;n++)t[n]=o();return t}function o(){var o,s,f,c=r[i];if(0===(128&c))return i++,c;if(128===(240&c))return s=15&c,i++,t(s);if(144===(240&c))return s=15&c,i++,a(s);if(160===(224&c))return s=31&c,i++,e(s);if(224===(224&c))return o=u.getInt8(i),i++,o;switch(c){case 192:return i++,null;case 194:return i++,!1;case 195:return i++,!0;case 196:return s=u.getUint8(i+1),i+=2,n(s);case 197:return s=u.getUint16(i+1),i+=3,n(s);case 198:return s=u.getUint32(i+1),i+=5,n(s);case 199:return s=u.getUint8(i+1),f=u.getUint8(i+2),i+=3,[f,n(s)];case 200:return s=u.getUint16(i+1),f=u.getUint8(i+3),i+=4,[f,n(s)];case 201:return s=u.getUint32(i+1),f=u.getUint8(i+5),i+=6,[f,n(s)];case 202:return o=u.getFloat32(i+1),i+=5,o;case 203:return o=u.getFloat64(i+1),i+=9,o;case 204:return o=r[i+1],i+=2,o;case 205:return o=u.getUint16(i+1),i+=3,o;case 206:return o=u.getUint32(i+1),i+=5,o;case 207:return i+=9,0;case 208:return o=u.getInt8(i+1),i+=2,o;case 209:return o=u.getInt16(i+1),i+=3,o;case 210:return o=u.getInt32(i+1),i+=5,o;case 211:return i+=9,0;case 212:return f=u.getUint8(i+1),i+=2,[f,n(1)];case 213:return f=u.getUint8(i+1),i+=2,[f,n(2)];case 214:return f=u.getUint8(i+1),i+=2,[f,n(4)];case 215:return f=u.getUint8(i+1),i+=2,[f,n(8)];case 216:return f=u.getUint8(i+1),i+=2,[f,n(16)];case 217:return s=u.getUint8(i+1),i+=2,e(s);case 218:return s=u.getUint16(i+1),i+=3,e(s);case 219:return s=u.getUint32(i+1),i+=5,e(s);case 220:return s=u.getUint16(i+1),i+=3,a(s);case 221:return s=u.getUint32(i+1),i+=5,a(s);case 222:return s=u.getUint16(i+1),i+=3,t(s);case 223:return s=u.getUint32(i+1),i+=5,t(s)}throw new Error("Unknown type 0x"+c.toString(16))}var i=0,u=new DataView(r.buffer);return o()}function t(r){return new Uint8Array(r.buffer,r.byteOffset,r.byteLength)}function n(r){return new Int8Array(r.buffer,r.byteOffset,r.byteLength)}function e(r,t,n){var e,a,o,i=r.byteOffset,u=r.byteLength;if(t||(t=new Int16Array(u/2)),n){var s=new DataView(r.buffer);for(e=0,a=0,o=u/2;o>e;++e,a+=2)t[e]=s.getInt16(i+a,n)}else for(e=0,a=0,o=u/2;o>e;++e,a+=2)t[e]=r[a]<<8^r[a+1]<<0;return t}function a(r,t,n){var e,a,o,i=r.byteOffset,u=r.byteLength;if(t||(t=new Int32Array(u/4)),n){var s=new DataView(r.buffer);for(e=0,a=0,o=u/4;o>e;++e,a+=4)t[e]=s.getInt32(i+a,n)}else for(e=0,a=0,o=u/4;o>e;++e,a+=4)t[e]=r[a]<<24^r[a+1]<<16^r[a+2]<<8^r[a+3]<<0;return t}function o(r){return new Int32Array(r.buffer,r.byteOffset,r.byteLength/4)}function i(r,t,n){var e=r.length,a=1/t;n||(n=new Float32Array(e));for(var o=0;e>o;++o)n[o]=r[o]*a;return n}function u(r,t){var n,e;if(!t){var a=0;for(n=0,e=r.length;e>n;n+=2)a+=r[n+1];t=new r.constructor(a)}var o=0;for(n=0,e=r.length;e>n;n+=2)for(var i=r[n],u=r[n+1],s=0;u>s;++s)t[o]=i,o+=1;return t}function s(r){for(var t=1,n=r.length;n>t;++t)r[t]+=r[t-1];return r}function f(r,t,n){var e=r.length/2+t.length;n||(n=new Int32Array(e));for(var a=0,o=0,i=0,u=r.length;u>i;i+=2){var s=r[i],f=r[i+1];n[a]=s,0!==i&&(n[a]+=n[a-1]),a+=1;for(var c=0;f>c;++c)n[a]=n[a-1]+t[o],a+=1,o+=1}return n}function c(r,t,n,u,s){var c=u?o(u):void 0,g=f(a(r,void 0,s),e(t,void 0,s),c);return i(g,n,u)}function g(r,t,n,e){var s=n?o(n):void 0,f=u(a(r,void 0,e),s);return i(f,t,n)}function d(e,o){e instanceof ArrayBuffer&&(e=new Uint8Array(e));var i;i=e instanceof Uint8Array?r(e):e,void 0===i.chainIdList&&(i.chainIdList=i.chainList,i.groupIdList=i.groupNumList);var f,d,l,y,v=i.numBonds||0,h=i.numAtoms||0,w=i.groupTypeList.length/4,U=i.chainIdList.length/4,b=i.chainsPerModel.length,A=i.groupMap,p=new Uint32Array(v+w),I=new Uint32Array(v+w),m=new Uint8Array(v+w),L=new Uint32Array(h),C=new Float32Array(h),S=new Float32Array(h),F=new Float32Array(h),O=new Float32Array(h),x=new Int32Array(h),B=new Uint8Array(h),M=new Uint8Array(h),z=new Float32Array(h),D=new Uint32Array(w),G=new Uint32Array(w),P=new Uint16Array(w),T=new Uint16Array(w),V=new Int32Array(w),N=n(i.secStructList),j=new Uint16Array(U),k=new Uint32Array(U),E=new Uint32Array(U),q=t(i.chainIdList),H=new Uint32Array(b),J=new Uint32Array(b);if(c(i.xCoordBig,i.xCoordSmall,1e3,C,o),c(i.yCoordBig,i.yCoordSmall,1e3,S,o),c(i.zCoordBig,i.zCoordSmall,1e3,F,o),i.bFactorBig&&i.bFactorSmall&&c(i.bFactorBig,i.bFactorSmall,100,O,o),i.atomIdList&&s(u(a(i.atomIdList,void 0,o),x)),i.altLabelList){var K=i.altLabelList;for(f=0,d=K.length;d>f;f+=2){var Q=K[f];"?"===Q?K[f]=0:K[f]=Q.charCodeAt(0),K[f+1]=parseInt(K[f+1])}u(K,B)}if(i.insCodeList){var R=i.insCodeList;for(f=0,d=R.length;d>f;f+=2){var W=R[f];null===W?R[f]=0:R[f]=W.charCodeAt(0),R[f+1]=parseInt(R[f+1])}u(R,M)}i.occList&&g(i.occList,100,z,o);var X,Y=i.chainsPerModel,Z=0;for(f=0;b>f;++f){for(X=Y[f],H[f]=Z,J[f]=X,l=0;X>l;++l)j[l+Z]=f;Z+=X}var $,_=i.groupsPerChain,rr=0;for(f=0;U>f;++f){for($=_[f],k[f]=rr,E[f]=$,l=0;$>l;++l)D[l+rr]=f;rr+=$}s(u(a(i.groupIdList,void 0,o),V)),a(i.groupTypeList,T,o);var tr=0,nr=0;for(f=0;w>f;++f){var er=A[T[f]],ar=er.atomInfo,or=ar.length/2,ir=er.bondIndices,ur=er.bondOrders;for(l=0,y=ur.length;y>l;++l)p[nr]=tr+ir[2*l],I[nr]=tr+ir[2*l+1],m[nr]=ur[l],nr+=1;for(G[f]=tr,P[f]=or,l=0;or>l;++l)L[tr]=f,tr+=1}if(i.bondAtomList){if(i.bondOrderList){var sr=i.bondOrderList;m.set(sr,nr)}var fr=a(i.bondAtomList,void 0,o);for(f=0,d=fr.length;d>f;f+=2)p[nr]=fr[f],I[nr]=fr[f+1],nr+=1}return{bondStore:{atomIndex1:p,atomIndex2:I,bondOrder:m},atomStore:{groupIndex:L,xCoord:C,yCoord:S,zCoord:F,bFactor:O,atomId:x,altLabel:B,insCode:M,occupancy:z},groupStore:{chainIndex:D,atomOffset:G,atomCount:P,groupTypeId:T,groupId:V,secStruct:N},chainStore:{modelIndex:j,groupOffset:k,groupCount:E,chainName:q},modelStore:{chainOffset:H,chainCount:J},groupMap:A,unitCell:i.unitCell,spaceGroup:i.spaceGroup,bioAssembly:i.bioAssembly,pdbId:i.pdbId,title:i.title,numBonds:v,numAtoms:h,numGroups:w,numChains:U,numModels:b}}return d}();<commit_msg>mmtf lib update<commit_after>var decodeMmtf=function(){"use strict";function r(r){function t(r){for(var t={},n=0;r>n;n++){var e=o();t[e]=o()}return t}function n(t){var n=r.subarray(i,i+t);return i+=t,n}function e(t){var n=r.subarray(i,i+t);i+=t;var e=65535;if(t>e){for(var a=[],o=0;o<n.length;o+=e)a.push(String.fromCharCode.apply(null,n.subarray(o,o+e)));return a.join("")}return String.fromCharCode.apply(null,n)}function a(r){for(var t=new Array(r),n=0;r>n;n++)t[n]=o();return t}function o(){var o,s,c,f=r[i];if(0===(128&f))return i++,f;if(128===(240&f))return s=15&f,i++,t(s);if(144===(240&f))return s=15&f,i++,a(s);if(160===(224&f))return s=31&f,i++,e(s);if(224===(224&f))return o=u.getInt8(i),i++,o;switch(f){case 192:return i++,null;case 194:return i++,!1;case 195:return i++,!0;case 196:return s=u.getUint8(i+1),i+=2,n(s);case 197:return s=u.getUint16(i+1),i+=3,n(s);case 198:return s=u.getUint32(i+1),i+=5,n(s);case 199:return s=u.getUint8(i+1),c=u.getUint8(i+2),i+=3,[c,n(s)];case 200:return s=u.getUint16(i+1),c=u.getUint8(i+3),i+=4,[c,n(s)];case 201:return s=u.getUint32(i+1),c=u.getUint8(i+5),i+=6,[c,n(s)];case 202:return o=u.getFloat32(i+1),i+=5,o;case 203:return o=u.getFloat64(i+1),i+=9,o;case 204:return o=r[i+1],i+=2,o;case 205:return o=u.getUint16(i+1),i+=3,o;case 206:return o=u.getUint32(i+1),i+=5,o;case 207:return i+=9,0;case 208:return o=u.getInt8(i+1),i+=2,o;case 209:return o=u.getInt16(i+1),i+=3,o;case 210:return o=u.getInt32(i+1),i+=5,o;case 211:return i+=9,0;case 212:return c=u.getUint8(i+1),i+=2,[c,n(1)];case 213:return c=u.getUint8(i+1),i+=2,[c,n(2)];case 214:return c=u.getUint8(i+1),i+=2,[c,n(4)];case 215:return c=u.getUint8(i+1),i+=2,[c,n(8)];case 216:return c=u.getUint8(i+1),i+=2,[c,n(16)];case 217:return s=u.getUint8(i+1),i+=2,e(s);case 218:return s=u.getUint16(i+1),i+=3,e(s);case 219:return s=u.getUint32(i+1),i+=5,e(s);case 220:return s=u.getUint16(i+1),i+=3,a(s);case 221:return s=u.getUint32(i+1),i+=5,a(s);case 222:return s=u.getUint16(i+1),i+=3,t(s);case 223:return s=u.getUint32(i+1),i+=5,t(s)}throw new Error("Unknown type 0x"+f.toString(16))}var i=0,u=new DataView(r.buffer);return o()}function t(r){return new Uint8Array(r.buffer,r.byteOffset,r.byteLength)}function n(r){return new Int8Array(r.buffer,r.byteOffset,r.byteLength)}function e(r,t,n){var e,a,o,i=r.byteOffset,u=r.byteLength;if(t||(t=new Int16Array(u/2)),n){var s=new DataView(r.buffer);for(e=0,a=0,o=u/2;o>e;++e,a+=2)t[e]=s.getInt16(i+a,n)}else for(e=0,a=0,o=u/2;o>e;++e,a+=2)t[e]=r[a]<<8^r[a+1]<<0;return t}function a(r,t,n){var e,a,o,i=r.byteOffset,u=r.byteLength;if(t||(t=new Int32Array(u/4)),n){var s=new DataView(r.buffer);for(e=0,a=0,o=u/4;o>e;++e,a+=4)t[e]=s.getInt32(i+a,n)}else for(e=0,a=0,o=u/4;o>e;++e,a+=4)t[e]=r[a]<<24^r[a+1]<<16^r[a+2]<<8^r[a+3]<<0;return t}function o(r){return new Int32Array(r.buffer,r.byteOffset,r.byteLength/4)}function i(r,t,n){var e=r.length,a=1/t;n||(n=new Float32Array(e));for(var o=0;e>o;++o)n[o]=r[o]*a;return n}function u(r,t){var n,e;if(!t){var a=0;for(n=0,e=r.length;e>n;n+=2)a+=r[n+1];t=new r.constructor(a)}var o=0;for(n=0,e=r.length;e>n;n+=2)for(var i=r[n],u=r[n+1],s=0;u>s;++s)t[o]=i,o+=1;return t}function s(r){for(var t=1,n=r.length;n>t;++t)r[t]+=r[t-1];return r}function c(r,t,n){var e=r.length/2+t.length;n||(n=new Int32Array(e));for(var a=0,o=0,i=0,u=r.length;u>i;i+=2){var s=r[i],c=r[i+1];n[a]=s,0!==i&&(n[a]+=n[a-1]),a+=1;for(var f=0;c>f;++f)n[a]=n[a-1]+t[o],a+=1,o+=1}return n}function f(r,t,n,u,s){var f=u?o(u):void 0,d=c(a(r,void 0,s),e(t,void 0,s),f);return i(d,n,u)}function d(r,t,n,e){var s=n?o(n):void 0,c=u(a(r,void 0,e),s);return i(c,t,n)}function g(e,o){o=o||{};var i=o.littleEndian,c=o.ignoreFields||[];e instanceof ArrayBuffer&&(e=new Uint8Array(e));var g;g=e instanceof Uint8Array?r(e):e,void 0===g.chainIdList&&void 0!==g.chainList&&(g.chainIdList=g.chainList,g.groupIdList=g.groupNumList);var l,y,v,h,m=g.bFactorBig&&g.bFactorSmall&&-1===c.indexOf("bFactor"),b=g.atomIdList&&-1===c.indexOf("atomId"),w=g.altLabelList&&-1===c.indexOf("altLabel"),U=g.insCodeList&&-1===c.indexOf("insCode"),A=g.occList&&-1===c.indexOf("occupancy"),I=g.secStructList&&-1===c.indexOf("secStruct"),p=g.chainNameList&&-1===c.indexOf("chainName"),L=g.numBonds||0,C=g.numAtoms||0,O=g.groupTypeList.length/4,S=g.chainIdList.length/4,x=g.chainsPerModel.length,F=g.groupMap,B=new Uint32Array(L+O),M=new Uint32Array(L+O),N=new Uint8Array(L+O),P=new Uint32Array(C),V=new Float32Array(C),z=new Float32Array(C),D=new Float32Array(C),G=m?new Float32Array(C):void 0,T=b?new Int32Array(C):void 0,E=w?new Uint8Array(C):void 0,j=U?new Uint8Array(C):void 0,k=A?new Float32Array(C):void 0,q=new Uint32Array(O),H=new Uint32Array(O),J=new Uint16Array(O),K=new Uint16Array(O),Q=new Int32Array(O),R=I?n(g.secStructList):void 0,W=new Uint16Array(S),X=new Uint32Array(S),Y=new Uint32Array(S),Z=t(g.chainIdList),$=p?t(g.chainNameList):void 0,_=new Uint32Array(x),rr=new Uint32Array(x);if(f(g.xCoordBig,g.xCoordSmall,1e3,V,i),f(g.yCoordBig,g.yCoordSmall,1e3,z,i),f(g.zCoordBig,g.zCoordSmall,1e3,D,i),m&&f(g.bFactorBig,g.bFactorSmall,100,G,i),b&&s(u(a(g.atomIdList,void 0,i),T)),w){var tr=g.altLabelList;for(l=0,y=tr.length;y>l;l+=2){var nr=tr[l];"?"===nr?tr[l]=0:tr[l]=nr.charCodeAt(0),tr[l+1]=parseInt(tr[l+1])}u(tr,E)}if(U){var er=g.insCodeList;for(l=0,y=er.length;y>l;l+=2){var ar=er[l];null===ar?er[l]=0:er[l]=ar.charCodeAt(0),er[l+1]=parseInt(er[l+1])}u(er,j)}A&&d(g.occList,100,k,i);var or,ir=g.chainsPerModel,ur=0;for(l=0;x>l;++l){for(or=ir[l],_[l]=ur,rr[l]=or,v=0;or>v;++v)W[v+ur]=l;ur+=or}var sr,cr=g.groupsPerChain,fr=0;for(l=0;S>l;++l){for(sr=cr[l],X[l]=fr,Y[l]=sr,v=0;sr>v;++v)q[v+fr]=l;fr+=sr}s(u(a(g.groupIdList,void 0,i),Q)),a(g.groupTypeList,K,i);var dr=0,gr=0;for(l=0;O>l;++l){var lr=F[K[l]],yr=lr.atomInfo,vr=yr.length/2,hr=lr.bondIndices,mr=lr.bondOrders;for(v=0,h=mr.length;h>v;++v)B[gr]=dr+hr[2*v],M[gr]=dr+hr[2*v+1],N[gr]=mr[v],gr+=1;for(H[l]=dr,J[l]=vr,v=0;vr>v;++v)P[dr]=l,dr+=1}if(g.bondAtomList){if(g.bondOrderList){var br=g.bondOrderList;N.set(br,gr)}var wr=a(g.bondAtomList,void 0,i);for(l=0,y=wr.length;y>l;l+=2)B[gr]=wr[l],M[gr]=wr[l+1],gr+=1}return{bondStore:{atomIndex1:B,atomIndex2:M,bondOrder:N},atomStore:{groupIndex:P,xCoord:V,yCoord:z,zCoord:D,bFactor:G,atomId:T,altLabel:E,insCode:j,occupancy:k},groupStore:{chainIndex:q,atomOffset:H,atomCount:J,groupTypeId:K,groupId:Q,secStruct:R},chainStore:{modelIndex:W,groupOffset:X,groupCount:Y,chainId:Z,chainName:$},modelStore:{chainOffset:_,chainCount:rr},groupMap:F,unitCell:g.unitCell,spaceGroup:g.spaceGroup,bioAssembly:g.bioAssembly,pdbId:g.pdbId,title:g.title,numBonds:L,numAtoms:C,numGroups:O,numChains:S,numModels:x,mmtfVersion:g.mmtfVersion,mmtfProducer:g.mmtfProducer}}return g}();<|endoftext|>