#!/usr/bin/env node

/*
  @license
	Rollup.js v1.23.1
	Sat, 05 Oct 2019 06:08:56 GMT - commit 53266e6b971fff985b273800d808b17084d5c41b


	https://github.com/rollup/rollup

	Released under the MIT License.
*/
'use strict';

var rollup_js = require('../rollup.js');
var index = require('../shared/index.js');
require('util');
var path = require('path');
var fs = require('fs');
require('acorn');
var events = require('events');
require('module');
var assert = require('assert');

var help = "rollup version __VERSION__\n=====================================\n\nUsage: rollup [options] <entry file>\n\nBasic options:\n\n-c, --config <filename>     Use this config file (if argument is used but value\n                              is unspecified, defaults to rollup.config.js)\n-d, --dir <dirname>         Directory for chunks (if absent, prints to stdout)\n-e, --external <ids>        Comma-separate list of module IDs to exclude\n-f, --format <format>       Type of output (amd, cjs, esm, iife, umd)\n-g, --globals <pairs>       Comma-separate list of `moduleID:Global` pairs\n-h, --help                  Show this help message\n-i, --input <filename>      Input (alternative to <entry file>)\n-m, --sourcemap             Generate sourcemap (`-m inline` for inline map)\n-n, --name <name>           Name for UMD export\n-o, --file <output>         Single output file (if absent, prints to stdout)\n-v, --version               Show version number\n-w, --watch                 Watch files in bundle and rebuild on changes\n--amd.id <id>               ID for AMD module (default is anonymous)\n--amd.define <name>         Function to use in place of `define`\n--assetFileNames <pattern>  Name pattern for emitted assets\n--banner <text>             Code to insert at top of bundle (outside wrapper)\n--chunkFileNames <pattern>  Name pattern for emitted secondary chunks\n--compact                   Minify wrapper code\n--context <variable>        Specify top-level `this` value\n--dynamicImportFunction <name>         Rename the dynamic `import()` function\n--entryFileNames <pattern>  Name pattern for emitted entry chunks\n--environment <values>      Settings passed to config file (see example)\n--no-esModule               Do not add __esModule property\n--exports <mode>            Specify export mode (auto, default, named, none)\n--extend                    Extend global variable defined by --name\n--footer <text>             Code to insert at end of bundle (outside wrapper)\n--no-freeze                 Do not freeze namespace objects\n--no-indent                 Don't indent result\n--no-interop                Do not include interop block\n--inlineDynamicImports      Create single bundle when using dynamic imports\n--intro <text>              Code to insert at top of bundle (inside wrapper)\n--namespaceToStringTag      Create proper `.toString` methods for namespaces\n--noConflict                Generate a noConflict method for UMD globals\n--no-strict                 Don't emit `\"use strict\";` in the generated modules\n--outro <text>              Code to insert at end of bundle (inside wrapper)\n--preferConst               Use `const` instead of `var` for exports\n--preserveModules           Preserve module structure\n--preserveSymlinks          Do not follow symlinks when resolving files\n--shimMissingExports        Create shim variables for missing exports\n--silent                    Don't print warnings\n--sourcemapExcludeSources   Do not include source code in source maps\n--sourcemapFile <file>      Specify bundle position for source maps\n--strictDeprecations        Throw errors for deprecated features\n--no-treeshake              Disable tree-shaking optimisations\n--no-treeshake.annotations  Ignore pure call annotations\n--no-treeshake.propertyReadSideEffects Ignore property access side-effects\n--treeshake.pureExternalModules        Assume side-effect free externals\n\nExamples:\n\n# use settings in config file\nrollup -c\n\n# in config file, process.env.INCLUDE_DEPS === 'true'\n# and process.env.BUILD === 'production'\nrollup -c --environment INCLUDE_DEPS,BUILD:production\n\n# create CommonJS bundle.js from src/main.js\nrollup --format=cjs --file=bundle.js -- src/main.js\n\n# create self-executing IIFE using `window.jQuery`\n# and `window._` as external globals\nrollup -f iife --globals jquery:jQuery,lodash:_ \\\n  -i src/app.js -o build/app.js -m build/app.js.map\n\nNotes:\n\n* When piping to stdout, only inline sourcemaps are permitted\n\nFor more information visit https://rollupjs.org\n";

var minimist = function (args, opts) {
    if (!opts)
        opts = {};
    var flags = { bools: {}, strings: {}, unknownFn: null };
    if (typeof opts['unknown'] === 'function') {
        flags.unknownFn = opts['unknown'];
    }
    if (typeof opts['boolean'] === 'boolean' && opts['boolean']) {
        flags.allBools = true;
    }
    else {
        [].concat(opts['boolean']).filter(Boolean).forEach(function (key) {
            flags.bools[key] = true;
        });
    }
    var aliases = {};
    Object.keys(opts.alias || {}).forEach(function (key) {
        aliases[key] = [].concat(opts.alias[key]);
        aliases[key].forEach(function (x) {
            aliases[x] = [key].concat(aliases[key].filter(function (y) {
                return x !== y;
            }));
        });
    });
    [].concat(opts.string).filter(Boolean).forEach(function (key) {
        flags.strings[key] = true;
        if (aliases[key]) {
            flags.strings[aliases[key]] = true;
        }
    });
    var defaults = opts['default'] || {};
    var argv = { _: [] };
    Object.keys(flags.bools).forEach(function (key) {
        setArg(key, defaults[key] === undefined ? false : defaults[key]);
    });
    var notFlags = [];
    if (args.indexOf('--') !== -1) {
        notFlags = args.slice(args.indexOf('--') + 1);
        args = args.slice(0, args.indexOf('--'));
    }
    function argDefined(key, arg) {
        return (flags.allBools && /^--[^=]+$/.test(arg)) ||
            flags.strings[key] || flags.bools[key] || aliases[key];
    }
    function setArg(key, val, arg) {
        if (arg && flags.unknownFn && !argDefined(key, arg)) {
            if (flags.unknownFn(arg) === false)
                return;
        }
        var value = !flags.strings[key] && isNumber(val)
            ? Number(val) : val;
        setKey(argv, key.split('.'), value);
        (aliases[key] || []).forEach(function (x) {
            setKey(argv, x.split('.'), value);
        });
    }
    function setKey(obj, keys, value) {
        var o = obj;
        keys.slice(0, -1).forEach(function (key) {
            if (o[key] === undefined)
                o[key] = {};
            o = o[key];
        });
        var key = keys[keys.length - 1];
        if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') {
            o[key] = value;
        }
        else if (Array.isArray(o[key])) {
            o[key].push(value);
        }
        else {
            o[key] = [o[key], value];
        }
    }
    function aliasIsBoolean(key) {
        return aliases[key].some(function (x) {
            return flags.bools[x];
        });
    }
    for (var i = 0; i < args.length; i++) {
        var arg = args[i];
        if (/^--.+=/.test(arg)) {
            // Using [\s\S] instead of . because js doesn't support the
            // 'dotall' regex modifier. See:
            // http://stackoverflow.com/a/1068308/13216
            var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
            var key = m[1];
            var value = m[2];
            if (flags.bools[key]) {
                value = value !== 'false';
            }
            setArg(key, value, arg);
        }
        else if (/^--no-.+/.test(arg)) {
            var key = arg.match(/^--no-(.+)/)[1];
            setArg(key, false, arg);
        }
        else if (/^--.+/.test(arg)) {
            var key = arg.match(/^--(.+)/)[1];
            var next = args[i + 1];
            if (next !== undefined && !/^-/.test(next)
                && !flags.bools[key]
                && !flags.allBools
                && (aliases[key] ? !aliasIsBoolean(key) : true)) {
                setArg(key, next, arg);
                i++;
            }
            else if (/^(true|false)$/.test(next)) {
                setArg(key, next === 'true', arg);
                i++;
            }
            else {
                setArg(key, flags.strings[key] ? '' : true, arg);
            }
        }
        else if (/^-[^-]+/.test(arg)) {
            var letters = arg.slice(1, -1).split('');
            var broken = false;
            for (var j = 0; j < letters.length; j++) {
                var next = arg.slice(j + 2);
                if (next === '-') {
                    setArg(letters[j], next, arg);
                    continue;
                }
                if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
                    setArg(letters[j], next.split('=')[1], arg);
                    broken = true;
                    break;
                }
                if (/[A-Za-z]/.test(letters[j])
                    && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
                    setArg(letters[j], next, arg);
                    broken = true;
                    break;
                }
                if (letters[j + 1] && letters[j + 1].match(/\W/)) {
                    setArg(letters[j], arg.slice(j + 2), arg);
                    broken = true;
                    break;
                }
                else {
                    setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg);
                }
            }
            var key = arg.slice(-1)[0];
            if (!broken && key !== '-') {
                if (args[i + 1] && !/^(-|--)[^-]/.test(args[i + 1])
                    && !flags.bools[key]
                    && (aliases[key] ? !aliasIsBoolean(key) : true)) {
                    setArg(key, args[i + 1], arg);
                    i++;
                }
                else if (args[i + 1] && /true|false/.test(args[i + 1])) {
                    setArg(key, args[i + 1] === 'true', arg);
                    i++;
                }
                else {
                    setArg(key, flags.strings[key] ? '' : true, arg);
                }
            }
        }
        else {
            if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
                argv._.push(flags.strings['_'] || !isNumber(arg) ? arg : Number(arg));
            }
            if (opts.stopEarly) {
                argv._.push.apply(argv._, args.slice(i + 1));
                break;
            }
        }
    }
    Object.keys(defaults).forEach(function (key) {
        if (!hasKey(argv, key.split('.'))) {
            setKey(argv, key.split('.'), defaults[key]);
            (aliases[key] || []).forEach(function (x) {
                setKey(argv, x.split('.'), defaults[key]);
            });
        }
    });
    if (opts['--']) {
        argv['--'] = new Array();
        notFlags.forEach(function (key) {
            argv['--'].push(key);
        });
    }
    else {
        notFlags.forEach(function (key) {
            argv._.push(key);
        });
    }
    return argv;
};
function hasKey(obj, keys) {
    var o = obj;
    keys.slice(0, -1).forEach(function (key) {
        o = (o[key] || {});
    });
    var key = keys[keys.length - 1];
    return key in o;
}
function isNumber(x) {
    if (typeof x === 'number')
        return true;
    if (/^0x[0-9a-f]+$/i.test(x))
        return true;
    return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
}

const tc = {
    enabled: process.env.FORCE_COLOR ||
        process.platform === "win32" ||
        (process.stdout.isTTY && process.env.TERM && process.env.TERM !== "dumb")
};
const Styles = (tc.Styles = {});
const defineProp = Object.defineProperty;
const init = (style, open, close, re) => {
    let i, len = 1, seq = [(Styles[style] = { open, close, re })];
    const fn = s => {
        if (tc.enabled) {
            for (i = 0, s += ""; i < len; i++) {
                style = seq[i];
                s =
                    (open = style.open) +
                        (~s.indexOf((close = style.close), 4) // skip first \x1b[
                            ? s.replace(style.re, open)
                            : s) +
                        close;
            }
            len = 1;
        }
        return s;
    };
    defineProp(tc, style, {
        get: () => {
            for (let k in Styles)
                defineProp(fn, k, {
                    get: () => ((seq[len++] = Styles[k]), fn)
                });
            delete tc[style];
            return (tc[style] = fn);
        },
        configurable: true
    });
};
init("reset", "\x1b[0m", "\x1b[0m", /\x1b\[0m/g);
init("bold", "\x1b[1m", "\x1b[22m", /\x1b\[22m/g);
init("dim", "\x1b[2m", "\x1b[22m", /\x1b\[22m/g);
init("italic", "\x1b[3m", "\x1b[23m", /\x1b\[23m/g);
init("underline", "\x1b[4m", "\x1b[24m", /\x1b\[24m/g);
init("inverse", "\x1b[7m", "\x1b[27m", /\x1b\[27m/g);
init("hidden", "\x1b[8m", "\x1b[28m", /\x1b\[28m/g);
init("strikethrough", "\x1b[9m", "\x1b[29m", /\x1b\[29m/g);
init("black", "\x1b[30m", "\x1b[39m", /\x1b\[39m/g);
init("red", "\x1b[31m", "\x1b[39m", /\x1b\[39m/g);
init("green", "\x1b[32m", "\x1b[39m", /\x1b\[39m/g);
init("yellow", "\x1b[33m", "\x1b[39m", /\x1b\[39m/g);
init("blue", "\x1b[34m", "\x1b[39m", /\x1b\[39m/g);
init("magenta", "\x1b[35m", "\x1b[39m", /\x1b\[39m/g);
init("cyan", "\x1b[36m", "\x1b[39m", /\x1b\[39m/g);
init("white", "\x1b[37m", "\x1b[39m", /\x1b\[39m/g);
init("gray", "\x1b[90m", "\x1b[39m", /\x1b\[39m/g);
init("bgBlack", "\x1b[40m", "\x1b[49m", /\x1b\[49m/g);
init("bgRed", "\x1b[41m", "\x1b[49m", /\x1b\[49m/g);
init("bgGreen", "\x1b[42m", "\x1b[49m", /\x1b\[49m/g);
init("bgYellow", "\x1b[43m", "\x1b[49m", /\x1b\[49m/g);
init("bgBlue", "\x1b[44m", "\x1b[49m", /\x1b\[49m/g);
init("bgMagenta", "\x1b[45m", "\x1b[49m", /\x1b\[49m/g);
init("bgCyan", "\x1b[46m", "\x1b[49m", /\x1b\[49m/g);
init("bgWhite", "\x1b[47m", "\x1b[49m", /\x1b\[49m/g);
var turbocolor = tc;

// log to stderr to keep `rollup main.js > bundle.js` from breaking
const stderr = console.error.bind(console);
function handleError(err, recover = false) {
    let description = err.message || err;
    if (err.name)
        description = `${err.name}: ${description}`;
    const message = (err.plugin
        ? `(plugin ${err.plugin}) ${description}`
        : description) || err;
    stderr(turbocolor.bold.red(`[!] ${turbocolor.bold(message.toString())}`));
    if (err.url) {
        stderr(turbocolor.cyan(err.url));
    }
    if (err.loc) {
        stderr(`${index.relativeId((err.loc.file || err.id))} (${err.loc.line}:${err.loc.column})`);
    }
    else if (err.id) {
        stderr(index.relativeId(err.id));
    }
    if (err.frame) {
        stderr(turbocolor.dim(err.frame));
    }
    if (err.stack) {
        stderr(turbocolor.dim(err.stack));
    }
    stderr('');
    if (!recover)
        process.exit(1);
}

function batchWarnings() {
    let allWarnings = new Map();
    let count = 0;
    return {
        get count() {
            return count;
        },
        add: (warning) => {
            if (typeof warning === 'string') {
                warning = { code: 'UNKNOWN', message: warning };
            }
            if (warning.code in immediateHandlers) {
                immediateHandlers[warning.code](warning);
                return;
            }
            if (!allWarnings.has(warning.code))
                allWarnings.set(warning.code, []);
            allWarnings.get(warning.code).push(warning);
            count += 1;
        },
        flush: () => {
            if (count === 0)
                return;
            const codes = Array.from(allWarnings.keys()).sort((a, b) => {
                if (deferredHandlers[a] && deferredHandlers[b]) {
                    return deferredHandlers[a].priority - deferredHandlers[b].priority;
                }
                if (deferredHandlers[a])
                    return -1;
                if (deferredHandlers[b])
                    return 1;
                return (allWarnings.get(b).length -
                    allWarnings.get(a).length);
            });
            codes.forEach(code => {
                const handler = deferredHandlers[code];
                const warnings = allWarnings.get(code);
                if (handler) {
                    handler.fn(warnings);
                }
                else {
                    warnings.forEach(warning => {
                        title(warning.message);
                        if (warning.url)
                            info(warning.url);
                        const id = (warning.loc && warning.loc.file) || warning.id;
                        if (id) {
                            const loc = warning.loc
                                ? `${index.relativeId(id)}: (${warning.loc.line}:${warning.loc.column})`
                                : index.relativeId(id);
                            stderr(turbocolor.bold(index.relativeId(loc)));
                        }
                        if (warning.frame)
                            info(warning.frame);
                    });
                }
            });
            allWarnings = new Map();
            count = 0;
        }
    };
}
const immediateHandlers = {
    UNKNOWN_OPTION: warning => {
        title(`You have passed an unrecognized option`);
        stderr(warning.message);
    },
    MISSING_NODE_BUILTINS: warning => {
        title(`Missing shims for Node.js built-ins`);
        const detail = warning.modules.length === 1
            ? `'${warning.modules[0]}'`
            : `${warning.modules
                .slice(0, -1)
                .map((name) => `'${name}'`)
                .join(', ')} and '${warning.modules.slice(-1)}'`;
        stderr(`Creating a browser bundle that depends on ${detail}. You might need to include https://www.npmjs.com/package/rollup-plugin-node-builtins`);
    },
    MIXED_EXPORTS: () => {
        title('Mixing named and default exports');
        stderr(`Consumers of your bundle will have to use bundle['default'] to access the default export, which may not be what you want. Use \`output.exports: 'named'\` to disable this warning`);
    },
    EMPTY_BUNDLE: () => {
        title(`Generated an empty bundle`);
    }
};
// TODO select sensible priorities
const deferredHandlers = {
    UNUSED_EXTERNAL_IMPORT: {
        fn: warnings => {
            title('Unused external imports');
            warnings.forEach(warning => {
                stderr(`${warning.names} imported from external module '${warning.source}' but never used`);
            });
        },
        priority: 1
    },
    UNRESOLVED_IMPORT: {
        fn: warnings => {
            title('Unresolved dependencies');
            info('https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency');
            const dependencies = new Map();
            warnings.forEach(warning => {
                if (!dependencies.has(warning.source))
                    dependencies.set(warning.source, []);
                dependencies.get(warning.source).push(warning.importer);
            });
            Array.from(dependencies.keys()).forEach(dependency => {
                const importers = dependencies.get(dependency);
                stderr(`${turbocolor.bold(dependency)} (imported by ${importers.join(', ')})`);
            });
        },
        priority: 1
    },
    MISSING_EXPORT: {
        fn: warnings => {
            title('Missing exports');
            info('https://rollupjs.org/guide/en/#error-name-is-not-exported-by-module');
            warnings.forEach(warning => {
                stderr(turbocolor.bold(warning.importer));
                stderr(`${warning.missing} is not exported by ${warning.exporter}`);
                stderr(turbocolor.gray(warning.frame));
            });
        },
        priority: 1
    },
    THIS_IS_UNDEFINED: {
        fn: warnings => {
            title('`this` has been rewritten to `undefined`');
            info('https://rollupjs.org/guide/en/#error-this-is-undefined');
            showTruncatedWarnings(warnings);
        },
        priority: 1
    },
    EVAL: {
        fn: warnings => {
            title('Use of eval is strongly discouraged');
            info('https://rollupjs.org/guide/en/#avoiding-eval');
            showTruncatedWarnings(warnings);
        },
        priority: 1
    },
    NON_EXISTENT_EXPORT: {
        fn: warnings => {
            title(`Import of non-existent ${warnings.length > 1 ? 'exports' : 'export'}`);
            showTruncatedWarnings(warnings);
        },
        priority: 1
    },
    NAMESPACE_CONFLICT: {
        fn: warnings => {
            title(`Conflicting re-exports`);
            warnings.forEach(warning => {
                stderr(`${turbocolor.bold(index.relativeId(warning.reexporter))} re-exports '${warning.name}' from both ${index.relativeId(warning.sources[0])} and ${index.relativeId(warning.sources[1])} (will be ignored)`);
            });
        },
        priority: 1
    },
    MISSING_GLOBAL_NAME: {
        fn: warnings => {
            title(`Missing global variable ${warnings.length > 1 ? 'names' : 'name'}`);
            stderr(`Use output.globals to specify browser global variable names corresponding to external modules`);
            warnings.forEach(warning => {
                stderr(`${turbocolor.bold(warning.source)} (guessing '${warning.guess}')`);
            });
        },
        priority: 1
    },
    SOURCEMAP_BROKEN: {
        fn: warnings => {
            title(`Broken sourcemap`);
            info('https://rollupjs.org/guide/en/#warning-sourcemap-is-likely-to-be-incorrect');
            const plugins = Array.from(new Set(warnings.map(w => w.plugin).filter(Boolean)));
            const detail = plugins.length === 0
                ? ''
                : plugins.length > 1
                    ? ` (such as ${plugins
                        .slice(0, -1)
                        .map(p => `'${p}'`)
                        .join(', ')} and '${plugins.slice(-1)}')`
                    : ` (such as '${plugins[0]}')`;
            stderr(`Plugins that transform code${detail} should generate accompanying sourcemaps`);
        },
        priority: 1
    },
    PLUGIN_WARNING: {
        fn: warnings => {
            const nestedByPlugin = nest(warnings, 'plugin');
            nestedByPlugin.forEach(({ key: plugin, items }) => {
                const nestedByMessage = nest(items, 'message');
                let lastUrl;
                nestedByMessage.forEach(({ key: message, items }) => {
                    title(`Plugin ${plugin}: ${message}`);
                    items.forEach(warning => {
                        if (warning.url !== lastUrl)
                            info((lastUrl = warning.url));
                        if (warning.id) {
                            let loc = index.relativeId(warning.id);
                            if (warning.loc) {
                                loc += `: (${warning.loc.line}:${warning.loc.column})`;
                            }
                            stderr(turbocolor.bold(loc));
                        }
                        if (warning.frame)
                            info(warning.frame);
                    });
                });
            });
        },
        priority: 1
    }
};
function title(str) {
    stderr(`${turbocolor.bold.yellow('(!)')} ${turbocolor.bold.yellow(str)}`);
}
function info(url) {
    stderr(turbocolor.gray(url));
}
function nest(array, prop) {
    const nested = [];
    const lookup = new Map();
    array.forEach(item => {
        const key = item[prop];
        if (!lookup.has(key)) {
            lookup.set(key, {
                items: [],
                key
            });
            nested.push(lookup.get(key));
        }
        lookup.get(key).items.push(item);
    });
    return nested;
}
function showTruncatedWarnings(warnings) {
    const nestedByModule = nest(warnings, 'id');
    const sliced = nestedByModule.length > 5 ? nestedByModule.slice(0, 3) : nestedByModule;
    sliced.forEach(({ key: id, items }) => {
        stderr(turbocolor.bold(index.relativeId(id)));
        stderr(turbocolor.gray(items[0].frame));
        if (items.length > 1) {
            stderr(`...and ${items.length - 1} other ${items.length > 2 ? 'occurrences' : 'occurrence'}`);
        }
    });
    if (nestedByModule.length > sliced.length) {
        stderr(`\n...and ${nestedByModule.length - sliced.length} other files`);
    }
}

var parseMs = milliseconds => {
    if (typeof milliseconds !== 'number') {
        throw new TypeError('Expected a number');
    }
    const roundTowardsZero = milliseconds > 0 ? Math.floor : Math.ceil;
    return {
        days: roundTowardsZero(milliseconds / 86400000),
        hours: roundTowardsZero(milliseconds / 3600000) % 24,
        minutes: roundTowardsZero(milliseconds / 60000) % 60,
        seconds: roundTowardsZero(milliseconds / 1000) % 60,
        milliseconds: roundTowardsZero(milliseconds) % 1000,
        microseconds: roundTowardsZero(milliseconds * 1000) % 1000,
        nanoseconds: roundTowardsZero(milliseconds * 1e6) % 1000
    };
};

const pluralize = (word, count) => count === 1 ? word : word + 's';
var prettyMs = (milliseconds, options = {}) => {
    if (!Number.isFinite(milliseconds)) {
        throw new TypeError('Expected a finite number');
    }
    if (options.compact) {
        options.secondsDecimalDigits = 0;
        options.millisecondsDecimalDigits = 0;
    }
    const result = [];
    const add = (value, long, short, valueString) => {
        if (value === 0) {
            return;
        }
        const postfix = options.verbose ? ' ' + pluralize(long, value) : short;
        result.push((valueString || value) + postfix);
    };
    const secondsDecimalDigits = typeof options.secondsDecimalDigits === 'number' ?
        options.secondsDecimalDigits :
        1;
    if (secondsDecimalDigits < 1) {
        const difference = 1000 - (milliseconds % 1000);
        if (difference < 500) {
            milliseconds += difference;
        }
    }
    const parsed = parseMs(milliseconds);
    add(Math.trunc(parsed.days / 365), 'year', 'y');
    add(parsed.days % 365, 'day', 'd');
    add(parsed.hours, 'hour', 'h');
    add(parsed.minutes, 'minute', 'm');
    if (options.separateMilliseconds ||
        options.formatSubMilliseconds ||
        milliseconds < 1000) {
        add(parsed.seconds, 'second', 's');
        if (options.formatSubMilliseconds) {
            add(parsed.milliseconds, 'millisecond', 'ms');
            add(parsed.microseconds, 'microsecond', 'µs');
            add(parsed.nanoseconds, 'nanosecond', 'ns');
        }
        else {
            const millisecondsAndBelow = parsed.milliseconds +
                (parsed.microseconds / 1000) +
                (parsed.nanoseconds / 1e6);
            const millisecondsDecimalDigits = typeof options.millisecondsDecimalDigits === 'number' ?
                options.millisecondsDecimalDigits :
                0;
            const millisecondsString = millisecondsDecimalDigits ?
                millisecondsAndBelow.toFixed(millisecondsDecimalDigits) :
                Math.ceil(millisecondsAndBelow);
            add(parseFloat(millisecondsString, 10), 'millisecond', 'ms', millisecondsString);
        }
    }
    else {
        const seconds = (milliseconds / 1000) % 60;
        const secondsDecimalDigits = typeof options.secondsDecimalDigits === 'number' ?
            options.secondsDecimalDigits :
            1;
        const secondsFixed = seconds.toFixed(secondsDecimalDigits);
        const secondsString = options.keepDecimalsOnWholeSeconds ?
            secondsFixed :
            secondsFixed.replace(/\.0+$/, '');
        add(parseFloat(secondsString, 10), 'second', 's', secondsString);
    }
    if (result.length === 0) {
        return '0' + (options.verbose ? ' milliseconds' : 'ms');
    }
    if (options.compact) {
        return '~' + result[0];
    }
    if (typeof options.unitCount === 'number') {
        return '~' + result.slice(0, Math.max(options.unitCount, 1)).join(' ');
    }
    return result.join(' ');
};

let SOURCEMAPPING_URL = 'sourceMa';
SOURCEMAPPING_URL += 'ppingURL';
var SOURCEMAPPING_URL$1 = SOURCEMAPPING_URL;

const BYTE_UNITS = [
    'B',
    'kB',
    'MB',
    'GB',
    'TB',
    'PB',
    'EB',
    'ZB',
    'YB'
];
const BIT_UNITS = [
    'b',
    'kbit',
    'Mbit',
    'Gbit',
    'Tbit',
    'Pbit',
    'Ebit',
    'Zbit',
    'Ybit'
];
/*
Formats the given number using `Number#toLocaleString`.
- If locale is a string, the value is expected to be a locale-key (for example: `de`).
- If locale is true, the system default locale is used for translation.
- If no value for locale is specified, the number is returned unmodified.
*/
const toLocaleString = (number, locale) => {
    let result = number;
    if (typeof locale === 'string') {
        result = number.toLocaleString(locale);
    }
    else if (locale === true) {
        result = number.toLocaleString();
    }
    return result;
};
var prettyBytes = (number, options) => {
    if (!Number.isFinite(number)) {
        throw new TypeError(`Expected a finite number, got ${typeof number}: ${number}`);
    }
    options = Object.assign({ bits: false }, options);
    const UNITS = options.bits ? BIT_UNITS : BYTE_UNITS;
    if (options.signed && number === 0) {
        return ' 0 ' + UNITS[0];
    }
    const isNegative = number < 0;
    const prefix = isNegative ? '-' : (options.signed ? '+' : '');
    if (isNegative) {
        number = -number;
    }
    if (number < 1) {
        const numberString = toLocaleString(number, options.locale);
        return prefix + numberString + ' ' + UNITS[0];
    }
    const exponent = Math.min(Math.floor(Math.log10(number) / 3), UNITS.length - 1);
    // eslint-disable-next-line unicorn/prefer-exponentiation-operator
    number = Number((number / Math.pow(1000, exponent)).toPrecision(3));
    const numberString = toLocaleString(number, options.locale);
    const unit = UNITS[exponent];
    return prefix + numberString + ' ' + unit;
};

function printTimings(timings) {
    Object.keys(timings).forEach(label => {
        const color = label[0] === '#' ? (label[1] !== '#' ? turbocolor.underline : turbocolor.bold) : (text) => text;
        const [time, memory, total] = timings[label];
        const row = `${label}: ${time.toFixed(0)}ms, ${prettyBytes(memory)} / ${prettyBytes(total)}`;
        console.info(color(row));
    });
}

function build(inputOptions, outputOptions, warnings, silent = false) {
    const useStdout = !outputOptions[0].file && !outputOptions[0].dir;
    const start = Date.now();
    const files = useStdout
        ? ['stdout']
        : outputOptions.map(t => index.relativeId(t.file || t.dir));
    if (!silent) {
        let inputFiles = undefined;
        if (typeof inputOptions.input === 'string') {
            inputFiles = inputOptions.input;
        }
        else if (inputOptions.input instanceof Array) {
            inputFiles = inputOptions.input.join(', ');
        }
        else if (typeof inputOptions.input === 'object' && inputOptions.input !== null) {
            inputFiles = Object.keys(inputOptions.input)
                .map(name => inputOptions.input[name])
                .join(', ');
        }
        stderr(turbocolor.cyan(`\n${turbocolor.bold(inputFiles)} → ${turbocolor.bold(files.join(', '))}...`));
    }
    return rollup_js.rollup(inputOptions)
        .then((bundle) => {
        if (useStdout) {
            const output = outputOptions[0];
            if (output.sourcemap && output.sourcemap !== 'inline') {
                handleError({
                    code: 'MISSING_OUTPUT_OPTION',
                    message: 'You must specify a --file (-o) option when creating a file with a sourcemap'
                });
            }
            return bundle.generate(output).then(({ output: outputs }) => {
                for (const file of outputs) {
                    let source;
                    if (file.type === 'asset') {
                        source = file.source;
                    }
                    else {
                        source = file.code;
                        if (output.sourcemap === 'inline') {
                            source += `\n//# ${SOURCEMAPPING_URL$1}=${file
                                .map.toUrl()}\n`;
                        }
                    }
                    if (outputs.length > 1)
                        process.stdout.write('\n' + turbocolor.cyan(turbocolor.bold('//→ ' + file.fileName + ':')) + '\n');
                    process.stdout.write(source);
                }
                return null;
            });
        }
        return Promise.all(outputOptions.map(output => bundle.write(output))).then(() => bundle);
    })
        .then((bundle) => {
        if (!silent) {
            warnings.flush();
            stderr(turbocolor.green(`created ${turbocolor.bold(files.join(', '))} in ${turbocolor.bold(prettyMs(Date.now() - start))}`));
            if (bundle && bundle.getTimings) {
                printTimings(bundle.getTimings());
            }
        }
    })
        .catch((err) => {
        if (warnings.count > 0)
            warnings.flush();
        handleError(err);
    });
}

function loadConfigFile(configFile, commandOptions = {}) {
    const silent = commandOptions.silent || false;
    const warnings = batchWarnings();
    return rollup_js.rollup({
        external: (id) => (id[0] !== '.' && !path.isAbsolute(id)) || id.slice(-5, id.length) === '.json',
        input: configFile,
        onwarn: warnings.add,
        treeshake: false
    })
        .then((bundle) => {
        if (!silent && warnings.count > 0) {
            stderr(turbocolor.bold(`loaded ${index.relativeId(configFile)} with warnings`));
            warnings.flush();
        }
        return bundle.generate({
            exports: 'named',
            format: 'cjs'
        });
    })
        .then(({ output: [{ code }] }) => {
        // temporarily override require
        const defaultLoader = require.extensions['.js'];
        require.extensions['.js'] = (module, filename) => {
            if (filename === configFile) {
                module._compile(code, filename);
            }
            else {
                defaultLoader(module, filename);
            }
        };
        delete require.cache[configFile];
        return Promise.resolve(require(configFile))
            .then(configFileContent => {
            if (configFileContent.default)
                configFileContent = configFileContent.default;
            if (typeof configFileContent === 'function') {
                return configFileContent(commandOptions);
            }
            return configFileContent;
        })
            .then(configs => {
            if (Object.keys(configs).length === 0) {
                handleError({
                    code: 'MISSING_CONFIG',
                    message: 'Config file must export an options object, or an array of options objects',
                    url: 'https://rollupjs.org/guide/en/#configuration-files'
                });
            }
            require.extensions['.js'] = defaultLoader;
            return Array.isArray(configs) ? configs : [configs];
        });
    });
}

var timeZone = date => {
    const offset = (date || new Date()).getTimezoneOffset();
    const absOffset = Math.abs(offset);
    const hours = Math.floor(absOffset / 60);
    const minutes = absOffset % 60;
    const minutesOut = minutes > 0 ? ':' + ('0' + minutes).slice(-2) : '';
    return (offset < 0 ? '+' : '-') + hours + minutesOut;
};

const dateTime = options => {
    options = Object.assign({
        date: new Date(),
        local: true,
        showTimeZone: false,
        showMilliseconds: false
    }, options);
    let { date } = options;
    if (options.local) {
        // Offset the date so it will return the correct value when getting the ISO string
        date = new Date(date.getTime() - (date.getTimezoneOffset() * 60000));
    }
    let end = '';
    if (options.showTimeZone) {
        end = ' UTC' + (options.local ? timeZone(date) : '');
    }
    if (options.showMilliseconds && date.getUTCMilliseconds() > 0) {
        end = ` ${date.getUTCMilliseconds()}ms${end}`;
    }
    return date
        .toISOString()
        .replace(/T/, ' ')
        .replace(/\..+/, end);
};
var dateTime_1 = dateTime;
// TODO: Remove this for the next major release
var default_1 = dateTime;
dateTime_1.default = default_1;

var signals = index.createCommonjsModule(function (module) {
    // This is not the set of all possible signals.
    //
    // It IS, however, the set of all signals that trigger
    // an exit on either Linux or BSD systems.  Linux is a
    // superset of the signal names supported on BSD, and
    // the unknown signals just fail to register, so we can
    // catch that easily enough.
    //
    // Don't bother with SIGKILL.  It's uncatchable, which
    // means that we can't fire any callbacks anyway.
    //
    // If a user does happen to register a handler on a non-
    // fatal signal like SIGWINCH or something, and then
    // exit, it'll end up firing `process.emit('exit')`, so
    // the handler will be fired anyway.
    //
    // SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised
    // artificially, inherently leave the process in a
    // state from which it is not safe to try and enter JS
    // listeners.
    module.exports = [
        'SIGABRT',
        'SIGALRM',
        'SIGHUP',
        'SIGINT',
        'SIGTERM'
    ];
    if (process.platform !== 'win32') {
        module.exports.push('SIGVTALRM', 'SIGXCPU', 'SIGXFSZ', 'SIGUSR2', 'SIGTRAP', 'SIGSYS', 'SIGQUIT', 'SIGIOT'
        // should detect profiler and enable/disable accordingly.
        // see #21
        // 'SIGPROF'
        );
    }
    if (process.platform === 'linux') {
        module.exports.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT', 'SIGUNUSED');
    }
});

// Note: since nyc uses this module to output coverage, any lines
// that are in the direct sync flow of nyc's outputCoverage are
// ignored, since we can never get coverage for them.
var signals$1 = signals;
var EE = events;
/* istanbul ignore if */
if (typeof EE !== 'function') {
    EE = EE.EventEmitter;
}
var emitter;
if (process.__signal_exit_emitter__) {
    emitter = process.__signal_exit_emitter__;
}
else {
    emitter = process.__signal_exit_emitter__ = new EE();
    emitter.count = 0;
    emitter.emitted = {};
}
// Because this emitter is a global, we have to check to see if a
// previous version of this library failed to enable infinite listeners.
// I know what you're about to say.  But literally everything about
// signal-exit is a compromise with evil.  Get used to it.
if (!emitter.infinite) {
    emitter.setMaxListeners(Infinity);
    emitter.infinite = true;
}
var signalExit = function (cb, opts) {
    assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler');
    if (loaded === false) {
        load();
    }
    var ev = 'exit';
    if (opts && opts.alwaysLast) {
        ev = 'afterexit';
    }
    var remove = function () {
        emitter.removeListener(ev, cb);
        if (emitter.listeners('exit').length === 0 &&
            emitter.listeners('afterexit').length === 0) {
            unload();
        }
    };
    emitter.on(ev, cb);
    return remove;
};
var unload_1 = unload;
function unload() {
    if (!loaded) {
        return;
    }
    loaded = false;
    signals$1.forEach(function (sig) {
        try {
            process.removeListener(sig, sigListeners[sig]);
        }
        catch (er) { }
    });
    process.emit = originalProcessEmit;
    process.reallyExit = originalProcessReallyExit;
    emitter.count -= 1;
}
function emit(event, code, signal) {
    if (emitter.emitted[event]) {
        return;
    }
    emitter.emitted[event] = true;
    emitter.emit(event, code, signal);
}
// { <signal>: <listener fn>, ... }
var sigListeners = {};
signals$1.forEach(function (sig) {
    sigListeners[sig] = function listener() {
        // If there are no other listeners, an exit is coming!
        // Simplest way: remove us and then re-send the signal.
        // We know that this will kill the process, so we can
        // safely emit now.
        var listeners = process.listeners(sig);
        if (listeners.length === emitter.count) {
            unload();
            emit('exit', null, sig);
            /* istanbul ignore next */
            emit('afterexit', null, sig);
            /* istanbul ignore next */
            process.kill(process.pid, sig);
        }
    };
});
var signals_1 = function () {
    return signals$1;
};
var load_1 = load;
var loaded = false;
function load() {
    if (loaded) {
        return;
    }
    loaded = true;
    // This is the number of onSignalExit's that are in play.
    // It's important so that we can count the correct number of
    // listeners on signals, and don't wait for the other one to
    // handle it instead of us.
    emitter.count += 1;
    signals$1 = signals$1.filter(function (sig) {
        try {
            process.on(sig, sigListeners[sig]);
            return true;
        }
        catch (er) {
            return false;
        }
    });
    process.emit = processEmit;
    process.reallyExit = processReallyExit;
}
var originalProcessReallyExit = process.reallyExit;
function processReallyExit(code) {
    process.exitCode = code || 0;
    emit('exit', process.exitCode, null);
    /* istanbul ignore next */
    emit('afterexit', process.exitCode, null);
    /* istanbul ignore next */
    originalProcessReallyExit.call(process, process.exitCode);
}
var originalProcessEmit = process.emit;
function processEmit(ev, arg) {
    if (ev === 'exit') {
        if (arg !== undefined) {
            process.exitCode = arg;
        }
        var ret = originalProcessEmit.apply(this, arguments);
        emit('exit', process.exitCode, null);
        /* istanbul ignore next */
        emit('afterexit', process.exitCode, null);
        return ret;
    }
    else {
        return originalProcessEmit.apply(this, arguments);
    }
}
signalExit.unload = unload_1;
signalExit.signals = signals_1;
signalExit.load = load_1;

const CLEAR_SCREEN = '\u001Bc';
function getResetScreen(clearScreen) {
    if (clearScreen) {
        return (heading) => stderr(CLEAR_SCREEN + heading);
    }
    let firstRun = true;
    return (heading) => {
        if (firstRun) {
            stderr(heading);
            firstRun = false;
        }
    };
}

function watch(configFile, configs, command, silent = false) {
    const isTTY = Boolean(process.stderr.isTTY);
    const warnings = batchWarnings();
    const initialConfigs = processConfigs(configs);
    const clearScreen = initialConfigs.every(config => config.watch.clearScreen !== false);
    const resetScreen = getResetScreen(isTTY && clearScreen);
    let watcher;
    let configWatcher;
    function processConfigs(configs) {
        return configs.map(options => {
            const merged = index.mergeOptions({
                command,
                config: options,
                defaultOnWarnHandler: warnings.add
            });
            const result = Object.assign(Object.assign({}, merged.inputOptions), { output: merged.outputOptions });
            if (!result.watch)
                result.watch = {};
            if (merged.optionError)
                merged.inputOptions.onwarn({
                    code: 'UNKNOWN_OPTION',
                    message: merged.optionError
                });
            return result;
        });
    }
    function start(configs) {
        watcher = rollup_js.watch(configs);
        watcher.on('event', (event) => {
            switch (event.code) {
                case 'FATAL':
                    handleError(event.error, true);
                    process.exit(1);
                    break;
                case 'ERROR':
                    warnings.flush();
                    handleError(event.error, true);
                    break;
                case 'START':
                    if (!silent) {
                        resetScreen(turbocolor.underline(`rollup v${index.version}`));
                    }
                    break;
                case 'BUNDLE_START':
                    if (!silent) {
                        let input = event.input;
                        if (typeof input !== 'string') {
                            input = Array.isArray(input)
                                ? input.join(', ')
                                : Object.keys(input)
                                    .map(key => input[key])
                                    .join(', ');
                        }
                        stderr(turbocolor.cyan(`bundles ${turbocolor.bold(input)} → ${turbocolor.bold(event.output.map(index.relativeId).join(', '))}...`));
                    }
                    break;
                case 'BUNDLE_END':
                    warnings.flush();
                    if (!silent)
                        stderr(turbocolor.green(`created ${turbocolor.bold(event.output.map(index.relativeId).join(', '))} in ${turbocolor.bold(prettyMs(event.duration))}`));
                    if (event.result && event.result.getTimings) {
                        printTimings(event.result.getTimings());
                    }
                    break;
                case 'END':
                    if (!silent && isTTY) {
                        stderr(`\n[${dateTime_1()}] waiting for changes...`);
                    }
            }
        });
    }
    // catch ctrl+c, kill, and uncaught errors
    const removeOnExit = signalExit(close);
    process.on('uncaughtException', close);
    // only listen to stdin if it is a pipe
    if (!process.stdin.isTTY) {
        process.stdin.on('end', close); // in case we ever support stdin!
    }
    function close(err) {
        removeOnExit();
        process.removeListener('uncaughtException', close);
        // removing a non-existent listener is a no-op
        process.stdin.removeListener('end', close);
        if (watcher)
            watcher.close();
        if (configWatcher)
            configWatcher.close();
        if (err) {
            console.error(err);
            process.exit(1);
        }
    }
    try {
        start(initialConfigs);
    }
    catch (err) {
        close(err);
        return;
    }
    if (configFile && !configFile.startsWith('node:')) {
        let restarting = false;
        let aborted = false;
        let configFileData = fs.readFileSync(configFile, 'utf-8');
        const restart = () => {
            const newConfigFileData = fs.readFileSync(configFile, 'utf-8');
            if (newConfigFileData === configFileData)
                return;
            configFileData = newConfigFileData;
            if (restarting) {
                aborted = true;
                return;
            }
            restarting = true;
            loadConfigFile(configFile, command)
                .then(() => {
                restarting = false;
                if (aborted) {
                    aborted = false;
                    restart();
                }
                else {
                    watcher.close();
                    start(initialConfigs);
                }
            })
                .catch((err) => {
                handleError(err, true);
            });
        };
        configWatcher = fs.watch(configFile, (event) => {
            if (event === 'change')
                restart();
        });
    }
}

function runRollup(command) {
    let inputSource;
    if (command._.length > 0) {
        if (command.input) {
            handleError({
                code: 'DUPLICATE_IMPORT_OPTIONS',
                message: 'use --input, or pass input path as argument'
            });
        }
        inputSource = command._;
    }
    else if (typeof command.input === 'string') {
        inputSource = [command.input];
    }
    else {
        inputSource = command.input;
    }
    if (inputSource && inputSource.length > 0) {
        if (inputSource.some((input) => input.indexOf('=') !== -1)) {
            command.input = {};
            inputSource.forEach((input) => {
                const equalsIndex = input.indexOf('=');
                const value = input.substr(equalsIndex + 1);
                let key = input.substr(0, equalsIndex);
                if (!key)
                    key = index.getAliasName(input);
                command.input[key] = value;
            });
        }
        else {
            command.input = inputSource;
        }
    }
    if (command.environment) {
        const environment = Array.isArray(command.environment)
            ? command.environment
            : [command.environment];
        environment.forEach((arg) => {
            arg.split(',').forEach((pair) => {
                const [key, value] = pair.split(':');
                if (value) {
                    process.env[key] = value;
                }
                else {
                    process.env[key] = String(true);
                }
            });
        });
    }
    let configFile = command.config === true ? 'rollup.config.js' : command.config;
    if (configFile) {
        if (configFile.slice(0, 5) === 'node:') {
            const pkgName = configFile.slice(5);
            try {
                configFile = index.relative.resolve(`rollup-config-${pkgName}`, process.cwd());
            }
            catch (err) {
                try {
                    configFile = index.relative.resolve(pkgName, process.cwd());
                }
                catch (err) {
                    if (err.code === 'MODULE_NOT_FOUND') {
                        handleError({
                            code: 'MISSING_EXTERNAL_CONFIG',
                            message: `Could not resolve config file ${configFile}`
                        });
                    }
                    throw err;
                }
            }
        }
        else {
            // find real path of config so it matches what Node provides to callbacks in require.extensions
            configFile = fs.realpathSync(configFile);
        }
        if (command.watch)
            process.env.ROLLUP_WATCH = 'true';
        loadConfigFile(configFile, command)
            .then(configs => execute(configFile, configs, command))
            .catch(handleError);
    }
    else {
        return execute(configFile, [{ input: null }], command);
    }
}
function execute(configFile, configs, command) {
    if (command.watch) {
        watch(configFile, configs, command, command.silent);
    }
    else {
        let promise = Promise.resolve();
        for (const config of configs) {
            promise = promise.then(() => {
                const warnings = batchWarnings();
                const { inputOptions, outputOptions, optionError } = index.mergeOptions({
                    command,
                    config,
                    defaultOnWarnHandler: warnings.add
                });
                if (optionError)
                    inputOptions.onwarn({ code: 'UNKNOWN_OPTION', message: optionError });
                return build(inputOptions, outputOptions, warnings, command.silent);
            });
        }
        return promise;
    }
}

const command = minimist(process.argv.slice(2), {
    alias: index.commandAliases
});
if (command.help || (process.argv.length <= 2 && process.stdin.isTTY)) {
    console.log(`\n${help.replace('__VERSION__', index.version)}\n`);
}
else if (command.version) {
    console.log(`rollup v${index.version}`);
}
else {
    try {
        require('source-map-support').install();
    }
    catch (err) {
        // do nothing
    }
    runRollup(command);
}
//# sourceMappingURL=rollup.map
