From 58d0d426755503375cfbf7203461352536b9ceb7 Mon Sep 17 00:00:00 2001 From: Davide Alberani Date: Sat, 16 May 2015 13:09:11 +0200 Subject: [PATCH] update angular-translate to version 2.7.0 and add angular-translate-loader-static-files --- ...gular-translate-loader-static-files.min.js | 6 + static/js/angular-translate.js | 702 +++++++++++++++--- static/js/angular-translate.min.js | 4 +- 3 files changed, 596 insertions(+), 116 deletions(-) create mode 100644 static/js/angular-translate-loader-static-files.min.js diff --git a/static/js/angular-translate-loader-static-files.min.js b/static/js/angular-translate-loader-static-files.min.js new file mode 100644 index 0000000..3c50ac2 --- /dev/null +++ b/static/js/angular-translate-loader-static-files.min.js @@ -0,0 +1,6 @@ +/*! + * angular-translate - v2.7.0 - 2015-05-02 + * http://github.com/angular-translate/angular-translate + * Copyright (c) 2015 ; Licensed MIT + */ +!function(a,b){"function"==typeof define&&define.amd?define([],function(){return b()}):"object"==typeof exports?module.exports=b():b()}(this,function(){function a(a,b){"use strict";return function(c){if(!(c&&(angular.isArray(c.files)||angular.isString(c.prefix)&&angular.isString(c.suffix))))throw new Error("Couldn't load static files, no files and prefix or suffix specified!");c.files||(c.files=[{prefix:c.prefix,suffix:c.suffix}]);for(var d=function(d){if(!d||!angular.isString(d.prefix)||!angular.isString(d.suffix))throw new Error("Couldn't load static file, no prefix or suffix specified!");var e=a.defer();return b(angular.extend({url:[d.prefix,c.key,d.suffix].join(""),method:"GET",params:""},c.$http)).success(function(a){e.resolve(a)}).error(function(){e.reject(c.key)}),e.promise},e=a.defer(),f=[],g=c.files.length,h=0;g>h;h++)f.push(d({prefix:c.files[h].prefix,key:c.key,suffix:c.files[h].suffix}));return a.all(f).then(function(a){for(var b=a.length,c={},d=0;b>d;d++)for(var f in a[d])c[f]=a[d][f];e.resolve(c)},function(a){e.reject(a)}),e.promise}}return angular.module("pascalprecht.translate").factory("$translateStaticFilesLoader",a),a.$inject=["$q","$http"],a.displayName="$translateStaticFilesLoader","pascalprecht.translate"}); \ No newline at end of file diff --git a/static/js/angular-translate.js b/static/js/angular-translate.js index 438cce3..a0ce7ba 100644 --- a/static/js/angular-translate.js +++ b/static/js/angular-translate.js @@ -1,8 +1,24 @@ /*! - * angular-translate - v2.6.1 - 2015-03-01 + * angular-translate - v2.7.0 - 2015-05-02 * http://github.com/angular-translate/angular-translate * Copyright (c) 2015 ; Licensed MIT */ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module unless amdModuleId is set + define([], function () { + return (factory()); + }); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + factory(); + } +}(this, function () { + /** * @ngdoc overview * @name pascalprecht.translate @@ -11,13 +27,16 @@ * The main module which holds everything together. */ angular.module('pascalprecht.translate', ['ng']) + .run(runTranslate); -.run(['$translate', function ($translate) { +function runTranslate($translate) { + + 'use strict'; var key = $translate.storageKey(), - storage = $translate.storage(); + storage = $translate.storage(); - var fallbackFromIncorrectStorageValue = function() { + var fallbackFromIncorrectStorageValue = function () { var preferred = $translate.preferredLanguage(); if (angular.isString(preferred)) { $translate.use(preferred); @@ -28,6 +47,8 @@ angular.module('pascalprecht.translate', ['ng']) } }; + fallbackFromIncorrectStorageValue.displayName = 'fallbackFromIncorrectStorageValue'; + if (storage) { if (!storage.get(key)) { fallbackFromIncorrectStorageValue(); @@ -37,7 +58,254 @@ angular.module('pascalprecht.translate', ['ng']) } else if (angular.isString($translate.preferredLanguage())) { $translate.use($translate.preferredLanguage()); } -}]); +} +runTranslate.$inject = ['$translate']; + +runTranslate.displayName = 'runTranslate'; + +/** + * @ngdoc object + * @name pascalprecht.translate.$translateSanitizationProvider + * + * @description + * + * Configurations for $translateSanitization + */ +angular.module('pascalprecht.translate').provider('$translateSanitization', $translateSanitizationProvider); + +function $translateSanitizationProvider () { + + 'use strict'; + + var $sanitize, + currentStrategy = null, // TODO change to either 'sanitize', 'escape' or ['sanitize', 'escapeParameters'] in 3.0. + hasConfiguredStrategy = false, + hasShownNoStrategyConfiguredWarning = false, + strategies; + + /** + * Definition of a sanitization strategy function + * @callback StrategyFunction + * @param {string|object} value - value to be sanitized (either a string or an interpolated value map) + * @param {string} mode - either 'text' for a string (translation) or 'params' for the interpolated params + * @return {string|object} + */ + + /** + * @ngdoc property + * @name strategies + * @propertyOf pascalprecht.translate.$translateSanitizationProvider + * + * @description + * Following strategies are built-in: + *
+ *
sanitize
+ *
Sanitizes HTML in the translation text using $sanitize
+ *
escape
+ *
Escapes HTML in the translation
+ *
sanitizeParameters
+ *
Sanitizes HTML in the values of the interpolation parameters using $sanitize
+ *
escapeParameters
+ *
Escapes HTML in the values of the interpolation parameters
+ *
escaped
+ *
Support legacy strategy name 'escaped' for backwards compatibility (will be removed in 3.0)
+ *
+ * + */ + + strategies = { + sanitize: function (value, mode) { + if (mode === 'text') { + value = htmlSanitizeValue(value); + } + return value; + }, + escape: function (value, mode) { + if (mode === 'text') { + value = htmlEscapeValue(value); + } + return value; + }, + sanitizeParameters: function (value, mode) { + if (mode === 'params') { + value = mapInterpolationParameters(value, htmlSanitizeValue); + } + return value; + }, + escapeParameters: function (value, mode) { + if (mode === 'params') { + value = mapInterpolationParameters(value, htmlEscapeValue); + } + return value; + } + }; + // Support legacy strategy name 'escaped' for backwards compatibility. + // TODO should be removed in 3.0 + strategies.escaped = strategies.escapeParameters; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateSanitizationProvider#addStrategy + * @methodOf pascalprecht.translate.$translateSanitizationProvider + * + * @description + * Adds a sanitization strategy to the list of known strategies. + * + * @param {string} strategyName - unique key for a strategy + * @param {StrategyFunction} strategyFunction - strategy function + * @returns {object} this + */ + this.addStrategy = function (strategyName, strategyFunction) { + strategies[strategyName] = strategyFunction; + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateSanitizationProvider#removeStrategy + * @methodOf pascalprecht.translate.$translateSanitizationProvider + * + * @description + * Removes a sanitization strategy from the list of known strategies. + * + * @param {string} strategyName - unique key for a strategy + * @returns {object} this + */ + this.removeStrategy = function (strategyName) { + delete strategies[strategyName]; + return this; + }; + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateSanitizationProvider#useStrategy + * @methodOf pascalprecht.translate.$translateSanitizationProvider + * + * @description + * Selects a sanitization strategy. When an array is provided the strategies will be executed in order. + * + * @param {string|StrategyFunction|array} strategy The sanitization strategy / strategies which should be used. Either a name of an existing strategy, a custom strategy function, or an array consisting of multiple names and / or custom functions. + * @returns {object} this + */ + this.useStrategy = function (strategy) { + hasConfiguredStrategy = true; + currentStrategy = strategy; + return this; + }; + + /** + * @ngdoc object + * @name pascalprecht.translate.$translateSanitization + * @requires $injector + * @requires $log + * + * @description + * Sanitizes interpolation parameters and translated texts. + * + */ + this.$get = ['$injector', '$log', function ($injector, $log) { + + var applyStrategies = function (value, mode, selectedStrategies) { + angular.forEach(selectedStrategies, function (selectedStrategy) { + if (angular.isFunction(selectedStrategy)) { + value = selectedStrategy(value, mode); + } else if (angular.isFunction(strategies[selectedStrategy])) { + value = strategies[selectedStrategy](value, mode); + } else { + throw new Error('pascalprecht.translate.$translateSanitization: Unknown sanitization strategy: \'' + selectedStrategy + '\''); + } + }); + return value; + }; + + // TODO: should be removed in 3.0 + var showNoStrategyConfiguredWarning = function () { + if (!hasConfiguredStrategy && !hasShownNoStrategyConfiguredWarning) { + $log.warn('pascalprecht.translate.$translateSanitization: No sanitization strategy has been configured. This can have serious security implications. See http://angular-translate.github.io/docs/#/guide/19_security for details.'); + hasShownNoStrategyConfiguredWarning = true; + } + }; + + if ($injector.has('$sanitize')) { + $sanitize = $injector.get('$sanitize'); + } + + return { + /** + * @ngdoc function + * @name pascalprecht.translate.$translateSanitization#useStrategy + * @methodOf pascalprecht.translate.$translateSanitization + * + * @description + * Selects a sanitization strategy. When an array is provided the strategies will be executed in order. + * + * @param {string|StrategyFunction|array} strategy The sanitization strategy / strategies which should be used. Either a name of an existing strategy, a custom strategy function, or an array consisting of multiple names and / or custom functions. + */ + useStrategy: (function (self) { + return function (strategy) { + self.useStrategy(strategy); + }; + })(this), + + /** + * @ngdoc function + * @name pascalprecht.translate.$translateSanitization#sanitize + * @methodOf pascalprecht.translate.$translateSanitization + * + * @description + * Sanitizes a value. + * + * @param {string|object} value The value which should be sanitized. + * @param {string} mode The current sanitization mode, either 'params' or 'text'. + * @param {string|StrategyFunction|array} [strategy] Optional custom strategy which should be used instead of the currently selected strategy. + * @returns {string|object} sanitized value + */ + sanitize: function (value, mode, strategy) { + if (!currentStrategy) { + showNoStrategyConfiguredWarning(); + } + + if (arguments.length < 3) { + strategy = currentStrategy; + } + + if (!strategy) { + return value; + } + + var selectedStrategies = angular.isArray(strategy) ? strategy : [strategy]; + return applyStrategies(value, mode, selectedStrategies); + } + }; + }]; + + var htmlEscapeValue = function (value) { + return angular.element('
').text(value).html(); + }; + + var htmlSanitizeValue = function (value) { + if (!$sanitize) { + throw new Error('pascalprecht.translate.$translateSanitization: Error cannot find $sanitize service. Either include the ngSanitize module (https://docs.angularjs.org/api/ngSanitize) or use a sanitization strategy which does not depend on $sanitize, such as \'escape\'.'); + } + return $sanitize(value); + }; + + var mapInterpolationParameters = function (value, iteratee) { + if (angular.isObject(value)) { + var result = angular.isArray(value) ? [] : {}; + + angular.forEach(value, function (propertyValue, propertyKey) { + result[propertyKey] = mapInterpolationParameters(propertyValue, iteratee); + }); + + return result; + } else if (angular.isNumber(value)) { + return value; + } else { + return iteratee(value); + } + }; +} /** * @ngdoc object @@ -48,7 +316,13 @@ angular.module('pascalprecht.translate', ['ng']) * and similar to configure translation behavior directly inside of a module. * */ -angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', '$windowProvider', function ($STORAGE_KEY, $windowProvider) { +angular.module('pascalprecht.translate') +.constant('pascalprechtTranslateOverrider', {}) +.provider('$translate', $translate); + +function $translate($STORAGE_KEY, $windowProvider, $translateSanitizationProvider, pascalprechtTranslateOverrider) { + + 'use strict'; var $translationTable = {}, $preferredLanguage, @@ -64,7 +338,6 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', $missingTranslationHandlerFactory, $interpolationFactory, $interpolatorFactories = [], - $interpolationSanitizationStrategy = false, $loaderFactory, $cloakClassName = 'translate-cloak', $loaderOptions, @@ -73,12 +346,35 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', $postCompilingEnabled = false, NESTED_OBJECT_DELIMITER = '.', loaderCache, - directivePriority = 0; + directivePriority = 0, + statefulFilter = true, + uniformLanguageTagResolver = 'default', + languageTagResolver = { + 'default': function (tag) { + return (tag || '').split('-').join('_'); + }, + java: function (tag) { + var temp = (tag || '').split('-').join('_'); + var parts = temp.split('_'); + return parts.length > 1 ? (parts[0].toLowerCase() + '_' + parts[1].toUpperCase()) : temp; + }, + bcp47: function (tag) { + var temp = (tag || '').split('_').join('-'); + var parts = temp.split('-'); + return parts.length > 1 ? (parts[0].toLowerCase() + '-' + parts[1].toUpperCase()) : temp; + } + }; - var version = '2.6.1'; + var version = '2.7.0'; // tries to determine the browsers language var getFirstBrowserLanguage = function () { + + // internal purpose only + if (angular.isFunction(pascalprechtTranslateOverrider.getLocale)) { + return pascalprechtTranslateOverrider.getLocale(); + } + var nav = $windowProvider.$get().navigator, browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'], i, @@ -108,7 +404,11 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', // tries to determine the browsers locale var getLocale = function () { - return (getFirstBrowserLanguage() || '').split('-').join('_'); + var locale = getFirstBrowserLanguage() || ''; + if (languageTagResolver[uniformLanguageTagResolver]) { + locale = languageTagResolver[uniformLanguageTagResolver](locale); + } + return locale; }; getLocale.displayName = 'angular-translate/service: getLocale'; @@ -180,10 +480,12 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', } } - var parts = preferred.split('_'); + if (preferred) { + var parts = preferred.split('_'); - if (parts.length > 1 && indexOf(avail, angular.lowercase(parts[0])) > -1) { - return parts[0]; + if (parts.length > 1 && indexOf(avail, angular.lowercase(parts[0])) > -1) { + return parts[0]; + } } // If everything fails, just return the preferred, unchanged. @@ -304,6 +606,7 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', } return result; }; + flatObject.displayName = 'flatObject'; /** * @ngdoc function @@ -361,7 +664,7 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', * @param {string} value Strategy type. */ this.useSanitizeValueStrategy = function (value) { - $interpolationSanitizationStrategy = value; + $translateSanitizationProvider.useStrategy(value); return this; }; @@ -511,7 +814,7 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', if (langKey) { if (!$translationTable[langKey] && (!$loaderFactory)) { // only throw an error, when not loading translation data asynchronously - throw new Error("$translateProvider couldn't find translationTable for langKey: '" + langKey + "'"); + throw new Error('$translateProvider couldn\'t find translationTable for langKey: \'' + langKey + '\''); } $uses = langKey; return this; @@ -713,6 +1016,62 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', return this; }; + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#uniformLanguageTag + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Tells angular-translate which language tag should be used as a result when determining + * the current browser language. + * + * This setting must be set before invoking {@link pascalprecht.translate.$translateProvider#methods_determinePreferredLanguage determinePreferredLanguage()}. + * + *
+   * $translateProvider
+   *   .uniformLanguageTag('bcp47')
+   *   .determinePreferredLanguage()
+   * 
+ * + * The resolver currently supports: + * * default + * (traditionally: hyphens will be converted into underscores, i.e. en-US => en_US) + * en-US => en_US + * en_US => en_US + * en-us => en_us + * * java + * like default, but the second part will be always in uppercase + * en-US => en_US + * en_US => en_US + * en-us => en_US + * * BCP 47 (RFC 4646 & 4647) + * en-US => en-US + * en_US => en-US + * en-us => en-US + * + * See also: + * * http://en.wikipedia.org/wiki/IETF_language_tag + * * http://www.w3.org/International/core/langtags/ + * * http://tools.ietf.org/html/bcp47 + * + * @param {string|object} options - options (or standard) + * @param {string} options.standard - valid values are 'default', 'bcp47', 'java' + */ + this.uniformLanguageTag = function (options) { + + if (!options) { + options = {}; + } else if (angular.isString(options)) { + options = { + standard: options + }; + } + + uniformLanguageTagResolver = options.standard; + + return this; + }; + /** * @ngdoc function * @name pascalprecht.translate.$translateProvider#determinePreferredLanguage @@ -728,9 +1087,9 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', * `[lang]` depending on what the browser provides. * * Use this method at your own risk, since not all browsers return a valid - * locale. + * locale (see {@link pascalprecht.translate.$translateProvider#methods_uniformLanguageTag uniformLanguageTag()}). * - * @param {object=} fn Function to determine a browser's locale + * @param {Function=} fn Function to determine a browser's locale */ this.determinePreferredLanguage = function (fn) { @@ -825,6 +1184,31 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', } }; + /** + * @ngdoc function + * @name pascalprecht.translate.$translateProvider#statefulFilter + * @methodOf pascalprecht.translate.$translateProvider + * + * @description + * Since AngularJS 1.3, filters which are not stateless (depending at the scope) + * have to explicit define this behavior. + * Sets whether the translate filter should be stateful or stateless. The standard value is `true` + * meaning being stateful. + * Calling this function without an argument will return the current value. + * + * @param {boolean} state - defines the state of the filter + */ + this.statefulFilter = function (state) { + if (state === undefined) { + // getter + return statefulFilter; + } else { + // setter with chaining + statefulFilter = state; + return this; + } + }; + /** * @ngdoc object * @name pascalprecht.translate.$translate @@ -944,9 +1328,12 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', // We can just translate. determineTranslation(translationId, interpolateParams, interpolationId, defaultTranslationText).then(deferred.resolve, deferred.reject); } else { - promiseToWaitFor.then(function () { + var promiseResolved = function () { determineTranslation(translationId, interpolateParams, interpolationId, defaultTranslationText).then(deferred.resolve, deferred.reject); - }, deferred.reject); + }; + promiseResolved.displayName = 'promiseResolved'; + + promiseToWaitFor['finally'](promiseResolved, deferred.reject); } return deferred.promise; }; @@ -995,10 +1382,14 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', } // inform default interpolator defaultInterpolator.setLocale($uses); - // inform all others too! - angular.forEach(interpolatorHashMap, function (interpolator, id) { + + var eachInterpolator = function (interpolator, id) { interpolatorHashMap[id].setLocale($uses); - }); + }; + eachInterpolator.displayName = 'eachInterpolatorLocaleSetter'; + + // inform all others too! + angular.forEach(interpolatorHashMap, eachInterpolator); $rootScope.$emit('$translateChangeEnd', {language: key}); }; @@ -1037,7 +1428,7 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', }, $loaderOptions.$http) }); - $injector.get($loaderFactory)(loaderOptions).then(function (data) { + var onLoaderSuccess = function (data) { var translationTable = {}; $rootScope.$emit('$translateLoadingSuccess', {language: key}); @@ -1054,11 +1445,19 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', table: translationTable }); $rootScope.$emit('$translateLoadingEnd', {language: key}); - }, function (key) { + }; + onLoaderSuccess.displayName = 'onLoaderSuccess'; + + var onLoaderError = function (key) { $rootScope.$emit('$translateLoadingError', {language: key}); deferred.reject(key); $rootScope.$emit('$translateLoadingEnd', {language: key}); - }); + }; + onLoaderError.displayName = 'onLoaderError'; + + $injector.get($loaderFactory)(loaderOptions) + .then(onLoaderSuccess, onLoaderError); + return deferred.promise; }; @@ -1070,25 +1469,19 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', } } - // apply additional settings - if (angular.isFunction(defaultInterpolator.useSanitizeValueStrategy)) { - defaultInterpolator.useSanitizeValueStrategy($interpolationSanitizationStrategy); - } - // if we have additional interpolations that were added via // $translateProvider.addInterpolation(), we have to map'em if ($interpolatorFactories.length) { - angular.forEach($interpolatorFactories, function (interpolatorFactory) { + var eachInterpolationFactory = function (interpolatorFactory) { var interpolator = $injector.get(interpolatorFactory); // setting initial locale for each interpolation service interpolator.setLocale($preferredLanguage || $uses); - // apply additional settings - if (angular.isFunction(interpolator.useSanitizeValueStrategy)) { - interpolator.useSanitizeValueStrategy($interpolationSanitizationStrategy); - } // make'em recognizable through id interpolatorHashMap[interpolator.getInterpolationIdentifier()] = interpolator; - }); + }; + eachInterpolationFactory.displayName = 'interpolationFactoryAdder'; + + angular.forEach($interpolatorFactories, eachInterpolationFactory); } /** @@ -1107,10 +1500,12 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', if (Object.prototype.hasOwnProperty.call($translationTable, langKey)) { deferred.resolve($translationTable[langKey]); } else if (langPromises[langKey]) { - langPromises[langKey].then(function (data) { + var onResolve = function (data) { translations(data.key, data.table); deferred.resolve(data.table); - }, deferred.reject); + }; + onResolve.displayName = 'translationTableResolver'; + langPromises[langKey].then(onResolve, deferred.reject); } else { deferred.reject(); } @@ -1135,7 +1530,7 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', var getFallbackTranslation = function (langKey, translationId, interpolateParams, Interpolator) { var deferred = $q.defer(); - getTranslationTable(langKey).then(function (translationTable) { + var onResolve = function (translationTable) { if (Object.prototype.hasOwnProperty.call(translationTable, translationId)) { Interpolator.setLocale(langKey); var translation = translationTable[translationId]; @@ -1149,7 +1544,10 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', } else { deferred.reject(); } - }, deferred.reject); + }; + onResolve.displayName = 'fallbackTranslationResolver'; + + getTranslationTable(langKey).then(onResolve, deferred.reject); return deferred.promise; }; @@ -1194,11 +1592,11 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', * @returns translation created by $missingTranslationHandler or translationId is $missingTranslationHandler is * absent */ - var translateByHandler = function (translationId) { + var translateByHandler = function (translationId, interpolateParams) { // If we have a handler factory - we might also call it here to determine if it provides // a default text for a translationid that can't be found anywhere in our tables if ($missingTranslationHandlerFactory) { - var resultString = $injector.get($missingTranslationHandlerFactory)(translationId, $uses); + var resultString = $injector.get($missingTranslationHandlerFactory)(translationId, $uses, interpolateParams); if (resultString !== undefined) { return resultString; } else { @@ -1243,7 +1641,7 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', } else { // if no default translation is set and an error handler is defined, send it to the handler // and then return the result - deferred.resolve(translateByHandler(translationId)); + deferred.resolve(translateByHandler(translationId, interpolateParams)); } } return deferred.promise; @@ -1324,7 +1722,7 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', var missingTranslationHandlerTranslation; // for logging purposes only (as in $translateMissingTranslationHandlerLog), value is not returned to promise if ($missingTranslationHandlerFactory && !pendingLoader) { - missingTranslationHandlerTranslation = translateByHandler(translationId); + missingTranslationHandlerTranslation = translateByHandler(translationId, interpolateParams); } // since we couldn't translate the inital requested translation id, @@ -1381,7 +1779,7 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', var missingTranslationHandlerTranslation; // for logging purposes only (as in $translateMissingTranslationHandlerLog), value is not returned to promise if ($missingTranslationHandlerFactory && !pendingLoader) { - missingTranslationHandlerTranslation = translateByHandler(translationId); + missingTranslationHandlerTranslation = translateByHandler(translationId, interpolateParams); } // since we couldn't translate the inital requested translation id, @@ -1403,6 +1801,13 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', return result; }; + var clearNextLangAndPromise = function(key) { + if ($nextLang === key) { + $nextLang = undefined; + } + langPromises[key] = undefined; + }; + /** * @ngdoc function * @name pascalprecht.translate.$translate#preferredLanguage @@ -1572,19 +1977,26 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', langPromises[key] = loadAsync(key).then(function (translation) { translations(translation.key, translation.table); deferred.resolve(translation.key); - useLanguage(translation.key); - if ($nextLang === key) { - $nextLang = undefined; - } return translation; }, function (key) { - if ($nextLang === key) { - $nextLang = undefined; - } $rootScope.$emit('$translateChangeError', {language: key}); deferred.reject(key); $rootScope.$emit('$translateChangeEnd', {language: key}); + return $q.reject(key); + }); + langPromises[key]['finally'](function () { + clearNextLangAndPromise(key); + }); + } else if ($nextLang === key && langPromises[key]) { + // we are already loading this asynchronously + // resolve our new deferred when the old langPromise is resolved + langPromises[key].then(function (translation) { + deferred.resolve(translation.key); + return translation; + }, function (key) { + deferred.reject(key); + return $q.reject(key); }); } else { deferred.resolve(key); @@ -1687,28 +2099,32 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', tables.push(loadAsync($uses)); } - $q.all(tables).then(function (tableData) { + var allTranslationsLoaded = function (tableData) { + $translationTable = {}; angular.forEach(tableData, function (data) { - if ($translationTable[data.key]) { - delete $translationTable[data.key]; - } translations(data.key, data.table); }); if ($uses) { useLanguage($uses); } resolve(); - }); + }; + allTranslationsLoaded.displayName = 'refreshPostProcessor'; + + $q.all(tables).then(allTranslationsLoaded); } else if ($translationTable[langKey]) { - loadAsync(langKey).then(function (data) { + var oneTranslationsLoaded = function (data) { translations(data.key, data.table); if (langKey === $uses) { useLanguage($uses); } resolve(); - }, reject); + }; + oneTranslationsLoaded.displayName = 'refreshPostProcessor'; + + loadAsync(langKey).then(oneTranslationsLoaded, reject); } else { reject(); @@ -1734,7 +2150,7 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', * @param {object} interpolateParams Params * @param {string} interpolationId The id of the interpolation to use * - * @return {string} translation + * @return {string|object} translation */ $translate.instant = function (translationId, interpolateParams, interpolationId) { @@ -1791,7 +2207,7 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', // Return translation of default interpolator if not found anything. result = defaultInterpolator.interpolate(translationId, interpolateParams); if ($missingTranslationHandlerFactory && !pendingLoader) { - result = translateByHandler(translationId); + result = translateByHandler(translationId, interpolateParams); } } @@ -1831,6 +2247,11 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', return directivePriority; }; + // internal purpose only + $translate.statefulFilter = function () { + return statefulFilter; + }; + if ($loaderFactory) { // If at least one async loader is defined and there are no @@ -1848,7 +2269,10 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', return translation; }; for (var i = 0, len = $fallbackLanguage.length; i < len; i++) { - langPromises[$fallbackLanguage[i]] = loadAsync($fallbackLanguage[i]).then(processAsyncResult); + var fallbackLanguageId = $fallbackLanguage[i]; + if (!$translationTable[fallbackLanguageId]) { + langPromises[fallbackLanguageId] = loadAsync(fallbackLanguageId).then(processAsyncResult); + } } } } @@ -1856,7 +2280,10 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', return $translate; } ]; -}]); +} +$translate.$inject = ['$STORAGE_KEY', '$windowProvider', '$translateSanitizationProvider', 'pascalprechtTranslateOverrider']; + +$translate.displayName = 'displayName'; /** * @ngdoc object @@ -1866,40 +2293,22 @@ angular.module('pascalprecht.translate').provider('$translate', ['$STORAGE_KEY', * @description * Uses angular's `$interpolate` services to interpolate strings against some values. * - * @return {object} $translateInterpolator Interpolator service + * Be aware to configure a proper sanitization strategy. + * + * See also: + * * {@link pascalprecht.translate.$translateSanitization} + * + * @return {object} $translateDefaultInterpolation Interpolator service */ -angular.module('pascalprecht.translate').factory('$translateDefaultInterpolation', ['$interpolate', function ($interpolate) { +angular.module('pascalprecht.translate').factory('$translateDefaultInterpolation', $translateDefaultInterpolation); + +function $translateDefaultInterpolation ($interpolate, $translateSanitization) { + + 'use strict'; var $translateInterpolator = {}, $locale, - $identifier = 'default', - $sanitizeValueStrategy = null, - // map of all sanitize strategies - sanitizeValueStrategies = { - escaped: function (params) { - var result = {}; - for (var key in params) { - if (Object.prototype.hasOwnProperty.call(params, key)) { - if (angular.isNumber(params[key])) { - result[key] = params[key]; - } else { - result[key] = angular.element('
').text(params[key]).html(); - } - } - } - return result; - } - }; - - var sanitizeParams = function (params) { - var result; - if (angular.isFunction(sanitizeValueStrategies[$sanitizeValueStrategy])) { - result = sanitizeValueStrategies[$sanitizeValueStrategy](params); - } else { - result = params; - } - return result; - }; + $identifier = 'default'; /** * @ngdoc function @@ -1929,8 +2338,12 @@ angular.module('pascalprecht.translate').factory('$translateDefaultInterpolation return $identifier; }; + /** + * @deprecated will be removed in 3.0 + * @see {@link pascalprecht.translate.$translateSanitization} + */ $translateInterpolator.useSanitizeValueStrategy = function (value) { - $sanitizeValueStrategy = value; + $translateSanitization.useStrategy(value); return this; }; @@ -1945,15 +2358,21 @@ angular.module('pascalprecht.translate').factory('$translateDefaultInterpolation * * @returns {string} interpolated string. */ - $translateInterpolator.interpolate = function (string, interpolateParams) { - if ($sanitizeValueStrategy) { - interpolateParams = sanitizeParams(interpolateParams); - } - return $interpolate(string)(interpolateParams || {}); + $translateInterpolator.interpolate = function (string, interpolationParams) { + interpolationParams = interpolationParams || {}; + interpolationParams = $translateSanitization.sanitize(interpolationParams, 'params'); + + var interpolatedText = $interpolate(string)(interpolationParams); + interpolatedText = $translateSanitization.sanitize(interpolatedText, 'text'); + + return interpolatedText; }; return $translateInterpolator; -}]); +} +$translateDefaultInterpolation.$inject = ['$interpolate', '$translateSanitization']; + +$translateDefaultInterpolation.displayName = '$translateDefaultInterpolation'; angular.module('pascalprecht.translate').constant('$STORAGE_KEY', 'NG_TRANSLATE_LANG_KEY'); @@ -1975,7 +2394,7 @@ angular.module('pascalprecht.translate') * @param {string=} translate-values Values to pass into translation id. Can be passed as object literal string or interpolated object. * @param {string=} translate-attr-ATTR translate Translation id and put it into ATTR attribute. * @param {string=} translate-default will be used unless translation was successful - * @param {boolean=} translate-compile (default true if present) defines locally activation of {@link pascalprecht.translate.$translate#usePostCompiling} + * @param {boolean=} translate-compile (default true if present) defines locally activation of {@link pascalprecht.translate.$translateProvider#methods_usePostCompiling} * * @example @@ -2044,7 +2463,10 @@ angular.module('pascalprecht.translate') */ -.directive('translate', ['$translate', '$q', '$interpolate', '$compile', '$parse', '$rootScope', function ($translate, $q, $interpolate, $compile, $parse, $rootScope) { +.directive('translate', translateDirective); +function translateDirective($translate, $q, $interpolate, $compile, $parse, $rootScope) { + + 'use strict'; /** * @name trim @@ -2083,6 +2505,22 @@ angular.module('pascalprecht.translate') scope.postText = ''; var translationIds = {}; + var initInterpolationParams = function (interpolateParams, iAttr, tAttr) { + // initial setup + if (iAttr.translateValues) { + angular.extend(interpolateParams, $parse(iAttr.translateValues)(scope.$parent)); + } + // initially fetch all attributes if existing and fill the params + if (translateValueExist) { + for (var attr in tAttr) { + if (Object.prototype.hasOwnProperty.call(iAttr, attr) && attr.substr(0, 14) === 'translateValue' && attr !== 'translateValues') { + var attributeName = angular.lowercase(attr.substr(14, 1)) + attr.substr(15); + interpolateParams[attributeName] = tAttr[attr]; + } + } + } + }; + // Ensures any change of the attribute "translate" containing the id will // be re-stored to the scope's "translationId". // If the attribute has no content, the element's text value (white spaces trimmed off) will be used. @@ -2125,6 +2563,9 @@ angular.module('pascalprecht.translate') }); }; + // initial setup with values + initInterpolationParams(scope.interpolateParams, iAttr, tAttr); + var firstAttributeChangedEvent = true; iAttr.$observe('translate', function (translationId) { if (typeof translationId === 'undefined') { @@ -2177,7 +2618,8 @@ angular.module('pascalprecht.translate') // Master update function var updateTranslations = function () { for (var key in translationIds) { - if (translationIds.hasOwnProperty(key)) { + + if (translationIds.hasOwnProperty(key) && translationIds[key] !== undefined) { updateTranslation(key, translationIds[key], scope, scope.interpolateParams, scope.defaultText); } } @@ -2216,12 +2658,19 @@ angular.module('pascalprecht.translate') if (!successful && typeof scope.defaultText !== 'undefined') { value = scope.defaultText; } - var attributeName = iAttr.$attr[translateAttr].substr(15); + var attributeName = iAttr.$attr[translateAttr]; + if (attributeName.substr(0, 5) === 'data-') { + // ensure html5 data prefix is stripped + attributeName = attributeName.substr(5); + } + attributeName = attributeName.substr(15); iElement.attr(attributeName, value); } }; - scope.$watch('interpolateParams', updateTranslations, true); + if (translateValuesExist || translateValueExist || iAttr.translateDefault) { + scope.$watch('interpolateParams', updateTranslations, true); + } // Ensures the text will be refreshed after the current language was changed // w/ $translate.use(...) @@ -2229,14 +2678,21 @@ angular.module('pascalprecht.translate') // ensure translation will be looked up at least one if (iElement.text().length) { - observeElementTranslation(''); + if (iAttr.translate) { + observeElementTranslation(iAttr.translate); + } else { + observeElementTranslation(''); + } } updateTranslations(); scope.$on('$destroy', unbind); }; } }; -}]); +} +translateDirective.$inject = ['$translate', '$q', '$interpolate', '$compile', '$parse', '$rootScope']; + +translateDirective.displayName = 'translateDirective'; angular.module('pascalprecht.translate') /** @@ -2260,7 +2716,11 @@ angular.module('pascalprecht.translate') * or hiding the cloak. Basically it relies on the translation * resolve. */ -.directive('translateCloak', ['$rootScope', '$translate', function ($rootScope, $translate) { +.directive('translateCloak', translateCloakDirective); + +function translateCloakDirective($rootScope, $translate) { + + 'use strict'; return { compile: function (tElement) { @@ -2287,7 +2747,10 @@ angular.module('pascalprecht.translate') }; } }; -}]); +} +translateCloakDirective.$inject = ['$rootScope', '$translate']; + +translateCloakDirective.displayName = 'translateCloakDirective'; angular.module('pascalprecht.translate') /** @@ -2341,7 +2804,12 @@ angular.module('pascalprecht.translate') */ -.filter('translate', ['$parse', '$translate', function ($parse, $translate) { +.filter('translate', translateFilterFactory); + +function translateFilterFactory($parse, $translate) { + + 'use strict'; + var translateFilter = function (translationId, interpolateParams, interpolation) { if (!angular.isObject(interpolateParams)) { @@ -2351,9 +2819,15 @@ angular.module('pascalprecht.translate') return $translate.instant(translationId, interpolateParams, interpolation); }; - // Since AngularJS 1.3, filters which are not stateless (depending at the scope) - // have to explicit define this behavior. - translateFilter.$stateful = true; + if ($translate.statefulFilter()) { + translateFilter.$stateful = true; + } return translateFilter; -}]); +} +translateFilterFactory.$inject = ['$parse', '$translate']; + +translateFilterFactory.displayName = 'translateFilterFactory'; +return 'pascalprecht.translate'; + +})); diff --git a/static/js/angular-translate.min.js b/static/js/angular-translate.min.js index cf4c127..f1104f5 100644 --- a/static/js/angular-translate.min.js +++ b/static/js/angular-translate.min.js @@ -1,6 +1,6 @@ /*! - * angular-translate - v2.6.1 - 2015-03-01 + * angular-translate - v2.7.0 - 2015-05-02 * http://github.com/angular-translate/angular-translate * Copyright (c) 2015 ; Licensed MIT */ -angular.module("pascalprecht.translate",["ng"]).run(["$translate",function(a){var b=a.storageKey(),c=a.storage(),d=function(){var d=a.preferredLanguage();angular.isString(d)?a.use(d):c.put(b,a.use())};c?c.get(b)?a.use(c.get(b))["catch"](d):d():angular.isString(a.preferredLanguage())&&a.use(a.preferredLanguage())}]),angular.module("pascalprecht.translate").provider("$translate",["$STORAGE_KEY","$windowProvider",function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r={},s=[],t=a,u=[],v=!1,w="translate-cloak",x=!1,y=".",z=0,A="2.6.1",B=function(){var a,c,d=b.$get().navigator,e=["language","browserLanguage","systemLanguage","userLanguage"];if(angular.isArray(d.languages))for(a=0;ac;c++)if(a[c]===b)return c;return-1},E=function(){return this.replace(/^\s+|\s+$/g,"")},F=function(a){for(var b=[],c=angular.lowercase(a),e=0,f=s.length;f>e;e++)b.push(angular.lowercase(s[e]));if(D(b,c)>-1)return a;if(d){var g;for(var h in d){var i=!1,j=Object.prototype.hasOwnProperty.call(d,h)&&angular.lowercase(h)===angular.lowercase(a);if("*"===h.slice(-1)&&(i=h.slice(0,-1)===a.slice(0,h.length-1)),(j||i)&&(g=d[h],D(b,angular.lowercase(g))>-1))return g}}var k=a.split("_");return k.length>1&&D(b,angular.lowercase(k[0]))>-1?k[0]:a},G=function(a,b){if(!a&&!b)return r;if(a&&!b){if(angular.isString(a))return r[a]}else angular.isObject(r[a])||(r[a]={}),angular.extend(r[a],H(b));return this};this.translations=G,this.cloakClassName=function(a){return a?(w=a,this):w};var H=function(a,b,c,d){var e,f,g,h;b||(b=[]),c||(c={});for(e in a)Object.prototype.hasOwnProperty.call(a,e)&&(h=a[e],angular.isObject(h)?H(h,b.concat(e),c,e):(f=b.length?""+b.join(y)+y+e:e,b.length&&e===d&&(g=""+b.join(y),c[g]="@:"+f),c[f]=h));return c};this.addInterpolation=function(a){return u.push(a),this},this.useMessageFormatInterpolation=function(){return this.useInterpolation("$translateMessageFormatInterpolation")},this.useInterpolation=function(a){return l=a,this},this.useSanitizeValueStrategy=function(a){return v=a,this},this.preferredLanguage=function(a){return I(a),this};var I=function(a){return a&&(c=a),c};this.translationNotFoundIndicator=function(a){return this.translationNotFoundIndicatorLeft(a),this.translationNotFoundIndicatorRight(a),this},this.translationNotFoundIndicatorLeft=function(a){return a?(o=a,this):o},this.translationNotFoundIndicatorRight=function(a){return a?(p=a,this):p},this.fallbackLanguage=function(a){return J(a),this};var J=function(a){return a?(angular.isString(a)?(f=!0,e=[a]):angular.isArray(a)&&(f=!1,e=a),angular.isString(c)&&D(e,c)<0&&e.push(c),this):f?e[0]:e};this.use=function(a){if(a){if(!r[a]&&!m)throw new Error("$translateProvider couldn't find translationTable for langKey: '"+a+"'");return g=a,this}return g};var K=function(a){return a?void(t=a):j?j+t:t};this.storageKey=K,this.useUrlLoader=function(a,b){return this.useLoader("$translateUrlLoader",angular.extend({url:a},b))},this.useStaticFilesLoader=function(a){return this.useLoader("$translateStaticFilesLoader",a)},this.useLoader=function(a,b){return m=a,n=b||{},this},this.useLocalStorage=function(){return this.useStorage("$translateLocalStorage")},this.useCookieStorage=function(){return this.useStorage("$translateCookieStorage")},this.useStorage=function(a){return i=a,this},this.storagePrefix=function(a){return a?(j=a,this):a},this.useMissingTranslationHandlerLog=function(){return this.useMissingTranslationHandler("$translateMissingTranslationHandlerLog")},this.useMissingTranslationHandler=function(a){return k=a,this},this.usePostCompiling=function(a){return x=!!a,this},this.determinePreferredLanguage=function(a){var b=a&&angular.isFunction(a)?a():C();return c=s.length?F(b):b,this},this.registerAvailableLanguageKeys=function(a,b){return a?(s=a,b&&(d=b),this):s},this.useLoaderCache=function(a){return a===!1?q=void 0:a===!0?q=!0:"undefined"==typeof a?q="$translationCache":a&&(q=a),this},this.directivePriority=function(a){return void 0===a?z:(z=a,this)},this.$get=["$log","$injector","$rootScope","$q",function(a,b,d,j){var s,y,B,C=b.get(l||"$translateDefaultInterpolation"),L=!1,M={},N={},O=function(a,b,d,f){if(angular.isArray(a)){var h=function(a){for(var c={},e=[],g=function(a){var e=j.defer(),g=function(b){c[a]=b,e.resolve([a,b])};return O(a,b,d,f).then(g,g),e.promise},h=0,i=a.length;i>h;h++)e.push(g(a[h]));return j.all(e).then(function(){return c})};return h(a)}var k=j.defer();a&&(a=E.apply(a));var l=function(){var a=c?N[c]:N[g];if(y=0,i&&!a){var b=s.get(t);if(a=N[b],e&&e.length){var d=D(e,b);y=0===d?1:0,D(e,c)<0&&e.push(c)}}return a}();return l?l.then(function(){$(a,b,d,f).then(k.resolve,k.reject)},k.reject):$(a,b,d,f).then(k.resolve,k.reject),k.promise},P=function(a){return o&&(a=[o,a].join(" ")),p&&(a=[a,p].join(" ")),a},Q=function(a){g=a,d.$emit("$translateChangeSuccess",{language:a}),i&&s.put(O.storageKey(),g),C.setLocale(g),angular.forEach(M,function(a,b){M[b].setLocale(g)}),d.$emit("$translateChangeEnd",{language:a})},R=function(a){if(!a)throw"No language key specified for loading.";var c=j.defer();d.$emit("$translateLoadingStart",{language:a}),L=!0;var e=q;"string"==typeof e&&(e=b.get(e));var f=angular.extend({},n,{key:a,$http:angular.extend({},{cache:e},n.$http)});return b.get(m)(f).then(function(b){var e={};d.$emit("$translateLoadingSuccess",{language:a}),angular.isArray(b)?angular.forEach(b,function(a){angular.extend(e,H(a))}):angular.extend(e,H(b)),L=!1,c.resolve({key:a,table:e}),d.$emit("$translateLoadingEnd",{language:a})},function(a){d.$emit("$translateLoadingError",{language:a}),c.reject(a),d.$emit("$translateLoadingEnd",{language:a})}),c.promise};if(i&&(s=b.get(i),!s.get||!s.put))throw new Error("Couldn't use storage '"+i+"', missing get() or put() method!");angular.isFunction(C.useSanitizeValueStrategy)&&C.useSanitizeValueStrategy(v),u.length&&angular.forEach(u,function(a){var d=b.get(a);d.setLocale(c||g),angular.isFunction(d.useSanitizeValueStrategy)&&d.useSanitizeValueStrategy(v),M[d.getInterpolationIdentifier()]=d});var S=function(a){var b=j.defer();return Object.prototype.hasOwnProperty.call(r,a)?b.resolve(r[a]):N[a]?N[a].then(function(a){G(a.key,a.table),b.resolve(a.table)},b.reject):b.reject(),b.promise},T=function(a,b,c,d){var e=j.defer();return S(a).then(function(f){if(Object.prototype.hasOwnProperty.call(f,b)){d.setLocale(a);var h=f[b];"@:"===h.substr(0,2)?T(a,h.substr(2),c,d).then(e.resolve,e.reject):e.resolve(d.interpolate(f[b],c)),d.setLocale(g)}else e.reject()},e.reject),e.promise},U=function(a,b,c,d){var e,f=r[a];if(f&&Object.prototype.hasOwnProperty.call(f,b)){if(d.setLocale(a),e=d.interpolate(f[b],c),"@:"===e.substr(0,2))return U(a,e.substr(2),c,d);d.setLocale(g)}return e},V=function(a){if(k){var c=b.get(k)(a,g);return void 0!==c?c:a}return a},W=function(a,b,c,d,f){var g=j.defer();if(a0?B:y,a,b,c,d)},Z=function(a,b,c){return X(B>0?B:y,a,b,c)},$=function(a,b,c,d){var f=j.defer(),h=g?r[g]:r,i=c?M[c]:C;if(h&&Object.prototype.hasOwnProperty.call(h,a)){var l=h[a];"@:"===l.substr(0,2)?O(l.substr(2),b,c,d).then(f.resolve,f.reject):f.resolve(i.interpolate(l,b))}else{var m;k&&!L&&(m=V(a)),g&&e&&e.length?Y(a,b,i,d).then(function(a){f.resolve(a)},function(a){f.reject(P(a))}):k&&!L&&m?f.resolve(d?d:m):d?f.resolve(d):f.reject(P(a))}return f.promise},_=function(a,b,c){var d,f=g?r[g]:r,h=C;if(M&&Object.prototype.hasOwnProperty.call(M,c)&&(h=M[c]),f&&Object.prototype.hasOwnProperty.call(f,a)){var i=f[a];d="@:"===i.substr(0,2)?_(i.substr(2),b,c):h.interpolate(i,b)}else{var j;k&&!L&&(j=V(a)),g&&e&&e.length?(y=0,d=Z(a,b,h)):d=k&&!L&&j?j:P(a)}return d};if(O.preferredLanguage=function(a){return a&&I(a),c},O.cloakClassName=function(){return w},O.fallbackLanguage=function(a){if(void 0!==a&&null!==a){if(J(a),m&&e&&e.length)for(var b=0,c=e.length;c>b;b++)N[e[b]]||(N[e[b]]=R(e[b]));O.use(O.use())}return f?e[0]:e},O.useFallbackLanguage=function(a){if(void 0!==a&&null!==a)if(a){var b=D(e,a);b>-1&&(B=b)}else B=0},O.proposedLanguage=function(){return h},O.storage=function(){return s},O.use=function(a){if(!a)return g;var b=j.defer();d.$emit("$translateChangeStart",{language:a});var c=F(a);return c&&(a=c),r[a]||!m||N[a]?(b.resolve(a),Q(a)):(h=a,N[a]=R(a).then(function(c){return G(c.key,c.table),b.resolve(c.key),Q(c.key),h===a&&(h=void 0),c},function(a){h===a&&(h=void 0),d.$emit("$translateChangeError",{language:a}),b.reject(a),d.$emit("$translateChangeEnd",{language:a})})),b.promise},O.storageKey=function(){return K()},O.isPostCompilingEnabled=function(){return x},O.refresh=function(a){function b(){f.resolve(),d.$emit("$translateRefreshEnd",{language:a})}function c(){f.reject(),d.$emit("$translateRefreshEnd",{language:a})}if(!m)throw new Error("Couldn't refresh translation table, no loader registered!");var f=j.defer();if(d.$emit("$translateRefreshStart",{language:a}),a)r[a]?R(a).then(function(c){G(c.key,c.table),a===g&&Q(g),b()},c):c();else{var h=[],i={};if(e&&e.length)for(var k=0,l=e.length;l>k;k++)h.push(R(e[k])),i[e[k]]=!0;g&&!i[g]&&h.push(R(g)),j.all(h).then(function(a){angular.forEach(a,function(a){r[a.key]&&delete r[a.key],G(a.key,a.table)}),g&&Q(g),b()})}return f.promise},O.instant=function(a,b,d){if(null===a||angular.isUndefined(a))return a;if(angular.isArray(a)){for(var f={},h=0,i=a.length;i>h;h++)f[a[h]]=O.instant(a[h],b,d);return f}if(angular.isString(a)&&a.length<1)return a;a&&(a=E.apply(a));var j,l=[];c&&l.push(c),g&&l.push(g),e&&e.length&&(l=l.concat(e));for(var m=0,n=l.length;n>m;m++){var q=l[m];if(r[q]&&("undefined"!=typeof r[q][a]?j=_(a,b,d):(o||p)&&(j=P(a))),"undefined"!=typeof j)break}return j||""===j||(j=C.interpolate(a,b),k&&!L&&(j=V(a))),j},O.versionInfo=function(){return A},O.loaderCache=function(){return q},O.directivePriority=function(){return z},m&&(angular.equals(r,{})&&O.use(O.use()),e&&e.length))for(var ab=function(a){return G(a.key,a.table),d.$emit("$translateChangeEnd",{language:a.key}),a},bb=0,cb=e.length;cb>bb;bb++)N[e[bb]]=R(e[bb]).then(ab);return O}]}]),angular.module("pascalprecht.translate").factory("$translateDefaultInterpolation",["$interpolate",function(a){var b,c={},d="default",e=null,f={escaped:function(a){var b={};for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=angular.isNumber(a[c])?a[c]:angular.element("
").text(a[c]).html());return b}},g=function(a){var b;return b=angular.isFunction(f[e])?f[e](a):a};return c.setLocale=function(a){b=a},c.getInterpolationIdentifier=function(){return d},c.useSanitizeValueStrategy=function(a){return e=a,this},c.interpolate=function(b,c){return e&&(c=g(c)),a(b)(c||{})},c}]),angular.module("pascalprecht.translate").constant("$STORAGE_KEY","NG_TRANSLATE_LANG_KEY"),angular.module("pascalprecht.translate").directive("translate",["$translate","$q","$interpolate","$compile","$parse","$rootScope",function(a,b,c,d,e,f){var g=function(){return this.replace(/^\s+|\s+$/g,"")};return{restrict:"AE",scope:!0,priority:a.directivePriority(),compile:function(b,h){var i=h.translateValues?h.translateValues:void 0,j=h.translateInterpolation?h.translateInterpolation:void 0,k=b[0].outerHTML.match(/translate-value-+/i),l="^(.*)("+c.startSymbol()+".*"+c.endSymbol()+")(.*)",m="^(.*)"+c.startSymbol()+"(.*)"+c.endSymbol()+"(.*)";return function(b,n,o){b.interpolateParams={},b.preText="",b.postText="";var p={},q=function(a){if(angular.isFunction(q._unwatchOld)&&(q._unwatchOld(),q._unwatchOld=void 0),angular.equals(a,"")||!angular.isDefined(a)){var d=g.apply(n.text()).match(l);if(angular.isArray(d)){b.preText=d[1],b.postText=d[3],p.translate=c(d[2])(b.$parent);var e=n.text().match(m);angular.isArray(e)&&e[2]&&e[2].length&&(q._unwatchOld=b.$watch(e[2],function(a){p.translate=a,w()}))}else p.translate=n.text().replace(/^\s+|\s+$/g,"")}else p.translate=a;w()},r=function(a){o.$observe(a,function(b){p[a]=b,w()})},s=!0;o.$observe("translate",function(a){"undefined"==typeof a?q(""):""===a&&s||(p.translate=a,w()),s=!1});for(var t in o)o.hasOwnProperty(t)&&"translateAttr"===t.substr(0,13)&&r(t);if(o.$observe("translateDefault",function(a){b.defaultText=a}),i&&o.$observe("translateValues",function(a){a&&b.$parent.$watch(function(){angular.extend(b.interpolateParams,e(a)(b.$parent))})}),k){var u=function(a){o.$observe(a,function(c){var d=angular.lowercase(a.substr(14,1))+a.substr(15);b.interpolateParams[d]=c})};for(var v in o)Object.prototype.hasOwnProperty.call(o,v)&&"translateValue"===v.substr(0,14)&&"translateValues"!==v&&u(v)}var w=function(){for(var a in p)p.hasOwnProperty(a)&&x(a,p[a],b,b.interpolateParams,b.defaultText)},x=function(b,c,d,e,f){c?a(c,e,j,f).then(function(a){y(a,d,!0,b)},function(a){y(a,d,!1,b)}):y(c,d,!1,b)},y=function(b,c,e,f){if("translate"===f){e||"undefined"==typeof c.defaultText||(b=c.defaultText),n.html(c.preText+b+c.postText);var g=a.isPostCompilingEnabled(),i="undefined"!=typeof h.translateCompile,j=i&&"false"!==h.translateCompile;(g&&!i||j)&&d(n.contents())(c)}else{e||"undefined"==typeof c.defaultText||(b=c.defaultText);var k=o.$attr[f].substr(15);n.attr(k,b)}};b.$watch("interpolateParams",w,!0);var z=f.$on("$translateChangeSuccess",w);n.text().length&&q(""),w(),b.$on("$destroy",z)}}}}]),angular.module("pascalprecht.translate").directive("translateCloak",["$rootScope","$translate",function(a,b){return{compile:function(c){var d=function(){c.addClass(b.cloakClassName())},e=function(){c.removeClass(b.cloakClassName())},f=a.$on("$translateChangeEnd",function(){e(),f(),f=null});return d(),function(a,c,f){f.translateCloak&&f.translateCloak.length&&f.$observe("translateCloak",function(a){b(a).then(e,d)})}}}}]),angular.module("pascalprecht.translate").filter("translate",["$parse","$translate",function(a,b){var c=function(c,d,e){return angular.isObject(d)||(d=a(d)(this)),b.instant(c,d,e)};return c.$stateful=!0,c}]); \ No newline at end of file +!function(a,b){"function"==typeof define&&define.amd?define([],function(){return b()}):"object"==typeof exports?module.exports=b():b()}(this,function(){function a(a){"use strict";var b=a.storageKey(),c=a.storage(),d=function(){var d=a.preferredLanguage();angular.isString(d)?a.use(d):c.put(b,a.use())};d.displayName="fallbackFromIncorrectStorageValue",c?c.get(b)?a.use(c.get(b))["catch"](d):d():angular.isString(a.preferredLanguage())&&a.use(a.preferredLanguage())}function b(){"use strict";var a,b,c=null,d=!1,e=!1;b={sanitize:function(a,b){return"text"===b&&(a=g(a)),a},escape:function(a,b){return"text"===b&&(a=f(a)),a},sanitizeParameters:function(a,b){return"params"===b&&(a=h(a,g)),a},escapeParameters:function(a,b){return"params"===b&&(a=h(a,f)),a}},b.escaped=b.escapeParameters,this.addStrategy=function(a,c){return b[a]=c,this},this.removeStrategy=function(a){return delete b[a],this},this.useStrategy=function(a){return d=!0,c=a,this},this.$get=["$injector","$log",function(f,g){var h=function(a,c,d){return angular.forEach(d,function(d){if(angular.isFunction(d))a=d(a,c);else{if(!angular.isFunction(b[d]))throw new Error("pascalprecht.translate.$translateSanitization: Unknown sanitization strategy: '"+d+"'");a=b[d](a,c)}}),a},i=function(){d||e||(g.warn("pascalprecht.translate.$translateSanitization: No sanitization strategy has been configured. This can have serious security implications. See http://angular-translate.github.io/docs/#/guide/19_security for details."),e=!0)};return f.has("$sanitize")&&(a=f.get("$sanitize")),{useStrategy:function(a){return function(b){a.useStrategy(b)}}(this),sanitize:function(a,b,d){if(c||i(),arguments.length<3&&(d=c),!d)return a;var e=angular.isArray(d)?d:[d];return h(a,b,e)}}}];var f=function(a){return angular.element("
").text(a).html()},g=function(b){if(!a)throw new Error("pascalprecht.translate.$translateSanitization: Error cannot find $sanitize service. Either include the ngSanitize module (https://docs.angularjs.org/api/ngSanitize) or use a sanitization strategy which does not depend on $sanitize, such as 'escape'.");return a(b)},h=function(a,b){if(angular.isObject(a)){var c=angular.isArray(a)?[]:{};return angular.forEach(a,function(a,d){c[d]=h(a,b)}),c}return angular.isNumber(a)?a:b(a)}}function c(a,b,c,d){"use strict";var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t={},u=[],v=a,w=[],x="translate-cloak",y=!1,z=".",A=0,B=!0,C="default",D={"default":function(a){return(a||"").split("-").join("_")},java:function(a){var b=(a||"").split("-").join("_"),c=b.split("_");return c.length>1?c[0].toLowerCase()+"_"+c[1].toUpperCase():b},bcp47:function(a){var b=(a||"").split("_").join("-"),c=b.split("-");return c.length>1?c[0].toLowerCase()+"-"+c[1].toUpperCase():b}},E="2.7.0",F=function(){if(angular.isFunction(d.getLocale))return d.getLocale();var a,c,e=b.$get().navigator,f=["language","browserLanguage","systemLanguage","userLanguage"];if(angular.isArray(e.languages))for(a=0;ac;c++)if(a[c]===b)return c;return-1},I=function(){return this.replace(/^\s+|\s+$/g,"")},J=function(a){for(var b=[],c=angular.lowercase(a),d=0,e=u.length;e>d;d++)b.push(angular.lowercase(u[d]));if(H(b,c)>-1)return a;if(f){var g;for(var h in f){var i=!1,j=Object.prototype.hasOwnProperty.call(f,h)&&angular.lowercase(h)===angular.lowercase(a);if("*"===h.slice(-1)&&(i=h.slice(0,-1)===a.slice(0,h.length-1)),(j||i)&&(g=f[h],H(b,angular.lowercase(g))>-1))return g}}if(a){var k=a.split("_");if(k.length>1&&H(b,angular.lowercase(k[0]))>-1)return k[0]}return a},K=function(a,b){if(!a&&!b)return t;if(a&&!b){if(angular.isString(a))return t[a]}else angular.isObject(t[a])||(t[a]={}),angular.extend(t[a],L(b));return this};this.translations=K,this.cloakClassName=function(a){return a?(x=a,this):x};var L=function(a,b,c,d){var e,f,g,h;b||(b=[]),c||(c={});for(e in a)Object.prototype.hasOwnProperty.call(a,e)&&(h=a[e],angular.isObject(h)?L(h,b.concat(e),c,e):(f=b.length?""+b.join(z)+z+e:e,b.length&&e===d&&(g=""+b.join(z),c[g]="@:"+f),c[f]=h));return c};L.displayName="flatObject",this.addInterpolation=function(a){return w.push(a),this},this.useMessageFormatInterpolation=function(){return this.useInterpolation("$translateMessageFormatInterpolation")},this.useInterpolation=function(a){return n=a,this},this.useSanitizeValueStrategy=function(a){return c.useStrategy(a),this},this.preferredLanguage=function(a){return M(a),this};var M=function(a){return a&&(e=a),e};this.translationNotFoundIndicator=function(a){return this.translationNotFoundIndicatorLeft(a),this.translationNotFoundIndicatorRight(a),this},this.translationNotFoundIndicatorLeft=function(a){return a?(q=a,this):q},this.translationNotFoundIndicatorRight=function(a){return a?(r=a,this):r},this.fallbackLanguage=function(a){return N(a),this};var N=function(a){return a?(angular.isString(a)?(h=!0,g=[a]):angular.isArray(a)&&(h=!1,g=a),angular.isString(e)&&H(g,e)<0&&g.push(e),this):h?g[0]:g};this.use=function(a){if(a){if(!t[a]&&!o)throw new Error("$translateProvider couldn't find translationTable for langKey: '"+a+"'");return i=a,this}return i};var O=function(a){return a?void(v=a):l?l+v:v};this.storageKey=O,this.useUrlLoader=function(a,b){return this.useLoader("$translateUrlLoader",angular.extend({url:a},b))},this.useStaticFilesLoader=function(a){return this.useLoader("$translateStaticFilesLoader",a)},this.useLoader=function(a,b){return o=a,p=b||{},this},this.useLocalStorage=function(){return this.useStorage("$translateLocalStorage")},this.useCookieStorage=function(){return this.useStorage("$translateCookieStorage")},this.useStorage=function(a){return k=a,this},this.storagePrefix=function(a){return a?(l=a,this):a},this.useMissingTranslationHandlerLog=function(){return this.useMissingTranslationHandler("$translateMissingTranslationHandlerLog")},this.useMissingTranslationHandler=function(a){return m=a,this},this.usePostCompiling=function(a){return y=!!a,this},this.uniformLanguageTag=function(a){return a?angular.isString(a)&&(a={standard:a}):a={},C=a.standard,this},this.determinePreferredLanguage=function(a){var b=a&&angular.isFunction(a)?a():G();return e=u.length?J(b):b,this},this.registerAvailableLanguageKeys=function(a,b){return a?(u=a,b&&(f=b),this):u},this.useLoaderCache=function(a){return a===!1?s=void 0:a===!0?s=!0:"undefined"==typeof a?s="$translationCache":a&&(s=a),this},this.directivePriority=function(a){return void 0===a?A:(A=a,this)},this.statefulFilter=function(a){return void 0===a?B:(B=a,this)},this.$get=["$log","$injector","$rootScope","$q",function(a,b,c,d){var f,l,u,z=b.get(n||"$translateDefaultInterpolation"),C=!1,D={},F={},G=function(a,b,c,h){if(angular.isArray(a)){var j=function(a){for(var e={},f=[],g=function(a){var f=d.defer(),g=function(b){e[a]=b,f.resolve([a,b])};return G(a,b,c,h).then(g,g),f.promise},i=0,j=a.length;j>i;i++)f.push(g(a[i]));return d.all(f).then(function(){return e})};return j(a)}var m=d.defer();a&&(a=I.apply(a));var n=function(){var a=e?F[e]:F[i];if(l=0,k&&!a){var b=f.get(v);if(a=F[b],g&&g.length){var c=H(g,b);l=0===c?1:0,H(g,e)<0&&g.push(e)}}return a}();if(n){var o=function(){_(a,b,c,h).then(m.resolve,m.reject)};o.displayName="promiseResolved",n["finally"](o,m.reject)}else _(a,b,c,h).then(m.resolve,m.reject);return m.promise},P=function(a){return q&&(a=[q,a].join(" ")),r&&(a=[a,r].join(" ")),a},Q=function(a){i=a,c.$emit("$translateChangeSuccess",{language:a}),k&&f.put(G.storageKey(),i),z.setLocale(i);var b=function(a,b){D[b].setLocale(i)};b.displayName="eachInterpolatorLocaleSetter",angular.forEach(D,b),c.$emit("$translateChangeEnd",{language:a})},R=function(a){if(!a)throw"No language key specified for loading.";var e=d.defer();c.$emit("$translateLoadingStart",{language:a}),C=!0;var f=s;"string"==typeof f&&(f=b.get(f));var g=angular.extend({},p,{key:a,$http:angular.extend({},{cache:f},p.$http)}),h=function(b){var d={};c.$emit("$translateLoadingSuccess",{language:a}),angular.isArray(b)?angular.forEach(b,function(a){angular.extend(d,L(a))}):angular.extend(d,L(b)),C=!1,e.resolve({key:a,table:d}),c.$emit("$translateLoadingEnd",{language:a})};h.displayName="onLoaderSuccess";var i=function(a){c.$emit("$translateLoadingError",{language:a}),e.reject(a),c.$emit("$translateLoadingEnd",{language:a})};return i.displayName="onLoaderError",b.get(o)(g).then(h,i),e.promise};if(k&&(f=b.get(k),!f.get||!f.put))throw new Error("Couldn't use storage '"+k+"', missing get() or put() method!");if(w.length){var S=function(a){var c=b.get(a);c.setLocale(e||i),D[c.getInterpolationIdentifier()]=c};S.displayName="interpolationFactoryAdder",angular.forEach(w,S)}var T=function(a){var b=d.defer();if(Object.prototype.hasOwnProperty.call(t,a))b.resolve(t[a]);else if(F[a]){var c=function(a){K(a.key,a.table),b.resolve(a.table)};c.displayName="translationTableResolver",F[a].then(c,b.reject)}else b.reject();return b.promise},U=function(a,b,c,e){var f=d.defer(),g=function(d){if(Object.prototype.hasOwnProperty.call(d,b)){e.setLocale(a);var g=d[b];"@:"===g.substr(0,2)?U(a,g.substr(2),c,e).then(f.resolve,f.reject):f.resolve(e.interpolate(d[b],c)),e.setLocale(i)}else f.reject()};return g.displayName="fallbackTranslationResolver",T(a).then(g,f.reject),f.promise},V=function(a,b,c,d){var e,f=t[a];if(f&&Object.prototype.hasOwnProperty.call(f,b)){if(d.setLocale(a),e=d.interpolate(f[b],c),"@:"===e.substr(0,2))return V(a,e.substr(2),c,d);d.setLocale(i)}return e},W=function(a,c){if(m){var d=b.get(m)(a,i,c);return void 0!==d?d:a}return a},X=function(a,b,c,e,f){var h=d.defer();if(a0?u:l,a,b,c,d)},$=function(a,b,c){return Y(u>0?u:l,a,b,c)},_=function(a,b,c,e){var f=d.defer(),h=i?t[i]:t,j=c?D[c]:z;if(h&&Object.prototype.hasOwnProperty.call(h,a)){var k=h[a];"@:"===k.substr(0,2)?G(k.substr(2),b,c,e).then(f.resolve,f.reject):f.resolve(j.interpolate(k,b))}else{var l;m&&!C&&(l=W(a,b)),i&&g&&g.length?Z(a,b,j,e).then(function(a){f.resolve(a)},function(a){f.reject(P(a))}):m&&!C&&l?f.resolve(e?e:l):e?f.resolve(e):f.reject(P(a))}return f.promise},ab=function(a,b,c){var d,e=i?t[i]:t,f=z;if(D&&Object.prototype.hasOwnProperty.call(D,c)&&(f=D[c]),e&&Object.prototype.hasOwnProperty.call(e,a)){var h=e[a];d="@:"===h.substr(0,2)?ab(h.substr(2),b,c):f.interpolate(h,b)}else{var j;m&&!C&&(j=W(a,b)),i&&g&&g.length?(l=0,d=$(a,b,f)):d=m&&!C&&j?j:P(a)}return d},bb=function(a){j===a&&(j=void 0),F[a]=void 0};if(G.preferredLanguage=function(a){return a&&M(a),e},G.cloakClassName=function(){return x},G.fallbackLanguage=function(a){if(void 0!==a&&null!==a){if(N(a),o&&g&&g.length)for(var b=0,c=g.length;c>b;b++)F[g[b]]||(F[g[b]]=R(g[b]));G.use(G.use())}return h?g[0]:g},G.useFallbackLanguage=function(a){if(void 0!==a&&null!==a)if(a){var b=H(g,a);b>-1&&(u=b)}else u=0},G.proposedLanguage=function(){return j},G.storage=function(){return f},G.use=function(a){if(!a)return i;var b=d.defer();c.$emit("$translateChangeStart",{language:a});var e=J(a);return e&&(a=e),t[a]||!o||F[a]?j===a&&F[a]?F[a].then(function(a){return b.resolve(a.key),a},function(a){return b.reject(a),d.reject(a)}):(b.resolve(a),Q(a)):(j=a,F[a]=R(a).then(function(a){return K(a.key,a.table),b.resolve(a.key),Q(a.key),a},function(a){return c.$emit("$translateChangeError",{language:a}),b.reject(a),c.$emit("$translateChangeEnd",{language:a}),d.reject(a)}),F[a]["finally"](function(){bb(a)})),b.promise},G.storageKey=function(){return O()},G.isPostCompilingEnabled=function(){return y},G.refresh=function(a){function b(){f.resolve(),c.$emit("$translateRefreshEnd",{language:a})}function e(){f.reject(),c.$emit("$translateRefreshEnd",{language:a})}if(!o)throw new Error("Couldn't refresh translation table, no loader registered!");var f=d.defer();if(c.$emit("$translateRefreshStart",{language:a}),a)if(t[a]){var h=function(c){K(c.key,c.table),a===i&&Q(i),b()};h.displayName="refreshPostProcessor",R(a).then(h,e)}else e();else{var j=[],k={};if(g&&g.length)for(var l=0,m=g.length;m>l;l++)j.push(R(g[l])),k[g[l]]=!0;i&&!k[i]&&j.push(R(i));var n=function(a){t={},angular.forEach(a,function(a){K(a.key,a.table)}),i&&Q(i),b()};n.displayName="refreshPostProcessor",d.all(j).then(n)}return f.promise},G.instant=function(a,b,c){if(null===a||angular.isUndefined(a))return a;if(angular.isArray(a)){for(var d={},f=0,h=a.length;h>f;f++)d[a[f]]=G.instant(a[f],b,c);return d}if(angular.isString(a)&&a.length<1)return a;a&&(a=I.apply(a));var j,k=[];e&&k.push(e),i&&k.push(i),g&&g.length&&(k=k.concat(g));for(var l=0,n=k.length;n>l;l++){var o=k[l];if(t[o]&&("undefined"!=typeof t[o][a]?j=ab(a,b,c):(q||r)&&(j=P(a))),"undefined"!=typeof j)break}return j||""===j||(j=z.interpolate(a,b),m&&!C&&(j=W(a,b))),j},G.versionInfo=function(){return E},G.loaderCache=function(){return s},G.directivePriority=function(){return A},G.statefulFilter=function(){return B},o&&(angular.equals(t,{})&&G.use(G.use()),g&&g.length))for(var cb=function(a){return K(a.key,a.table),c.$emit("$translateChangeEnd",{language:a.key}),a},db=0,eb=g.length;eb>db;db++){var fb=g[db];t[fb]||(F[fb]=R(fb).then(cb))}return G}]}function d(a,b){"use strict";var c,d={},e="default";return d.setLocale=function(a){c=a},d.getInterpolationIdentifier=function(){return e},d.useSanitizeValueStrategy=function(a){return b.useStrategy(a),this},d.interpolate=function(c,d){d=d||{},d=b.sanitize(d,"params");var e=a(c)(d);return e=b.sanitize(e,"text")},d}function e(a,b,c,d,e,f){"use strict";var g=function(){return this.replace(/^\s+|\s+$/g,"")};return{restrict:"AE",scope:!0,priority:a.directivePriority(),compile:function(b,h){var i=h.translateValues?h.translateValues:void 0,j=h.translateInterpolation?h.translateInterpolation:void 0,k=b[0].outerHTML.match(/translate-value-+/i),l="^(.*)("+c.startSymbol()+".*"+c.endSymbol()+")(.*)",m="^(.*)"+c.startSymbol()+"(.*)"+c.endSymbol()+"(.*)";return function(b,n,o){b.interpolateParams={},b.preText="",b.postText="";var p={},q=function(a,c,d){if(c.translateValues&&angular.extend(a,e(c.translateValues)(b.$parent)),k)for(var f in d)if(Object.prototype.hasOwnProperty.call(c,f)&&"translateValue"===f.substr(0,14)&&"translateValues"!==f){var g=angular.lowercase(f.substr(14,1))+f.substr(15);a[g]=d[f]}},r=function(a){if(angular.isFunction(r._unwatchOld)&&(r._unwatchOld(),r._unwatchOld=void 0),angular.equals(a,"")||!angular.isDefined(a)){var d=g.apply(n.text()).match(l);if(angular.isArray(d)){b.preText=d[1],b.postText=d[3],p.translate=c(d[2])(b.$parent);var e=n.text().match(m);angular.isArray(e)&&e[2]&&e[2].length&&(r._unwatchOld=b.$watch(e[2],function(a){p.translate=a,x()}))}else p.translate=n.text().replace(/^\s+|\s+$/g,"")}else p.translate=a;x()},s=function(a){o.$observe(a,function(b){p[a]=b,x()})};q(b.interpolateParams,o,h);var t=!0;o.$observe("translate",function(a){"undefined"==typeof a?r(""):""===a&&t||(p.translate=a,x()),t=!1});for(var u in o)o.hasOwnProperty(u)&&"translateAttr"===u.substr(0,13)&&s(u);if(o.$observe("translateDefault",function(a){b.defaultText=a}),i&&o.$observe("translateValues",function(a){a&&b.$parent.$watch(function(){angular.extend(b.interpolateParams,e(a)(b.$parent))})}),k){var v=function(a){o.$observe(a,function(c){var d=angular.lowercase(a.substr(14,1))+a.substr(15);b.interpolateParams[d]=c})};for(var w in o)Object.prototype.hasOwnProperty.call(o,w)&&"translateValue"===w.substr(0,14)&&"translateValues"!==w&&v(w)}var x=function(){for(var a in p)p.hasOwnProperty(a)&&void 0!==p[a]&&y(a,p[a],b,b.interpolateParams,b.defaultText)},y=function(b,c,d,e,f){c?a(c,e,j,f).then(function(a){z(a,d,!0,b)},function(a){z(a,d,!1,b)}):z(c,d,!1,b)},z=function(b,c,e,f){if("translate"===f){e||"undefined"==typeof c.defaultText||(b=c.defaultText),n.html(c.preText+b+c.postText);var g=a.isPostCompilingEnabled(),i="undefined"!=typeof h.translateCompile,j=i&&"false"!==h.translateCompile;(g&&!i||j)&&d(n.contents())(c)}else{e||"undefined"==typeof c.defaultText||(b=c.defaultText);var k=o.$attr[f];"data-"===k.substr(0,5)&&(k=k.substr(5)),k=k.substr(15),n.attr(k,b)}};(i||k||o.translateDefault)&&b.$watch("interpolateParams",x,!0);var A=f.$on("$translateChangeSuccess",x);n.text().length&&r(o.translate?o.translate:""),x(),b.$on("$destroy",A)}}}}function f(a,b){"use strict";return{compile:function(c){var d=function(){c.addClass(b.cloakClassName())},e=function(){c.removeClass(b.cloakClassName())},f=a.$on("$translateChangeEnd",function(){e(),f(),f=null});return d(),function(a,c,f){f.translateCloak&&f.translateCloak.length&&f.$observe("translateCloak",function(a){b(a).then(e,d)})}}}}function g(a,b){"use strict";var c=function(c,d,e){return angular.isObject(d)||(d=a(d)(this)),b.instant(c,d,e)};return b.statefulFilter()&&(c.$stateful=!0),c}return angular.module("pascalprecht.translate",["ng"]).run(a),a.$inject=["$translate"],a.displayName="runTranslate",angular.module("pascalprecht.translate").provider("$translateSanitization",b),angular.module("pascalprecht.translate").constant("pascalprechtTranslateOverrider",{}).provider("$translate",c),c.$inject=["$STORAGE_KEY","$windowProvider","$translateSanitizationProvider","pascalprechtTranslateOverrider"],c.displayName="displayName",angular.module("pascalprecht.translate").factory("$translateDefaultInterpolation",d),d.$inject=["$interpolate","$translateSanitization"],d.displayName="$translateDefaultInterpolation",angular.module("pascalprecht.translate").constant("$STORAGE_KEY","NG_TRANSLATE_LANG_KEY"),angular.module("pascalprecht.translate").directive("translate",e),e.$inject=["$translate","$q","$interpolate","$compile","$parse","$rootScope"],e.displayName="translateDirective",angular.module("pascalprecht.translate").directive("translateCloak",f),f.$inject=["$rootScope","$translate"],f.displayName="translateCloakDirective",angular.module("pascalprecht.translate").filter("translate",g),g.$inject=["$parse","$translate"],g.displayName="translateFilterFactory","pascalprecht.translate"}); \ No newline at end of file