text: package humanize
  
  /*
  Slightly adapted from the source to fit go-humanize.
  
  Author: https://github.com/gorhill
  Source: https://gist.github.com/gorhill/5285193
  
  */
  
  import (
  	"math"
  	"strconv"
  )
  
  var (
  	renderFloatPrecisionMultipliers = [...]float64{
  		1,
  		10,
  		100,
  		1000,
  		10000,
  		100000,
  		1000000,
  		10000000,
  		100000000,
  		1000000000,
  	}
  
  	renderFloatPrecisionRounders = [...]float64{
  		0.5,
  		0.05,
  		0.005,
  		0.0005,
  		0.00005,
  		0.000005,
  		0.0000005,
  		0.00000005,
  		0.000000005,
  		0.0000000005,
  	}
  )
  
  // FormatFloat produces a formatted number as string based on the following user-specified criteria:
  // * thousands separator
  // * decimal separator
  // * decimal precision
  //
  // Usage: s := RenderFloat(format, n)
  // The format parameter tells how to render the number n.
  //
  // See examples: http://play.golang.org/p/LXc1Ddm1lJ
  //
  // Examples of format strings, given n = 12345.6789:
  // "#,###.##" => "12,345.67"
  // "#,###." => "12,345"
  // "#,###" => "12345,678"
  // "#\u202F###,##" => "12 345,68"
  // "#.###,###### => 12.345,678900
  // "" (aka default format) => 12,345.67
  //
  // The highest precision allowed is 9 digits after the decimal symbol.
  // There is also a version for integer number, FormatInteger(),
  // which is convenient for calls within template.
  func FormatFloat(format string, n float64) string {
  	// Special cases:
  	//   NaN = "NaN"
  	//   +Inf = "+Infinity"
  	//   -Inf = "-Infinity"
  	if math.IsNaN(n) {
  		return "NaN"
  	}
  	if n > math.MaxFloat64 {
  		return "Infinity"
  	}
  	if n < -math.MaxFloat64 {
  		return "-Infinity"
  	}
  
  	// default format
  	precision := 2
  	decimalStr := "."
  	thousandStr := ","
  	positiveStr := ""
  	negativeStr := "-"
  
  	if len(format) > 0 {
  		format := []rune(format)
  
  		// If there is an explicit format directive,
  		// then default values are these:
  		precision = 9
  		thousandStr = ""
  
  		// collect indices of meaningful formatting directives
  		formatIndx := []int{}
  		for i, char := range format {
  			if char != '#' && char != '0' {
  				formatIndx = append(formatIndx, i)
  			}
  		}
  
  		if len(formatIndx) > 0 {
  			// Directive at index 0:
  			//   Must be a '+'
  			//   Raise an error if not the case
  			// index: 0123456789
  			//        +0.000,000
  			//        +000,000.0
  			//        +0000.00
  			//        +0000
  			if formatIndx[0] == 0 {
  				if format[formatIndx[0]] != '+' {
  					panic("RenderFloat(): invalid positive sign directive")
  				}
  				positiveStr = "+"
  				formatIndx = formatIndx[1:]
  			}
  
  			// Two directives:
  			//   First is thousands separator
  			//   Raise an error if not followed by 3-digit
  			// 0123456789
  			// 0.000,000
  			// 000,000.00
  			if len(formatIndx) == 2 {
  				if (formatIndx[1] - formatIndx[0]) != 4 {
  					panic("RenderFloat(): thousands separator directive must be followed by 3 digit-specifiers")
  				}
  				thousandStr = string(format[formatIndx[0]])
  				formatIndx = formatIndx[1:]
  			}
  
  			// One directive:
  			//   Directive is decimal separator
  			//   The number of digit-specifier following the separator indicates wanted precision
  			// 0123456789
  			// 0.00
  			// 000,0000
  			if len(formatIndx) == 1 {
  				decimalStr = string(format[formatIndx[0]])
  				precision = len(format) - formatIndx[0] - 1
  			}
  		}
  	}
  
  	// generate sign part
  	var signStr string
  	if n >= 0.000000001 {
  		signStr = positiveStr
  	} else if n <= -0.000000001 {
  		signStr = negativeStr
  		n = -n
  	} else {
  		signStr = ""
  		n = 0.0
  	}
  
  	// split number into integer and fractional parts
  	intf, fracf := math.Modf(n + renderFloatPrecisionRounders[precision])
  
  	// generate integer part string
  	intStr := strconv.FormatInt(int64(intf), 10)
  
  	// add thousand separator if required
  	if len(thousandStr) > 0 {
  		for i := len(intStr); i > 3; {
  			i -= 3
  			intStr = intStr[:i] + thousandStr + intStr[i:]
  		}
  	}
  
  	// no fractional part, we can leave now
  	if precision == 0 {
  		return signStr + intStr
  	}
  
  	// generate fractional part
  	fracStr := strconv.Itoa(int(fracf * renderFloatPrecisionMultipliers[precision]))
  	// may need padding
  	if len(fracStr) < precision {
  		fracStr = "000000000000000"[:precision-len(fracStr)] + fracStr
  	}
  
  	return signStr + intStr + decimalStr + fracStr
  }
  
  // FormatInteger produces a formatted number as string.
  // See FormatFloat.
  func FormatInteger(format string, n int) string {
  	return FormatFloat(format, float64(n))
  }
  