whole_func_string: function jajax(o,done,fail,_u) {
              let xhr = jajax.createXHR(FALSE);
              if ( !xhr ) {
                  fail && fail(NULL, 'xhr', `Couldn't create XHR object`);
                  return xhr;
              }
  
              if ( type(o) == 'String' ) {
                  if ( done && type(done) == 'Object' ) {
                      done.url = o;
                      o    = done;
                      done = fail;
                      fail = _u;
                  }
                  else {
                      o = { url: o };
                  }
              }
  
              o = extend({
                  url        : '',    // String
                  type       : 'GET', // String - alias of .method
                  cache      : FALSE, // Bool
                  timeout    : NULL,  // Number
                  contentType: 'application/x-www-form-urlencoded; charset=UTF-8', // String
                  dataType   : '',    // String
                  mimeType   : '',    // String
                  data       : NULL,  // Object
                  headers    : NULL,  // Object
                  error      : NULL,  // Function
                  success    : NULL   // Function
              }, o);
  
              var headers = {}
              ,   setHeader = (name, value) => { headers[name.toLowerCase()] = [name, value]; }
              ,   method = o.method || o.type
              ,   url = o.url
              ,   abort_to
              ,   responseType
              ,   resolve, reject, then, _catch
              ,   onerror = function (error, type, xh, res) {
                      if(o.error) {
                          o.error(xh || res, type, error, res);
                      }
                      if(fail) {
                          fail(xh || res, type, error, res);
                      }
                      if ( reject ) {
                          if ( !error ) {
                              if ( type ) {
                                  error = new Error(`jajax error: ${type}`);
                                  error.type = type;
                              }
                              else {
                                  error = new Error(`jajax error: unknown`);
                              }
                              error.xhr = xh || res;
                              error.response = res;
                          }
                          reject(error);
                      }
                  }
              ,   onsuccecc = function (xh, result, res) {
                      var dataType = o.dataType || o.mimeType && jajax.mimeToDataType(o.mimeType) || responseType
                      ,   error
                      ;
                      try {
                          switch(dataType) {
                              case 'json': {
                                  result = 'responseJSON' in xh ? xh.responseJSON : (/^\s*$/.test(result) ? NULL : jajax.parseJSON(result));
                              } break;
  
                              case 'xml': {
                                  result = xh.responseXML;
                              } break;
  
                              case 'script': {
                                  // http://perfectionkills.com/global-eval-what-are-the-options/
                                  (1,eval)(result); //jshint ignore:line
                              } break;
  
                              case 'text': /*falls through*/
                              default: {
                                  // result = xh.responseText
                              } break;
                          }
                      } catch (e) { error = e; }
  
                      if (error) {
                          onerror(error, 'parsererror', xh, res);
                      }
                      else {
                          if (o.success) {
                              o.success(result, xh.statusText, xh, res);
                          }
                          if(done) {
                              done(result, xh.statusText, xh, res);
                          }
                          if ( resolve ) {
                              resolve(result);
                          }
                      }
                  }
              ,   oncomplete = function (xh, res) {
                      abort_to && clearTimeout(abort_to);
  
                      let response = xh.responseText || xh.response;
  
                      // responseType from response headers
                      responseType = jajax.mimeToDataType(xh.getResponseHeader('content-type'));
  
                      // If responseType is 'json', make sure there is xh.responseJSON
                      if ( responseType == 'json' && !('responseJSON' in xh) ) {
                          if ( /^\s*$/.test(response) ) {
                              xh.responseJSON = NULL;
                          }
                          else {
                              try {
                                  xh.responseJSON = jajax.parseJSON(response);
                              }
                              catch(err) {}
                          }
                      }
  
  
                      if( (xh.status >= 200 && xh.status < 300) || xh.status == 304 ) {
                          onsuccecc(xh, response, res);
                      }
                      else {
                          onerror(xh.statusText || NULL, xh.status ? 'error' : 'abort', xh, res);
                      }
                  }
              ;
  
              if ( typeof Promise == 'function' ) {
                  let prom = new Promise((_resolve, _reject) => {
                      resolve = _resolve;
                      reject = _reject;
                  });
                  then = prom.then.bind(prom);
                  _catch = prom.catch.bind(prom);
              }
  
              each({'X-Requested-With': 'XMLHttpRequest'}, setHeader);
  
              if(o.contentType) {
                  setHeader('Content-Type', o.contentType);
              }
              setHeader('Accept', (accepts[o.dataType] ? accepts[o.dataType] + ', ': '') + allTypes + '; q=0.01');
  
              each(o.headers, setHeader);
  
              method = method.toLowerCase();
  
              if ( o.data && (method == 'get' || method == 'head') ) {
                  url += (url.indexOf('?') < 0 ? '?' : '&') + jajax.param(o.data);
                  o.data = NULL;
              }
  
              if(jajax.xhr_type == 'REQUEST') {
                  each(o.data, function (n,v,d) { if(v == NULL) delete d[n]; });
                  var h = {
                          url,
                          content: o.data || {},
                          headers: {},
                          onComplete(res) {
                              if(h.aborted) return;
                              var _xhr = {
                                  getResponseHeader(name) {
                                      return res.headers[name];
                                  },
                                  status: res.status,
                                  statusText: res.statusText,
                                  responseText: res.text,
                                  responseJSON: res.json
                              };
                              oncomplete(_xhr, res);
                          }
                      }
                  ;
                  each(headers, (i,a) => { if(a[0] && a[0] != NULL) h.headers[a[0]] = a[1]; });
                  if(o.contentType) h.contentType = o.contentType;
  
                  if (o.timeout > 0) abort_to = setTimeout(() => {
                      h.aborted = now();
                      // xhr.abort(); // @todo: abort request
                      onerror(NULL, 'timeout', xhr);
                  }, o.timeout);
  
                  let _xhr;
                  try {
                      _xhr = xhr.Request(h);
                      _xhr[method]();
                  }
                  catch(er) {
                      // If method not supported. try to override it
                      try {
                          h.headers['X-HTTP-Method-Override'] = method.toUpperCase();
                          _xhr = xhr.Request(h);
                          _xhr.post();
                      }
                      catch(er) {
                          // If override doesn't work, try XHR - synchronous in FF
                          switch (method) {
                              case 'delete': {
                                  // Firefox REQUEST object doesn't support DELETE,
                                  // need to create manual xhr object
                                  const XHR = require("sdk/net/xhr");
                                  _xhr = new XHR.XMLHttpRequest();
                                  _xhr.open(method, url);
                                  each(h.headers, (n,v) => { _xhr.setRequestHeader(n, v); });
                                  _xhr.send();
                                  oncomplete(_xhr);
                              } break;
                              default: throw er;
                          }
                      }
                  }
                  if ( _xhr ) {
                      xhr = _xhr;
                  }
              }
              else {
                  xhr.open(method, url, TRUE);
  
                  each(headers, (i,a) => { if(a[1] != NULL) xhr.setRequestHeader( a[0], a[1] + NIL ); });
  
                  if (o.timeout > 0) abort_to = setTimeout(() => {
                      xhr.onreadystatechange = noop;
                      xhr.abort();
                      onerror(NULL, 'timeout', xhr);
                  }, o.timeout);
  
                  const callback = () => {
                      if (xhr.readyState == 4) {
                          xhr.onreadystatechange = noop;
                          oncomplete(xhr);
                      }
                  };
  
                  xhr.send(o.data ? typeof o.data == 'string' ? o.data : jajax.param(o.data) : NULL);
  
                  if(xhr.readyState === 4) {
                      // (IE6 & IE7) if it's in cache and has been
                      // retrieved directly we need to fire the callback
                      setTimeout( callback );
                  }
                  else {
                      xhr.onreadystatechange = callback;
                  }
              }
  
              if ( then && !xhr.then ) {
                  xhr.then = then;
                  if ( _catch ) xhr.catch = _catch;
              }
  
              return xhr;
          }
func_code_string: function jajax(o,done,fail,_u) {
              let xhr = jajax.createXHR(FALSE);
              if ( !xhr ) {
                  fail && fail(NULL, 'xhr', `Couldn't create XHR object`);
                  return xhr;
              }
  
              if ( type(o) == 'String' ) {
                  if ( done && type(done) == 'Object' ) {
                      done.url = o;
                      o    = done;
                      done = fail;
                      fail = _u;
                  }
                  else {
                      o = { url: o };
                  }
              }
  
              o = extend({
                  url        : '',    // String
                  type       : 'GET', // String - alias of .method
                  cache      : FALSE, // Bool
                  timeout    : NULL,  // Number
                  contentType: 'application/x-www-form-urlencoded; charset=UTF-8', // String
                  dataType   : '',    // String
                  mimeType   : '',    // String
                  data       : NULL,  // Object
                  headers    : NULL,  // Object
                  error      : NULL,  // Function
                  success    : NULL   // Function
              }, o);
  
              var headers = {}
              ,   setHeader = (name, value) => { headers[name.toLowerCase()] = [name, value]; }
              ,   method = o.method || o.type
              ,   url = o.url
              ,   abort_to
              ,   responseType
              ,   resolve, reject, then, _catch
              ,   onerror = function (error, type, xh, res) {
                      if(o.error) {
                          o.error(xh || res, type, error, res);
                      }
                      if(fail) {
                          fail(xh || res, type, error, res);
                      }
                      if ( reject ) {
                          if ( !error ) {
                              if ( type ) {
                                  error = new Error(`jajax error: ${type}`);
                                  error.type = type;
                              }
                              else {
                                  error = new Error(`jajax error: unknown`);
                              }
                              error.xhr = xh || res;
                              error.response = res;
                          }
                          reject(error);
                      }
                  }
              ,   onsuccecc = function (xh, result, res) {
                      var dataType = o.dataType || o.mimeType && jajax.mimeToDataType(o.mimeType) || responseType
                      ,   error
                      ;
                      try {
                          switch(dataType) {
                              case 'json': {
                                  result = 'responseJSON' in xh ? xh.responseJSON : (/^\s*$/.test(result) ? NULL : jajax.parseJSON(result));
                              } break;
  
                              case 'xml': {
                                  result = xh.responseXML;
                              } break;
  
                              case 'script': {
                                  // http://perfectionkills.com/global-eval-what-are-the-options/
                                  (1,eval)(result); //jshint ignore:line
                              } break;
  
                              case 'text': /*falls through*/
                              default: {
                                  // result = xh.responseText
                              } break;
                          }
                      } catch (e) { error = e; }
  
                      if (error) {
                          onerror(error, 'parsererror', xh, res);
                      }
                      else {
                          if (o.success) {
                              o.success(result, xh.statusText, xh, res);
                          }
                          if(done) {
                              done(result, xh.statusText, xh, res);
                          }
                          if ( resolve ) {
                              resolve(result);
                          }
                      }
                  }
              ,   oncomplete = function (xh, res) {
                      abort_to && clearTimeout(abort_to);
  
                      let response = xh.responseText || xh.response;
  
                      // responseType from response headers
                      responseType = jajax.mimeToDataType(xh.getResponseHeader('content-type'));
  
                      // If responseType is 'json', make sure there is xh.responseJSON
                      if ( responseType == 'json' && !('responseJSON' in xh) ) {
                          if ( /^\s*$/.test(response) ) {
                              xh.responseJSON = NULL;
                          }
                          else {
                              try {
                                  xh.responseJSON = jajax.parseJSON(response);
                              }
                              catch(err) {}
                          }
                      }
  
  
                      if( (xh.status >= 200 && xh.status < 300) || xh.status == 304 ) {
                          onsuccecc(xh, response, res);
                      }
                      else {
                          onerror(xh.statusText || NULL, xh.status ? 'error' : 'abort', xh, res);
                      }
                  }
              ;
  
              if ( typeof Promise == 'function' ) {
                  let prom = new Promise((_resolve, _reject) => {
                      resolve = _resolve;
                      reject = _reject;
                  });
                  then = prom.then.bind(prom);
                  _catch = prom.catch.bind(prom);
              }
  
              each({'X-Requested-With': 'XMLHttpRequest'}, setHeader);
  
              if(o.contentType) {
                  setHeader('Content-Type', o.contentType);
              }
              setHeader('Accept', (accepts[o.dataType] ? accepts[o.dataType] + ', ': '') + allTypes + '; q=0.01');
  
              each(o.headers, setHeader);
  
              method = method.toLowerCase();
  
              if ( o.data && (method == 'get' || method == 'head') ) {
                  url += (url.indexOf('?') < 0 ? '?' : '&') + jajax.param(o.data);
                  o.data = NULL;
              }
  
              if(jajax.xhr_type == 'REQUEST') {
                  each(o.data, function (n,v,d) { if(v == NULL) delete d[n]; });
                  var h = {
                          url,
                          content: o.data || {},
                          headers: {},
                          onComplete(res) {
                              if(h.aborted) return;
                              var _xhr = {
                                  getResponseHeader(name) {
                                      return res.headers[name];
                                  },
                                  status: res.status,
                                  statusText: res.statusText,
                                  responseText: res.text,
                                  responseJSON: res.json
                              };
                              oncomplete(_xhr, res);
                          }
                      }
                  ;
                  each(headers, (i,a) => { if(a[0] && a[0] != NULL) h.headers[a[0]] = a[1]; });
                  if(o.contentType) h.contentType = o.contentType;
  
                  if (o.timeout > 0) abort_to = setTimeout(() => {
                      h.aborted = now();
                      // xhr.abort(); // @todo: abort request
                      onerror(NULL, 'timeout', xhr);
                  }, o.timeout);
  
                  let _xhr;
                  try {
                      _xhr = xhr.Request(h);
                      _xhr[method]();
                  }
                  catch(er) {
                      // If method not supported. try to override it
                      try {
                          h.headers['X-HTTP-Method-Override'] = method.toUpperCase();
                          _xhr = xhr.Request(h);
                          _xhr.post();
                      }
                      catch(er) {
                          // If override doesn't work, try XHR - synchronous in FF
                          switch (method) {
                              case 'delete': {
                                  // Firefox REQUEST object doesn't support DELETE,
                                  // need to create manual xhr object
                                  const XHR = require("sdk/net/xhr");
                                  _xhr = new XHR.XMLHttpRequest();
                                  _xhr.open(method, url);
                                  each(h.headers, (n,v) => { _xhr.setRequestHeader(n, v); });
                                  _xhr.send();
                                  oncomplete(_xhr);
                              } break;
                              default: throw er;
                          }
                      }
                  }
                  if ( _xhr ) {
                      xhr = _xhr;
                  }
              }
              else {
                  xhr.open(method, url, TRUE);
  
                  each(headers, (i,a) => { if(a[1] != NULL) xhr.setRequestHeader( a[0], a[1] + NIL ); });
  
                  if (o.timeout > 0) abort_to = setTimeout(() => {
                      xhr.onreadystatechange = noop;
                      xhr.abort();
                      onerror(NULL, 'timeout', xhr);
                  }, o.timeout);
  
                  const callback = () => {
                      if (xhr.readyState == 4) {
                          xhr.onreadystatechange = noop;
                          oncomplete(xhr);
                      }
                  };
  
                  xhr.send(o.data ? typeof o.data == 'string' ? o.data : jajax.param(o.data) : NULL);
  
                  if(xhr.readyState === 4) {
                      // (IE6 & IE7) if it's in cache and has been
                      // retrieved directly we need to fire the callback
                      setTimeout( callback );
                  }
                  else {
                      xhr.onreadystatechange = callback;
                  }
              }
  
              if ( then && !xhr.then ) {
                  xhr.then = then;
                  if ( _catch ) xhr.catch = _catch;
              }
  
              return xhr;
          }
func_documentation_string: ------------------------------------------------------------- AJAX method itself