<commit_before>
var errorSound = "http://www.soundjay.com/button/sounds/button-10.mp3";
var startSound = "http://www.soundjay.com/misc/bell-ringing-05.mp3";
var victoryCount = 3;
var victorySeq = [0, 1, 2, 3, 0, 1, 2, 3];

// n: number, z: 0
function pad(n, width, z) {
    z = z || '0';
    n = n + '';
    return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}

function isPrefix(a, b) {
    var p = b.slice(0, a.length);
    var isSame = (a.length == p.length) && a.every(function(element, index) {
        return element === p[index];
    });
    return isSame;
}

function genSeq(len, min, max) {
    var seq = [];
    for (var i = 0; i < len; i++) {
        seq.push(Math.floor(Math.random() * max));
    }
    return seq;
}

function sleepPromise(ms) {
    return new Promise(function(resolve) {
        setTimeout(resolve, ms);
    });
}

function playSoundPromise(url) {
    return new Promise(function(resolve, reject) {
        var audio = new Audio();
        audio.preload = "auto";
        audio.autoplay = true;
        audio.onerror = reject;
        audio.onended = resolve;

        audio.src = url
    });
}

var quad = Vue.extend({
    template: '#quad-template',
    props: ['qid', 'soundUrl'],
    data: function() {
        return {
            lightened: false,
        }
    },
    methods: {
        play: function() {
            this.lighten();
            this.$dispatch('quad-played', this.qid);
        },
        lighten: function() {
            this.lightened = true
            this.$parent.countDisplay = pad(this.$parent.count, 2);
            playSoundPromise(this.soundUrl).then(this.darken);
        },
        darken: function() {
            this.lightened = false
        }
    }
});

var main = new Vue({
    el: '#main',
    data: {
        'isStrict': false,
        'isOn': false,
        'count': 0,
        'latency': 1000,
        'countDisplay': '--',
        'blink': false,
        'showedSeq': [],
        'playedSeq': [],
        'generatedSeq': []
    },
    components: {
        'quad': quad
    },
    methods: {
        showSeq: function() {
            console.log("showSeq");
            var seq = this.generatedSeq;
            var quad = this.$children;
            var showedSeq = this.showedSeq;
            var latency = this.latency;

            var sequence = Promise.resolve();
            for (var i = 0; i < seq.length; i++) {
                var child = quad[seq[i]];
                var qid = parseInt(child.qid);
                sequence = sequence.then(sleepPromise.bind(null, latency))
                .then(child.lighten)
                .then(function(showedSeq, qid) {
                    showedSeq.push(qid);
                }.bind(null, showedSeq, qid));
            }
        },
        nextSeq: function() {
            console.log("nextSeq");
            if (this.isOn) {
                this.count ++;
                this.countDisplay = pad(this.count, 2);
                this.showedSeq = [];
                this.playedSeq = [];
                this.generatedSeq = genSeq(this.count, 0, this.$children.length);
                this.showSeq();
                console.log(this.showedSeq);
            }
        },
        toggleStrict: function() {
            if (this.isOn) {
                this.isStrict = !this.isStrict;
            }
        },
        reset: function() {
            if (this.isOn) {
                this.count = 0;
                this.countDisplay = '--';
                this.showedSeq = [];
                this.playedSeq = [];
                this.generatedSeq = [];
                this.blink = false;
                this.latency = 1000;
            }
        },
        start: function() {
            if (this.isOn) {
                this.reset();
                playSoundPromise(startSound).then(this.nextSeq);
            }
        },
        toggleOn: function() {
            this.reset();
            this.isStrict = false;
            this.isOn = !this.isOn;
        },
        quadPlayed: function(qid) {
            if (this.isOn) {
                this.playedSeq.push(qid);
                // check array contains
                console.log(this.playedSeq);
                if (isPrefix(this.playedSeq, this.showedSeq)) {
                    if (this.playedSeq.length === this.showedSeq.length) {
                        var that = this;
                        if (this.count === victoryCount) {
                            this.generatedSeq = victorySeq;
                            this.blink = true;
                            this.latency = 500;
                            setTimeout(function() {
                               that.showSeq();
                            }, 500);
                            setTimeout(function() {
                                that.start();
                            }, 8000);
                        } else {
                            setTimeout(function() {
                                that.nextSeq();
                            }, 2000);
                        }
                    }<commit_msg>More promises<commit_after>
var errorSound = "http://www.soundjay.com/button/sounds/button-10.mp3";
var startSound = "http://www.soundjay.com/misc/bell-ringing-05.mp3";
var victoryCount = 3;
var victorySeq = [0, 1, 2, 3, 0, 1, 2, 3];

// n: number, z: 0
function pad(n, width, z) {
    z = z || '0';
    n = n + '';
    return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}

function isPrefix(a, b) {
    var p = b.slice(0, a.length);
    var isSame = (a.length == p.length) && a.every(function(element, index) {
        return element === p[index];
    });
    return isSame;
}

function genSeq(len, min, max) {
    var seq = [];
    for (var i = 0; i < len; i++) {
        seq.push(Math.floor(Math.random() * max));
    }
    return seq;
}

function sleepPromise(ms) {
    return new Promise(function(resolve) {
        setTimeout(resolve, ms);
    });
}

function playSoundPromise(url) {
    return new Promise(function(resolve, reject) {
        var audio = new Audio();
        audio.preload = "auto";
        audio.autoplay = true;
        audio.onerror = reject;
        audio.onended = resolve;

        audio.src = url
    });
}

var quad = Vue.extend({
    template: '#quad-template',
    props: ['qid', 'soundUrl'],
    data: function() {
        return {
            lightened: false,
        }
    },
    methods: {
        play: function() {
            this.lighten().then(this.darken);
            this.$dispatch('quad-played', this.qid);
        },
        lighten: function() {
            this.lightened = true
            this.$parent.countDisplay = pad(this.$parent.count, 2);
            return playSoundPromise(this.soundUrl);
        },
        darken: function() {
            this.lightened = false
        }
    }
});

var main = new Vue({
    el: '#main',
    data: {
        'isStrict': false,
        'isOn': false,
        'count': 0,
        'latency': 500,
        'countDisplay': '--',
        'blink': false,
        'showedSeq': [],
        'playedSeq': [],
        'generatedSeq': []
    },
    components: {
        'quad': quad
    },
    methods: {
        showSeq: function() {
            console.log("showSeq");
            var seq = this.generatedSeq;
            var quad = this.$children;
            var showedSeq = this.showedSeq;
            var latency = this.latency;

            var sequence = Promise.resolve();
            for (var i = 0; i < seq.length; i++) {
                var child = quad[seq[i]];
                var qid = parseInt(child.qid);
                sequence = sequence.then(sleepPromise.bind(null, latency))
                .then(child.lighten)
                .then(child.darken)
                .then(function(showedSeq, qid) {
                    showedSeq.push(qid);
                }.bind(null, showedSeq, qid));
            }
            return sequence;
        },
        nextSeq: function() {
            console.log("nextSeq");
            if (this.isOn) {
                this.count ++;
                this.countDisplay = pad(this.count, 2);
                this.showedSeq = [];
                this.playedSeq = [];
                this.generatedSeq = genSeq(this.count, 0, this.$children.length);
                return this.showSeq();
            }
        },
        toggleStrict: function() {
            if (this.isOn) {
                this.isStrict = !this.isStrict;
            }
        },
        reset: function() {
            if (this.isOn) {
                this.count = 0;
                this.countDisplay = '--';
                this.showedSeq = [];
                this.playedSeq = [];
                this.generatedSeq = [];
                this.blink = false;
                this.latency = 500;
            }
        },
        start: function() {
            if (this.isOn) {
                this.reset();
                playSoundPromise(startSound).then(this.nextSeq);
            }
        },
        toggleOn: function() {
            this.reset();
            this.isStrict = false;
            this.isOn = !this.isOn;
        },
        quadPlayed: function(qid) {
            if (this.isOn) {
                this.playedSeq.push(qid);
                // check array contains
                console.log(this.playedSeq);
                if (isPrefix(this.playedSeq, this.showedSeq)) {
                    if (this.playedSeq.length === this.showedSeq.length) {
                        var that = this;
                        if (this.count === victoryCount) {
                            this.generatedSeq = victorySeq;
                            this.blink = true;
                            this.latency = 0;
                            sleepPromise(500)
                                .then(that.showSeq)
                                .then(sleepPromise.bind(null, 3000))
                                .then(that.start);
                        } else {
                            sleepPromise(2000).then(that.nextSeq);
                        }
                    }
{'fraction_non_alphanumeric': 0.13441975308641976, 'fraction_numerical': 0.00908641975308642, 'mean_word_length': 1.277040701596582, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '440429', 'n_tokens_mistral': 3008, 'n_tokens_neox': 2832, 'n_words': 578}