<commit_before>"use strict";

var L = require('leaflet'),
    Bacon = require('baconjs'),
    _ = require('lodash'),
    questUtils = require('./questUtils'),
    zoneStyle = require('./zoneStyles');

module.exports = {
    init: function (options) {
        var map = initMap(),
            opts = _.extend({ map: map }, options),
            locationStream = require('./geolocator').init(opts),
            latLngStream = locationStream.map(toLatLng),
            questManager = require('./questManager').init(latLngStream),
            locationMarker = addLocationMarkerToMap(map),
            ghostMarkers = [];

        L.tileLayer('tiles/{z}/{x}/{y}.png', {maxZoom: 18}).addTo(map);

        latLngStream
            .doAction(updateGhostTrail, ghostMarkers, map)
            .onValue(locationMarker, 'setLatLng');

        initQuestZoneLayers(map, questManager.zones);

        questManager.zoneDiffProperty.onValue(highlightZoneChange);

        questManager.zoneFinishedStream
            .filter('.bonusPhotos')
            .flatMap(addBonusPhotos, map)
            .onValue(questManager, 'setCardValue');

        // Style the initial zones, and any updates based on their status
        Bacon.mergeAll(questManager.zoneStatusChangeStream,
                Bacon.fromArray(questManager.zones))
            .onValue(changeZoneStyle, questManager.showDeck);

        // Show and animate zone markers periodically
        // for zones that have not been started
        Bacon.interval(30000, questManager.zones)
            .map(getUnstartedZones)
            .onValue(showAndAnimateInactiveZones);
    }
};

function updateGhostTrail(markers, map, latlng) {
    var icon = L.icon({iconUrl: 'img/location.png'}),
        marker = L.marker(latlng, {icon: icon, clickable: false}),
        lastMarker = null,
        minTrailMarkerSpacing = 10, // In meters.
        maxNumberOfMarkersInTrail = 10,
        distance = minTrailMarkerSpacing;

    if (markers.length > 0) {
        distance = latlng.distanceTo(markers[0].getLatLng());
    }

    // Only add new points if the distance is greater than the minimum spacing
    // distance so ghost trail points don't stack up.
    if (distance >= minTrailMarkerSpacing) {
        map.addLayer(marker);
        markers.unshift(marker);

        // Show only a fixed number of points in the trail at any given time.
        if (markers.length > maxNumberOfMarkersInTrail) {
            lastMarker = markers.pop();
            map.removeLayer(lastMarker);
        }

        // Reduce the opacity by a fixed percentage (100/points) for each
        // previous location from the current location. Start at 95% end at 5%.
        for (var i = 0; i < markers.length; i++) {
            markers[i].setOpacity((105 - (100 / maxNumberOfMarkersInTrail) * i) / 100);
        }
    }
    // Return the latlng to the stream.
    return latlng;
}

function initMap() {
    var mapOptions = {
            attributionControl: false,
            zoomControl: false,
            center: [39.9665675,-75.1834254],
            zoom: 18
        },
        map = L.map('tour-map', mapOptions);
    return map;
}

function toLatLng(position) {
    return L.latLng([position.coords.latitude, position.coords.longitude]);
}

function addLocationMarkerToMap(map) {
    var icon = L.icon({iconUrl: 'img/location.png'}),
        marker = L.marker([0,0],{icon: icon, clickable: false})
            .addTo(map);

    return marker;
}

function initQuestZoneLayers(map, zones) {
    var questLayerGroup = L.layerGroup().addTo(map);
    _.each(zones, function(zone) {
        var geom = zone.location,
            latLng = L.latLng(geom[0], geom[1]),
            options = zone.zoneStyleInitial || zoneStyle.initial,
            circle = L.circle(latLng, zone.radius, options);

        questLayerGroup.addLayer(circle);

        zone.latLng = latLng;
        zone.layer = circle;
    });
}

function highlightZoneChange(diff) {
    if (diff.newZone) {
        diff.newZone.layer.setStyle(diff.newZone.zoneStyleActive || zoneStyle.active);
    }
    if (diff.oldZone) {
        diff.oldZone.layer.setStyle(diff.oldZone.zoneStyleInactive || zoneStyle.inactive);
    }
}

function changeZoneStyle(showDeck, zone) {
    if (questUtils.allQuestsDone(zone)) {
        zone.layer.setStyle(zoneStyle.done);
        zone.layer.setStyle(zoneStyle.active);<commit_msg>Center map on current location<commit_after>"use strict";

var L = require('leaflet'),
    Bacon = require('baconjs'),
    _ = require('lodash'),
    questUtils = require('./questUtils'),
    zoneStyle = require('./zoneStyles');

module.exports = {
    init: function (options) {
        var map = initMap(),
            opts = _.extend({ map: map }, options),
            locationStream = require('./geolocator').init(opts),
            latLngStream = locationStream.map(toLatLng),
            questManager = require('./questManager').init(latLngStream),
            locationMarker = addLocationMarkerToMap(map),
            ghostMarkers = [];

        L.tileLayer('tiles/{z}/{x}/{y}.png', {maxZoom: 18}).addTo(map);

        latLngStream
            .doAction(updateGhostTrail, ghostMarkers, map)
            .doAction(centerMapOnPosiiton, map)
            .onValue(locationMarker, 'setLatLng');

        initQuestZoneLayers(map, questManager.zones);

        questManager.zoneDiffProperty.onValue(highlightZoneChange);

        questManager.zoneFinishedStream
            .filter('.bonusPhotos')
            .flatMap(addBonusPhotos, map)
            .onValue(questManager, 'setCardValue');

        // Style the initial zones, and any updates based on their status
        Bacon.mergeAll(questManager.zoneStatusChangeStream,
                Bacon.fromArray(questManager.zones))
            .onValue(changeZoneStyle, questManager.showDeck);

        // Show and animate zone markers periodically
        // for zones that have not been started
        Bacon.interval(30000, questManager.zones)
            .map(getUnstartedZones)
            .onValue(showAndAnimateInactiveZones);
    }
};

function updateGhostTrail(markers, map, latlng) {
    var icon = L.icon({iconUrl: 'img/location.png'}),
        marker = L.marker(latlng, {icon: icon, clickable: false}),
        lastMarker = null,
        minTrailMarkerSpacing = 10, // In meters.
        maxNumberOfMarkersInTrail = 10,
        distance = minTrailMarkerSpacing;

    if (markers.length > 0) {
        distance = latlng.distanceTo(markers[0].getLatLng());
    }

    // Only add new points if the distance is greater than the minimum spacing
    // distance so ghost trail points don't stack up.
    if (distance >= minTrailMarkerSpacing) {
        map.addLayer(marker);
        markers.unshift(marker);

        // Show only a fixed number of points in the trail at any given time.
        if (markers.length > maxNumberOfMarkersInTrail) {
            lastMarker = markers.pop();
            map.removeLayer(lastMarker);
        }

        // Reduce the opacity by a fixed percentage (100/points) for each
        // previous location from the current location. Start at 95% end at 5%.
        for (var i = 0; i < markers.length; i++) {
            markers[i].setOpacity((105 - (100 / maxNumberOfMarkersInTrail) * i) / 100);
        }
    }
    // Return the latlng to the stream.
    return latlng;
}

function initMap() {
    var mapOptions = {
            attributionControl: false,
            zoomControl: false,
            center: [39.9665675,-75.1834254],
            zoom: 18
        },
        map = L.map('tour-map', mapOptions);
    return map;
}

function toLatLng(position) {
    return L.latLng([position.coords.latitude, position.coords.longitude]);
}

function addLocationMarkerToMap(map) {
    var icon = L.icon({iconUrl: 'img/location.png'}),
        marker = L.marker([0,0],{icon: icon, clickable: false})
            .addTo(map);

    return marker;
}

function centerMapOnPosiiton(map, latlng) {
    map.panTo(latlng);
}

function initQuestZoneLayers(map, zones) {
    var questLayerGroup = L.layerGroup().addTo(map);
    _.each(zones, function(zone) {
        var geom = zone.location,
            latLng = L.latLng(geom[0], geom[1]),
            options = zone.zoneStyleInitial || zoneStyle.initial,
            circle = L.circle(latLng, zone.radius, options);

        questLayerGroup.addLayer(circle);

        zone.latLng = latLng;
        zone.layer = circle;
    });
}

function highlightZoneChange(diff) {
    if (diff.newZone) {
        diff.newZone.layer.setStyle(diff.newZone.zoneStyleActive || zoneStyle.active);
    }
    if (diff.oldZone) {
        diff.oldZone.layer.setStyle(diff.oldZone.zoneStyleInactive || zoneStyle.inactive);
    }
}

function changeZoneStyle(showDeck, zone) {
    if (questUtils.allQuestsDone(zone)) {
        zone.layer.setStyle(zoneStyle.done);
        zone.layer.setStyle(zoneStyle.active);
{'fraction_non_alphanumeric': 0.11975711233554481, 'fraction_numerical': 0.011919487237152818, 'mean_word_length': 2.5209817893903406, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, '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': '2793684', 'n_tokens_mistral': 2774, 'n_tokens_neox': 2641, 'n_words': 567}