UNPKG

appbir

Version:

常用脚手架库 -【app-lib-cli】

7,924 lines 240 kB
(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory(require("app-lib-nobuild"), require("child_process"), require("events"), require("fs"), require("os"), require("path"), require("process"), require("readline"));
	else if(typeof define === 'function' && define.amd)
		define(["app-lib-nobuild", "child_process", "events", "fs", "os", "path", "process", "readline"], factory);
	else {
		var a = typeof exports === 'object' ? factory(require("app-lib-nobuild"), require("child_process"), require("events"), require("fs"), require("os"), require("path"), require("process"), require("readline")) : factory(root["app-lib-nobuild"], root["child_process"], root["events"], root["fs"], root["os"], root["path"], root["process"], root["readline"]);
		for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
	}
})(this, (__WEBPACK_EXTERNAL_MODULE__305__, __WEBPACK_EXTERNAL_MODULE__198__, __WEBPACK_EXTERNAL_MODULE__735__, __WEBPACK_EXTERNAL_MODULE__89__, __WEBPACK_EXTERNAL_MODULE__44__, __WEBPACK_EXTERNAL_MODULE__56__, __WEBPACK_EXTERNAL_MODULE__910__, __WEBPACK_EXTERNAL_MODULE__908__) => {
return /******/ (() => { // webpackBootstrap
/******/ 	var __webpack_modules__ = ({

/***/ 491:
/***/ ((module, exports, __webpack_require__) => {

const { Argument } = __webpack_require__(811);
const { Command } = __webpack_require__(527);
const { CommanderError, InvalidArgumentError } = __webpack_require__(831);
const { Help } = __webpack_require__(437);
const { Option } = __webpack_require__(311);

// @ts-check

/**
 * Expose the root command.
 */

exports = module.exports = new Command();
exports.program = exports; // More explicit access to global command.
// Implicit export of createArgument, createCommand, and createOption.

/**
 * Expose classes
 */

exports.Argument = Argument;
exports.Command = Command;
exports.CommanderError = CommanderError;
exports.Help = Help;
exports.InvalidArgumentError = InvalidArgumentError;
exports.InvalidOptionArgumentError = InvalidArgumentError; // Deprecated
exports.Option = Option;


/***/ }),

/***/ 811:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {

const { InvalidArgumentError } = __webpack_require__(831);

// @ts-check

class Argument {
  /**
   * Initialize a new command argument with the given name and description.
   * The default is that the argument is required, and you can explicitly
   * indicate this with <> around the name. Put [] around the name for an optional argument.
   *
   * @param {string} name
   * @param {string} [description]
   */

  constructor(name, description) {
    this.description = description || '';
    this.variadic = false;
    this.parseArg = undefined;
    this.defaultValue = undefined;
    this.defaultValueDescription = undefined;
    this.argChoices = undefined;

    switch (name[0]) {
      case '<': // e.g. <required>
        this.required = true;
        this._name = name.slice(1, -1);
        break;
      case '[': // e.g. [optional]
        this.required = false;
        this._name = name.slice(1, -1);
        break;
      default:
        this.required = true;
        this._name = name;
        break;
    }

    if (this._name.length > 3 && this._name.slice(-3) === '...') {
      this.variadic = true;
      this._name = this._name.slice(0, -3);
    }
  }

  /**
   * Return argument name.
   *
   * @return {string}
   */

  name() {
    return this._name;
  }

  /**
   * @api private
   */

  _concatValue(value, previous) {
    if (previous === this.defaultValue || !Array.isArray(previous)) {
      return [value];
    }

    return previous.concat(value);
  }

  /**
   * Set the default value, and optionally supply the description to be displayed in the help.
   *
   * @param {any} value
   * @param {string} [description]
   * @return {Argument}
   */

  default(value, description) {
    this.defaultValue = value;
    this.defaultValueDescription = description;
    return this;
  }

  /**
   * Set the custom handler for processing CLI command arguments into argument values.
   *
   * @param {Function} [fn]
   * @return {Argument}
   */

  argParser(fn) {
    this.parseArg = fn;
    return this;
  }

  /**
   * Only allow argument value to be one of choices.
   *
   * @param {string[]} values
   * @return {Argument}
   */

  choices(values) {
    this.argChoices = values.slice();
    this.parseArg = (arg, previous) => {
      if (!this.argChoices.includes(arg)) {
        throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(', ')}.`);
      }
      if (this.variadic) {
        return this._concatValue(arg, previous);
      }
      return arg;
    };
    return this;
  }

  /**
   * Make argument required.
   */
  argRequired() {
    this.required = true;
    return this;
  }

  /**
   * Make argument optional.
   */
  argOptional() {
    this.required = false;
    return this;
  }
}

/**
 * Takes an argument and returns its human readable equivalent for help usage.
 *
 * @param {Argument} arg
 * @return {string}
 * @api private
 */

function humanReadableArgName(arg) {
  const nameOutput = arg.name() + (arg.variadic === true ? '...' : '');

  return arg.required
    ? '<' + nameOutput + '>'
    : '[' + nameOutput + ']';
}

exports.Argument = Argument;
exports.humanReadableArgName = humanReadableArgName;


/***/ }),

/***/ 527:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {

const EventEmitter = (__webpack_require__(735).EventEmitter);
const childProcess = __webpack_require__(198);
const path = __webpack_require__(56);
const fs = __webpack_require__(89);
const process = __webpack_require__(910);

const { Argument, humanReadableArgName } = __webpack_require__(811);
const { CommanderError } = __webpack_require__(831);
const { Help } = __webpack_require__(437);
const { Option, splitOptionFlags, DualOptions } = __webpack_require__(311);
const { suggestSimilar } = __webpack_require__(426);

// @ts-check

class Command extends EventEmitter {
  /**
   * Initialize a new `Command`.
   *
   * @param {string} [name]
   */

  constructor(name) {
    super();
    /** @type {Command[]} */
    this.commands = [];
    /** @type {Option[]} */
    this.options = [];
    this.parent = null;
    this._allowUnknownOption = false;
    this._allowExcessArguments = true;
    /** @type {Argument[]} */
    this._args = [];
    /** @type {string[]} */
    this.args = []; // cli args with options removed
    this.rawArgs = [];
    this.processedArgs = []; // like .args but after custom processing and collecting variadic
    this._scriptPath = null;
    this._name = name || '';
    this._optionValues = {};
    this._optionValueSources = {}; // default, env, cli etc
    this._storeOptionsAsProperties = false;
    this._actionHandler = null;
    this._executableHandler = false;
    this._executableFile = null; // custom name for executable
    this._executableDir = null; // custom search directory for subcommands
    this._defaultCommandName = null;
    this._exitCallback = null;
    this._aliases = [];
    this._combineFlagAndOptionalValue = true;
    this._description = '';
    this._summary = '';
    this._argsDescription = undefined; // legacy
    this._enablePositionalOptions = false;
    this._passThroughOptions = false;
    this._lifeCycleHooks = {}; // a hash of arrays
    /** @type {boolean | string} */
    this._showHelpAfterError = false;
    this._showSuggestionAfterError = true;

    // see .configureOutput() for docs
    this._outputConfiguration = {
      writeOut: (str) => process.stdout.write(str),
      writeErr: (str) => process.stderr.write(str),
      getOutHelpWidth: () => process.stdout.isTTY ? process.stdout.columns : undefined,
      getErrHelpWidth: () => process.stderr.isTTY ? process.stderr.columns : undefined,
      outputError: (str, write) => write(str)
    };

    this._hidden = false;
    this._hasHelpOption = true;
    this._helpFlags = '-h, --help';
    this._helpDescription = 'display help for command';
    this._helpShortFlag = '-h';
    this._helpLongFlag = '--help';
    this._addImplicitHelpCommand = undefined; // Deliberately undefined, not decided whether true or false
    this._helpCommandName = 'help';
    this._helpCommandnameAndArgs = 'help [command]';
    this._helpCommandDescription = 'display help for command';
    this._helpConfiguration = {};
  }

  /**
   * Copy settings that are useful to have in common across root command and subcommands.
   *
   * (Used internally when adding a command using `.command()` so subcommands inherit parent settings.)
   *
   * @param {Command} sourceCommand
   * @return {Command} `this` command for chaining
   */
  copyInheritedSettings(sourceCommand) {
    this._outputConfiguration = sourceCommand._outputConfiguration;
    this._hasHelpOption = sourceCommand._hasHelpOption;
    this._helpFlags = sourceCommand._helpFlags;
    this._helpDescription = sourceCommand._helpDescription;
    this._helpShortFlag = sourceCommand._helpShortFlag;
    this._helpLongFlag = sourceCommand._helpLongFlag;
    this._helpCommandName = sourceCommand._helpCommandName;
    this._helpCommandnameAndArgs = sourceCommand._helpCommandnameAndArgs;
    this._helpCommandDescription = sourceCommand._helpCommandDescription;
    this._helpConfiguration = sourceCommand._helpConfiguration;
    this._exitCallback = sourceCommand._exitCallback;
    this._storeOptionsAsProperties = sourceCommand._storeOptionsAsProperties;
    this._combineFlagAndOptionalValue = sourceCommand._combineFlagAndOptionalValue;
    this._allowExcessArguments = sourceCommand._allowExcessArguments;
    this._enablePositionalOptions = sourceCommand._enablePositionalOptions;
    this._showHelpAfterError = sourceCommand._showHelpAfterError;
    this._showSuggestionAfterError = sourceCommand._showSuggestionAfterError;

    return this;
  }

  /**
   * Define a command.
   *
   * There are two styles of command: pay attention to where to put the description.
   *
   * @example
   * // Command implemented using action handler (description is supplied separately to `.command`)
   * program
   *   .command('clone <source> [destination]')
   *   .description('clone a repository into a newly created directory')
   *   .action((source, destination) => {
   *     console.log('clone command called');
   *   });
   *
   * // Command implemented using separate executable file (description is second parameter to `.command`)
   * program
   *   .command('start <service>', 'start named service')
   *   .command('stop [service]', 'stop named service, or all if no name supplied');
   *
   * @param {string} nameAndArgs - command name and arguments, args are `<required>` or `[optional]` and last may also be `variadic...`
   * @param {Object|string} [actionOptsOrExecDesc] - configuration options (for action), or description (for executable)
   * @param {Object} [execOpts] - configuration options (for executable)
   * @return {Command} returns new command for action handler, or `this` for executable command
   */

  command(nameAndArgs, actionOptsOrExecDesc, execOpts) {
    let desc = actionOptsOrExecDesc;
    let opts = execOpts;
    if (typeof desc === 'object' && desc !== null) {
      opts = desc;
      desc = null;
    }
    opts = opts || {};
    const [, name, args] = nameAndArgs.match(/([^ ]+) *(.*)/);

    const cmd = this.createCommand(name);
    if (desc) {
      cmd.description(desc);
      cmd._executableHandler = true;
    }
    if (opts.isDefault) this._defaultCommandName = cmd._name;
    cmd._hidden = !!(opts.noHelp || opts.hidden); // noHelp is deprecated old name for hidden
    cmd._executableFile = opts.executableFile || null; // Custom name for executable file, set missing to null to match constructor
    if (args) cmd.arguments(args);
    this.commands.push(cmd);
    cmd.parent = this;
    cmd.copyInheritedSettings(this);

    if (desc) return this;
    return cmd;
  }

  /**
   * Factory routine to create a new unattached command.
   *
   * See .command() for creating an attached subcommand, which uses this routine to
   * create the command. You can override createCommand to customise subcommands.
   *
   * @param {string} [name]
   * @return {Command} new command
   */

  createCommand(name) {
    return new Command(name);
  }

  /**
   * You can customise the help with a subclass of Help by overriding createHelp,
   * or by overriding Help properties using configureHelp().
   *
   * @return {Help}
   */

  createHelp() {
    return Object.assign(new Help(), this.configureHelp());
  }

  /**
   * You can customise the help by overriding Help properties using configureHelp(),
   * or with a subclass of Help by overriding createHelp().
   *
   * @param {Object} [configuration] - configuration options
   * @return {Command|Object} `this` command for chaining, or stored configuration
   */

  configureHelp(configuration) {
    if (configuration === undefined) return this._helpConfiguration;

    this._helpConfiguration = configuration;
    return this;
  }

  /**
   * The default output goes to stdout and stderr. You can customise this for special
   * applications. You can also customise the display of errors by overriding outputError.
   *
   * The configuration properties are all functions:
   *
   *     // functions to change where being written, stdout and stderr
   *     writeOut(str)
   *     writeErr(str)
   *     // matching functions to specify width for wrapping help
   *     getOutHelpWidth()
   *     getErrHelpWidth()
   *     // functions based on what is being written out
   *     outputError(str, write) // used for displaying errors, and not used for displaying help
   *
   * @param {Object} [configuration] - configuration options
   * @return {Command|Object} `this` command for chaining, or stored configuration
   */

  configureOutput(configuration) {
    if (configuration === undefined) return this._outputConfiguration;

    Object.assign(this._outputConfiguration, configuration);
    return this;
  }

  /**
   * Display the help or a custom message after an error occurs.
   *
   * @param {boolean|string} [displayHelp]
   * @return {Command} `this` command for chaining
   */
  showHelpAfterError(displayHelp = true) {
    if (typeof displayHelp !== 'string') displayHelp = !!displayHelp;
    this._showHelpAfterError = displayHelp;
    return this;
  }

  /**
   * Display suggestion of similar commands for unknown commands, or options for unknown options.
   *
   * @param {boolean} [displaySuggestion]
   * @return {Command} `this` command for chaining
   */
  showSuggestionAfterError(displaySuggestion = true) {
    this._showSuggestionAfterError = !!displaySuggestion;
    return this;
  }

  /**
   * Add a prepared subcommand.
   *
   * See .command() for creating an attached subcommand which inherits settings from its parent.
   *
   * @param {Command} cmd - new subcommand
   * @param {Object} [opts] - configuration options
   * @return {Command} `this` command for chaining
   */

  addCommand(cmd, opts) {
    if (!cmd._name) {
      throw new Error(`Command passed to .addCommand() must have a name
- specify the name in Command constructor or using .name()`);
    }

    opts = opts || {};
    if (opts.isDefault) this._defaultCommandName = cmd._name;
    if (opts.noHelp || opts.hidden) cmd._hidden = true; // modifying passed command due to existing implementation

    this.commands.push(cmd);
    cmd.parent = this;
    return this;
  }

  /**
   * Factory routine to create a new unattached argument.
   *
   * See .argument() for creating an attached argument, which uses this routine to
   * create the argument. You can override createArgument to return a custom argument.
   *
   * @param {string} name
   * @param {string} [description]
   * @return {Argument} new argument
   */

  createArgument(name, description) {
    return new Argument(name, description);
  }

  /**
   * Define argument syntax for command.
   *
   * The default is that the argument is required, and you can explicitly
   * indicate this with <> around the name. Put [] around the name for an optional argument.
   *
   * @example
   * program.argument('<input-file>');
   * program.argument('[output-file]');
   *
   * @param {string} name
   * @param {string} [description]
   * @param {Function|*} [fn] - custom argument processing function
   * @param {*} [defaultValue]
   * @return {Command} `this` command for chaining
   */
  argument(name, description, fn, defaultValue) {
    const argument = this.createArgument(name, description);
    if (typeof fn === 'function') {
      argument.default(defaultValue).argParser(fn);
    } else {
      argument.default(fn);
    }
    this.addArgument(argument);
    return this;
  }

  /**
   * Define argument syntax for command, adding multiple at once (without descriptions).
   *
   * See also .argument().
   *
   * @example
   * program.arguments('<cmd> [env]');
   *
   * @param {string} names
   * @return {Command} `this` command for chaining
   */

  arguments(names) {
    names.split(/ +/).forEach((detail) => {
      this.argument(detail);
    });
    return this;
  }

  /**
   * Define argument syntax for command, adding a prepared argument.
   *
   * @param {Argument} argument
   * @return {Command} `this` command for chaining
   */
  addArgument(argument) {
    const previousArgument = this._args.slice(-1)[0];
    if (previousArgument && previousArgument.variadic) {
      throw new Error(`only the last argument can be variadic '${previousArgument.name()}'`);
    }
    if (argument.required && argument.defaultValue !== undefined && argument.parseArg === undefined) {
      throw new Error(`a default value for a required argument is never used: '${argument.name()}'`);
    }
    this._args.push(argument);
    return this;
  }

  /**
   * Override default decision whether to add implicit help command.
   *
   *    addHelpCommand() // force on
   *    addHelpCommand(false); // force off
   *    addHelpCommand('help [cmd]', 'display help for [cmd]'); // force on with custom details
   *
   * @return {Command} `this` command for chaining
   */

  addHelpCommand(enableOrNameAndArgs, description) {
    if (enableOrNameAndArgs === false) {
      this._addImplicitHelpCommand = false;
    } else {
      this._addImplicitHelpCommand = true;
      if (typeof enableOrNameAndArgs === 'string') {
        this._helpCommandName = enableOrNameAndArgs.split(' ')[0];
        this._helpCommandnameAndArgs = enableOrNameAndArgs;
      }
      this._helpCommandDescription = description || this._helpCommandDescription;
    }
    return this;
  }

  /**
   * @return {boolean}
   * @api private
   */

  _hasImplicitHelpCommand() {
    if (this._addImplicitHelpCommand === undefined) {
      return this.commands.length && !this._actionHandler && !this._findCommand('help');
    }
    return this._addImplicitHelpCommand;
  }

  /**
   * Add hook for life cycle event.
   *
   * @param {string} event
   * @param {Function} listener
   * @return {Command} `this` command for chaining
   */

  hook(event, listener) {
    const allowedValues = ['preSubcommand', 'preAction', 'postAction'];
    if (!allowedValues.includes(event)) {
      throw new Error(`Unexpected value for event passed to hook : '${event}'.
Expecting one of '${allowedValues.join("', '")}'`);
    }
    if (this._lifeCycleHooks[event]) {
      this._lifeCycleHooks[event].push(listener);
    } else {
      this._lifeCycleHooks[event] = [listener];
    }
    return this;
  }

  /**
   * Register callback to use as replacement for calling process.exit.
   *
   * @param {Function} [fn] optional callback which will be passed a CommanderError, defaults to throwing
   * @return {Command} `this` command for chaining
   */

  exitOverride(fn) {
    if (fn) {
      this._exitCallback = fn;
    } else {
      this._exitCallback = (err) => {
        if (err.code !== 'commander.executeSubCommandAsync') {
          throw err;
        } else {
          // Async callback from spawn events, not useful to throw.
        }
      };
    }
    return this;
  }

  /**
   * Call process.exit, and _exitCallback if defined.
   *
   * @param {number} exitCode exit code for using with process.exit
   * @param {string} code an id string representing the error
   * @param {string} message human-readable description of the error
   * @return never
   * @api private
   */

  _exit(exitCode, code, message) {
    if (this._exitCallback) {
      this._exitCallback(new CommanderError(exitCode, code, message));
      // Expecting this line is not reached.
    }
    process.exit(exitCode);
  }

  /**
   * Register callback `fn` for the command.
   *
   * @example
   * program
   *   .command('serve')
   *   .description('start service')
   *   .action(function() {
   *      // do work here
   *   });
   *
   * @param {Function} fn
   * @return {Command} `this` command for chaining
   */

  action(fn) {
    const listener = (args) => {
      // The .action callback takes an extra parameter which is the command or options.
      const expectedArgsCount = this._args.length;
      const actionArgs = args.slice(0, expectedArgsCount);
      if (this._storeOptionsAsProperties) {
        actionArgs[expectedArgsCount] = this; // backwards compatible "options"
      } else {
        actionArgs[expectedArgsCount] = this.opts();
      }
      actionArgs.push(this);

      return fn.apply(this, actionArgs);
    };
    this._actionHandler = listener;
    return this;
  }

  /**
   * Factory routine to create a new unattached option.
   *
   * See .option() for creating an attached option, which uses this routine to
   * create the option. You can override createOption to return a custom option.
   *
   * @param {string} flags
   * @param {string} [description]
   * @return {Option} new option
   */

  createOption(flags, description) {
    return new Option(flags, description);
  }

  /**
   * Add an option.
   *
   * @param {Option} option
   * @return {Command} `this` command for chaining
   */
  addOption(option) {
    const oname = option.name();
    const name = option.attributeName();

    // store default value
    if (option.negate) {
      // --no-foo is special and defaults foo to true, unless a --foo option is already defined
      const positiveLongFlag = option.long.replace(/^--no-/, '--');
      if (!this._findOption(positiveLongFlag)) {
        this.setOptionValueWithSource(name, option.defaultValue === undefined ? true : option.defaultValue, 'default');
      }
    } else if (option.defaultValue !== undefined) {
      this.setOptionValueWithSource(name, option.defaultValue, 'default');
    }

    // register the option
    this.options.push(option);

    // handler for cli and env supplied values
    const handleOptionValue = (val, invalidValueMessage, valueSource) => {
      // val is null for optional option used without an optional-argument.
      // val is undefined for boolean and negated option.
      if (val == null && option.presetArg !== undefined) {
        val = option.presetArg;
      }

      // custom processing
      const oldValue = this.getOptionValue(name);
      if (val !== null && option.parseArg) {
        try {
          val = option.parseArg(val, oldValue);
        } catch (err) {
          if (err.code === 'commander.invalidArgument') {
            const message = `${invalidValueMessage} ${err.message}`;
            this.error(message, { exitCode: err.exitCode, code: err.code });
          }
          throw err;
        }
      } else if (val !== null && option.variadic) {
        val = option._concatValue(val, oldValue);
      }

      // Fill-in appropriate missing values. Long winded but easy to follow.
      if (val == null) {
        if (option.negate) {
          val = false;
        } else if (option.isBoolean() || option.optional) {
          val = true;
        } else {
          val = ''; // not normal, parseArg might have failed or be a mock function for testing
        }
      }
      this.setOptionValueWithSource(name, val, valueSource);
    };

    this.on('option:' + oname, (val) => {
      const invalidValueMessage = `error: option '${option.flags}' argument '${val}' is invalid.`;
      handleOptionValue(val, invalidValueMessage, 'cli');
    });

    if (option.envVar) {
      this.on('optionEnv:' + oname, (val) => {
        const invalidValueMessage = `error: option '${option.flags}' value '${val}' from env '${option.envVar}' is invalid.`;
        handleOptionValue(val, invalidValueMessage, 'env');
      });
    }

    return this;
  }

  /**
   * Internal implementation shared by .option() and .requiredOption()
   *
   * @api private
   */
  _optionEx(config, flags, description, fn, defaultValue) {
    if (typeof flags === 'object' && flags instanceof Option) {
      throw new Error('To add an Option object use addOption() instead of option() or requiredOption()');
    }
    const option = this.createOption(flags, description);
    option.makeOptionMandatory(!!config.mandatory);
    if (typeof fn === 'function') {
      option.default(defaultValue).argParser(fn);
    } else if (fn instanceof RegExp) {
      // deprecated
      const regex = fn;
      fn = (val, def) => {
        const m = regex.exec(val);
        return m ? m[0] : def;
      };
      option.default(defaultValue).argParser(fn);
    } else {
      option.default(fn);
    }

    return this.addOption(option);
  }

  /**
   * Define option with `flags`, `description` and optional
   * coercion `fn`.
   *
   * The `flags` string contains the short and/or long flags,
   * separated by comma, a pipe or space. The following are all valid
   * all will output this way when `--help` is used.
   *
   *     "-p, --pepper"
   *     "-p|--pepper"
   *     "-p --pepper"
   *
   * @example
   * // simple boolean defaulting to undefined
   * program.option('-p, --pepper', 'add pepper');
   *
   * program.pepper
   * // => undefined
   *
   * --pepper
   * program.pepper
   * // => true
   *
   * // simple boolean defaulting to true (unless non-negated option is also defined)
   * program.option('-C, --no-cheese', 'remove cheese');
   *
   * program.cheese
   * // => true
   *
   * --no-cheese
   * program.cheese
   * // => false
   *
   * // required argument
   * program.option('-C, --chdir <path>', 'change the working directory');
   *
   * --chdir /tmp
   * program.chdir
   * // => "/tmp"
   *
   * // optional argument
   * program.option('-c, --cheese [type]', 'add cheese [marble]');
   *
   * @param {string} flags
   * @param {string} [description]
   * @param {Function|*} [fn] - custom option processing function or default value
   * @param {*} [defaultValue]
   * @return {Command} `this` command for chaining
   */

  option(flags, description, fn, defaultValue) {
    return this._optionEx({}, flags, description, fn, defaultValue);
  }

  /**
  * Add a required option which must have a value after parsing. This usually means
  * the option must be specified on the command line. (Otherwise the same as .option().)
  *
  * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space.
  *
  * @param {string} flags
  * @param {string} [description]
  * @param {Function|*} [fn] - custom option processing function or default value
  * @param {*} [defaultValue]
  * @return {Command} `this` command for chaining
  */

  requiredOption(flags, description, fn, defaultValue) {
    return this._optionEx({ mandatory: true }, flags, description, fn, defaultValue);
  }

  /**
   * Alter parsing of short flags with optional values.
   *
   * @example
   * // for `.option('-f,--flag [value]'):
   * program.combineFlagAndOptionalValue(true);  // `-f80` is treated like `--flag=80`, this is the default behaviour
   * program.combineFlagAndOptionalValue(false) // `-fb` is treated like `-f -b`
   *
   * @param {Boolean} [combine=true] - if `true` or omitted, an optional value can be specified directly after the flag.
   */
  combineFlagAndOptionalValue(combine = true) {
    this._combineFlagAndOptionalValue = !!combine;
    return this;
  }

  /**
   * Allow unknown options on the command line.
   *
   * @param {Boolean} [allowUnknown=true] - if `true` or omitted, no error will be thrown
   * for unknown options.
   */
  allowUnknownOption(allowUnknown = true) {
    this._allowUnknownOption = !!allowUnknown;
    return this;
  }

  /**
   * Allow excess command-arguments on the command line. Pass false to make excess arguments an error.
   *
   * @param {Boolean} [allowExcess=true] - if `true` or omitted, no error will be thrown
   * for excess arguments.
   */
  allowExcessArguments(allowExcess = true) {
    this._allowExcessArguments = !!allowExcess;
    return this;
  }

  /**
   * Enable positional options. Positional means global options are specified before subcommands which lets
   * subcommands reuse the same option names, and also enables subcommands to turn on passThroughOptions.
   * The default behaviour is non-positional and global options may appear anywhere on the command line.
   *
   * @param {Boolean} [positional=true]
   */
  enablePositionalOptions(positional = true) {
    this._enablePositionalOptions = !!positional;
    return this;
  }

  /**
   * Pass through options that come after command-arguments rather than treat them as command-options,
   * so actual command-options come before command-arguments. Turning this on for a subcommand requires
   * positional options to have been enabled on the program (parent commands).
   * The default behaviour is non-positional and options may appear before or after command-arguments.
   *
   * @param {Boolean} [passThrough=true]
   * for unknown options.
   */
  passThroughOptions(passThrough = true) {
    this._passThroughOptions = !!passThrough;
    if (!!this.parent && passThrough && !this.parent._enablePositionalOptions) {
      throw new Error('passThroughOptions can not be used without turning on enablePositionalOptions for parent command(s)');
    }
    return this;
  }

  /**
    * Whether to store option values as properties on command object,
    * or store separately (specify false). In both cases the option values can be accessed using .opts().
    *
    * @param {boolean} [storeAsProperties=true]
    * @return {Command} `this` command for chaining
    */

  storeOptionsAsProperties(storeAsProperties = true) {
    this._storeOptionsAsProperties = !!storeAsProperties;
    if (this.options.length) {
      throw new Error('call .storeOptionsAsProperties() before adding options');
    }
    return this;
  }

  /**
   * Retrieve option value.
   *
   * @param {string} key
   * @return {Object} value
   */

  getOptionValue(key) {
    if (this._storeOptionsAsProperties) {
      return this[key];
    }
    return this._optionValues[key];
  }

  /**
   * Store option value.
   *
   * @param {string} key
   * @param {Object} value
   * @return {Command} `this` command for chaining
   */

  setOptionValue(key, value) {
    return this.setOptionValueWithSource(key, value, undefined);
  }

  /**
    * Store option value and where the value came from.
    *
    * @param {string} key
    * @param {Object} value
    * @param {string} source - expected values are default/config/env/cli/implied
    * @return {Command} `this` command for chaining
    */

  setOptionValueWithSource(key, value, source) {
    if (this._storeOptionsAsProperties) {
      this[key] = value;
    } else {
      this._optionValues[key] = value;
    }
    this._optionValueSources[key] = source;
    return this;
  }

  /**
    * Get source of option value.
    * Expected values are default | config | env | cli | implied
    *
    * @param {string} key
    * @return {string}
    */

  getOptionValueSource(key) {
    return this._optionValueSources[key];
  }

  /**
    * Get source of option value. See also .optsWithGlobals().
    * Expected values are default | config | env | cli | implied
    *
    * @param {string} key
    * @return {string}
    */

  getOptionValueSourceWithGlobals(key) {
    // global overwrites local, like optsWithGlobals
    let source;
    getCommandAndParents(this).forEach((cmd) => {
      if (cmd.getOptionValueSource(key) !== undefined) {
        source = cmd.getOptionValueSource(key);
      }
    });
    return source;
  }

  /**
   * Get user arguments from implied or explicit arguments.
   * Side-effects: set _scriptPath if args included script. Used for default program name, and subcommand searches.
   *
   * @api private
   */

  _prepareUserArgs(argv, parseOptions) {
    if (argv !== undefined && !Array.isArray(argv)) {
      throw new Error('first parameter to parse must be array or undefined');
    }
    parseOptions = parseOptions || {};

    // Default to using process.argv
    if (argv === undefined) {
      argv = process.argv;
      // @ts-ignore: unknown property
      if (process.versions && process.versions.electron) {
        parseOptions.from = 'electron';
      }
    }
    this.rawArgs = argv.slice();

    // make it a little easier for callers by supporting various argv conventions
    let userArgs;
    switch (parseOptions.from) {
      case undefined:
      case 'node':
        this._scriptPath = argv[1];
        userArgs = argv.slice(2);
        break;
      case 'electron':
        // @ts-ignore: unknown property
        if (process.defaultApp) {
          this._scriptPath = argv[1];
          userArgs = argv.slice(2);
        } else {
          userArgs = argv.slice(1);
        }
        break;
      case 'user':
        userArgs = argv.slice(0);
        break;
      default:
        throw new Error(`unexpected parse option { from: '${parseOptions.from}' }`);
    }

    // Find default name for program from arguments.
    if (!this._name && this._scriptPath) this.nameFromFilename(this._scriptPath);
    this._name = this._name || 'program';

    return userArgs;
  }

  /**
   * Parse `argv`, setting options and invoking commands when defined.
   *
   * The default expectation is that the arguments are from node and have the application as argv[0]
   * and the script being run in argv[1], with user parameters after that.
   *
   * @example
   * program.parse(process.argv);
   * program.parse(); // implicitly use process.argv and auto-detect node vs electron conventions
   * program.parse(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
   *
   * @param {string[]} [argv] - optional, defaults to process.argv
   * @param {Object} [parseOptions] - optionally specify style of options with from: node/user/electron
   * @param {string} [parseOptions.from] - where the args are from: 'node', 'user', 'electron'
   * @return {Command} `this` command for chaining
   */

  parse(argv, parseOptions) {
    const userArgs = this._prepareUserArgs(argv, parseOptions);
    this._parseCommand([], userArgs);

    return this;
  }

  /**
   * Parse `argv`, setting options and invoking commands when defined.
   *
   * Use parseAsync instead of parse if any of your action handlers are async. Returns a Promise.
   *
   * The default expectation is that the arguments are from node and have the application as argv[0]
   * and the script being run in argv[1], with user parameters after that.
   *
   * @example
   * await program.parseAsync(process.argv);
   * await program.parseAsync(); // implicitly use process.argv and auto-detect node vs electron conventions
   * await program.parseAsync(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
   *
   * @param {string[]} [argv]
   * @param {Object} [parseOptions]
   * @param {string} parseOptions.from - where the args are from: 'node', 'user', 'electron'
   * @return {Promise}
   */

  async parseAsync(argv, parseOptions) {
    const userArgs = this._prepareUserArgs(argv, parseOptions);
    await this._parseCommand([], userArgs);

    return this;
  }

  /**
   * Execute a sub-command executable.
   *
   * @api private
   */

  _executeSubCommand(subcommand, args) {
    args = args.slice();
    let launchWithNode = false; // Use node for source targets so do not need to get permissions correct, and on Windows.
    const sourceExt = ['.js', '.ts', '.tsx', '.mjs', '.cjs'];

    function findFile(baseDir, baseName) {
      // Look for specified file
      const localBin = path.resolve(baseDir, baseName);
      if (fs.existsSync(localBin)) return localBin;

      // Stop looking if candidate already has an expected extension.
      if (sourceExt.includes(path.extname(baseName))) return undefined;

      // Try all the extensions.
      const foundExt = sourceExt.find(ext => fs.existsSync(`${localBin}${ext}`));
      if (foundExt) return `${localBin}${foundExt}`;

      return undefined;
    }

    // Not checking for help first. Unlikely to have mandatory and executable, and can't robustly test for help flags in external command.
    this._checkForMissingMandatoryOptions();
    this._checkForConflictingOptions();

    // executableFile and executableDir might be full path, or just a name
    let executableFile = subcommand._executableFile || `${this._name}-${subcommand._name}`;
    let executableDir = this._executableDir || '';
    if (this._scriptPath) {
      let resolvedScriptPath; // resolve possible symlink for installed npm binary
      try {
        resolvedScriptPath = fs.realpathSync(this._scriptPath);
      } catch (err) {
        resolvedScriptPath = this._scriptPath;
      }
      executableDir = path.resolve(path.dirname(resolvedScriptPath), executableDir);
    }

    // Look for a local file in preference to a command in PATH.
    if (executableDir) {
      let localFile = findFile(executableDir, executableFile);

      // Legacy search using prefix of script name instead of command name
      if (!localFile && !subcommand._executableFile && this._scriptPath) {
        const legacyName = path.basename(this._scriptPath, path.extname(this._scriptPath));
        if (legacyName !== this._name) {
          localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
        }
      }
      executableFile = localFile || executableFile;
    }

    launchWithNode = sourceExt.includes(path.extname(executableFile));

    let proc;
    if (process.platform !== 'win32') {
      if (launchWithNode) {
        args.unshift(executableFile);
        // add executable arguments to spawn
        args = incrementNodeInspectorPort(process.execArgv).concat(args);

        proc = childProcess.spawn(process.argv[0], args, { stdio: 'inherit' });
      } else {
        proc = childProcess.spawn(executableFile, args, { stdio: 'inherit' });
      }
    } else {
      args.unshift(executableFile);
      // add executable arguments to spawn
      args = incrementNodeInspectorPort(process.execArgv).concat(args);
      proc = childProcess.spawn(process.execPath, args, { stdio: 'inherit' });
    }

    if (!proc.killed) { // testing mainly to avoid leak warnings during unit tests with mocked spawn
      const signals = ['SIGUSR1', 'SIGUSR2', 'SIGTERM', 'SIGINT', 'SIGHUP'];
      signals.forEach((signal) => {
        // @ts-ignore
        process.on(signal, () => {
          if (proc.killed === false && proc.exitCode === null) {
            proc.kill(signal);
          }
        });
      });
    }

    // By default terminate process when spawned process terminates.
    // Suppressing the exit if exitCallback defined is a bit messy and of limited use, but does allow process to stay running!
    const exitCallback = this._exitCallback;
    if (!exitCallback) {
      proc.on('close', process.exit.bind(process));
    } else {
      proc.on('close', () => {
        exitCallback(new CommanderError(process.exitCode || 0, 'commander.executeSubCommandAsync', '(close)'));
      });
    }
    proc.on('error', (err) => {
      // @ts-ignore
      if (err.code === 'ENOENT') {
        const executableDirMessage = executableDir
          ? `searched for local subcommand relative to directory '${executableDir}'`
          : 'no directory for search for local subcommand, use .executableDir() to supply a custom directory';
        const executableMissing = `'${executableFile}' does not exist
 - if '${subcommand._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
 - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
 - ${executableDirMessage}`;
        throw new Error(executableMissing);
      // @ts-ignore
      } else if (err.code === 'EACCES') {
        throw new Error(`'${executableFile}' not executable`);
      }
      if (!exitCallback) {
        process.exit(1);
      } else {
        const wrappedError = new CommanderError(1, 'commander.executeSubCommandAsync', '(error)');
        wrappedError.nestedError = err;
        exitCallback(wrappedError);
      }
    });

    // Store the reference to the child process
    this.runningCommand = proc;
  }

  /**
   * @api private
   */

  _dispatchSubcommand(commandName, operands, unknown) {
    const subCommand = this._findCommand(commandName);
    if (!subCommand) this.help({ error: true });

    let hookResult;
    hookResult = this._chainOrCallSubCommandHook(hookResult, subCommand, 'preSubcommand');
    hookResult = this._chainOrCall(hookResult, () => {
      if (subCommand._executableHandler) {
        this._executeSubCommand(subCommand, operands.concat(unknown));
      } else {
        return subCommand._parseCommand(operands, unknown);
      }
    });
    return hookResult;
  }

  /**
   * Check this.args against expected this._args.
   *
   * @api private
   */

  _checkNumberOfArguments() {
    // too few
    this._args.forEach((arg, i) => {
      if (arg.required && this.args[i] == null) {
        this.missingArgument(arg.name());
      }
    });
    // too many
    if (this._args.length > 0 && this._args[this._args.length - 1].variadic) {
      return;
    }
    if (this.args.length > this._args.length) {
      this._excessArguments(this.args);
    }
  }

  /**
   * Process this.args using this._args and save as this.processedArgs!
   *
   * @api private
   */

  _processArguments() {
    const myParseArg = (argument, value, previous) => {
      // Extra processing for nice error message on parsing failure.
      let parsedValue = value;
      if (value !== null && argument.parseArg) {
        try {
          parsedValue = argument.parseArg(value, previous);
        } catch (err) {
          if (err.code === 'commander.invalidArgument') {
            const message = `error: command-argument value '${value}' is invalid for argument '${argument.name()}'. ${err.message}`;
            this.error(message, { exitCode: err.exitCode, code: err.code });
          }
          throw err;
        }
      }
      return parsedValue;
    };

    this._checkNumberOfArguments();

    const processedArgs = [];
    this._args.forEach((declaredArg, index) => {
      let value = declaredArg.defaultValue;
      if (declaredArg.variadic) {
        // Collect together remaining arguments for passing together as an array.
        if (index < this.args.length) {
          value = this.args.slice(index);
          if (declaredArg.parseArg) {
            value = value.reduce((processed, v) => {
              return myParseArg(declaredArg, v, processed);
            }, declaredArg.defaultValue);
          }
        } else if (value === undefined) {
          value = [];
        }
      } else if (index < this.args.length) {
        value = this.args[index];
        if (declaredArg.parseArg) {
          value = myParseArg(declaredArg, value, declaredArg.defaultValue);
        }
      }
      processedArgs[index] = value;
    });
    this.processedArgs = processedArgs;
  }

  /**
   * Once we have a promise we chain, but call synchronously until then.
   *
   * @param {Promise|undefined} promise
   * @param {Function} fn
   * @return {Promise|undefined}
   * @api private
   */

  _chainOrCall(promise, fn) {
    // thenable
    if (promise && promise.then && typeof promise.then === 'function') {
      // already have a promise, chain callback
      return promise.then(() => fn());
    }
    // callback might return a promise
    return fn();
  }

  /**
   *
   * @param {Promise|undefined} promise
   * @param {string} event
   * @return {Promise|undefined}
   * @api private
   */

  _chainOrCallHooks(promise, event) {
    let result = promise;
    const hooks = [];
    getCommandAndParents(this)
      .reverse()
      .filter(cmd => cmd._lifeCycleHooks[event] !== undefined)
      .forEach(hookedCommand => {
        hookedCommand._lifeCycleHooks[event].forEach((callback) => {
          hooks.push({ hookedCommand, callback });
        });
      });
    if (event === 'postAction') {
      hooks.reverse();
    }

    hooks.forEach((hookDetail) => {
      result = this._chainOrCall(result, () => {
        return hookDetail.callback(hookDetail.hookedCommand, this);
      });
    });
    return result;
  }

  /**
   *
   * @param {Promise|undefined} promise
   * @param {Command} subCommand
   * @param {string} event
   * @return {Promise|undefined}
   * @api private
   */

  _chainOrCallSubCommandHook(promise, subCommand, event) {
    let result = promise;
    if (this._lifeCycleHooks[event] !== undefined) {
      this._lifeCycleHooks[event].forEach((hook) => {
        result = this._chainOrCall(result, () => {
          return hook(this, subCommand);
        });
      });
    }
    return result;
  }

  /**
   * Process arguments in context of this command.
   * Returns action result, in case it is a promise.
   *
   * @api private
   */

  _parseCommand(operands, unknown) {
    const parsed = this.parseOptions(unknown);
    this._parseOptionsEnv(); // after cli, so parseArg not called on both cli and env
    this._parseOptionsImplied();
    operands = operands.concat(parsed.operands);
    unknown = parsed.unknown;
    this.args = operands.concat(unknown);

    if (operands && this._findCommand(operands[0])) {
      return this._dispatchSubcommand(operands[0], operands.slice(1), unknown);
    }
    if (this._hasImplicitHelpCommand() && operands[0] === this._helpCommandName) {
      if (operands.length === 1) {
        this.help();
      }
      return this._dispatchSubcommand(operands[1], [], [this._helpLongFlag]);
    }
    if (this._defaultCommandName) {
      outputHelpIfRequested(this, unknown); // Run the help for default command from parent rather than passing to default command
      return this._dispatchSubcommand(this._defaultCommandName, operands, unknown);
    }
    if (this.commands.length && this.args.length === 0 && !this._actionHandler && !this._defaultCommandName) {
      // probably missing subcommand and no handler, user needs help (and exit)
      this.help({ error: true });
    }

    outputHelpIfRequested(this, parsed.unknown);
    this._checkForMissingMandatoryOptions();
    this._checkForConflictingOptions();

    // We do not always call this check to avoid masking a "better" error, like unknown command.
    const checkForUnknownOptions = () => {
      if (parsed.unknown.length > 0) {
        this.unknownOption(parsed.unknown[0]);
      }
    };

    const commandEvent = `command:${this.name()}`;
    if (this._actionHandler) {
      checkForUnknownOptions();
      this._processArguments();

      let actionResult;
      actionResult = this._chainOrCallHooks(actionResult, 'preAction');
      actionResult = this._chainOrCall(actionResult, () => this._actionHandler(this.processedArgs));
      if (this.parent) {
        actionResult = this._chainOrCall(actionResult, () => {
          this.parent.emit(commandEvent, operands, unknown); // legacy
        });
      }
      actionResult = this._chainOrCallHooks(actionResult, 'postAction');
      return actionResult;
    }
    if (this.parent && this.parent.listenerCount(commandEvent)) {
      checkForUnknownOptions();
      this._processArguments();
      this.parent.emit(commandEvent, operands, unknown); // legacy
    } else if (operands.length) {
      if (this._findCommand('*')) { // legacy default command
        return this._dispatchSubcommand('*', operands, unknown);
      }
      if (this.listenerCount('command:*')) {
        // skip option check, emit event for possible misspelling suggestion
        this.emit('command:*', operands, unknown);
      } else if (this.commands.length) {
        this.unknownCommand();
      } else {
        checkForUnknownOptions();
        this._processArguments();
      }
    } else if (this.commands.length) {
      checkForUnknownOptions();
      // This command has subcommands and nothing hooked up at this level, so display help (and exit).
      this.help({ error: true });
    } else {
      checkForUnknownOptions();
      this._processArguments();
      // fall through for caller to handle after calling .parse()
    }
  }

  /**
   * Find matching command.
   *
   * @api private
   */
  _findCommand(name) {
    if (!name) return undefined;
    return this.commands.find(cmd => cmd._name === name || cmd._aliases.includes(name));
  }

  /**
   * Return an option matching `arg` if any.
   *
   * @param {string} arg
   * @return {Option}
   * @api private
   */

  _findOption(arg) {
    return this.options.find(option => option.is(arg));
  }

  /**
   * Display an error message if a mandatory option does not have a value.
   * Called after checking for help flags in leaf subcommand.
   *
   * @api private
   */

  _checkForMissingMandatoryOptions() {
    // Walk up hierarchy so can call in subcommand after checking for displaying help.
    for (let cmd = this; cmd; cmd = cmd.parent) {
      cmd.options.forEach((anOption) => {
        if (anOption.mandatory && (cmd.getOptionValue(anOption.attributeName()) === undefined)) {
          cmd.missingMandatoryOptionValue(anOption);
        }
      });
    }
  }

  /**
   * Display an error message if conflicting options are used together in this.
   *
   * @api private
   */
  _checkForConflictingLocalOptions() {
    const definedNonDefaultOptions = this.options.filter(
      (option) => {
        const optionKey = option.attributeName();
        if (this.getOptionValue(optionKey) === undefined) {
          return false;
        }
        return this.getOptionValueSource(optionKey) !== 'default';
      }
    );

    const optionsWithConflicting = definedNonDefaultOptions.filter(
      (option) => option.conflictsWith.length > 0
    );

    optionsWithConflicting.forEach((option) => {
      const conflictingAndDefined = definedNonDefaultOptions.find((defined) =>
        option.conflictsWith.includes(defined.attributeName())
      );
      if (conflictingAndDefined) {
        this._conflictingOption(option, conflictingAndDefined);
      }
    });
  }

  /**
   * Display an error message if conflicting options are used together.
   * Called after checking for help flags in leaf subcommand.
   *
   * @api private
   */
  _checkForConflictingOptions() {
    // Walk up hierarchy so can call in subcommand after checking for displaying help.
    for (let cmd = this; cmd; cmd = cmd.parent) {
      cmd._checkForConflictingLocalOptions();
    }
  }

  /**
   * Parse options from `argv` removing known options,
   * and return argv split into operands and unknown arguments.
   *
   * Examples:
   *
   *     argv => operands, unknown
   *     --known kkk op => [op], []
   *     op --known kkk => [op], []
   *     sub --unknown uuu op => [sub], [--unknown uuu op]
   *     sub -- --unknown uuu op => [sub --unknown uuu op], []
   *
   * @param {String[]} argv
   * @return {{operands: String[], unknown: String[]}}
   */

  parseOptions(argv) {
    const operands = []; // operands, not options or values
    const unknown = []; // first unknown option and remaining unknown args
    let dest = operands;
    const args = argv.slice();

    function maybeOption(arg) {
      return arg.length > 1 && arg[0] === '-';
    }

    // parse options
    let activeVariadicOption = null;
    while (args.length) {
      const arg = args.shift();

      // literal
      if (arg === '--') {
        if (dest === unknown) dest.push(arg);
        dest.push(...args);
        break;
      }

      if (activeVariadicOption && !maybeOption(arg)) {
        this.emit(`option:${activeVariadicOption.name()}`, arg);
        continue;
      }
      activeVariadicOption = null;

      if (maybeOption(arg)) {
        const option = this._findOption(arg);
        // recognised option, call listener to assign value with possible custom processing
        if (option) {
          if (option.required) {
            const value = args.shift();
            if (value === undefined) this.optionMissingArgument(option);
            this.emit(`option:${option.name()}`, value);
          } else if (option.optional) {
            let value = null;
            // historical behaviour is optional value is following arg unless an option
            if (args.length > 0 && !maybeOption(args[0])) {
              value = args.shift();
            }
            this.emit(`option:${option.name()}`, value);
          } else { // boolean flag
            this.emit(`option:${option.name()}`);
          }
          activeVariadicOption = option.variadic ? option : null;
          continue;
        }
      }

      // Look for combo options following single dash, eat first one if known.
      if (arg.length > 2 && arg[0] === '-' && arg[1] !== '-') {
        const option = this._findOption(`-${arg[1]}`);
        if (option) {
          if (option.required || (option.optional && this._combineFlagAndOptionalValue)) {
            // option with value following in same argument
            this.emit(`option:${option.name()}`, arg.slice(2));
          } else {
            // boolean option, emit and put back remainder of arg for further processing
            this.emit(`option:${option.name()}`);
            args.unshift(`-${arg.slice(2)}`);
          }
          continue;
        }
      }

      // Look for known long flag with value, like --foo=bar
      if (/^--[^=]+=/.test(arg)) {
        const index = arg.indexOf('=');
        const option = this._findOption(arg.slice(0, index));
        if (option && (option.required || option.optional)) {
          this.emit(`option:${option.name()}`, arg.slice(index + 1));
          continue;
        }
      }

      // Not a recognised option by this command.
      // Might be a command-argument, or subcommand option, or unknown option, or help command or option.

      // An unknown option means further arguments also classified as unknown so can be reprocessed by subcommands.
      if (maybeOption(arg)) {
        dest = unknown;
      }

      // If using positionalOptions, stop processing our options at subcommand.
      if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown.length === 0) {
        if (this._findCommand(arg)) {
          operands.push(arg);
          if (args.length > 0) unknown.push(...args);
          break;
        } else if (arg === this._helpCommandName && this._hasImplicitHelpCommand()) {
          operands.push(arg);
          if (args.length > 0) operands.push(...args);
          break;
        } else if (this._defaultCommandName) {
          unknown.push(arg);
          if (args.length > 0) unknown.push(...args);
          break;
        }
      }

      // If using passThroughOptions, stop processing options at first command-argument.
      if (this._passThroughOptions) {
        dest.push(arg);
        if (args.length > 0) dest.push(...args);
        break;
      }

      // add arg
      dest.push(arg);
    }

    return { operands, unknown };
  }

  /**
   * Return an object containing local option values as key-value pairs.
   *
   * @return {Object}
   */
  opts() {
    if (this._storeOptionsAsProperties) {
      // Preserve original behaviour so backwards compatible when still using properties
      const result = {};
      const len = this.options.length;

      for (let i = 0; i < len; i++) {
        const key = this.options[i].attributeName();
        result[key] = key === this._versionOptionName ? this._version : this[key];
      }
      return result;
    }

    return this._optionValues;
  }

  /**
   * Return an object containing merged local and global option values as key-value pairs.
   *
   * @return {Object}
   */
  optsWithGlobals() {
    // globals overwrite locals
    return getCommandAndParents(this).reduce(
      (combinedOptions, cmd) => Object.assign(combinedOptions, cmd.opts()),
      {}
    );
  }

  /**
   * Display error message and exit (or call exitOverride).
   *
   * @param {string} message
   * @param {Object} [errorOptions]
   * @param {string} [errorOptions.code] - an id string representing the error
   * @param {number} [errorOptions.exitCode] - used with process.exit
   */
  error(message, errorOptions) {
    // output handling
    this._outputConfiguration.outputError(`${message}\n`, this._outputConfiguration.writeErr);
    if (typeof this._showHelpAfterError === 'string') {
      this._outputConfiguration.writeErr(`${this._showHelpAfterError}\n`);
    } else if (this._showHelpAfterError) {
      this._outputConfiguration.writeErr('\n');
      this.outputHelp({ error: true });
    }

    // exit handling
    const config = errorOptions || {};
    const exitCode = config.exitCode || 1;
    const code = config.code || 'commander.error';
    this._exit(exitCode, code, message);
  }

  /**
   * Apply any option related environment variables, if option does
   * not have a value from cli or client code.
   *
   * @api private
   */
  _parseOptionsEnv() {
    this.options.forEach((option) => {
      if (option.envVar && option.envVar in process.env) {
        const optionKey = option.attributeName();
        // Priority check. Do not overwrite cli or options from unknown source (client-code).
        if (this.getOptionValue(optionKey) === undefined || ['default', 'config', 'env'].includes(this.getOptionValueSource(optionKey))) {
          if (option.required || option.optional) { // option can take a value
            // keep very simple, optional always takes value
            this.emit(`optionEnv:${option.name()}`, process.env[option.envVar]);
          } else { // boolean
            // keep very simple, only care that envVar defined and not the value
            this.emit(`optionEnv:${option.name()}`);
          }
        }
      }
    });
  }

  /**
   * Apply any implied option values, if option is undefined or default value.
   *
   * @api private
   */
  _parseOptionsImplied() {
    const dualHelper = new DualOptions(this.options);
    const hasCustomOptionValue = (optionKey) => {
      return this.getOptionValue(optionKey) !== undefined && !['default', 'implied'].includes(this.getOptionValueSource(optionKey));
    };
    this.options
      .filter(option => (option.implied !== undefined) &&
        hasCustomOptionValue(option.attributeName()) &&
        dualHelper.valueFromOption(this.getOptionValue(option.attributeName()), option))
      .forEach((option) => {
        Object.keys(option.implied)
          .filter(impliedKey => !hasCustomOptionValue(impliedKey))
          .forEach(impliedKey => {
            this.setOptionValueWithSource(impliedKey, option.implied[impliedKey], 'implied');
          });
      });
  }

  /**
   * Argument `name` is missing.
   *
   * @param {string} name
   * @api private
   */

  missingArgument(name) {
    const message = `error: missing required argument '${name}'`;
    this.error(message, { code: 'commander.missingArgument' });
  }

  /**
   * `Option` is missing an argument.
   *
   * @param {Option} option
   * @api private
   */

  optionMissingArgument(option) {
    const message = `error: option '${option.flags}' argument missing`;
    this.error(message, { code: 'commander.optionMissingArgument' });
  }

  /**
   * `Option` does not have a value, and is a mandatory option.
   *
   * @param {Option} option
   * @api private
   */

  missingMandatoryOptionValue(option) {
    const message = `error: required option '${option.flags}' not specified`;
    this.error(message, { code: 'commander.missingMandatoryOptionValue' });
  }

  /**
   * `Option` conflicts with another option.
   *
   * @param {Option} option
   * @param {Option} conflictingOption
   * @api private
   */
  _conflictingOption(option, conflictingOption) {
    // The calling code does not know whether a negated option is the source of the
    // value, so do some work to take an educated guess.
    const findBestOptionFromValue = (option) => {
      const optionKey = option.attributeName();
      const optionValue = this.getOptionValue(optionKey);
      const negativeOption = this.options.find(target => target.negate && optionKey === target.attributeName());
      const positiveOption = this.options.find(target => !target.negate && optionKey === target.attributeName());
      if (negativeOption && (
        (negativeOption.presetArg === undefined && optionValue === false) ||
        (negativeOption.presetArg !== undefined && optionValue === negativeOption.presetArg)
      )) {
        return negativeOption;
      }
      return positiveOption || option;
    };

    const getErrorMessage = (option) => {
      const bestOption = findBestOptionFromValue(option);
      const optionKey = bestOption.attributeName();
      const source = this.getOptionValueSource(optionKey);
      if (source === 'env') {
        return `environment variable '${bestOption.envVar}'`;
      }
      return `option '${bestOption.flags}'`;
    };

    const message = `error: ${getErrorMessage(option)} cannot be used with ${getErrorMessage(conflictingOption)}`;
    this.error(message, { code: 'commander.conflictingOption' });
  }

  /**
   * Unknown option `flag`.
   *
   * @param {string} flag
   * @api private
   */

  unknownOption(flag) {
    if (this._allowUnknownOption) return;
    let suggestion = '';

    if (flag.startsWith('--') && this._showSuggestionAfterError) {
      // Looping to pick up the global options too
      let candidateFlags = [];
      let command = this;
      do {
        const moreFlags = command.createHelp().visibleOptions(command)
          .filter(option => option.long)
          .map(option => option.long);
        candidateFlags = candidateFlags.concat(moreFlags);
        command = command.parent;
      } while (command && !command._enablePositionalOptions);
      suggestion = suggestSimilar(flag, candidateFlags);
    }

    const message = `error: unknown option '${flag}'${suggestion}`;
    this.error(message, { code: 'commander.unknownOption' });
  }

  /**
   * Excess arguments, more than expected.
   *
   * @param {string[]} receivedArgs
   * @api private
   */

  _excessArguments(receivedArgs) {
    if (this._allowExcessArguments) return;

    const expected = this._args.length;
    const s = (expected === 1) ? '' : 's';
    const forSubcommand = this.parent ? ` for '${this.name()}'` : '';
    const message = `error: too many arguments${forSubcommand}. Expected ${expected} argument${s} but got ${receivedArgs.length}.`;
    this.error(message, { code: 'commander.excessArguments' });
  }

  /**
   * Unknown command.
   *
   * @api private
   */

  unknownCommand() {
    const unknownName = this.args[0];
    let suggestion = '';

    if (this._showSuggestionAfterError) {
      const candidateNames = [];
      this.createHelp().visibleCommands(this).forEach((command) => {
        candidateNames.push(command.name());
        // just visible alias
        if (command.alias()) candidateNames.push(command.alias());
      });
      suggestion = suggestSimilar(unknownName, candidateNames);
    }

    const message = `error: unknown command '${unknownName}'${suggestion}`;
    this.error(message, { code: 'commander.unknownCommand' });
  }

  /**
   * Set the program version to `str`.
   *
   * This method auto-registers the "-V, --version" flag
   * which will print the version number when passed.
   *
   * You can optionally supply the  flags and description to override the defaults.
   *
   * @param {string} str
   * @param {string} [flags]
   * @param {string} [description]
   * @return {this | string} `this` command for chaining, or version string if no arguments
   */

  version(str, flags, description) {
    if (str === undefined) return this._version;
    this._version = str;
    flags = flags || '-V, --version';
    description = description || 'output the version number';
    const versionOption = this.createOption(flags, description);
    this._versionOptionName = versionOption.attributeName();
    this.options.push(versionOption);
    this.on('option:' + versionOption.name(), () => {
      this._outputConfiguration.writeOut(`${str}\n`);
      this._exit(0, 'commander.version', str);
    });
    return this;
  }

  /**
   * Set the description.
   *
   * @param {string} [str]
   * @param {Object} [argsDescription]
   * @return {string|Command}
   */
  description(str, argsDescription) {
    if (str === undefined && argsDescription === undefined) return this._description;
    this._description = str;
    if (argsDescription) {
      this._argsDescription = argsDescription;
    }
    return this;
  }

  /**
   * Set the summary. Used when listed as subcommand of parent.
   *
   * @param {string} [str]
   * @return {string|Command}
   */
  summary(str) {
    if (str === undefined) return this._summary;
    this._summary = str;
    return this;
  }

  /**
   * Set an alias for the command.
   *
   * You may call more than once to add multiple aliases. Only the first alias is shown in the auto-generated help.
   *
   * @param {string} [alias]
   * @return {string|Command}
   */

  alias(alias) {
    if (alias === undefined) return this._aliases[0]; // just return first, for backwards compatibility

    /** @type {Command} */
    let command = this;
    if (this.commands.length !== 0 && this.commands[this.commands.length - 1]._executableHandler) {
      // assume adding alias for last added executable subcommand, rather than this
      command = this.commands[this.commands.length - 1];
    }

    if (alias === command._name) throw new Error('Command alias can\'t be the same as its name');

    command._aliases.push(alias);
    return this;
  }

  /**
   * Set aliases for the command.
   *
   * Only the first alias is shown in the auto-generated help.
   *
   * @param {string[]} [aliases]
   * @return {string[]|Command}
   */

  aliases(aliases) {
    // Getter for the array of aliases is the main reason for having aliases() in addition to alias().
    if (aliases === undefined) return this._aliases;

    aliases.forEach((alias) => this.alias(alias));
    return this;
  }

  /**
   * Set / get the command usage `str`.
   *
   * @param {string} [str]
   * @return {String|Command}
   */

  usage(str) {
    if (str === undefined) {
      if (this._usage) return this._usage;

      const args = this._args.map((arg) => {
        return humanReadableArgName(arg);
      });
      return [].concat(
        (this.options.length || this._hasHelpOption ? '[options]' : []),
        (this.commands.length ? '[command]' : []),
        (this._args.length ? args : [])
      ).join(' ');
    }

    this._usage = str;
    return this;
  }

  /**
   * Get or set the name of the command.
   *
   * @param {string} [str]
   * @return {string|Command}
   */

  name(str) {
    if (str === undefined) return this._name;
    this._name = str;
    return this;
  }

  /**
   * Set the name of the command from script filename, such as process.argv[1],
   * or require.main.filename, or __filename.
   *
   * (Used internally and public although not documented in README.)
   *
   * @example
   * program.nameFromFilename(require.main.filename);
   *
   * @param {string} filename
   * @return {Command}
   */

  nameFromFilename(filename) {
    this._name = path.basename(filename, path.extname(filename));

    return this;
  }

  /**
   * Get or set the directory for searching for executable subcommands of this command.
   *
   * @example
   * program.executableDir(__dirname);
   * // or
   * program.executableDir('subcommands');
   *
   * @param {string} [path]
   * @return {string|Command}
   */

  executableDir(path) {
    if (path === undefined) return this._executableDir;
    this._executableDir = path;
    return this;
  }

  /**
   * Return program help documentation.
   *
   * @param {{ error: boolean }} [contextOptions] - pass {error:true} to wrap for stderr instead of stdout
   * @return {string}
   */

  helpInformation(contextOptions) {
    const helper = this.createHelp();
    if (helper.helpWidth === undefined) {
      helper.helpWidth = (contextOptions && contextOptions.error) ? this._outputConfiguration.getErrHelpWidth() : this._outputConfiguration.getOutHelpWidth();
    }
    return helper.formatHelp(this, helper);
  }

  /**
   * @api private
   */

  _getHelpContext(contextOptions) {
    contextOptions = contextOptions || {};
    const context = { error: !!contextOptions.error };
    let write;
    if (context.error) {
      write = (arg) => this._outputConfiguration.writeErr(arg);
    } else {
      write = (arg) => this._outputConfiguration.writeOut(arg);
    }
    context.write = contextOptions.write || write;
    context.command = this;
    return context;
  }

  /**
   * Output help information for this command.
   *
   * Outputs built-in help, and custom text added using `.addHelpText()`.
   *
   * @param {{ error: boolean } | Function} [contextOptions] - pass {error:true} to write to stderr instead of stdout
   */

  outputHelp(contextOptions) {
    let deprecatedCallback;
    if (typeof contextOptions === 'function') {
      deprecatedCallback = contextOptions;
      contextOptions = undefined;
    }
    const context = this._getHelpContext(contextOptions);

    getCommandAndParents(this).reverse().forEach(command => command.emit('beforeAllHelp', context));
    this.emit('beforeHelp', context);

    let helpInformation = this.helpInformation(context);
    if (deprecatedCallback) {
      helpInformation = deprecatedCallback(helpInformation);
      if (typeof helpInformation !== 'string' && !Buffer.isBuffer(helpInformation)) {
        throw new Error('outputHelp callback must return a string or a Buffer');
      }
    }
    context.write(helpInformation);

    this.emit(this._helpLongFlag); // deprecated
    this.emit('afterHelp', context);
    getCommandAndParents(this).forEach(command => command.emit('afterAllHelp', context));
  }

  /**
   * You can pass in flags and a description to override the help
   * flags and help description for your command. Pass in false to
   * disable the built-in help option.
   *
   * @param {string | boolean} [flags]
   * @param {string} [description]
   * @return {Command} `this` command for chaining
   */

  helpOption(flags, description) {
    if (typeof flags === 'boolean') {
      this._hasHelpOption = flags;
      return this;
    }
    this._helpFlags = flags || this._helpFlags;
    this._helpDescription = description || this._helpDescription;

    const helpFlags = splitOptionFlags(this._helpFlags);
    this._helpShortFlag = helpFlags.shortFlag;
    this._helpLongFlag = helpFlags.longFlag;

    return this;
  }

  /**
   * Output help information and exit.
   *
   * Outputs built-in help, and custom text added using `.addHelpText()`.
   *
   * @param {{ error: boolean }} [contextOptions] - pass {error:true} to write to stderr instead of stdout
   */

  help(contextOptions) {
    this.outputHelp(contextOptions);
    let exitCode = process.exitCode || 0;
    if (exitCode === 0 && contextOptions && typeof contextOptions !== 'function' && contextOptions.error) {
      exitCode = 1;
    }
    // message: do not have all displayed text available so only passing placeholder.
    this._exit(exitCode, 'commander.help', '(outputHelp)');
  }

  /**
   * Add additional text to be displayed with the built-in help.
   *
   * Position is 'before' or 'after' to affect just this command,
   * and 'beforeAll' or 'afterAll' to affect this command and all its subcommands.
   *
   * @param {string} position - before or after built-in help
   * @param {string | Function} text - string to add, or a function returning a string
   * @return {Command} `this` command for chaining
   */
  addHelpText(position, text) {
    const allowedValues = ['beforeAll', 'before', 'after', 'afterAll'];
    if (!allowedValues.includes(position)) {
      throw new Error(`Unexpected value for position to addHelpText.
Expecting one of '${allowedValues.join("', '")}'`);
    }
    const helpEvent = `${position}Help`;
    this.on(helpEvent, (context) => {
      let helpStr;
      if (typeof text === 'function') {
        helpStr = text({ error: context.error, command: context.command });
      } else {
        helpStr = text;
      }
      // Ignore falsy value when nothing to output.
      if (helpStr) {
        context.write(`${helpStr}\n`);
      }
    });
    return this;
  }
}

/**
 * Output help information if help flags specified
 *
 * @param {Command} cmd - command to output help for
 * @param {Array} args - array of options to search for help flags
 * @api private
 */

function outputHelpIfRequested(cmd, args) {
  const helpOption = cmd._hasHelpOption && args.find(arg => arg === cmd._helpLongFlag || arg === cmd._helpShortFlag);
  if (helpOption) {
    cmd.outputHelp();
    // (Do not have all displayed text available so only passing placeholder.)
    cmd._exit(0, 'commander.helpDisplayed', '(outputHelp)');
  }
}

/**
 * Scan arguments and increment port number for inspect calls (to avoid conflicts when spawning new command).
 *
 * @param {string[]} args - array of arguments from node.execArgv
 * @returns {string[]}
 * @api private
 */

function incrementNodeInspectorPort(args) {
  // Testing for these options:
  //  --inspect[=[host:]port]
  //  --inspect-brk[=[host:]port]
  //  --inspect-port=[host:]port
  return args.map((arg) => {
    if (!arg.startsWith('--inspect')) {
      return arg;
    }
    let debugOption;
    let debugHost = '127.0.0.1';
    let debugPort = '9229';
    let match;
    if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) {
      // e.g. --inspect
      debugOption = match[1];
    } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null) {
      debugOption = match[1];
      if (/^\d+$/.test(match[3])) {
        // e.g. --inspect=1234
        debugPort = match[3];
      } else {
        // e.g. --inspect=localhost
        debugHost = match[3];
      }
    } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
      // e.g. --inspect=localhost:1234
      debugOption = match[1];
      debugHost = match[3];
      debugPort = match[4];
    }

    if (debugOption && debugPort !== '0') {
      return `${debugOption}=${debugHost}:${parseInt(debugPort) + 1}`;
    }
    return arg;
  });
}

/**
 * @param {Command} startCommand
 * @returns {Command[]}
 * @api private
 */

function getCommandAndParents(startCommand) {
  const result = [];
  for (let command = startCommand; command; command = command.parent) {
    result.push(command);
  }
  return result;
}

exports.Command = Command;


/***/ }),

/***/ 831:
/***/ ((__unused_webpack_module, exports) => {

// @ts-check

/**
 * CommanderError class
 * @class
 */
class CommanderError extends Error {
  /**
   * Constructs the CommanderError class
   * @param {number} exitCode suggested exit code which could be used with process.exit
   * @param {string} code an id string representing the error
   * @param {string} message human-readable description of the error
   * @constructor
   */
  constructor(exitCode, code, message) {
    super(message);
    // properly capture stack trace in Node.js
    Error.captureStackTrace(this, this.constructor);
    this.name = this.constructor.name;
    this.code = code;
    this.exitCode = exitCode;
    this.nestedError = undefined;
  }
}

/**
 * InvalidArgumentError class
 * @class
 */
class InvalidArgumentError extends CommanderError {
  /**
   * Constructs the InvalidArgumentError class
   * @param {string} [message] explanation of why argument is invalid
   * @constructor
   */
  constructor(message) {
    super(1, 'commander.invalidArgument', message);
    // properly capture stack trace in Node.js
    Error.captureStackTrace(this, this.constructor);
    this.name = this.constructor.name;
  }
}

exports.CommanderError = CommanderError;
exports.InvalidArgumentError = InvalidArgumentError;


/***/ }),

/***/ 437:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {

const { humanReadableArgName } = __webpack_require__(811);

/**
 * TypeScript import types for JSDoc, used by Visual Studio Code IntelliSense and `npm run typescript-checkJS`
 * https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#import-types
 * @typedef { import("./argument.js").Argument } Argument
 * @typedef { import("./command.js").Command } Command
 * @typedef { import("./option.js").Option } Option
 */

// @ts-check

// Although this is a class, methods are static in style to allow override using subclass or just functions.
class Help {
  constructor() {
    this.helpWidth = undefined;
    this.sortSubcommands = false;
    this.sortOptions = false;
    this.showGlobalOptions = false;
  }

  /**
   * Get an array of the visible subcommands. Includes a placeholder for the implicit help command, if there is one.
   *
   * @param {Command} cmd
   * @returns {Command[]}
   */

  visibleCommands(cmd) {
    const visibleCommands = cmd.commands.filter(cmd => !cmd._hidden);
    if (cmd._hasImplicitHelpCommand()) {
      // Create a command matching the implicit help command.
      const [, helpName, helpArgs] = cmd._helpCommandnameAndArgs.match(/([^ ]+) *(.*)/);
      const helpCommand = cmd.createCommand(helpName)
        .helpOption(false);
      helpCommand.description(cmd._helpCommandDescription);
      if (helpArgs) helpCommand.arguments(helpArgs);
      visibleCommands.push(helpCommand);
    }
    if (this.sortSubcommands) {
      visibleCommands.sort((a, b) => {
        // @ts-ignore: overloaded return type
        return a.name().localeCompare(b.name());
      });
    }
    return visibleCommands;
  }

  /**
   * Compare options for sort.
   *
   * @param {Option} a
   * @param {Option} b
   * @returns number
   */
  compareOptions(a, b) {
    const getSortKey = (option) => {
      // WYSIWYG for order displayed in help. Short used for comparison if present. No special handling for negated.
      return option.short ? option.short.replace(/^-/, '') : option.long.replace(/^--/, '');
    };
    return getSortKey(a).localeCompare(getSortKey(b));
  }

  /**
   * Get an array of the visible options. Includes a placeholder for the implicit help option, if there is one.
   *
   * @param {Command} cmd
   * @returns {Option[]}
   */

  visibleOptions(cmd) {
    const visibleOptions = cmd.options.filter((option) => !option.hidden);
    // Implicit help
    const showShortHelpFlag = cmd._hasHelpOption && cmd._helpShortFlag && !cmd._findOption(cmd._helpShortFlag);
    const showLongHelpFlag = cmd._hasHelpOption && !cmd._findOption(cmd._helpLongFlag);
    if (showShortHelpFlag || showLongHelpFlag) {
      let helpOption;
      if (!showShortHelpFlag) {
        helpOption = cmd.createOption(cmd._helpLongFlag, cmd._helpDescription);
      } else if (!showLongHelpFlag) {
        helpOption = cmd.createOption(cmd._helpShortFlag, cmd._helpDescription);
      } else {
        helpOption = cmd.createOption(cmd._helpFlags, cmd._helpDescription);
      }
      visibleOptions.push(helpOption);
    }
    if (this.sortOptions) {
      visibleOptions.sort(this.compareOptions);
    }
    return visibleOptions;
  }

  /**
   * Get an array of the visible global options. (Not including help.)
   *
   * @param {Command} cmd
   * @returns {Option[]}
   */

  visibleGlobalOptions(cmd) {
    if (!this.showGlobalOptions) return [];

    const globalOptions = [];
    for (let parentCmd = cmd.parent; parentCmd; parentCmd = parentCmd.parent) {
      const visibleOptions = parentCmd.options.filter((option) => !option.hidden);
      globalOptions.push(...visibleOptions);
    }
    if (this.sortOptions) {
      globalOptions.sort(this.compareOptions);
    }
    return globalOptions;
  }

  /**
   * Get an array of the arguments if any have a description.
   *
   * @param {Command} cmd
   * @returns {Argument[]}
   */

  visibleArguments(cmd) {
    // Side effect! Apply the legacy descriptions before the arguments are displayed.
    if (cmd._argsDescription) {
      cmd._args.forEach(argument => {
        argument.description = argument.description || cmd._argsDescription[argument.name()] || '';
      });
    }

    // If there are any arguments with a description then return all the arguments.
    if (cmd._args.find(argument => argument.description)) {
      return cmd._args;
    }
    return [];
  }

  /**
   * Get the command term to show in the list of subcommands.
   *
   * @param {Command} cmd
   * @returns {string}
   */

  subcommandTerm(cmd) {
    // Legacy. Ignores custom usage string, and nested commands.
    const args = cmd._args.map(arg => humanReadableArgName(arg)).join(' ');
    return cmd._name +
      (cmd._aliases[0] ? '|' + cmd._aliases[0] : '') +
      (cmd.options.length ? ' [options]' : '') + // simplistic check for non-help option
      (args ? ' ' + args : '');
  }

  /**
   * Get the option term to show in the list of options.
   *
   * @param {Option} option
   * @returns {string}
   */

  optionTerm(option) {
    return option.flags;
  }

  /**
   * Get the argument term to show in the list of arguments.
   *
   * @param {Argument} argument
   * @returns {string}
   */

  argumentTerm(argument) {
    return argument.name();
  }

  /**
   * Get the longest command term length.
   *
   * @param {Command} cmd
   * @param {Help} helper
   * @returns {number}
   */

  longestSubcommandTermLength(cmd, helper) {
    return helper.visibleCommands(cmd).reduce((max, command) => {
      return Math.max(max, helper.subcommandTerm(command).length);
    }, 0);
  }

  /**
   * Get the longest option term length.
   *
   * @param {Command} cmd
   * @param {Help} helper
   * @returns {number}
   */

  longestOptionTermLength(cmd, helper) {
    return helper.visibleOptions(cmd).reduce((max, option) => {
      return Math.max(max, helper.optionTerm(option).length);
    }, 0);
  }

  /**
   * Get the longest global option term length.
   *
   * @param {Command} cmd
   * @param {Help} helper
   * @returns {number}
   */

  longestGlobalOptionTermLength(cmd, helper) {
    return helper.visibleGlobalOptions(cmd).reduce((max, option) => {
      return Math.max(max, helper.optionTerm(option).length);
    }, 0);
  }

  /**
   * Get the longest argument term length.
   *
   * @param {Command} cmd
   * @param {Help} helper
   * @returns {number}
   */

  longestArgumentTermLength(cmd, helper) {
    return helper.visibleArguments(cmd).reduce((max, argument) => {
      return Math.max(max, helper.argumentTerm(argument).length);
    }, 0);
  }

  /**
   * Get the command usage to be displayed at the top of the built-in help.
   *
   * @param {Command} cmd
   * @returns {string}
   */

  commandUsage(cmd) {
    // Usage
    let cmdName = cmd._name;
    if (cmd._aliases[0]) {
      cmdName = cmdName + '|' + cmd._aliases[0];
    }
    let parentCmdNames = '';
    for (let parentCmd = cmd.parent; parentCmd; parentCmd = parentCmd.parent) {
      parentCmdNames = parentCmd.name() + ' ' + parentCmdNames;
    }
    return parentCmdNames + cmdName + ' ' + cmd.usage();
  }

  /**
   * Get the description for the command.
   *
   * @param {Command} cmd
   * @returns {string}
   */

  commandDescription(cmd) {
    // @ts-ignore: overloaded return type
    return cmd.description();
  }

  /**
   * Get the subcommand summary to show in the list of subcommands.
   * (Fallback to description for backwards compatibility.)
   *
   * @param {Command} cmd
   * @returns {string}
   */

  subcommandDescription(cmd) {
    // @ts-ignore: overloaded return type
    return cmd.summary() || cmd.description();
  }

  /**
   * Get the option description to show in the list of options.
   *
   * @param {Option} option
   * @return {string}
   */

  optionDescription(option) {
    const extraInfo = [];

    if (option.argChoices) {
      extraInfo.push(
        // use stringify to match the display of the default value
        `choices: ${option.argChoices.map((choice) => JSON.stringify(choice)).join(', ')}`);
    }
    if (option.defaultValue !== undefined) {
      // default for boolean and negated more for programmer than end user,
      // but show true/false for boolean option as may be for hand-rolled env or config processing.
      const showDefault = option.required || option.optional ||
        (option.isBoolean() && typeof option.defaultValue === 'boolean');
      if (showDefault) {
        extraInfo.push(`default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`);
      }
    }
    // preset for boolean and negated are more for programmer than end user
    if (option.presetArg !== undefined && option.optional) {
      extraInfo.push(`preset: ${JSON.stringify(option.presetArg)}`);
    }
    if (option.envVar !== undefined) {
      extraInfo.push(`env: ${option.envVar}`);
    }
    if (extraInfo.length > 0) {
      return `${option.description} (${extraInfo.join(', ')})`;
    }

    return option.description;
  }

  /**
   * Get the argument description to show in the list of arguments.
   *
   * @param {Argument} argument
   * @return {string}
   */

  argumentDescription(argument) {
    const extraInfo = [];
    if (argument.argChoices) {
      extraInfo.push(
        // use stringify to match the display of the default value
        `choices: ${argument.argChoices.map((choice) => JSON.stringify(choice)).join(', ')}`);
    }
    if (argument.defaultValue !== undefined) {
      extraInfo.push(`default: ${argument.defaultValueDescription || JSON.stringify(argument.defaultValue)}`);
    }
    if (extraInfo.length > 0) {
      const extraDescripton = `(${extraInfo.join(', ')})`;
      if (argument.description) {
        return `${argument.description} ${extraDescripton}`;
      }
      return extraDescripton;
    }
    return argument.description;
  }

  /**
   * Generate the built-in help text.
   *
   * @param {Command} cmd
   * @param {Help} helper
   * @returns {string}
   */

  formatHelp(cmd, helper) {
    const termWidth = helper.padWidth(cmd, helper);
    const helpWidth = helper.helpWidth || 80;
    const itemIndentWidth = 2;
    const itemSeparatorWidth = 2; // between term and description
    function formatItem(term, description) {
      if (description) {
        const fullText = `${term.padEnd(termWidth + itemSeparatorWidth)}${description}`;
        return helper.wrap(fullText, helpWidth - itemIndentWidth, termWidth + itemSeparatorWidth);
      }
      return term;
    }
    function formatList(textArray) {
      return textArray.join('\n').replace(/^/gm, ' '.repeat(itemIndentWidth));
    }

    // Usage
    let output = [`Usage: ${helper.commandUsage(cmd)}`, ''];

    // Description
    const commandDescription = helper.commandDescription(cmd);
    if (commandDescription.length > 0) {
      output = output.concat([helper.wrap(commandDescription, helpWidth, 0), '']);
    }

    // Arguments
    const argumentList = helper.visibleArguments(cmd).map((argument) => {
      return formatItem(helper.argumentTerm(argument), helper.argumentDescription(argument));
    });
    if (argumentList.length > 0) {
      output = output.concat(['Arguments:', formatList(argumentList), '']);
    }

    // Options
    const optionList = helper.visibleOptions(cmd).map((option) => {
      return formatItem(helper.optionTerm(option), helper.optionDescription(option));
    });
    if (optionList.length > 0) {
      output = output.concat(['Options:', formatList(optionList), '']);
    }

    if (this.showGlobalOptions) {
      const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
        return formatItem(helper.optionTerm(option), helper.optionDescription(option));
      });
      if (globalOptionList.length > 0) {
        output = output.concat(['Global Options:', formatList(globalOptionList), '']);
      }
    }

    // Commands
    const commandList = helper.visibleCommands(cmd).map((cmd) => {
      return formatItem(helper.subcommandTerm(cmd), helper.subcommandDescription(cmd));
    });
    if (commandList.length > 0) {
      output = output.concat(['Commands:', formatList(commandList), '']);
    }

    return output.join('\n');
  }

  /**
   * Calculate the pad width from the maximum term length.
   *
   * @param {Command} cmd
   * @param {Help} helper
   * @returns {number}
   */

  padWidth(cmd, helper) {
    return Math.max(
      helper.longestOptionTermLength(cmd, helper),
      helper.longestGlobalOptionTermLength(cmd, helper),
      helper.longestSubcommandTermLength(cmd, helper),
      helper.longestArgumentTermLength(cmd, helper)
    );
  }

  /**
   * Wrap the given string to width characters per line, with lines after the first indented.
   * Do not wrap if insufficient room for wrapping (minColumnWidth), or string is manually formatted.
   *
   * @param {string} str
   * @param {number} width
   * @param {number} indent
   * @param {number} [minColumnWidth=40]
   * @return {string}
   *
   */

  wrap(str, width, indent, minColumnWidth = 40) {
    // Full \s characters, minus the linefeeds.
    const indents = ' \\f\\t\\v\u00a0\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff';
    // Detect manually wrapped and indented strings by searching for line break followed by spaces.
    const manualIndent = new RegExp(`[\\n][${indents}]+`);
    if (str.match(manualIndent)) return str;
    // Do not wrap if not enough room for a wrapped column of text (as could end up with a word per line).
    const columnWidth = width - indent;
    if (columnWidth < minColumnWidth) return str;

    const leadingStr = str.slice(0, indent);
    const columnText = str.slice(indent).replace('\r\n', '\n');
    const indentString = ' '.repeat(indent);
    const zeroWidthSpace = '\u200B';
    const breaks = `\\s${zeroWidthSpace}`;
    // Match line end (so empty lines don't collapse),
    // or as much text as will fit in column, or excess text up to first break.
    const regex = new RegExp(`\n|.{1,${columnWidth - 1}}([${breaks}]|$)|[^${breaks}]+?([${breaks}]|$)`, 'g');
    const lines = columnText.match(regex) || [];
    return leadingStr + lines.map((line, i) => {
      if (line === '\n') return ''; // preserve empty lines
      return ((i > 0) ? indentString : '') + line.trimEnd();
    }).join('\n');
  }
}

exports.Help = Help;


/***/ }),

/***/ 311:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {

const { InvalidArgumentError } = __webpack_require__(831);

// @ts-check

class Option {
  /**
   * Initialize a new `Option` with the given `flags` and `description`.
   *
   * @param {string} flags
   * @param {string} [description]
   */

  constructor(flags, description) {
    this.flags = flags;
    this.description = description || '';

    this.required = flags.includes('<'); // A value must be supplied when the option is specified.
    this.optional = flags.includes('['); // A value is optional when the option is specified.
    // variadic test ignores <value,...> et al which might be used to describe custom splitting of single argument
    this.variadic = /\w\.\.\.[>\]]$/.test(flags); // The option can take multiple values.
    this.mandatory = false; // The option must have a value after parsing, which usually means it must be specified on command line.
    const optionFlags = splitOptionFlags(flags);
    this.short = optionFlags.shortFlag;
    this.long = optionFlags.longFlag;
    this.negate = false;
    if (this.long) {
      this.negate = this.long.startsWith('--no-');
    }
    this.defaultValue = undefined;
    this.defaultValueDescription = undefined;
    this.presetArg = undefined;
    this.envVar = undefined;
    this.parseArg = undefined;
    this.hidden = false;
    this.argChoices = undefined;
    this.conflictsWith = [];
    this.implied = undefined;
  }

  /**
   * Set the default value, and optionally supply the description to be displayed in the help.
   *
   * @param {any} value
   * @param {string} [description]
   * @return {Option}
   */

  default(value, description) {
    this.defaultValue = value;
    this.defaultValueDescription = description;
    return this;
  }

  /**
   * Preset to use when option used without option-argument, especially optional but also boolean and negated.
   * The custom processing (parseArg) is called.
   *
   * @example
   * new Option('--color').default('GREYSCALE').preset('RGB');
   * new Option('--donate [amount]').preset('20').argParser(parseFloat);
   *
   * @param {any} arg
   * @return {Option}
   */

  preset(arg) {
    this.presetArg = arg;
    return this;
  }

  /**
   * Add option name(s) that conflict with this option.
   * An error will be displayed if conflicting options are found during parsing.
   *
   * @example
   * new Option('--rgb').conflicts('cmyk');
   * new Option('--js').conflicts(['ts', 'jsx']);
   *
   * @param {string | string[]} names
   * @return {Option}
   */

  conflicts(names) {
    this.conflictsWith = this.conflictsWith.concat(names);
    return this;
  }

  /**
   * Specify implied option values for when this option is set and the implied options are not.
   *
   * The custom processing (parseArg) is not called on the implied values.
   *
   * @example
   * program
   *   .addOption(new Option('--log', 'write logging information to file'))
   *   .addOption(new Option('--trace', 'log extra details').implies({ log: 'trace.txt' }));
   *
   * @param {Object} impliedOptionValues
   * @return {Option}
   */
  implies(impliedOptionValues) {
    this.implied = Object.assign(this.implied || {}, impliedOptionValues);
    return this;
  }

  /**
   * Set environment variable to check for option value.
   *
   * An environment variable is only used if when processed the current option value is
   * undefined, or the source of the current value is 'default' or 'config' or 'env'.
   *
   * @param {string} name
   * @return {Option}
   */

  env(name) {
    this.envVar = name;
    return this;
  }

  /**
   * Set the custom handler for processing CLI option arguments into option values.
   *
   * @param {Function} [fn]
   * @return {Option}
   */

  argParser(fn) {
    this.parseArg = fn;
    return this;
  }

  /**
   * Whether the option is mandatory and must have a value after parsing.
   *
   * @param {boolean} [mandatory=true]
   * @return {Option}
   */

  makeOptionMandatory(mandatory = true) {
    this.mandatory = !!mandatory;
    return this;
  }

  /**
   * Hide option in help.
   *
   * @param {boolean} [hide=true]
   * @return {Option}
   */

  hideHelp(hide = true) {
    this.hidden = !!hide;
    return this;
  }

  /**
   * @api private
   */

  _concatValue(value, previous) {
    if (previous === this.defaultValue || !Array.isArray(previous)) {
      return [value];
    }

    return previous.concat(value);
  }

  /**
   * Only allow option value to be one of choices.
   *
   * @param {string[]} values
   * @return {Option}
   */

  choices(values) {
    this.argChoices = values.slice();
    this.parseArg = (arg, previous) => {
      if (!this.argChoices.includes(arg)) {
        throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(', ')}.`);
      }
      if (this.variadic) {
        return this._concatValue(arg, previous);
      }
      return arg;
    };
    return this;
  }

  /**
   * Return option name.
   *
   * @return {string}
   */

  name() {
    if (this.long) {
      return this.long.replace(/^--/, '');
    }
    return this.short.replace(/^-/, '');
  }

  /**
   * Return option name, in a camelcase format that can be used
   * as a object attribute key.
   *
   * @return {string}
   * @api private
   */

  attributeName() {
    return camelcase(this.name().replace(/^no-/, ''));
  }

  /**
   * Check if `arg` matches the short or long flag.
   *
   * @param {string} arg
   * @return {boolean}
   * @api private
   */

  is(arg) {
    return this.short === arg || this.long === arg;
  }

  /**
   * Return whether a boolean option.
   *
   * Options are one of boolean, negated, required argument, or optional argument.
   *
   * @return {boolean}
   * @api private
   */

  isBoolean() {
    return !this.required && !this.optional && !this.negate;
  }
}

/**
 * This class is to make it easier to work with dual options, without changing the existing
 * implementation. We support separate dual options for separate positive and negative options,
 * like `--build` and `--no-build`, which share a single option value. This works nicely for some
 * use cases, but is tricky for others where we want separate behaviours despite
 * the single shared option value.
 */
class DualOptions {
  /**
   * @param {Option[]} options
   */
  constructor(options) {
    this.positiveOptions = new Map();
    this.negativeOptions = new Map();
    this.dualOptions = new Set();
    options.forEach(option => {
      if (option.negate) {
        this.negativeOptions.set(option.attributeName(), option);
      } else {
        this.positiveOptions.set(option.attributeName(), option);
      }
    });
    this.negativeOptions.forEach((value, key) => {
      if (this.positiveOptions.has(key)) {
        this.dualOptions.add(key);
      }
    });
  }

  /**
   * Did the value come from the option, and not from possible matching dual option?
   *
   * @param {any} value
   * @param {Option} option
   * @returns {boolean}
   */
  valueFromOption(value, option) {
    const optionKey = option.attributeName();
    if (!this.dualOptions.has(optionKey)) return true;

    // Use the value to deduce if (probably) came from the option.
    const preset = this.negativeOptions.get(optionKey).presetArg;
    const negativeValue = (preset !== undefined) ? preset : false;
    return option.negate === (negativeValue === value);
  }
}

/**
 * Convert string from kebab-case to camelCase.
 *
 * @param {string} str
 * @return {string}
 * @api private
 */

function camelcase(str) {
  return str.split('-').reduce((str, word) => {
    return str + word[0].toUpperCase() + word.slice(1);
  });
}

/**
 * Split the short and long flag out of something like '-m,--mixed <value>'
 *
 * @api private
 */

function splitOptionFlags(flags) {
  let shortFlag;
  let longFlag;
  // Use original very loose parsing to maintain backwards compatibility for now,
  // which allowed for example unintended `-sw, --short-word` [sic].
  const flagParts = flags.split(/[ |,]+/);
  if (flagParts.length > 1 && !/^[[<]/.test(flagParts[1])) shortFlag = flagParts.shift();
  longFlag = flagParts.shift();
  // Add support for lone short flag without significantly changing parsing!
  if (!shortFlag && /^-[^-]$/.test(longFlag)) {
    shortFlag = longFlag;
    longFlag = undefined;
  }
  return { shortFlag, longFlag };
}

exports.Option = Option;
exports.splitOptionFlags = splitOptionFlags;
exports.DualOptions = DualOptions;


/***/ }),

/***/ 426:
/***/ ((__unused_webpack_module, exports) => {

const maxDistance = 3;

function editDistance(a, b) {
  // https://en.wikipedia.org/wiki/Damerau–Levenshtein_distance
  // Calculating optimal string alignment distance, no substring is edited more than once.
  // (Simple implementation.)

  // Quick early exit, return worst case.
  if (Math.abs(a.length - b.length) > maxDistance) return Math.max(a.length, b.length);

  // distance between prefix substrings of a and b
  const d = [];

  // pure deletions turn a into empty string
  for (let i = 0; i <= a.length; i++) {
    d[i] = [i];
  }
  // pure insertions turn empty string into b
  for (let j = 0; j <= b.length; j++) {
    d[0][j] = j;
  }

  // fill matrix
  for (let j = 1; j <= b.length; j++) {
    for (let i = 1; i <= a.length; i++) {
      let cost = 1;
      if (a[i - 1] === b[j - 1]) {
        cost = 0;
      } else {
        cost = 1;
      }
      d[i][j] = Math.min(
        d[i - 1][j] + 1, // deletion
        d[i][j - 1] + 1, // insertion
        d[i - 1][j - 1] + cost // substitution
      );
      // transposition
      if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
        d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
      }
    }
  }

  return d[a.length][b.length];
}

/**
 * Find close matches, restricted to same number of edits.
 *
 * @param {string} word
 * @param {string[]} candidates
 * @returns {string}
 */

function suggestSimilar(word, candidates) {
  if (!candidates || candidates.length === 0) return '';
  // remove possible duplicates
  candidates = Array.from(new Set(candidates));

  const searchingOptions = word.startsWith('--');
  if (searchingOptions) {
    word = word.slice(2);
    candidates = candidates.map(candidate => candidate.slice(2));
  }

  let similar = [];
  let bestDistance = maxDistance;
  const minSimilarity = 0.4;
  candidates.forEach((candidate) => {
    if (candidate.length <= 1) return; // no one character guesses

    const distance = editDistance(word, candidate);
    const length = Math.max(word.length, candidate.length);
    const similarity = (length - distance) / length;
    if (similarity > minSimilarity) {
      if (distance < bestDistance) {
        // better edit distance, throw away previous worse matches
        bestDistance = distance;
        similar = [candidate];
      } else if (distance === bestDistance) {
        similar.push(candidate);
      }
    }
  });

  similar.sort((a, b) => a.localeCompare(b));
  if (searchingOptions) {
    similar = similar.map(candidate => `--${candidate}`);
  }

  if (similar.length > 1) {
    return `\n(Did you mean one of ${similar.join(', ')}?)`;
  }
  if (similar.length === 1) {
    return `\n(Did you mean ${similar[0]}?)`;
  }
  return '';
}

exports.suggestSimilar = suggestSimilar;


/***/ }),

/***/ 708:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

(function webpackUniversalModuleDefinition(root, factory) {
	if(true)
		module.exports = factory(__webpack_require__(198), __webpack_require__(56), __webpack_require__(89), __webpack_require__(810));
	else { var i, a; }
})(this, (__WEBPACK_EXTERNAL_MODULE_child_process__, __WEBPACK_EXTERNAL_MODULE_path__, __WEBPACK_EXTERNAL_MODULE_fs__, __WEBPACK_EXTERNAL_MODULE_app_lib_log__) => {
return /******/ (() => { // webpackBootstrap
/******/ 	var __webpack_modules__ = ({

/***/ "./src/cross-spawn/index.js":
/*!**********************************!*\
  !*** ./src/cross-spawn/index.js ***!
  \**********************************/
/***/ ((module, __unused_webpack_exports, __nested_webpack_require_1098__) => {

"use strict";


const cp = __nested_webpack_require_1098__(/*! child_process */ "child_process");
const parse = __nested_webpack_require_1098__(/*! ./lib/parse */ "./src/cross-spawn/lib/parse.js");
const enoent = __nested_webpack_require_1098__(/*! ./lib/enoent */ "./src/cross-spawn/lib/enoent.js");
const {log} = __nested_webpack_require_1098__(/*! app-lib-log */ "app-lib-log");
function spawn(command, args, options) {
    // Parse the arguments
    const parsed = parse(command, args, options);

    // Spawn the child process
    const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);

    // Hook into child process "exit" event to emit an error if the command
    // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16
    enoent.hookChildProcess(spawned, parsed);

    return spawned;
}

function spawnSync(command, args, options) {
    // Parse the arguments
    const parsed = parse(command, args, options);

    log.md('exe node:',parsed.command, parsed.args,  {...parsed.options,windowsHide:true})
    // Spawn the child process
    const result = cp.spawnSync(parsed.command, parsed.args, {...parsed.options});

    // Analyze if the command does not exist, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16
    result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);

    return result;
}

module.exports = spawn;
module.exports.spawn = spawn;
module.exports.sync = spawnSync;

module.exports._parse = parse;
module.exports._enoent = enoent;


/***/ }),

/***/ "./src/cross-spawn/lib/enoent.js":
/*!***************************************!*\
  !*** ./src/cross-spawn/lib/enoent.js ***!
  \***************************************/
/***/ ((module) => {

"use strict";


const isWin = process.platform === 'win32';

function notFoundError(original, syscall) {
    return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), {
        code: 'ENOENT',
        errno: 'ENOENT',
        syscall: `${syscall} ${original.command}`,
        path: original.command,
        spawnargs: original.args,
    });
}

function hookChildProcess(cp, parsed) {
    if (!isWin) {
        return;
    }

    const originalEmit = cp.emit;

    cp.emit = function (name, arg1) {
        // If emitting "exit" event and exit code is 1, we need to check if
        // the command exists and emit an "error" instead
        // See https://github.com/IndigoUnited/node-cross-spawn/issues/16
        if (name === 'exit') {
            const err = verifyENOENT(arg1, parsed, 'spawn');

            if (err) {
                return originalEmit.call(cp, 'error', err);
            }
        }

        return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params
    };
}

function verifyENOENT(status, parsed) {
    if (isWin && status === 1 && !parsed.file) {
        return notFoundError(parsed.original, 'spawn');
    }

    return null;
}

function verifyENOENTSync(status, parsed) {
    if (isWin && status === 1 && !parsed.file) {
        return notFoundError(parsed.original, 'spawnSync');
    }

    return null;
}

module.exports = {
    hookChildProcess,
    verifyENOENT,
    verifyENOENTSync,
    notFoundError,
};


/***/ }),

/***/ "./src/cross-spawn/lib/parse.js":
/*!**************************************!*\
  !*** ./src/cross-spawn/lib/parse.js ***!
  \**************************************/
/***/ ((module, __unused_webpack_exports, __nested_webpack_require_4632__) => {

"use strict";


const path = __nested_webpack_require_4632__(/*! path */ "path");
const resolveCommand = __nested_webpack_require_4632__(/*! ./util/resolveCommand */ "./src/cross-spawn/lib/util/resolveCommand.js");
const escape = __nested_webpack_require_4632__(/*! ./util/escape */ "./src/cross-spawn/lib/util/escape.js");
const readShebang = __nested_webpack_require_4632__(/*! ./util/readShebang */ "./src/cross-spawn/lib/util/readShebang.js");

const isWin = process.platform === 'win32';
const isExecutableRegExp = /\.(?:com|exe)$/i;
const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;

function detectShebang(parsed) {
    parsed.file = resolveCommand(parsed);

    const shebang = parsed.file && readShebang(parsed.file);

    if (shebang) {
        parsed.args.unshift(parsed.file);
        parsed.command = shebang;

        return resolveCommand(parsed);
    }

    return parsed.file;
}

function parseNonShell(parsed) {
    if (!isWin) {
        return parsed;
    }

    // Detect & add support for shebangs
    const commandFile = detectShebang(parsed);

    // We don't need a shell if the command filename is an executable
    const needsShell = !isExecutableRegExp.test(commandFile);

    // If a shell is required, use cmd.exe and take care of escaping everything correctly
    // Note that `forceShell` is an hidden option used only in tests
    if (parsed.options.forceShell || needsShell) {
        // Need to double escape meta chars if the command is a cmd-shim located in `node_modules/.bin/`
        // The cmd-shim simply calls execute the package bin file with NodeJS, proxying any argument
        // Because the escape of metachars with ^ gets interpreted when the cmd.exe is first called,
        // we need to double escape them
        const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);

        // Normalize posix paths into OS compatible paths (e.g.: foo/bar -> foo\bar)
        // This is necessary otherwise it will always fail with ENOENT in those cases
        parsed.command = path.normalize(parsed.command);

        // Escape command & arguments
        parsed.command = escape.command(parsed.command);
        parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));

        const shellCommand = [parsed.command].concat(parsed.args).join(' ');

        parsed.args = ['/d', '/s', '/c', `"${shellCommand}"`];
        parsed.command = process.env.comspec || 'cmd.exe';
        parsed.options.windowsVerbatimArguments = true; // Tell node's spawn that the arguments are already escaped
    }

    return parsed;
}

function parse(command, args, options) {
    // Normalize arguments, similar to nodejs
    if (args && !Array.isArray(args)) {
        options = args;
        args = null;
    }

    args = args ? args.slice(0) : []; // Clone array to avoid changing the original
    // 添加windows默认不显示
    // let defaultConfig = {windowsHide:true};
    let defaultConfig = {};
    options = Object.assign(defaultConfig, options); // Clone object to avoid changing the original

    // Build our parsed object
    const parsed = {
        command,
        args,
        options,
        file: undefined,
        original: {
            command,
            args,
        },
    };

    // Delegate further parsing to shell or non-shell
    return options.shell ? parsed : parseNonShell(parsed);
}

module.exports = parse;


/***/ }),

/***/ "./src/cross-spawn/lib/util/escape.js":
/*!********************************************!*\
  !*** ./src/cross-spawn/lib/util/escape.js ***!
  \********************************************/
/***/ ((module) => {

"use strict";


// See http://www.robvanderwoude.com/escapechars.php
const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g;

function escapeCommand(arg) {
    // Escape meta chars
    arg = arg.replace(metaCharsRegExp, '^$1');

    return arg;
}

function escapeArgument(arg, doubleEscapeMetaChars) {
    // Convert to string
    arg = `${arg}`;

    // Algorithm below is based on https://qntm.org/cmd

    // Sequence of backslashes followed by a double quote:
    // double up all the backslashes and escape the double quote
    arg = arg.replace(/(\\*)"/g, '$1$1\\"');

    // Sequence of backslashes followed by the end of the string
    // (which will become a double quote later):
    // double up all the backslashes
    arg = arg.replace(/(\\*)$/, '$1$1');

    // All other backslashes occur literally

    // Quote the whole thing:
    arg = `"${arg}"`;

    // Escape meta chars
    arg = arg.replace(metaCharsRegExp, '^$1');

    // Double escape meta chars if necessary
    if (doubleEscapeMetaChars) {
        arg = arg.replace(metaCharsRegExp, '^$1');
    }

    return arg;
}

module.exports.command = escapeCommand;
module.exports.argument = escapeArgument;


/***/ }),

/***/ "./src/cross-spawn/lib/util/path-key/path-key.js":
/*!*******************************************************!*\
  !*** ./src/cross-spawn/lib/util/path-key/path-key.js ***!
  \*******************************************************/
/***/ ((module) => {

"use strict";


const pathKey = (options = {}) => {
	const environment = options.env || process.env;
	const platform = options.platform || process.platform;

	if (platform !== 'win32') {
		return 'PATH';
	}

	return Object.keys(environment).reverse().find(key => key.toUpperCase() === 'PATH') || 'Path';
};

module.exports = pathKey;
// TODO: Remove this for the next major release
module.exports["default"] = pathKey;


/***/ }),

/***/ "./src/cross-spawn/lib/util/readShebang.js":
/*!*************************************************!*\
  !*** ./src/cross-spawn/lib/util/readShebang.js ***!
  \*************************************************/
/***/ ((module, __unused_webpack_exports, __nested_webpack_require_10543__) => {

"use strict";


const fs = __nested_webpack_require_10543__(/*! fs */ "fs");
// const shebangCommand = require('shebang-command');
const shebangCommand = __nested_webpack_require_10543__(/*! ./shebang-command/shebang-command.js */ "./src/cross-spawn/lib/util/shebang-command/shebang-command.js");
function readShebang(command) {
    // Read the first 150 bytes from the file
    const size = 150;
    const buffer = Buffer.alloc(size);

    let fd;

    try {
        fd = fs.openSync(command, 'r');
        fs.readSync(fd, buffer, 0, size, 0);
        fs.closeSync(fd);
    } catch (e) { /* Empty */ }

    // Attempt to extract shebang (null is returned if not a shebang)
    return shebangCommand(buffer.toString());
}

module.exports = readShebang;


/***/ }),

/***/ "./src/cross-spawn/lib/util/resolveCommand.js":
/*!****************************************************!*\
  !*** ./src/cross-spawn/lib/util/resolveCommand.js ***!
  \****************************************************/
/***/ ((module, __unused_webpack_exports, __nested_webpack_require_11602__) => {

"use strict";


const path = __nested_webpack_require_11602__(/*! path */ "path");
// const which = require('which');
const which = __nested_webpack_require_11602__(/*! ./which/which */ "./src/cross-spawn/lib/util/which/which.js");

const getPathKey = __nested_webpack_require_11602__(/*! ./path-key/path-key */ "./src/cross-spawn/lib/util/path-key/path-key.js");

function resolveCommandAttempt(parsed, withoutPathExt) {
    const env = parsed.options.env || process.env;
    const cwd = process.cwd();
    const hasCustomCwd = parsed.options.cwd != null;
    // Worker threads do not have process.chdir()
    const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined && !process.chdir.disabled;

    // If a custom `cwd` was specified, we need to change the process cwd
    // because `which` will do stat calls but does not support a custom cwd
    if (shouldSwitchCwd) {
        try {
            process.chdir(parsed.options.cwd);
        } catch (err) {
            /* Empty */
        }
    }

    let resolved;

    try {
        resolved = which.sync(parsed.command, {
            path: env[getPathKey({ env })],
            pathExt: withoutPathExt ? path.delimiter : undefined,
        });
    } catch (e) {
        /* Empty */
    } finally {
        if (shouldSwitchCwd) {
            process.chdir(cwd);
        }
    }

    // If we successfully resolved, ensure that an absolute path is returned
    // Note that when a custom `cwd` was used, we need to resolve to an absolute path based on it
    if (resolved) {
        resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : '', resolved);
    }

    return resolved;
}

function resolveCommand(parsed) {
    return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true);
}

module.exports = resolveCommand;


/***/ }),

/***/ "./src/cross-spawn/lib/util/shebang-command/shebang-command.js":
/*!*********************************************************************!*\
  !*** ./src/cross-spawn/lib/util/shebang-command/shebang-command.js ***!
  \*********************************************************************/
/***/ ((module, __unused_webpack_exports, __nested_webpack_require_13798__) => {

"use strict";

// const shebangRegex = require('shebang-regex');
const shebangRegex = __nested_webpack_require_13798__(/*! ./shebang-regex/shebang-regex.js */ "./src/cross-spawn/lib/util/shebang-command/shebang-regex/shebang-regex.js");

module.exports = (string = '') => {
	const match = string.match(shebangRegex);

	if (!match) {
		return null;
	}

	const [path, argument] = match[0].replace(/#! ?/, '').split(' ');
	const binary = path.split('/').pop();

	if (binary === 'env') {
		return argument;
	}

	return argument ? `${binary} ${argument}` : binary;
};


/***/ }),

/***/ "./src/cross-spawn/lib/util/shebang-command/shebang-regex/shebang-regex.js":
/*!*********************************************************************************!*\
  !*** ./src/cross-spawn/lib/util/shebang-command/shebang-regex/shebang-regex.js ***!
  \*********************************************************************************/
/***/ ((module) => {

"use strict";

module.exports = /^#!(.*)/;


/***/ }),

/***/ "./src/cross-spawn/lib/util/which/isexe/isexe.js":
/*!*******************************************************!*\
  !*** ./src/cross-spawn/lib/util/which/isexe/isexe.js ***!
  \*******************************************************/
/***/ ((module, __unused_webpack_exports, __nested_webpack_require_15112__) => {

var fs = __nested_webpack_require_15112__(/*! fs */ "fs")
var core
if (process.platform === 'win32' || __nested_webpack_require_15112__.g.TESTING_WINDOWS) {
  core = __nested_webpack_require_15112__(/*! ./windows.js */ "./src/cross-spawn/lib/util/which/isexe/windows.js")
} else {
  core = __nested_webpack_require_15112__(/*! ./mode.js */ "./src/cross-spawn/lib/util/which/isexe/mode.js")
}

module.exports = isexe
isexe.sync = sync

function isexe (path, options, cb) {
  if (typeof options === 'function') {
    cb = options
    options = {}
  }

  if (!cb) {
    if (typeof Promise !== 'function') {
      throw new TypeError('callback not provided')
    }

    return new Promise(function (resolve, reject) {
      isexe(path, options || {}, function (er, is) {
        if (er) {
          reject(er)
        } else {
          resolve(is)
        }
      })
    })
  }

  core(path, options || {}, function (er, is) {
    // ignore EACCES because that just means we aren't allowed to run it
    if (er) {
      if (er.code === 'EACCES' || options && options.ignoreErrors) {
        er = null
        is = false
      }
    }
    cb(er, is)
  })
}

function sync (path, options) {
  // my kingdom for a filtered catch
  try {
    return core.sync(path, options || {})
  } catch (er) {
    if (options && options.ignoreErrors || er.code === 'EACCES') {
      return false
    } else {
      throw er
    }
  }
}


/***/ }),

/***/ "./src/cross-spawn/lib/util/which/isexe/mode.js":
/*!******************************************************!*\
  !*** ./src/cross-spawn/lib/util/which/isexe/mode.js ***!
  \******************************************************/
/***/ ((module, __unused_webpack_exports, __nested_webpack_require_16850__) => {

module.exports = isexe
isexe.sync = sync

var fs = __nested_webpack_require_16850__(/*! fs */ "fs")

function isexe (path, options, cb) {
  fs.stat(path, function (er, stat) {
    cb(er, er ? false : checkStat(stat, options))
  })
}

function sync (path, options) {
  return checkStat(fs.statSync(path), options)
}

function checkStat (stat, options) {
  return stat.isFile() && checkMode(stat, options)
}

function checkMode (stat, options) {
  var mod = stat.mode
  var uid = stat.uid
  var gid = stat.gid

  var myUid = options.uid !== undefined ?
    options.uid : process.getuid && process.getuid()
  var myGid = options.gid !== undefined ?
    options.gid : process.getgid && process.getgid()

  var u = parseInt('100', 8)
  var g = parseInt('010', 8)
  var o = parseInt('001', 8)
  var ug = u | g

  var ret = (mod & o) ||
    (mod & g) && gid === myGid ||
    (mod & u) && uid === myUid ||
    (mod & ug) && myUid === 0

  return ret
}


/***/ }),

/***/ "./src/cross-spawn/lib/util/which/isexe/windows.js":
/*!*********************************************************!*\
  !*** ./src/cross-spawn/lib/util/which/isexe/windows.js ***!
  \*********************************************************/
/***/ ((module, __unused_webpack_exports, __nested_webpack_require_18151__) => {

module.exports = isexe
isexe.sync = sync

var fs = __nested_webpack_require_18151__(/*! fs */ "fs")

function checkPathExt (path, options) {
  var pathext = options.pathExt !== undefined ?
    options.pathExt : process.env.PATHEXT

  if (!pathext) {
    return true
  }

  pathext = pathext.split(';')
  if (pathext.indexOf('') !== -1) {
    return true
  }
  for (var i = 0; i < pathext.length; i++) {
    var p = pathext[i].toLowerCase()
    if (p && path.substr(-p.length).toLowerCase() === p) {
      return true
    }
  }
  return false
}

function checkStat (stat, path, options) {
  if (!stat.isSymbolicLink() && !stat.isFile()) {
    return false
  }
  return checkPathExt(path, options)
}

function isexe (path, options, cb) {
  fs.stat(path, function (er, stat) {
    cb(er, er ? false : checkStat(stat, path, options))
  })
}

function sync (path, options) {
  return checkStat(fs.statSync(path), path, options)
}


/***/ }),

/***/ "./src/cross-spawn/lib/util/which/which.js":
/*!*************************************************!*\
  !*** ./src/cross-spawn/lib/util/which/which.js ***!
  \*************************************************/
/***/ ((module, __unused_webpack_exports, __nested_webpack_require_19402__) => {

const isWindows = process.platform === 'win32' ||
    process.env.OSTYPE === 'cygwin' ||
    process.env.OSTYPE === 'msys'

const path = __nested_webpack_require_19402__(/*! path */ "path")
const COLON = isWindows ? ';' : ':'
// const isexe = require('isexe')
const isexe = __nested_webpack_require_19402__(/*! ./isexe/isexe */ "./src/cross-spawn/lib/util/which/isexe/isexe.js")

const getNotFoundError = (cmd) =>
  Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' })

const getPathInfo = (cmd, opt) => {
  const colon = opt.colon || COLON

  // If it has a slash, then we don't bother searching the pathenv.
  // just check the file itself, and that's it.
  const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? ['']
    : (
      [
        // windows always checks the cwd first
        ...(isWindows ? [process.cwd()] : []),
        ...(opt.path || process.env.PATH ||
          /* istanbul ignore next: very unusual */ '').split(colon),
      ]
    )
  const pathExtExe = isWindows
    ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM'
    : ''
  const pathExt = isWindows ? pathExtExe.split(colon) : ['']

  if (isWindows) {
    if (cmd.indexOf('.') !== -1 && pathExt[0] !== '')
      pathExt.unshift('')
  }

  return {
    pathEnv,
    pathExt,
    pathExtExe,
  }
}

const which = (cmd, opt, cb) => {
  if (typeof opt === 'function') {
    cb = opt
    opt = {}
  }
  if (!opt)
    opt = {}

  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt)
  const found = []

  const step = i => new Promise((resolve, reject) => {
    if (i === pathEnv.length)
      return opt.all && found.length ? resolve(found)
        : reject(getNotFoundError(cmd))

    const ppRaw = pathEnv[i]
    const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw

    const pCmd = path.join(pathPart, cmd)
    const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd
      : pCmd

    resolve(subStep(p, i, 0))
  })

  const subStep = (p, i, ii) => new Promise((resolve, reject) => {
    if (ii === pathExt.length)
      return resolve(step(i + 1))
    const ext = pathExt[ii]
    isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
      if (!er && is) {
        if (opt.all)
          found.push(p + ext)
        else
          return resolve(p + ext)
      }
      return resolve(subStep(p, i, ii + 1))
    })
  })

  return cb ? step(0).then(res => cb(null, res), cb) : step(0)
}

const whichSync = (cmd, opt) => {
  opt = opt || {}

  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt)
  const found = []

  for (let i = 0; i < pathEnv.length; i ++) {
    const ppRaw = pathEnv[i]
    const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw

    const pCmd = path.join(pathPart, cmd)
    const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd
      : pCmd

    for (let j = 0; j < pathExt.length; j ++) {
      const cur = p + pathExt[j]
      try {
        const is = isexe.sync(cur, { pathExt: pathExtExe })
        if (is) {
          if (opt.all)
            found.push(cur)
          else
            return cur
        }
      } catch (ex) {}
    }
  }

  if (opt.all && found.length)
    return found

  if (opt.nothrow)
    return null

  throw getNotFoundError(cmd)
}

module.exports = which
which.sync = whichSync


/***/ }),

/***/ "app-lib-log":
/*!******************************!*\
  !*** external "app-lib-log" ***!
  \******************************/
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE_app_lib_log__;

/***/ }),

/***/ "child_process":
/*!********************************!*\
  !*** external "child_process" ***!
  \********************************/
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE_child_process__;

/***/ }),

/***/ "fs":
/*!*********************!*\
  !*** external "fs" ***!
  \*********************/
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE_fs__;

/***/ }),

/***/ "path":
/*!***********************!*\
  !*** external "path" ***!
  \***********************/
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE_path__;

/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __nested_webpack_require_23948__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId](module, module.exports, __nested_webpack_require_23948__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
/******/ 	/* webpack/runtime/global */
/******/ 	(() => {
/******/ 		__nested_webpack_require_23948__.g = (function() {
/******/ 			if (typeof globalThis === 'object') return globalThis;
/******/ 			try {
/******/ 				return this || new Function('return this')();
/******/ 			} catch (e) {
/******/ 				if (typeof window === 'object') return window;
/******/ 			}
/******/ 		})();
/******/ 	})();
/******/ 	
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
var exports = __webpack_exports__;
/*!**********************!*\
  !*** ./src/index.js ***!
  \**********************/
// 支持同步 异步 bat/shell 脚本和命令
// 同步 spawn
// spawn('npm', ['list', '-g', '-depth', '0'], { stdio: 'inherit' }); 
// 异步 pawn.sync
// spawn.sync('npm', ['list', '-g', '-depth', '0'], { stdio: 'inherit' });
// 异步执行多个bat文件
// spawn.sync('./demo01/ping.bat', [], { stdio: 'inherit' }); 
// spawn.sync('./demo01/echo.bat', [], { stdio: 'inherit' });

// 注意:
// 有的命令会晃动 eg: tree
// 一直晃动
// spawn.sync('tree.bat', [], { stdio: 'inherit',cwd:'./demo01' });
// cwd 有的命令 tree 会抖动
// spawn.sync('echo.bat', [], { stdio: 'inherit', cwd: './demo01/' });


// https://github.com/moxystudio/node-cross-spawn
// https://nodejs.org/docs/latest-v14.x/api/child_process.html#child_process_options_stdio

// const spawn = require('cross-spawn');
const spawn = __nested_webpack_require_23948__(/*! ./cross-spawn/index.js */ "./src/cross-spawn/index.js");
const {log} = __nested_webpack_require_23948__(/*! app-lib-log */ "app-lib-log");


const isDebug = ()=>{
    const { DEBUG } = process?.env || {};
    // 命令行参数优先 直接设置环境变量DEBUG 或者
    let debug = process.argv.slice(2).includes('--debug') || DEBUG;
    return debug;
  }
  
/**
 * ---
 * ##### 数据类型判断 
 * @function
 * @param {string} commondOrFile  可执行的文件路径或者文件
 * @param {array} args  所有命令行参数
 * @param {object} options 执行参数配置
 * @param {boolean} [isAsync=true]  是否同步 
 * @returns {null} 无返回
 * 
 * ##### Examples
 *  option下支持的参数
 *  * stidio 支持的 [pipe,overlapped,ignore,inherit]
 *   ```
 *      inherit  // Child will use parent's stdios.
 *      stdio: ['pipe', 'pipe', process.stderr]  // Spawn child sharing only stderr.
 *   ```
 */
 const exec = (commondOrFile, args,opt, isAsync = true) => {
    let fn = isAsync ? spawn.sync : spawn;
    let options = opt || {};
    if (!options.stdio) {
        options.stdio = isDebug() ? 'inherit' : ['ignore','ignore','inherit'];
    }
    // 默认模式内部输出
    // debug模式输出全部
    // 否则值输出错误
    log.md.apply(log, [fn.name, commondOrFile, JSON.stringify(args),opt, options, isAsync]);
    return fn(commondOrFile, args, options)
}

exports.exec = exec;

})();

/******/ 	return __webpack_exports__;
/******/ })()
;
});
//# sourceMappingURL=index.js.map

/***/ }),

/***/ 798:
/***/ (function(module) {

(function webpackUniversalModuleDefinition(root, factory) {
	if(true)
		module.exports = factory();
	else { var i, a; }
})(this, () => {
return /******/ (() => { // webpackBootstrap
/******/ 	"use strict";
/******/ 	// The require scope
/******/ 	var __nested_webpack_require_468__ = {};
/******/ 	
/************************************************************************/
/******/ 	/* webpack/runtime/define property getters */
/******/ 	(() => {
/******/ 		// define getter functions for harmony exports
/******/ 		__nested_webpack_require_468__.d = (exports, definition) => {
/******/ 			for(var key in definition) {
/******/ 				if(__nested_webpack_require_468__.o(definition, key) && !__nested_webpack_require_468__.o(exports, key)) {
/******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ 				}
/******/ 			}
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/global */
/******/ 	(() => {
/******/ 		__nested_webpack_require_468__.g = (function() {
/******/ 			if (typeof globalThis === 'object') return globalThis;
/******/ 			try {
/******/ 				return this || new Function('return this')();
/******/ 			} catch (e) {
/******/ 				if (typeof window === 'object') return window;
/******/ 			}
/******/ 		})();
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
/******/ 	(() => {
/******/ 		__nested_webpack_require_468__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/make namespace object */
/******/ 	(() => {
/******/ 		// define __esModule on exports
/******/ 		__nested_webpack_require_468__.r = (exports) => {
/******/ 			if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 				Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 			}
/******/ 			Object.defineProperty(exports, '__esModule', { value: true });
/******/ 		};
/******/ 	})();
/******/ 	
/************************************************************************/
var __webpack_exports__ = {};
/*!**********************!*\
  !*** ./src/index.js ***!
  \**********************/
__nested_webpack_require_468__.r(__webpack_exports__);
/* harmony export */ __nested_webpack_require_468__.d(__webpack_exports__, {
/* harmony export */   ENV: () => (/* binding */ ENV),
/* harmony export */   bindToGlobal: () => (/* binding */ bindToGlobal),
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   getEnv: () => (/* binding */ getEnv),
/* harmony export */   getGlobal: () => (/* binding */ getGlobal),
/* harmony export */   getbindData: () => (/* binding */ getbindData),
/* harmony export */   isBindToGlobal: () => (/* binding */ isBindToGlobal),
/* harmony export */   isBroswerEnv: () => (/* binding */ isBroswerEnv),
/* harmony export */   isNodeEnv: () => (/* binding */ isNodeEnv)
/* harmony export */ });

/**
 * 支持的环境变量
 *  ```
 *  *  NODE: 'node',       // ndoejs 环境
 *  *  BROWSER: 'browser', // 浏览器环境
 *  ```
 */
 const ENV = {
    NODE: 'node', // ndoejs 环境
    BROWSER: 'browser', // 浏览器环境
}

/**
 * 获取当前环境
 * 
 * @function
 * @returns  {string} 当前环境常量
 */
const getEnv = () => {
    let root = getGlobal();
    return root.window == root ? ENV.BROWSER : ENV.NODE;
}

/**
 * 判断是否为nodejs环境
 * 
 * @function
 * @returns {Boolean}
 *  * true 是nodejs环境
 *  * false 不是nodejs环境
 */
const isNodeEnv = () => getEnv() === ENV.NODE;


/**
 * 判断是否为浏览器环境
 * 
 * @function
 * @returns {Boolean}
 *  * true 是浏览器环境
 *  * false 不是浏览器环境
 */
const isBroswerEnv = () => getEnv() === ENV.BROWSER;

/**
* 获取全局变量
* 
*
* @returns  {Object} - 获取的全局变量 
*  * window  
*  * global
* @description
*   获取当前运行环境的全局变量
*    * 支持浏览器 window
*    * 支持nodejs gloabl
* @function 
*/
const getGlobal = () => {
    let root;
    if (typeof __nested_webpack_require_468__.g === 'object') {
        root = __nested_webpack_require_468__.g;
    } else if (typeof window === 'object') {
        root = window;
    }
    return root;
}

/**
 * 获取绑定数据
 * 
 * 
 * @param {string} namespace  命名空间
 * @returns  {any}  已绑定的值
 * @function
 */
const getbindData = (namespace) => {
    let root = getGlobal();
    if (!root) throw new Error('未找到当前环境的全局变量');
    return root[namespace];
}


/**
 * 绑定数据到全局
 *  
 * 
 * @param {string} namespace 命名空间
 * @param {any} bindData  绑定数据
 * @param {boolean} [isForce=false]   是否强制绑定  - 存在当前值时,进行强制绑定
 * @returns {any} 全局已绑定的值
 * @function
 */
const bindToGlobal = (namespace, bindData, isForce) => {
    let isBind = isBindToGlobal(namespace);
    if (isBind && !isForce) return getbindData(namespace);
    let root = getGlobal()
    root[namespace] = bindData;
    return bindData;
}


/**
 *  是否也绑定到全局
 * 
 *
 * @param {string} namespace  命名空间
 * @param {Object} [needbindData='undefined'] - 绑定对象
 * @returns  {boolean}  是否绑定
 *  * true  已绑定  
 *  * false 未绑定
 * @description 
 *   是否也绑定到全局
 *   * needbindData  绑定对象不为undefined时:
 *   * 比对值相等 或者 json 序列化后相等 则表示已绑定
 * @function 
 */
const isBindToGlobal = (namespace, needbindData) => {
    if (!namespace) throw new Error('必须执行绑定名称');
    let root = getGlobal();
    /**
     * @throws {DOMException}
     */
    if (!root) throw new Error('未找到当前环境的全局变量');
    let bindData = root[namespace];
    //  全局对象上的属性为undifed 表示未绑定
    if (void 0 === bindData) return false;
    // 需要比对指定绑定的值 值直接相等或者json 序列化后相等 则表示1已绑定
    if (void 0 != needbindData) {
        return bindData === needbindData || JSON.stringify(bindData) === JSON.stringify(needbindData);
    }

    return true;
}



/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (bindToGlobal);
/******/ 	return __webpack_exports__;
/******/ })()
;
});
//# sourceMappingURL=index.js.map

/***/ }),

/***/ 810:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

(function webpackUniversalModuleDefinition(root, factory) {
	if(true)
		module.exports = factory(__webpack_require__(798));
	else { var i, a; }
})(this, (__WEBPACK_EXTERNAL_MODULE_app_lib_global__) => {
return /******/ (() => { // webpackBootstrap
/******/ 	"use strict";
/******/ 	var __webpack_modules__ = ({

/***/ "app-lib-global":
/*!*********************************!*\
  !*** external "app-lib-global" ***!
  \*********************************/
/***/ ((module) => {

module.exports = __WEBPACK_EXTERNAL_MODULE_app_lib_global__;

/***/ }),

/***/ "./src/chalk/source/index.js":
/*!***********************************!*\
  !*** ./src/chalk/source/index.js ***!
  \***********************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nested_webpack_require_1095__) => {

__nested_webpack_require_1095__.r(__webpack_exports__);
/* harmony export */ __nested_webpack_require_1095__.d(__webpack_exports__, {
/* harmony export */   Chalk: () => (/* binding */ Chalk),
/* harmony export */   backgroundColorNames: () => (/* reexport safe */ _ansi_styles__WEBPACK_IMPORTED_MODULE_0__.backgroundColorNames),
/* harmony export */   backgroundColors: () => (/* reexport safe */ _ansi_styles__WEBPACK_IMPORTED_MODULE_0__.backgroundColorNames),
/* harmony export */   chalkStderr: () => (/* binding */ chalkStderr),
/* harmony export */   colorNames: () => (/* reexport safe */ _ansi_styles__WEBPACK_IMPORTED_MODULE_0__.colorNames),
/* harmony export */   colors: () => (/* reexport safe */ _ansi_styles__WEBPACK_IMPORTED_MODULE_0__.colorNames),
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   foregroundColorNames: () => (/* reexport safe */ _ansi_styles__WEBPACK_IMPORTED_MODULE_0__.foregroundColorNames),
/* harmony export */   foregroundColors: () => (/* reexport safe */ _ansi_styles__WEBPACK_IMPORTED_MODULE_0__.foregroundColorNames),
/* harmony export */   modifierNames: () => (/* reexport safe */ _ansi_styles__WEBPACK_IMPORTED_MODULE_0__.modifierNames),
/* harmony export */   modifiers: () => (/* reexport safe */ _ansi_styles__WEBPACK_IMPORTED_MODULE_0__.modifierNames),
/* harmony export */   supportsColor: () => (/* binding */ stdoutColor),
/* harmony export */   supportsColorStderr: () => (/* binding */ stderrColor)
/* harmony export */ });
/* harmony import */ var _ansi_styles__WEBPACK_IMPORTED_MODULE_0__ = __nested_webpack_require_1095__(/*! ./vendor/ansi-styles/index.js */ "./src/chalk/source/vendor/ansi-styles/index.js");
/* harmony import */ var _supports_color__WEBPACK_IMPORTED_MODULE_1__ = __nested_webpack_require_1095__(/*! #supports-color */ "./src/chalk/source/vendor/supports-color/browser.js");
/* harmony import */ var _utilities_js__WEBPACK_IMPORTED_MODULE_2__ = __nested_webpack_require_1095__(/*! ./utilities.js */ "./src/chalk/source/utilities.js");




const {stdout: stdoutColor, stderr: stderrColor} = _supports_color__WEBPACK_IMPORTED_MODULE_1__["default"];

const GENERATOR = Symbol('GENERATOR');
const STYLER = Symbol('STYLER');
const IS_EMPTY = Symbol('IS_EMPTY');

// `supportsColor.level` → `ansiStyles.color[name]` mapping
const levelMapping = [
	'ansi',
	'ansi',
	'ansi256',
	'ansi16m',
];

const styles = Object.create(null);

const applyOptions = (object, options = {}) => {
	if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
		throw new Error('The `level` option should be an integer from 0 to 3');
	}

	// Detect level if not set manually
	const colorLevel = stdoutColor ? stdoutColor.level : 0;
	object.level = options.level === undefined ? colorLevel : options.level;
};

class Chalk {
	constructor(options) {
		// eslint-disable-next-line no-constructor-return
		return chalkFactory(options);
	}
}

const chalkFactory = options => {
	const chalk = (...strings) => strings.join(' ');
	applyOptions(chalk, options);

	Object.setPrototypeOf(chalk, createChalk.prototype);

	return chalk;
};

function createChalk(options) {
	return chalkFactory(options);
}

Object.setPrototypeOf(createChalk.prototype, Function.prototype);

for (const [styleName, style] of Object.entries(_ansi_styles__WEBPACK_IMPORTED_MODULE_0__["default"])) {
	styles[styleName] = {
		get() {
			const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
			Object.defineProperty(this, styleName, {value: builder});
			return builder;
		},
	};
}

styles.visible = {
	get() {
		const builder = createBuilder(this, this[STYLER], true);
		Object.defineProperty(this, 'visible', {value: builder});
		return builder;
	},
};

const getModelAnsi = (model, level, type, ...arguments_) => {
	if (model === 'rgb') {
		if (level === 'ansi16m') {
			return _ansi_styles__WEBPACK_IMPORTED_MODULE_0__["default"][type].ansi16m(...arguments_);
		}

		if (level === 'ansi256') {
			return _ansi_styles__WEBPACK_IMPORTED_MODULE_0__["default"][type].ansi256(_ansi_styles__WEBPACK_IMPORTED_MODULE_0__["default"].rgbToAnsi256(...arguments_));
		}

		return _ansi_styles__WEBPACK_IMPORTED_MODULE_0__["default"][type].ansi(_ansi_styles__WEBPACK_IMPORTED_MODULE_0__["default"].rgbToAnsi(...arguments_));
	}

	if (model === 'hex') {
		return getModelAnsi('rgb', level, type, ..._ansi_styles__WEBPACK_IMPORTED_MODULE_0__["default"].hexToRgb(...arguments_));
	}

	return _ansi_styles__WEBPACK_IMPORTED_MODULE_0__["default"][type][model](...arguments_);
};

const usedModels = ['rgb', 'hex', 'ansi256'];

for (const model of usedModels) {
	styles[model] = {
		get() {
			const {level} = this;
			return function (...arguments_) {
				const styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), _ansi_styles__WEBPACK_IMPORTED_MODULE_0__["default"].color.close, this[STYLER]);
				return createBuilder(this, styler, this[IS_EMPTY]);
			};
		},
	};

	const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
	styles[bgModel] = {
		get() {
			const {level} = this;
			return function (...arguments_) {
				const styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), _ansi_styles__WEBPACK_IMPORTED_MODULE_0__["default"].bgColor.close, this[STYLER]);
				return createBuilder(this, styler, this[IS_EMPTY]);
			};
		},
	};
}

const proto = Object.defineProperties(() => {}, {
	...styles,
	level: {
		enumerable: true,
		get() {
			return this[GENERATOR].level;
		},
		set(level) {
			this[GENERATOR].level = level;
		},
	},
});

const createStyler = (open, close, parent) => {
	let openAll;
	let closeAll;
	if (parent === undefined) {
		openAll = open;
		closeAll = close;
	} else {
		openAll = parent.openAll + open;
		closeAll = close + parent.closeAll;
	}

	return {
		open,
		close,
		openAll,
		closeAll,
		parent,
	};
};

const createBuilder = (self, _styler, _isEmpty) => {
	// Single argument is hot path, implicit coercion is faster than anything
	// eslint-disable-next-line no-implicit-coercion
	const builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' '));

	// We alter the prototype because we must return a function, but there is
	// no way to create a function with a different prototype
	Object.setPrototypeOf(builder, proto);

	builder[GENERATOR] = self;
	builder[STYLER] = _styler;
	builder[IS_EMPTY] = _isEmpty;

	return builder;
};

const applyStyle = (self, string) => {
	if (self.level <= 0 || !string) {
		return self[IS_EMPTY] ? '' : string;
	}

	let styler = self[STYLER];

	if (styler === undefined) {
		return string;
	}

	const {openAll, closeAll} = styler;
	if (string.includes('\u001B')) {
		while (styler !== undefined) {
			// Replace any instances already present with a re-opening code
			// otherwise only the part of the string until said closing code
			// will be colored, and the rest will simply be 'plain'.
			string = (0,_utilities_js__WEBPACK_IMPORTED_MODULE_2__.stringReplaceAll)(string, styler.close, styler.open);

			styler = styler.parent;
		}
	}

	// We can move both next actions out of loop, because remaining actions in loop won't have
	// any/visible effect on parts we add here. Close the styling before a linebreak and reopen
	// after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92
	const lfIndex = string.indexOf('\n');
	if (lfIndex !== -1) {
		string = (0,_utilities_js__WEBPACK_IMPORTED_MODULE_2__.stringEncaseCRLFWithFirstIndex)(string, closeAll, openAll, lfIndex);
	}

	return openAll + string + closeAll;
};

Object.defineProperties(createChalk.prototype, styles);

const chalk = createChalk();
const chalkStderr = createChalk({level: stderrColor ? stderrColor.level : 0});





/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (chalk);


/***/ }),

/***/ "./src/chalk/source/utilities.js":
/*!***************************************!*\
  !*** ./src/chalk/source/utilities.js ***!
  \***************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nested_webpack_require_9470__) => {

__nested_webpack_require_9470__.r(__webpack_exports__);
/* harmony export */ __nested_webpack_require_9470__.d(__webpack_exports__, {
/* harmony export */   stringEncaseCRLFWithFirstIndex: () => (/* binding */ stringEncaseCRLFWithFirstIndex),
/* harmony export */   stringReplaceAll: () => (/* binding */ stringReplaceAll)
/* harmony export */ });
// TODO: When targeting Node.js 16, use `String.prototype.replaceAll`.
function stringReplaceAll(string, substring, replacer) {
	let index = string.indexOf(substring);
	if (index === -1) {
		return string;
	}

	const substringLength = substring.length;
	let endIndex = 0;
	let returnValue = '';
	do {
		returnValue += string.slice(endIndex, index) + substring + replacer;
		endIndex = index + substringLength;
		index = string.indexOf(substring, endIndex);
	} while (index !== -1);

	returnValue += string.slice(endIndex);
	return returnValue;
}

function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
	let endIndex = 0;
	let returnValue = '';
	do {
		const gotCR = string[index - 1] === '\r';
		returnValue += string.slice(endIndex, (gotCR ? index - 1 : index)) + prefix + (gotCR ? '\r\n' : '\n') + postfix;
		endIndex = index + 1;
		index = string.indexOf('\n', endIndex);
	} while (index !== -1);

	returnValue += string.slice(endIndex);
	return returnValue;
}


/***/ }),

/***/ "./src/chalk/source/vendor/ansi-styles/index.js":
/*!******************************************************!*\
  !*** ./src/chalk/source/vendor/ansi-styles/index.js ***!
  \******************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nested_webpack_require_11151__) => {

__nested_webpack_require_11151__.r(__webpack_exports__);
/* harmony export */ __nested_webpack_require_11151__.d(__webpack_exports__, {
/* harmony export */   backgroundColorNames: () => (/* binding */ backgroundColorNames),
/* harmony export */   colorNames: () => (/* binding */ colorNames),
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   foregroundColorNames: () => (/* binding */ foregroundColorNames),
/* harmony export */   modifierNames: () => (/* binding */ modifierNames)
/* harmony export */ });
const ANSI_BACKGROUND_OFFSET = 10;

const wrapAnsi16 = (offset = 0) => code => `\u001B[${code + offset}m`;

const wrapAnsi256 = (offset = 0) => code => `\u001B[${38 + offset};5;${code}m`;

const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`;

const styles = {
	modifier: {
		reset: [0, 0],
		// 21 isn't widely supported and 22 does the same thing
		bold: [1, 22],
		dim: [2, 22],
		italic: [3, 23],
		underline: [4, 24],
		overline: [53, 55],
		inverse: [7, 27],
		hidden: [8, 28],
		strikethrough: [9, 29],
	},
	color: {
		black: [30, 39],
		red: [31, 39],
		green: [32, 39],
		yellow: [33, 39],
		blue: [34, 39],
		magenta: [35, 39],
		cyan: [36, 39],
		white: [37, 39],

		// Bright color
		blackBright: [90, 39],
		gray: [90, 39], // Alias of `blackBright`
		grey: [90, 39], // Alias of `blackBright`
		redBright: [91, 39],
		greenBright: [92, 39],
		yellowBright: [93, 39],
		blueBright: [94, 39],
		magentaBright: [95, 39],
		cyanBright: [96, 39],
		whiteBright: [97, 39],
	},
	bgColor: {
		bgBlack: [40, 49],
		bgRed: [41, 49],
		bgGreen: [42, 49],
		bgYellow: [43, 49],
		bgBlue: [44, 49],
		bgMagenta: [45, 49],
		bgCyan: [46, 49],
		bgWhite: [47, 49],

		// Bright color
		bgBlackBright: [100, 49],
		bgGray: [100, 49], // Alias of `bgBlackBright`
		bgGrey: [100, 49], // Alias of `bgBlackBright`
		bgRedBright: [101, 49],
		bgGreenBright: [102, 49],
		bgYellowBright: [103, 49],
		bgBlueBright: [104, 49],
		bgMagentaBright: [105, 49],
		bgCyanBright: [106, 49],
		bgWhiteBright: [107, 49],
	},
};

const modifierNames = Object.keys(styles.modifier);
const foregroundColorNames = Object.keys(styles.color);
const backgroundColorNames = Object.keys(styles.bgColor);
const colorNames = [...foregroundColorNames, ...backgroundColorNames];

function assembleStyles() {
	const codes = new Map();

	for (const [groupName, group] of Object.entries(styles)) {
		for (const [styleName, style] of Object.entries(group)) {
			styles[styleName] = {
				open: `\u001B[${style[0]}m`,
				close: `\u001B[${style[1]}m`,
			};

			group[styleName] = styles[styleName];

			codes.set(style[0], style[1]);
		}

		Object.defineProperty(styles, groupName, {
			value: group,
			enumerable: false,
		});
	}

	Object.defineProperty(styles, 'codes', {
		value: codes,
		enumerable: false,
	});

	styles.color.close = '\u001B[39m';
	styles.bgColor.close = '\u001B[49m';

	styles.color.ansi = wrapAnsi16();
	styles.color.ansi256 = wrapAnsi256();
	styles.color.ansi16m = wrapAnsi16m();
	styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
	styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
	styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);

	// From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js
	Object.defineProperties(styles, {
		rgbToAnsi256: {
			value(red, green, blue) {
				// We use the extended greyscale palette here, with the exception of
				// black and white. normal palette only has 4 greyscale shades.
				if (red === green && green === blue) {
					if (red < 8) {
						return 16;
					}

					if (red > 248) {
						return 231;
					}

					return Math.round(((red - 8) / 247) * 24) + 232;
				}

				return 16
					+ (36 * Math.round(red / 255 * 5))
					+ (6 * Math.round(green / 255 * 5))
					+ Math.round(blue / 255 * 5);
			},
			enumerable: false,
		},
		hexToRgb: {
			value(hex) {
				const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
				if (!matches) {
					return [0, 0, 0];
				}

				let [colorString] = matches;

				if (colorString.length === 3) {
					colorString = [...colorString].map(character => character + character).join('');
				}

				const integer = Number.parseInt(colorString, 16);

				return [
					/* eslint-disable no-bitwise */
					(integer >> 16) & 0xFF,
					(integer >> 8) & 0xFF,
					integer & 0xFF,
					/* eslint-enable no-bitwise */
				];
			},
			enumerable: false,
		},
		hexToAnsi256: {
			value: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
			enumerable: false,
		},
		ansi256ToAnsi: {
			value(code) {
				if (code < 8) {
					return 30 + code;
				}

				if (code < 16) {
					return 90 + (code - 8);
				}

				let red;
				let green;
				let blue;

				if (code >= 232) {
					red = (((code - 232) * 10) + 8) / 255;
					green = red;
					blue = red;
				} else {
					code -= 16;

					const remainder = code % 36;

					red = Math.floor(code / 36) / 5;
					green = Math.floor(remainder / 6) / 5;
					blue = (remainder % 6) / 5;
				}

				const value = Math.max(red, green, blue) * 2;

				if (value === 0) {
					return 30;
				}

				// eslint-disable-next-line no-bitwise
				let result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red));

				if (value === 2) {
					result += 60;
				}

				return result;
			},
			enumerable: false,
		},
		rgbToAnsi: {
			value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
			enumerable: false,
		},
		hexToAnsi: {
			value: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
			enumerable: false,
		},
	});

	return styles;
}

const ansiStyles = assembleStyles();

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ansiStyles);


/***/ }),

/***/ "./src/chalk/source/vendor/supports-color/browser.js":
/*!***********************************************************!*\
  !*** ./src/chalk/source/vendor/supports-color/browser.js ***!
  \***********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nested_webpack_require_17540__) => {

__nested_webpack_require_17540__.r(__webpack_exports__);
/* harmony export */ __nested_webpack_require_17540__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* eslint-env browser */

let isBlinkBasedBrowser = false;
if (typeof navigator != 'undefined') {
	isBlinkBasedBrowser = navigator && navigator.userAgentData
		? navigator.userAgentData.brands.some(({ brand }) => brand === 'Chromium')
		: /\b(Chrome|Chromium)\//.test(navigator.userAgent);
}



const colorSupport = isBlinkBasedBrowser ? {
	level: 1,
	hasBasic: true,
	has256: false,
	has16m: false,
} : false;

const supportsColor = {
	stdout: colorSupport,
	stderr: colorSupport,
};

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (supportsColor);


/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __nested_webpack_require_18593__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId](module, module.exports, __nested_webpack_require_18593__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
/******/ 	/* webpack/runtime/compat get default export */
/******/ 	(() => {
/******/ 		// getDefaultExport function for compatibility with non-harmony modules
/******/ 		__nested_webpack_require_18593__.n = (module) => {
/******/ 			var getter = module && module.__esModule ?
/******/ 				() => (module['default']) :
/******/ 				() => (module);
/******/ 			__nested_webpack_require_18593__.d(getter, { a: getter });
/******/ 			return getter;
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/define property getters */
/******/ 	(() => {
/******/ 		// define getter functions for harmony exports
/******/ 		__nested_webpack_require_18593__.d = (exports, definition) => {
/******/ 			for(var key in definition) {
/******/ 				if(__nested_webpack_require_18593__.o(definition, key) && !__nested_webpack_require_18593__.o(exports, key)) {
/******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ 				}
/******/ 			}
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
/******/ 	(() => {
/******/ 		__nested_webpack_require_18593__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/make namespace object */
/******/ 	(() => {
/******/ 		// define __esModule on exports
/******/ 		__nested_webpack_require_18593__.r = (exports) => {
/******/ 			if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 				Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 			}
/******/ 			Object.defineProperty(exports, '__esModule', { value: true });
/******/ 		};
/******/ 	})();
/******/ 	
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
/*!**********************!*\
  !*** ./src/index.js ***!
  \**********************/
__nested_webpack_require_18593__.r(__webpack_exports__);
/* harmony export */ __nested_webpack_require_18593__.d(__webpack_exports__, {
/* harmony export */   ALL_FUNCTIONS: () => (/* binding */ ALL_FUNCTIONS),
/* harmony export */   LEVEL: () => (/* binding */ LEVEL),
/* harmony export */   Logger: () => (/* binding */ Logger),
/* harmony export */   TYPE: () => (/* binding */ TYPE),
/* harmony export */   create: () => (/* binding */ create),
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   log: () => (/* binding */ log)
/* harmony export */ });
/* harmony import */ var _chalk_source_index__WEBPACK_IMPORTED_MODULE_0__ = __nested_webpack_require_18593__(/*! ./chalk/source/index */ "./src/chalk/source/index.js");
/* harmony import */ var app_lib_global__WEBPACK_IMPORTED_MODULE_1__ = __nested_webpack_require_18593__(/*! app-lib-global */ "app-lib-global");
/* harmony import */ var app_lib_global__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__nested_webpack_require_18593__.n(app_lib_global__WEBPACK_IMPORTED_MODULE_1__);





/***************************************************************************************************
 * 
 *  * 注意
 *  1. 由于类的注释 在jsdoc-to-md 的组件中不能显示,故将类内部的方法独立出来
 *  2. 由于箭头函数没有this指向到类 同时为了能在实例上显示具体的执行方法,便于简写能一目了然 故使用函数式声明
 * 
 *  * 参考地址
 *  * https://jsdoc.app/ 官方文档
 *  * https://github.com/jsdoc/jsdoc github
 * 
 * @ignore
 ***************************************************************************************************/


/**
 * 
 * * 测试全局方法
*  @constant ALL_FUNCTIONS
*  @description
*  * 日志级别相关方法
*
* |级别|堆栈|调试|日志|信息|成功|表格|时间|警告|错误|
* |-|-|-|-|-|-|-|-|-|-|
* |方法名|trace|debug|log|info|success|table|time|warn/warnNoTrace|error/errorNoTrace|
* |简写|t|d|l|i|s|T|tt|w/wn|e/wn|
* |模块化|mTrace|mDebug|mLog|mInfo|mSuccess|mTable|mTime|mWarn/mWarnNoTrace|mError/mErrorNoTrace|
* |简写|mt|md|ml|mi|ms|mT|mtt|mw/mwn|me/mwn|
*
* * 彩色转换与其他方法
*  > 参考详细文档
*
*/
const ALL_FUNCTIONS = [];





/**
 *  @ignore
 * 是否浏览器模式
 */
const isBroswer = (0,app_lib_global__WEBPACK_IMPORTED_MODULE_1__.isBroswerEnv)();

/**
 * @ignore
 * 环境变量
 */
const env = (0,app_lib_global__WEBPACK_IMPORTED_MODULE_1__.getEnv)();

/**
 * @ignore
 * 终端彩色打印
 */
const chalk = new _chalk_source_index__WEBPACK_IMPORTED_MODULE_0__.Chalk({ level: 2 });


/**
 * 支持的打印类型 
 *  @constant
 *  @name TYPE 
 *  @description
 *  日志类型
 * 
 * |级别|堆栈|调试|日志|信息|成功|表格|时间|警告|错误|
 * |-|-|-|-|-|-|-|-|-|-|
 * |常量名称|TRACE|DEBUG|LOG|INFO|SUCCESS|TABLE|TIME|WARN|ERROR|
 * |常量值|trace|debug|log|info|success|table|time|warn|error|
 */
const TYPE = {
    TRACE: 'trace',
    DEBUG: 'debug',
    INFO: 'info',
    LOG: 'log',
    SUCCESS: 'success',
    TABLE: 'table',
    TIME: 'time',
    WARN: 'warn',
    ERROR: 'error',
};

/**
 *  日志级别
 *  @constant
 *  @name LEVEL
 *  @description
 *  日志级别
 *  * 通过setOption({level:number})进行打印高于该值(number)的日志
 *  * 调整该顺序值进行灵活打印
 *  * 或者只打印某几项日志
 * 
 * |级别|堆栈|调试|日志|信息|成功|表格|时间|警告|错误|
 * |-|-|-|-|-|-|-|-|-|-|
 * |常量名|trace|debug|log|info|success|table|time|warn|error|
 * |常量值|10|20|30|31|32|33|40|60|70|
 */
const LEVEL = {
    trace: 10, // 跟踪 堆栈
    debug: 20, // 调试
    info: 30,  // 信息
    log: 31,// 元素的log
    success: 32,// 成功--便于开发高亮标识
    table: 33,
    time: 40,  // 时间--带时间戳
    warn: 60,  // 告警
    error: 70 // 错误
};



// 多彩的配置
const colorful = {
    node: {
        maxCharLength: 9, // 显示级别的最大字符长度 9 即success+两个空格
        textAlgin: 'right', // 支持left/right和center
        space: "", // 级别标识后的间隔距离
        module: { // 模块标识背景和颜色
            background: '#0a0afb',
            color: '#ffffff',
        },
        trace: {
            background: '#4a4848',
            color: '#ffffff'
        },
        debug: {
            background: '#4a4848',
            color: '#ffffff',
            index: '      ', // 标识前缩进
        },
        info: {
            background: '#08df08',
            color: '#ffffff',
            index: '      ', // 标识前缩进
        },
        success: {
            background: '#0808ef',
            color: '#ffffff',
            index: '      ', // 标识前缩进
        },
        warn: {
            background: '#ffff08',
            color: '#ff0000',
        },
        error: {
            background: '#f50303',
            color: '#ffffff',
        },
        time: {
            background: '#47b2b2',
            color: '#ffffff',
            index: '      ', // 标识前缩进
        }
    },
    browser: {
        maxCharLength: 9, // 显示级别的最大字符长度 9 即success+两个空格
        textAlgin: 'right', // 支持left/right和center
        // 缩进- 由于chrome浏览器对不同级别的日志打印有的带堆栈和三角 故对不带堆栈的进行缩进 保持对齐
        index: "background: transparent;margin-left:4px;",
        // 空间隔  多个标签之间得到间隔
        space: "background: transparent;",
        // 每种log的标签样式  便于开发中快速copy样式代码
        trace: "background: linear-gradient(90deg, #b7b2b2,#8080804d, #b7b2b2);  color:white; font-weight:bold; border-radius: 1px; ",
        debug: "background:linear-gradient(70deg, #b7b2b2, #8080804d, #b7b2b2); color:white;  font-weight:bold; border-radius: 1px;",
        info: "background: linear-gradient(70deg, #00800085, #57d4c1,#57d4c1, #00800085); color:white; font-weight:bold;border-radius: 1px;",
        success: "background: linear-gradient(70deg, #172bdca1, #0000ff36, #172bdca1); color:white; font-weight:bold;border-radius: 1px;",
        time: "background: linear-gradient(70deg, #00bfffcf,#00bfff4f,#00bfffcf); color:white; font-weight:bold;border-radius: 1px;",
        warn: "background: linear-gradient(90deg, #eab60e, #eab60e6e, #eab60e);  color:yellow; font-weight:bold; border-radius: 1px;",
        error: "background: linear-gradient(90deg, #ff00006b, #ff000033,#ff000033, #ff00006b);  color:red; font-weight:bold; border-radius: 1px;",
        // 日期标签
        dateTime: "background: none; border: 1px #ad10da4d solid;  color:#ad10dacf; font-weight:bold; border-radius: 1px;",
        // 模块标签
        module: "background: linear-gradient(70deg, #0a0afb, #44448a); color:white; font-weight:bold; border-radius: 1px;padding:0 5px"
    }
};

/**
 *  日志配置
 *  @constant
 *  @name option
 *  @description
 *  默认配置
 *  * setOption - 进行设置  
 *  * getOption - 获取当前的配置
 * 
 * |参数名|参数类型|参数默认值|参数描述|备注|
 * |-|-|-|-|-|
 * |bindGlobalName|string|log|全局的名称|直接在windows或者nodejs环境中直接使用log即可|
 * |level|number/array|20|打印日志级别|低于该级别的类型忽略输出/或者打印指定级别['warn',error]的日志|
 * |moduleName|string|''|模块名称|模块打印的名称|mxx打印时直接输入自定义名称即可|
 * |isModule|boolean|false|是否开启模块标识打印|关闭模块打印表示|
 * |isColorful|boolean|true|是否开启彩色打印|
 * |colorful|object|参考彩色配置|不同终端、不同级别颜色配置|
 * |LEVEL|object|参考LEVEL|配置打印级别值|灵活调整日志级别顺序|
 * |dateFormatter|string/function|'YYYY-MM-DD HH:mm:ss'|日期打印格式化输出|
 * |onLogger|function|null|日志输出记录|用于日志的收集管理|
 */
const defaultOption = {
    bindGlobalName: 'log',
    level: 0,
    moduleName: '',
    isModule: false,
    isColorful: true,
    colorful: colorful[env],
    LEVEL,
    dateFormatter: 'YYYY-MM-DD HH:mm:ss',
    onLogger: null,
};


const PLACE_HOLDER = '%c';
const MODULE_PLACE_HOLDER = '%s';

/**
 *  默认日期格式化
 *  @ignore
 */
const formatDate = (date, fmt) => {
    var o = {
        "M+": date.getMonth() + 1, //月份 
        "D+": date.getDate(), //日 
        "H+": date.getHours(), //小时 
        "m+": date.getMinutes(), //分 
        "s+": date.getSeconds() //秒 
    };
    if (/(Y+)/.test(fmt)) { //根据y的长度来截取年
        fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
    }
    for (var k in o) {
        if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    }
    return fmt;
}


/**********************************************************************************
 * 
 * 便于MARKDOWN中显示 API 采用prototype形式 
 * 
 **********************************************************************************
 */


/**
 * 设置配置
 *  * 设置后即刻生效 
 *  * 后续日志打印按照该设置进行
 * @function
 * @param {object} option  参考默认option配置
 * @returns {objcet} 新的参数配置option
 * 
 */
const setOption = function (option) {
    this.option = { ...this.option, ...option };
    return this.option;
}


/**
 * 获取配置
 * @function
 * @returns {object} 参考默认option
 */
const getOption = function () {
    return this.option;
}

/**
 *  根据命令行终端参数动态设置日志级别
 *    * --debug 
 *    * process.env.DEBUG
 *    仅在nodejs中生效
 *    debug模式 默认级别为0 否则为21
 * @name auotLevel/auotLogLevel
 * @function
 * @returns {object} log  日志实例
 */
const auotLogLevel = function () {
    const { DEBUG } = process?.env || {};
    // 命令行参数优先 直接设置环境变量DEBUG 或者
    let debug = process.argv.slice(2).includes('--debug') || DEBUG;
    this.setOption({ level: debug && debug != 'undefined' ? 0 : 21 });
}

/**********************************************************************************
 *  直接设置颜色输出形式 [只适合nodejs]
 **********************************************************************************
 */


/**
 *
 * 输出执行缩进 显示块长度 文件颜色 和背景色的 文本
 *   1. option参数
 *  * indent  缩进
 *  * width  块的长度
 *  * algin 对齐
 *  * color  颜色
 *  * background 背景颜色
*  @name tb/transTextColorBlock
*  @function
 * @param {string} text 
 * @param {object} opitons 
 * @returns {string} 彩色文案
 * 
 */
function transTextColorBlock(text, opitons) {
    let { indent, width, algin, color, background } = opitons
    return log.fill(indent || 0) + log.tx(log.autoFillText(text, width, algin), color, background);
}


/**
 * 转换文本颜色
 * @name tx/transTextColor
 * @function
 * @param {string} text  文本内容 
 * @param {string} color  文字颜色 hex 格式
 * @param {string} background  背景颜色 hex 格式
 * @returns {string} 彩色文案
 */
function transTextColor(text, color, background) {
    let cTextFn = chalk.hex(color || '#ffffff');
    if (background) {
        cTextFn = cTextFn.bgHex(background);
    }
    return cTextFn(text)
}


/**
 * 转换文本颜色并且打印
 *  * 不受级别控制
 * @function
 * @name txl/transTextColorAndLog
 * @param {string} text  文本内容 
 * @param {string} color  文字颜色 hex 格式
 * @param {string} background  背景颜色 hex 格式
 * @returns {string} 彩色文本内容
 **/
function transTextColorAndLog(text, color, background) {
    let res = this.tx(text, color, background)
    console.log(res)
    return res;
}






/**
*  转换指定级别文本颜色
*  * 不受级别控制
* @name tl/transLevelTextColor
* @function
* @param {string} [level=TYPE.INFO]  日志界别 参考log.TYPE
* @param {string} text   打印的文本内容
* @param {boolean} isBackground  是否包含背景
* @returns {string} 彩色文本内容
*/
function transLevelTextColor(level = TYPE.INFO, text = '', isBackground = true) {
    let { background, color } = colorful.node[level] || colorful.node[TYPE.INFO];
    // 打印文本
    let cTextFn = chalk.hex(color || background || '#ffffff');
    if (isBackground && background) {
        cTextFn = cTextFn.bgHex(background);
    }
    return cTextFn(text)
}
/**
 *  转换指定级别文本颜色
 *  * 不受级别控制
 * @name tll/transLevelTextColorAndLog
 * @function
 * @param {string} [level=TYPE.INFO]  日志界别 参考log.TYPE
 * @param {string} text   打印的文本内容
 * @param {boolean} isBackground  是否包含背景
 * @returns {string} 彩色文本内容
 */
function transLevelTextColorAndLog(level = TYPE.INFO, text = '', isBackground = false) {
    console.log.apply(null, this.tl(level, text, isBackground));
}
/**
 * 打印指定的脚本 
 *  * 带级别字段和内容 
 * 
 * @name tlh/transLevelHeaderAndLog
 * @function
 * @param {string} level  级别
 * @param {string} text   文本内容
 * @param {string} chalkOption  颜色配置参数 { bg, color } 形式
 * @returns {string} 转换后的字符内容
 */
function transLevelHeaderAndLog(level, text, chalkOption) {
    const type = typeof chalkOption;
    if (!['object', 'undefined'].includes(type)) {
        return this.error(`transLevelTextColorAndLog(level,text,chalkOption)方法参数chalkOption传递错误, 请传递{ bg, color }对象形式`)
    }
    let args = level ? this._getTerminalColorfulArguments(level) : [];
    args = args.length ? [args.join('')] : args;
    // 如果不传递背景值 则按照配置的级别答应字体颜色 无背景颜色
    let { background } = colorful.node[level];

    let { bg, color } = chalkOption || { color: background || '#ffffff' };
    // 打印文本
    let cTextFn = chalk.hex(color || background || '#ffffff');
    if (bg) {
        cTextFn = cTextFn.bgHex(bg);
    }
    args.push(cTextFn(' ' + text + ' '))
    return args.join('');
}


/**********************************************************************************
 *  按照级别形式 
 **********************************************************************************
 */



/**
* trace 调试打印
* @name t/trace
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function trace(...args) {
    return this.exe(TYPE.TRACE, args);
}


/**
* debug 调试打印
* @name d/debug
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function debug(...arg) {
    return this.exe(TYPE.DEBUG, [...arguments]);
}


/**
* info 信息打印
* @name i/info
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function info(...arg) {
    return this.exe(TYPE.INFO, [...arguments]);
}


/**
* log 日志打印
* @name l/log
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function logFn(...arg) {
    return this.exe(TYPE.LOG, [...arguments]);
}

/**
* success 成功打印
* @name s/success
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function success(...arg) {
    return this.exe(TYPE.SUCCESS, [...arguments]);
}

/**
* time 时间打印
* @name tt/time
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function time(...arg) {
    return this.exe(TYPE.TIME, [...arguments]);
}



/**
* table 表格打印
* @name T/table
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function table(...arg) {
    return this.exe(TYPE.TABLE, [...arguments]);
}

/**
* warn 警告打印
* @name w/warn
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function warn(...arg) {
    return this.exe(TYPE.WARN, [...arguments]);
}


/**
* debug 调试打印
* * 不带堆栈
* @name wn/warnNoTrace
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function warnNoTrace(...arg) {
    return this.exe(TYPE.WARN, [...arguments], { noTrace: true });
}


/**
* error 错误打印
*
* @name e/error
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function error(...arg) {
    return this.exe(TYPE.ERROR, [...arguments]);
}


/**
* error 调试打印
* * 不带堆栈
* @name en/errorNoTrace
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function errorNoTrace(...arg) {
    return this.exe(TYPE.ERROR, [...arguments], { noTrace: true });
}


/**********************************************************************************
*  模块按照级别输出形式 
**********************************************************************************
*/


/**
* mTrace 堆栈打印(模块化)
*
* @name mt/mTrace
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function mTrace(...arg) {
    return this._mExecute(TYPE.TRACE, [...arguments]);
}

/**
* mDebug 调试打印(模块化)
*
* @name md/mDebug
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function mDebug(...arg) {
    return this._mExecute(TYPE.DEBUG, [...arguments]);
}
/**
* mInfo 信息打印(模块化)
*
* @name mi/mInfo
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function mInfo(...arg) {
    return this._mExecute(TYPE.INFO, [...arguments]);
}

/**
* mLog 日志打印(模块化)
*   * 原生的控制台打印
* @name ml/mLog
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function mLog(...arg) {
    return this._mExecute(TYPE.LOG, [...arguments]);
}

/**
* mSuccess 成功打印(模块化)
*
* @name ms/mSuccess
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function mSuccess(...arg) {
    return this._mExecute(TYPE.SUCCESS, [...arguments]);
}

/**
* mTime 调试打印(模块化)
*
* @name mtt/mTime
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function mTime(...arg) {
    return this._mExecute(TYPE.TIME, [...arguments]);
}

/**
* mTable 表格打印(模块化)
*
* @name mT/mTable
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function mTable(...arg) {
    return this._mExecute(TYPE.TABLE, [...arguments]);
}

/**
* mWarn 告警打印(模块化)
*
* @name mw/mWarn
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function mWarn(...arg) {
    return this._mExecute(TYPE.WARN, [...arguments]);
}



/**
* mWarnNoTrace 调试打印(模块化)
*   * 不带堆栈
* @name mwn/mWarnNoTrace
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function mWarnNoTrace(...arg) {
    return this._mExecute(TYPE.WARN, [...arguments], { noTrace: true });
}




/**
* mError 调试打印(模块化)
* @name me/mError
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function mError(...arg) {
    return this._mExecute(TYPE.ERROR, [...arguments]);
}

/**
* mErrorNoTrace 调试打印(模块化)
* * 不带堆栈
* @name men/mErrorNoTrace
* @function
* @param {any} args 打印的内容 
* @returns {null} 
*/
function mErrorNoTrace(...arg) {
    return this._mExecute(TYPE.ERROR, [...arguments], { noTrace: true });
}



/**
 * autoFillText 动态补全文本
 *  * 常用于打印类似各种级别的日志 配置配合tl使用
 * @param {string} text  文本内容
 * @param {number} length 长度 默认级别打印的长度设置保持一致 超出长度按照超出的部分显示
 * @param {string} aligin 对齐 支持center,left 和 默认 right
 * @returns 整合的字段
 */
function autoFillText(text, length, aligin = 'right') {
    let defaultLength = this.option.colorful.maxCharLength;
    return this._autoFillLength(length || defaultLength, text, aligin);
}

/**
 *  * 填充文本(一般是空白)
 * 
 * @param {number} length  填充的次数
 * @param {string} content  填充的内容
 * @returns  string 填充后的内容
 */
function fill(length, content) {
    return this._fill(length, content);
}


const instanceSupportFunctions = {
    // 默认操作
    setOption, getOption, auotLogLevel, auotLevel: auotLogLevel,
    // 文本操作
    autoFillText, fill, transTextColorBlock, tb: transTextColorBlock,
    // 基础操作
    trace, debug, info, log: logFn, success, time, table, warn, warnNoTrace, error, errorNoTrace,
    // 简化操作
    t: trace, d: debug, i: info, l: logFn, s: success, tt: time, T: table, w: warn, wn: warnNoTrace, e: error, en: errorNoTrace,
    // 模块化
    mTrace, mDebug, mInfo, mLog, mSuccess, mTime, mTable, mWarn, mWarnNoTrace, mError, mErrorNoTrace,
    // 简化模块化输出
    mt: mTrace, md: mDebug, mi: mInfo, ml: mLog, ms: mSuccess, mtt: mTime, mT: mTable, mw: mWarn, mwn: mWarnNoTrace, me: mError, men: mErrorNoTrace,
    // // 带颜色的操作
    transTextColor, transTextColorAndLog, transLevelTextColor, transLevelTextColorAndLog, transLevelHeaderAndLog,
    tx: transTextColor, txl: transTextColorAndLog, tl: transLevelTextColor, tll: transLevelTextColorAndLog, tlh: transLevelHeaderAndLog,


};


/**
 * 动态设置prototype上的方式
 * @ignore
 * @param {object} instanceSupportFunctions  支持的方法 非箭头函数
 */
const initMethonds = (instance) => {
    for (let key in instanceSupportFunctions) {
        instance[key] = instanceSupportFunctions[key]
    }
}



/**
 * 日志类
 * 创建日志
 */
class Logger {
    /**
    * Create a Logger
    * @param {object} option  参考默认option
    */
    constructor(option) {
        this.option = { ...defaultOption, ...option };
        initMethonds(this);
    }
    // 是否缩进
    _isIndex(level) {
        return ![TYPE.TRACE, TYPE.WARN, TYPE.ERROR].includes(level);
    }

    // 获取空格间隔
    _getSpace(num) {
        let space = '';
        for (let i = 0; i < num; i++) {
            space += ' ';
        }
        return space;
    }
    // 获取对齐的字段
    _getAlgin(level, algin, maxCharLength) {
        let length = maxCharLength - level.length;
        let pre = 0;
        let suf = 1;
        if (algin === 'center') {
            // 除不尽时 前者取消值 后面间隔取大值
            pre = Math.floor(length / 2); // 向下取整
            suf = Math.ceil(length / 2); // 向上取整
        } else { // 靠右对齐
            pre = length - 1;
        }
        return PLACE_HOLDER + this._getSpace(pre) + level.toLowerCase() + this._getSpace(suf);
    }

    // 获取多色的参数显示
    _getBroswerColorfulArguments(level) {
        let { isColorful, colorful, moduleName, dateFormatter } = this.option;
        let { textAlgin, maxCharLength, index, space, module, dateTime } = colorful;
        if (!isColorful) return [];
        let template = '';
        let arg = [];
        // 是否缩进
        if (this._isIndex(level)) {
            template += PLACE_HOLDER + ' ';
            arg.push(index);
        }
        // 不同级别不同间隔和不同的样式
        template += this._getAlgin(level, textAlgin, maxCharLength);
        arg.push(colorful[level.toLowerCase()]);


        // 添加模块标识
        if (moduleName) {
            template += PLACE_HOLDER + ' ' + PLACE_HOLDER + MODULE_PLACE_HOLDER;
            arg = arg.concat([space, module, moduleName]);
        }
        // 添加time 时间戳标识
        if (level === TYPE.TIME) {
            template += PLACE_HOLDER + ' ' + PLACE_HOLDER + MODULE_PLACE_HOLDER;
            let dateTimeString = (typeof dateFormatter === 'string') ? formatDate(new Date(), dateFormatter) : dateFormatter(new Date())
            arg = arg.concat([space, dateTime, dateTimeString]);
        }
        return [template].concat(arg);
    }

    _fill(length, fillString = ' ') {
        let res = [];
        for (let i = 0; i < length; i++) {

            res.push(fillString)
        }
        return res.join('');
    }
    // 居中时获取前后补充的长度
    _getPosition(needFillLength) {
        //  需要补充的长度
        let avg = needFillLength / 2;
        return [Math.ceil(avg), Math.floor(avg)]
    }
    // 动态配置长度
    _autoFillLength(length, str, textAlgin = "right") {
        // 尾部默认一个空格显示漂亮一下
        str = str + ' ';
        let less = length - str.length;
        // 居中补充
        if (textAlgin === 'center') {
            let [preLength, endLength] = this._getPosition(less);
            return this._fill(preLength) + str + this._fill(endLength);
        }
        if (less <= 0) return str;
        return textAlgin == 'right' ? this._fill(less) + str : str + this._fill(less);
    }





    _getTerminalColorfulArguments(level, options = {}) {
        let { isColorful, colorful, moduleName, dateFormatter } = this.option;
        if (!isColorful) return [];

        let { textAlgin, maxCharLength, space, module } = colorful;

        let { background, color, index } = colorful[level] || colorful['trace'];

        let arg = [];
        // 是否缩进
        if (options.noTrace || index) {
            arg.push(options.noTrace ? colorful.debug.index : index);
        }
        // 不同级别不同间隔和不同的样式
        let template = this._autoFillLength(maxCharLength, level.toLowerCase(), textAlgin);
        arg.push(chalk.bgHex(background).hex(color)(template))
        // 类型标识与后面文案的间距
        arg.push(space);
        // 添加模块标识
        if (moduleName) {
            arg.push(chalk.bgHex(module.background).hex(module.color)(' ' + moduleName + ' '));
        }
        // 添加time 时间戳标识
        if (level === TYPE.TIME) {
            let dateTimeString = (typeof dateFormatter === 'string') ? formatDate(new Date(), dateFormatter) : dateFormatter(new Date())
            arg = arg.concat([dateTimeString]);
        }
        return arg;
    }

    // 根据配置和不同环境 不同的输出 TODO 扩展其他情况
    _output(type, innerArg, outerArg, options = {}) {
        let { onLogger, level } = this.option;
        // 配置的打印级别小于当前打印的级别
        if (typeof level === 'number') {
            // if (level > LEVEL[type]) return;
            if (level > this.option.LEVEL[type]) return;
            // 支持动态设置日志级别
        } else if (Array.isArray(level)) {
            if (!level.includes(type)) {
                return false;
            }
        };
        // 外部输出
        onLogger && onLogger(type, outerArg);

        // 内部打印
        if (console) {
            // node js 下 兼容 error 与warm 打印堆栈
            let foramtType = (!isBroswer && [TYPE.WARN, TYPE.ERROR].includes(type)) && !options.noTrace ? TYPE.TRACE : type;

            // 兼容浏览器下能打印debug
            foramtType = (isBroswer && [TYPE.DEBUG].includes(type)) ? TYPE.INFO : foramtType;

            let fn = console[foramtType.toLowerCase()] || console[TYPE.INFO];

            // 兼容表格直接输出
            if (foramtType.toLowerCase() === TYPE.TABLE) {
                console.table.apply(null, outerArg);
            } else if (foramtType.toLowerCase() === TYPE.TIME) {
                console.log.apply(null, innerArg.concat(outerArg))
            } else if (foramtType.toLowerCase() === TYPE.LOG) {
                console.log.apply(null, outerArg)
            } else {
                fn.apply(null, innerArg.concat(outerArg));
            }
        }
    }

    exe(level, userArg, options) {
        let arg = isBroswer ? this._getBroswerColorfulArguments(level) : this._getTerminalColorfulArguments(level, options);
        this._output(level, arg, userArg, options);
        return null;
    }

    _mExecute(level, userArg, options = {}) {
        this.option.moduleName = userArg[0];
        let fn = level.toLowerCase() + (options.noTrace ? 'NoTrace' : '');
        this[fn] && this[fn].apply(this, userArg.slice(1, userArg.length));
        this.option.moduleName = '';
    }

}


// autoAppendClassFn(fns);

/**
 * 创建日志实例
 * 
 * @function
 * @description 
 *   1. 第一次引入 默认创建实例
 *   2. 后续导入  直接返回第一次创建的实例 
 * 
 * @param {Object} option  详细参数参考option
 * @returns  {object} logInstance 日志实例
 */
const create = function (option) {
    let namespace = option.bindGlobalName;
    if (!(0,app_lib_global__WEBPACK_IMPORTED_MODULE_1__.isBindToGlobal)(namespace)) {
        return (0,app_lib_global__WEBPACK_IMPORTED_MODULE_1__.bindToGlobal)(namespace, new Logger(option || {}))
    }
    return (0,app_lib_global__WEBPACK_IMPORTED_MODULE_1__.getbindData)(namespace);
}


/**
 * 默认自动创建实例 
 * 
 * @constant
 * @description
 *  * 默认会挂载全局 直接通过log来使用
 * 
 */
const log = create(defaultOption);

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (log);

})();

/******/ 	return __webpack_exports__;
/******/ })()
;
});
//# sourceMappingURL=index.js.map

/***/ }),

/***/ 882:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

(function webpackUniversalModuleDefinition(root, factory) {
	if(true)
		module.exports = factory(__webpack_require__(708), __webpack_require__(810), __webpack_require__(305), __webpack_require__(89), __webpack_require__(44), __webpack_require__(56), __webpack_require__(908));
	else { var i, a; }
})(this, (__WEBPACK_EXTERNAL_MODULE__86__, __WEBPACK_EXTERNAL_MODULE__668__, __WEBPACK_EXTERNAL_MODULE__305__, __WEBPACK_EXTERNAL_MODULE__89__, __WEBPACK_EXTERNAL_MODULE__44__, __WEBPACK_EXTERNAL_MODULE__56__, __WEBPACK_EXTERNAL_MODULE__908__) => {
return /******/ (() => { // webpackBootstrap
/******/ 	var __webpack_modules__ = ({

/***/ 138:
/***/ ((module, __unused_webpack_exports, __nested_webpack_require_1254__) => {

const path = __nested_webpack_require_1254__(56);
const fs = __nested_webpack_require_1254__(89);
const { log } = __nested_webpack_require_1254__(668);
const { exec } = __nested_webpack_require_1254__(86);
const node_readline = __nested_webpack_require_1254__(908);
const { appRequire } = __nested_webpack_require_1254__(305);
// 避免被weppack打包  采用该变量的形式使用


/**
 * nodejs内置所有模块 
 *  * 常用于webpack编译umd排除使用
 */
const NODE_INNER_MODULES = Object.keys(process.binding('natives')).filter(module => !/^internal\//.test(module)).sort();

/**
 *  同步判断磁盘文件是否存在
 *
 * @param {string} path   相对路径
 * @returns {boolean} 是否存在  true 存在 false 不存在
 * @function
 */
const isExistFile = fs.existsSync;


/**
 * 相对路径获取的据对路径
 * 
 * @param {string} pathName  相对路径地址
 * @returns {string}  据对路径地址
 * @function
 */
const resolve = path.resolve;




/**
 * 判断当前命令是否未全局安装
 * 
 *  * 向上两层判断是否存在node.exe
 *
 * @returns {boolean} 是否为全局安装
 * @function
 */
const isGlobalInstall = () => {
    let path = getRootPath();
    return isExistDir(resolve(path, '../../node.exe'));
}



/**
 *  是否存在bind
 * 
 * @param {string} relativePath  相对路径
 * @param {string} name  组件名称
 * @returns {boolean} 是否存在bin
 * @function
 */
const isExistBin = (relativePath, name) => {
    let binPath = resolve(relativePath, `./node_modules/.bin/${name}`)
    return isExistFile(binPath) ? binPath : null;
}


/**
 * 获取nodejs的bin执行位置
 * 
 * @param {string} compnentName  组件名称
 * @returns {string} 组件的路径
 * 
 * * tips
 * 
 * 1. 开发模式直接获取当前目录的下的指定配置路径
 * 2. 局部查找
 * 3. 全局组件内部
 * 4. 全局外部
 * 
 * @function 
 * 
 */
const getBin = (compnentName) => {

    // 运行路径
    let mainPath = getMainPath();
    let runMain = isExistBin(mainPath, compnentName);
    log.md('getBin:', compnentName, runMain)

    if (runMain) {
        return runMain;
    }

    return compnentName;
}



/**
 * 
 * 是否为app 定义的开发模式
 * 
 * @returns {boolean} 是否为开发模式
 * 
 * * tips
 *  1. cross-env 中不支持中划线 eg:APP-MODLE
 *  2. MODE 或在 M  值为 DEV 或者DEVELOP, develop,dev
 *  3. 主要用于该工程的开发模式
 * 
 * @function
 */
const isDev = () => ["DEVELOP", 'DEV', 'develop', 'dev'].includes(process.env.MODE || process.env['M']);


/**
 * 获取模版位置
 *
 * @returns {string} 模版位置
 * @function
 */
const getTemplate = () => {
    let template = './src/template.html';
    if (!isExistFile(template)) {
        log.mi(`use default tempalte config! diy in [${template}]`)
        template = resolve(getRootPath(), '../../', './src/template', './init.index.default.template.html')
    }
    return template;
}




/**
 *  读文件【异步】
 * 
 * 
 * @param  {string|Buffer|URL|integer} path  文件路径
 * @param {object} options  ndoejs的配置
 * @returns {promise}   data <string> | <Buffer> 读取的文件内容
 * 
 * * tips
 *   1. string|Buffer|URL|integer filename or file descriptor
 *   2. https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_fs_readfile_path_options_callback
 * @function
 */
const readFile = (path, options = {}) => new Promise((res, reject) => {
    const defualtOption = { encoding: 'utf8' };
    if (options === true || options.cwd) {
        path = resolve(path);
        options = {}
        options.cwd && delete options.cwd;
    }
    fs.readFile(path, { ...defualtOption, ...options }, function (err, data) {
        if (err) return reject(err);
        res(data);
    })
});


/**
 *  读文件【同步】
 * 
 * 
 * @param   {string|Buffer|URL|integer} path  文件路径
 * @param   {object} options  ndoejs的配置
 * @returns {string} 文件内容
 * 
 * * tips
 *   1. string|Buffer|URL|integer filename or file descriptor
 *   2. https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_fs_readfile_path_options_callback
 * @function
 */
const readFileSync = (path, options = {}) => {
    const defualtOption = { encoding: 'utf8' };
    return fs.readFileSync(path, { ...defualtOption, options })
}

/**
 *  写文件【异步】
 * 
 * 
 * @param {string|Buffer|URL|integer} path  文件路径
 * @param {object} options  ndoejs的配置
 * @returns {promise}   data <string> | <Buffer> 读取的文件内容
 * 
 * * tips
 *   1. string|Buffer|URL|integer filename or file descriptor
 *   2. https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_fs_readfile_path_options_callback
 * @function
 */
const writeFile = (path, data, options = {}) => new Promise((resolve, reject) => {
    if (options === true || options.cwd) {
        path = resolve(path);
        options = {}
        options.cwd && delete options.cwd;
    }
    const defualtOption = { encoding: 'utf8', flag: 'w+' };
    fs.writeFile(path, data, {
        ...defualtOption,
        ...options
    }, function (err) {
        if (err) return reject(err);
        resolve(data);
    })
});



/**
 *  写文件【同步】
 * 
 * 
 * @param {string|Buffer|URL|integer} path  文件路径
 * @param {object} options  ndoejs的配置
 * @returns {string} 文件内容
 * 
 * * tips
 *   1. string|Buffer|URL|integer filename or file descriptor
 *   2. https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_fs_readfile_path_options_callback
 * @function
 */
const  writeFileSync= (path, data, options = {}) => {
    const defualtOption = { encoding: 'utf8' };
    return fs.writeFileSync(path, data, { ...defualtOption, options })
}

/**
 *  写文件【同步】 不存在文件夹则创建
 * 
 * @param {string|Buffer|URL|integer} path  文件路径
 * @param {object} options  ndoejs的配置
 * @returns {string} 文件内容
 * @function
 */ 

const  writeFileSyncAndCreate= (filePath, data, options = {}) => {
    let root = path.parse(filePath).dir;
    if (!isExistDir(root)) {
        mkdir(root);
    }
    writeFileSync(filePath, data, options = {})
}


/**
 * 是否为文件夹
 * 
 * @param {string} path  文件夹路径
 * @returns {boolean} 是否为文件夹
 * @function
 */
const isExistDir = (path) => {
    let existPath = fs.existsSync(path);
    if (existPath) {
        return fs.statSync(path).isDirectory();
    }
    return false;
}

/**
 *  获取指定路径的父级目录包含的文件夹名
 * 
 * @param {string} path  当前的路径
 * @param {string} dirName  文件夹名称
 * @param {number} layer   当前目录到找到目录目录的层级
 * @returns  {object}  找的父级的路径
 * 
 * * example
 * ```
 *  {
 *   path : null 标识不存在 否则标识存在的路径
 *   layer: number 查到的层级
 *  }
 * ```
 * @function
 **/

const getParentDir = (path, dirName, layer = 0, paths = []) => {
    let justPath = resolve(path, dirName);
    let parentPath = resolve(path, '../', dirName);

    if (justPath === parentPath) {
        // 查到最后 则推出循环
        return null;
    }

    if (isExistDir(justPath)) {
        return { path: justPath, layer, paths };
    } else {
        paths.push(path.split('\\').pop())
        return getParentDir(resolve(path, '../'), dirName, layer + 1, paths);
    }
}


/**
 * 复制文件
 *  * 不存在目录则创建 但是一定是两边都包含文件
 *  否则会报错 operation not permitted, copyfile  xxx
 * 
 * @param {string} src  源地址
 * @param {string } dest  目标地址
 * @param {string} isForce 文件存在是否强制覆盖 默认false
 * @param {number} flags 复制标识
 * @returns {promise}
 * @function 
 */
const copyFile = (src, dest, isForce, flags = 0) => new Promise((res, reject) => {
    const dirPath = resolve(dest, '../');
    const realCopy = () => {
        fs.copyFileSync(src, dest);
        res();
    }
    const copy = async () => {
        if (!isForce) { // 不是强制复制
            if (isExistFile(dest)) {// 存在文件 提示
                log.mwn(`exist file [${dest}], recover it ?`);
                let isCover = await readline(`yes/no`, 'yes');
                if (['yes', 'y'].includes(isCover)) {
                    realCopy();
                } else {
                    res();
                }
            } else {
                realCopy();
            }
        }


    }

    if (!fs.existsSync(dirPath)) {
        mkdir(dirPath);
        copy();
    } else {
        copy();
    }
});


/**
 * 单文件强制复制文件
 *  
 * 不存在目录则创建 但是一定是两边都包含文件
 *  否则会报错 operation not permitted, copyfile  xxx
 * 
 * @param {string} src  源文件路径
 * @param {string} dest  目标文件路径
 * @function
 */
const copyFileSync = (src, dest) => {
    const dirPath = resolve(dest, '../');
    const realCopy = () => {
        fs.copyFileSync(src, dest);
        res()
    }
    if (!fs.existsSync(dirPath)) {
        mkdir(dirPath);
        realCopy();
    } else {
        realCopy();
    }
}



/**
 *  创建目录【同步】
 * 
 * @param {string} path  路径
 * @param {object} options  参数
 * @returns {null} 无返回
 * 
 * * tips
 *  1. https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_fs_mkdir_path_options_callback
 * @function
 * 
 */
const mkdir = (path, options = { recursive: true }) => {
    fs.mkdirSync(path, options);
}

/**
 *  录取用户输入
 * @param {string} tips  提示信息
 * @param {string} [defaultValue=yes] 默认值
 * @returns {promise} 读取结果
 * @function
 */
const yesOrNo = async (message, defaultValue = "yes") => {
    // log.mwn(message);
    let isForce = await readline(`${message} [yes/no]`, defaultValue);
    return ['yes', 'y'].includes(isForce);
}



/**
 *  录取用户输入
 * 
 * @param {string} tips  提示信息
 * @param {boolean} isAlowEmpty 运行为空 
 * @returns {promise} 读取结果
 * @function
 */
const readline = (tips = '', defaultValue = '', isAlowEmpty = false) => new Promise((resolve) => {
    log.mi(tips + '');
    const r = node_readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });

    let defaultValueTips = defaultValue ? `(${defaultValue})` : '';
    // 默认标签
    let defaultFlag = log.fill(7) + log.tx(log.autoFillText('default'), '#FFFFFF', '#7506ef');
    let def = log.tx(defaultValueTips, '#00ffdc');
    let tipMsg = `${defaultFlag}  ${def}`
    let question = () => {
        r.question(tipMsg, (answer) => {
            if (!isAlowEmpty) {
                let resultValue = answer || defaultValue;
                if (resultValue) {
                    r.close();
                    resolve(resultValue);
                } else {
                    log.mwn("can't empty! please input again")
                    question();
                }
            } else {
                r.close();
                resolve(answer || defaultValue);
            }
        })
    }
    question();
});

/**
* 文本中添加或者覆盖指定内容
* 
* @param {object} options 参数
* @param {object} [options.content]   文本内容
* @param {object} [options.startflag]   开始标识
* @param {object} [options.endFalg]  结束标识
* @param {object} [options.appContent]   最佳或者替换的内容
* @param {object} [options.isRepalce]   是否为替换 默认是追加 false
* @param {object} [options.isStart]   不存在时 追加最前面 默认是后面
* @param {object} [options.isInnerStart]   追加文档时 追加在heade与oldcontent之间 默认在尾部 
* @param {object} [options.space]   与标识符的间隔
* @param {object} [options.newHeader]   不存在时候  添加头部内容
* @returns {string} 新文本
* @function
*/

const updateContent = ({ content, startflag, endFalg, appContent, isRepalce, isStart, isInnerStart, space, newHeader }) => {
    const SPACE = space || '\r\n';
    let begin = content.indexOf(startflag);
    let end = content.indexOf(endFalg);

    if (begin === -1 || end === -1) { // 不存在的时候 前面
        let newContent = [startflag, newHeader, appContent, endFalg].filter(v => v);
        return isStart ? newContent.concat([content]).join(SPACE) : [content].concat(newContent).join(SPACE);
    }
    let _oldContent = content.substr(begin, end - begin);
    let oldContent = _oldContent.replace(/\r\n$/, '').replace(/\r\n$/, '')
    let newContent = [];
    if (isRepalce) {
        newContent = [startflag, newHeader, appContent].filter(v => v);
    } else {
        if (isInnerStart) {
            if (newHeader) {
                const newOldContent = oldContent.replace(startflag, '').replace(newHeader, '');
                newContent = [startflag, newHeader, appContent, newOldContent];
            } else {
                newContent = [appContent, oldContent];
            }
        } else {
            newContent = [oldContent, appContent]
        }
    }

    newContent = newContent.join(SPACE) + SPACE;

    return content.replace(_oldContent, newContent)
}




/**
 * 获取安装类库的据对目录
 * 
 * @param {string} relativePath  执行文件的相对目录 默认 ../../
 * @returns {string} 主目录路径
 * @function
 */
const getRootPath = (relativePath = './') => {
    return resolve(getMainPath(), relativePath);
}

/** 
 *  当前安装 或者执行命令 的路径 
 * 
 * @param {string} relativePath  相对路径
 * @returns {string} 新路径
 *  
 * * tips 
 *  默认执行的bin文件 在工程目录的下两层
 *  到当前组件的跟目录层
 *  上一侧目录都为当前组件的目录
 * 
 * @function
 */
const getMainPath = (relativePath = '../../') => {
    // webpack-ignore-line
    return resolve(appRequire.main.filename, relativePath)
}


/**
 * 获取当前组件bin的路径
 * @returns {string} bin路径
 * @function
 */
const getBinPath = () => {
    let path = getRootPath();
    return isGlobalInstall() ? resolve(path, '../..') :
        (isDev() ? resolve(path, './node_modules/.bin') : resolve(path, '../.bin'))
}


/**
 * 读取目录【同步】
 * 
 * @param {string} path  目录路径
 * * @param {object} options  读取配置
 * @returns {array} 文件目录
 * @function
 */
const readdirSync = (path, options) => fs.readdirSync(path, options)


/**
 * 嵌套删除子文件夹和文件
 *  
 * @param {string} path  路径
 * @function
 */
const delDir = (path) => {
    let files = [];
    if (fs.existsSync(path)) {
        files = fs.readdirSync(path);
        files.forEach((file, index) => {
            let curPath = path + "/" + file;
            if (fs.statSync(curPath).isDirectory()) {
                delDir(curPath); //递归删除文件夹
            } else {
                fs.unlinkSync(curPath); //删除文件
            }
        });
        fs.rmdirSync(path);
    }

};


/**
 *  删除文件【同步】
 * 
 *  @param {string} path 文件路径
 *  @function
 * 
 */
const delFile = (path) => {
    return fs.unlinkSync(path);
}


/**
 * 系统判断端口使用 // TODO 采用静态编译方式 处理静态文件
 * 
 * @param {number} port  端口号
 * @returns {boolean} 事都被占用
 * @function
 */
const isSysUsePort = (port) => {
    // 避免乱码
    let path = resolve(getRootPath(), './init.justport.used.config.ps1');
    // 不能通过node的本身判断  判断不出webpackserver的端口使用
    let res = exec('powershell', [path, port], { stdio: 'pipe' });
    let isExistPort = res.stdout.toString();
    log.md('test port result:', isExistPort)
    return !!isExistPort;
}


/**
 * 获取到能够使用的端口
 *  * 动态自增的方式 直到可用的端口
 * @param {number} port 
 * @returns  {number} 可用的端口
 * @function
 */
const getCanUsePort = async (port) => {
    let usePort = 1 * port;
    let isUse = await isSysUsePort(usePort);
    if (isUse) {
        return await getCanUsePort(usePort + 1)
    }
    return usePort;
}



/**
 *   复制文件 【异步】
 * 
 * @param {string} from  相对发布组件的目录
 * @param {string} to  相对生成的目录
 * @param {boolean} defaultIsSucess  不存在文件的时候是否默认为成功 默认为成功
 * @function
 */
const copyProjectFile = async (from, to, defaultIsSucess = 0) => {
    let resourcePath = resolve(getRootPath(), from);
    let toPath = resolve(to);
    if (!isExistFile(resourcePath)) {
        log.mwn(`not exist [${resourcePath}]`)
        return defaultIsSucess;
    }
    await copyFile(resourcePath, toPath);
    log.md(`finish copy [${resourcePath}] to ${toPath}`);
    return 0;
}


/**
 *   复制文件 【同步】
 * 
 * @param {string} from  相对发布组件的目录
 * @param {string} to  相对生成的目录
 * @param {boolean} defaultIsSucess  不存在文件的时候是否默认为成功 默认为成功
 * @function
 */
const copyProjectFileSync = (from, to, defaultIsSucess = 0) => {
    let resourcePath = resolve(getRootPath(), from);
    let toPath = resolve(to);
    if (!isExistFile(resourcePath)) {
        log.mwn(`not exist [${resourcePath}]`)
        return defaultIsSucess;
    }
    copyFileSync(resourcePath, toPath);
    log.md(`finish copy [${resourcePath}] to ${toPath}`);
    return 0;
}

const _copyFile = (source, target) => {
    fs.copyFileSync(source, target);
}

/**
 * 嵌套复制文件夹 【同步】
 * 
 * @param {string} source  源路径
 * @param {string} target  目标路径
 * @function
 */
const copyFolder = (source, target) => {
    if (!fs.existsSync(target)) {
        fs.mkdirSync(target);
    }

    const files = fs.readdirSync(source);
    files.forEach((file) => {
        const currentSource = path.join(source, file);
        const currentTarget = path.join(target, file);
        if (fs.lstatSync(currentSource).isDirectory()) {
            copyFolder(currentSource, currentTarget);
        } else {
            _copyFile(currentSource, currentTarget);
        }
    });
}

/**
 * 获取本机IP
 * 
 * * windows验证 其他环境还未验证
 * 
 * @returns {string}  ip地址
 * 
 * * tips 
 *  1. 目前值返回IPv4 后续可以扩展IPv6
 * 
 * @function
 */
function getLocalIP() {
    const os = __nested_webpack_require_1254__(44);
    const osType = os.type(); //系统类型
    const netInfo = os.networkInterfaces(); //网络信息
    let ip = '';
    if (osType === 'Windows_NT') {
        for (let dev in netInfo) {
            //win7的网络信息中显示为本地连接,win10显示为以太网
            if (dev === '本地连接' || dev === '以太网') {
                for (let j = 0; j < netInfo[dev].length; j++) {
                    if (netInfo[dev][j].family === 'IPv4') {
                        ip = netInfo[dev][j].address;
                        break;
                    }
                }
            }
        }

    } else if (osType === 'Linux') {
        ip = netInfo.eth0[0].address;
    } else if (osType === 'Darwin') {
        // mac操作系统
        // ip = netInfo.eth0[0].address;
    } else {
        // 其他操作系统
    }

    return ip;
}

/**
 *  特殊路径
 * 
 *  获取当前代码的路径 __dirname 据对文件的路径
 *  在使用动态加载文件后 resolve会指向动态加载的位置 则需要使用__dirname来获取相对位置
 * 
 */
module.exports = {
    copyFile, // 带提示的赋值 异步
    copyFileSync, // 不带输入提示的辅助 同步
    copyProjectFile, // 复制nodes发布目录到工程目录
    copyFolder,       // 复制文件夹
    copyProjectFileSync, // 嵌套复制文件
    delDir,     // 删除目录
    delFile,   // 删除文件
    getBin, // 获取所有组件的执行位置
    getBinPath, // 获取当前组件的bin执行位置 - 全局  开发 和 内部安装
    getCanUsePort, // 可用的端口
    getLocalIP, // 获取本机IP
    getMainPath, // 获取执行命令 入口位置
    getParentDir, // 获取指定路径的父级目录包含的文件夹名 
    getRootPath, // 获取类库的根目录 动态加载后需要使用 __dirname 获取据对文件的路径
    getTemplate,
    isDev,     // 是否为开发模式
    isExistBin, // 是否存在bin
    isExistDir, // 目录是否存在
    isExistFile,  // 文件是否存在
    isGlobalInstall, // 是否全局安装
    isSysUsePort, // 端口是否被占用
    mkdir,      // 创建目录
    NODE_INNER_MODULES,
    readFile,      // 读文件数据 
    readFileSync,  // 同步度文件数据
    readdirSync, // 读取目录下的所有文件
    readline,   // 读用户输出
    resolve,   // 路径处理
    updateContent, // 更新文件内容
    writeFile,  // 文件中写数据
    writeFileSync, // 同步文件写数据
    writeFileSyncAndCreate, // 同步文件写数据不存在目录则创建
    yesOrNo, // 提示yes和no
}

/***/ }),

/***/ 86:
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE__86__;

/***/ }),

/***/ 668:
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE__668__;

/***/ }),

/***/ 305:
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE__305__;

/***/ }),

/***/ 89:
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE__89__;

/***/ }),

/***/ 44:
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE__44__;

/***/ }),

/***/ 56:
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE__56__;

/***/ }),

/***/ 908:
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE__908__;

/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __nested_webpack_require_20996__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId](module, module.exports, __nested_webpack_require_20996__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
/******/ 	
/******/ 	// startup
/******/ 	// Load entry module and return exports
/******/ 	// This entry module is referenced by other modules so it can't be inlined
/******/ 	var __webpack_exports__ = __nested_webpack_require_20996__(138);
/******/ 	
/******/ 	return __webpack_exports__;
/******/ })()
;
});
//# sourceMappingURL=index.js.map

/***/ }),

/***/ 561:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {

/******/ (() => { // webpackBootstrap
/******/ 	var __webpack_modules__ = ({

/***/ 138:
/***/ ((module, __unused_webpack_exports, __nested_webpack_require_131__) => {

const path = __nested_webpack_require_131__(423);
const { readFileSync, isExistFile,resolve, isExistDir, writeFileSyncAndCreate, readdirSync,getRootPath } = __nested_webpack_require_131__(32);
const { log } = __nested_webpack_require_131__(115);

const BUILD_PATH = "./src/trans-static";
const FILE_PATH = "./static/"; // 默认文件写入位置
const BASE_PATH = "./static/store.json"; // 默认文件存储位置

/**
 *  将文件转换为JSON进行存储
 * 
 * @param {array} filePaths  多个文件转换了路径
 * @param {string} [storagePath='./static/store.json'] 存储的文件路径名称 一般为json 便捷处理
 * @returns {array} 返回文件读取的JSON内容
 *  
 * * example
 *  ```
 *   filesToJson([path.resolve(__dirname,`./b.ps1`),path.resolve(__dirname,`./a.ps1`)]
 *  ```
 * @function
 */

const filesToJson = (filePaths = [], storagePath = BASE_PATH) => {
    let storageDatas = filePaths.map(filePath => {
        if (!isExistFile(filePath)) {
            log.men("不存在文件文件", path.resolve(filePath));
            return null;
        } else {
            let data = readFileSync(filePath);
            return { name: filePath.split('\\').pop(), content: data };
        }
    }).filter(v => !!v)
    // 写入文件
    storageDatas.length && writeFileSyncAndCreate(storagePath, JSON.stringify(storageDatas, null, 2));
    return storageDatas;
}


/**
 *  存储文件转换为文件 
 * @param {string} [storagePath='./static/store.json']   存储文件位置
 * @param {string} [basePath ='./static/'] 每个文件存储路径
 * @returns  {array} 所有存储的文件路径
 */
const pathToFile = (storagePath = BASE_PATH, basePath = FILE_PATH) => {
    if (!isExistFile(storagePath)) {
        return log.men("不存在文件文件", storagePath);
    }
    return jsonToFile(JSON.parse(readFileSync(storagePath)), basePath);
}

/**
 *  存储文件转换为文件 
 * @param {array} [fileDatas='[]']   存储数据
 * @param {string} [basePath ='./static/'] 每个文件存储路径
 * @param {boolean} [isForce=false] 是否强制写入 默认false
 * @returns  {array} 所有存储的文件路径
 * @function
 */
const jsonToFile = (fileDatas = [], basePath = FILE_PATH, isForce = false) =>
    fileDatas.map(({ name, content }) => {
        // let filePath = path.resolve(basePath || '', name);
        let filePath = getRootPath(path.join(basePath || '', name));
        // console.log(getRootPath(),filePath,resolve(filePath));
        // 非强制时候 不是每次都会写入 避免频繁的磁盘抄作 只有第一次会写入
        // 后续可以考虑按照版本来进行判断是否要清理缓存 避免静态文件未更新的情况 目前不需要 
        if (!isForce && isExistFile(filePath)) {
            // log.md("文件已经存在,不再进行覆写",filePath)
            return filePath;
        }
        writeFileSyncAndCreate(filePath, content)
        return filePath
    })

/**
 *  构建文件夹 
 *  * 注意 所有文件路径是平级 不支持嵌套
 * @param {string} buildDirPath=src/trans-static  构建的文件夹路径
 * @param {string} [storagePath=./static/store.json] 存储路径
 */
const buildDirFiles = (buildDirPath = BUILD_PATH, storagePath = BASE_PATH) => {
    // 扫描
    if (!isExistDir(buildDirPath)) {
        return log.md("不存在静态文件目录", buildDirPath);
    }
    // 只用文件 文件夹不在范围 也不支持嵌套
    let filePaths = readdirSync(buildDirPath).filter(v => !isExistDir(path.resolve(buildDirPath, v)))
        .map(v=>path.resolve(buildDirPath,v));
    return filesToJson(filePaths, storagePath)
}


module.exports = {
    filesToJson, // 作为工具使用
    pathToFile,  // 存储路径转换为文件
    jsonToFile,  // 常用
    buildDirFiles, // 编译目录
}

/***/ }),

/***/ 115:
/***/ ((module) => {

"use strict";
module.exports = __webpack_require__(810);

/***/ }),

/***/ 32:
/***/ ((module) => {

"use strict";
module.exports = __webpack_require__(882);

/***/ }),

/***/ 423:
/***/ ((module) => {

"use strict";
module.exports = __webpack_require__(56);

/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __nested_webpack_require_3952__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId](module, module.exports, __nested_webpack_require_3952__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
/******/ 	
/******/ 	// startup
/******/ 	// Load entry module and return exports
/******/ 	// This entry module is referenced by other modules so it can't be inlined
/******/ 	var __webpack_exports__ = __nested_webpack_require_3952__(138);
/******/ 	var __webpack_export_target__ = exports;
/******/ 	for(var i in __webpack_exports__) __webpack_export_target__[i] = __webpack_exports__[i];
/******/ 	if(__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", { value: true });
/******/ 	
/******/ })()
;
//# sourceMappingURL=index.js.map

/***/ }),

/***/ 17:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

const { log } = __webpack_require__(810);
/**
 * 错误的定义
 *
 */
const ERROR_CODE = {
  ERROR: -1, // 终止程序 往往有 message
  WARN: 1, // 警告 不终止程序
  SUCESS: 0,
};

let CODES = [];
for (let key in ERROR_CODE) {
  CODES.push(ERROR_CODE[key]);
}

const LOG_FN = {
  [ERROR_CODE.ERROR]: "e",
  [ERROR_CODE.WARN]: "w",
  [ERROR_CODE.SUCESS]: "s",
};
/**
 * msg 打印的内容
 */
class AppError {
  /**
   *
   * @param {*} msg  打印的日志内容 可以是数组
   * @param {*} code 打印日志的错误格式
   * @param {*} cfg  配置
   */
  constructor(msg, code = ERROR_CODE.WARN, cfg = {}) {
    if (!CODES.includes(code)) {
      throw log.me(
        `create AppError code [${code}] is no't in ERROR_CODE [${CODES}] `
      );
    }
    let message = Array.isArray(msg) ? msg : msg == void 0 ? [] : [msg];
    let config = {
      trace: false, // 默认打印堆栈
      module: true, // 默认模块化打印
      data: undefined, // 接受的数据
      print: true,
      ...cfg,
    };
    this.options = { message, code, config };
    config.print && this.print();
  }
  // 后续扩展功能
  print(option = {}) {
    let { message, code, config } = { ...this.options, ...option };
    let { trace, module } = config;
    if (message && message.length) {
      let fnName = [module && "m", LOG_FN[code], trace ? "" : "n"].join("");
      let fn = log[fnName];
      if (fn) {
        fn.apply(log, message);
      } else {
        throw log.me(`log no exist ${fnName} function`);
      }
    }
  }
  isError() {
    return this.options.code === ERROR_CODE.ERROR;
  }
  noError() {
    return this.options.code === ERROR_CODE.SUCESS;
  }
}

module.exports = {
  AppError,
  ERROR_CODE: ERROR_CODE,
};


/***/ }),

/***/ 585:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {


const {LANGUAGE} = __webpack_require__(598)
// 常用常数配置
const ARGUMENTS = {
    // 支持语言
    language:(opt)=> [
        '[language]',
        `[${LANGUAGE.join('/')}] default(${LANGUAGE[0]})`,
        (language) => {
            if (!LANGUAGE.includes(language)) {
                log.en('error', `command-argument value '${language}' is invalid for argument 'language' , please choice right language in [${LANGUAGE.join(',')}]`)
                throw new  opt.commander.InvalidArgumentError();
            }
            return language
        }
        ,
        LANGUAGE[0]
    ]
}

module.exports = {
    ARGUMENTS
}

/***/ }),

/***/ 598:
/***/ ((module) => {



// 支持的包格式 目标类型
const TARGET = ['server', 'doc', 'build', 'process'];

// 支持的语言类型 static静态资源
const LANGUAGE = ['es', 'node','bin','react', 'vue','static'];

// 支持的编译类型
const LIBRARY_TARGET_OBJ = {
    // umd的编译模式 使用与node 与 brower
    umd: { key: 'umd' },
    commonjs: { key: 'commonjs' },
    window: { key: 'window' },
    // es module 暂时为支持
    // module: { key: 'module' },
    // amd: { key: 'amd' },
    // system: { key: 'system' },
}

// 数组形式
let LIBRARY_TARGET = (() => {
    let res = [];
    for (prop in LIBRARY_TARGET_OBJ) {
        res.push(LIBRARY_TARGET_OBJ[prop].key)
    }
    return res;
})()

module.exports = {
    TARGET,
    LANGUAGE,
    LIBRARY_TARGET_OBJ,
    LIBRARY_TARGET
}

/***/ }),

/***/ 919:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {


const { TARGET, LIBRARY_TARGET } = __webpack_require__(598);

// 常用的OPTIONS
const OPTIONS = {
    // 支持目标文档
    target: ({ Option }) => new Option('-t, --target [string]', 'server target module').choices(TARGET),
    // debug: new Option('-d, --debug', 'is show debug log').default(false, 'toggle show debug log'),
    debug: ({ Option }) => new Option('-d, --debug', 'show debug log'),
    // 默认的输出类型
    libraryTarget: ({ Option }) => new Option('-t, --libraryTarget [string]', 'output libraryTarget').choices(LIBRARY_TARGET).default(LIBRARY_TARGET[0], 'default is umd'),
    // message 用户输入信息
    message: ({ Option }) => new Option('-msg, --message [string]', 'git submit or change log message'),
}

module.exports = OPTIONS;

/***/ }),

/***/ 783:
/***/ ((module) => {


const int = (error, val) => {
    let value = 1 * val;
    if (isNaN(value)) {
        throw new error()
    }
    return value;
};

const port = int;



module.exports = {
    int,
    port,
}

/***/ }),

/***/ 174:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

const { log } = __webpack_require__(810);
const { ERROR_CODE, AppError } = __webpack_require__(17);
const { getRootPath, resolve } = __webpack_require__(882);
const { autoRequire } = __webpack_require__(305);

const prase = __webpack_require__(783);
// 解析统一测脚本参数
const praseOpt = (opt) => {
    let { options } = opt;
    // 倒数第二个为配置参数
    let option = options.slice(options.length - 2, options.length - 1)[0];
    // 入参为前面内容
    let arg = options.slice(0, options.length - 2);
    return { arg, option };
}


/**
 *  执行 参数传递 同事执行对应的start函数
 * @param {*} args 
 * @param  {...any} options 
 */
const action = async (args, ...options) => {
    let { commond, start, ...arg } = args;
    let outOption = options.slice(0, options.length - 1);
    const commondName = typeof options[0] === 'string' ? options[0] : '';

    log.md(`${commond} ${commondName}::BEGAIN`, { ...arg, options: outOption })

    // 构建
    let error = await start({ commond, ...arg, options });
    // 校验
    if (error === void 0) {
        return new AppError(`[./plugins/${commond}.commong.js] function need return `, ERROR_CODE.ERROR)
    }
    // 数字返回 则表示直接是ERROR_CODE的异常
    if (typeof error != 'object') {
        error = new AppError('', error, { print: false });
    }

    if (error.noError()) {
        log.md(`${commond} ${options[0]}::SUCCESS`)
    } else {
        log.md(`execute [${commond} ${commondName}] result is not 0, confirm is execute success`, `exexute file is [./plugins/${commond}.commong.js]`)
        if (error.isError()) {
            log.men(`execute [${commond} ${commondName}] result is error!`)
        } else {
            log.mwn(`execute [${commond} ${commondName}]  is not complete!`)
        }
    }
    // TODO 后续很如处理 
    // 1. 错误统一处理 深入了解commonder和nodesjs child_process 中的数据回传 eg:process.stdout.write("xxxx") 
    // 将异常传递到父进程
    return error;
}

// commander option 参数转换为 exec 执行的参数
const optionsToArray = (options = {}, except = []) => {
    let res = [];
    for (key in options) {
        if (!except.includes(key)) {
            res.push(`--${key}`);
            res.push(options[key]);
        }
    }
    return res;
}

// 对象绑定执行的参数
const bindArg = (obj, arg) => {
    let newObj = {};
    for (key in obj) {
        newObj[key] = obj[key].bind(null, arg)
    }
    return newObj;
}

// 动态获取环境变量 
const transEnv = (option, fileds = []) => {
    let res = [];
    for (let key in option) {
        if (fileds.includes(key)) {
            res.push(`${camelToConst(key)}=${option[key]}`);
        }
    }
    return res;
}
/**
 * ---
 * ##### 驼峰转下划线
 *  
 * @param {string} camelStr 驼峰字符串 
 * @returns  {string} 下划线字符串
 * @function
 */
const camelToUnderline = camelStr => camelStr.replace(/([A-Z])/g, "_$1").toLowerCase();


/**
 * ---
 * ##### 驼峰转常量格式
 * 
 * @function 
 * @param {string} camelStr 驼峰字符串 
 * @returns  {string} 常量字符串
 * 
 */
const camelToConst = str => camelToUnderline(str).toUpperCase();

/**
 * // TODO 去掉
 * 获取配置文件路径
 * @param {object} param0 
 * @returns  string 路径
 *  文件名称命名规范
 *  commond + name + append+ .config.js
 *  路径 工程跟路径 + 配置相对位置+ 文件
 */
const getConfigPath = (args) => {
    let { opt, append } = args;
    let { commond, options } = opt;
    let fileName = [commond, options[0]].concat(append || []).concat(['config.js']).join('.');
    return resolve(getRootPath(), './static/config', fileName);
}

// 获取静态资源路径下的
const getStaticPath = (path = "") => resolve(getRootPath(), './static/', path)

// 动态加载发布目录 或者当前工程目录的文件
const autoRequireFile = (path, isRoot = true) => autoRequire(isRoot ? resolve(getRootPath(), path) : resolve(path))

// 动态 加载发布目录下的静态文件
const autoRequireStaticFile = (path) => autoRequireFile(getStaticPath(path));

module.exports = {
    praseOpt,
    action,
    optionsToArray,
    bindArg,
    prase,
    transEnv,
    getConfigPath,// TODO 去掉
    getStaticPath,
    autoRequireFile,
    autoRequireStaticFile
}

/***/ }),

/***/ 625:
/***/ ((module) => {



// 支持的包格式 目标类型
const TARGET = ['server', 'doc', 'build', 'process'];

// 支持的语言类型
const LANGUAGE = ['es','bin','node', 'react', 'vue'];

// 支持的编译类型
const LIBRARY_TARGET_OBJ = {
    // umd的编译模式 使用与node 与 brower
    umd: { key: 'umd' },
    commonjs: { key: 'commonjs' },
    window: { key: 'window' },
    // es module 暂时为支持
    // module: { key: 'module' },
    // amd: { key: 'amd' },
    // system: { key: 'system' },
}

// 数组形式
let LIBRARY_TARGET = (() => {
    let res = [];
    for (prop in LIBRARY_TARGET_OBJ) {
        res.push(LIBRARY_TARGET_OBJ[prop].key)
    }
    return res;
})()

module.exports = {
    TARGET,
    LANGUAGE,
    LIBRARY_TARGET_OBJ,
    LIBRARY_TARGET
}

/***/ }),

/***/ 424:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

/**
 * 动态读取插件 注册到系统
 *  命名生效两个条件
 *  1: 需要配置或者用plugin命令
 *  2: 需要启用 该命名 默认安装是启用
 */

const STATIC_FILE_DATA = __webpack_require__(177);

// 获取支持的命令
// const getSupportCommonds = ({ utils: { autoRequireStaticFile } }) => autoRequireStaticFile('plugin/plugin.config.json')


// 热注册命令
const hotRegisterCommond = (commonds, opts) => {
    let { program, commander, utils: { autoRequireStaticFile, action }, OPTIONS, noBuild: { appRequire } } = opts;
    const resitCommond = [];
    commonds.forEach(commond => {
        if (commond?.enable) { // 启用的时候才注册
            let fileName = commond.path;
            let commondName = commond.name;
            try {
                // 本地的时候 直接加载本地静态文件  包模式 直接加载包
                let pluginFn = commond?.type == "local" ?
                    autoRequireStaticFile(`plugin/${fileName}`)
                    : appRequire(fileName);

                const plugin = pluginFn?.start(opts);

                if (!plugin.init) return log.me('need init method export in ' + fileName)
                if (!plugin.start) return log.me('need start method export in ' + fileName)

                // 添加命令名称
                let instance = program.command(commondName)

                // 自定义部分
                plugin.init(instance, opts);

                // 默认追加--debug参数和--message参数 已经 调用执行方法
                instance.addOption(OPTIONS.debug(commander))
                    .action(action.bind(null, {
                        start: plugin.start, // 执行方法
                        commond: commondName, // 命令名称
                    }));

                instance.addOption(OPTIONS.message(commander));
                resitCommond.push(commond)
            } catch (e) {
                log.me(`regiter ${commondName} commond error,please check [${fileName}] file`, e)
            }
        }
    });
    log.md(`already  success register   ${resitCommond.length} commonds`);
    let registerCommods = resitCommond.map(c => (
        {
            commond: c.name,
            'see commond help': `appbir ${c.name} --help`,
            enable: c.enable,
            type: c.type,
            discription: c.discription
        }));
    if (process.argv.includes('--debug')) {
        log.T(registerCommods)
    }
    return registerCommods;
}


/**
 * 初始化插件命令
 */
const initPluginCommond = (opts) => {
    let {STATIC: { jsonToFile },utils: {autoRequireStaticFile }}=opts;
    // 静态资源自动生成
    jsonToFile(STATIC_FILE_DATA);
    let commonds = autoRequireStaticFile("plugin.config.json");
    // 如果命令失效 或者删除了static/store 则需要打开命令执行后再次隐藏即可
    // let commonds = [
    //     {"name":"plugin","enable":true,"type":"package","path":"app-lib-cli-plugin-plugin","discription":"插件管理命令// TODO 进行插件管理的开发 "},
    //     {"name":"git","enable":true,"type":"package","path":"app-lib-cli-plugin-git","discription":"GIT操作"},
    //     {"name":"build","enable":true,"type":"package","path":"app-lib-cli-plugin-build","discription":"构建编译"},
    //     {"name":"md","enable":true,"type":"package","path":"app-lib-cli-plugin-md","discription":"markdown编译"},
    //     {"name":"run","enable":true,"type":"package","path":"app-lib-cli-plugin-run","discription":"自定义命令"},
    //     {"name":"server","enable":true,"type":"package","path":"app-lib-cli-plugin-server","discription":"启动服务"},
    //     {"name":"init","enable":true,"type":"package","path":"app-lib-cli-plugin-init","discription":"初始工程"},
    //     {"name":"doc","enable":true,"type":"package","path":"app-lib-cli-plugin-doc","discription":"API文档"}
    // ];
    let registerCommond = hotRegisterCommond(commonds, opts);
    return { commonds, registerCommond };
}


module.exports = { initCommond: initPluginCommond }

/***/ }),

/***/ 555:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {


const { log } = __webpack_require__(810);
const commander = __webpack_require__(491);
const nodeUtils = __webpack_require__(882);
const STATIC = __webpack_require__(561);
const { exec } = __webpack_require__(708);

const utils = __webpack_require__(174);
const noBuild = __webpack_require__(305);
const OPTIONS = __webpack_require__(919);
const { ARGUMENTS } = __webpack_require__(585);
const Error = __webpack_require__(17);
const CONSTANT = __webpack_require__(625)
module.exports = {
    nodeUtils,
    utils,
    exec,
    commander,
    log,
    noBuild,
    OPTIONS, // 常用的option
    ARGUMENTS, // 常用debugger
    Error,
    STATIC,//静态文件存储
    CONSTANT,//常量
}

/***/ }),

/***/ 305:
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE__305__;

/***/ }),

/***/ 198:
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE__198__;

/***/ }),

/***/ 735:
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE__735__;

/***/ }),

/***/ 89:
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE__89__;

/***/ }),

/***/ 44:
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE__44__;

/***/ }),

/***/ 56:
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE__56__;

/***/ }),

/***/ 910:
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE__910__;

/***/ }),

/***/ 908:
/***/ ((module) => {

"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE__908__;

/***/ }),

/***/ 177:
/***/ ((module) => {

"use strict";
module.exports = JSON.parse('[{"name":"plugin.config.json","content":"[\\r\\n    {\\"name\\":\\"plugin\\",\\"enable\\":true,\\"type\\":\\"package\\",\\"path\\":\\"app-lib-cli-plugin-plugin\\",\\"discription\\":\\"//TODO 插件管理\\"},\\r\\n    {\\"name\\":\\"git\\",\\"enable\\":true,\\"type\\":\\"package\\",\\"path\\":\\"app-lib-cli-plugin-git\\",\\"discription\\":\\"GIT操作\\"},\\r\\n    {\\"name\\":\\"build\\",\\"enable\\":true,\\"type\\":\\"package\\",\\"path\\":\\"app-lib-cli-plugin-build\\",\\"discription\\":\\"构建编译\\"},\\r\\n    {\\"name\\":\\"md\\",\\"enable\\":true,\\"type\\":\\"package\\",\\"path\\":\\"app-lib-cli-plugin-md\\",\\"discription\\":\\"markdown编译\\"},\\r\\n    {\\"name\\":\\"run\\",\\"enable\\":true,\\"type\\":\\"package\\",\\"path\\":\\"app-lib-cli-plugin-run\\",\\"discription\\":\\"自定义命令\\"},\\r\\n    {\\"name\\":\\"server\\",\\"enable\\":true,\\"type\\":\\"package\\",\\"path\\":\\"app-lib-cli-plugin-server\\",\\"discription\\":\\"启动服务\\"},\\r\\n    {\\"name\\":\\"init\\",\\"enable\\":true,\\"type\\":\\"package\\",\\"path\\":\\"app-lib-cli-plugin-init\\",\\"discription\\":\\"初始工程\\"},\\r\\n    {\\"name\\":\\"doc\\",\\"enable\\":true,\\"type\\":\\"package\\",\\"path\\":\\"app-lib-cli-plugin-doc\\",\\"discription\\":\\"API文档\\"}\\r\\n]"}]');

/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
/**
 * * commonder  命令组件
 * https://github.com/tj/commander.js/blob/master/Readme_zh-CN.md
 * 
 */
const { initCommond } = __webpack_require__(424);
const utils = __webpack_require__(555);
let { log, commander: { Command },
    utils: { action, autoRequireFile } } = utils;

// log.mi("---------内置路径:", {
//     getMainPath: inner.getMainPath(),
//     getRootPath: inner.getRootPath(),
//     getBinPath: inner.getBinPath(),
//     getBin_appbir: inner.getBin('appbir'),
//     getBin_npm: inner.getBin('npm'),
//     getBin_node: inner.getBin('app-lib-node'),
// })

// log.mi("---------引用路径:", {
//     getMainPath: nodes.getMainPath(),
//     getRootPath: nodes.getRootPath(),
//     getBinPath: nodes.getBinPath(),
//     getBin_appbir: nodes.getBin('appbir'),
//     getBin_npm: nodes.getBin('npm'),
//     getBin_node: nodes.getBin('app-lib-node'),
// })


const program = new Command();

/**
 *  初始化日志
 */
log.auotLevel();


/**
 * 初始化命令
 */
let { registerCommond } = initCommond({ ...utils, program });

// 获取PKG.json的配置
const PKG = autoRequireFile('package.json');

// 打印显示内容
const display = async () => {
    log.mi("usage [ appbir --help ] , show support commond >")
    log.T(registerCommond);
    return 0;
}

/**
 * appbir 的总入口命令
 * 所有的debugger 命令会被外出拦截 最好不要添加其他命令
 */
program
    .version(`v${PKG.version}`, '-v,--version', 'the current version')
    .description('appbir personal cli tool for speed work, you can connection email for appbir@163.com')
    .action(action.bind(null, { start: display, commond: PKG.name }));


log.md("run.argv", JSON.stringify(process.argv.slice(2)))

/**
 * 命令解析
 */
program.parse(process.argv);

})();

/******/ 	return __webpack_exports__;
/******/ })()
;
});
//# sourceMappingURL=cli-bundle.js.map