function parseMeta(code, { errors, retDefault, retMetaStr } = {}) {
  // initialize meta
  const meta = metaTypes::mapEntry(value => value.default());
  const match = matchUserScript(code);
  if (!match) return retDefault ? meta : false;
  // TODO: use `null` instead of `false` + null check in all callers?
  if (errors) checkMetaItemErrors(match, 1, errors);
  let parts;
  while ((parts = META_ITEM_RE.exec(match[4]))) {
    const [keyName, locale] = parts[3].slice(1).split(':');
    const camelKey = keyName.replace(/[-_](\w)/g, (m, g) => g.toUpperCase());
    const key = locale ? `${camelKey}:${locale.toLowerCase()}` : camelKey;
    const val = parts[4].trim();
    const metaType = metaTypes[key] || metaOptionalTypes[key] || defaultType;
    let oldValue = meta[key];
    if (typeof oldValue === 'undefined') oldValue = metaType.default();
    if (errors) checkMetaItemErrors(parts, 0, errors);
    meta[key] = metaType.transform(oldValue, val);
  }
  if (errors) checkMetaItemErrors(match, 5, errors);
  meta.resources = meta.resource;
  delete meta.resource;
  if (retMetaStr) meta[__CODE] = match[0];
  return meta;
}
@param {string} code
@param {object} [opts]
@param {Array} [opts.errors] - to collect errors
@param {boolean} [opts.retDefault] - returns the default empty meta if no meta is found
@param {boolean} [opts.retMetaStr] - adds the matched part as [__CODE] prop in result
@return {VMScript.Meta | false}