// i18next, v1.11.2 // Copyright (c)2015 Jan Mühlemann (jamuhl). // Distributed under MIT license // http://i18next.com (function(root) { // add indexOf to non ECMA-262 standard compliant browsers if (!Array.prototype.indexOf) { Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) { "use strict"; if (this == null) { throw new TypeError(); } var t = Object(this); var len = t.length >>> 0; if (len === 0) { return -1; } var n = 0; if (arguments.length > 0) { n = Number(arguments[1]); if (n != n) { // shortcut for verifying if it's NaN n = 0; } else if (n != 0 && n != Infinity && n != -Infinity) { n = (n > 0 || -1) * Math.floor(Math.abs(n)); } } if (n >= len) { return -1; } var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); for (; k < len; k++) { if (k in t && t[k] === searchElement) { return k; } } return -1; } } // add lastIndexOf to non ECMA-262 standard compliant browsers if (!Array.prototype.lastIndexOf) { Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/) { "use strict"; if (this == null) { throw new TypeError(); } var t = Object(this); var len = t.length >>> 0; if (len === 0) { return -1; } var n = len; if (arguments.length > 1) { n = Number(arguments[1]); if (n != n) { n = 0; } else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) { n = (n > 0 || -1) * Math.floor(Math.abs(n)); } } var k = n >= 0 ? Math.min(n, len - 1) : len - Math.abs(n); for (; k >= 0; k--) { if (k in t && t[k] === searchElement) { return k; } } return -1; }; } // Add string trim for IE8. if (typeof String.prototype.trim !== 'function') { String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); } } var $ = root.jQuery || root.Zepto , i18n = {} , resStore = {} , currentLng , replacementCounter = 0 , languages = [] , initialized = false , sync = {} , conflictReference = null; // Export the i18next object for **CommonJS**. // If we're not in CommonJS, add `i18n` to the // global object or to jquery. if (typeof module !== 'undefined' && module.exports) { module.exports = i18n; } else { if ($) { $.i18n = $.i18n || i18n; } if (root.i18n) { conflictReference = root.i18n; } root.i18n = i18n; } sync = { load: function(lngs, options, cb) { if (options.useLocalStorage) { sync._loadLocal(lngs, options, function(err, store) { var missingLngs = []; for (var i = 0, len = lngs.length; i < len; i++) { if (!store[lngs[i]]) missingLngs.push(lngs[i]); } if (missingLngs.length > 0) { sync._fetch(missingLngs, options, function(err, fetched) { f.extend(store, fetched); sync._storeLocal(fetched); cb(err, store); }); } else { cb(err, store); } }); } else { sync._fetch(lngs, options, function(err, store){ cb(err, store); }); } }, _loadLocal: function(lngs, options, cb) { var store = {} , nowMS = new Date().getTime(); if(window.localStorage) { var todo = lngs.length; f.each(lngs, function(key, lng) { var local = f.localStorage.getItem('res_' + lng); if (local) { local = JSON.parse(local); if (local.i18nStamp && local.i18nStamp + options.localStorageExpirationTime > nowMS) { store[lng] = local; } } todo--; // wait for all done befor callback if (todo === 0) cb(null, store); }); } }, _storeLocal: function(store) { if(window.localStorage) { for (var m in store) { store[m].i18nStamp = new Date().getTime(); f.localStorage.setItem('res_' + m, JSON.stringify(store[m])); } } return; }, _fetch: function(lngs, options, cb) { var ns = options.ns , store = {}; if (!options.dynamicLoad) { var todo = ns.namespaces.length * lngs.length , errors; // load each file individual f.each(ns.namespaces, function(nsIndex, nsValue) { f.each(lngs, function(lngIndex, lngValue) { // Call this once our translation has returned. var loadComplete = function(err, data) { if (err) { errors = errors || []; errors.push(err); } store[lngValue] = store[lngValue] || {}; store[lngValue][nsValue] = data; todo--; // wait for all done befor callback if (todo === 0) cb(errors, store); }; if(typeof options.customLoad == 'function'){ // Use the specified custom callback. options.customLoad(lngValue, nsValue, options, loadComplete); } else { //~ // Use our inbuilt sync. sync._fetchOne(lngValue, nsValue, options, loadComplete); } }); }); } else { // Call this once our translation has returned. var loadComplete = function(err, data) { cb(err, data); }; if(typeof options.customLoad == 'function'){ // Use the specified custom callback. options.customLoad(lngs, ns.namespaces, options, loadComplete); } else { var url = applyReplacement(options.resGetPath, { lng: lngs.join('+'), ns: ns.namespaces.join('+') }); // load all needed stuff once f.ajax({ url: url, cache: options.cache, success: function(data, status, xhr) { f.log('loaded: ' + url); loadComplete(null, data); }, error : function(xhr, status, error) { f.log('failed loading: ' + url); loadComplete('failed loading resource.json error: ' + error); }, dataType: "json", async : options.getAsync, timeout: options.ajaxTimeout }); } } }, _fetchOne: function(lng, ns, options, done) { var url = applyReplacement(options.resGetPath, { lng: lng, ns: ns }); f.ajax({ url: url, cache: options.cache, success: function(data, status, xhr) { f.log('loaded: ' + url); done(null, data); }, error : function(xhr, status, error) { if ((status && status == 200) || (xhr && xhr.status && xhr.status == 200)) { // file loaded but invalid json, stop waste time ! f.error('There is a typo in: ' + url); } else if ((status && status == 404) || (xhr && xhr.status && xhr.status == 404)) { f.log('Does not exist: ' + url); } else { var theStatus = status ? status : ((xhr && xhr.status) ? xhr.status : null); f.log(theStatus + ' when loading ' + url); } done(error, {}); }, dataType: "json", async : options.getAsync, timeout: options.ajaxTimeout, headers: options.headers }); }, postMissing: function(lng, ns, key, defaultValue, lngs) { var payload = {}; payload[key] = defaultValue; var urls = []; if (o.sendMissingTo === 'fallback' && o.fallbackLng[0] !== false) { for (var i = 0; i < o.fallbackLng.length; i++) { urls.push({lng: o.fallbackLng[i], url: applyReplacement(o.resPostPath, { lng: o.fallbackLng[i], ns: ns })}); } } else if (o.sendMissingTo === 'current' || (o.sendMissingTo === 'fallback' && o.fallbackLng[0] === false) ) { urls.push({lng: lng, url: applyReplacement(o.resPostPath, { lng: lng, ns: ns })}); } else if (o.sendMissingTo === 'all') { for (var i = 0, l = lngs.length; i < l; i++) { urls.push({lng: lngs[i], url: applyReplacement(o.resPostPath, { lng: lngs[i], ns: ns })}); } } for (var y = 0, len = urls.length; y < len; y++) { var item = urls[y]; f.ajax({ url: item.url, type: o.sendType, data: payload, success: function(data, status, xhr) { f.log('posted missing key \'' + key + '\' to: ' + item.url); // add key to resStore var keys = key.split('.'); var x = 0; var value = resStore[item.lng][ns]; while (keys[x]) { if (x === keys.length - 1) { value = value[keys[x]] = defaultValue; } else { value = value[keys[x]] = value[keys[x]] || {}; } x++; } }, error : function(xhr, status, error) { f.log('failed posting missing key \'' + key + '\' to: ' + item.url); }, dataType: "json", async : o.postAsync, timeout: o.ajaxTimeout }); } }, reload: reload }; // defaults var o = { lng: undefined, load: 'all', preload: [], lowerCaseLng: false, returnObjectTrees: false, fallbackLng: ['dev'], fallbackNS: [], detectLngQS: 'setLng', detectLngFromLocalStorage: false, ns: { namespaces: ['translation'], defaultNs: 'translation' }, fallbackOnNull: true, fallbackOnEmpty: false, fallbackToDefaultNS: false, showKeyIfEmpty: false, nsseparator: ':', keyseparator: '.', selectorAttr: 'data-i18n', debug: false, resGetPath: 'locales/__lng__/__ns__.json', resPostPath: 'locales/add/__lng__/__ns__', getAsync: true, postAsync: true, resStore: undefined, useLocalStorage: false, localStorageExpirationTime: 7*24*60*60*1000, dynamicLoad: false, sendMissing: false, sendMissingTo: 'fallback', // current | all sendType: 'POST', interpolationPrefix: '__', interpolationSuffix: '__', defaultVariables: false, reusePrefix: '$t(', reuseSuffix: ')', pluralSuffix: '_plural', pluralNotFound: ['plural_not_found', Math.random()].join(''), contextNotFound: ['context_not_found', Math.random()].join(''), escapeInterpolation: false, indefiniteSuffix: '_indefinite', indefiniteNotFound: ['indefinite_not_found', Math.random()].join(''), setJqueryExt: true, defaultValueFromContent: true, useDataAttrOptions: false, cookieExpirationTime: undefined, useCookie: true, cookieName: 'i18next', cookieDomain: undefined, objectTreeKeyHandler: undefined, postProcess: undefined, parseMissingKey: undefined, missingKeyHandler: sync.postMissing, ajaxTimeout: 0, shortcutFunction: 'sprintf' // or: defaultValue }; function _extend(target, source) { if (!source || typeof source === 'function') { return target; } for (var attr in source) { target[attr] = source[attr]; } return target; } function _deepExtend(target, source, overwrite) { for (var prop in source) if (prop in target) { // If we reached a leaf string in target or source then replace with source or skip depending on the 'overwrite' switch if (typeof target[prop] === 'string' || target[prop] instanceof String || typeof source[prop] === 'string' || source[prop] instanceof String) { if (overwrite) { target[prop] = source[prop]; } } else { _deepExtend(target[prop], source[prop], overwrite); } } else { target[prop] = source[prop]; } return target; } function _each(object, callback, args) { var name, i = 0, length = object.length, isObj = length === undefined || Object.prototype.toString.apply(object) !== '[object Array]' || typeof object === "function"; if (args) { if (isObj) { for (name in object) { if (callback.apply(object[name], args) === false) { break; } } } else { for ( ; i < length; ) { if (callback.apply(object[i++], args) === false) { break; } } } // A special, fast, case for the most common use of each } else { if (isObj) { for (name in object) { if (callback.call(object[name], name, object[name]) === false) { break; } } } else { for ( ; i < length; ) { if (callback.call(object[i], i, object[i++]) === false) { break; } } } } return object; } var _entityMap = { "&": "&", "<": "<", ">": ">", '"': '"', "'": ''', "/": '/' }; function _escape(data) { if (typeof data === 'string') { return data.replace(/[&<>"'\/]/g, function (s) { return _entityMap[s]; }); }else{ return data; } } function _ajax(options) { // v0.5.0 of https://github.com/goloroden/http.js var getXhr = function (callback) { // Use the native XHR object if the browser supports it. if (window.XMLHttpRequest) { return callback(null, new XMLHttpRequest()); } else if (window.ActiveXObject) { // In Internet Explorer check for ActiveX versions of the XHR object. try { return callback(null, new ActiveXObject("Msxml2.XMLHTTP")); } catch (e) { return callback(null, new ActiveXObject("Microsoft.XMLHTTP")); } } // If no XHR support was found, throw an error. return callback(new Error()); }; var encodeUsingUrlEncoding = function (data) { if(typeof data === 'string') { return data; } var result = []; for(var dataItem in data) { if(data.hasOwnProperty(dataItem)) { result.push(encodeURIComponent(dataItem) + '=' + encodeURIComponent(data[dataItem])); } } return result.join('&'); }; var utf8 = function (text) { text = text.replace(/\r\n/g, '\n'); var result = ''; for(var i = 0; i < text.length; i++) { var c = text.charCodeAt(i); if(c < 128) { result += String.fromCharCode(c); } else if((c > 127) && (c < 2048)) { result += String.fromCharCode((c >> 6) | 192); result += String.fromCharCode((c & 63) | 128); } else { result += String.fromCharCode((c >> 12) | 224); result += String.fromCharCode(((c >> 6) & 63) | 128); result += String.fromCharCode((c & 63) | 128); } } return result; }; var base64 = function (text) { var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; text = utf8(text); var result = '', chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0; do { chr1 = text.charCodeAt(i++); chr2 = text.charCodeAt(i++); chr3 = text.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if(isNaN(chr2)) { enc3 = enc4 = 64; } else if(isNaN(chr3)) { enc4 = 64; } result += keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4); chr1 = chr2 = chr3 = ''; enc1 = enc2 = enc3 = enc4 = ''; } while(i < text.length); return result; }; var mergeHeaders = function () { // Use the first header object as base. var result = arguments[0]; // Iterate through the remaining header objects and add them. for(var i = 1; i < arguments.length; i++) { var currentHeaders = arguments[i]; for(var header in currentHeaders) { if(currentHeaders.hasOwnProperty(header)) { result[header] = currentHeaders[header]; } } } // Return the merged headers. return result; }; var ajax = function (method, url, options, callback) { // Adjust parameters. if(typeof options === 'function') { callback = options; options = {}; } // Set default parameter values. options.cache = options.cache || false; options.data = options.data || {}; options.headers = options.headers || {}; options.jsonp = options.jsonp || false; options.async = options.async === undefined ? true : options.async; // Merge the various header objects. var headers = mergeHeaders({ 'accept': '*/*', 'content-type': 'application/x-www-form-urlencoded;charset=UTF-8' }, ajax.headers, options.headers); // Encode the data according to the content-type. var payload; if (headers['content-type'] === 'application/json') { payload = JSON.stringify(options.data); } else { payload = encodeUsingUrlEncoding(options.data); } // Specially prepare GET requests: Setup the query string, handle caching and make a JSONP call // if neccessary. if(method === 'GET') { // Setup the query string. var queryString = []; if(payload) { queryString.push(payload); payload = null; } // Handle caching. if(!options.cache) { queryString.push('_=' + (new Date()).getTime()); } // If neccessary prepare the query string for a JSONP call. if(options.jsonp) { queryString.push('callback=' + options.jsonp); queryString.push('jsonp=' + options.jsonp); } // Merge the query string and attach it to the url. queryString = queryString.join('&'); if (queryString.length > 1) { if (url.indexOf('?') > -1) { url += '&' + queryString; } else { url += '?' + queryString; } } // Make a JSONP call if neccessary. if(options.jsonp) { var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.type = 'text/javascript'; script.src = url; head.appendChild(script); return; } } // Since we got here, it is no JSONP request, so make a normal XHR request. getXhr(function (err, xhr) { if(err) return callback(err); // Open the request. xhr.open(method, url, options.async); // Set the request headers. for(var header in headers) { if(headers.hasOwnProperty(header)) { xhr.setRequestHeader(header, headers[header]); } } // Handle the request events. xhr.onreadystatechange = function () { if(xhr.readyState === 4) { var data = xhr.responseText || ''; // If no callback is given, return. if(!callback) { return; } // Return an object that provides access to the data as text and JSON. callback(xhr.status, { text: function () { return data; }, json: function () { try { return JSON.parse(data) } catch (e) { f.error('Can not parse JSON. URL: ' + url); return {}; } } }); } }; // Actually send the XHR request. xhr.send(payload); }); }; // Define the external interface. var http = { authBasic: function (username, password) { ajax.headers['Authorization'] = 'Basic ' + base64(username + ':' + password); }, connect: function (url, options, callback) { return ajax('CONNECT', url, options, callback); }, del: function (url, options, callback) { return ajax('DELETE', url, options, callback); }, get: function (url, options, callback) { return ajax('GET', url, options, callback); }, head: function (url, options, callback) { return ajax('HEAD', url, options, callback); }, headers: function (headers) { ajax.headers = headers || {}; }, isAllowed: function (url, verb, callback) { this.options(url, function (status, data) { callback(data.text().indexOf(verb) !== -1); }); }, options: function (url, options, callback) { return ajax('OPTIONS', url, options, callback); }, patch: function (url, options, callback) { return ajax('PATCH', url, options, callback); }, post: function (url, options, callback) { return ajax('POST', url, options, callback); }, put: function (url, options, callback) { return ajax('PUT', url, options, callback); }, trace: function (url, options, callback) { return ajax('TRACE', url, options, callback); } }; var methode = options.type ? options.type.toLowerCase() : 'get'; http[methode](options.url, options, function (status, data) { // file: protocol always gives status code 0, so check for data if (status === 200 || (status === 0 && data.text())) { options.success(data.json(), status, null); } else { options.error(data.text(), status, null); } }); } var _cookie = { create: function(name,value,minutes,domain) { var expires; if (minutes) { var date = new Date(); date.setTime(date.getTime()+(minutes*60*1000)); expires = "; expires="+date.toGMTString(); } else expires = ""; domain = (domain)? "domain="+domain+";" : ""; document.cookie = name+"="+value+expires+";"+domain+"path=/"; }, read: function(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length,c.length); } return null; }, remove: function(name) { this.create(name,"",-1); } }; var cookie_noop = { create: function(name,value,minutes,domain) {}, read: function(name) { return null; }, remove: function(name) {} }; // move dependent functions to a container so that // they can be overriden easier in no jquery environment (node.js) var f = { extend: $ ? $.extend : _extend, deepExtend: _deepExtend, each: $ ? $.each : _each, ajax: $ ? $.ajax : (typeof document !== 'undefined' ? _ajax : function() {}), cookie: typeof document !== 'undefined' ? _cookie : cookie_noop, detectLanguage: detectLanguage, escape: _escape, log: function(str) { if (o.debug && typeof console !== "undefined") console.log(str); }, error: function(str) { if (typeof console !== "undefined") console.error(str); }, getCountyIndexOfLng: function(lng) { var lng_index = 0; if (lng === 'nb-NO' || lng === 'nn-NO' || lng === 'nb-no' || lng === 'nn-no') lng_index = 1; return lng_index; }, toLanguages: function(lng, fallbackLng) { var log = this.log; fallbackLng = fallbackLng || o.fallbackLng; if (typeof fallbackLng === 'string') fallbackLng = [fallbackLng]; function applyCase(l) { var ret = l; if (typeof l === 'string' && l.indexOf('-') > -1) { var parts = l.split('-'); ret = o.lowerCaseLng ? parts[0].toLowerCase() + '-' + parts[1].toLowerCase() : parts[0].toLowerCase() + '-' + parts[1].toUpperCase(); } else { ret = o.lowerCaseLng ? l.toLowerCase() : l; } return ret; } var languages = []; var whitelist = o.lngWhitelist || false; var addLanguage = function(language){ //reject langs not whitelisted if(!whitelist || whitelist.indexOf(language) > -1){ languages.push(language); }else{ log('rejecting non-whitelisted language: ' + language); } }; if (typeof lng === 'string' && lng.indexOf('-') > -1) { var parts = lng.split('-'); if (o.load !== 'unspecific') addLanguage(applyCase(lng)); if (o.load !== 'current') addLanguage(applyCase(parts[this.getCountyIndexOfLng(lng)])); } else { addLanguage(applyCase(lng)); } for (var i = 0; i < fallbackLng.length; i++) { if (languages.indexOf(fallbackLng[i]) === -1 && fallbackLng[i]) languages.push(applyCase(fallbackLng[i])); } return languages; }, regexEscape: function(str) { return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); }, regexReplacementEscape: function(strOrFn) { if (typeof strOrFn === 'string') { return strOrFn.replace(/\$/g, "$$$$"); } else { return strOrFn; } }, localStorage: { setItem: function(key, value) { if (window.localStorage) { try { window.localStorage.setItem(key, value); } catch (e) { f.log('failed to set value for key "' + key + '" to localStorage.'); } } }, getItem: function(key, value) { if (window.localStorage) { try { return window.localStorage.getItem(key, value); } catch (e) { f.log('failed to get value for key "' + key + '" from localStorage.'); return undefined; } } } } }; function init(options, cb) { if (typeof options === 'function') { cb = options; options = {}; } options = options || {}; // override defaults with passed in options f.extend(o, options); delete o.fixLng; /* passed in each time */ // override functions: .log(), .detectLanguage(), etc if (o.functions) { delete o.functions; f.extend(f, options.functions); } // create namespace object if namespace is passed in as string if (typeof o.ns == 'string') { o.ns = { namespaces: [o.ns], defaultNs: o.ns}; } // fallback namespaces if (typeof o.fallbackNS == 'string') { o.fallbackNS = [o.fallbackNS]; } // fallback languages if (typeof o.fallbackLng == 'string' || typeof o.fallbackLng == 'boolean') { o.fallbackLng = [o.fallbackLng]; } // escape prefix/suffix o.interpolationPrefixEscaped = f.regexEscape(o.interpolationPrefix); o.interpolationSuffixEscaped = f.regexEscape(o.interpolationSuffix); if (!o.lng) o.lng = f.detectLanguage(); languages = f.toLanguages(o.lng); currentLng = languages[0]; f.log('currentLng set to: ' + currentLng); if (o.useCookie && f.cookie.read(o.cookieName) !== currentLng){ //cookie is unset or invalid f.cookie.create(o.cookieName, currentLng, o.cookieExpirationTime, o.cookieDomain); } if (o.detectLngFromLocalStorage && typeof document !== 'undefined' && window.localStorage) { f.localStorage.setItem('i18next_lng', currentLng); } var lngTranslate = translate; if (options.fixLng) { lngTranslate = function(key, options) { options = options || {}; options.lng = options.lng || lngTranslate.lng; return translate(key, options); }; lngTranslate.lng = currentLng; } pluralExtensions.setCurrentLng(currentLng); // add JQuery extensions if ($ && o.setJqueryExt) { addJqueryFunct && addJqueryFunct(); } else { addJqueryLikeFunctionality && addJqueryLikeFunctionality(); } // jQuery deferred var deferred; if ($ && $.Deferred) { deferred = $.Deferred(); } // return immidiatly if res are passed in if (o.resStore) { resStore = o.resStore; initialized = true; if (cb) cb(null, lngTranslate); if (deferred) deferred.resolve(lngTranslate); if (deferred) return deferred.promise(); return; } // languages to load var lngsToLoad = f.toLanguages(o.lng); if (typeof o.preload === 'string') o.preload = [o.preload]; for (var i = 0, l = o.preload.length; i < l; i++) { var pres = f.toLanguages(o.preload[i]); for (var y = 0, len = pres.length; y < len; y++) { if (lngsToLoad.indexOf(pres[y]) < 0) { lngsToLoad.push(pres[y]); } } } // else load them i18n.sync.load(lngsToLoad, o, function(err, store) { resStore = store; initialized = true; if (cb) cb(err, lngTranslate); if (deferred) (!err ? deferred.resolve : deferred.reject)(err || lngTranslate); }); if (deferred) return deferred.promise(); } function isInitialized() { return initialized; } function preload(lngs, cb) { if (typeof lngs === 'string') lngs = [lngs]; for (var i = 0, l = lngs.length; i < l; i++) { if (o.preload.indexOf(lngs[i]) < 0) { o.preload.push(lngs[i]); } } return init(cb); } function addResourceBundle(lng, ns, resources, deep, overwrite) { if (typeof ns !== 'string') { resources = ns; ns = o.ns.defaultNs; } else if (o.ns.namespaces.indexOf(ns) < 0) { o.ns.namespaces.push(ns); } resStore[lng] = resStore[lng] || {}; resStore[lng][ns] = resStore[lng][ns] || {}; if (deep) { f.deepExtend(resStore[lng][ns], resources, overwrite); } else { f.extend(resStore[lng][ns], resources); } if (o.useLocalStorage) { sync._storeLocal(resStore); } } function hasResourceBundle(lng, ns) { if (typeof ns !== 'string') { ns = o.ns.defaultNs; } resStore[lng] = resStore[lng] || {}; var res = resStore[lng][ns] || {}; var hasValues = false; for(var prop in res) { if (res.hasOwnProperty(prop)) { hasValues = true; } } return hasValues; } function getResourceBundle(lng, ns) { if (typeof ns !== 'string') { ns = o.ns.defaultNs; } resStore[lng] = resStore[lng] || {}; return f.extend({}, resStore[lng][ns]); } function removeResourceBundle(lng, ns) { if (typeof ns !== 'string') { ns = o.ns.defaultNs; } resStore[lng] = resStore[lng] || {}; resStore[lng][ns] = {}; if (o.useLocalStorage) { sync._storeLocal(resStore); } } function addResource(lng, ns, key, value) { if (typeof ns !== 'string') { resource = ns; ns = o.ns.defaultNs; } else if (o.ns.namespaces.indexOf(ns) < 0) { o.ns.namespaces.push(ns); } resStore[lng] = resStore[lng] || {}; resStore[lng][ns] = resStore[lng][ns] || {}; var keys = key.split(o.keyseparator); var x = 0; var node = resStore[lng][ns]; var origRef = node; while (keys[x]) { if (x == keys.length - 1) node[keys[x]] = value; else { if (node[keys[x]] == null) node[keys[x]] = {}; node = node[keys[x]]; } x++; } if (o.useLocalStorage) { sync._storeLocal(resStore); } } function addResources(lng, ns, resources) { if (typeof ns !== 'string') { resources = ns; ns = o.ns.defaultNs; } else if (o.ns.namespaces.indexOf(ns) < 0) { o.ns.namespaces.push(ns); } for (var m in resources) { if (typeof resources[m] === 'string') addResource(lng, ns, m, resources[m]); } } function setDefaultNamespace(ns) { o.ns.defaultNs = ns; } function loadNamespace(namespace, cb) { loadNamespaces([namespace], cb); } function loadNamespaces(namespaces, cb) { var opts = { dynamicLoad: o.dynamicLoad, resGetPath: o.resGetPath, getAsync: o.getAsync, customLoad: o.customLoad, ns: { namespaces: namespaces, defaultNs: ''} /* new namespaces to load */ }; // languages to load var lngsToLoad = f.toLanguages(o.lng); if (typeof o.preload === 'string') o.preload = [o.preload]; for (var i = 0, l = o.preload.length; i < l; i++) { var pres = f.toLanguages(o.preload[i]); for (var y = 0, len = pres.length; y < len; y++) { if (lngsToLoad.indexOf(pres[y]) < 0) { lngsToLoad.push(pres[y]); } } } // check if we have to load var lngNeedLoad = []; for (var a = 0, lenA = lngsToLoad.length; a < lenA; a++) { var needLoad = false; var resSet = resStore[lngsToLoad[a]]; if (resSet) { for (var b = 0, lenB = namespaces.length; b < lenB; b++) { if (!resSet[namespaces[b]]) needLoad = true; } } else { needLoad = true; } if (needLoad) lngNeedLoad.push(lngsToLoad[a]); } if (lngNeedLoad.length) { i18n.sync._fetch(lngNeedLoad, opts, function(err, store) { var todo = namespaces.length * lngNeedLoad.length; // load each file individual f.each(namespaces, function(nsIndex, nsValue) { // append namespace to namespace array if (o.ns.namespaces.indexOf(nsValue) < 0) { o.ns.namespaces.push(nsValue); } f.each(lngNeedLoad, function(lngIndex, lngValue) { resStore[lngValue] = resStore[lngValue] || {}; resStore[lngValue][nsValue] = store[lngValue][nsValue]; todo--; // wait for all done befor callback if (todo === 0 && cb) { if (o.useLocalStorage) i18n.sync._storeLocal(resStore); cb(); } }); }); }); } else { if (cb) cb(); } } function setLng(lng, options, cb) { if (typeof options === 'function') { cb = options; options = {}; } else if (!options) { options = {}; } options.lng = lng; return init(options, cb); } function lng() { return currentLng; } function dir() { var rtlLangs = [ "ar", "shu", "sqr", "ssh", "xaa", "yhd", "yud", "aao", "abh", "abv", "acm", "acq", "acw", "acx", "acy", "adf", "ads", "aeb", "aec", "afb", "ajp", "apc", "apd", "arb", "arq", "ars", "ary", "arz", "auz", "avl", "ayh", "ayl", "ayn", "ayp", "bbz", "pga", "he", "iw", "ps", "pbt", "pbu", "pst", "prp", "prd", "ur", "ydd", "yds", "yih", "ji", "yi", "hbo", "men", "xmn", "fa", "jpr", "peo", "pes", "prs", "dv", "sam" ]; if ( rtlLangs.some( function( lang ) { return new RegExp( '^' + lang ).test( currentLng ); } ) ) { return 'rtl'; } return 'ltr'; } function reload(cb) { resStore = {}; setLng(currentLng, cb); } function noConflict() { window.i18next = window.i18n; if (conflictReference) { window.i18n = conflictReference; } else { delete window.i18n; } } function addJqueryFunct() { // $.t shortcut $.t = $.t || translate; function parse(ele, key, options) { if (key.length === 0) return; var attr = 'text'; if (key.indexOf('[') === 0) { var parts = key.split(']'); key = parts[1]; attr = parts[0].substr(1, parts[0].length-1); } if (key.indexOf(';') === key.length-1) { key = key.substr(0, key.length-2); } var optionsToUse; if (attr === 'html') { optionsToUse = o.defaultValueFromContent ? $.extend({ defaultValue: ele.html() }, options) : options; ele.html($.t(key, optionsToUse)); } else if (attr === 'text') { optionsToUse = o.defaultValueFromContent ? $.extend({ defaultValue: ele.text() }, options) : options; ele.text($.t(key, optionsToUse)); } else if (attr === 'prepend') { optionsToUse = o.defaultValueFromContent ? $.extend({ defaultValue: ele.html() }, options) : options; ele.prepend($.t(key, optionsToUse)); } else if (attr === 'append') { optionsToUse = o.defaultValueFromContent ? $.extend({ defaultValue: ele.html() }, options) : options; ele.append($.t(key, optionsToUse)); } else if (attr.indexOf("data-") === 0) { var dataAttr = attr.substr(("data-").length); optionsToUse = o.defaultValueFromContent ? $.extend({ defaultValue: ele.data(dataAttr) }, options) : options; var translated = $.t(key, optionsToUse); //we change into the data cache ele.data(dataAttr, translated); //we change into the dom ele.attr(attr, translated); } else { optionsToUse = o.defaultValueFromContent ? $.extend({ defaultValue: ele.attr(attr) }, options) : options; ele.attr(attr, $.t(key, optionsToUse)); } } function localize(ele, options) { var key = ele.attr(o.selectorAttr); if (!key && typeof key !== 'undefined' && key !== false) key = ele.text() || ele.val(); if (!key) return; var target = ele , targetSelector = ele.data("i18n-target"); if (targetSelector) { target = ele.find(targetSelector) || ele; } if (!options && o.useDataAttrOptions === true) { options = ele.data("i18n-options"); } options = options || {}; if (key.indexOf(';') >= 0) { var keys = key.split(';'); $.each(keys, function(m, k) { if (k !== '') parse(target, k, options); }); } else { parse(target, key, options); } if (o.useDataAttrOptions === true) { var clone = $.extend({lng: 'non', lngs: [], _origLng: 'non'}, options); delete clone.lng; delete clone.lngs; delete clone._origLng; ele.data("i18n-options", clone); } } // fn $.fn.i18n = function (options) { return this.each(function() { // localize element itself localize($(this), options); // localize childs var elements = $(this).find('[' + o.selectorAttr + ']'); elements.each(function() { localize($(this), options); }); }); }; } function addJqueryLikeFunctionality() { function parse(ele, key, options) { if (key.length === 0) return; var attr = 'text'; if (key.indexOf('[') === 0) { var parts = key.split(']'); key = parts[1]; attr = parts[0].substr(1, parts[0].length-1); } if (key.indexOf(';') === key.length-1) { key = key.substr(0, key.length-2); } if (attr === 'html') { ele.innerHTML = translate(key, options); } else if (attr === 'text') { ele.textContent = translate(key, options); } else if (attr === 'prepend') { ele.insertAdjacentHTML(translate(key, options), 'afterbegin'); } else if (attr === 'append') { ele.insertAdjacentHTML(translate(key, options), 'beforeend'); } else { ele.setAttribute(attr, translate(key, options)); } } function localize(ele, options) { var key = ele.getAttribute(o.selectorAttr); if (!key && typeof key !== 'undefined' && key !== false) key = ele.textContent || ele.value; if (!key) return; var target = ele , targetSelector = ele.getAttribute("i18n-target"); if (targetSelector) { target = ele.querySelector(targetSelector) || ele; } if (key.indexOf(';') >= 0) { var keys = key.split(';'), index = 0, length = keys.length; for ( ; index < length; index++) { if (keys[index] !== '') parse(target, keys[index], options); } } else { parse(target, key, options); } } // fn i18n.translateObject = function (object, options) { // localize childs var elements = object.querySelectorAll('[' + o.selectorAttr + ']'); var index = 0, length = elements.length; for ( ; index < length; index++) { localize(elements[index], options); } }; } function applyReplacement(str, replacementHash, nestedKey, options) { if (!str) return str; options = options || replacementHash; // first call uses replacement hash combined with options if (str.indexOf(options.interpolationPrefix || o.interpolationPrefix) < 0) return str; var prefix = options.interpolationPrefix ? f.regexEscape(options.interpolationPrefix) : o.interpolationPrefixEscaped , suffix = options.interpolationSuffix ? f.regexEscape(options.interpolationSuffix) : o.interpolationSuffixEscaped , keyseparator = options.keyseparator || o.keyseparator , unEscapingSuffix = 'HTML'+suffix; var hash = replacementHash.replace && typeof replacementHash.replace === 'object' ? replacementHash.replace : replacementHash; var replacementRegex = new RegExp([prefix, '(.+?)', '(HTML)?', suffix].join(''), 'g'); var escapeInterpolation = options.escapeInterpolation || o.escapeInterpolation; return str.replace(replacementRegex, function (wholeMatch, keyMatch, htmlMatched) { // Check for recursive matches of object var objectMatching = hash; var keyLeaf = keyMatch; while (keyLeaf.indexOf(keyseparator) >= 0 && typeof objectMatching === 'object' && objectMatching) { var propName = keyLeaf.slice(0, keyLeaf.indexOf(keyseparator)); keyLeaf = keyLeaf.slice(keyLeaf.indexOf(keyseparator) + 1); objectMatching = objectMatching[propName]; } if (objectMatching && typeof objectMatching === 'object' && objectMatching.hasOwnProperty(keyLeaf)) { var value = objectMatching[keyLeaf]; if (escapeInterpolation && !htmlMatched) { return f.escape(objectMatching[keyLeaf]); } else { return objectMatching[keyLeaf]; } } else { return wholeMatch; } }); } // append it to functions f.applyReplacement = applyReplacement; function applyReuse(translated, options) { var comma = ','; var options_open = '{'; var options_close = '}'; var opts = f.extend({}, options); delete opts.postProcess; delete opts.isFallbackLookup; while (translated.indexOf(o.reusePrefix) != -1) { replacementCounter++; if (replacementCounter > o.maxRecursion) { break; } // safety net for too much recursion var index_of_opening = translated.lastIndexOf(o.reusePrefix); var index_of_end_of_closing = translated.indexOf(o.reuseSuffix, index_of_opening) + o.reuseSuffix.length; var token = translated.substring(index_of_opening, index_of_end_of_closing); var token_without_symbols = token.replace(o.reusePrefix, '').replace(o.reuseSuffix, ''); if (index_of_end_of_closing <= index_of_opening) { f.error('there is an missing closing in following translation value', translated); return ''; } if (token_without_symbols.indexOf(comma) != -1) { var index_of_token_end_of_closing = token_without_symbols.indexOf(comma); if (token_without_symbols.indexOf(options_open, index_of_token_end_of_closing) != -1 && token_without_symbols.indexOf(options_close, index_of_token_end_of_closing) != -1) { var index_of_opts_opening = token_without_symbols.indexOf(options_open, index_of_token_end_of_closing); var index_of_opts_end_of_closing = token_without_symbols.indexOf(options_close, index_of_opts_opening) + options_close.length; try { opts = f.extend(opts, JSON.parse(token_without_symbols.substring(index_of_opts_opening, index_of_opts_end_of_closing))); token_without_symbols = token_without_symbols.substring(0, index_of_token_end_of_closing); } catch (e) { } } } var translated_token = _translate(token_without_symbols, opts); translated = translated.replace(token, f.regexReplacementEscape(translated_token)); } return translated; } function hasContext(options) { return (options.context && (typeof options.context == 'string' || typeof options.context == 'number')); } function needsPlural(options, lng) { return (options.count !== undefined && typeof options.count != 'string'/* && pluralExtensions.needsPlural(lng, options.count)*/); } function needsIndefiniteArticle(options) { return (options.indefinite_article !== undefined && typeof options.indefinite_article != 'string' && options.indefinite_article); } function exists(key, options) { options = options || {}; var notFound = _getDefaultValue(key, options) , found = _find(key, options); return found !== undefined || found === notFound; } function translate(key, options) { if (!initialized) { f.log('i18next not finished initialization. you might have called t function before loading resources finished.') if (options && options.defaultValue) { return options.detaultValue; } else { return ''; } }; replacementCounter = 0; return _translate.apply(null, arguments); } function _getDefaultValue(key, options) { return (options.defaultValue !== undefined) ? options.defaultValue : key; } function _injectSprintfProcessor() { var values = []; // mh: build array from second argument onwards for (var i = 1; i < arguments.length; i++) { values.push(arguments[i]); } return { postProcess: 'sprintf', sprintf: values }; } function _translate(potentialKeys, options) { if (typeof options !== 'undefined' && typeof options !== 'object') { if (o.shortcutFunction === 'sprintf') { // mh: gettext like sprintf syntax found, automatically create sprintf processor options = _injectSprintfProcessor.apply(null, arguments); } else if (o.shortcutFunction === 'defaultValue') { options = { defaultValue: options } } } else { options = options || {}; } if (typeof o.defaultVariables === 'object') { options = f.extend({}, o.defaultVariables, options); } if (potentialKeys === undefined || potentialKeys === null || potentialKeys === '') return ''; if (typeof potentialKeys === 'number') { potentialKeys = String(potentialKeys); } if (typeof potentialKeys === 'string') { potentialKeys = [potentialKeys]; } var key = potentialKeys[0]; if (potentialKeys.length > 1) { for (var i = 0; i < potentialKeys.length; i++) { key = potentialKeys[i]; if (exists(key, options)) { break; } } } var notFound = _getDefaultValue(key, options) , found = _find(key, options) , nsseparator = options.nsseparator || o.nsseparator , lngs = options.lng ? f.toLanguages(options.lng, options.fallbackLng) : languages , ns = options.ns || o.ns.defaultNs , parts; // split ns and key if (key.indexOf(nsseparator) > -1) { parts = key.split(nsseparator); ns = parts[0]; key = parts[1]; } if (found === undefined && o.sendMissing && typeof o.missingKeyHandler === 'function') { if (options.lng) { o.missingKeyHandler(lngs[0], ns, key, notFound, lngs); } else { o.missingKeyHandler(o.lng, ns, key, notFound, lngs); } } var postProcessorsToApply, postProcessor, j; if (typeof o.postProcess === 'string' && o.postProcess !== '') { postProcessorsToApply = [o.postProcess]; } else if (typeof o.postProcess === 'array' || typeof o.postProcess === 'object') { postProcessorsToApply = o.postProcess; } else { postProcessorsToApply = []; } if (typeof options.postProcess === 'string' && options.postProcess !== '') { postProcessorsToApply = postProcessorsToApply.concat([options.postProcess]); } else if (typeof options.postProcess === 'array' || typeof options.postProcess === 'object') { postProcessorsToApply = postProcessorsToApply.concat(options.postProcess); } if (found !== undefined && postProcessorsToApply.length) { for (j = 0; j < postProcessorsToApply.length; j += 1) { postProcessor = postProcessorsToApply[j]; if (postProcessors[postProcessor]) { found = postProcessors[postProcessor](found, key, options); } } } // process notFound if function exists var splitNotFound = notFound; if (notFound.indexOf(nsseparator) > -1) { parts = notFound.split(nsseparator); splitNotFound = parts[1]; } if (splitNotFound === key && o.parseMissingKey) { notFound = o.parseMissingKey(notFound); } if (found === undefined) { notFound = applyReplacement(notFound, options); notFound = applyReuse(notFound, options); if (postProcessorsToApply.length) { found = _getDefaultValue(key, options); for (j = 0; j < postProcessorsToApply.length; j += 1) { postProcessor = postProcessorsToApply[j]; if (postProcessors[postProcessor]) { found = postProcessors[postProcessor](found, key, options); } } } } return (found !== undefined) ? found : notFound; } function _find(key, options) { options = options || {}; var optionWithoutCount, translated , notFound = _getDefaultValue(key, options) , lngs = languages; if (!resStore) { return notFound; } // no resStore to translate from // CI mode if (lngs[0].toLowerCase() === 'cimode') return notFound; // passed in lng if (options.lngs) lngs = options.lngs; if (options.lng) { lngs = f.toLanguages(options.lng, options.fallbackLng); if (!resStore[lngs[0]]) { var oldAsync = o.getAsync; o.getAsync = false; i18n.sync.load(lngs, o, function(err, store) { f.extend(resStore, store); o.getAsync = oldAsync; }); } } var ns = options.ns || o.ns.defaultNs; var nsseparator = options.nsseparator || o.nsseparator; if (key.indexOf(nsseparator) > -1) { var parts = key.split(nsseparator); ns = parts[0]; key = parts[1]; } if (hasContext(options)) { optionWithoutCount = f.extend({}, options); delete optionWithoutCount.context; optionWithoutCount.defaultValue = o.contextNotFound; var contextKey = ns + nsseparator + key + '_' + options.context; translated = translate(contextKey, optionWithoutCount); if (translated != o.contextNotFound) { return applyReplacement(translated, { context: options.context }); // apply replacement for context only } // else continue translation with original/nonContext key } if (needsPlural(options, lngs[0])) { optionWithoutCount = f.extend({ lngs: [lngs[0]]}, options); delete optionWithoutCount.count; optionWithoutCount._origLng = optionWithoutCount._origLng || optionWithoutCount.lng || lngs[0]; delete optionWithoutCount.lng; optionWithoutCount.defaultValue = o.pluralNotFound; var pluralKey; if (!pluralExtensions.needsPlural(lngs[0], options.count)) { pluralKey = ns + nsseparator + key; } else { pluralKey = ns + nsseparator + key + o.pluralSuffix; var pluralExtension = pluralExtensions.get(lngs[0], options.count); if (pluralExtension >= 0) { pluralKey = pluralKey + '_' + pluralExtension; } else if (pluralExtension === 1) { pluralKey = ns + nsseparator + key; // singular } } translated = translate(pluralKey, optionWithoutCount); if (translated != o.pluralNotFound) { return applyReplacement(translated, { count: options.count, interpolationPrefix: options.interpolationPrefix, interpolationSuffix: options.interpolationSuffix }); // apply replacement for count only } else if (lngs.length > 1) { // remove failed lng var clone = lngs.slice(); clone.shift(); options = f.extend(options, { lngs: clone }); options._origLng = optionWithoutCount._origLng; delete options.lng; // retry with fallbacks translated = translate(ns + nsseparator + key, options); if (translated != o.pluralNotFound) return translated; } else { optionWithoutCount.lng = optionWithoutCount._origLng; delete optionWithoutCount._origLng; translated = translate(ns + nsseparator + key, optionWithoutCount); return applyReplacement(translated, { count: options.count, interpolationPrefix: options.interpolationPrefix, interpolationSuffix: options.interpolationSuffix }); } } if (needsIndefiniteArticle(options)) { var optionsWithoutIndef = f.extend({}, options); delete optionsWithoutIndef.indefinite_article; optionsWithoutIndef.defaultValue = o.indefiniteNotFound; // If we don't have a count, we want the indefinite, if we do have a count, and needsPlural is false var indefiniteKey = ns + nsseparator + key + (((options.count && !needsPlural(options, lngs[0])) || !options.count) ? o.indefiniteSuffix : ""); translated = translate(indefiniteKey, optionsWithoutIndef); if (translated != o.indefiniteNotFound) { return translated; } } var found; var keyseparator = options.keyseparator || o.keyseparator; var keys = key.split(keyseparator); for (var i = 0, len = lngs.length; i < len; i++ ) { if (found !== undefined) break; var l = lngs[i]; var x = 0; var value = resStore[l] && resStore[l][ns]; while (keys[x]) { value = value && value[keys[x]]; x++; } if (value !== undefined && (!o.showKeyIfEmpty || value !== '')) { var valueType = Object.prototype.toString.apply(value); if (typeof value === 'string') { value = applyReplacement(value, options); value = applyReuse(value, options); } else if (valueType === '[object Array]' && !o.returnObjectTrees && !options.returnObjectTrees) { value = value.join('\n'); value = applyReplacement(value, options); value = applyReuse(value, options); } else if (value === null && o.fallbackOnNull === true) { value = undefined; } else if (value !== null) { if (!o.returnObjectTrees && !options.returnObjectTrees) { if (o.objectTreeKeyHandler && typeof o.objectTreeKeyHandler == 'function') { value = o.objectTreeKeyHandler(key, value, l, ns, options); } else { value = 'key \'' + ns + ':' + key + ' (' + l + ')\' ' + 'returned an object instead of string.'; f.log(value); } } else if (valueType !== '[object Number]' && valueType !== '[object Function]' && valueType !== '[object RegExp]') { var copy = (valueType === '[object Array]') ? [] : {}; // apply child translation on a copy f.each(value, function(m) { copy[m] = _translate(ns + nsseparator + key + keyseparator + m, options); }); value = copy; } } if (typeof value === 'string' && value.trim() === '' && o.fallbackOnEmpty === true) value = undefined; found = value; } } if (found === undefined && !options.isFallbackLookup && (o.fallbackToDefaultNS === true || (o.fallbackNS && o.fallbackNS.length > 0))) { // set flag for fallback lookup - avoid recursion options.isFallbackLookup = true; if (o.fallbackNS.length) { for (var y = 0, lenY = o.fallbackNS.length; y < lenY; y++) { found = _find(o.fallbackNS[y] + nsseparator + key, options); if (found || (found==="" && o.fallbackOnEmpty === false)) { /* compare value without namespace */ var foundValue = found.indexOf(nsseparator) > -1 ? found.split(nsseparator)[1] : found , notFoundValue = notFound.indexOf(nsseparator) > -1 ? notFound.split(nsseparator)[1] : notFound; if (foundValue !== notFoundValue) break; } } } else { options.ns = o.ns.defaultNs; found = _find(key, options); // fallback to default NS } options.isFallbackLookup = false; } return found; } function detectLanguage() { var detectedLng; var whitelist = o.lngWhitelist || []; var userLngChoices = []; // get from qs var qsParm = []; if (typeof window !== 'undefined') { (function() { var query = window.location.search.substring(1); var params = query.split('&'); for (var i=0; i 0) { var key = params[i].substring(0,pos); if (key == o.detectLngQS) { userLngChoices.push(params[i].substring(pos+1)); } } } })(); } // get from cookie if (o.useCookie && typeof document !== 'undefined') { var c = f.cookie.read(o.cookieName); if (c) userLngChoices.push(c); } // get from localStorage if (o.detectLngFromLocalStorage && typeof window !== 'undefined' && window.localStorage) { var lang = f.localStorage.getItem('i18next_lng'); if (lang) { userLngChoices.push(lang); } } // get from navigator if (typeof navigator !== 'undefined') { if (navigator.languages) { // chrome only; not an array, so can't use .push.apply instead of iterating for (var i=0;i -1) { var parts = lng.split('-'); lng = o.lowerCaseLng ? parts[0].toLowerCase() + '-' + parts[1].toLowerCase() : parts[0].toLowerCase() + '-' + parts[1].toUpperCase(); } if (whitelist.length === 0 || whitelist.indexOf(lng) > -1) { detectedLng = lng; break; } } })(); //fallback if (!detectedLng){ detectedLng = o.fallbackLng[0]; } return detectedLng; } // definition http://translate.sourceforge.net/wiki/l10n/pluralforms /* [code, name, numbers, pluralsType] */ var _rules = [ ["ach", "Acholi", [1,2], 1], ["af", "Afrikaans",[1,2], 2], ["ak", "Akan", [1,2], 1], ["am", "Amharic", [1,2], 1], ["an", "Aragonese",[1,2], 2], ["ar", "Arabic", [0,1,2,3,11,100],5], ["arn", "Mapudungun",[1,2], 1], ["ast", "Asturian", [1,2], 2], ["ay", "Aymará", [1], 3], ["az", "Azerbaijani",[1,2],2], ["be", "Belarusian",[1,2,5],4], ["bg", "Bulgarian",[1,2], 2], ["bn", "Bengali", [1,2], 2], ["bo", "Tibetan", [1], 3], ["br", "Breton", [1,2], 1], ["bs", "Bosnian", [1,2,5],4], ["ca", "Catalan", [1,2], 2], ["cgg", "Chiga", [1], 3], ["cs", "Czech", [1,2,5],6], ["csb", "Kashubian",[1,2,5],7], ["cy", "Welsh", [1,2,3,8],8], ["da", "Danish", [1,2], 2], ["de", "German", [1,2], 2], ["dev", "Development Fallback", [1,2], 2], ["dz", "Dzongkha", [1], 3], ["el", "Greek", [1,2], 2], ["en", "English", [1,2], 2], ["eo", "Esperanto",[1,2], 2], ["es", "Spanish", [1,2], 2], ["es_ar","Argentinean Spanish", [1,2], 2], ["et", "Estonian", [1,2], 2], ["eu", "Basque", [1,2], 2], ["fa", "Persian", [1], 3], ["fi", "Finnish", [1,2], 2], ["fil", "Filipino", [1,2], 1], ["fo", "Faroese", [1,2], 2], ["fr", "French", [1,2], 9], ["fur", "Friulian", [1,2], 2], ["fy", "Frisian", [1,2], 2], ["ga", "Irish", [1,2,3,7,11],10], ["gd", "Scottish Gaelic",[1,2,3,20],11], ["gl", "Galician", [1,2], 2], ["gu", "Gujarati", [1,2], 2], ["gun", "Gun", [1,2], 1], ["ha", "Hausa", [1,2], 2], ["he", "Hebrew", [1,2], 2], ["hi", "Hindi", [1,2], 2], ["hr", "Croatian", [1,2,5],4], ["hu", "Hungarian",[1,2], 2], ["hy", "Armenian", [1,2], 2], ["ia", "Interlingua",[1,2],2], ["id", "Indonesian",[1], 3], ["is", "Icelandic",[1,2], 12], ["it", "Italian", [1,2], 2], ["ja", "Japanese", [1], 3], ["jbo", "Lojban", [1], 3], ["jv", "Javanese", [0,1], 13], ["ka", "Georgian", [1], 3], ["kk", "Kazakh", [1], 3], ["km", "Khmer", [1], 3], ["kn", "Kannada", [1,2], 2], ["ko", "Korean", [1], 3], ["ku", "Kurdish", [1,2], 2], ["kw", "Cornish", [1,2,3,4],14], ["ky", "Kyrgyz", [1], 3], ["lb", "Letzeburgesch",[1,2],2], ["ln", "Lingala", [1,2], 1], ["lo", "Lao", [1], 3], ["lt", "Lithuanian",[1,2,10],15], ["lv", "Latvian", [1,2,0],16], ["mai", "Maithili", [1,2], 2], ["mfe", "Mauritian Creole",[1,2],1], ["mg", "Malagasy", [1,2], 1], ["mi", "Maori", [1,2], 1], ["mk", "Macedonian",[1,2],17], ["ml", "Malayalam",[1,2], 2], ["mn", "Mongolian",[1,2], 2], ["mnk", "Mandinka", [0,1,2],18], ["mr", "Marathi", [1,2], 2], ["ms", "Malay", [1], 3], ["mt", "Maltese", [1,2,11,20],19], ["nah", "Nahuatl", [1,2], 2], ["nap", "Neapolitan",[1,2], 2], ["nb", "Norwegian Bokmal",[1,2],2], ["ne", "Nepali", [1,2], 2], ["nl", "Dutch", [1,2], 2], ["nn", "Norwegian Nynorsk",[1,2],2], ["no", "Norwegian",[1,2], 2], ["nso", "Northern Sotho",[1,2],2], ["oc", "Occitan", [1,2], 1], ["or", "Oriya", [2,1], 2], ["pa", "Punjabi", [1,2], 2], ["pap", "Papiamento",[1,2], 2], ["pl", "Polish", [1,2,5],7], ["pms", "Piemontese",[1,2], 2], ["ps", "Pashto", [1,2], 2], ["pt", "Portuguese",[1,2], 2], ["pt_br","Brazilian Portuguese",[1,2], 2], ["rm", "Romansh", [1,2], 2], ["ro", "Romanian", [1,2,20],20], ["ru", "Russian", [1,2,5],4], ["sah", "Yakut", [1], 3], ["sco", "Scots", [1,2], 2], ["se", "Northern Sami",[1,2], 2], ["si", "Sinhala", [1,2], 2], ["sk", "Slovak", [1,2,5],6], ["sl", "Slovenian",[5,1,2,3],21], ["so", "Somali", [1,2], 2], ["son", "Songhay", [1,2], 2], ["sq", "Albanian", [1,2], 2], ["sr", "Serbian", [1,2,5],4], ["su", "Sundanese",[1], 3], ["sv", "Swedish", [1,2], 2], ["sw", "Swahili", [1,2], 2], ["ta", "Tamil", [1,2], 2], ["te", "Telugu", [1,2], 2], ["tg", "Tajik", [1,2], 1], ["th", "Thai", [1], 3], ["ti", "Tigrinya", [1,2], 1], ["tk", "Turkmen", [1,2], 2], ["tr", "Turkish", [1,2], 1], ["tt", "Tatar", [1], 3], ["ug", "Uyghur", [1], 3], ["uk", "Ukrainian",[1,2,5],4], ["ur", "Urdu", [1,2], 2], ["uz", "Uzbek", [1,2], 1], ["vi", "Vietnamese",[1], 3], ["wa", "Walloon", [1,2], 1], ["wo", "Wolof", [1], 3], ["yo", "Yoruba", [1,2], 2], ["zh", "Chinese", [1], 3] ]; var _rulesPluralsTypes = { 1: function(n) {return Number(n > 1);}, 2: function(n) {return Number(n != 1);}, 3: function(n) {return 0;}, 4: function(n) {return Number(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);}, 5: function(n) {return Number(n===0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5);}, 6: function(n) {return Number((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2);}, 7: function(n) {return Number(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);}, 8: function(n) {return Number((n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3);}, 9: function(n) {return Number(n >= 2);}, 10: function(n) {return Number(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4) ;}, 11: function(n) {return Number((n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3);}, 12: function(n) {return Number(n%10!=1 || n%100==11);}, 13: function(n) {return Number(n !== 0);}, 14: function(n) {return Number((n==1) ? 0 : (n==2) ? 1 : (n == 3) ? 2 : 3);}, 15: function(n) {return Number(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);}, 16: function(n) {return Number(n%10==1 && n%100!=11 ? 0 : n !== 0 ? 1 : 2);}, 17: function(n) {return Number(n==1 || n%10==1 ? 0 : 1);}, 18: function(n) {return Number(n==0 ? 0 : n==1 ? 1 : 2);}, 19: function(n) {return Number(n==1 ? 0 : n===0 || ( n%100>1 && n%100<11) ? 1 : (n%100>10 && n%100<20 ) ? 2 : 3);}, 20: function(n) {return Number(n==1 ? 0 : (n===0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2);}, 21: function(n) {return Number(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n%100==4 ? 3 : 0); } }; var pluralExtensions = { rules: (function () { var l, rules = {}; for (l=_rules.length; l-- ;) { rules[_rules[l][0]] = { name: _rules[l][1], numbers: _rules[l][2], plurals: _rulesPluralsTypes[_rules[l][3]] } } return rules; }()), // you can add your own pluralExtensions addRule: function(lng, obj) { pluralExtensions.rules[lng] = obj; }, setCurrentLng: function(lng) { if (!pluralExtensions.currentRule || pluralExtensions.currentRule.lng !== lng) { var parts = lng.split('-'); pluralExtensions.currentRule = { lng: lng, rule: pluralExtensions.rules[parts[0]] }; } }, needsPlural: function(lng, count) { var parts = lng.split('-'); var ext; if (pluralExtensions.currentRule && pluralExtensions.currentRule.lng === lng) { ext = pluralExtensions.currentRule.rule; } else { ext = pluralExtensions.rules[parts[f.getCountyIndexOfLng(lng)]]; } if (ext && ext.numbers.length <= 1) { return false; } else { return this.get(lng, count) !== 1; } }, get: function(lng, count) { var parts = lng.split('-'); function getResult(l, c) { var ext; if (pluralExtensions.currentRule && pluralExtensions.currentRule.lng === lng) { ext = pluralExtensions.currentRule.rule; } else { ext = pluralExtensions.rules[l]; } if (ext) { var i; if (ext.noAbs) { i = ext.plurals(c); } else { i = ext.plurals(Math.abs(c)); } var number = ext.numbers[i]; if (ext.numbers.length === 2 && ext.numbers[0] === 1) { if (number === 2) { number = -1; // regular plural } else if (number === 1) { number = 1; // singular } }//console.log(count + '-' + number); return number; } else { return c === 1 ? '1' : '-1'; } } return getResult(parts[f.getCountyIndexOfLng(lng)], count); } }; var postProcessors = {}; var addPostProcessor = function(name, fc) { postProcessors[name] = fc; }; // sprintf support var sprintf = (function() { function get_type(variable) { return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); } function str_repeat(input, multiplier) { for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */} return output.join(''); } var str_format = function() { if (!str_format.cache.hasOwnProperty(arguments[0])) { str_format.cache[arguments[0]] = str_format.parse(arguments[0]); } return str_format.format.call(null, str_format.cache[arguments[0]], arguments); }; str_format.format = function(parse_tree, argv) { var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; for (i = 0; i < tree_length; i++) { node_type = get_type(parse_tree[i]); if (node_type === 'string') { output.push(parse_tree[i]); } else if (node_type === 'array') { match = parse_tree[i]; // convenience purposes only if (match[2]) { // keyword argument arg = argv[cursor]; for (k = 0; k < match[2].length; k++) { if (!arg.hasOwnProperty(match[2][k])) { throw(sprintf('[sprintf] property "%s" does not exist', match[2][k])); } arg = arg[match[2][k]]; } } else if (match[1]) { // positional argument (explicit) arg = argv[match[1]]; } else { // positional argument (implicit) arg = argv[cursor++]; } if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { throw(sprintf('[sprintf] expecting number but found %s', get_type(arg))); } switch (match[8]) { case 'b': arg = arg.toString(2); break; case 'c': arg = String.fromCharCode(arg); break; case 'd': arg = parseInt(arg, 10); break; case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; case 'o': arg = arg.toString(8); break; case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; case 'u': arg = Math.abs(arg); break; case 'x': arg = arg.toString(16); break; case 'X': arg = arg.toString(16).toUpperCase(); break; } arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; pad_length = match[6] - String(arg).length; pad = match[6] ? str_repeat(pad_character, pad_length) : ''; output.push(match[5] ? arg + pad : pad + arg); } } return output.join(''); }; str_format.cache = {}; str_format.parse = function(fmt) { var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; while (_fmt) { if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { parse_tree.push(match[0]); } else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { parse_tree.push('%'); } else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { if (match[2]) { arg_names |= 1; var field_list = [], replacement_field = match[2], field_match = []; if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { field_list.push(field_match[1]); while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { field_list.push(field_match[1]); } else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { field_list.push(field_match[1]); } else { throw('[sprintf] huh?'); } } } else { throw('[sprintf] huh?'); } match[2] = field_list; } else { arg_names |= 2; } if (arg_names === 3) { throw('[sprintf] mixing positional and named placeholders is not (yet) supported'); } parse_tree.push(match); } else { throw('[sprintf] huh?'); } _fmt = _fmt.substring(match[0].length); } return parse_tree; }; return str_format; })(); var vsprintf = function(fmt, argv) { argv.unshift(fmt); return sprintf.apply(null, argv); }; addPostProcessor("sprintf", function(val, key, opts) { if (!opts.sprintf) return val; if (Object.prototype.toString.apply(opts.sprintf) === '[object Array]') { return vsprintf(val, opts.sprintf); } else if (typeof opts.sprintf === 'object') { return sprintf(val, opts.sprintf); } return val; }); // public api interface i18n.init = init; i18n.isInitialized = isInitialized; i18n.setLng = setLng; i18n.preload = preload; i18n.addResourceBundle = addResourceBundle; i18n.hasResourceBundle = hasResourceBundle; i18n.getResourceBundle = getResourceBundle; i18n.addResource = addResource; i18n.addResources = addResources; i18n.removeResourceBundle = removeResourceBundle; i18n.loadNamespace = loadNamespace; i18n.loadNamespaces = loadNamespaces; i18n.setDefaultNamespace = setDefaultNamespace; i18n.t = translate; i18n.translate = translate; i18n.exists = exists; i18n.detectLanguage = f.detectLanguage; i18n.pluralExtensions = pluralExtensions; i18n.sync = sync; i18n.functions = f; i18n.lng = lng; i18n.dir = dir; i18n.addPostProcessor = addPostProcessor; i18n.applyReplacement = f.applyReplacement; i18n.options = o; i18n.noConflict = noConflict; })(typeof exports === 'undefined' ? window : exports);