Skip to content
Snippets Groups Projects
index.js 7.56 MiB
Newer Older
  • Learn to ignore specific revisions
  • Romain CREY's avatar
    Romain CREY committed
    /******/ (function(modules) { // webpackBootstrap
    /******/ 	// The module cache
    /******/ 	var installedModules = {};
    /******/
    /******/ 	// The require function
    /******/ 	function __webpack_require__(moduleId) {
    /******/
    /******/ 		// Check if module is in cache
    /******/ 		if(installedModules[moduleId]) {
    /******/ 			return installedModules[moduleId].exports;
    /******/ 		}
    /******/ 		// Create a new module (and put it into the cache)
    /******/ 		var module = installedModules[moduleId] = {
    /******/ 			i: moduleId,
    /******/ 			l: false,
    /******/ 			exports: {}
    /******/ 		};
    /******/
    /******/ 		// Execute the module function
    /******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
    /******/
    /******/ 		// Flag the module as loaded
    /******/ 		module.l = true;
    /******/
    /******/ 		// Return the exports of the module
    /******/ 		return module.exports;
    /******/ 	}
    /******/
    /******/
    /******/ 	// expose the modules object (__webpack_modules__)
    /******/ 	__webpack_require__.m = modules;
    /******/
    /******/ 	// expose the module cache
    /******/ 	__webpack_require__.c = installedModules;
    /******/
    /******/ 	// define getter function for harmony exports
    /******/ 	__webpack_require__.d = function(exports, name, getter) {
    /******/ 		if(!__webpack_require__.o(exports, name)) {
    /******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
    /******/ 		}
    /******/ 	};
    /******/
    /******/ 	// define __esModule on exports
    /******/ 	__webpack_require__.r = function(exports) {
    /******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
    /******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
    /******/ 		}
    /******/ 		Object.defineProperty(exports, '__esModule', { value: true });
    /******/ 	};
    /******/
    /******/ 	// create a fake namespace object
    /******/ 	// mode & 1: value is a module id, require it
    /******/ 	// mode & 2: merge all properties of value into the ns
    /******/ 	// mode & 4: return value when already ns object
    /******/ 	// mode & 8|1: behave like require
    /******/ 	__webpack_require__.t = function(value, mode) {
    /******/ 		if(mode & 1) value = __webpack_require__(value);
    /******/ 		if(mode & 8) return value;
    /******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
    /******/ 		var ns = Object.create(null);
    /******/ 		__webpack_require__.r(ns);
    /******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
    /******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
    /******/ 		return ns;
    /******/ 	};
    /******/
    /******/ 	// getDefaultExport function for compatibility with non-harmony modules
    /******/ 	__webpack_require__.n = function(module) {
    /******/ 		var getter = module && module.__esModule ?
    /******/ 			function getDefault() { return module['default']; } :
    /******/ 			function getModuleExports() { return module; };
    /******/ 		__webpack_require__.d(getter, 'a', getter);
    /******/ 		return getter;
    /******/ 	};
    /******/
    /******/ 	// Object.prototype.hasOwnProperty.call
    /******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
    /******/
    /******/ 	// __webpack_public_path__
    /******/ 	__webpack_require__.p = "";
    /******/
    /******/
    /******/ 	// Load entry module and return exports
    /******/ 	return __webpack_require__(__webpack_require__.s = 0);
    /******/ })
    /************************************************************************/
    /******/ ([
    /* 0 */
    /***/ (function(module, exports, __webpack_require__) {
    
    const {
      BaseKonnector,
      log,
      errors,
      addData,
      hydrateAndFilter,
      cozyClient
    
    } = __webpack_require__(1);
    
    // const fetch = require('node-fetch')
    const rp = __webpack_require__(1307);
    const moment = __webpack_require__(1339);
    __webpack_require__(1476);
    
    moment.locale("fr"); // set the language
    moment.tz.setDefault("Europe/Paris"); // set the timezone
    
    
    const manualExecution =
    
      process.env.COZY_JOB_MANUAL_EXECUTION === "true" ? true : false;
    
    
    const startDate = manualExecution
    
          .subtract(1, "year")
          .format("MM/DD/YYYY")
    
          .subtract(3, "year")
          .format("MM/DD/YYYY");
    
    const endDate = moment().format("MM/DD/YYYY");
    
    // const timeRange = ['day', 'month', 'year']
    
    const rangeDate = {
      day: {
    
        doctype: "com.grandlyon.egl.day",
        keys: ["year", "month", "day"]
    
        doctype: "com.grandlyon.egl.month",
        keys: ["year", "month"]
    
        doctype: "com.grandlyon.egl.year",
        keys: ["year"]
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    module.exports = new BaseKonnector(start);
    
    Romain CREY's avatar
    Romain CREY committed
    
    // The start function is run by the BaseKonnector instance only when it got all the account
    // information (fields). When you run this connector yourself in "standalone" mode or "dev" mode,
    // the account information come from ./konnector-dev-config.json file
    async function start(fields, cozyParameters) {
      try {
    
        // Local debug data
    
        // const baseUrl = fields.eglBaseURL
        // const apiAuthKey = fields.eglAPIAuthKey
        const baseUrl = cozyParameters.secret.eglBaseURL;
        const apiAuthKey = cozyParameters.secret.eglAPIAuthKey;
        log("info", "Authenticating ...");
    
    Romain CREY's avatar
    Romain CREY committed
        const response = await authenticate(
          fields.login,
          fields.password,
          baseUrl,
          apiAuthKey
    
        );
        log("info", "Successfully logged in");
    
        const eglData = await getData(response, baseUrl, apiAuthKey);
    
        if (eglData) {
    
          log("debug", "Process egl daily data");
    
          const processedLoadData = await processData(
            eglData,
            rangeDate.day.doctype,
            rangeDate.day.keys
    
          );
          log("debug", "Agregate egl load data for month and year");
          await agregateMonthAndYearData(processedLoadData);
    
        } else {
    
          log("debug", "No data found");
    
    Romain CREY's avatar
    Romain CREY committed
      } catch (error) {
    
        throw new Error(error.message);
    
    Romain CREY's avatar
    Romain CREY committed
      }
    }
    
    /**
     * Parse data
     * Remove existing data from DB using hydrateAndFilter
     * Store filtered data
     * Return the list of filtered data
     */
    async function processData(data, doctype, filterKeys) {
      // const formatedData = await formateData(data)
    
      log("debug", "processData - data formated");
    
      // Remove data for existing days into the DB
      const filteredData = await hydrateAndFilter(data, doctype, {
        keys: filterKeys
    
      });
      log("debug", "processData - data filtered");
    
      // Store new day data
    
      await storeData(filteredData, doctype, filterKeys);
      return filteredData;
    
    }
    
    /**
     * Agregate data from daily data to monthly and yearly data
     */
    async function agregateMonthAndYearData(data) {
      // Sum year and month values into object with year or year-month as keys
      if (data && data.length !== 0) {
    
        let monthData = {};
        let yearData = {};
    
    
        data.forEach(element => {
    
          element.year + "-" + element.month in monthData
            ? (monthData[element.year + "-" + element.month] += element.load)
            : (monthData[element.year + "-" + element.month] = element.load);
    
          element.year in yearData
            ? (yearData[element.year] += element.load)
    
            : (yearData[element.year] = element.load);
        });
    
        // Agregation for Month data
        const agregatedMonthData = await buildAgregatedData(
          monthData,
    
          "com.grandlyon.egl.month"
        );
        await storeData(agregatedMonthData, "com.grandlyon.egl.month", [
          "year",
          "month"
        ]);
    
        // Agregation for Year data
        const agregatedYearData = await buildAgregatedData(
          yearData,
    
          "com.grandlyon.egl.year"
        );
        await storeData(agregatedYearData, "com.grandlyon.egl.year", ["year"]);
    
      }
    }
    
    /**
     * Retrieve and remove old data for a specific doctype
     * Return an Array of agregated data
     */
    async function buildAgregatedData(data, doctype) {
    
      log("info", "entering buildAgregatedData");
      let agregatedData = [];
    
      for (let [key, value] of Object.entries(data)) {
    
        const data = await buildDataFromKey(doctype, key, value);
        const oldValue = await resetInProgressAggregatedData(data, doctype);
        log("info", "Dataload + oldvalue is " + data.load + " + " + oldValue);
        data.load += oldValue;
        agregatedData.push(data);
    
      return agregatedData;
    
    Romain CREY's avatar
    Romain CREY committed
    async function authenticate(login, password, baseUrl, apiAuthKey) {
    
      
      log("debug", "BEFORE REQUEST");
    
    Romain CREY's avatar
    Romain CREY committed
      const authRequest = {
    
        uri: baseUrl + "/connect.aspx",
    
    Romain CREY's avatar
    Romain CREY committed
        headers: {
          AuthKey: apiAuthKey,
    
          "Content-Type": "application/x-www-form-urlencoded"
    
    Romain CREY's avatar
    Romain CREY committed
        },
    
    Romain CREY's avatar
    Romain CREY committed
          login: login,
          pass: password
    
      let response = {}
      try {
        await rp(authRequest);
      } catch(e) {
    
        log("debug", "POUET ERROR");
        log("debug", e)
    
      
      log("debug", `Auth code: ${response.codeRetour}`);
    
    Yoan VALLET's avatar
    Yoan VALLET committed
      if (response.codeRetour === 100) {
    
    Yoan VALLET's avatar
    Yoan VALLET committed
      } else {
    
        throw new Error(errors.LOGIN_FAILED);
    
    Romain CREY's avatar
    Romain CREY committed
      }
    }
    
    async function getData(response, baseUrl, apiAuthKey) {
    
      log("debug", "Start date : " + startDate);
      log("debug", "End date : " + endDate);
    
    Romain CREY's avatar
    Romain CREY committed
      const dataRequest = {
    
        uri: baseUrl + "/getAllAgregatsByAbonnement.aspx",
    
    Romain CREY's avatar
    Romain CREY committed
        headers: {
          AuthKey: apiAuthKey,
    
          "Content-Type": "application/x-www-form-urlencoded"
    
    Romain CREY's avatar
    Romain CREY committed
        },
    
    Romain CREY's avatar
    Romain CREY committed
          token: response.resultatRetour.token,
          num_abt: response.resultatRetour.num_abt,
          date_debut: startDate,
          date_fin: endDate
    
    Romain CREY's avatar
    Romain CREY committed
      try {
    
        // Sort data by date
    
        log("debug", "TRY ?");
    
        const responseEgl = await rp(dataRequest).then(eglRawData => {
          eglRawData.resultatRetour.sort(function(a, b) {
            return new Date(a.DateReleve) - new Date(b.DateReleve);
          });
          return eglRawData;
        });
    
        log("debug", `Code retour: ${responseEgl.codeRetour}`);
    
    Yoan VALLET's avatar
    Yoan VALLET committed
        switch (responseEgl.codeRetour) {
    
    Romain CREY's avatar
    Romain CREY committed
          case 100:
    
            return format(responseEgl);
    
    Romain CREY's avatar
    Romain CREY committed
          case -2:
    
            throw errors.LOGIN_FAILED;
    
    Romain CREY's avatar
    Romain CREY committed
          case -1:
    
            throw errors.VENDOR_DOWN;
    
    Romain CREY's avatar
    Romain CREY committed
          default:
    
            throw errors.UNKNOWN_ERROR;
    
    Romain CREY's avatar
    Romain CREY committed
        }
      } catch (error) {
    
        log("debug", "Error from getAllAgregatsByAbonnement");
        throw new Error(errors.VENDOR_DOWN);
    
    Romain CREY's avatar
    Romain CREY committed
      }
    }
    
    function format(response) {
    
      log("info", "origin response size is : " + response.resultatRetour.length);
    
      // Store first value as reference for index processing
    
      let refValue = response.resultatRetour[0];
    
      // Create copy of data without first value
    
    Yoan VALLET's avatar
    Yoan VALLET committed
      const data = response.resultatRetour
    
        .filter(value => value.ValeurIndex);
      log("info", "filtered size is : " + data.length);
    
      return data.map(value => {
    
        const time = moment(value.DateReleve, moment.ISO_8601);
        const procesedLoad = value.ValeurIndex - refValue.ValeurIndex;
    
        if (procesedLoad < 0) {
          log(
    
            "error",
            `processing load for day ${parseInt(time.format("D"))}/${parseInt(
              time.format("M")
            )}/${parseInt(time.format("YYYY"))}, value is : ${procesedLoad}`
          );
          throw errors.VENDOR_DOWN;
    
        }
        // Change index ref value
    
        return {
          load: procesedLoad,
    
          year: parseInt(time.format("YYYY")),
          month: parseInt(time.format("M")),
          day: parseInt(time.format("D")),
    
          hour: 0,
          minute: 0,
          type: value.TypeAgregat
    
    
    /**
     * Save data in the right doctype db and prevent duplicated keys
     */
    async function storeData(data, doctype, filterKeys) {
    
      log("debug", "Store into " + doctype);
      log("debug", "Store into keys : " + filterKeys);
    
      // data.map(v => {
      //   log("info", "Saving data " + v.load + " for " + v.day + "/" + v.month + "/" + v.year);
      // });
    
      const filteredDocuments = await hydrateAndFilter(data, doctype, {
        keys: filterKeys
    
      });
      return await addData(filteredDocuments, doctype);
    
    }
    
    /**
     * Format an entry for DB storage
     * using key and value
     * For year doctype: key = "YYYY"
     * For month doctype: key = "YYYY-MM"
     */
    async function buildDataFromKey(doctype, key, value) {
    
      let year, month, day, hour;
      if (doctype === "com.grandlyon.egl.year") {
        year = key;
        month = 1;
        day = 0;
        hour = 0;
      } else if (doctype === "com.grandlyon.egl.month") {
        const split = key.split("-");
        year = split[0];
        month = split[1];
        day = 0;
        hour = 0;
    
      } else {
    
        const split = key.split("-");
        year = split[0];
        month = split[1];
        day = split[2];
        hour = split[3];
    
      return {
        load: Math.round(value * 10000) / 10000,
        year: parseInt(year),
        month: parseInt(month),
        day: parseInt(day),
        hour: parseInt(hour),
        minute: 0
    
    /**
     * Function handling special case.
     * The temporary aggregated data need to be remove in order for the most recent one te be saved.
    
    Yoan VALLET's avatar
    Yoan VALLET committed
     * ex for com.grandlyon.egl.month :
    
     * { load: 76.712, month: 2020, ... } need to be replace by
    
     * { load: 82.212, month: 2020, ... } after egl data reprocess
    
    async function resetInProgressAggregatedData(data, doctype) {
    
      // /!\ Warning: cannot use mongo queries because not supported for dev by cozy-konnectors-libs
    
      log("debug", "Remove aggregated data for " + doctype);
      const result = await cozyClient.data.findAll(doctype);
    
      if (result && result.length > 0) {
    
        // Filter data to remove
    
        var filtered = [];
        if (doctype === "com.grandlyon.egl.year") {
    
          // Yearly case
          filtered = result.filter(function(el) {
    
            return el.year == data.year;
          });
        } else if (doctype === "com.grandlyon.egl.month") {
    
          filtered = result.filter(function(el) {
    
            return el.year == data.year && el.month == data.month;
          });
    
        } else {
          // Hourly case
    
          filtered = result.filter(function(el) {
            return (
    
              el.year == data.year &&
              el.month == data.month &&
              el.day == data.day &&
              el.hour == data.hour
    
        }
        // Remove data
    
        for (const doc of filtered) {
    
          sum += doc.load;
          log("debug", "Removing this entry for " + doc.load);
          await cozyClient.data.delete(doctype, doc);
    
    Romain CREY's avatar
    Romain CREY committed
      }
    
    Romain CREY's avatar
    Romain CREY committed
    }
    
    
    /***/ }),
    /* 1 */
    /***/ (function(module, exports, __webpack_require__) {
    
    
    const log = __webpack_require__(2).namespace('cozy-konnector-libs');
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const requestFactory = __webpack_require__(22);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const hydrateAndFilter = __webpack_require__(369);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const categorization = __webpack_require__(1162);
    
    Romain CREY's avatar
    Romain CREY committed
    
    module.exports = {
    
      BaseKonnector: __webpack_require__(1222),
      CookieKonnector: __webpack_require__(1300),
    
      cozyClient: __webpack_require__(485),
    
      errors: __webpack_require__(1228),
    
    Romain CREY's avatar
    Romain CREY committed
      log,
    
      saveFiles: __webpack_require__(1224),
      saveBills: __webpack_require__(1223),
      saveIdentity: __webpack_require__(1266),
      linkBankOperations: __webpack_require__(1245),
      addData: __webpack_require__(1244),
    
    Romain CREY's avatar
    Romain CREY committed
      hydrateAndFilter,
    
      htmlToPDF: __webpack_require__(1301).htmlToPDF,
      createCozyPDFDocument: __webpack_require__(1301).createCozyPDFDocument,
    
    Romain CREY's avatar
    Romain CREY committed
      filterData: deprecate(hydrateAndFilter, 'Use hydrateAndFilter now. filterData will be removed in cozy-konnector-libs@4'),
    
      updateOrCreate: __webpack_require__(1265),
    
    Romain CREY's avatar
    Romain CREY committed
      request: deprecate(requestFactory, 'Use requestFactory instead of request. It will be removed in cozy-konnector-libs@4'),
      requestFactory,
    
      retry: __webpack_require__(1225),
      wrapIfSentrySetUp: __webpack_require__(1267).wrapIfSentrySetUp,
      Document: __webpack_require__(1302),
      signin: __webpack_require__(1262),
      submitForm: __webpack_require__(1262),
      scrape: __webpack_require__(1304),
      mkdirp: __webpack_require__(1227),
      normalizeFilename: __webpack_require__(1305),
    
      utils: __webpack_require__(484),
    
      solveCaptcha: __webpack_require__(1306),
    
    Romain CREY's avatar
    Romain CREY committed
      createCategorizer: categorization.createCategorizer,
      categorize: categorization.categorize,
    
      manifest: __webpack_require__(833)
    
    Romain CREY's avatar
    Romain CREY committed
    };
    
    function deprecate(wrapped, message) {
      return function () {
        log('warn', message);
        return wrapped.apply(this, arguments);
      };
    }
    
    /***/ }),
    /* 2 */
    /***/ (function(module, exports, __webpack_require__) {
    
    
    const { filterLevel, filterSecrets } = __webpack_require__(3)
    const Secret = __webpack_require__(4)
    const { LOG_LEVEL } = process.env
    
    Romain CREY's avatar
    Romain CREY committed
    let level = LOG_LEVEL || 'debug'
    
    const format = __webpack_require__(5)
    
    Romain CREY's avatar
    Romain CREY committed
    const filters = [filterLevel, filterSecrets]
    
    const filterOut = function() {
      for (const filter of filters) {
        if (filter.apply(null, arguments) === false) {
          return true
        }
      }
      return false
    }
    
    /**
     * Use it to log messages in your konnector. Typical types are
     *
     * - `debug`
     * - `warning`
     * - `info`
     * - `error`
     * - `ok`
     *
     *
     * @example
     *
     * They will be colored in development mode. In production mode, those logs are formatted in JSON to be interpreted by the stack and possibly sent to the client. `error` will stop the konnector.
     *
     * ```js
     * logger = log('my-namespace')
     * logger('debug', '365 bills')
     * // my-namespace : debug : 365 bills
     * logger('info', 'Page fetched')
     * // my-namespace : info : Page fetched
     * ```
     * @param  {string} type
     * @param  {string} message
     * @param  {string} label
     * @param  {string} namespace
     */
    function log(type, message, label, namespace) {
      if (filterOut(level, type, message, label, namespace)) {
        return
      }
      // eslint-disable-next-line no-console
      console.log(format(type, message, label, namespace))
    }
    
    log.addFilter = function(filter) {
      return filters.push(filter)
    }
    
    log.setLevel = function(lvl) {
      level = lvl
    }
    
    // Short-hands
    const methods = ['debug', 'info', 'warn', 'error', 'ok', 'critical']
    methods.forEach(level => {
      log[level] = function(message, label, namespace) {
        return log(level, message, label, namespace)
      }
    })
    
    module.exports = log
    
    log.setNoRetry = obj => {
      if (obj) obj.no_retry = true
      else obj = { no_retry: true }
      return obj.no_retry
    }
    log.Secret = Secret
    log.namespace = function(namespace) {
      return function(type, message, label, ns = namespace) {
        log(type, message, label, ns)
      }
    }
    
    
    /***/ }),
    /* 3 */
    /***/ (function(module, exports, __webpack_require__) {
    
    
    const levels = {
      secret: 0,
      debug: 10,
      info: 20,
      warn: 30,
      error: 40,
      ok: 50,
      critical: 50
    
    const Secret = __webpack_require__(4)
    
    const filterSecrets = function(level, type, message) {
      if (type !== 'secret' && message instanceof Secret) {
        throw new Error('You should log a secret with log.secret')
      }
    }
    
    const filterLevel = function(level, type) {
      return levels[type] >= levels[level]
    }
    
    module.exports = {
      filterSecrets,
      filterLevel
    }
    
    
    /***/ }),
    /* 4 */
    /***/ (function(module, exports) {
    
    const Secret = function(data) {
      Object.assign(this, data)
      return this
    
    Romain CREY's avatar
    Romain CREY committed
    }
    
    
    Secret.prototype.toString = function() {
      throw new Error('Cannot convert Secret to string')
    }
    
    module.exports = Secret
    
    
    /***/ }),
    /* 5 */
    /***/ (function(module, exports, __webpack_require__) {
    
    const prodFormat = __webpack_require__(6)
    const devFormat = __webpack_require__(8)
    
    switch ("none") {
      case 'production':
        module.exports = prodFormat
        break
      case 'development':
        module.exports = devFormat
        break
      case 'standalone':
        module.exports = devFormat
        break
      case 'test':
        module.exports = devFormat
        break
      default:
        module.exports = prodFormat
    }
    
    
    /***/ }),
    /* 6 */
    /***/ (function(module, exports, __webpack_require__) {
    
    const stringify = __webpack_require__(7)
    
    const LOG_LENGTH_LIMIT = 64 * 1024 - 1
    
    
    Romain CREY's avatar
    Romain CREY committed
    function prodFormat(type, message, label, namespace) {
      const log = { time: new Date(), type, label, namespace }
    
      if (typeof message === 'object') {
        if (message && message.no_retry) {
          log.no_retry = message.no_retry
        }
        if (message && message.message) {
          log.message = message.message
        }
      } else {
        log.message = message
      }
    
      // properly display error messages
      if (log.message && log.message.stack) {
        log.message = log.message.stack
      }
    
      // cut the string to avoid a fail in the stack
      let result = log
      try {
        result = stringify(log).substr(0, LOG_LENGTH_LIMIT)
      } catch (err) {
        // eslint-disable-next-line no-console
        console.log(err.message, 'cozy-logger: Failed to convert message to JSON')
      }
      return result
    }
    
    
    module.exports = prodFormat
    
    
    /***/ }),
    /* 7 */
    /***/ (function(module, exports) {
    
    exports = module.exports = stringify
    exports.getSerialize = serializer
    
    function stringify(obj, replacer, spaces, cycleReplacer) {
      return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces)
    }
    
    function serializer(replacer, cycleReplacer) {
      var stack = [], keys = []
    
      if (cycleReplacer == null) cycleReplacer = function(key, value) {
        if (stack[0] === value) return "[Circular ~]"
        return "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]"
      }
    
      return function(key, value) {
        if (stack.length > 0) {
          var thisPos = stack.indexOf(this)
          ~thisPos ? stack.splice(thisPos + 1) : stack.push(this)
          ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key)
          if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value)
        }
        else stack.push(value)
    
        return replacer == null ? value : replacer.call(this, key, value)
      }
    }
    
    
    /***/ }),
    /* 8 */
    /***/ (function(module, exports, __webpack_require__) {
    
    const util = __webpack_require__(9)
    const chalk = __webpack_require__(10)
    
    if (util && util.inspect && util.inspect.defaultOptions) {
      util.inspect.defaultOptions.maxArrayLength = null
      util.inspect.defaultOptions.depth = 2
      util.inspect.defaultOptions.colors = true
    }
    
    const type2color = {
      debug: 'cyan',
      warn: 'yellow',
      info: 'blue',
      error: 'red',
      ok: 'green',
      secret: 'red',
      critical: 'red'
    }
    
    
    Romain CREY's avatar
    Romain CREY committed
    function devFormat(type, message, label, namespace) {
      let formatmessage = message
    
      if (typeof formatmessage !== 'string') {
        formatmessage = util.inspect(formatmessage)
      }
    
      let formatlabel = label ? ` : "${label}" ` : ''
      let formatnamespace = namespace ? chalk.magenta(`${namespace}: `) : ''
    
      let color = type2color[type]
      let formattype = color ? chalk[color](type) : type
    
      return `${formatnamespace}${formattype}${formatlabel} : ${formatmessage}`
    }
    
    
    module.exports = devFormat
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    
    /***/ }),
    /* 9 */
    /***/ (function(module, exports) {
    
    module.exports = require("util");
    
    Romain CREY's avatar
    Romain CREY committed
    
    /***/ }),
    
    /* 10 */
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    "use strict";
    
    
    const escapeStringRegexp = __webpack_require__(11);
    const ansiStyles = __webpack_require__(12);
    const stdoutColor = __webpack_require__(18).stdout;
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const template = __webpack_require__(21);
    
    Romain CREY's avatar
    Romain CREY committed
    
    const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm');
    
    // `supportsColor.level` → `ansiStyles.color[name]` mapping
    const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m'];
    
    // `color-convert` models to exclude from the Chalk API due to conflicts and such
    const skipModels = new Set(['gray']);
    
    const styles = Object.create(null);
    
    function applyOptions(obj, options) {
    	options = options || {};
    
    	// Detect level if not set manually
    	const scLevel = stdoutColor ? stdoutColor.level : 0;
    	obj.level = options.level === undefined ? scLevel : options.level;
    	obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0;
    }
    
    function Chalk(options) {
    	// We check for this.template here since calling `chalk.constructor()`
    	// by itself will have a `this` of a previously constructed chalk object
    	if (!this || !(this instanceof Chalk) || this.template) {
    		const chalk = {};
    		applyOptions(chalk, options);
    
    		chalk.template = function () {
    			const args = [].slice.call(arguments);
    			return chalkTag.apply(null, [chalk.template].concat(args));
    		};
    
    		Object.setPrototypeOf(chalk, Chalk.prototype);
    		Object.setPrototypeOf(chalk.template, chalk);
    
    		chalk.template.constructor = Chalk;
    
    		return chalk.template;
    	}
    
    	applyOptions(this, options);
    }
    
    // Use bright blue on Windows as the normal blue color is illegible
    if (isSimpleWindowsTerm) {
    	ansiStyles.blue.open = '\u001B[94m';
    }
    
    for (const key of Object.keys(ansiStyles)) {
    	ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
    
    	styles[key] = {
    		get() {
    			const codes = ansiStyles[key];
    			return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key);
    		}
    	};
    }
    
    styles.visible = {
    	get() {
    		return build.call(this, this._styles || [], true, 'visible');
    	}
    };
    
    ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g');
    for (const model of Object.keys(ansiStyles.color.ansi)) {
    	if (skipModels.has(model)) {
    		continue;
    	}
    
    	styles[model] = {
    		get() {
    			const level = this.level;
    			return function () {
    				const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments);
    				const codes = {
    					open,
    					close: ansiStyles.color.close,
    					closeRe: ansiStyles.color.closeRe
    				};
    				return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
    			};
    		}
    	};
    }
    
    ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g');
    for (const model of Object.keys(ansiStyles.bgColor.ansi)) {
    	if (skipModels.has(model)) {
    		continue;
    	}
    
    	const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
    	styles[bgModel] = {
    		get() {
    			const level = this.level;
    			return function () {
    				const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments);
    				const codes = {
    					open,
    					close: ansiStyles.bgColor.close,
    					closeRe: ansiStyles.bgColor.closeRe
    				};
    				return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
    			};
    		}
    	};
    }
    
    const proto = Object.defineProperties(() => {}, styles);
    
    function build(_styles, _empty, key) {
    	const builder = function () {
    		return applyStyle.apply(builder, arguments);
    	};
    
    	builder._styles = _styles;
    	builder._empty = _empty;
    
    	const self = this;
    
    	Object.defineProperty(builder, 'level', {
    		enumerable: true,
    		get() {
    			return self.level;
    		},
    		set(level) {
    			self.level = level;
    		}
    	});
    
    	Object.defineProperty(builder, 'enabled', {
    		enumerable: true,
    		get() {
    			return self.enabled;
    		},
    		set(enabled) {
    			self.enabled = enabled;
    		}
    	});
    
    	// See below for fix regarding invisible grey/dim combination on Windows
    	builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey';
    
    	// `__proto__` is used because we must return a function, but there is
    	// no way to create a function with a different prototype
    	builder.__proto__ = proto; // eslint-disable-line no-proto
    
    	return builder;
    }
    
    function applyStyle() {
    	// Support varags, but simply cast to string in case there's only one arg
    	const args = arguments;
    	const argsLen = args.length;
    	let str = String(arguments[0]);
    
    	if (argsLen === 0) {
    		return '';
    	}
    
    	if (argsLen > 1) {
    		// Don't slice `arguments`, it prevents V8 optimizations
    		for (let a = 1; a < argsLen; a++) {
    			str += ' ' + args[a];
    		}
    	}
    
    	if (!this.enabled || this.level <= 0 || !str) {
    		return this._empty ? '' : str;
    	}
    
    	// Turns out that on Windows dimmed gray text becomes invisible in cmd.exe,
    	// see https://github.com/chalk/chalk/issues/58
    	// If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop.
    	const originalDim = ansiStyles.dim.open;
    	if (isSimpleWindowsTerm && this.hasGrey) {
    		ansiStyles.dim.open = '';
    	}
    
    	for (const code of this._styles.slice().reverse()) {
    		// 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'.
    		str = code.open + str.replace(code.closeRe, code.open) + code.close;
    
    		// 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
    		str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`);
    	}
    
    	// Reset the original `dim` if we changed it to work around the Windows dimmed gray issue
    	ansiStyles.dim.open = originalDim;
    
    	return str;
    }
    
    function chalkTag(chalk, strings) {
    	if (!Array.isArray(strings)) {