/**
 * ejs
 *
 * @category   ejs
 * @author     Vaibhav Mehta <vaibhav@decodingweb.com>
 * @copyright  Copyright (c) 2016 Vaibhav Mehta <https://github.com/i-break-codes>
 * @license    http://www.opensource.org/licenses/mit-license.html  MIT License
 * @version    1.0.0 Beta
 */
 
'use strict';

var Error = function() {
  
  function init(userConfig = {}) {
    // Default configuration
    var config = {
      detailedErrors: true,
      remoteLogging: false,
      remoteSettings: {
        url: null,
        additionalParams: null,
        successCallback: null,
        errorCallback: null
      }
    }
    
    // Override with user config
    var setConfig = Object.assign(config, userConfig);
    
    // Listen to errors
    window.addEventListener('error', function(e) {
      if(setConfig.detailedErrors) {
        _detailedErrors(e);
      }
      
      if(setConfig.remoteLogging) {
        _remoteLogging(e, setConfig.remoteSettings);
      }
    });
  }
  
  // NOTE: Private
  function _detailedErrors(e) {
    _formatError(e);
  }

  function _formatError(e) {
    var i = _errorData(e);
    var helpPath = encodeURI("https://stackoverflow.com/search?q=" + i.error.split(' ').join('+'));

    var str = [
      "%cType: %c" + i.type,
      "%cError: %c" + i.error,
      "%cFile Name: %c" + i.filename,
      "%cPath: %c" + i.path,
      "%cLine: %c" + i.line,
      "%cColumn: %c" + i.column,
      "%cDate: %c" + i.datetime,
      "%cDebug : %c" + i.path + ':' + i.line,
      "%cGet Help: " + "%c" + helpPath
    ].join("\n");

    console.log(str, "font-weight: bold;", "color: #e74c3c;", "font-weight: bold;", "font-weight: normal; color: #e74c3c;", "font-weight: bold;", "font-weight: normal;", "font-weight: bold;", "font-weight: normal;", "font-weight: bold;", "font-weight: normal;", "font-weight: bold;", "font-weight: normal;", "font-weight: bold;", "font-weight: normal;", "font-weight: bold;", "font-weight: normal;", "font-weight: bold;", "font-weight: normal; color: #3498db;");
  }
  
  function _remoteLogging(e, remoteSettings) {
    if(!remoteSettings.url) {
      throw 'Provide remote URL to log errors remotely';
      return false;
    } else if(remoteSettings.additionalParams && typeof remoteSettings.additionalParams !== 'object') {
      throw 'Invalid data type, additionalParams should be a valid object';
      return false;
    }
    
    var http = new XMLHttpRequest();
    var url = remoteSettings.url;
    var data = _errorData(e);
    var setData = Object.assign(data, remoteSettings.additionalParams);
    var params = _serializeData(setData);
    
    http.open("POST", url, true);
    http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    http.send(params);

    http.onreadystatechange = function() {
      if(http.readyState == 4 && http.status == 200) {
        if (http.readyState == XMLHttpRequest.DONE) {
          if(remoteSettings.successCallback) {
            remoteSettings.successCallback();
          }
        } else {
          if(remoteSettings.errorCallback) {
            remoteSettings.errorCallback();
          } else {
            throw 'Remote error logging failed!';
          }
        }
      }
    }
  }
  
  function _serializeData(params) {
    return Object.keys(params).map(function(k) {
      return encodeURIComponent(k) + "=" + encodeURIComponent(params[k]);
    }).join('&');
  }
  
  function _errorData(e) {
    var filename = e.filename.lastIndexOf('/');
    var datetime = new Date().toString();

    return {
      type: e.type,
      path: e.filename,
      filename: e.filename.substring(++filename),
      line: e.lineno,
      column: e.colno,
      error: e.message,
      datetime: datetime
    }
  }

  return {
    init: init
  }
}();
@@ -1281,16 +1281,57 @@
 .error,%0A
+      %22%25cStackTrace: %25c%22 + i.stackTrace,%0A
       %22%25
@@ -1696,24 +1696,85 @@
 rmal; color:
+ #e74c3c;%22,%22font-weight: bold;%22, %22font-weight: normal; color:
  #e74c3c;%22, 
@@ -3795,16 +3795,89 @@
 essage,%0A
+      stackTrace: e.error.stack.toString().replace(/(%5Cr%5Cn%7C%5Cn%7C%5Cr)/gm,%22%22),%0A
       da

add stacktrace