<commit_before>'use strict';

/**
 * A sprite that can be drawn on a 2D canvas.
 * @constructor
 * @param {string|HTMLImageElement|HTMLCanvasElement} filename File to load or a graphical element that's already
 * loaded.
 * @param {string=} filter Filter function to convert the sprite, for example Sprite.turnSolidColored('black')
 * @param {string|HTMLImageElement|HTMLCanvasElement=} fallback Fallback file to load or a graphical element that's
 * already loaded.
 */
var Sprite = function(filename, /* Optional */ filter, fallback) {
    this.filename = filename;
    this.missing = false;
    this.fallback = fallback;
    this.filter = filter;
    Sprite.createdCount++;
    this._reload();
};

/**
 * Reload the Sprite.
 * @protected
 */
Sprite.prototype._reload = function() {
    if (typeof this.filename != typeof '') {
        this.img = this.filename;
        this.loaded = true;
        Sprite.loadedCount++;
        this.width = this.filename.width;
        this.height = this.filename.height;
        if (this.filter !== undefined) {
            this.filter(this);
        }
    } else {
        this.img = document.createElement('img');
        if (this.filename.substring(0, 5) === 'data:' || this.filename.substring(0, 5) === 'http:') {
            this.img.src = this.filename;
        } else {
            this.img.src = Sprite.gfxPath + this.filename;
        }
        var that = this;
        this.loaded = false;
        this.img.onload = function() {
            that.loaded = true;
            Sprite.loadedCount++;
            that.width = that.img.width;
            that.height = that.img.height;
            if (that.filter !== undefined) {
                that.filter(that);
            }
        };
        this.img.onerror = function() {
            if (that.fallback) {
                that.filename = that.fallback;
                that.fallback = undefined;
                that._reload();
                return;
            }
            that.loaded = true;
            that.missing = true;
            Sprite.loadedCount++;
            that.img = document.createElement('canvas');
            that.img.width = 150;
            that.img.height = 20;
            that.width = that.img.width;
            that.height = that.img.height;
            var ctx =that.img.getContext('2d');
            ctx.textBaseline = 'top';
            ctx.fillStyle = '#fff';
            ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
            ctx.fillStyle = '#000';
            ctx.fillText('Missing: ' + that.filename, 0, 0);
        };
    }
};

/**
 * Path for graphics files. Set this before creating any Sprite objects.
 */
Sprite.gfxPath = 'assets/gfx/';

/**
 * Filter for turning the sprite solid colored.
 */
Sprite.turnSolidColored = function(solidColor) {
    return function(sprite) {
        var canvas = document.createElement('canvas');
        canvas.width = sprite.width;
        canvas.height = sprite.height;
        var ctx = canvas.getContext('2d');
        ctx.fillStyle = solidColor;
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.globalCompositeOperation = 'destination-in';
        sprite.draw(ctx, 0, 0);
        sprite.img = canvas;
    };
};

/**
 * Filter for generating a different hued variation of the sprite.
 */
Sprite.varyHue = function(options) {
    var defaults = {
        minHue: 0,
        maxHue: 1,
        hueChange: 0
    };
    for(var key in defaults) {
        if(!options.hasOwnProperty(key)) {
            options[key] = defaults[key];
        }
    }
    while (options.hueChange < 0) {
        options.hueChange += 1;
    }
    while (options.hueChange > 1) {
        options.hueChange -= 1;
    }
    return function(sprite) {
        var canvas = document.createElement('canvas');
        canvas.width = sprite.width;
        canvas.height = sprite.height;
        var ctx = canvas.getContext('2d');
        sprite.draw(ctx, 0, 0);
        var data = ctx.getImageData(0, 0, canvas.width, canvas.height);
        for (var i = 0; i < data.data.length; i += 4) {
            var r = data.data[i];
            var g = data.data[i + 1];
            var b = data.data[i + 2];
            var hsl = rgbToHsl(r, g, b);
            if (hsl[0] >= options.minHue && hsl[0] <= options.maxHue) {
                hsl[0] += options.hueChange;
                if (hsl[0] > 1.0) {
                    hsl[0] -= 1.0;
                }
                var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
                data.data[i] = rgb[0];
                data.data[i + 1] = rgb[1];
                data.data[i + 2] = rgb[2];
            }
        }
        ctx.putImageData(data, 0, 0);
        sprite.img = canvas;
    };
};

/**
 * How many Sprite objects have been created.
 */<commit_msg>Catch SecurityErrors when loading Sprites<commit_after>'use strict';

/**
 * A sprite that can be drawn on a 2D canvas.
 * @constructor
 * @param {string|HTMLImageElement|HTMLCanvasElement} filename File to load or a graphical element that's already
 * loaded.
 * @param {string=} filter Filter function to convert the sprite, for example Sprite.turnSolidColored('black')
 * @param {string|HTMLImageElement|HTMLCanvasElement=} fallback Fallback file to load or a graphical element that's
 * already loaded.
 */
var Sprite = function(filename, /* Optional */ filter, fallback) {
    this.filename = filename;
    this.missing = false;
    this.fallback = fallback;
    this.filter = filter;
    Sprite.createdCount++;
    this._reload();
};

/**
 * Reload the Sprite.
 * @protected
 */
Sprite.prototype._reload = function() {
    if (typeof this.filename != typeof '') {
        this.img = this.filename;
        this.loaded = true;
        Sprite.loadedCount++;
        this.width = this.filename.width;
        this.height = this.filename.height;
        if (this.filter !== undefined) {
            this.filter(this);
        }
    } else {
        this.img = document.createElement('img');
        if (this.filename.substring(0, 5) === 'data:' || this.filename.substring(0, 5) === 'http:') {
            this.img.src = this.filename;
        } else {
            this.img.src = Sprite.gfxPath + this.filename;
        }
        var that = this;
        this.loaded = false;
        this.img.onload = function() {
            that.loaded = true;
            Sprite.loadedCount++;
            that.width = that.img.width;
            that.height = that.img.height;
            if (that.filter !== undefined) {
                that.filter(that);
            }
        };
        this.img.onerror = function() {
            if (that.fallback) {
                that.filename = that.fallback;
                that.fallback = undefined;
                that._reload();
                return;
            }
            that.loaded = true;
            that.missing = true;
            Sprite.loadedCount++;
            that.img = document.createElement('canvas');
            that.img.width = 150;
            that.img.height = 20;
            that.width = that.img.width;
            that.height = that.img.height;
            var ctx =that.img.getContext('2d');
            ctx.textBaseline = 'top';
            ctx.fillStyle = '#fff';
            ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
            ctx.fillStyle = '#000';
            ctx.fillText('Missing: ' + that.filename, 0, 0);
        };
    }
};

/**
 * Path for graphics files. Set this before creating any Sprite objects.
 */
Sprite.gfxPath = 'assets/gfx/';

/**
 * Filter for turning the sprite solid colored.
 */
Sprite.turnSolidColored = function(solidColor) {
    return function(sprite) {
        var canvas = document.createElement('canvas');
        canvas.width = sprite.width;
        canvas.height = sprite.height;
        var ctx = canvas.getContext('2d');
        ctx.fillStyle = solidColor;
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.globalCompositeOperation = 'destination-in';
        sprite.draw(ctx, 0, 0);
        sprite.img = canvas;
    };
};

/**
 * Filter for generating a different hued variation of the sprite.
 */
Sprite.varyHue = function(options) {
    var defaults = {
        minHue: 0,
        maxHue: 1,
        hueChange: 0
    };
    for(var key in defaults) {
        if(!options.hasOwnProperty(key)) {
            options[key] = defaults[key];
        }
    }
    while (options.hueChange < 0) {
        options.hueChange += 1;
    }
    while (options.hueChange > 1) {
        options.hueChange -= 1;
    }
    return function(sprite) {
        var canvas = document.createElement('canvas');
        canvas.width = sprite.width;
        canvas.height = sprite.height;
        var ctx = canvas.getContext('2d');
        sprite.draw(ctx, 0, 0);
        try {
            var data = ctx.getImageData(0, 0, canvas.width, canvas.height);
        } catch (e) {
            if (e.name == 'SecurityError') {
                if (!Sprite.reportedSecurityError) {
                    Sprite.reportedSecurityError = true;
                    console.log(e.message);
                }
                return;
            }
        }
        for (var i = 0; i < data.data.length; i += 4) {
            var r = data.data[i];
            var g = data.data[i + 1];
            var b = data.data[i + 2];
            var hsl = rgbToHsl(r, g, b);
            if (hsl[0] >= options.minHue && hsl[0] <= options.maxHue) {
                hsl[0] += options.hueChange;
                if (hsl[0] > 1.0) {
                    hsl[0] -= 1.0;
                }
                var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
                data.data[i] = rgb[0];
                data.data[i + 1] = rgb[1];
                data.data[i + 2] = rgb[2];
            }
        }
        ctx.putImageData(data, 0, 0);
        sprite.img = canvas;
    };
};

Sprite.reportedSecurityError = false;

/**
 * How many Sprite objects have been created.
 */
{'fraction_non_alphanumeric': 0.13366236905721193, 'fraction_numerical': 0.011684125705076551, 'mean_word_length': 1.7835716288197365, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, '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': '6560323', 'n_tokens_mistral': 3056, 'n_tokens_neox': 2931, 'n_words': 684}