<commit_before>/**
 * ByYearSpineList: SpineList extended for holding Spines by year
 */
 window.ByYearSpineList = window.SpineList.extend({
    model: Spine, // same

    initialize: function(models, options) {
    	// Backbone.Model.prototype.set.call(this, attributes, options);
    	window.SpineList.prototype.initialize.call(this, models, options);
        // additional bindings
        _.bindAll(this, 'getAvailableYears');
    },

    url: function(){
	    return '/simpleshelf/_design/simpleshelf/_view/by_year'
	},

    parse: function(response){
        var results = [], row, values, year;
        if (response.rows){
            for (var x = 0; x < response.rows.length; x++){
                row = response.rows[x];
                year = parseInt(row.key);
                if (_.isNaN(year)){
                    year = null;
                }
                values = {
                	'_rev': row.value._rev,
                	'id': row.id,
                	'latestDateFinished': row.value.latestDateFinished,
                	'title': row.value.title,
                    'year': year
                };
                results.push(values);
            }
       }
       return results;
    },

    /**
     * Return sorted list of years with data
     */
    getAvailableYears: function(){
        var allYears = this.map(function(model){
            return model.get('year');
        });
        // sort, make uniq
        allYears.sort();
        return _.uniq(allYears, true);
    },

    /**
     * Return list of spines within given year
     */
    getSpinesByYear: function(year){
        return this.filter(function(model){
            if (model.get('year') == year) {
                return true;
            }
        });
    }

});<commit_msg>Add custom comparator for ByYearSpineList<commit_after>/**
 * ByYearSpineList: SpineList extended for holding Spines by year
 */
 window.ByYearSpineList = window.SpineList.extend({
    model: Spine, // same

    initialize: function(models, options) {
    	// Backbone.Model.prototype.set.call(this, attributes, options);
    	window.SpineList.prototype.initialize.call(this, models, options);
        // additional bindings
        _.bindAll(this, 'getAvailableYears', 'getSpinesByYear');
    },

    url: function(){
	    return '/simpleshelf/_design/simpleshelf/_view/by_year'
	},

    comparator: function(model) {
        return model.get('latestDateFinished');
    },

    parse: function(response){
        var results = [], row, values, year;
        if (response.rows){
            for (var x = 0; x < response.rows.length; x++){
                row = response.rows[x];
                year = parseInt(row.key);
                if (_.isNaN(year)){
                    year = null;
                }
                values = {
                	'_rev': row.value._rev,
                	'id': row.id,
                	'latestDateFinished': row.value.latestDateFinished,
                	'title': row.value.title,
                    'year': year
                };
                results.push(values);
            }
       }
       return results;
    },

    /**
     * Return sorted list of years with data
     */
    getAvailableYears: function(){
        var allYears = this.map(function(model){
            return model.get('year');
        });
        // sort, make uniq
        allYears.sort();
        return _.uniq(allYears, true);
    },

    /**
     * Return list of spines within given year
     */
    getSpinesByYear: function(year){
        return this.filter(function(model){
            if (model.get('year') == year) {
                return true;
            }
        });
    },

    _goto: function(offset){
        var currentSpineIdx = null;
        var spineId = null;
        var me = this;
        this.each(function(spine, index){
            if (me._currentSpine == spine.id){
                currentSpineIdx = index;
                return;
            }
        });

        var gotoIndex = currentSpineIdx + offset;
        if (currentSpineIdx !== null){
            if (gotoIndex == -1){
                // previous wrap-around
                spineId = this.at(this.length - 1).id;
            }
            else if (this.length == gotoIndex){
                // next wrap-around
                spineId = this.at(0).id;
            } else {
                spineId = this.at(gotoIndex).id;
            }
        } else {
            return null;
        }

        this._currentSpine = spineId;
        this.trigger('spinelist:move', spineId);
    }
});
{'fraction_non_alphanumeric': 0.12363238512035012, 'fraction_numerical': 0.0010940919037199124, 'mean_word_length': 1.5282079646017699, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, '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': '4260540', 'n_tokens_mistral': 1306, 'n_tokens_neox': 1255, 'n_words': 273}