aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/libs/third-party/numeral.js
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-web/src/main/js/libs/third-party/numeral.js')
-rwxr-xr-xserver/sonar-web/src/main/js/libs/third-party/numeral.js698
1 files changed, 698 insertions, 0 deletions
diff --git a/server/sonar-web/src/main/js/libs/third-party/numeral.js b/server/sonar-web/src/main/js/libs/third-party/numeral.js
new file mode 100755
index 00000000000..d67c0ce6efb
--- /dev/null
+++ b/server/sonar-web/src/main/js/libs/third-party/numeral.js
@@ -0,0 +1,698 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/*!
+ * numeral.js
+ * version : 1.5.3
+ * author : Adam Draper
+ * license : MIT
+ * http://adamwdraper.github.com/Numeral-js/
+ */
+
+(function () {
+
+ /************************************
+ Constants
+ ************************************/
+
+ var numeral,
+ VERSION = '1.5.3',
+ // internal storage for language config files
+ languages = {},
+ currentLanguage = 'en',
+ zeroFormat = null,
+ defaultFormat = '0,0',
+ // check for nodeJS
+ hasModule = (typeof module !== 'undefined' && module.exports);
+
+
+ /************************************
+ Constructors
+ ************************************/
+
+
+ // Numeral prototype object
+ function Numeral (number) {
+ this._value = number;
+ }
+
+ /**
+ * Implementation of toFixed() that treats floats more like decimals
+ *
+ * Fixes binary rounding issues (eg. (0.615).toFixed(2) === '0.61') that present
+ * problems for accounting- and finance-related software.
+ */
+ function toFixed (value, precision, roundingFunction, optionals) {
+ var power = Math.pow(10, precision),
+ optionalsRegExp,
+ output;
+
+ //roundingFunction = (roundingFunction !== undefined ? roundingFunction : Math.round);
+ // Multiply up by precision, round accurately, then divide and use native toFixed():
+ output = (roundingFunction(value * power) / power).toFixed(precision);
+
+ if (optionals) {
+ optionalsRegExp = new RegExp('0{1,' + optionals + '}$');
+ output = output.replace(optionalsRegExp, '');
+ }
+
+ return output;
+ }
+
+ /************************************
+ Formatting
+ ************************************/
+
+ // determine what type of formatting we need to do
+ function formatNumeral (n, format, roundingFunction) {
+ var output;
+
+ // figure out what kind of format we are dealing with
+ if (format.indexOf('$') > -1) { // currency!!!!!
+ output = formatCurrency(n, format, roundingFunction);
+ } else if (format.indexOf('%') > -1) { // percentage
+ output = formatPercentage(n, format, roundingFunction);
+ } else if (format.indexOf(':') > -1) { // time
+ output = formatTime(n, format);
+ } else { // plain ol' numbers or bytes
+ output = formatNumber(n._value, format, roundingFunction);
+ }
+
+ // return string
+ return output;
+ }
+
+ // revert to number
+ function unformatNumeral (n, string) {
+ var stringOriginal = string,
+ thousandRegExp,
+ millionRegExp,
+ billionRegExp,
+ trillionRegExp,
+ suffixes = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
+ bytesMultiplier = false,
+ power;
+
+ if (string.indexOf(':') > -1) {
+ n._value = unformatTime(string);
+ } else {
+ if (string === zeroFormat) {
+ n._value = 0;
+ } else {
+ if (languages[currentLanguage].delimiters.decimal !== '.') {
+ string = string.replace(/\./g,'').replace(languages[currentLanguage].delimiters.decimal, '.');
+ }
+
+ // see if abbreviations are there so that we can multiply to the correct number
+ thousandRegExp = new RegExp('[^a-zA-Z]' + languages[currentLanguage].abbreviations.thousand + '(?:\\)|(\\' + languages[currentLanguage].currency.symbol + ')?(?:\\))?)?$');
+ millionRegExp = new RegExp('[^a-zA-Z]' + languages[currentLanguage].abbreviations.million + '(?:\\)|(\\' + languages[currentLanguage].currency.symbol + ')?(?:\\))?)?$');
+ billionRegExp = new RegExp('[^a-zA-Z]' + languages[currentLanguage].abbreviations.billion + '(?:\\)|(\\' + languages[currentLanguage].currency.symbol + ')?(?:\\))?)?$');
+ trillionRegExp = new RegExp('[^a-zA-Z]' + languages[currentLanguage].abbreviations.trillion + '(?:\\)|(\\' + languages[currentLanguage].currency.symbol + ')?(?:\\))?)?$');
+
+ // see if bytes are there so that we can multiply to the correct number
+ for (power = 0; power <= suffixes.length; power++) {
+ bytesMultiplier = (string.indexOf(suffixes[power]) > -1) ? Math.pow(1024, power + 1) : false;
+
+ if (bytesMultiplier) {
+ break;
+ }
+ }
+
+ // do some math to create our number
+ n._value = ((bytesMultiplier) ? bytesMultiplier : 1) * ((stringOriginal.match(thousandRegExp)) ? Math.pow(10, 3) : 1) * ((stringOriginal.match(millionRegExp)) ? Math.pow(10, 6) : 1) * ((stringOriginal.match(billionRegExp)) ? Math.pow(10, 9) : 1) * ((stringOriginal.match(trillionRegExp)) ? Math.pow(10, 12) : 1) * ((string.indexOf('%') > -1) ? 0.01 : 1) * (((string.split('-').length + Math.min(string.split('(').length-1, string.split(')').length-1)) % 2)? 1: -1) * Number(string.replace(/[^0-9\.]+/g, ''));
+
+ // round if we are talking about bytes
+ n._value = (bytesMultiplier) ? Math.ceil(n._value) : n._value;
+ }
+ }
+ return n._value;
+ }
+
+ function formatCurrency (n, format, roundingFunction) {
+ var symbolIndex = format.indexOf('$'),
+ openParenIndex = format.indexOf('('),
+ minusSignIndex = format.indexOf('-'),
+ space = '',
+ spliceIndex,
+ output;
+
+ // check for space before or after currency
+ if (format.indexOf(' $') > -1) {
+ space = ' ';
+ format = format.replace(' $', '');
+ } else if (format.indexOf('$ ') > -1) {
+ space = ' ';
+ format = format.replace('$ ', '');
+ } else {
+ format = format.replace('$', '');
+ }
+
+ // format the number
+ output = formatNumber(n._value, format, roundingFunction);
+
+ // position the symbol
+ if (symbolIndex <= 1) {
+ if (output.indexOf('(') > -1 || output.indexOf('-') > -1) {
+ output = output.split('');
+ spliceIndex = 1;
+ if (symbolIndex < openParenIndex || symbolIndex < minusSignIndex){
+ // the symbol appears before the "(" or "-"
+ spliceIndex = 0;
+ }
+ output.splice(spliceIndex, 0, languages[currentLanguage].currency.symbol + space);
+ output = output.join('');
+ } else {
+ output = languages[currentLanguage].currency.symbol + space + output;
+ }
+ } else {
+ if (output.indexOf(')') > -1) {
+ output = output.split('');
+ output.splice(-1, 0, space + languages[currentLanguage].currency.symbol);
+ output = output.join('');
+ } else {
+ output = output + space + languages[currentLanguage].currency.symbol;
+ }
+ }
+
+ return output;
+ }
+
+ function formatPercentage (n, format, roundingFunction) {
+ var space = '',
+ output,
+ value = n._value * 100;
+
+ // check for space before %
+ if (format.indexOf(' %') > -1) {
+ space = ' ';
+ format = format.replace(' %', '');
+ } else {
+ format = format.replace('%', '');
+ }
+
+ output = formatNumber(value, format, roundingFunction);
+
+ if (output.indexOf(')') > -1 ) {
+ output = output.split('');
+ output.splice(-1, 0, space + '%');
+ output = output.join('');
+ } else {
+ output = output + space + '%';
+ }
+
+ return output;
+ }
+
+ function formatTime (n) {
+ var hours = Math.floor(n._value/60/60),
+ minutes = Math.floor((n._value - (hours * 60 * 60))/60),
+ seconds = Math.round(n._value - (hours * 60 * 60) - (minutes * 60));
+ return hours + ':' + ((minutes < 10) ? '0' + minutes : minutes) + ':' + ((seconds < 10) ? '0' + seconds : seconds);
+ }
+
+ function unformatTime (string) {
+ var timeArray = string.split(':'),
+ seconds = 0;
+ // turn hours and minutes into seconds and add them all up
+ if (timeArray.length === 3) {
+ // hours
+ seconds = seconds + (Number(timeArray[0]) * 60 * 60);
+ // minutes
+ seconds = seconds + (Number(timeArray[1]) * 60);
+ // seconds
+ seconds = seconds + Number(timeArray[2]);
+ } else if (timeArray.length === 2) {
+ // minutes
+ seconds = seconds + (Number(timeArray[0]) * 60);
+ // seconds
+ seconds = seconds + Number(timeArray[1]);
+ }
+ return Number(seconds);
+ }
+
+ function formatNumber (value, format, roundingFunction) {
+ var negP = false,
+ signed = false,
+ optDec = false,
+ abbr = '',
+ abbrK = false, // force abbreviation to thousands
+ abbrM = false, // force abbreviation to millions
+ abbrB = false, // force abbreviation to billions
+ abbrT = false, // force abbreviation to trillions
+ abbrForce = false, // force abbreviation
+ bytes = '',
+ ord = '',
+ abs = Math.abs(value),
+ suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
+ min,
+ max,
+ power,
+ w,
+ precision,
+ thousands,
+ d = '',
+ neg = false;
+
+ // check if number is zero and a custom zero format has been set
+ if (value === 0 && zeroFormat !== null) {
+ return zeroFormat;
+ } else {
+ // see if we should use parentheses for negative number or if we should prefix with a sign
+ // if both are present we default to parentheses
+ if (format.indexOf('(') > -1) {
+ negP = true;
+ format = format.slice(1, -1);
+ } else if (format.indexOf('+') > -1) {
+ signed = true;
+ format = format.replace(/\+/g, '');
+ }
+
+ // see if abbreviation is wanted
+ if (format.indexOf('a') > -1) {
+ // check if abbreviation is specified
+ abbrK = format.indexOf('aK') >= 0;
+ abbrM = format.indexOf('aM') >= 0;
+ abbrB = format.indexOf('aB') >= 0;
+ abbrT = format.indexOf('aT') >= 0;
+ abbrForce = abbrK || abbrM || abbrB || abbrT;
+
+ // check for space before abbreviation
+ if (format.indexOf(' a') > -1) {
+ abbr = ' ';
+ format = format.replace(' a', '');
+ } else {
+ format = format.replace('a', '');
+ }
+
+ if (abs >= Math.pow(10, 12) && !abbrForce || abbrT) {
+ // trillion
+ abbr = abbr + languages[currentLanguage].abbreviations.trillion;
+ value = value / Math.pow(10, 12);
+ } else if (abs < Math.pow(10, 12) && abs >= Math.pow(10, 9) && !abbrForce || abbrB) {
+ // billion
+ abbr = abbr + languages[currentLanguage].abbreviations.billion;
+ value = value / Math.pow(10, 9);
+ } else if (abs < Math.pow(10, 9) && abs >= Math.pow(10, 6) && !abbrForce || abbrM) {
+ // million
+ abbr = abbr + languages[currentLanguage].abbreviations.million;
+ value = value / Math.pow(10, 6);
+ } else if (abs < Math.pow(10, 6) && abs >= Math.pow(10, 3) && !abbrForce || abbrK) {
+ // thousand
+ abbr = abbr + languages[currentLanguage].abbreviations.thousand;
+ value = value / Math.pow(10, 3);
+ }
+ }
+
+ // see if we are formatting bytes
+ if (format.indexOf('b') > -1) {
+ // check for space before
+ if (format.indexOf(' b') > -1) {
+ bytes = ' ';
+ format = format.replace(' b', '');
+ } else {
+ format = format.replace('b', '');
+ }
+
+ for (power = 0; power <= suffixes.length; power++) {
+ min = Math.pow(1024, power);
+ max = Math.pow(1024, power+1);
+
+ if (value >= min && value < max) {
+ bytes = bytes + suffixes[power];
+ if (min > 0) {
+ value = value / min;
+ }
+ break;
+ }
+ }
+ }
+
+ // see if ordinal is wanted
+ if (format.indexOf('o') > -1) {
+ // check for space before
+ if (format.indexOf(' o') > -1) {
+ ord = ' ';
+ format = format.replace(' o', '');
+ } else {
+ format = format.replace('o', '');
+ }
+
+ ord = ord + languages[currentLanguage].ordinal(value);
+ }
+
+ if (format.indexOf('[.]') > -1) {
+ optDec = true;
+ format = format.replace('[.]', '.');
+ }
+
+ w = value.toString().split('.')[0];
+ precision = format.split('.')[1];
+ thousands = format.indexOf(',');
+
+ if (precision) {
+ if (precision.indexOf('[') > -1) {
+ precision = precision.replace(']', '');
+ precision = precision.split('[');
+ d = toFixed(value, (precision[0].length + precision[1].length), roundingFunction, precision[1].length);
+ } else {
+ d = toFixed(value, precision.length, roundingFunction);
+ }
+
+ w = d.split('.')[0];
+
+ if (d.split('.')[1].length) {
+ d = languages[currentLanguage].delimiters.decimal + d.split('.')[1];
+ } else {
+ d = '';
+ }
+
+ if (optDec && Number(d.slice(1)) === 0) {
+ d = '';
+ }
+ } else {
+ w = toFixed(value, null, roundingFunction);
+ }
+
+ // format number
+ if (w.indexOf('-') > -1) {
+ w = w.slice(1);
+ neg = true;
+ }
+
+ if (thousands > -1) {
+ w = w.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' + languages[currentLanguage].delimiters.thousands);
+ }
+
+ if (format.indexOf('.') === 0) {
+ w = '';
+ }
+
+ return ((negP && neg) ? '(' : '') + ((!negP && neg) ? '-' : '') + ((!neg && signed) ? '+' : '') + w + d + ((ord) ? ord : '') + ((abbr) ? abbr : '') + ((bytes) ? bytes : '') + ((negP && neg) ? ')' : '');
+ }
+ }
+
+ /************************************
+ Top Level Functions
+ ************************************/
+
+ numeral = function (input) {
+ if (numeral.isNumeral(input)) {
+ input = input.value();
+ } else if (input === 0 || typeof input === 'undefined') {
+ input = 0;
+ } else if (!Number(input)) {
+ input = numeral.fn.unformat(input);
+ }
+
+ return new Numeral(Number(input));
+ };
+
+ // version number
+ numeral.version = VERSION;
+
+ // compare numeral object
+ numeral.isNumeral = function (obj) {
+ return obj instanceof Numeral;
+ };
+
+ // This function will load languages and then set the global language. If
+ // no arguments are passed in, it will simply return the current global
+ // language key.
+ numeral.language = function (key, values) {
+ if (!key) {
+ return currentLanguage;
+ }
+
+ if (key && !values) {
+ if(!languages[key]) {
+ return;
+ }
+ currentLanguage = key;
+ }
+
+ if (values || !languages[key]) {
+ loadLanguage(key, values);
+ }
+
+ return numeral;
+ };
+
+ // This function provides access to the loaded language data. If
+ // no arguments are passed in, it will simply return the current
+ // global language object.
+ numeral.languageData = function (key) {
+ if (!key) {
+ return languages[currentLanguage];
+ }
+
+ if (!languages[key]) {
+ throw new Error('Unknown language : ' + key);
+ }
+
+ return languages[key];
+ };
+
+ numeral.language('en', {
+ delimiters: {
+ thousands: ',',
+ decimal: '.'
+ },
+ abbreviations: {
+ thousand: 'k',
+ million: 'm',
+ billion: 'b',
+ trillion: 't'
+ },
+ ordinal: function (number) {
+ var b = number % 10;
+ return (~~ (number % 100 / 10) === 1) ? 'th' :
+ (b === 1) ? 'st' :
+ (b === 2) ? 'nd' :
+ (b === 3) ? 'rd' : 'th';
+ },
+ currency: {
+ symbol: '$'
+ }
+ });
+
+ numeral.zeroFormat = function (format) {
+ zeroFormat = typeof(format) === 'string' ? format : null;
+ };
+
+ numeral.defaultFormat = function (format) {
+ defaultFormat = typeof(format) === 'string' ? format : '0.0';
+ };
+
+ /************************************
+ Helpers
+ ************************************/
+
+ function loadLanguage(key, values) {
+ languages[key] = values;
+ }
+
+ /************************************
+ Floating-point helpers
+ ************************************/
+
+ // The floating-point helper functions and implementation
+ // borrows heavily from sinful.js: http://guipn.github.io/sinful.js/
+
+ /**
+ * Array.prototype.reduce for browsers that don't support it
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce#Compatibility
+ */
+ if ('function' !== typeof Array.prototype.reduce) {
+ Array.prototype.reduce = function (callback, opt_initialValue) {
+ 'use strict';
+
+ if (null === this || 'undefined' === typeof this) {
+ // At the moment all modern browsers, that support strict mode, have
+ // native implementation of Array.prototype.reduce. For instance, IE8
+ // does not support strict mode, so this check is actually useless.
+ throw new TypeError('Array.prototype.reduce called on null or undefined');
+ }
+
+ if ('function' !== typeof callback) {
+ throw new TypeError(callback + ' is not a function');
+ }
+
+ var index,
+ value,
+ length = this.length >>> 0,
+ isValueSet = false;
+
+ if (1 < arguments.length) {
+ value = opt_initialValue;
+ isValueSet = true;
+ }
+
+ for (index = 0; length > index; ++index) {
+ if (this.hasOwnProperty(index)) {
+ if (isValueSet) {
+ value = callback(value, this[index], index, this);
+ } else {
+ value = this[index];
+ isValueSet = true;
+ }
+ }
+ }
+
+ if (!isValueSet) {
+ throw new TypeError('Reduce of empty array with no initial value');
+ }
+
+ return value;
+ };
+ }
+
+
+ /**
+ * Computes the multiplier necessary to make x >= 1,
+ * effectively eliminating miscalculations caused by
+ * finite precision.
+ */
+ function multiplier(x) {
+ var parts = x.toString().split('.');
+ if (parts.length < 2) {
+ return 1;
+ }
+ return Math.pow(10, parts[1].length);
+ }
+
+ /**
+ * Given a variable number of arguments, returns the maximum
+ * multiplier that must be used to normalize an operation involving
+ * all of them.
+ */
+ function correctionFactor() {
+ var args = Array.prototype.slice.call(arguments);
+ return args.reduce(function (prev, next) {
+ var mp = multiplier(prev),
+ mn = multiplier(next);
+ return mp > mn ? mp : mn;
+ }, -Infinity);
+ }
+
+
+ /************************************
+ Numeral Prototype
+ ************************************/
+
+
+ numeral.fn = Numeral.prototype = {
+
+ clone : function () {
+ return numeral(this);
+ },
+
+ format : function (inputString, roundingFunction) {
+ return formatNumeral(this,
+ inputString ? inputString : defaultFormat,
+ (roundingFunction !== undefined) ? roundingFunction : Math.round
+ );
+ },
+
+ unformat : function (inputString) {
+ if (Object.prototype.toString.call(inputString) === '[object Number]') {
+ return inputString;
+ }
+ return unformatNumeral(this, inputString ? inputString : defaultFormat);
+ },
+
+ value : function () {
+ return this._value;
+ },
+
+ valueOf : function () {
+ return this._value;
+ },
+
+ set : function (value) {
+ this._value = Number(value);
+ return this;
+ },
+
+ add : function (value) {
+ var corrFactor = correctionFactor.call(null, this._value, value);
+ function cback(accum, curr, currI, O) {
+ return accum + corrFactor * curr;
+ }
+ this._value = [this._value, value].reduce(cback, 0) / corrFactor;
+ return this;
+ },
+
+ subtract : function (value) {
+ var corrFactor = correctionFactor.call(null, this._value, value);
+ function cback(accum, curr, currI, O) {
+ return accum - corrFactor * curr;
+ }
+ this._value = [value].reduce(cback, this._value * corrFactor) / corrFactor;
+ return this;
+ },
+
+ multiply : function (value) {
+ function cback(accum, curr, currI, O) {
+ var corrFactor = correctionFactor(accum, curr);
+ return (accum * corrFactor) * (curr * corrFactor) /
+ (corrFactor * corrFactor);
+ }
+ this._value = [this._value, value].reduce(cback, 1);
+ return this;
+ },
+
+ divide : function (value) {
+ function cback(accum, curr, currI, O) {
+ var corrFactor = correctionFactor(accum, curr);
+ return (accum * corrFactor) / (curr * corrFactor);
+ }
+ this._value = [this._value, value].reduce(cback);
+ return this;
+ },
+
+ difference : function (value) {
+ return Math.abs(numeral(this._value).subtract(value).value());
+ }
+
+ };
+
+ /************************************
+ Exposing Numeral
+ ************************************/
+
+ // CommonJS module is defined
+ if (hasModule) {
+ module.exports = numeral;
+ }
+
+ /*global ender:false */
+ if (typeof ender === 'undefined') {
+ // here, `this` means `window` in the browser, or `global` on the server
+ // add `numeral` as a global object via a string identifier,
+ // for Closure Compiler 'advanced' mode
+ this['numeral'] = numeral;
+ }
+
+ /*global define:false */
+ if (typeof define === 'function' && define.amd) {
+ define([], function () {
+ return numeral;
+ });
+ }
+}).call(this);