<commit_before>(function (root, factory) {
    // factory requires Intl and MessageFormat to be passed to it
    // Inlt can be the system Intl or an Intl polyfill assigned to root.Intl
    // MessageFormat can be MessageFormat on the Intl namespace or an IntlMessageFormat polyfill
    var lib = factory(root.Intl, (root.Intl && root.Intl.MessageFormat) || root.IntlMessageFormat);

    if (typeof module === 'object' && module.exports) {
        // node.js/CommonJs
        module.exports = lib;
    }
    if (typeof define === 'function' && define.amd) {
        // AMD anonymous module
        define(lib);
    }
    if (root) {
        root.HandlebarsHelperIntl = lib;
    }
})(typeof global !== 'undefined' ? global : this, function (Intl, IntlMessageFormat) {

    if (!Intl) {
        throw new ReferenceError('Intl must be provided.');
    }

    if (!IntlMessageFormat) {
        throw new ReferenceError('IntlMessageFormat must be provided.');
    }

    // Utility method used to avoid manipulating options.hash
    function extend (receiver, sender) {
        var p;

        for (p in sender) {
            if (sender.hasOwnProperty(p)) {
                receiver[p] = sender[p];
            }
        }

        return receiver;
    }

    var CONTEXT_KEY = 'i18n',
        _dateTimeFormats = {},
        _numberFormats = {};


    /**
     Sets options for Intl.DateTimeFormat to a specified key. The key can then
     be used with `intlDate` as `{{intlDate format="key"}}`
     @method setDateTimeFormat
     @param {String} key
     @param {Object} options
     */
    function setDateTimeFormat (key, options) {
        _dateTimeFormats[key] = options;
    }

    /**
     Returns the DateTimeFormat options for the specified key, or null if the
     key is not found
     @method getDateTimeFormat
     @param {String} key
     @return {Object|null}
     */
    function getDateTimeFormat (key) {
        return _dateTimeFormats[key] || null;
    }

    /**
     Sets options for Intl.NumberFormat to a specified key. The key can then
     be used with `intlNum` as `{{intlNum format="key"}}`
     @method setNumberFormat
     @param {String} key
     @param {Object} options
     */
    function setNumberFormat (key, options) {
        _numberFormats[key] = options;
    }

    /**
     Returns the NumberFormat options for the specified key, or null if the
     key is not found
     @method getNumberFormat
     @param {String} key
     @return {Object|null}
     */
    function getNumberFormat (key) {
        return _numberFormats[key] || null;
    }

    /**
     Central location for helper methods to get a locale to use. Arguments are
     looped through to search for locale itmes. After all parameters have been
     exhausted, it defaults to the global `this` for a locale.
     @protected
     @method _getLocale
     @param {Object} [hash] `options.hash` from the helper
     @param {Object} [ctx] Context of the helper
     @return Locale
     */
    function _getLocale (hash, ctx) {
        /*jshint expr:true */
        hash || (hash = {});
        /*jshint expr:true */
        ctx  || (ctx  = {});

        return hash.locale || ctx.locale || this.locale;
    }

    /**
     Creates a new context for the given code. This allows you to define new
     values on the context for things like `locale` and `currency`
     @method intlBlock
     @para {Object} options Options passed to the method from the handlebars handler
     @return {String}
     */
    function intlBlock (options) {
        var data = {},
            hash = options.hash || {},
            p;

        /* jshint proto:true */
        data.__proto__ = options.data;

        if (hash.locale) {
            data.locale = hash.locale;
        }

        if (hash.currency) {
            data.currency = hash.currency;
        }

        return options.fn(this, {
            data: data
        });
    }

    /**
    Performs a string replacement with provided token, CONTEXT_KEY context, and YRB
    formatted objects
    @method intlMessage
    @param {String} str String on which to perform replacements
    @param {Object} options Options passed to the method from the handlebars handler
    @return {String} Manipulated string that has had tokens replaced
    */
    function intlMessage (str, options) {
        if (!options) {
            throw new ReferenceError('A string must be provided.');
        }

        var hash = (options && options.hash) || {},
            data = (options && options.data) || {},
            formatOptions = extend({
                currency: data.currency
            }, hash),
            locale = hash.locale || data.locale;

        return new IntlMessageFormat(str, locale, formatOptions);
    }


    /**
    Formats the provided number based on the options. Options may specify if the
    returned value should be a delineated number, currency value, or a percentage.
    @method intlNumber
    @param {Number} num Number to format
    @param {Object} options Options passed to the method from the handlebars handler
    @return {String} Formatted number
    */
    function intlNumber (num, options) {
        if (!options) {
            throw new ReferenceError('A number must be provided.');
        }

        var hash = (options && options.hash) || {},
            data = (options && options.data) || {},
            formatOptions = hash.format && _numberFormats[hash.format] || hash,
            locale = hash.locale || data.locale;

        return new Intl.NumberFormat(locale, formatOptions).format(num);
    }


    /**
    Formats the provided date or time stamp to the current locale
    @param {Date|Number} stamp Date Object or time stamp to be formatted
    @param {Object} options Options passed to the method from the handlebars handler
    @return {String} Formatted date
    */
    function intlDate (stamp, options) {
        if (!options) {
            throw new ReferenceError('A date or time stamp must be provided.');
        }

        var hash = (options && options.hash) || {},
            data = (options && options.data) || {},
            formatOptions = hash.format && _dateTimeFormats[hash.format] || hash,
            locale = hash.locale || data.locale;
            _date;

        stamp = new Date(stamp).getTime();

        return new Intl.DateTimeFormat(locale, formatOptions).format(stamp);
    }


    /**
    Passes through to other intl methods to format number, format dates, create
    new context blocks, or format messages.
    @method intl
    @param {Number|Date|String} val Value to be formatted or applied
    @param {Object} options Options passed to the method from the handlebars handler
    @return {String|null} Returns the formated or translated value.
    */
    function intl (val, options) {
        if (!options) {
            options = val;
            val = null;
        }

        var token,
            len,
            i;

        // pass off to BLOCK
        if (options.fn) {
            return intlBlock.call(this, options);
        }

        // only use token if val is not defined
        if (!val) {
            if (options.hash.token) {
                val = options.data,
                token = options.hash.token.split('.');

                try {
                    for (i = 0, len = token.length; i < len; i++) {
                        val = val[token[i]];
                    }
                } catch (e) {
                    throw new ReferenceError('Could not find path ' + options.hash.token + ' in ' + _val + ' at ' + token[i]);
                }

            } else {
                throw new SyntaxError('A value or a token must be provided.');
            }
        }

        if (typeof val === 'number') {
            // pass off to NUMBER
            val = intlNumber.call(this, val, options);
        } else if (val instanceof Date) {
            // pass off to DATE
            val = intlDate.call(this, val, options);
        } else {
            // pass off to MESSAGE
            val = intlMessage.call(this, val, options);
        }

        return val;
    }


    return {
        // expose the helpers individually in case someone wants to use
        // only some of them
        helpers: {
            intlMessage  : intlMessage,
            intlNumber   : intlNumber,
            intlDate     : intlDate,
            intl         : intl
        },

        // utility method to register all the helpers
        register: function(engine) {
            engine.registerHelper('intlMessage', intlMessage);
            engine.registerHelper('intlNumber', intlNumber);
            engine.registerHelper('intlDate', intlDate);
            engine.registerHelper('intl', intl);
        },

        // expose format methods
        setDateTimeFormat : setDateTimeFormat,
        getDateTimeFormat : getDateTimeFormat,
        setNumberFormat   : setNumberFormat,
        getNumberFormat   : getNumberFormat

    };
});<commit_msg>Re-structure how the helpers integrate with the Intl system and app code<commit_after>(function (root, factory) {
    'use strict';

    // Intl and IntlMessageFormat are dependencies of this package. The built-in
    // `Intl` is preferred, but when not available it looks for the polyfill.
    var Intl = root.Intl || root.IntlPolyfill,
        lib  = factory(root.Intl, root.IntlMessageFormat);

    /* istanbul ignore next */
    if (typeof define === 'function' && define.amd) {
        define(lib);
    }
    if (typeof exports === 'object') {
        module.exports = lib;
    }

    root.HandlebarsHelperIntl = lib;

})(typeof global !== 'undefined' ? global : this, function (Intl, IntlMessageFormat) {
    'use strict';

    if (!Intl) {
        throw new ReferenceError('Intl must be provided.');
    }

    if (!IntlMessageFormat) {
        throw new ReferenceError('IntlMessageFormat must be provided.');
    }

    var exports = {};

    // Export the helpers.
    exports.helpers = {
        intl       : intl,
        intlDate   : intlDate,
        intlNumber : intlNumber,
        intlGet    : intlGet,
        intlMessage: intlMessage
    };

    // Export tility function to register all the helpers.
    exports.register = function (engine) {
        var helpers = exports.helpers;

        for (var name in helpers) {
            if (helpers.hasOwnProperty(name)) {
                engine.registerHelper(name, helpers[name]);
            }
        }
    };

    function extend(obj) {
        Array.prototype.slice.call(arguments, 1).forEach(function (source) {
            var key;

            if (!source) { return; }

            for (key in source) {
                if (source.hasOwnProperty(key)) {
                    obj[key] = source[key];
                }
            }
        });

        return obj;
    }

    function intl(options) {
        /* jshint validthis:true */
        if (!options.fn) {
            throw new ReferenceError('intl must be invoked as a block helper');
        }

        var hash = options.hash,
            data = options.data;

        return options.fn(this, {
            data: extend({}, data, {
                intl: extend({}, data.intl, hash)
            })
        });
    }

    /**
    Formats the provided date or time stamp to the current locale
    @param {Date|Number} stamp Date Object or time stamp to be formatted
    @param {Object} options Options passed to the method from the handlebars handler
    @return {String} Formatted date
    */
    function intlDate (date, options) {
        date = new Date(date);

        // Determine if `date` is valid.
        if (!(date && date.getTime())) {
            throw new TypeError('A date must be provided.');
        }

        var hash     = options.hash,
            intlData = options.data && options.data.intl;

        return new Intl.DateTimeFormat(intlData.locales, hash).format(date);
    }

    /**
    Formats the provided number based on the options. Options may specify if the
    returned value should be a delineated number, currency value, or a percentage.
    @method intlNumber
    @param {Number} num Number to format
    @param {Object} options Options passed to the method from the handlebars handler
    @return {String} Formatted number
    */
    function intlNumber (num, options) {
        if (typeof num !== 'number') {
            throw new TypeError('A number must be provided.');
        }

        var hash     = options.hash,
            intlData = options.data && options.data.intl;

        return new Intl.NumberFormat(intlData.locales, hash).format(num);
    }

    function intlGet(path, options) {
        var intlData  = (options.data && options.data.intl) || {},
            messages  = intlData.messages,
            pathParts = path.split('.'),
            message, len, i;

        try {
            for (i = 0, len = pathParts.length; i < len; i++) {
                message = messages = messages[pathParts[i]];
            }
        } finally {
            if (message === undefined) {
                throw new ReferenceError('Could not find Intl message: ' + path);
            }
        }

        return message;
    }

    function intlMessage(message, options) {
        if (!options) {
            options = message;
            message = null;
        }

        var hash = options.hash;

        if (!(message || typeof message === 'string' || hash.intlName)) {
            throw new ReferenceError('A message or intlName must be provided');
        }

        var intlData = (options.data && options.data.intl) || {},
            locales  = intlData.locales,
            formats  = intlData.formats;

        // Lookup message by path name.
        if (!message && hash.intlName) {
            message = intlGet(hash.intlName, options);
        }

        // Look for a cached formatter on the message.
        var formatter = message.__formatter__;

        if (!formatter) {
            formatter = new IntlMessageFormat(message, locales, formats);

            // Cache formatter on message. String values don't support expand-o
            // properties, therefore the formatter cannot be cached on them.
            if (typeof message !== 'string') {
                message.__formatter__ = formatter;
            }
        }

        return formatter.format(hash);
    }

    return exports;
});
{'fraction_non_alphanumeric': 0.10073094326487991, 'fraction_numerical': 0.0003480682213713888, 'mean_word_length': 1.9187322226737098, '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': '7169989', 'n_tokens_mistral': 3911, 'n_tokens_neox': 3807, 'n_words': 1274}