lookupParamDoc = function lookupParamDoc(func) {
              // look for the docs in the `data.json` datastructure

              var ichDot = func.lastIndexOf('.');
              var funcName = func.substr(ichDot + 1);
              var funcClass = func.substr(0, ichDot) || 'p5';

              var queryResult;
              var classitems = arrDoc.classitems;
              var _iteratorNormalCompletion = true;
              var _didIteratorError = false;
              var _iteratorError = undefined;
              try {
                for (
                  var _iterator = classitems[Symbol.iterator](), _step;
                  !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
                  _iteratorNormalCompletion = true
                ) {
                  var x = _step.value;
                  if (x.name === funcName && x.class === funcClass) {
                    queryResult = x;
                    break;
                  }
                }

                // different JSON structure for funct with multi-format
              } catch (err) {
                _didIteratorError = true;
                _iteratorError = err;
              } finally {
                try {
                  if (!_iteratorNormalCompletion && _iterator.return != null) {
                    _iterator.return();
                  }
                } finally {
                  if (_didIteratorError) {
                    throw _iteratorError;
                  }
                }
              }
              var overloads = [];
              if (queryResult.hasOwnProperty('overloads')) {
                // add all the overloads
                for (var i = 0; i < queryResult.overloads.length; i++) {
                  overloads.push({ formats: queryResult.overloads[i].params });
                }
              } else {
                // no overloads, just add the main method definition
                overloads.push({ formats: queryResult.params || [] });
              }

              // parse the parameter types for each overload
              var mapConstants = {};
              var maxParams = 0;
              overloads.forEach(function(overload) {
                var formats = overload.formats;

                // keep a record of the maximum number of arguments
                // this method requires.
                if (maxParams < formats.length) {
                  maxParams = formats.length;
                }

                // calculate the minimum number of arguments
                // this overload requires.
                var minParams = formats.length;
                while (minParams > 0 && formats[minParams - 1].optional) {
                  minParams--;
                }
                overload.minParams = minParams;

                // loop through each parameter position, and parse its types
                formats.forEach(function(format) {
                  // split this parameter's types
                  format.types = format.type.split('|').map(function ct(type) {
                    // array
                    if (type.substr(type.length - 2, 2) === '[]') {
                      return {
                        name: type,
                        array: ct(type.substr(0, type.length - 2))
                      };
                    }

                    var lowerType = type.toLowerCase();

                    // contant
                    if (lowerType === 'constant') {
                      var constant;
                      if (mapConstants.hasOwnProperty(format.name)) {
                        constant = mapConstants[format.name];
                      } else {
                        // parse possible constant values from description
                        var myRe = /either\s+(?:[A-Z0-9_]+\s*,?\s*(?:or)?\s*)+/g;
                        var values = {};
                        var _names = [];

                        constant = mapConstants[format.name] = {
                          values: values,
                          names: _names
                        };

                        var myArray = myRe.exec(format.description);
                        if (func === 'endShape' && format.name === 'mode') {
                          values[constants.CLOSE] = true;
                          _names.push('CLOSE');
                        } else {
                          var match = myArray[0];
                          var reConst = /[A-Z0-9_]+/g;
                          var matchConst;
                          while ((matchConst = reConst.exec(match)) !== null) {
                            var name = matchConst[0];
                            if (constants.hasOwnProperty(name)) {
                              values[constants[name]] = true;
                              _names.push(name);
                            }
                          }
                        }
                      }
                      return {
                        name: type,
                        builtin: lowerType,
                        names: constant.names,
                        values: constant.values
                      };
                    }

                    // function
                    if (lowerType.substr(0, 'function'.length) === 'function') {
                      lowerType = 'function';
                    }
                    // builtin
                    if (builtinTypes.includes(lowerType)) {
                      return { name: type, builtin: lowerType };
                    }

                    // find type's prototype
                    var t = window;
                    var typeParts = type.split('.');

                    // special-case 'p5' since it may be non-global
                    if (typeParts[0] === 'p5') {
                      t = _main.default;
                      typeParts.shift();
                    }

                    typeParts.forEach(function(p) {
                      t = t && t[p];
                    });
                    if (t) {
                      return { name: type, prototype: t };
                    }

                    return { name: type, type: lowerType };
                  });
                });
              });
              return {
                overloads: overloads,
                maxParams: maxParams
              };
            }
This is a generic method that can be called from anywhere in the p5
library to alert users to a common error.

@method _friendlyError
@private
@param  {Number} message message to be printed
@param  {String} method name of method