Parse input and save the i18n strings to a PO file.

@param Array|String input Array of files to parse or input string
@param Object options Options
@param Function cb Callback
351214
function xgettext (input, options, cb) {
  if (typeof options === 'function') {
    cb = options;
    options = {};
  }

  options = options || {};

  if (!input) {
    throw new Error('No input specified');
  }

  if (!options.language && typeof input === 'string') {
    throw new Error('Language is required');
  }

  options['output'] = options['output'] || 'messages.po';
  options.directory = options.directory || ['.'];
  options.keyword = options.keyword || [];
  options['from-code'] = options['from-code'] || 'utf8';
  options['force-po'] = options['force-po'] || false;
  options['join-existing'] = options['join-existing'] || false;

  if (typeof options.keyword === 'string') {
    options.keyword = [options.keyword];
  }

  if (typeof options.directory === 'string') {
    options.directory = [options.directory];
  }

  const parsers = {};
  const getParser = function (name, keywordSpec) {
    name = name.trim().toLowerCase();

    if (!parsers[name]) {
      const Parser = require(`gettext-${name}`);

      if (Object.keys(keywordSpec).length > 0) {
        parsers[name] = new Parser(keywordSpec);
      } else if (Parser.keywordSpec) {
        parsers[name] = new Parser(Parser.keywordSpec);
      } else {
        parsers[name] = new Parser();
      }
    }

    return parsers[name];
  };

  const keywordSpec = createKeywordSpec(options.keyword);
  const translations = Object.create(null);

  const parseTemplate = function (parser, template, linePrefixer) {
    const strings = parser.parse(template);

    for (const key in strings) {
      if (strings.hasOwnProperty(key)) {
        const msgctxt = strings[key].msgctxt || '';
        const context = translations[msgctxt] || (translations[msgctxt] = {});
        const msgid = strings[key].msgid || key;
        context[msgid] = context[msgid] || { msgid: msgid, comments: {} };

        if (msgctxt) {
          context[msgid].msgctxt = strings[key].msgctxt;
        }

        if (strings[key].plural) {
          context[msgid].msgid_plural = context[msgid].msgid_plural || strings[key].plural;
          context[msgid].msgstr = ['', ''];
        }

        if (!options['no-location']) {
          context[msgid].comments.reference = (context[msgid].comments.reference || '')
            .split('\n')
            .concat(strings[key].line.map(linePrefixer))
            .join('\n')
            .trim('\n');
        }
      }
    }
  };

  const output = function () {
    if (cb) {
      if (Object.keys(translations).length > 0 || options['force-po']) {
        let existing = {};
        const writeToStdout = options.output === '-' || options.output === '/dev/stdout';

        if (!writeToStdout && options['join-existing']) {
          try {
            fs.accessSync(options.output, fs.F_OK);
            existing = gt.po.parse(fs.readFileSync(options.output, {
              encoding: options['from-code']
            }));
          } catch (e) {
            // ignore non-existing file
          }

          mergeDeep(translations, existing.translations);
        }

        const po = gt.po.compile({
          charset: options['from-code'],
          headers: {
            'content-type': `text/plain; charset=${options['from-code']}`
          },
          translations: translations
        });

        if (writeToStdout) {
          cb(po);
        } else {
          fs.writeFile(options.output, po, err => {
            if (err) {
              throw err;
            }

            cb(po);
          });
        }
      } else {
        cb();
      }
    }
  };

  if (typeof input === 'string') {
    parseTemplate(
      getParser(options.language, keywordSpec),
      input,
      line => `standard input:${line}`
    );

    output();
  } else {
    const addPath = path => line => `${path}:${line}`;

    if (options['files-from']) {
      input = fs.readFileSync(options['files-from'], options['from-code'])
        .split('\n')
        .filter(line => line.trim().length > 0);
    }

    const files = options.directory.reduce(
      (result, directory) => result.concat(input.map(
        file => path.join(directory, file.replace(/\\/g, path.sep))
      )),
      []
    );

    async.parallel(files.map(function (file) {
      return function (cb) {
        fs.readFile(path.resolve(file), options['from-code'], (err, res) => {
          if (err) {
            throw err;
          }

          const extension = path.extname(file);
          const language = options.language || xgettext.languages[extension];

          if (!language) {
            throw new Error(`No language specified for extension '${extension}'.`);
          }

          parseTemplate(getParser(language, keywordSpec), res, addPath(file.replace(/\\/g, '/')));

          cb();
        });
      };
    }), output);
  }
}
595089
function (str, options, cb) {
    var tmpl = this.cache(options) || this.cache(options, this.engine.compile(str, options));
    tmpl.eval(options, function(str){
      cb(null, str);
    });
  }
214356
function (filePath, cb) {
            filePath = getFileWithExt(filePath);
            if (cb) {
                fs.readFile(filePath, function (err, data) {
                    if (err) {
                        cb(err);
                    } else {
                        cb(null, data.toString('utf8'));
                    }
                })
            } else {
                try {
                    var data = fs.readFileSync(filePath);
                } catch (err) {
                    throw err;
                }
                return data.toString('utf8');
            }
        }
208861
function initArrays(optlist, parsedOptions){
	Object.keys(optlist).forEach(function(key) {
		if (optlist[key].type === Array && !(key in parsedOptions)) {
			parsedOptions[key] = [];
		}
	});
}
628116
function parseString(xml, cb) {
    return fastxml2js.parseString(xml, function(err, data) {
        //So that it's asynchronous
        process.nextTick(function() {
            cb(err, data);
        });
    });
}
134249
public static function fromString($string, Translations $translations, array $options = [])
    {
        $lines = \explode("\n", $string);
        $i = 0;

        $translation = new Translation('', '');

        for ($n = \count($lines); $i < $n; ++$i) {
            $line = \trim($lines[$i]);
            $line = self::fixMultiLines($line, $lines, $i);

            if ($line === '') {
                if ($translation->is('', '')) {
                    self::extractHeaders($translation->getTranslation(), $translations);
                } elseif ($translation->hasOriginal()) {
                    $translations[] = $translation;
                }

                $translation = new Translation('', '');
                continue;
            }

            $splitLine = \preg_split('/\s+/', $line, 2);
            $key = $splitLine[0];
            $data = $splitLine[1] ?? '';

            if ($key === '#~') {
                $translation->setDisabled(true);

                $splitLine = \preg_split('/\s+/', $data, 2);
                $key = $splitLine[0];
                $data = $splitLine[1] ?? '';
            }

            switch ($key) {
                case '#':
                    $translation->addComment($data);
                    $append = null;
                    break;

                case '#.':
                    $translation->addExtractedComment($data);
                    $append = null;
                    break;

                case '#,':
                    foreach (\array_map('\trim', \explode(',', \trim($data))) as $value) {
                        $translation->addFlag($value);
                    }
                    $append = null;
                    break;

                case '#:':
                    foreach (\preg_split('/\s+/', \trim($data)) as $value) {
                        if (\preg_match('/^(.+)(:(\d*))?$/U', $value, $matches)) {
                            $translation->addReference($matches[1], $matches[3] ?? null);
                        }
                    }
                    $append = null;
                    break;

                case 'msgctxt':
                    $translation = $translation->getClone(self::convertString($data));
                    $append = 'Context';
                    break;

                case 'msgid':
                    $translation = $translation->getClone(null, self::convertString($data));
                    $append = 'Original';
                    break;

                case 'msgid_plural':
                    $translation->setPlural(self::convertString($data));
                    $append = 'Plural';
                    break;

                case 'msgstr':
                case 'msgstr[0]':
                    $translation->setTranslation(self::convertString($data));
                    $append = 'Translation';
                    break;

                case 'msgstr[1]':
                    $translation->setPluralTranslations([self::convertString($data)]);
                    $append = 'PluralTranslation';
                    break;

                default:
                    if (\strpos($key, 'msgstr[') === 0) {
                        $p = $translation->getPluralTranslations();
                        $p[] = self::convertString($data);

                        $translation->setPluralTranslations($p);
                        $append = 'PluralTranslation';
                        break;
                    }

                    if (isset($append)) {
                        if ($append === 'Context') {
                            $translation = $translation->getClone($translation->getContext()
                                . "\n"
                                . self::convertString($data));
                            break;
                        }

                        if ($append === 'Original') {
                            $translation = $translation->getClone(null, $translation->getOriginal()
                                . "\n"
                                . self::convertString($data));
                            break;
                        }

                        if ($append === 'PluralTranslation') {
                            $p = $translation->getPluralTranslations();
                            $p[] = \array_pop($p) . "\n" . self::convertString($data);
                            $translation->setPluralTranslations($p);
                            break;
                        }

                        $getMethod = 'get' . $append;
                        $setMethod = 'set' . $append;
                        $translation->$setMethod($translation->$getMethod() . "\n" . self::convertString($data));
                    }
                    break;
            }
        }

        if ($translation->hasOriginal() && !\in_array($translation, \iterator_to_array($translations))) {
            $translations[] = $translation;
        }
    }
1104493
function splitArgsIntoOptionsAndCallback (args) {
  let params;
  let options;
  let cb;
  if (args.length > 1) {
    const possibleCb = args[args.length - 1];
    if ('function' === typeof possibleCb) {
      cb = possibleCb;
      options = args.length === 3 ? args[1] : undefined;
    } else {
      options = args[1];
    }
    params = args[0];
  } else if ('object' === typeof args[0]) {
    params = args[0];
  } else if ('function' === typeof args[0]) {
    cb = args[0];
  }
  return { params, options, cb };
}
486478
function (message, config, cb) {
        if(typeof config === 'function') {
            cb = config;
            config = {};
        }
        var stdin = config.stdin || process.stdin,
            stdout = config.stdout || process.stdout,
            prompt = config.prompt || '\u203A';
        stdout.write('  ' + message + '\n  ' + prompt + ' ');
        stdin.resume();
        stdin.setEncoding('utf8');
        stdin.on('data', function (text) {
            text = text.trim().replace(/\r\n|\n/, '');
            cb(text);
        });
    }
797725
function parse(str, options, callback) {
	if (typeof options === 'function') {
		callback = options
		options = {}
	}
	process.nextTick(() => {
		const output = parseSync(str, options)
		callback(output)
	})
}
525578
function( key /* or array */, callback ) {
            var me = this;
            if ( this.isArray( key ) ) {
                var values = [];
                for ( var i = 0, il = key.length; i < il; i++ ) {
                    me.get( key[i], function( result ) {
                        if ( result ) values.push( result );
                        if ( values.length === il && callback ) {
                            me.lambda( callback ).call( me, values );
                        }
                    });
                }
            } else {
                var error = function(e) { fail( e ); if ( callback ) me.lambda( callback ).call( me ); };
                root( this, function( store ) {
                    store.getFile( key, {create:false}, function( entry ) {
                        entry.file(function( file ) {
                            var reader = new FileReader();

                            reader.onerror = error;

                            reader.onload = function(e) {
                                if ( callback ) me.lambda( callback ).call( me, JSON.parse( e.target.result ) );
                            };

                            reader.readAsText( file );
                        }, error );
                    }, error );
                });
            }
            return this;
        }
830585
function astFromFile(options, file, cb) {
  function convertSourceFile(file, packageName, packagePath) {
    fs.readFile(file, 'utf-8', function (err, source) {
      if (err) {
        return cb(err);
      }
      var extension = path.extname(file);
      if (extension[0] === '.') {
        extension = extension.substr(1);
      }
      astFromSource(options, source, extension, function (err, ast) {
        if (err) {
          err.file = file;
          return cb(err);
        }
        if (packageName) {
          ast.package = {name: packageName, path: packagePath};
          if (packagePath[0] !== '/') {
            ast.package.path = path.join(process.cwd(), packagePath);
          }
          ast.package.originalPath = packagePath;
        }
        ast.originalPath = file;
        if (file[0] === '/') {
          ast.path = file;
        } else {
          ast.path = path.join(process.cwd(), file);
        }
        return cb(null, ast);
      });
    });
  }

  function convertPackage() {
    if (path.basename(file) === 'package.json') {
      fs.readFile(file, 'utf-8', function (err, pkgString) {
        try {
          var pkg = JSON.parse(pkgString);
          if (!pkg.main) {
            return cb(new Error(file + " has no main modules."));
          }
          var main = path.join(path.dirname(file), pkg.main);
          if (!main.match(/\.js$/)) {
            main = main + '.js';
          }
          convertSourceFile(main, pkg.name, file);
        } catch (packageParseError) {
          packageParseError.message = 'Error parsing ' + file + ' - ' + packageParseError.message;
          return cb(packageParseError);
        }
      });
    } else {
      convertSourceFile(file, null);
    }
  }

  convertPackage();
}
1202702
function geocode(point, options, _callback, _errorCallback) {
  let promise;
  let cb_resolve, cb_reject;

  var addr = settings.GEOCODEHOST;
  addr += "?point=" + +point[0] + "," + +point[1];

  if (typeof options == "function") {
    _errorCallback = _callback;
    _callback = options;
    options = {};
  }

  options = {
    lang: "en",
    seq: 0,
    ...(options || {})
  };

  if (options.seq) {
    addr += "&seq=" + +options.seq;
  }
  if (options.lang) {
    addr += "&lng=" + options.lang;
  }

  if (typeof Promise != "undefined") {
    promise = new Promise((resolve, reject) => {
      cb_resolve = resolve;
      cb_reject = reject;
    });
  } else {
    cb_resolve = cb_reject = () => {};
  }

  const callback = geojson => {
    cb_resolve(geojson);
    _callback && _callback(geojson);
  };

  const errorCallback = geojson => {
    cb_reject(geojson);
    _errorCallback && _errorCallback(geojson);
  };

  settings.load(addr, json => callback(json), err => errorCallback(err));

  return promise;
}
1019763
function parse(fileString, callback) {
	return NginxConf.parse(fileString, function(err, _config) {
		if (err) {
			return callback(err);
		}

		return parseNginxConf(_config, callback);
	});
}
159870
function(params, cb) {
    if (CONSOLE_MESSAGES) console.log(new Date().toISOString(),'S3Handler.getObject params:',params);

    S3Handler.s3.getObject({Bucket: S3Handler.options.bucket, Key: params.Key}, function(error, responseData) {
      if (error) {
        if (CONSOLE_MESSAGES) console.log(new Date().toISOString(),"S3.getObject Error:", error);
        cb(error, null);
      } else {
        // decode response body according to params.type
        switch(params.type.toLowerCase()) {
          case 'json':
            var responseData = JSON.parse(responseData.Body);
          break;
          case 'stream':
            var responseData = responseData.Body.toString();
          break;
        }

        if (CONSOLE_MESSAGES) console.log(new Date().toISOString(),'S3Handler.getObject responseData:',responseData);

        cb(null, responseData);
      }
    });
  }
84973
function parse($TEXT, options) {

    options = defaults(options, {
        bare_returns   : false,
        cli            : false,
        expression     : false,
        filename       : null,
        html5_comments : true,
        shebang        : true,
        strict         : false,
        toplevel       : null,
    });

    var S = {
        input         : (typeof $TEXT == "string"
                         ? tokenizer($TEXT, options.filename,
                                     options.html5_comments, options.shebang)
                         : $TEXT),
        token         : null,
        prev          : null,
        peeked        : null,
        in_function   : 0,
        in_directives : true,
        in_loop       : 0,
        labels        : []
    };

    S.token = next();

    function is(type, value) {
        return is_token(S.token, type, value);
    };

    function peek() { return S.peeked || (S.peeked = S.input()); };

    function next() {
        S.prev = S.token;
        if (S.peeked) {
            S.token = S.peeked;
            S.peeked = null;
        } else {
            S.token = S.input();
        }
        S.in_directives = S.in_directives && (
            S.token.type == "string" || is("punc", ";")
        );
        return S.token;
    };

    function prev() {
        return S.prev;
    };

    function croak(msg, line, col, pos) {
        var ctx = S.input.context();
        js_error(msg,
                 ctx.filename,
                 line != null ? line : ctx.tokline,
                 col != null ? col : ctx.tokcol,
                 pos != null ? pos : ctx.tokpos);
    };

    function token_error(token, msg) {
        croak(msg, token.line, token.col);
    };

    function unexpected(token) {
        if (token == null)
            token = S.token;
        token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
    };

    function expect_token(type, val) {
        if (is(type, val)) {
            return next();
        }
        token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»");
    };

    function expect(punc) { return expect_token("punc", punc); };

    function can_insert_semicolon() {
        return !options.strict && (
            S.token.nlb || is("eof") || is("punc", "}")
        );
    };

    function semicolon(optional) {
        if (is("punc", ";")) next();
        else if (!optional && !can_insert_semicolon()) unexpected();
    };

    function parenthesised() {
        expect("(");
        var exp = expression(true);
        expect(")");
        return exp;
    };

    function embed_tokens(parser) {
        return function() {
            var start = S.token;
            var expr = parser();
            var end = prev();
            expr.start = start;
            expr.end = end;
            return expr;
        };
    };

    function handle_regexp() {
        if (is("operator", "/") || is("operator", "/=")) {
            S.peeked = null;
            S.token = S.input(S.token.value.substr(1)); // force regexp
        }
    };

    var statement = embed_tokens(function() {
        handle_regexp();
        switch (S.token.type) {
          case "string":
            if (S.in_directives) {
                var token = peek();
                if (S.token.raw.indexOf("\\") == -1
                    && (token.nlb
                        || is_token(token, "eof")
                        || is_token(token, "punc", ";")
                        || is_token(token, "punc", "}"))) {
                    S.input.add_directive(S.token.value);
                } else {
                    S.in_directives = false;
                }
            }
            var dir = S.in_directives, stat = simple_statement();
            return dir ? new AST_Directive(stat.body) : stat;
          case "num":
          case "regexp":
          case "operator":
          case "atom":
            return simple_statement();

          case "name":
            return is_token(peek(), "punc", ":")
                ? labeled_statement()
                : simple_statement();

          case "punc":
            switch (S.token.value) {
              case "{":
                return new AST_BlockStatement({
                    start : S.token,
                    body  : block_(),
                    end   : prev()
                });
              case "[":
              case "(":
                return simple_statement();
              case ";":
                S.in_directives = false;
                next();
                return new AST_EmptyStatement();
              default:
                unexpected();
            }

          case "keyword":
            switch (S.token.value) {
              case "break":
                next();
                return break_cont(AST_Break);

              case "continue":
                next();
                return break_cont(AST_Continue);

              case "debugger":
                next();
                semicolon();
                return new AST_Debugger();

              case "do":
                next();
                var body = in_loop(statement);
                expect_token("keyword", "while");
                var condition = parenthesised();
                semicolon(true);
                return new AST_Do({
                    body      : body,
                    condition : condition
                });

              case "while":
                next();
                return new AST_While({
                    condition : parenthesised(),
                    body      : in_loop(statement)
                });

              case "for":
                next();
                return for_();

              case "function":
                next();
                return function_(AST_Defun);

              case "if":
                next();
                return if_();

              case "return":
                if (S.in_function == 0 && !options.bare_returns)
                    croak("'return' outside of function");
                next();
                var value = null;
                if (is("punc", ";")) {
                    next();
                } else if (!can_insert_semicolon()) {
                    value = expression(true);
                    semicolon();
                }
                return new AST_Return({
                    value: value
                });

              case "switch":
                next();
                return new AST_Switch({
                    expression : parenthesised(),
                    body       : in_loop(switch_body_)
                });

              case "throw":
                next();
                if (S.token.nlb)
                    croak("Illegal newline after 'throw'");
                var value = expression(true);
                semicolon();
                return new AST_Throw({
                    value: value
                });

              case "try":
                next();
                return try_();

              case "var":
                next();
                var node = var_();
                semicolon();
                return node;

              case "const":
                next();
                var node = const_();
                semicolon();
                return node;

              case "with":
                if (S.input.has_directive("use strict")) {
                    croak("Strict mode may not include a with statement");
                }
                next();
                return new AST_With({
                    expression : parenthesised(),
                    body       : statement()
                });
            }
        }
        unexpected();
    });

    function labeled_statement() {
        var label = as_symbol(AST_Label);
        if (find_if(function(l){ return l.name == label.name }, S.labels)) {
            // ECMA-262, 12.12: An ECMAScript program is considered
            // syntactically incorrect if it contains a
            // LabelledStatement that is enclosed by a
            // LabelledStatement with the same Identifier as label.
            croak("Label " + label.name + " defined twice");
        }
        expect(":");
        S.labels.push(label);
        var stat = statement();
        S.labels.pop();
        if (!(stat instanceof AST_IterationStatement)) {
            // check for `continue` that refers to this label.
            // those should be reported as syntax errors.
            // https://github.com/mishoo/UglifyJS2/issues/287
            label.references.forEach(function(ref){
                if (ref instanceof AST_Continue) {
                    ref = ref.label.start;
                    croak("Continue label `" + label.name + "` refers to non-IterationStatement.",
                          ref.line, ref.col, ref.pos);
                }
            });
        }
        return new AST_LabeledStatement({ body: stat, label: label });
    };

    function simple_statement(tmp) {
        return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) });
    };

    function break_cont(type) {
        var label = null, ldef;
        if (!can_insert_semicolon()) {
            label = as_symbol(AST_LabelRef, true);
        }
        if (label != null) {
            ldef = find_if(function(l){ return l.name == label.name }, S.labels);
            if (!ldef)
                croak("Undefined label " + label.name);
            label.thedef = ldef;
        }
        else if (S.in_loop == 0)
            croak(type.TYPE + " not inside a loop or switch");
        semicolon();
        var stat = new type({ label: label });
        if (ldef) ldef.references.push(stat);
        return stat;
    };

    function for_() {
        expect("(");
        var init = null;
        if (!is("punc", ";")) {
            init = is("keyword", "var")
                ? (next(), var_(true))
                : expression(true, true);
            if (is("operator", "in")) {
                if (init instanceof AST_Var && init.definitions.length > 1)
                    croak("Only one variable declaration allowed in for..in loop");
                next();
                return for_in(init);
            }
        }
        return regular_for(init);
    };

    function regular_for(init) {
        expect(";");
        var test = is("punc", ";") ? null : expression(true);
        expect(";");
        var step = is("punc", ")") ? null : expression(true);
        expect(")");
        return new AST_For({
            init      : init,
            condition : test,
            step      : step,
            body      : in_loop(statement)
        });
    };

    function for_in(init) {
        var lhs = init instanceof AST_Var ? init.definitions[0].name : null;
        var obj = expression(true);
        expect(")");
        return new AST_ForIn({
            init   : init,
            name   : lhs,
            object : obj,
            body   : in_loop(statement)
        });
    };

    var function_ = function(ctor) {
        var in_statement = ctor === AST_Defun;
        var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
        if (in_statement && !name)
            unexpected();
        expect("(");
        return new ctor({
            name: name,
            argnames: (function(first, a){
                while (!is("punc", ")")) {
                    if (first) first = false; else expect(",");
                    a.push(as_symbol(AST_SymbolFunarg));
                }
                next();
                return a;
            })(true, []),
            body: (function(loop, labels){
                ++S.in_function;
                S.in_directives = true;
                S.input.push_directives_stack();
                S.in_loop = 0;
                S.labels = [];
                var a = block_();
                S.input.pop_directives_stack();
                --S.in_function;
                S.in_loop = loop;
                S.labels = labels;
                return a;
            })(S.in_loop, S.labels)
        });
    };

    function if_() {
        var cond = parenthesised(), body = statement(), belse = null;
        if (is("keyword", "else")) {
            next();
            belse = statement();
        }
        return new AST_If({
            condition   : cond,
            body        : body,
            alternative : belse
        });
    };

    function block_() {
        expect("{");
        var a = [];
        while (!is("punc", "}")) {
            if (is("eof")) unexpected();
            a.push(statement());
        }
        next();
        return a;
    };

    function switch_body_() {
        expect("{");
        var a = [], cur = null, branch = null, tmp;
        while (!is("punc", "}")) {
            if (is("eof")) unexpected();
            if (is("keyword", "case")) {
                if (branch) branch.end = prev();
                cur = [];
                branch = new AST_Case({
                    start      : (tmp = S.token, next(), tmp),
                    expression : expression(true),
                    body       : cur
                });
                a.push(branch);
                expect(":");
            }
            else if (is("keyword", "default")) {
                if (branch) branch.end = prev();
                cur = [];
                branch = new AST_Default({
                    start : (tmp = S.token, next(), expect(":"), tmp),
                    body  : cur
                });
                a.push(branch);
            }
            else {
                if (!cur) unexpected();
                cur.push(statement());
            }
        }
        if (branch) branch.end = prev();
        next();
        return a;
    };

    function try_() {
        var body = block_(), bcatch = null, bfinally = null;
        if (is("keyword", "catch")) {
            var start = S.token;
            next();
            expect("(");
            var name = as_symbol(AST_SymbolCatch);
            expect(")");
            bcatch = new AST_Catch({
                start   : start,
                argname : name,
                body    : block_(),
                end     : prev()
            });
        }
        if (is("keyword", "finally")) {
            var start = S.token;
            next();
            bfinally = new AST_Finally({
                start : start,
                body  : block_(),
                end   : prev()
            });
        }
        if (!bcatch && !bfinally)
            croak("Missing catch/finally blocks");
        return new AST_Try({
            body     : body,
            bcatch   : bcatch,
            bfinally : bfinally
        });
    };

    function vardefs(no_in, in_const) {
        var a = [];
        for (;;) {
            a.push(new AST_VarDef({
                start : S.token,
                name  : as_symbol(in_const ? AST_SymbolConst : AST_SymbolVar),
                value : is("operator", "=") ? (next(), expression(false, no_in)) : null,
                end   : prev()
            }));
            if (!is("punc", ","))
                break;
            next();
        }
        return a;
    };

    var var_ = function(no_in) {
        return new AST_Var({
            start       : prev(),
            definitions : vardefs(no_in, false),
            end         : prev()
        });
    };

    var const_ = function() {
        return new AST_Const({
            start       : prev(),
            definitions : vardefs(false, true),
            end         : prev()
        });
    };

    var new_ = function(allow_calls) {
        var start = S.token;
        expect_token("operator", "new");
        var newexp = expr_atom(false), args;
        if (is("punc", "(")) {
            next();
            args = expr_list(")");
        } else {
            args = [];
        }
        return subscripts(new AST_New({
            start      : start,
            expression : newexp,
            args       : args,
            end        : prev()
        }), allow_calls);
    };

    function as_atom_node() {
        var tok = S.token, ret;
        switch (tok.type) {
          case "name":
          case "keyword":
            ret = _make_symbol(AST_SymbolRef);
            break;
          case "num":
            ret = new AST_Number({ start: tok, end: tok, value: tok.value });
            break;
          case "string":
            ret = new AST_String({
                start : tok,
                end   : tok,
                value : tok.value,
                quote : tok.quote
            });
            break;
          case "regexp":
            ret = new AST_RegExp({ start: tok, end: tok, value: tok.value });
            break;
          case "atom":
            switch (tok.value) {
              case "false":
                ret = new AST_False({ start: tok, end: tok });
                break;
              case "true":
                ret = new AST_True({ start: tok, end: tok });
                break;
              case "null":
                ret = new AST_Null({ start: tok, end: tok });
                break;
            }
            break;
          case "operator":
            if (!is_identifier_string(tok.value)) {
                croak("Invalid getter/setter name: " + tok.value,
                    tok.line, tok.col, tok.pos);
            }
            ret = _make_symbol(AST_SymbolRef);
            break;
        }
        next();
        return ret;
    };

    var expr_atom = function(allow_calls) {
        if (is("operator", "new")) {
            return new_(allow_calls);
        }
        var start = S.token;
        if (is("punc")) {
            switch (start.value) {
              case "(":
                next();
                var ex = expression(true);
                ex.start = start;
                ex.end = S.token;
                expect(")");
                return subscripts(ex, allow_calls);
              case "[":
                return subscripts(array_(), allow_calls);
              case "{":
                return subscripts(object_(), allow_calls);
            }
            unexpected();
        }
        if (is("keyword", "function")) {
            next();
            var func = function_(AST_Function);
            func.start = start;
            func.end = prev();
            return subscripts(func, allow_calls);
        }
        if (ATOMIC_START_TOKEN[S.token.type]) {
            return subscripts(as_atom_node(), allow_calls);
        }
        unexpected();
    };

    function expr_list(closing, allow_trailing_comma, allow_empty) {
        var first = true, a = [];
        while (!is("punc", closing)) {
            if (first) first = false; else expect(",");
            if (allow_trailing_comma && is("punc", closing)) break;
            if (is("punc", ",") && allow_empty) {
                a.push(new AST_Hole({ start: S.token, end: S.token }));
            } else {
                a.push(expression(false));
            }
        }
        next();
        return a;
    };

    var array_ = embed_tokens(function() {
        expect("[");
        return new AST_Array({
            elements: expr_list("]", !options.strict, true)
        });
    });

    var create_accessor = embed_tokens(function() {
        return function_(AST_Accessor);
    });

    var object_ = embed_tokens(function() {
        expect("{");
        var first = true, a = [];
        while (!is("punc", "}")) {
            if (first) first = false; else expect(",");
            if (!options.strict && is("punc", "}"))
                // allow trailing comma
                break;
            var start = S.token;
            var type = start.type;
            var name = as_property_name();
            if (type == "name" && !is("punc", ":")) {
                var key = new AST_SymbolAccessor({
                    start: S.token,
                    name: as_property_name(),
                    end: prev()
                });
                if (name == "get") {
                    a.push(new AST_ObjectGetter({
                        start : start,
                        key   : key,
                        value : create_accessor(),
                        end   : prev()
                    }));
                    continue;
                }
                if (name == "set") {
                    a.push(new AST_ObjectSetter({
                        start : start,
                        key   : key,
                        value : create_accessor(),
                        end   : prev()
                    }));
                    continue;
                }
            }
            expect(":");
            a.push(new AST_ObjectKeyVal({
                start : start,
                quote : start.quote,
                key   : name,
                value : expression(false),
                end   : prev()
            }));
        }
        next();
        return new AST_Object({ properties: a });
    });

    function as_property_name() {
        var tmp = S.token;
        switch (tmp.type) {
          case "operator":
            if (!KEYWORDS(tmp.value)) unexpected();
          case "num":
          case "string":
          case "name":
          case "keyword":
          case "atom":
            next();
            return tmp.value;
          default:
            unexpected();
        }
    };

    function as_name() {
        var tmp = S.token;
        if (tmp.type != "name") unexpected();
        next();
        return tmp.value;
    };

    function _make_symbol(type) {
        var name = S.token.value;
        return new (name == "this" ? AST_This : type)({
            name  : String(name),
            start : S.token,
            end   : S.token
        });
    };

    function as_symbol(type, noerror) {
        if (!is("name")) {
            if (!noerror) croak("Name expected");
            return null;
        }
        var sym = _make_symbol(type);
        next();
        return sym;
    };

    var subscripts = function(expr, allow_calls) {
        var start = expr.start;
        if (is("punc", ".")) {
            next();
            return subscripts(new AST_Dot({
                start      : start,
                expression : expr,
                property   : as_name(),
                end        : prev()
            }), allow_calls);
        }
        if (is("punc", "[")) {
            next();
            var prop = expression(true);
            expect("]");
            return subscripts(new AST_Sub({
                start      : start,
                expression : expr,
                property   : prop,
                end        : prev()
            }), allow_calls);
        }
        if (allow_calls && is("punc", "(")) {
            next();
            return subscripts(new AST_Call({
                start      : start,
                expression : expr,
                args       : expr_list(")"),
                end        : prev()
            }), true);
        }
        return expr;
    };

    var maybe_unary = function(allow_calls) {
        var start = S.token;
        if (is("operator") && UNARY_PREFIX(start.value)) {
            next();
            handle_regexp();
            var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
            ex.start = start;
            ex.end = prev();
            return ex;
        }
        var val = expr_atom(allow_calls);
        while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) {
            val = make_unary(AST_UnaryPostfix, S.token, val);
            val.start = start;
            val.end = S.token;
            next();
        }
        return val;
    };

    function make_unary(ctor, token, expr) {
        var op = token.value;
        if ((op == "++" || op == "--") && !is_assignable(expr))
            croak("Invalid use of " + op + " operator", token.line, token.col, token.pos);
        return new ctor({ operator: op, expression: expr });
    };

    var expr_op = function(left, min_prec, no_in) {
        var op = is("operator") ? S.token.value : null;
        if (op == "in" && no_in) op = null;
        var prec = op != null ? PRECEDENCE[op] : null;
        if (prec != null && prec > min_prec) {
            next();
            var right = expr_op(maybe_unary(true), prec, no_in);
            return expr_op(new AST_Binary({
                start    : left.start,
                left     : left,
                operator : op,
                right    : right,
                end      : right.end
            }), min_prec, no_in);
        }
        return left;
    };

    function expr_ops(no_in) {
        return expr_op(maybe_unary(true), 0, no_in);
    };

    var maybe_conditional = function(no_in) {
        var start = S.token;
        var expr = expr_ops(no_in);
        if (is("operator", "?")) {
            next();
            var yes = expression(false);
            expect(":");
            return new AST_Conditional({
                start       : start,
                condition   : expr,
                consequent  : yes,
                alternative : expression(false, no_in),
                end         : prev()
            });
        }
        return expr;
    };

    function is_assignable(expr) {
        if (options.cli) return true;
        return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef;
    };

    var maybe_assign = function(no_in) {
        var start = S.token;
        var left = maybe_conditional(no_in), val = S.token.value;
        if (is("operator") && ASSIGNMENT(val)) {
            if (is_assignable(left)) {
                next();
                return new AST_Assign({
                    start    : start,
                    left     : left,
                    operator : val,
                    right    : maybe_assign(no_in),
                    end      : prev()
                });
            }
            croak("Invalid assignment");
        }
        return left;
    };

    var expression = function(commas, no_in) {
        var start = S.token;
        var expr = maybe_assign(no_in);
        if (commas && is("punc", ",")) {
            next();
            return new AST_Seq({
                start  : start,
                car    : expr,
                cdr    : expression(true, no_in),
                end    : peek()
            });
        }
        return expr;
    };

    function in_loop(cont) {
        ++S.in_loop;
        var ret = cont();
        --S.in_loop;
        return ret;
    };

    if (options.expression) {
        return expression(true);
    }

    return (function(){
        var start = S.token;
        var body = [];
        S.input.push_directives_stack();
        while (!is("eof"))
            body.push(statement());
        S.input.pop_directives_stack();
        var end = prev();
        var toplevel = options.toplevel;
        if (toplevel) {
            toplevel.body = toplevel.body.concat(body);
            toplevel.end = end;
        } else {
            toplevel = new AST_Toplevel({ start: start, body: body, end: end });
        }
        return toplevel;
    })();

}
1354318
function _filesToString (files, encoding, separator, callback) {

			if ("undefined" === typeof files) {
				throw new ReferenceError("missing \"files\" argument");
			}
				else if ("object" !== typeof files || !(files instanceof Array)) {
					throw new TypeError("\"files\" argument is not an Array");
				}
			else if ("undefined" === typeof callback && "undefined" === typeof separator && "undefined" === typeof encoding) {
				throw new ReferenceError("missing \"callback\" argument");
			}
				else if ("function" !== typeof callback && "function" !== typeof separator && "function" !== typeof encoding) {
					throw new TypeError("\"callback\" argument is not a function");
				}
			else {

				let _callback = callback;

				if ("undefined" === typeof _callback) {

					if ("undefined" === typeof separator) {
						_callback = encoding;
					}
					else {
						_callback = separator;
					}

				}

				filesToStreamProm(files, "string" === typeof separator ? separator : " ").then((readStream) => {

					return new Promise((resolve, reject) => {

						let data = "";
						let error = false;

						readStream.once("error", (_err) => {

							error = true;
							reject(_err);

						}).on("data", (chunk) => {
							data += chunk.toString("string" === typeof encoding ? encoding : "utf8");
						}).once("end", () => {

							if (!error) {
								resolve(data);
							}

						});

					});

				}).then((data) => {
					_callback(null, data);
				}).catch(_callback);

			}

		}
1102848
function parseArguments(opts, callback) {
  if ('function' === typeof opts) {
    callback = opts
    opts = {}
  }

  opts = opts || {}
  opts.callback = callback

  return opts
}