<commit_before>﻿define('RankedVote', ['jquery', 'knockout', 'jqueryUI', 'Common', 'PollOptions', 'ResultChart', 'SliderExtension'], function ($, ko, jqueryUI, Common, PollOptions) {

    return function RankedVote(pollId, token) {

        var self = this;
        self.pollOptions = new PollOptions(pollId);
        self.selectedOptions = ko.observableArray();
        self.remainOptions = ko.observableArray();

        self.chartData = ko.observableArray();
        self.winVotesRequired = ko.observable(0);
        self.winners = ko.observableArray();

        self.roundsRange = ko.observableArray([0, 0]);
        self.roundsDisplay = ko.observableArray([0, 0]);

        self.filteredChartData = ko.computed(function () {
            var display = {
                from: self.roundsDisplay()[0] - 1,
                to: self.roundsDisplay()[1] - 1
            };

            return self.chartData().map(function (option) {
                return {
                    Name: option.Name,
                    Data: option.Data.filter(function (r, i) {
                        return i >= display.from && i <= display.to;
                    })
                };
            });
        });

        var selectPickedOptions = function (votes) {
            self.selectedOptions([]);
            self.remainOptions([]);

            var selected = votes.map(function (vote) {
                return ko.utils.arrayFirst(self.pollOptions.options(), function (item) {
                    return item.Id === vote.OptionId;
                });
            });
            self.selectedOptions(selected);

            var notSelected = function (option) {
                return self.selectedOptions().filter(function (o) { return o.Id === option.Id; }).length === 0;
            };

            self.remainOptions(self.pollOptions.options().filter(notSelected));
        };

        var orderedNames = [];
        var chart;
        var roundIndex = 0;

        var sortByVoteValue = function (a, b) {
            return a.VoteValue - b.VoteValue;
        };

        var sortByBallotCount = function (a, b) {
            return a.ballots.length - b.ballots.length;
        };

        var countVotes = function (votes) {
            var options = [];
            var ballots = [];
            var totalBallots = 0;
            var totalOptions = self.pollOptions.options().length;
            var resultsByRound = [];

            for (var k = 0; k < totalOptions; k++) {
                var optionId = self.pollOptions.options()[k].Id;
                options[k] = { Id: optionId, ballots: [] };
            }

            // Group votes into ballots (per user)
            votes.forEach(function (vote) {
                if (!ballots[vote.UserId]) {
                    ballots[vote.UserId] = [];
                    totalBallots++;
                }
                ballots[vote.UserId].push(vote);
            });

            // Start counting
            while (options.length > 0) {

                // Clear out all ballots from previous round
                options = options.map(function (d) {
                    d.ballots = [];
                    return d;
                });

                var availableOptions = options.map(function (d) { return d.Id; });

                // Sort the votes on the ballots and assign each ballot to first choice
                ballots.forEach(function (ballot) {
                    ballot.sort(sortByVoteValue);
                    var availableChoices = ballot.filter(function (option) { return $.inArray(option.OptionId, availableOptions) !== -1; });
                    if (availableChoices.length > 0) {
                        var firstChoiceId = availableChoices[0].OptionId;
                        var firstChoiceOption = options.filter(function (option) { return option.Id === firstChoiceId; })[0];
                        firstChoiceOption.ballots.push(ballot);
                    }
                });

                options.sort(sortByBallotCount);

                //Convert into a chartable style
                var roundOptions = options.map(function (d) {
                    var matchingOption = $.grep(self.pollOptions.options(), function (opt) { return opt.Id === d.Id; })[0];
                    return {
                        Name: matchingOption.Name,
                        Sum: d.ballots.length,
                        Voters: d.ballots.map(function (x) { return x[0].VoterName + " (#" + (x.map(function (y) { return y.OptionId; }).indexOf(matchingOption.Id) + 1) + ")"; })
                    };
                });

                var roundSeries = {
                    name: (resultsByRound.length + 1).toString(),
                    data: roundOptions
                };

                // End if we have a majority
                if (options[options.length - 1].ballots.length > totalBallots / 2) {

                    //Mark all other remaining results as having lost
                    for (var i = 0; i < options.length - 1; i++) {
                        options[i].rank = 2;
                    }

                    resultsByRound.push(roundSeries);
                    break;
                }

                if (options[0].ballots.length > 0) {
                    resultsByRound.push(roundSeries);
                }

                // Remove all last place options
                var lastPlaceOption = options[0];
                var lastPlaceBallotCount = lastPlaceOption.ballots.length;

                options = options.filter(function (d) { return d.ballots.length > lastPlaceBallotCount; });
            }

            // Transpose the rounds with options data into options with rounds for the chart
            var resultsByOption = self.pollOptions.options().map(function (option) {
                // Get the per-round results for this option
                var roundData = resultsByRound.map(function (round) {
                    var roundOption = round.data.filter(function (o) { return o.Name === option.Name; });
                    if (roundOption.length > 0) {
                        return {
                            Name: round.name,
                            Sum: roundOption[0].Sum,
                            Voters: roundOption[0].Voters
                        };
                    } else {
                        return {
                            Name: round.name,
                            Sum: 0,
                            Voters: []
                        };<commit_msg>Simplified calculation of chart data for Ranked vote<commit_after>﻿define('RankedVote', ['jquery', 'knockout', 'jqueryUI', 'Common', 'PollOptions', 'ResultChart', 'SliderExtension'], function ($, ko, jqueryUI, Common, PollOptions) {

    return function RankedVote(pollId, token) {

        var self = this;
        self.pollOptions = new PollOptions(pollId);
        self.selectedOptions = ko.observableArray();
        self.remainOptions = ko.observableArray();

        self.chartData = ko.observableArray();
        self.winVotesRequired = ko.observable(0);
        self.winners = ko.observableArray();

        self.roundsRange = ko.observableArray([0, 0]);
        self.roundsDisplay = ko.observableArray([0, 0]);

        self.filteredChartData = ko.computed(function () {
            var display = {
                from: self.roundsDisplay()[0] - 1,
                to: self.roundsDisplay()[1] - 1
            };

            return self.chartData().map(function (option) {
                return {
                    Name: option.Name,
                    Data: option.Data.filter(function (r, i) {
                        return i >= display.from && i <= display.to;
                    })
                };
            });
        });

        var selectPickedOptions = function (votes) {
            self.selectedOptions([]);
            self.remainOptions([]);

            var selected = votes.map(function (vote) {
                return ko.utils.arrayFirst(self.pollOptions.options(), function (item) {
                    return item.Id === vote.OptionId;
                });
            });
            self.selectedOptions(selected);

            var notSelected = function (option) {
                return self.selectedOptions().filter(function (o) { return o.Id === option.Id; }).length === 0;
            };

            self.remainOptions(self.pollOptions.options().filter(notSelected));
        };

        var orderedNames = [];
        var chart;
        var roundIndex = 0;

        var sortByVoteValue = function (a, b) {
            return a.VoteValue - b.VoteValue;
        };

        var sortByBallotCount = function (a, b) {
            return a.ballots.length - b.ballots.length;
        };

        var countVotes = function (votes) {
            var ballots = [];
            var totalBallots = 0;
            var resultsByRound = [];

            var options = self.pollOptions.options().map(function (o) { return { Name: o.Name, Id: o.Id, ballots: [] }; });

            // Group votes into ballots (per user)
            votes.forEach(function (vote) {
                if (!ballots[vote.UserId]) {
                    ballots[vote.UserId] = [];
                    totalBallots++;
                }
                ballots[vote.UserId].push(vote);
            });

            // Start counting
            while (options.length > 0) {

                // Clear out all ballots from previous round
                options.forEach(function (d) { d.ballots = []; });
                // Option IDs that haven't been eliminated
                var availableOptions = options.map(function (d) { return d.Id; });

                // Sort the votes on the ballots and assign each ballot to first choice
                ballots.forEach(function (ballot) {
                    ballot.sort(sortByVoteValue);
                    var availableChoices = ballot.filter(function (option) { return $.inArray(option.OptionId, availableOptions) !== -1; });
                    if (availableChoices.length > 0) {
                        var firstChoiceId = availableChoices[0].OptionId;
                        var firstChoiceOption = options.filter(function (option) { return option.Id === firstChoiceId; })[0];
                        firstChoiceOption.ballots.push(ballot);
                    }
                });

                // Sort by performance in this round
                options.sort(sortByBallotCount);

                //Convert into a chartable style
                var roundOptions = options.map(function (d) {
                    return {
                        Name: d.Name,
                        Sum: d.ballots.length,
                        Voters: d.ballots.map(function (x) { return x[0].VoterName + " (#" + (x.map(function (y) { return y.OptionId; }).indexOf(d.Id) + 1) + ")"; })
                    };
                });

                // Series representing this round
                if (options[0].ballots.length > 0) {
                    resultsByRound.push({
                        name: (resultsByRound.length + 1).toString(),
                        data: roundOptions
                    });
                }

                // End if we have a majority
                if (options[options.length - 1].ballots.length > totalBallots / 2) {
                    break;
                }

                // Remove all last place options
                var lastPlaceOption = options[0];
                var lastPlaceBallotCount = lastPlaceOption.ballots.length;

                options = options.filter(function (d) { return d.ballots.length > lastPlaceBallotCount; });
            }

            // Transpose the rounds with options data into options with rounds for the chart
            var resultsByOption = self.pollOptions.options().map(function (option) {
                // Get the per-round results for this option
                var roundData = resultsByRound.map(function (round) {
                    var roundOption = round.data.filter(function (o) { return o.Name === option.Name; });
                    if (roundOption.length > 0) {
                        return {
                            Name: round.name,
                            Sum: roundOption[0].Sum,
                            Voters: roundOption[0].Voters
                        };
                    } else {
                        return {
                            Name: round.name,
                            Sum: 0,
                            Voters: []
                        };
{'fraction_non_alphanumeric': 0.11011289553188106, 'fraction_numerical': 0.005008745428525998, 'mean_word_length': 1.3534144059869035, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 17, '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': '5106978', 'n_tokens_mistral': 3275, 'n_tokens_neox': 3000, 'n_words': 721}