{"version":3,"sources":["../src/index.ts","../src/units.ts"],"sourcesContent":["import Big from 'big.js';\nimport { getUnit, addUnit, setDisplay } from './units';\nimport type { Unit, DisplayFormat } from './units';\n\nclass BitcoinUnit {\n  protected value: Big;\n  protected unit: Unit;\n\n  constructor(value: number, unitName: string) {\n    try {\n      this.value = Big(value);\n    } catch (error) {\n      this.value = Big(0);\n    }\n\n    this.unit = getUnit(unitName);\n  }\n\n  to(toUnitName: string): BitcoinUnit {\n    const toUnit = getUnit(toUnitName);\n\n    this.value = this.value.times(this.unit.value).div(toUnit.value);\n\n    this.unit = getUnit(toUnitName);\n\n    return this;\n  }\n\n  getValue(): number {\n    return this.value.toNumber();\n  }\n\n  getValueAsString(): string {\n    return this.value.toFixed(this.unit.display.fractionDigits);\n  }\n\n  toString(): string {\n    return this.getValueAsString();\n  }\n\n  format(): string {\n    const { format, fractionDigits, trailingZeros } = this.unit.display;\n\n    let valueString: string;\n\n    const addThousandSeparator = (s: string) => s.replace(/\\B(?<!\\.\\d*)(?=(\\d{3})+(?!\\d))/g, ',');\n\n    const removeTrailingZeros = (s: string) => s.replace(/^(\\d+\\.\\d*?[1-9])0+$/g, '$1');\n\n    valueString = this.value.toFixed(fractionDigits, Big.roundDown);\n\n    if (!trailingZeros) {\n      valueString = removeTrailingZeros(valueString);\n    }\n\n    valueString = addThousandSeparator(valueString);\n\n    return format.replace('{amount}', valueString);\n  }\n\n  static setDisplay(unitName: string, options: Partial<DisplayFormat>) {\n    setDisplay(unitName, options);\n\n    return this;\n  }\n\n  static addUnit(name: string, value: number, display?: Partial<DisplayFormat>, aliases?: string[]) {\n    return addUnit(name, value, display, aliases);\n  }\n\n  static getUnit(name: string) {\n    return getUnit(name);\n  }\n\n  static setFiat(currency: string, rate: number, display?: Partial<DisplayFormat>) {\n    return BitcoinUnit.addUnit(currency, 1 / rate, display);\n  }\n}\n\nexport { BitcoinUnit, Unit, DisplayFormat, addUnit, setDisplay, getUnit };\n","import Big from 'big.js';\n\ntype DisplayFormat = {\n  format: string;\n  fractionDigits: number;\n  trailingZeros: boolean;\n};\n\nconst displayFormatDefaults = (display?: Partial<DisplayFormat>): DisplayFormat => {\n  return {\n    format: display?.format ?? '',\n    fractionDigits: display?.fractionDigits ?? 0,\n    trailingZeros: display?.trailingZeros ?? false,\n  };\n};\n\nclass Unit {\n  public name: string;\n  public aliases: string[];\n  public value: Big;\n  public display: DisplayFormat;\n\n  constructor(name: string, value: number | Big, display?: Partial<DisplayFormat>, aliases?: string[]) {\n    this.name = name;\n    this.display = displayFormatDefaults(display);\n    this.aliases = aliases ? aliases : [];\n\n    if (value instanceof Big) {\n      this.value = value;\n    } else {\n      this.value = Big(value);\n    }\n  }\n\n  setDisplay(display: DisplayFormat) {\n    this.display = display;\n  }\n}\n\nconst units: Unit[] = [\n  new Unit(\n    'btc',\n    1,\n    {\n      format: '{amount} BTC',\n      fractionDigits: 8,\n      trailingZeros: true,\n    },\n    ['bitcoin'],\n  ),\n\n  new Unit(\n    'mbtc',\n    1 / 1e3,\n    {\n      format: '{amount} mBTC',\n      fractionDigits: 5,\n      trailingZeros: true,\n    },\n    ['millibtc'],\n  ),\n  new Unit(\n    'bit',\n    1 / 1e6,\n    {\n      format: '{amount} μBTC',\n      fractionDigits: 2,\n      trailingZeros: true,\n    },\n    ['microbtc'],\n  ),\n\n  new Unit(\n    'sats',\n    1 / 1e8,\n    {\n      format: '{amount} satoshis',\n      fractionDigits: 0,\n      trailingZeros: false,\n    },\n    ['sat', 'satoshis', 'satoshi'],\n  ),\n];\n\nlet unitsMap: Map<string, Unit>;\n\nconst setUnitsMap = () => {\n  unitsMap = new Map();\n\n  units.forEach((unit) => {\n    unitsMap.set(unit.name, unit);\n\n    unit.aliases.forEach((alias) => {\n      unitsMap.set(alias, unit);\n    });\n  });\n};\n\nsetUnitsMap();\n\nconst getUnit = (name: string) => {\n  const unit = unitsMap.get(name.toLowerCase());\n\n  if (!unit) {\n    throw new Error(`Invalid unit: ${name}`);\n  }\n\n  return unit;\n};\n\nconst addUnit = (name: string, value: number, display?: Partial<DisplayFormat>, aliases?: string[]) => {\n  const unit = new Unit(name, value, display, aliases);\n\n  units.push(unit);\n\n  setUnitsMap();\n};\n\nconst setDisplay = (unitName: string, display: Partial<DisplayFormat>) => {\n  const unit = getUnit(unitName);\n\n  unit.display = displayFormatDefaults(display);\n};\n\nexport { Unit, DisplayFormat, setDisplay, getUnit, addUnit };\n"],"mappings":"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","names":["Big","Unit","Big"]}