"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InvalidDecimalNumberError = exports.exponents = void 0;
exports.format = format;
exports.formatEther = formatEther;
exports.formatGwei = formatGwei;
exports.from = from;
exports.fromEther = fromEther;
exports.fromGwei = fromGwei;
const Errors = require("./Errors.js");
exports.exponents = {
    wei: 0,
    gwei: 9,
    szabo: 12,
    finney: 15,
    ether: 18,
};
function format(value, decimals = 0) {
    let display = value.toString();
    const negative = display.startsWith('-');
    if (negative)
        display = display.slice(1);
    display = display.padStart(decimals, '0');
    let [integer, fraction] = [
        display.slice(0, display.length - decimals),
        display.slice(display.length - decimals),
    ];
    fraction = fraction.replace(/(0+)$/, '');
    return `${negative ? '-' : ''}${integer || '0'}${fraction ? `.${fraction}` : ''}`;
}
function formatEther(wei, unit = 'wei') {
    return format(wei, exports.exponents.ether - exports.exponents[unit]);
}
function formatGwei(wei, unit = 'wei') {
    return format(wei, exports.exponents.gwei - exports.exponents[unit]);
}
function from(value, decimals = 0) {
    if (!/^(-?)([0-9]*)\.?([0-9]*)$/.test(value))
        throw new InvalidDecimalNumberError({ value });
    let [integer = '', fraction = '0'] = value.split('.');
    const negative = integer.startsWith('-');
    if (negative)
        integer = integer.slice(1);
    fraction = fraction.replace(/(0+)$/, '');
    if (decimals === 0) {
        if (Math.round(Number(`.${fraction}`)) === 1)
            integer = `${BigInt(integer) + 1n}`;
        fraction = '';
    }
    else if (fraction.length > decimals) {
        const [left, unit, right] = [
            fraction.slice(0, decimals - 1),
            fraction.slice(decimals - 1, decimals),
            fraction.slice(decimals),
        ];
        const rounded = Math.round(Number(`${unit}.${right}`));
        if (rounded > 9)
            fraction = `${BigInt(left) + BigInt(1)}0`.padStart(left.length + 1, '0');
        else
            fraction = `${left}${rounded}`;
        if (fraction.length > decimals) {
            fraction = fraction.slice(1);
            integer = `${BigInt(integer) + 1n}`;
        }
        fraction = fraction.slice(0, decimals);
    }
    else {
        fraction = fraction.padEnd(decimals, '0');
    }
    return BigInt(`${negative ? '-' : ''}${integer}${fraction}`);
}
function fromEther(ether, unit = 'wei') {
    return from(ether, exports.exponents.ether - exports.exponents[unit]);
}
function fromGwei(gwei, unit = 'wei') {
    return from(gwei, exports.exponents.gwei - exports.exponents[unit]);
}
class InvalidDecimalNumberError extends Errors.BaseError {
    constructor({ value }) {
        super(`Value \`${value}\` is not a valid decimal number.`);
        Object.defineProperty(this, "name", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: 'Value.InvalidDecimalNumberError'
        });
    }
}
exports.InvalidDecimalNumberError = InvalidDecimalNumberError;
//# sourceMappingURL=Value.js.map