<commit_before>import {
    event as d3_event,
    select as d3_select
} from 'd3-selection';

import * as sexagesimal from '@mapbox/sexagesimal';
import { t } from '../util/locale';
import { dmsCoordinatePair } from '../util/units';
import { coreGraph } from '../core/graph';
import { geoSphericalDistance } from '../geo/geo';
import { geoExtent, geoChooseEdge } from '../geo';
import { modeSelect } from '../modes/select';
import { osmEntity } from '../osm/entity';
import { services } from '../services';
import { svgIcon } from '../svg/icon';
import { uiCmd } from './cmd';

import {
    utilDisplayName,
    utilDisplayType,
    utilEntityOrMemberSelector,
    utilNoAuto
} from '../util';


export function uiFeatureList(context) {
    var _geocodeResults;


    function featureList(selection) {
        var header = selection
            .append('div')
            .attr('class', 'header fillL cf');

        header
            .append('h3')
            .text(t('inspector.feature_list'));

        var searchWrap = selection
            .append('div')
            .attr('class', 'search-header');

        var search = searchWrap
            .append('input')
            .attr('placeholder', t('inspector.search'))
            .attr('type', 'search')
            .call(utilNoAuto)
            .on('keypress', keypress)
            .on('keydown', keydown)
            .on('input', inputevent);

        searchWrap
            .call(svgIcon('#iD-icon-search', 'pre-text'));

        var listWrap = selection
            .append('div')
            .attr('class', 'inspector-body');

        var list = listWrap
            .append('div')
            .attr('class', 'feature-list cf');

        context
            .on('exit.feature-list', clearSearch);
        context.map()
            .on('drawn.feature-list', mapDrawn);

        context.keybinding()
            .on(uiCmd('⌘F'), focusSearch);


        function focusSearch() {
            var mode = context.mode() && context.mode().id;
            if (mode !== 'browse') return;

            d3_event.preventDefault();
            search.node().focus();
        }


        function keydown() {
            if (d3_event.keyCode === 27) {  // escape
                search.node().blur();
            }
        }


        function keypress() {
            var q = search.property('value'),
                items = list.selectAll('.feature-list-item');
            if (d3_event.keyCode === 13 && q.length && items.size()) {  // return
                click(items.datum());
            }
        }


        function inputevent() {
            _geocodeResults = undefined;
            drawList();
        }


        function clearSearch() {
            search.property('value', '');
            drawList();
        }


        function mapDrawn(e) {
            if (e.full) {
                drawList();
            }
        }


        function features() {
            var result = [];
            var graph = context.graph();
            var visibleCenter = context.map().extent().center();
            var q = search.property('value').toLowerCase();

            if (!q) return result;

            var idMatch = q.match(/^([nwr])([0-9]+)$/);

            if (idMatch) {
                result.push({
                    id: idMatch[0],
                    geometry: idMatch[1] === 'n' ? 'point' : idMatch[1] === 'w' ? 'line' : 'relation',
                    type: idMatch[1] === 'n' ? t('inspector.node') : idMatch[1] === 'w' ? t('inspector.way') : t('inspector.relation'),
                    name: idMatch[2]
                });
            }

            var locationMatch = sexagesimal.pair(q.toUpperCase()) || q.match(/^(-?\d+\.?\d*)\s+(-?\d+\.?\d*)$/);

            if (locationMatch) {
                var loc = [parseFloat(locationMatch[0]), parseFloat(locationMatch[1])];
                result.push({
                    id: -1,
                    geometry: 'point',
                    type: t('inspector.location'),
                    name: dmsCoordinatePair([loc[1], loc[0]]),
                    location: loc
                });
            }

            var allEntities = graph.entities;
            var localResults = [];
            for (var id in allEntities) {
                var entity = allEntities[id];
                var name = utilDisplayName(entity) || '';
                if (name.toLowerCase().indexOf(q) < 0) continue;
                var matched = context.presets().match(entity, graph);
                var type = (matched && matched.name()) || utilDisplayType(entity.id);
                var extent = entity.extent(graph);
                var distance = extent ? geoSphericalDistance(visibleCenter, extent.center()) : 0;

                localResults.push({
                    id: entity.id,
                    entity: entity,
                    geometry: context.geometry(entity.id),
                    type: type,
                    name: name,
                    distance: distance
                });

                if (localResults.length > 100) break;
            }
            localResults = localResults.sort(function byDistance(a, b) {
                return a.distance - b.distance;
            });
            result = result.concat(localResults);

            (_geocodeResults || []).forEach(function(d) {<commit_msg>Fix issue with searching features with a deleted feature in history<commit_after>import {
    event as d3_event,
    select as d3_select
} from 'd3-selection';

import * as sexagesimal from '@mapbox/sexagesimal';
import { t } from '../util/locale';
import { dmsCoordinatePair } from '../util/units';
import { coreGraph } from '../core/graph';
import { geoSphericalDistance } from '../geo/geo';
import { geoExtent, geoChooseEdge } from '../geo';
import { modeSelect } from '../modes/select';
import { osmEntity } from '../osm/entity';
import { services } from '../services';
import { svgIcon } from '../svg/icon';
import { uiCmd } from './cmd';

import {
    utilDisplayName,
    utilDisplayType,
    utilEntityOrMemberSelector,
    utilNoAuto
} from '../util';


export function uiFeatureList(context) {
    var _geocodeResults;


    function featureList(selection) {
        var header = selection
            .append('div')
            .attr('class', 'header fillL cf');

        header
            .append('h3')
            .text(t('inspector.feature_list'));

        var searchWrap = selection
            .append('div')
            .attr('class', 'search-header');

        var search = searchWrap
            .append('input')
            .attr('placeholder', t('inspector.search'))
            .attr('type', 'search')
            .call(utilNoAuto)
            .on('keypress', keypress)
            .on('keydown', keydown)
            .on('input', inputevent);

        searchWrap
            .call(svgIcon('#iD-icon-search', 'pre-text'));

        var listWrap = selection
            .append('div')
            .attr('class', 'inspector-body');

        var list = listWrap
            .append('div')
            .attr('class', 'feature-list cf');

        context
            .on('exit.feature-list', clearSearch);
        context.map()
            .on('drawn.feature-list', mapDrawn);

        context.keybinding()
            .on(uiCmd('⌘F'), focusSearch);


        function focusSearch() {
            var mode = context.mode() && context.mode().id;
            if (mode !== 'browse') return;

            d3_event.preventDefault();
            search.node().focus();
        }


        function keydown() {
            if (d3_event.keyCode === 27) {  // escape
                search.node().blur();
            }
        }


        function keypress() {
            var q = search.property('value'),
                items = list.selectAll('.feature-list-item');
            if (d3_event.keyCode === 13 && q.length && items.size()) {  // return
                click(items.datum());
            }
        }


        function inputevent() {
            _geocodeResults = undefined;
            drawList();
        }


        function clearSearch() {
            search.property('value', '');
            drawList();
        }


        function mapDrawn(e) {
            if (e.full) {
                drawList();
            }
        }


        function features() {
            var result = [];
            var graph = context.graph();
            var visibleCenter = context.map().extent().center();
            var q = search.property('value').toLowerCase();

            if (!q) return result;

            var idMatch = q.match(/^([nwr])([0-9]+)$/);

            if (idMatch) {
                result.push({
                    id: idMatch[0],
                    geometry: idMatch[1] === 'n' ? 'point' : idMatch[1] === 'w' ? 'line' : 'relation',
                    type: idMatch[1] === 'n' ? t('inspector.node') : idMatch[1] === 'w' ? t('inspector.way') : t('inspector.relation'),
                    name: idMatch[2]
                });
            }

            var locationMatch = sexagesimal.pair(q.toUpperCase()) || q.match(/^(-?\d+\.?\d*)\s+(-?\d+\.?\d*)$/);

            if (locationMatch) {
                var loc = [parseFloat(locationMatch[0]), parseFloat(locationMatch[1])];
                result.push({
                    id: -1,
                    geometry: 'point',
                    type: t('inspector.location'),
                    name: dmsCoordinatePair([loc[1], loc[0]]),
                    location: loc
                });
            }

            var allEntities = graph.entities;
            var localResults = [];
            for (var id in allEntities) {
                var entity = allEntities[id];
                if (!entity) continue;

                var name = utilDisplayName(entity) || '';
                if (name.toLowerCase().indexOf(q) < 0) continue;
                
                var matched = context.presets().match(entity, graph);
                var type = (matched && matched.name()) || utilDisplayType(entity.id);
                var extent = entity.extent(graph);
                var distance = extent ? geoSphericalDistance(visibleCenter, extent.center()) : 0;

                localResults.push({
                    id: entity.id,
                    entity: entity,
                    geometry: context.geometry(entity.id),
                    type: type,
                    name: name,
                    distance: distance
                });

                if (localResults.length > 100) break;
            }
            localResults = localResults.sort(function byDistance(a, b) {
                return a.distance - b.distance;
            });
            result = result.concat(localResults);

            (_geocodeResults || []).forEach(function(d) {
{'fraction_non_alphanumeric': 0.1454646530158436, 'fraction_numerical': 0.005373853423515242, 'mean_word_length': 1.529053420805998, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3071019', 'n_tokens_mistral': 3011, 'n_tokens_neox': 2832, 'n_words': 621}