<commit_before>(function (out) {
    
    out.canvas = out.canvas || {};
    
    /**
     *    [Constructor] MO5.canvas.Rain
     *    =============================
     *    
     *        A rain effect.
     *        
     *        Concepts:
     *        ---------
     *        
     * Dimensions
     * Layer
     * Transparency
     * Rotation
     * Position
     *        
     *        Parameters:
     *        -----------
     *        
     *            1. canvas:
     *                [MO5.canvas.Canvas] The Canvas object to use.
     *            
     *            2. args:
     *                [Object] An object literal with optional arguments.
     *                
     *                Properties:
     *                
     * speed:
     *                        [Number] The number of pixels to move on each iteration.
     *                    
     * drops:
     *                        [Number] The number of rain drops to display.
     *                        
     *                        
     */
    out.canvas.Rain = function (canvas, args)
    {
        var self = this;
        
        args = args || {};
        
        out.canvas.CanvasObject.call(this, canvas, args);

        this.color = args.color || "#fff";
        this.drops = args.drops || 100;
        this.data = null;
        this.speed = args.speed || 800;
        this.width = args.width || canvas.cv.width * 2;
        this.height = args.height || canvas.cv.height * 2;
        this.x = args.x || ((this.width - canvas.cv.width) / 2);
        this.y = args.y || ((this.height - canvas.cv.height) / 2);
        this.lastDrawTime = 0;

        this.canvas.bus.subscribe(
            function () {
                self.hide();
            }, 
            "mo5.canvas.rain.hideAll"
        );

        this.canvas.bus.subscribe(
            function () {
                self.display();
            }, 
            "mo5.canvas.rain.displayAll"
        );
    };
    
    out.canvas.Rain.prototype = new out.canvas.CanvasObject();

    out.canvas.Rain.prototype.draw = function ()
    {
        var self = this,
            ct = self.canvas.ct,
            drops = self.drops,
            i,
            data = self.data,
            x,
            fy,
            ly,
            width = self.width,
            height = self.height,
            cur,
            speed = (((Date.now() - self.lastDrawTime) / 1000) * self.speed) | 0;
        
        //console.log("speed: ", speed);
        
        ct.save();
        ct.globalAlpha = self.alpha;
        
        if (self.rotation > 0) {
            
            ct.translate(self.pivotX, self.pivotY);
            ct.rotate((Math.PI * self.rotation) / 180);
            ct.translate(-self.pivotX, - self.pivotY);
        }
        
        if (data === null) {
            
            data = [];
            
            for (i = 0; i < drops; ++i) {
                
                x = (Math.random() * width - (self.width - self.canvas.cv.width) / 2) | 0;
                fy = (Math.random() * height - (self.height - self.canvas.cv.height) / 2) | 0;
                ly = (Math.random() * 40 + 5) | 0;
                
                data.push({
                    x: x,
                    fy: fy,
                    ly: ly
                });
            }
        }
        
        ct.strokeStyle = self.color;
        ct.lineWidth = 1;
        ct.beginPath();
        
        for (i = 0; i < drops; ++i) {
            
            cur = data[i];
            cur.fy += speed;
            
            if (cur.fy > self.canvas.cv.height + cur.ly) {
                cur.fy = 0 - (self.height - self.canvas.cv.height) / 2 - cur.ly;
                cur.x = Math.random() * width - (self.width - self.canvas.cv.width) / 2;
            }
            <commit_msg>Changed MO5.canvas.Rain to use new drawing mechanism.<commit_after>(function (out) {
    
    out.canvas = out.canvas || {};
    
    /**
     *    [Constructor] MO5.canvas.Rain
     *    =============================
     *    
     *        A rain effect.
     *        
     *        Concepts:
     *        ---------
     *        
     * Dimensions
     * Layer
     * Transparency
     * Rotation
     * Position
     *        
     *        Parameters:
     *        -----------
     *        
     *            1. canvas:
     *                [MO5.canvas.Canvas] The Canvas object to use.
     *            
     *            2. args:
     *                [Object] An object literal with optional arguments.
     *                
     *                Properties:
     *                
     * speed:
     *                        [Number] The number of pixels to move on each iteration.
     *                    
     * drops:
     *                        [Number] The number of rain drops to display.
     *                        
     *                        
     */
    out.canvas.Rain = function (args)
    {
        var self = this;
        
        args = args || {};
        
        out.canvas.CanvasObject.call(this, args);

        this.color = args.color || "#fff";
        this.drops = args.drops || 100;
        this.data = null;
        this.speed = args.speed || 800;
        this.width = args.width || 800;
        this.height = args.height || 600;
        this.x = args.x || 0;
        this.y = args.y || 0;
        this.lastDrawTime = 0;
    };
    
    out.canvas.Rain.prototype = new out.canvas.CanvasObject();

    out.canvas.Rain.prototype.draw = function (env)
    {
        var self = this,
            ct = env.context,
            cv = env.canvas,
            drops = self.drops,
            i,
            data = self.data,
            x,
            fy,
            ly,
            width = self.width,
            height = self.height,
            cur,
            speed = (((Date.now() - self.lastDrawTime) / 1000) * self.speed) | 0;
        
        //console.log("speed: ", speed);
        
        ct.save();
        ct.globalAlpha = self.alpha;
        
        if (self.rotation > 0) {
            
            ct.translate(self.pivotX, self.pivotY);
            ct.rotate((Math.PI * self.rotation) / 180);
            ct.translate(-self.pivotX, - self.pivotY);
        }
        
        if (data === null) {
            
            data = [];
            
            for (i = 0; i < drops; ++i) {
                
                x = (Math.random() * width - (self.width - cv.width) / 2) | 0;
                fy = (Math.random() * height - (self.height - cv.height) / 2) | 0;
                ly = (Math.random() * 40 + 5) | 0;
                
                data.push({
                    x: x,
                    fy: fy,
                    ly: ly
                });
            }
        }
        
        ct.strokeStyle = self.color;
        ct.lineWidth = 1;
        ct.beginPath();
        
        for (i = 0; i < drops; ++i) {
            
            cur = data[i];
            cur.fy += speed;
            
            if (cur.fy > cv.height + cur.ly) {
                cur.fy = 0 - (self.height - cv.height) / 2 - cur.ly;
                cur.x = Math.random() * width - (self.width - cv.width) / 2;
            }
            
{'fraction_non_alphanumeric': 0.13500415397396842, 'fraction_numerical': 0.011492661312655774, 'mean_word_length': 0.9032938076416337, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '3585870', 'n_tokens_mistral': 2169, 'n_tokens_neox': 2013, 'n_words': 425}