<commit_before>/*global tarteaucitron */
tarteaucitron.lang = {
    "middleBarHead": "☝ 🍪",
    "adblock": "Привет! Этот сайт совершенно открытый и позволяет вам выбрать сервисы третьих лиц, которым вы хотите дать доступ.",
    "adblock_call": "Пожалуйста дезактивируйте АдБлокер чтобы начать настройку.",
    "reload": "Перезагрузите страницу",

    "alertBigScroll": "Продолжая прокрутки",
    "alertBigClick": "Если вы продолжаете использовать сайт",
    "alertBig": "вы позволяете сервисы третьих лиц",

    "alertBigPrivacy": "Этот сайт использует кукис и позволяет вам контролировать сервисы которые вы хотите активировать",
    "alertSmall": "Настройка сервисов",
    "personalize": "Персонализировать",
    "acceptAll": "Ок, все активировать",
    "close": "Закрыть",

    "privacyUrl": "Политика конфиденциальности",

    "all": "Преференция всем сервисам",

    "info": "Защитить вашу конфиденциальность",
    "disclaimer": "Активирование сервисов третьих лиц позволяет использование их кукис и технолоний отслеживания необходимых для их функционирования",
    "allow": "Позролить",
    "deny": "Не позволить",
    "noCookie": "Этот сервис не использует кукис.",
    "useCookie": "Этот сервис может быть инсталирован",
    "useCookieCurrent": "Этот сервис инсталирован",
    "useNoCookie": "Этот сервис не использует кукис.",
    "more": "Подробнее",
    "source": "Посетите официальный сайт",
    "credit": "Кукис манаджер tarteaucitron.js",

    "toggleInfoBox": "Show/hide informations about cookie storage",
    "title": "Cookies management panel",
    "cookieDetail": "Cookie detail for",
    "ourSite": "on our site",
    "newWindow": "(new window)",
    "allowAll": "Разрешить использование cookies",
    "denyAll": "Запретить использование cookies",

    "fallback": "Деактивирован.",

    "ads": {
        "title": "Рекламная сеть",
        "details": "Мы позволяем вам аренду нашей рекламной сети."
    },
    "analytic": {
        "title": "Измерение аудиенции",
        "details": "Измерение аудиенции сайта для статистики помогают улучшить предлагаемый сервис."
    },
    "social": {
        "title": "Социальная сеть",
        "details": "Социальная сеть сайтов помогает улучшить предлагаемый сервис через обмен информации."
    },
    "video": {
        "title": "Видео",
        "details": "Обмен видео информации позволяет улучшить сервис и увеличит траффик сайта."
    },
    "comment": {
        "title": "Комментарии",
        "details": "Манаджер комментариев позволяет обмен информации и борьбу со спамом."
    },
    "support": {
        "title": "Помощь",
        "details": "Помощь позволяет вам контактировать напрямую сайт манаджер и улучшить предлагаемый сервис."
    },
    "api": {
        "title": "АПИ",
        "details": "АПИ используются для загрузки скриптов; геолокация, поисковый мотор и переводы..."
    },
    "other": {
        "title": "Другие",
        "details": "Службы для отображения веб-контента."
    }
};
<commit_msg>fix .ru trad<commit_after>/*global tarteaucitron */
tarteaucitron.lang = {
    "middleBarHead": "☝ 🍪",
    "adblock": "Привет! Этот сайт совершенно открытый и позволяет вам выбрать сервисы третьих лиц, которым вы хотите дать доступ.",
    "adblock_call": "Пожалуйста дезактивируйте АдБлокер чтобы начать настройку.",
    "reload": "Перезагрузите страницу",

    "alertBigScroll": "Продолжая прокрутки",
    "alertBigClick": "Если вы продолжаете использовать сайт",
    "alertBig": "вы позволяете сервисы третьих лиц",

    "alertBigPrivacy": "Этот сайт использует кукис и позволяет вам контролировать сервисы которые вы хотите активировать",
    "alertSmall": "Настройка сервисов",
    "personalize": "Персонализировать",
    "acceptAll": "Ок, все активировать",
    "close": "Закрыть",

    "privacyUrl": "Политика конфиденциальности",

    "all": "Преференция всем сервисам",

    "info": "Защитить вашу конфиденциальность",
    "disclaimer": "Активирование сервисов третьих лиц позволяет использование их кукис и технолоний отслеживания необходимых для их функционирования",
    "allow": "Позролить",
    "deny": "Не позволить",
    "noCookie": "Этот сервис не использует кукис.",
    "useCookie": "Этот сервис может быть инсталирован",
    "useCookieCurrent": "Этот сервис инсталирован",
    "useNoCookie": "Этот сервис не использует кукис.",
    "more": "Подробнее",
    "source": "Посетите официальный сайт",
    "credit": "Кукис манаджер tarteaucitron.js",

    "toggleInfoBox": "Show/hide informations about cookie storage",
    "title": "Панель управления cookies",
    "cookieDetail": "Cookie detail for",
    "ourSite": "on our site",
    "newWindow": "(new window)",
    "allowAll": "Разрешить использование cookies",
    "denyAll": "Запретить использование cookies",

    "fallback": "Деактивирован.",

    "ads": {
        "title": "Рекламная сеть",
        "details": "Мы позволяем вам аренду нашей рекламной сети."
    },
    "analytic": {
        "title": "Измерение аудиенции",
        "details": "Измерение аудиенции сайта для статистики помогают улучшить предлагаемый сервис."
    },
    "social": {
        "title": "Социальная сеть",
        "details": "Социальная сеть сайтов помогает улучшить предлагаемый сервис через обмен информации."
    },
    "video": {
        "title": "Видео",
        "details": "Обмен видео информации позволяет улучшить сервис и увеличит траффик сайта."
    },
    "comment": {
        "title": "Комментарии",
        "details": "Манаджер комментариев позволяет обмен информации и борьбу со спамом."
    },
    "support": {
        "title": "Помощь",
        "details": "Помощь позволяет вам контактировать напрямую сайт манаджер и улучшить предлагаемый сервис."
    },
    "api": {
        "title": "АПИ",
        "details": "АПИ используются для загрузки скриптов; геолокация, поисковый мотор и переводы..."
    },
    "other": {
        "title": "Другие",
        "details": "Службы для отображения веб-контента."
    }
};
<|endoftext|>


<commit_before>// Apply to elements with recordSet class.
;jQuery(function(){
    jQuery('.recordSet').dbRecordSet();
});

// dbRecordSet plugin
// Call on a DOM element which contains the dbRecords.
;(function($, window, undefined){

    // Use the jQuery UI widget factory.
    $.widget('qcode.dbRecordSet', {
	options: {
	    saveType: "recordOut"
	},
	_getCreateOptions: function() {
	    return {
		saveType: this.element.attr('saveType')
	    }
	},
	_create: function(){
	    // Constructor function

	    // Event listeners - instead of seperate event listeners for each field, delegated event listeners are added to the container.
	    // Elements with class "editable" should be editable fields.
	    this._on({
		'mousedown .editable': function(event) {
		    $(event.currentTarget).dbField('onMouseDown', event);
		},
		'editorKeyDown .editable': function(event) {
		    $(event.currentTarget).dbField('editorKeyDown', event);
		},
		'editorKeyUp .editable': function(event) {
		    $(event.currentTarget).dbField('editorKeyUp', event);
		},
		'editorCut .editable': function(event) {
		    $(event.currentTarget).dbField('editorCut', event);
		},
		'editorPaste .editable': function(event) {
		    $(event.currentTarget).dbField('editorPaste', event);
		},
		'editorBlur .editable': function(event) {
		    $(event.currentTarget).dbField('editorBlur', event);
		}
	    });
	    this._on(window, {
		'beforeunload': this._onBeforeUnload,
		'beforeprint': this._onBeforePrint,
	    });

	    // Initialize as empty jQuery object.
	    this.currentField = $([]);
	    this.currentRecord = $([]);
	},
	save: function(aysnc) {
	    // Save the current record
	    this.getCurrentRecord().dbRecord('save', async);
	},
	getCurrentRecord: function() {
	    // Returns the current record
	    return this.currentRecord;
	},
	setCurrentRecord: function(newRecord) {
	    // Sets the current field
	    this.currentRecord = $(newRecord);
	},
	getCurrentField: function() {
	    // Returns the current field
	    return this.currentField;
	},
	setCurrentField: function(newField) {
	    // Sets the current field
	    this.currentField = $(newField);
	},
	fieldChange: function(toField) {
	    // Move to the target field
	    var currentRecord = this.getCurrentRecord();
	    var newRecord = toField.dbField('getRecord');

	    this.getCurrentField().dbField('fieldOut');
	    if ( ! currentRecord.is(newRecord) ) {
		currentRecord.dbRecord('recordOut');
	    }

	    toField.dbField('fieldIn');
	    if ( ! currentRecord.is(newRecord) ) {
		newRecord.dbRecord('recordIn');
	    }
	},
	_onBeforeUnload: function(event){
	    // Before leaving the page, offer the user a chance to save changes.
	    var records = this.element.find('.record');
	    for (var i = 0; i < records.length; i++) {
		var record = records.eq(i);
		if ( record.dbRecord('getState') === 'dirty' || record.dbRecord('getState') === 'error' ) {
		    return "Your changes have not been saved.\nStay on the current page to correct.";
		}
	    }
	},
	_onBeforePrint: function(event){
	    // Before printing, stop editing
	    this.getCurrentField().dbField('fieldOut');
	    this.getCurrentRecord().dbRecord('recordOut');
	}
    });
})(jQuery, window);
<commit_msg>Added a comment<commit_after>// Apply to elements with recordSet class.
;jQuery(function(){
    jQuery('.recordSet').dbRecordSet();
});

// dbRecordSet plugin
// Call on a DOM element which contains the dbRecords.
;(function($, window, undefined){

    // Use the jQuery UI widget factory.
    $.widget('qcode.dbRecordSet', {
	options: {
	    saveType: "recordOut"
	},
	_getCreateOptions: function() {
	    // Use custom attributes to overwite default options
	    return {
		saveType: this.element.attr('saveType')
	    }
	},
	_create: function(){
	    // Constructor function

	    // Event listeners - instead of seperate event listeners for each field, delegated event listeners are added to the container.
	    // Elements with class "editable" should be editable fields.
	    this._on({
		'mousedown .editable': function(event) {
		    $(event.currentTarget).dbField('onMouseDown', event);
		},
		'editorKeyDown .editable': function(event) {
		    $(event.currentTarget).dbField('editorKeyDown', event);
		},
		'editorKeyUp .editable': function(event) {
		    $(event.currentTarget).dbField('editorKeyUp', event);
		},
		'editorCut .editable': function(event) {
		    $(event.currentTarget).dbField('editorCut', event);
		},
		'editorPaste .editable': function(event) {
		    $(event.currentTarget).dbField('editorPaste', event);
		},
		'editorBlur .editable': function(event) {
		    $(event.currentTarget).dbField('editorBlur', event);
		}
	    });
	    this._on(window, {
		'beforeunload': this._onBeforeUnload,
		'beforeprint': this._onBeforePrint,
	    });

	    // Initialize as empty jQuery object.
	    this.currentField = $([]);
	    this.currentRecord = $([]);
	},
	save: function(aysnc) {
	    // Save the current record
	    this.getCurrentRecord().dbRecord('save', async);
	},
	getCurrentRecord: function() {
	    // Returns the current record
	    return this.currentRecord;
	},
	setCurrentRecord: function(newRecord) {
	    // Sets the current field
	    this.currentRecord = $(newRecord);
	},
	getCurrentField: function() {
	    // Returns the current field
	    return this.currentField;
	},
	setCurrentField: function(newField) {
	    // Sets the current field
	    this.currentField = $(newField);
	},
	fieldChange: function(toField) {
	    // Move to the target field
	    var currentRecord = this.getCurrentRecord();
	    var newRecord = toField.dbField('getRecord');

	    this.getCurrentField().dbField('fieldOut');
	    if ( ! currentRecord.is(newRecord) ) {
		currentRecord.dbRecord('recordOut');
	    }

	    toField.dbField('fieldIn');
	    if ( ! currentRecord.is(newRecord) ) {
		newRecord.dbRecord('recordIn');
	    }
	},
	_onBeforeUnload: function(event){
	    // Before leaving the page, offer the user a chance to save changes.
	    var records = this.element.find('.record');
	    for (var i = 0; i < records.length; i++) {
		var record = records.eq(i);
		if ( record.dbRecord('getState') === 'dirty' || record.dbRecord('getState') === 'error' ) {
		    return "Your changes have not been saved.\nStay on the current page to correct.";
		}
	    }
	},
	_onBeforePrint: function(event){
	    // Before printing, stop editing
	    this.getCurrentField().dbField('fieldOut');
	    this.getCurrentRecord().dbRecord('recordOut');
	}
    });
})(jQuery, window);
<|endoftext|>


<commit_before>jQuery(function ($) {
    function setQuantityToZero(parentTag) {
        return function (button) {
            return button.parents(parentTag + ":first")
                .find("input.quantity").val(0)
                .parents("form");
        };
    }

    $(".shoppingcart .delete").live("click", function () {
        setQuantityToZero("tr")($(this)).submit();
    });

    var mini = $(".minicart");
    mini.load(mini.data("url"));

    function miniLoad(form) {
        mini.load(form.attr("action"), form.serializeArray());
        return false;
    }

    $(".minicart .delete").live("click", function () {
        return miniLoad(setQuantityToZero("li")($(this)));
    });

    $(".minicart .update-button, .addtocart-button").live("click", function () {
        return miniLoad($(this).parents("form"));
    });
});<commit_msg>Completely hide minicart if empty<commit_after>jQuery(function ($) {
    function setQuantityToZero(parentTag) {
        return function (button) {
            return button.parents(parentTag + ":first")
                .find("input.quantity").val(0)
                .parents("form");
        };
    }

    $(".shoppingcart .delete").live("click", function () {
        setQuantityToZero("tr")($(this)).submit();
    });

    var mini = $(".minicart");
    mini.load(mini.data("url"), onload).parent().hide();

    function miniLoad(form) {
        mini.load(form.attr("action"), form.serializeArray(), onload);
        return false;
    }

    function onload(text) {
        mini.parent().toggle(text.trim().length > 0);
    }

    $(".minicart .delete").live("click", function () {
        return miniLoad(setQuantityToZero("li")($(this)));
    });

    $(".minicart .update-button, .addtocart-button").live("click", function () {
        return miniLoad($(this).parents("form"));
    });
});<|endoftext|>


<commit_before>"use strict"

// MAP
$( document ).ready(function() {

    // INIT
    L.mapbox.accessToken = getMapboxAccessToken();
    var map = L.mapbox.map('map').setView([51.961298, 7.625849], 14);

    L.control.layers({
        'Streets': L.mapbox.tileLayer('mapbox.streets').addTo(map),
        'Satellite': L.mapbox.tileLayer('mapbox.satellite'),
        'Light': L.mapbox.tileLayer('mapbox.light')
    }).addTo(map);

    var boxes = [];
    var markers = [];
    requestData();

    // MAP-FUNCTION
    map.on('zoomend', function() {
        console.log(map.getZoom());
        if (map.getZoom() >= 14) {
            map.featureLayer.setFilter(function() { return true; });
        } else {
            map.featureLayer.setFilter(function() { return false; });
        }
    });

    // REQUEST DATA FROM API
    function requestData(){

        $.ajax({
            url: getURL() + "/boxes",
            global: false,
            type: 'GET',
            async: false,
            success: function(data) {
                boxes = data;
                boxes.forEach(function (box, key) {
                    $.ajax({
                        url: getURL() + "/boxes/" + box._id + "/tracks",
                        global: false,
                        type: 'GET',
                        async: false,
                        success: function(data) {
                            box.tracks = data;
                            box.tracks.forEach(function (track, key) {
                                $.ajax({
                                    url: getURL() + "/boxes/" + box._id + "/tracks/" + track._id + "/measurements",
                                    global: false,
                                    type: 'GET',
                                    async: false,
                                    success: function(data) {
                                        track.measurements = data;
                                    }
                                });
                            });
                        }
                    });
                });
                drawMarkers();
            }
        });
    }

    function drawMarkers() {

        var geoJsonFeatures = [];

        boxes.forEach(function (box, key) {
            box.tracks.forEach(function (track, key) {

                // Interpolate the data before the visualization
                track.measurements = interpolate(track.measurements);

                track.measurements.forEach(function (measurement, key) {

                    geoJsonFeatures.push(
                        {
                            type: 'Feature',
                            geometry: {
                                type: 'Point',
                                coordinates: [
                                    measurement.lng, measurement.lat,
                                ]
                            },
                            'properties': {
                                'title': '
' + box._id + ' BoxId
' +
                                    '
' + track._id + ' TrackId
',
                                'description': '

' +
                                    '
Longitude	' + measurement.lng + '
' +
                                    '
Latitude	' + measurement.lat + '
' +
                                    '
Altitude	' + measurement.altitude + '
' +
                                    '
Speed	' + measurement.speed + '
' +
                                    '
Vibration	' + measurement.vibration + '
' +
                                    '
Sound	' + measurement.sound + '
' +
                                    '
Brightness	' + measurement.brightness + '
' +
                                    '
IR	' + measurement.ir + '
' +
                                    '
UV	' + measurement.uv + '
' +
                                    '

',
                                'perfect': isPerfectCondition(measurement.speed, measurement.vibration),
                                'poor': isPoorCondition(measurement.speed, measurement.vibration),
                                'icon': {
                                    'iconUrl': calcRoadConditionIcon(measurement.speed, measurement.vibration),
                                    'iconSize': [12, 12], // size of the icon
                                    'iconAnchor': [6, 6], // point of the icon which will correspond to marker's location
                                    'popupAnchor': [0, -6], // point from which the popup should open relative to the iconAnchor
                                    'className': 'dot'
                                }
                            }
                        }
                    );
                });
            });
        });

        // Add markers to the map
        var markers = L.mapbox.featureLayer().addTo(map);
        markers.on('layeradd', function(e) {
            var marker = e.layer;
            var feature = marker.feature;
            marker.setIcon(L.icon(feature.properties.icon));
        });
        markers.setGeoJSON(geoJsonFeatures);

        $('.menu-ui a').on('click', function() {
            // For each filter link, get the 'data-filter' attribute value.
            var filter = $(this).data('filter');
            $(this).addClass('active').siblings().removeClass('active');
            markers.setFilter(function(f) {
                // If the data-filter attribute is set to "all", return
                // all (true). Otherwise, filter on markers that have
                // a value set to true based on the filter name.
                return (filter === 'all') ? true : f.properties[filter] === true;
            });
            return false;
        });
    };

    /*
        Function to interpolate the speed and vibration values
    */
    function interpolate(measurements) {
        for (var i = 2; i < measurements.length - 2; i++) {
            var m_2 = measurements[i-2],
                m_1 = measurements[i-1],
                m = measurements[i],
                m1 = measurements[i+1],
                m2 = measurements[i+2];
            measurements[i].speed = (m_2.speed + m_1.speed + m.speed + m1.speed + m2.speed) / 5;
            measurements[i].vibration = (m_2.vibration + m_1.vibration + m.vibration + m1.vibration + m2.vibration) / 5;
        }

        return measurements;
    }

    /*
        Function to calculate the condition of the road based on the measured parameters
        Returns the icon file path
    */
    function calcRoadConditionIcon(speed, vibration) {
        var icon;

        if (speed > 15 && vibration < 1.2 && vibration > 0.8) {
            // Perfect Cycling Road
            icon = '/img/circle_green.png';
        } else {
            // Poor Cycling Road
            icon = '/img/circle_red.png';
        }

        return icon;
    }

    /*
        Function to calculate whether the condition of the road is perfect
        Returns true or false
    */
    function isPerfectCondition(speed, vibration) {
        if (speed > 15 && vibration < 1.2 && vibration > 0.8) {
            // Perfect Cycling Road
            return true;
        } else {
            // Poor Cycling Road
            return false;
        }
    }

    /*
        Function to calculate whether the condition of the road is poor
        Returns true or false
    */
    function isPoorCondition(speed, vibration) {
        if (speed > 15 && vibration < 1.2 && vibration > 0.8) {
            // Perfect Cycling Road
            return false;
        } else {
            // Poor Cycling Road
            return true;
        }
    }

});
<commit_msg>Added dark-map<commit_after>"use strict"

// MAP
$( document ).ready(function() {

    // INIT
    L.mapbox.accessToken = getMapboxAccessToken();
    var map = L.mapbox.map('map').setView([51.961298, 7.625849], 14);

    L.control.layers({
        'Streets': L.mapbox.tileLayer('mapbox.streets').addTo(map),
        'Satellite': L.mapbox.tileLayer('mapbox.satellite'),
        'Light': L.mapbox.tileLayer('mapbox.light'),
        'Dark': L.mapbox.tileLayer('mapbox.dark')
    }).addTo(map);

    var boxes = [];
    var markers = [];
    requestData();

    // MAP-FUNCTION
    map.on('zoomend', function() {
        console.log(map.getZoom());
        if (map.getZoom() >= 14) {
            map.featureLayer.setFilter(function() { return true; });
        } else {
            map.featureLayer.setFilter(function() { return false; });
        }
    });

    // REQUEST DATA FROM API
    function requestData(){
        $.ajax({
            url: getURL() + "/boxes",
            global: false,
            type: 'GET',
            async: false,
            success: function(data) {
                boxes = data;
                boxes.forEach(function (box, key) {
                    $.ajax({
                        url: getURL() + "/boxes/" + box._id + "/tracks",
                        global: false,
                        type: 'GET',
                        async: false,
                        success: function(data) {
                            box.tracks = data;
                            box.tracks.forEach(function (track, key) {
                                $.ajax({
                                    url: getURL() + "/boxes/" + box._id + "/tracks/" + track._id + "/measurements",
                                    global: false,
                                    type: 'GET',
                                    async: false,
                                    success: function(data) {
                                        track.measurements = data;
                                    }
                                });
                            });
                        }
                    });
                });
                drawMarkers();
            }
        });
    }

    function drawMarkers() {

        var geoJsonFeatures = [];

        boxes.forEach(function (box, key) {
            box.tracks.forEach(function (track, key) {

                // Interpolate the data before the visualization
                track.measurements = interpolate(track.measurements);

                track.measurements.forEach(function (measurement, key) {

                    geoJsonFeatures.push(
                        {
                            type: 'Feature',
                            geometry: {
                                type: 'Point',
                                coordinates: [
                                    measurement.lng, measurement.lat,
                                ]
                            },
                            'properties': {
                                'title': '
' + box._id + ' BoxId
' +
                                    '
' + track._id + ' TrackId
',
                                'description': '

' +
                                    '
Longitude	' + measurement.lng + '
' +
                                    '
Latitude	' + measurement.lat + '
' +
                                    '
Altitude	' + measurement.altitude + '
' +
                                    '
Speed	' + measurement.speed + '
' +
                                    '
Vibration	' + measurement.vibration + '
' +
                                    '
Sound	' + measurement.sound + '
' +
                                    '
Brightness	' + measurement.brightness + '
' +
                                    '
IR	' + measurement.ir + '
' +
                                    '
UV	' + measurement.uv + '
' +
                                    '

',
                                'perfect': isPerfectCondition(measurement.speed, measurement.vibration),
                                'poor': isPoorCondition(measurement.speed, measurement.vibration),
                                'icon': {
                                    'iconUrl': calcRoadConditionIcon(measurement.speed, measurement.vibration),
                                    'iconSize': [12, 12], // size of the icon
                                    'iconAnchor': [6, 6], // point of the icon which will correspond to marker's location
                                    'popupAnchor': [0, -6], // point from which the popup should open relative to the iconAnchor
                                    'className': 'dot'
                                }
                            }
                        }
                    );
                });
            });
        });

        // Add markers to the map
        var markers = L.mapbox.featureLayer().addTo(map);
        markers.on('layeradd', function(e) {
            var marker = e.layer;
            var feature = marker.feature;
            marker.setIcon(L.icon(feature.properties.icon));
        });
        markers.setGeoJSON(geoJsonFeatures);

        $('.menu-ui a').on('click', function() {
            // For each filter link, get the 'data-filter' attribute value.
            var filter = $(this).data('filter');
            $(this).addClass('active').siblings().removeClass('active');
            markers.setFilter(function(f) {
                // If the data-filter attribute is set to "all", return
                // all (true). Otherwise, filter on markers that have
                // a value set to true based on the filter name.
                return (filter === 'all') ? true : f.properties[filter] === true;
            });
            return false;
        });
    };

    /*
        Function to interpolate the speed and vibration values
    */
    function interpolate(measurements) {
        for (var i = 2; i < measurements.length - 2; i++) {
            var m_2 = measurements[i-2],
                m_1 = measurements[i-1],
                m = measurements[i],
                m1 = measurements[i+1],
                m2 = measurements[i+2];
            measurements[i].speed = (m_2.speed + m_1.speed + m.speed + m1.speed + m2.speed) / 5;
            measurements[i].vibration = (m_2.vibration + m_1.vibration + m.vibration + m1.vibration + m2.vibration) / 5;
        }

        return measurements;
    }

    /*
        Function to calculate the condition of the road based on the measured parameters
        Returns the icon file path
    */
    function calcRoadConditionIcon(speed, vibration) {
        var icon;

        if (speed > 15 && vibration < 1.2 && vibration > 0.8) {
            // Perfect Cycling Road
            icon = '/img/circle_green.png';
        } else {
            // Poor Cycling Road
            icon = '/img/circle_red.png';
        }

        return icon;
    }

    /*
        Function to calculate whether the condition of the road is perfect
        Returns true or false
    */
    function isPerfectCondition(speed, vibration) {
        if (speed > 15 && vibration < 1.2 && vibration > 0.8) {
            // Perfect Cycling Road
            return true;
        } else {
            // Poor Cycling Road
            return false;
        }
    }

    /*
        Function to calculate whether the condition of the road is poor
        Returns true or false
    */
    function isPoorCondition(speed, vibration) {
        if (speed > 15 && vibration < 1.2 && vibration > 0.8) {
            // Perfect Cycling Road
            return false;
        } else {
            // Poor Cycling Road
            return true;
        }
    }

});
<|endoftext|>


<commit_before>/**
 * Compose user messages.
 */

// Internal packages:
const rulesWrapper = require('./rules-wrapper')
,   english = require('./l10n-en_GB')
;

// Constants:
const en_GB = english.messages;

// Variables:
var lang;

/**
 * Set a locale to be used globally by this module.
 *
 * @param {String} language - locale, expressed as a string, eg en_GB.
 */

exports.setLanguage = function(language) {
    if (!language)
        throw new Error('l10n.setLanguage() invoked without passing a language code as parameter');
    else if (language.match(/^en([\.\-_]?gb)?$/i))
        lang = en_GB;
    else
        throw new Error('Language code passed to l10n.setLanguage() is not valid');
};

/**
 * @TODO Document.
 */

exports.message = function (profile, rule, key, extra) {
    const result = {};
    var name;
    if ('string' === typeof rule)
        name = rule;
    else
        name = rule.name;
    profile = profile.replace('-Echidna', '');
    if (!lang)
        throw new Error('l10n.message() invoked before a locale is defined; call l10n.setLanguage() first');
    else if (!rulesWrapper.hasOwnProperty(profile))
        throw new Error(`l10n.message(): unknown profile code “${profile}”`);
    else {
        if (!lang.hasOwnProperty(name + '.' + key))
            throw new Error(`l10n.message() could not interpret key “${name}.${key}”`);
        result.message = lang[name + '.' + key];
        if (false === result.message)
            result.message = '';
        else
            result.message = `<div class="message">${result.message}</div>`;
        if (extra)
            result.message = result.message.replace(/\$\{([^\}]+)\}/g, function interpolate (m, p1) {
                if (extra.hasOwnProperty(p1))
                    return extra[p1];
                else
                    throw new Error(`l10n.message() could not interpolate variable “${p1}”`);
            });
        if (rule.section && rule.rule) {
            result.message += `<div class="quote">${rulesWrapper[profile][rule.section][rule.rule].text}</div>`;
            result.id = rule.rule;
            result.name = rule.name;
        }
        return result;
    }
};
<commit_msg>Fix #386<commit_after>/**
 * Compose user messages.
 */

// Internal packages:
const rulesWrapper = require('./rules-wrapper')
,   english = require('./l10n-en_GB')
;

// Constants:
const en_GB = english.messages;

// Variables:
var lang;

/**
 * Set a locale to be used globally by this module.
 *
 * @param {String} language - locale, expressed as a string, eg en_GB.
 */

exports.setLanguage = function(language) {
    if (!language)
        throw new Error('l10n.setLanguage() invoked without passing a language code as parameter');
    else if (language.match(/^en([\.\-_]?gb)?$/i))
        lang = en_GB;
    else
        throw new Error('Language code passed to l10n.setLanguage() is not valid');
};

/**
 * @TODO Document.
 */

exports.message = function (profile, rule, key, extra) {
    const result = {};
    var name;
    if ('string' === typeof rule)
        name = rule;
    else
        name = rule.name;
    profile = profile.replace('-Echidna', '');
    if (!lang)
        throw new Error('l10n.message() invoked before a locale is defined; call l10n.setLanguage() first');
    else if (!rulesWrapper.hasOwnProperty(profile))
        throw new Error(`l10n.message(): unknown profile code “${profile}”`);
    else {
        if (!lang.hasOwnProperty(name + '.' + key))
            throw new Error(`l10n.message() could not interpret key “${name}.${key}”`);
        result.message = lang[name + '.' + key];
        if (false === result.message)
            result.message = '';
        else
            result.message = `<div class="message">${result.message}</div>`;
        if (extra)
            result.message = result.message.replace(/\$\{([^\}]+)\}/g, function interpolate (m, p1) {
                if (extra.hasOwnProperty(p1))
                    return extra[p1];
                else
                    throw new Error(`l10n.message() could not interpolate variable “${p1}”`);
            });
        if (rule.section && rule.rule) {
            var selector;
            if (rulesWrapper[profile][rule.section]) {
                if (rulesWrapper[profile][rule.section][rule.rule]) {
                    if (rulesWrapper[profile][rule.section][rule.rule].text) {
                        result.message += `<div class="quote">${rulesWrapper[profile][rule.section][rule.rule].text}</div>`;
                    } else
                        selector = encodeURIComponent(`[${profile}][${rule.section}][${rule.rule}].text`);
                } else
                    selector = encodeURIComponent(`[${profile}][${rule.section}][${rule.rule}]`);
            } else
                selector = encodeURIComponent(`[${profile}][${rule.section}]`);
            if (selector)
                result.message += `
NB: Pubrules hit an internal error while checking this rule.
Please file this issue on GitHub to help developers fix the problem
(you can submit it as is; no additional information is required).
`;
            result.id = rule.rule;
            result.name = rule.name;
        }
        return result;
    }
};
<|endoftext|>


<commit_before>'use strict';

/**
 * less
 */
const Promise = require('bluebird');
const co = require('co');
const wrap = co.wrap;
const _ = require('lodash');
const pathFn = require('path');
const fs = Promise.promisifyAll(require('fs'));
const Debug = require('debug');

// less
const less = require('less');
less.renderAsync = Promise.promisify(less.render);
const AutoPrefix = require('less-plugin-autoprefix');
const NpmImport = require('less-plugin-npm-import');
const CleanCss = require('less-plugin-clean-css');

// get default options
const getDefaultOPtions = () => {
  const env = process.env.NODE_ENV || 'development';
  const options = {
    plugins: [
      new AutoPrefix({
        browsers: 'last 10 versions'
      }),
      new NpmImport() // prefix - default: npm://
    ]
  };

  // development
  //  - sourceMaps
  if (env === 'development') {
    options.sourceMaps = {
      sourceMapFileInline: true
    };
  }

  // production
  //  - no sourceMaps
  //  - CleanCss
  if (env === 'production') {

    // no sourceMaps
    delete options.sourceMaps;

    // CleanCss
    options.plugins.push(new CleanCss({
      advanced: true
    }));
  }

  return options;
};

exports.renderFileAsync = co.wrap(function*(options) {
  // read
  const content = yield fs.readFileAsync(options.filename, 'utf8');
  const debug = Debug('predator:less');

  /**
   * options 现有
   * 	- filename
   * 	- paths
   *
   * 设置 plugins
   * 	- 共用
   * 		- autoprefix
   * 		- npm import
   * 	- development
   * 		- sourceMaps
   * 	- production
   * 		- clean css
   */
  options = _.merge(getDefaultOPtions(), options);

  // render
  let output;

  try {
    debug('render options %j', options);
    output = yield less.renderAsync(content, options);
  } catch (e) {
    e.message = less.formatError(e);
    throw e;
  }

  // return
  return output.css;
});<commit_msg>less: fix sourceMap<commit_after>'use strict';

/**
 * less
 */
const Promise = require('bluebird');
const co = require('co');
const wrap = co.wrap;
const _ = require('lodash');
const pathFn = require('path');
const fs = Promise.promisifyAll(require('fs'));
const Debug = require('debug');

// less
const less = require('less');
less.renderAsync = Promise.promisify(less.render);
const AutoPrefix = require('less-plugin-autoprefix');
const NpmImport = require('less-plugin-npm-import');
const CleanCss = require('less-plugin-clean-css');

// get default options
const getDefaultOPtions = () => {
  const env = process.env.NODE_ENV || 'development';
  const options = {
    plugins: [
      new AutoPrefix({
        browsers: 'last 10 versions'
      }),
      new NpmImport() // prefix - default: npm://
    ]
  };

  // development
  //  - sourceMaps
  if (env === 'development') {
    options.sourceMap = options.sourceMap || {};
    options.sourceMap.sourceMapFileInline = true;
  }

  // production
  //  - no sourceMaps
  //  - CleanCss
  if (env === 'production') {

    // no sourceMaps
    delete options.sourceMaps;

    // CleanCss
    options.plugins.push(new CleanCss({
      advanced: true
    }));
  }

  return options;
};

exports.renderFileAsync = co.wrap(function*(options) {
  // read
  const content = yield fs.readFileAsync(options.filename, 'utf8');
  const debug = Debug('predator:less');

  /**
   * options 现有
   * 	- filename
   * 	- paths
   *
   * 设置 plugins
   * 	- 共用
   * 		- autoprefix
   * 		- npm import
   * 	- development
   * 		- sourceMaps
   * 	- production
   * 		- clean css
   */
  options = _.merge(getDefaultOPtions(), options);

  // render
  let output;

  try {
    debug('render options %j', options);
    output = yield less.renderAsync(content, options);
  } catch (e) {
    e.message = less.formatError(e);
    throw e;
  }

  // return
  return output.css;
});<|endoftext|>


<commit_before>'use strict';
var path = require('path');
var when = require('when');
var u    = {
  run     : require('../util/run'),
  switches: require('../util/switches')
};

/**
 * List contents of archive.
 * @promise List
 * @param archive {string} Path to the archive.
 * @param options {Object} An object of acceptable options to 7za bin.
 * @progress {array} Listed files and directories.
 * @resolve {Object} Tech spec about the archive.
 * @reject {Error} The error as issued by 7-Zip.
 */
module.exports = function (archive, options) {
  return when.promise(function (resolve, reject, progress) {

    var spec  = {};
    /* jshint maxlen: 130 */
    var regex = /(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) ([\.DA]+) +(\d+) +(\d+)? +(.+)/;
    /* jshint maxlen: 80 */

    // Create a string that can be parsed by `run`.
    var command = '7z l "' + archive + '" ';

    var buffer = ""; //Store imcomplete line of a progress data.
    // Start the command
    u.run(command, options)

    // When a stdout is emitted, parse each line and search for a pattern. When
    // the pattern is found, extract the file (or directory) name from it and
    // pass it to an array. Finally returns this array.
    .progress(function (data) {
      var entries = [];

      // Last progress had an incomplete line. Prepend it to the data and clear
      // buffer.
      if (buffer.length > 0) {
        data = buffer + data;
        buffer = "";
      }

      data.split('\n').forEach(function (line) {

        // Populate the tech specs of the archive that are passed to the
        // resolve handler.
        if (line.substr(0, 7) === 'Path = ') {
          spec.path = line.substr(7, line.length);
        } else if (line.substr(0, 7) === 'Type = ') {
          spec.type = line.substr(7, line.length);
        } else if (line.substr(0, 9) === 'Method = ') {
          spec.method = line.substr(9, line.length);
        } else if (line.substr(0, 16) === 'Physical Size = ') {
          spec.physicalSize = parseInt(line.substr(16, line.length), 10);
        } else if (line.substr(0, 15) === 'Headers Size = ') {
          spec.headersSize = parseInt(line.substr(15, line.length), 10);
        } else {
          // Parse the stdout to find entries
          var res = regex.exec(line);
          if (res) {
            var e = {
              date: new Date(res[1]),
              attr: res[2],
              size: parseInt(res[3], 10),
              name: res[5].replace(path.sep, '/')
            };

            entries.push(e);
          }

          // Line may be incomplete, Save it to the buffer.
          else buffer = line;

        }
      });
      return progress(entries);
    })

    // When all is done resolve the Promise.
    .then(function () {
      return resolve(spec);
    })

    // Catch the error and pass it to the reject function of the Promise.
    .catch(function (err) {
      return reject(err);
    });

  });
};
<commit_msg>Specify correct attribute flags<commit_after>'use strict';
var path = require('path');
var when = require('when');
var u    = {
  run     : require('../util/run'),
  switches: require('../util/switches')
};

/**
 * List contents of archive.
 * @promise List
 * @param archive {string} Path to the archive.
 * @param options {Object} An object of acceptable options to 7za bin.
 * @progress {array} Listed files and directories.
 * @resolve {Object} Tech spec about the archive.
 * @reject {Error} The error as issued by 7-Zip.
 */
module.exports = function (archive, options) {
  return when.promise(function (resolve, reject, progress) {

    var spec  = {};
    /* jshint maxlen: 130 */
    var regex = /(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) ([\.D][\.R][\.H][\.S][\.A]) +(\d+) +(\d+)? +(.+)/;
    /* jshint maxlen: 80 */

    // Create a string that can be parsed by `run`.
    var command = '7z l "' + archive + '" ';

    var buffer = ""; //Store imcomplete line of a progress data.
    // Start the command
    u.run(command, options)

    // When a stdout is emitted, parse each line and search for a pattern. When
    // the pattern is found, extract the file (or directory) name from it and
    // pass it to an array. Finally returns this array.
    .progress(function (data) {
      var entries = [];

      // Last progress had an incomplete line. Prepend it to the data and clear
      // buffer.
      if (buffer.length > 0) {
        data = buffer + data;
        buffer = "";
      }

      data.split('\n').forEach(function (line) {

        // Populate the tech specs of the archive that are passed to the
        // resolve handler.
        if (line.substr(0, 7) === 'Path = ') {
          spec.path = line.substr(7, line.length);
        } else if (line.substr(0, 7) === 'Type = ') {
          spec.type = line.substr(7, line.length);
        } else if (line.substr(0, 9) === 'Method = ') {
          spec.method = line.substr(9, line.length);
        } else if (line.substr(0, 16) === 'Physical Size = ') {
          spec.physicalSize = parseInt(line.substr(16, line.length), 10);
        } else if (line.substr(0, 15) === 'Headers Size = ') {
          spec.headersSize = parseInt(line.substr(15, line.length), 10);
        } else {
          // Parse the stdout to find entries
          var res = regex.exec(line);
          if (res) {
            var e = {
              date: new Date(res[1]),
              attr: res[2],
              size: parseInt(res[3], 10),
              name: res[5].replace(path.sep, '/')
            };

            entries.push(e);
          }

          // Line may be incomplete, Save it to the buffer.
          else buffer = line;

        }
      });
      return progress(entries);
    })

    // When all is done resolve the Promise.
    .then(function () {
      return resolve(spec);
    })

    // Catch the error and pass it to the reject function of the Promise.
    .catch(function (err) {
      return reject(err);
    });

  });
};
<|endoftext|>


<commit_before>var _ = require('underscore');
var keystone = require('../');
var schemaPlugins = require('./schemaPlugins');
var utils = require('keystone-utils');
var random = require('mongoose-simple-random');
/**
 * List Class
 *
 * @param {String} key
 * @param {Object} options
 */

function List(key, options) {
	if (!(this instanceof List)) return new List(key, options);

	var defaultOptions = {
		schema: {
			collection: keystone.prefixModel(key)
		},
		noedit: false,
		nocreate: false,
		nodelete: false,
		autocreate: false,
		sortable: false,
		hidden: false,
		track: false,
		inherits: false,
		searchFields: '__name__',
		defaultSort: '__default__',
		defaultColumns: '__name__'
	};

	// initialFields values are initialised on demand by the getter
	var initialFields;

	// Inherit default options from parent list if it exists
	if (options && options.inherits) {
		if (options.inherits.options && options.inherits.options.inherits) {
			throw new Error('Inherited Lists may not contain any inheritance');
		}
		defaultOptions = utils.options(defaultOptions, options.inherits.options);
	}

	this.options = utils.options(defaultOptions, options);

	// init properties
	this.key = key;
	this.path = this.get('path') || utils.keyToPath(key, true);
	this.schema = new keystone.mongoose.Schema({}, this.options.schema);
	this.schema.plugin(random);
	this.schemaFields = [];
	this.uiElements = [];
	this.underscoreMethods = {};
	this.fields = {};
	this.fieldsArray = [];
	this.fieldTypes = {};
	this.relationshipFields = [];
	this.relationships = {};
	this.mappings = {
		name: null,
		createdBy: null,
		createdOn: null,
		modifiedBy: null,
		modifiedOn: null
	};

	// init mappings
	_.each(this.options.map, function(val, key) { this.map(key, val); }, this);

	// define property getters
	Object.defineProperty(this, 'label', { get: function() {
		return this.get('label') || this.set('label', utils.plural(utils.keyToLabel(key)));
	} });
	Object.defineProperty(this, 'singular', { get: function() {
		return this.get('singular') || this.set('singular', utils.singular(this.label));
	} });
	Object.defineProperty(this, 'plural', { get: function() {
		return this.get('plural') || this.set('plural', utils.plural(this.singular));
	} });
	Object.defineProperty(this, 'namePath', { get: function() {
		return this.mappings.name || '_id';
	} });
	Object.defineProperty(this, 'nameField', { get: function() {
		return this.fields[this.mappings.name];
	} });
	Object.defineProperty(this, 'nameIsVirtual', { get: function() {
		return this.model.schema.virtuals[this.mappings.name] ? true : false;
	} });
	Object.defineProperty(this, 'nameIsEditable', { get: function() {
		return (this.fields[this.mappings.name] && this.fields[this.mappings.name].type === 'text') ? !this.fields[this.mappings.name].noedit : false;
	} });
	Object.defineProperty(this, 'nameIsInitial', { get: function() {
		return (this.fields[this.mappings.name] && this.fields[this.mappings.name].options.initial === undefined);
	} });
	Object.defineProperty(this, 'initialFields', { get: function() {
		return initialFields || (initialFields = _.filter(this.fields, function(i) { return i.initial; }));
	} });
	if (this.get('sortable')) {
		schemaPlugins.sortable.apply(this);
	}
	if (this.get('autokey')) {
		schemaPlugins.autokey.apply(this);
	}
	if (this.get('track')) {
		schemaPlugins.track.apply(this);
	}
	if (this.get('history')) {
		schemaPlugins.history.apply(this);
	}
	if (this.get('inherits')) {
		var parentFields = this.get('inherits').schemaFields;
		this.add.apply(this, parentFields);
	}
}

// Search Fields
Object.defineProperty(List.prototype, 'searchFields', {
	get: function() {
		if (!this._searchFields) {
			this._searchFields = this.expandPaths(this.get('searchFields'));
		}
		return this._searchFields;
	}, set: function(value) {
		this.set('searchFields', value);
		delete this._searchFields;
	}
});

// Default Sort Field
Object.defineProperty(List.prototype, 'defaultSort', {
	get: function() {
		var ds = this.get('defaultSort');
		return (ds === '__default__') ? (this.get('sortable') ? 'sortOrder' : this.namePath) : ds;
	}, set: function(value) {
		this.set('defaultSort', value);
	}
});

// Default Column Fields
Object.defineProperty(List.prototype, 'defaultColumns', {
	get: function() {
		if (!this._defaultColumns) {
			this._defaultColumns = this.expandColumns(this.get('defaultColumns'));
		}
		return this._defaultColumns;
	}, set: function(value) {
		this.set('defaultColumns', value);
		delete this._defaultColumns;
	}
});

<<<<<<< HEAD

/**
 * Registers relationships to this list defined on others
 *
 * @api public
 */

List.prototype.relationship = function(def) {
	if (arguments.length > 1) {
		_.map(arguments, function(def) { this.relationship(def); }, this);
		return this;
	}

	if ('string' === typeof def) {
		def = { ref: def };
	}

	if (!def.ref) {
		throw new Error('List Relationships must be specified with an object containing ref (' + this.key + ')');
	}

	if (!def.refPath) {
		def.refPath = utils.downcase(this.key);
	}

	if (!def.path) {
		def.path = utils.keyToProperty(def.ref, true);
	}

	Object.defineProperty(def, 'refList', {
		get: function() {
			return keystone.list(def.ref);
		}
	});

	Object.defineProperty(def, 'isValid', {
		get: function() {
			return keystone.list(def.ref) ? true : false;
		}
	});

	this.relationships[def.path] = def;
	return this;
};

/**
 * Registers the Schema with Mongoose, and the List with Keystone
 *
 * Also adds default fields and virtuals to the schema for the list
 *
 * @api public
 */

List.prototype.register = function() {
	var list = this;

	this.schema.virtual('list').get(function () {
		return list;
	});

	if (!_.isEmpty(this.relationships)) {
		this.schema.methods.getRelated = schemaPlugins.methods.getRelated;
		this.schema.methods.populateRelated = schemaPlugins.methods.populateRelated;
		if (!this.schema.options.toObject) this.schema.options.toObject = {};
		this.schema.options.toObject.transform = schemaPlugins.options.transform;
	}

	this.schema.virtual('_').get(function() {
		if (!this.__methods) {
			this.__methods = utils.bindMethods(list.underscoreMethods, this);
		}
		return this.__methods;
	});

	this.schema.method('getUpdateHandler', function(req, res, ops) {
		return new UpdateHandler(list, this, req, res, ops);
	});

	if (this.get('inherits')) {
		this.model = this.get('inherits').model.discriminator(this.key, this.schema);
	} else {
		this.model = keystone.mongoose.model(this.key, this.schema);
	}

	require('../').list(this);

	return this;
};

/**
 * Gets the name of the provided document from the correct path
 *
 * ####Example:
 *
 *     var name = list.getDocumentName(item)
 *
 * @param {Object} item
 * @param {Boolean} escape - causes HTML entities to be encoded
 * @api public
 */

List.prototype.getDocumentName = function(doc, escape) {
	var name = String(this.nameField ? this.nameField.format(doc) : doc.get(this.namePath));
	return (escape) ? utils.encodeHTMLEntities(name) : name;
};

/**
 * Processes a filter string into a filters object
 *
 * @param {String} filters
 * @api private
 */

List.prototype.processFilters = function(q) {
	var list = this;
	var filters = {};
	queryfilterlib.QueryFilters.create(q).getFilters().forEach(function(filter){
		filter.path = filter.key; // alias for b/c
		filter.field = list.fields[filter.key];
		filters[filter.path] = filter;
	});
	return filters;
};

/**
 * Gets filters for a Mongoose query that will search for the provided string,
 * based on the searchFields List option.
 *
 * Also accepts a filters object from `processFilters()`, any of which may
 * override the search string.
 *
 * ####Example:
 *
 *     list.getSearchFilters('jed') // returns { name: /jed/i }
 *
 * @param {String} query
 * @param {Object} additional filters
 * @api public
 */

List.prototype.getSearchFilters = function(search, add) {
	var filters = {};
	var list = this;

	search = String(search || '').trim();

	if (search.length) {
		var searchFilter,
			searchParts = search.split(' '),
			searchRx = new RegExp(utils.escapeRegExp(search), 'i'),
			splitSearchRx = new RegExp((searchParts.length > 1) ? _.map(searchParts, utils.escapeRegExp).join('|') : search, 'i'),
			searchFields = this.get('searchFields'),
			searchFilters = [],
			searchIdField = utils.isValidObjectId(search);

		if ('string' === typeof searchFields) {
			searchFields = searchFields.split(',');
		}

		searchFields.forEach(function(path) {
			path = path.trim();

			if (path === '__name__') {
				path = list.mappings.name;
			}

			var field = list.fields[path];

			if (field && field.type === 'name') {
				var first = {};
				first[field.paths.first] = splitSearchRx;
				var last = {};
				last[field.paths.last] = splitSearchRx;
				searchFilter = {};
				searchFilter.$or = [first, last];
				searchFilters.push(searchFilter);
			} else {
				searchFilter = {};
				searchFilter[path] = searchRx;
				searchFilters.push(searchFilter);
			}
		});

		if (list.autokey) {
			searchFilter = {};
			searchFilter[list.autokey.path] = searchRx;
			searchFilters.push(searchFilter);
		}

		if (searchIdField) {
			searchFilter = {};
			searchFilter._id = search;
			searchFilters.push(searchFilter);
		}

		if (searchFilters.length > 1) {
			filters.$or = searchFilters;
		} else if (searchFilters.length) {
			filters = searchFilters[0];
		}

	}

	if (add) {
		_.each(add, function(filter) {
			var cond, path = filter.key, value = filter.value;

			switch (filter.field.type) {
				case 'boolean':
					if (!value || value === 'false') {
						filters[path] = { $ne: true };
					} else {
						filters[path] = true;
					}
					break;

				case 'localfile':
				case 'cloudinaryimage':
				case 'cloudinaryimages':
				case 's3file':
				case 'name':
				case 'password':
					// TODO
					break;

				case 'location':
					_.each(['street1', 'suburb', 'state', 'postcode', 'country'], function(pathKey, i) {
						var value = filter.value[i];
						if (value) {
							filters[filter.field.paths[pathKey]] = new RegExp(utils.escapeRegExp(value), 'i');
						}
					});
					break;

				case 'relationship':
					if (value) {
						if (filter.field.many) {
							filters[path] = (filter.inverse) ? { $nin: [value] } : { $in: [value] };
						} else {
							filters[path] = (filter.inverse) ? { $ne: value } : value;
						}
					} else {
						if (filter.field.many) {
							filters[path] = (filter.inverse) ? { $not: { $size: 0 } } : { $size: 0 };
						} else {
							filters[path] = (filter.inverse) ? { $ne: null } : null;
						}
					}
					// TODO: Searching on "not linked to" (null) values seems to return all results.
					// console.log(filter.field.path + ':');
					// console.log(filters[filter.field.path]);
					break;

				case 'select':
					if (filter.value) {
						filters[path] = (filter.inverse) ? { $ne: value } : value;
					} else {
						filters[path] = (filter.inverse) ? { $nin: ['', null] } : { $in: ['', null] };
					}
					break;

				case 'number':
				case 'money':
					if (filter.operator === 'bt') {
						value = [
							utils.number(value[0]),
							utils.number(value[1])
						];
						if ( !isNaN(value[0]) && !isNaN(value[1]) ) {
							filters[path] = {
								$gte: value[0],
								$lte: value[1]
							};
						}
						else {
							filters[path] = null;
						}
					}
					else {
						value = utils.number(value);
						if ( !isNaN(value) ) {
							if (filter.operator === 'gt') {
								filters[path] = { $gt: value };
							}
							else if (filter.operator === 'lt') {
								filters[path] = { $lt: value };
							}
							else {
								filters[path] = value;
							}
						}
						else {
							filters[path] = null;
						}
					}
				break;

				case 'date':
				case 'datetime':
					if (filter.operator === 'bt') {
						value = [
							moment(value[0]),
							moment(value[1])
						];
						if ( (value[0] && value[0].isValid()) && (value[1] && value[0].isValid()) ) {
							filters[path] = {
								$gte: moment(value[0]).startOf('day').toDate(),
								$lte: moment(value[1]).endOf('day').toDate()
							};
						}
					}
					else {
						value = moment(value);
						if (value && value.isValid()) {
							var start = moment(value).startOf('day').toDate();
							var end = moment(value).endOf('day').toDate();
							if (filter.operator === 'gt') {
								filters[path] = { $gt: end };
							} else if (filter.operator === 'lt') {
								filters[path] = { $lt: start };
							} else {
								filters[path] = { $lte: end, $gte: start };
							}
						}
					}
					break;

				case 'text':
				case 'textarea':
				case 'html':
				case 'email':
				case 'url':
				case 'key':
					if (filter.exact) {
						if (value) {
							cond = new RegExp('^' + utils.escapeRegExp(value) + '$', 'i');
							filters[path] = filter.inverse ? { $not: cond } : cond;
						} else {
							if (filter.inverse) {
								filters[path] = { $nin: ['', null] };
							} else {
								filters[path] = { $in: ['', null] };
							}
						}
					} else if (value) {
						cond = new RegExp(utils.escapeRegExp(value), 'i');
						filters[path] = filter.inverse ? { $not: cond } : cond;
					}
					break;

			}
		});
	}
	return filters;
};

/**
 * Updates every document in a List,
 * setting the provided data on each.
 *
 * @param {Object} data
 * @param {Function} callback (optional)
 * @api public
 */

List.prototype.updateAll = function(data, callback) {
	if ('function' === typeof data) {
		callback = data;
		data = null;
	}
	callback = callback || function() {};
	this.model.find(function(err, results) {
		if (err) return callback(err);
		async.eachSeries(results, function(doc, next) {
			if (data) {
				doc.set(data);
			}
			doc.save(next);
		}, function(err) {
			callback(err);
		});
	});
};

/**
 * Gets a unique value from a generator method by checking for documents with the same value.
 *
 * To avoid infinite loops when a unique value cannot be found, it will bail and pass back an
 * undefined value after 10 attemptes.
 *
 * WARNING: Because there will always be a small amount of time between checking for an
 * existing value and saving a document, race conditions can occur and it is possible that
 * another document has the 'unique' value assigned at the same time.
 *
 * Because of this, if true uniqueness is required, you should also create a unique index on
 * the database path, and handle duplicate errors thrown on save.
 *
 * @param {String} path to check for uniqueness
 * @param {Function} generator method to call to generate a new value
 * @param {Number} the maximum number of attempts (optional, defaults to 10)
 * @param {Function} callback(err, uniqueValue)
 * @api public
 */

List.prototype.getUniqueValue = function(path, generator, limit, callback) {
	var model = this.model;
	var count = 0;
	var value;

	if (utils.isFunction(limit)) {
		callback = limit;
		limit = 10;
	}

	if (utils.isArray(generator)) {
		var fn = generator[0];
		var args = generator.slice(1);
		generator = function() {
			return fn.apply(this, args);
		};
	}

	var check = function() {
		if (count++ > 10) {
			return callback(undefined, undefined);
		}
		value = generator();
		model.count().where(path, value).exec(function(err, matches) {
			if (err) return callback(err);
			if (matches) return check();
			callback(undefined, value);
		});
	};

	check();
};

/**
 * Generate page array for pagination
 *
 * @param {Number} the maximum number pages to display in the pagination
 * @param {Object} page options
 * @api public
 */
List.prototype.getPages = function(options, maxPages) {
	var surround = Math.floor(maxPages / 2);
	var firstPage = maxPages ? Math.max(1, options.currentPage - surround) : 1;
	var padRight = Math.max(((options.currentPage - surround) - 1) * -1, 0);
	var lastPage = maxPages ? Math.min(options.totalPages, options.currentPage + surround + padRight) : options.totalPages;
	var padLeft = Math.max(((options.currentPage + surround) - lastPage), 0);

	options.pages = [];

	firstPage = Math.max(Math.min(firstPage, firstPage - padLeft), 1);

	for (var i = firstPage; i <= lastPage; i++) {
		options.pages.push(i);
	}

	if (firstPage !== 1) {
		options.pages.shift();
		options.pages.unshift('...');
	}

	if (lastPage !== Number(options.totalPages)) {
		options.pages.pop();
		options.pages.push('...');
	}
};

/**
 * Gets a special Query object that will paginate documents in the list
 *
 * ####Example:
 *
 *     list.paginate({
 *         page: 1,
 *         perPage: 100,
 *         maxPages: 10
 *     }).exec(function(err, results) {
 *         // do something
 *     });
 *
 * @param {Object} options
 * @param {Function} callback (optional)
 * @api public
 */

List.prototype.paginate = function(options, callback) {
	var list = this;
	var model = this.model;

	options = options || {};

	var query = model.find(options.filters);

	query._original_exec = query.exec;
	query._original_sort = query.sort;
	query._original_select = query.select;

	var currentPage = Number(options.page) || 1;
	var resultsPerPage = Number(options.perPage) || 50;
	var maxPages = Number(options.maxPages) || 10;
	var skip = (currentPage - 1) * resultsPerPage;

	list.pagination = { maxPages: maxPages };

	// as of mongoose 3.7.x, we need to defer sorting and field selection
	// until after the count has been executed

	query.select = function() {
		options.select = arguments[0];
		return query;
	};

	query.sort = function() {
		options.sort = arguments[0];
		return query;
	};

	query.exec = function(callback) {
		query.count(function(err, count) {
			if (err) return callback(err);

			query.find().limit(resultsPerPage).skip(skip);

			// apply the select and sort options before calling exec
			if (options.select) {
				query._original_select(options.select);
			}

			if (options.sort) {
				query._original_sort(options.sort);
			}

			query._original_exec(function(err, results) {
				if (err) return callback(err);
				var totalPages = Math.ceil(count / resultsPerPage);
				var rtn = {
					total: count,
					results: results,
					currentPage: currentPage,
					totalPages: totalPages,
					pages: [],
					previous: (currentPage > 1) ? (currentPage - 1) : false,
					next: (currentPage < totalPages) ? (currentPage + 1) : false,
					first: skip + 1,
					last: skip + results.length
				};
				list.getPages(rtn, maxPages);
				callback(err, rtn);
			});
		});

	};

	if (callback) {
		return query(callback);
	} else {
		return query;
	}
};

=======
// Add prototype methods
List.prototype.set = require('./list/set');
List.prototype.get = List.prototype.set;
List.prototype.add = require('./list/add');
List.prototype.map = require('./list/map');
List.prototype.automap = require('./list/automap');
List.prototype.field = require('./list/field');
List.prototype.relationship = require('./list/relationship');
List.prototype.underscoreMethod = require('./list/underscoreMethod');
List.prototype.register = require('./list/register');
List.prototype.getCSV = require('./list/getCSV');
List.prototype.getData = require('./list/getData');
List.prototype.getOptions = require('./list/getOptions');
List.prototype.getAdminURL = require('./list/getAdminURL');
List.prototype.getDocumentName = require('./list/getDocumentName');
List.prototype.addSearchToQuery = require('./list/addSearchToQuery');
List.prototype.addFiltersToQuery = require('./list/addFiltersToQuery');
List.prototype.isReserved = require('./list/isReserved');
List.prototype.expandColumns = require('./list/expandColumns');
List.prototype.expandPaths = require('./list/expandPaths');
List.prototype.expandSort = require('./list/expandSort');
List.prototype.selectColumns = require('./list/selectColumns');
List.prototype.processFilters = require('./list/processFilters');
List.prototype.getSearchFilters = require('./list/getSearchFilters');
List.prototype.updateAll = require('./list/updateAll');
List.prototype.getUniqueValue = require('./list/getUniqueValue');
List.prototype.getPages = require('./list/getPages');
List.prototype.paginate = require('./list/paginate');
>>>>>>> keystonejs/master

/*!
 * Export class
 */
exports = module.exports = List;
<commit_msg>delete some errors from last merge<commit_after>var _ = require('underscore');
var keystone = require('../');
var schemaPlugins = require('./schemaPlugins');
var utils = require('keystone-utils');

/**
 * List Class
 *
 * @param {String} key
 * @param {Object} options
 */

function List(key, options) {
	if (!(this instanceof List)) return new List(key, options);

	var defaultOptions = {
		schema: {
			collection: keystone.prefixModel(key)
		},
		noedit: false,
		nocreate: false,
		nodelete: false,
		autocreate: false,
		sortable: false,
		hidden: false,
		track: false,
		inherits: false,
		searchFields: '__name__',
		defaultSort: '__default__',
		defaultColumns: '__name__'
	};

	// initialFields values are initialised on demand by the getter
	var initialFields;

	// Inherit default options from parent list if it exists
	if (options && options.inherits) {
		if (options.inherits.options && options.inherits.options.inherits) {
			throw new Error('Inherited Lists may not contain any inheritance');
		}
		defaultOptions = utils.options(defaultOptions, options.inherits.options);
	}

	this.options = utils.options(defaultOptions, options);

	// init properties
	this.key = key;
	this.path = this.get('path') || utils.keyToPath(key, true);
	this.schema = new keystone.mongoose.Schema({}, this.options.schema);
	this.schemaFields = [];
	this.uiElements = [];
	this.underscoreMethods = {};
	this.fields = {};
	this.fieldsArray = [];
	this.fieldTypes = {};
	this.relationshipFields = [];
	this.relationships = {};
	this.mappings = {
		name: null,
		createdBy: null,
		createdOn: null,
		modifiedBy: null,
		modifiedOn: null
	};

	// init mappings
	_.each(this.options.map, function(val, key) { this.map(key, val); }, this);

	// define property getters
	Object.defineProperty(this, 'label', { get: function() {
		return this.get('label') || this.set('label', utils.plural(utils.keyToLabel(key)));
	} });
	Object.defineProperty(this, 'singular', { get: function() {
		return this.get('singular') || this.set('singular', utils.singular(this.label));
	} });
	Object.defineProperty(this, 'plural', { get: function() {
		return this.get('plural') || this.set('plural', utils.plural(this.singular));
	} });
	Object.defineProperty(this, 'namePath', { get: function() {
		return this.mappings.name || '_id';
	} });
	Object.defineProperty(this, 'nameField', { get: function() {
		return this.fields[this.mappings.name];
	} });
	Object.defineProperty(this, 'nameIsVirtual', { get: function() {
		return this.model.schema.virtuals[this.mappings.name] ? true : false;
	} });
	Object.defineProperty(this, 'nameIsEditable', { get: function() {
		return (this.fields[this.mappings.name] && this.fields[this.mappings.name].type === 'text') ? !this.fields[this.mappings.name].noedit : false;
	} });
	Object.defineProperty(this, 'nameIsInitial', { get: function() {
		return (this.fields[this.mappings.name] && this.fields[this.mappings.name].options.initial === undefined);
	} });
	Object.defineProperty(this, 'initialFields', { get: function() {
		return initialFields || (initialFields = _.filter(this.fields, function(i) { return i.initial; }));
	} });
	if (this.get('sortable')) {
		schemaPlugins.sortable.apply(this);
	}
	if (this.get('autokey')) {
		schemaPlugins.autokey.apply(this);
	}
	if (this.get('track')) {
		schemaPlugins.track.apply(this);
	}
	if (this.get('history')) {
		schemaPlugins.history.apply(this);
	}
	if (this.get('inherits')) {
		var parentFields = this.get('inherits').schemaFields;
		this.add.apply(this, parentFields);
	}
}

// Search Fields
Object.defineProperty(List.prototype, 'searchFields', {
	get: function() {
		if (!this._searchFields) {
			this._searchFields = this.expandPaths(this.get('searchFields'));
		}
		return this._searchFields;
	}, set: function(value) {
		this.set('searchFields', value);
		delete this._searchFields;
	}
});

// Default Sort Field
Object.defineProperty(List.prototype, 'defaultSort', {
	get: function() {
		var ds = this.get('defaultSort');
		return (ds === '__default__') ? (this.get('sortable') ? 'sortOrder' : this.namePath) : ds;
	}, set: function(value) {
		this.set('defaultSort', value);
	}
});

// Default Column Fields
Object.defineProperty(List.prototype, 'defaultColumns', {
	get: function() {
		if (!this._defaultColumns) {
			this._defaultColumns = this.expandColumns(this.get('defaultColumns'));
		}
		return this._defaultColumns;
	}, set: function(value) {
		this.set('defaultColumns', value);
		delete this._defaultColumns;
	}
});

// Add prototype methods
List.prototype.set = require('./list/set');
List.prototype.get = List.prototype.set;
List.prototype.add = require('./list/add');
List.prototype.map = require('./list/map');
List.prototype.automap = require('./list/automap');
List.prototype.field = require('./list/field');
List.prototype.relationship = require('./list/relationship');
List.prototype.underscoreMethod = require('./list/underscoreMethod');
List.prototype.register = require('./list/register');
List.prototype.getCSV = require('./list/getCSV');
List.prototype.getData = require('./list/getData');
List.prototype.getOptions = require('./list/getOptions');
List.prototype.getAdminURL = require('./list/getAdminURL');
List.prototype.getDocumentName = require('./list/getDocumentName');
List.prototype.addSearchToQuery = require('./list/addSearchToQuery');
List.prototype.addFiltersToQuery = require('./list/addFiltersToQuery');
List.prototype.isReserved = require('./list/isReserved');
List.prototype.expandColumns = require('./list/expandColumns');
List.prototype.expandPaths = require('./list/expandPaths');
List.prototype.expandSort = require('./list/expandSort');
List.prototype.selectColumns = require('./list/selectColumns');
List.prototype.processFilters = require('./list/processFilters');
List.prototype.getSearchFilters = require('./list/getSearchFilters');
List.prototype.updateAll = require('./list/updateAll');
List.prototype.getUniqueValue = require('./list/getUniqueValue');
List.prototype.getPages = require('./list/getPages');
List.prototype.paginate = require('./list/paginate');

/*!
 * Export class
 */
exports = module.exports = List;
<|endoftext|>


<commit_before>var _ = require('underscore');
var _s = require('underscore.string');
var uuid = require('node-uuid');
var async = require('async');
var redis = require('./redis-client');
var client = redis.client;
var lua = require('./lua');

/**
 * reapLock
 * Detects any child locks referenced in the key set that have expired and removes their
 * entries from the key set. Fires a callback with err.
 * @param {string} key the identifier of the shared lock for which to reap expired child locks
 * @param {function} callback signature (err)
 */
exports.reapLock = function(key, callback) {
  client.smembers(key, function(err, members) {
    if (err) { return callback(err); }

    iterator = function(member, callback) {
      client.get(member, function(err, value) {
        if (err || value) { return callback(err); }
        client.srem(key, member, function(err) {
          return callback(err);
        });
      });
    };

    async.each(members, iterator, callback);
  });
};

/**
 * acquireLock
 * Attempt to acquire a shared lock. Acquiring the lock will fail if maximumLocks or more
 * locks are already being held by other clients. Acquiring the lock creates a new lockId, adds it
 * to the key set, then sets the lockId with the passed TTL. Fires a callback with err and the
 * lockId if it was successfully acquired, otherwise null.
 * @param {string} key the identifier of the shared lock to acquire
 * @param {int} maximumLocks the maximum number of locks that can be held after a successful lock acquisition
 * @param {number} ttlSeconds the number of seconds for which to hold the lock
 * @param {function} callback signature (err, lockId if acquired else null)
 */
exports.acquireLock = function(key, maximumLocks, ttlSeconds, callback) {
  var lockId = uuid.v1();
  async.waterfall([
    function(cb) { return redis.ensureScript(client, lua.acquire_lock, cb); },
    function(cb) {
      client.eval(lua.acquire_lock, 1, key, lockId, maximumLocks, ttlSeconds, function(err, response) {
        if (err) { return cb(err, null); }
        return cb(null, response ? lockId : null);
      });
    }
  ], function(err, lockId) {
    if (err) { return callback(err, null); }
    return callback(null, lockId);
  });
};

/**
 * acquireMultipleLocks
 * Attempt to acquire multiple shared locks, all subject to the same maximumLocks and ttlSeconds.
 * Acquiring *all* of the locks will fail if maximumLocks or more locks are already being held by
 * other clients on *any* of the shared locks. If all locks are successfully acquired, separate lock
 * IDs are returned for each lock. Fires a callback with err and a mapping of keys to lock IDs if
 * all locks were successfully acquired, otherwise null.
 * @param {[string]} keys the identifiers of the shared locks to acquire
 * @param {int} maximumLocks the maximum number of locks (per key) that can be held after a successful lock acquisition
 * @param {number} ttlSeconds the number of seconds for which to hold each lock
 * @param {function} callback signature (err, lockIdMapping if acquired else null)
 */
exports.acquireMultipleLocks = function(keys, maximumLocks, ttlSeconds, callback) {
  var lockIds = _.map(keys, function(key) { return uuid.v1(); });
  var lockIdsPipeDelimited = lockIds.join('|');
  var evalArgs = _.flatten([lua.acquire_multiple_locks, keys.length, keys, lockIdsPipeDelimited, maximumLocks, ttlSeconds]);

  async.waterfall([
    function(cb) { return redis.ensureScript(client, lua.acquire_multiple_locks, cb); },
    function(cb) {
      client.eval(evalArgs, function(err, response) {
        if (err) { return cb(err, null); }
        var lockIdMapping = _.object(keys, lockIds);
        return cb(null, response ? lockIdMapping : null);
      });
    }
  ], function(err, lockIdMapping) {
    if (err) { return callback(err, null); }
    return callback(null, lockIdMapping);
  });
};

/**
 * releaseLock
 * Release any lock that is currently held with the passed lockId. This deletes the lock's key if
 * it exists, then removes the lockId from the key set. Fires a callback with err in either case.
 * @param {string} lockId lock identifier returned from a successful lock acquisition
 * @param {function} callback signature (err)
 */
exports.releaseLock = function(lockId, callback) {
  client.get(lockId, function(err, key) {
    if (err) { return callback(err); }
    client
      .multi()
      .srem(key, lockId)
      .del(lockId)
      .exec(function(err) {
        return callback(err);
      });
  });
};
<commit_msg>Remove some extraneous args to callbacks when erroring<commit_after>var _ = require('underscore');
var _s = require('underscore.string');
var uuid = require('node-uuid');
var async = require('async');
var redis = require('./redis-client');
var client = redis.client;
var lua = require('./lua');

/**
 * reapLock
 * Detects any child locks referenced in the key set that have expired and removes their
 * entries from the key set. Fires a callback with err.
 * @param {string} key the identifier of the shared lock for which to reap expired child locks
 * @param {function} callback signature (err)
 */
exports.reapLock = function(key, callback) {
  client.smembers(key, function(err, members) {
    if (err) { return callback(err); }

    iterator = function(member, callback) {
      client.get(member, function(err, value) {
        if (err || value) { return callback(err); }
        client.srem(key, member, function(err) {
          return callback(err);
        });
      });
    };

    async.each(members, iterator, callback);
  });
};

/**
 * acquireLock
 * Attempt to acquire a shared lock. Acquiring the lock will fail if maximumLocks or more
 * locks are already being held by other clients. Acquiring the lock creates a new lockId, adds it
 * to the key set, then sets the lockId with the passed TTL. Fires a callback with err and the
 * lockId if it was successfully acquired, otherwise null.
 * @param {string} key the identifier of the shared lock to acquire
 * @param {int} maximumLocks the maximum number of locks that can be held after a successful lock acquisition
 * @param {number} ttlSeconds the number of seconds for which to hold the lock
 * @param {function} callback signature (err, lockId if acquired else null)
 */
exports.acquireLock = function(key, maximumLocks, ttlSeconds, callback) {
  var lockId = uuid.v1();
  async.waterfall([
    function(cb) { return redis.ensureScript(client, lua.acquire_lock, cb); },
    function(cb) {
      client.eval(lua.acquire_lock, 1, key, lockId, maximumLocks, ttlSeconds, function(err, response) {
        if (err) { return cb(err); }
        return cb(null, response ? lockId : null);
      });
    }
  ], function(err, lockId) {
    if (err) { return callback(err); }
    return callback(null, lockId);
  });
};

/**
 * acquireMultipleLocks
 * Attempt to acquire multiple shared locks, all subject to the same maximumLocks and ttlSeconds.
 * Acquiring *all* of the locks will fail if maximumLocks or more locks are already being held by
 * other clients on *any* of the shared locks. If all locks are successfully acquired, separate lock
 * IDs are returned for each lock. Fires a callback with err and a mapping of keys to lock IDs if
 * all locks were successfully acquired, otherwise null.
 * @param {[string]} keys the identifiers of the shared locks to acquire
 * @param {int} maximumLocks the maximum number of locks (per key) that can be held after a successful lock acquisition
 * @param {number} ttlSeconds the number of seconds for which to hold each lock
 * @param {function} callback signature (err, lockIdMapping if acquired else null)
 */
exports.acquireMultipleLocks = function(keys, maximumLocks, ttlSeconds, callback) {
  var lockIds = _.map(keys, function(key) { return uuid.v1(); });
  var lockIdsPipeDelimited = lockIds.join('|');
  var evalArgs = _.flatten([lua.acquire_multiple_locks, keys.length, keys, lockIdsPipeDelimited, maximumLocks, ttlSeconds]);

  async.waterfall([
    function(cb) { return redis.ensureScript(client, lua.acquire_multiple_locks, cb); },
    function(cb) {
      client.eval(evalArgs, function(err, response) {
        if (err) { return cb(err); }
        var lockIdMapping = _.object(keys, lockIds);
        return cb(null, response ? lockIdMapping : null);
      });
    }
  ], function(err, lockIdMapping) {
    if (err) { return callback(err); }
    return callback(null, lockIdMapping);
  });
};

/**
 * releaseLock
 * Release any lock that is currently held with the passed lockId. This deletes the lock's key if
 * it exists, then removes the lockId from the key set. Fires a callback with err in either case.
 * @param {string} lockId lock identifier returned from a successful lock acquisition
 * @param {function} callback signature (err)
 */
exports.releaseLock = function(lockId, callback) {
  client.get(lockId, function(err, key) {
    if (err) { return callback(err); }
    client
      .multi()
      .srem(key, lockId)
      .del(lockId)
      .exec(function(err) {
        return callback(err);
      });
  });
};
<|endoftext|>