text: 'use strict';
  
  function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
  
  var assign = require('lodash').assign;
  var attachHook = require('./attachHook');
  var dirname = require('path').dirname;
  var genericNames = require('generic-names');
  var globToRegex = require('glob-to-regexp');
  var identity = require('lodash').identity;
  var negate = require('lodash').negate;
  var camelCaseFunc = require('lodash').camelCase;
  var mapKeys = require('lodash').mapKeys;
  var readFileSync = require('fs').readFileSync;
  var relative = require('path').relative;
  var resolve = require('path').resolve;
  var validate = require('./validate');
  
  var postcss = require('postcss');
  var Values = require('postcss-modules-values');
  var LocalByDefault = require('postcss-modules-local-by-default');
  var ExtractImports = require('postcss-modules-extract-imports');
  var Scope = require('postcss-modules-scope');
  var Parser = require('postcss-modules-parser');
  
  var debugFetch = require('debug')('css-modules:fetch');
  var debugSetup = require('debug')('css-modules:setup');
  
  module.exports = function setupHook(_ref) {
    var devMode = _ref.devMode;
    var _ref$extensions = _ref.extensions;
    var extensions = _ref$extensions === undefined ? '.css' : _ref$extensions;
    var ignore = _ref.ignore;
    var _ref$preprocessCss = _ref.preprocessCss;
    var preprocessCss = _ref$preprocessCss === undefined ? identity : _ref$preprocessCss;
    var processCss = _ref.processCss;
    var processorOpts = _ref.processorOpts;
    var camelCase = _ref.camelCase;
    var _ref$append = _ref.append;
    var append = _ref$append === undefined ? [] : _ref$append;
    var _ref$prepend = _ref.prepend;
    var prepend = _ref$prepend === undefined ? [] : _ref$prepend;
    var createImportedName = _ref.createImportedName;
    var generateScopedName = _ref.generateScopedName;
    var hashPrefix = _ref.hashPrefix;
    var mode = _ref.mode;
    var use = _ref.use;
    var _ref$rootDir = _ref.rootDir;
    var context = _ref$rootDir === undefined ? process.cwd() : _ref$rootDir;
  
    debugSetup(arguments[0]);
    validate(arguments[0]);
  
    var tokensByFile = {};
  
    // debug option is preferred NODE_ENV === 'development'
    var debugMode = typeof devMode !== 'undefined' ? devMode : process.env.NODE_ENV === 'development';
  
    var scopedName = void 0;
    if (generateScopedName) {
      scopedName = typeof generateScopedName !== 'function' ? genericNames(generateScopedName, { context: context, hashPrefix: hashPrefix }) //  for example '[name]__[local]___[hash:base64:5]'
      : generateScopedName;
    } else {
      // small fallback
      scopedName = function scopedName(local, filename) {
        return Scope.generateScopedName(local, relative(context, filename));
      };
    }
  
    var plugins = (use || [].concat(_toConsumableArray(prepend), [Values, mode ? new LocalByDefault({ mode: mode }) : LocalByDefault, createImportedName ? new ExtractImports({ createImportedName: createImportedName }) : ExtractImports, new Scope({ generateScopedName: scopedName })], _toConsumableArray(append))).concat(new Parser({ fetch: fetch })); // no pushing in order to avoid the possible mutations;
  
    // https://github.com/postcss/postcss#options
    var runner = postcss(plugins);
  
    /**
     * @todo   think about replacing sequential fetch function calls with requires calls
     * @param  {string} _to
     * @param  {string} from
     * @return {object}
     */
    function fetch(_to, from) {
      // getting absolute path to the processing file
      var filename = /[^\\/?%*:|"<>\.]/i.test(_to[0]) ? require.resolve(_to) : resolve(dirname(from), _to);
  
      // checking cache
      var tokens = tokensByFile[filename];
      if (tokens) {
        debugFetch(filename + ' \u2192 cache');
        debugFetch(tokens);
        return tokens;
      }
  
      var source = preprocessCss(readFileSync(filename, 'utf8'), filename);
      // https://github.com/postcss/postcss/blob/master/docs/api.md#processorprocesscss-opts
      var lazyResult = runner.process(source, assign({}, processorOpts, { from: filename }));
  
      // https://github.com/postcss/postcss/blob/master/docs/api.md#lazywarnings
      lazyResult.warnings().forEach(function (message) {
        return console.warn(message.text);
      });
  
      tokens = lazyResult.root.tokens;
  
      if (camelCase) {
        tokens = assign(mapKeys(tokens, function (value, key) {
          return camelCaseFunc(key);
        }), tokens);
      }
  
      if (!debugMode) {
        // updating cache
        tokensByFile[filename] = tokens;
      } else {
        // clearing cache in development mode
        delete require.cache[filename];
      }
  
      if (processCss) {
        processCss(lazyResult.css, filename);
      }
  
      debugFetch(filename + ' \u2192 fs');
      debugFetch(tokens);
  
      return tokens;
    };
  
    var exts = toArray(extensions);
    var isException = buildExceptionChecker(ignore);
  
    // @todo add possibility to specify particular config for each extension
    exts.forEach(function (extension) {
      return attachHook(function (filename) {
        return fetch(filename, filename);
      }, extension, isException);
    });
  };
  
  /**
   * @param  {*} option
   * @return {array}
   */
  function toArray(option) {
    return Array.isArray(option) ? option : [option];
  }
  
  /**
   * @param  {function|regex|string} ignore glob, regex or function
   * @return {function}
   */
  function buildExceptionChecker(ignore) {
    if (ignore instanceof RegExp) {
      return function (filepath) {
        return ignore.test(filepath);
      };
    }
  
    if (typeof ignore === 'string') {
      return function (filepath) {
        return globToRegex(ignore).test(filepath);
      };
    }
  
    return ignore || negate(identity);
  }