{"version":3,"file":"rxn-parser.umd.min.js","sources":["../node_modules/ensure-string/lib/index.js","../src/index.js"],"sourcesContent":["/**\n * Ensure that the data is string. If it is an ArrayBuffer it will be converted to string using TextDecoder.\n * @param blob\n * @param options\n * @returns\n */\nexport function ensureString(blob, options = {}) {\n    if (typeof blob === 'string') {\n        return blob;\n    }\n    if (ArrayBuffer.isView(blob) || blob instanceof ArrayBuffer) {\n        if (options.encoding) {\n            return new TextDecoder(options.encoding).decode(blob);\n        }\n        else {\n            return decodeText(blob);\n        }\n    }\n    throw new TypeError(`blob must be a string, ArrayBuffer or ArrayBufferView`);\n}\nfunction decodeText(blob) {\n    const uint8 = ArrayBuffer.isView(blob)\n        ? new Uint8Array(blob.buffer, blob.byteOffset, blob.byteLength)\n        : new Uint8Array(blob);\n    if (uint8.length >= 2) {\n        if (uint8[0] === 0xfe && uint8[1] === 0xff) {\n            return new TextDecoder('utf-16be').decode(uint8);\n        }\n        if (uint8[0] === 0xff && uint8[1] === 0xfe) {\n            return new TextDecoder('utf-16le').decode(uint8);\n        }\n    }\n    try {\n        return new TextDecoder('utf-8', { fatal: true }).decode(uint8);\n    }\n    catch {\n        return new TextDecoder('latin1').decode(uint8);\n    }\n}\n//# sourceMappingURL=index.js.map","import { ensureString } from 'ensure-string';\n\n/**\n * Parse a rxn file and return an object with reagents and products.\n * @param {import('cheminfo-types').TextData} rxn - RXN file content.\n * @returns {{ reagents: string[], products: string[] }} Parsed reagents and products.\n */\nexport function parse(rxn) {\n  rxn = ensureString(rxn);\n  // we will find the delimiter in order to be much faster and not use regular expression\n  const header = rxn.slice(0, 1000);\n  let crlf = '\\n';\n  if (header.includes('\\r\\n')) {\n    crlf = '\\r\\n';\n  } else if (header.includes('\\r')) {\n    crlf = '\\r';\n  }\n\n  const rxnParts = rxn.split(`${crlf}$MOL${crlf}`);\n\n  const reagents = [];\n  const products = [];\n\n  // the first part is expected to contain the number of reagents and products\n\n  // First part should start with $RXN\n  // and the fifth line should contain the number of reagents and products\n  if (rxnParts.length === 0) throw new Error('file looks empty');\n\n  const headerPart = rxnParts[0];\n  if (headerPart.indexOf('$RXN') !== 0) {\n    throw new Error('file does not start with $RXN');\n  }\n\n  const lines = headerPart.split(crlf);\n  if (lines.length < 5) throw new Error('incorrect number of lines in header');\n\n  let numberReagents = lines[4].slice(0, 3) >> 0;\n  const numberProducts = lines[4].slice(3, 6) >> 0;\n\n  // hack for JSME\n  const thirdNumber = lines[4].slice(6, 9) >> 0; // for jsme\n\n  if (thirdNumber && rxnParts[1]) {\n    const jsmeLines = rxnParts[1].split(crlf);\n    if (jsmeLines[0]) {\n      numberReagents = jsmeLines[0]\n        .trim()\n        .replace(/>[^>]*$/, '')\n        .split(/[.>]/).length;\n    }\n  }\n\n  if (numberReagents + numberProducts !== rxnParts.length - 1) {\n    throw new Error('not the correct number of molecules');\n  }\n\n  for (let i = 1; i < rxnParts.length; i++) {\n    if (i <= numberReagents) {\n      reagents.push(rxnParts[i]);\n    } else {\n      products.push(rxnParts[i]);\n    }\n  }\n  return { reagents, products };\n}\n"],"names":["ensureString","blob","options","ArrayBuffer","isView","encoding","TextDecoder","decode","uint8","Uint8Array","buffer","byteOffset","byteLength","length","fatal","decodeText","TypeError","rxn","header","slice","crlf","includes","rxnParts","split","reagents","products","Error","headerPart","indexOf","lines","numberReagents","numberProducts","jsmeLines","trim","replace","i","push"],"mappings":";gPAkBM,SAAUA,EACdC,EACAC,EAA+B,IAE/B,GAAoB,iBAATD,EACT,OAAOA,EAET,GAAIE,YAAYC,OAAOH,IAASA,aAAgBE,YAC9C,OAAID,EAAQG,SACH,IAAIC,YAAYJ,EAAQG,UAAUE,OAAON,GAQtD,SAAoBA,GAClB,MAAMO,EAAQL,YAAYC,OAAOH,GAC7B,IAAIQ,WAAWR,EAAKS,OAAQT,EAAKU,WAAYV,EAAKW,YAClD,IAAIH,WAAWR,GACnB,GAAIO,EAAMK,QAAU,EAAG,CACrB,GAAiB,MAAbL,EAAM,IAA4B,MAAbA,EAAM,GAC7B,OAAO,IAAIF,YAAY,YAAYC,OAAOC,GAE5C,GAAiB,MAAbA,EAAM,IAA4B,MAAbA,EAAM,GAC7B,OAAO,IAAIF,YAAY,YAAYC,OAAOC,EAE9C,CACA,IACE,OAAO,IAAIF,YAAY,QAAS,CAAEQ,OAAO,IAAQP,OAAOC,EAC1D,CAAE,MACA,OAAO,IAAIF,YAAY,UAAUC,OAAOC,EAC1C,CACF,CAvBaO,CAAWd,GAGtB,MAAM,IAAIe,UAAU,wDACtB,SC1BO,SAAeC,GAGpB,MAAMC,GAFND,EAAMjB,EAAaiB,IAEAE,MAAM,EAAG,KAC5B,IAAIC,EAAO,KACPF,EAAOG,SAAS,QAClBD,EAAO,OACEF,EAAOG,SAAS,QACzBD,EAAO,MAGT,MAAME,EAAWL,EAAIM,MAAM,GAAGH,QAAWA,KAEnCI,EAAW,GACXC,EAAW,GAMjB,GAAwB,IAApBH,EAAST,OAAc,MAAM,IAAIa,MAAM,oBAE3C,MAAMC,EAAaL,EAAS,GAC5B,GAAmC,IAA/BK,EAAWC,QAAQ,QACrB,MAAM,IAAIF,MAAM,iCAGlB,MAAMG,EAAQF,EAAWJ,MAAMH,GAC/B,GAAIS,EAAMhB,OAAS,EAAG,MAAM,IAAIa,MAAM,uCAEtC,IAAII,EAAiBD,EAAM,GAAGV,MAAM,EAAG,GAAM,EAC7C,MAAMY,EAAiBF,EAAM,GAAGV,MAAM,EAAG,GAAM,EAK/C,GAFoBU,EAAM,GAAGV,MAAM,EAAG,GAAM,GAEzBG,EAAS,GAAI,CAC9B,MAAMU,EAAYV,EAAS,GAAGC,MAAMH,GAChCY,EAAU,KACZF,EAAiBE,EAAU,GACxBC,OACAC,QAAQ,UAAW,IACnBX,MAAM,QAAQV,OAErB,CAEA,GAAIiB,EAAiBC,IAAmBT,EAAST,OAAS,EACxD,MAAM,IAAIa,MAAM,uCAGlB,IAAK,IAAIS,EAAI,EAAGA,EAAIb,EAAST,OAAQsB,IAC/BA,GAAKL,EACPN,EAASY,KAAKd,EAASa,IAEvBV,EAASW,KAAKd,EAASa,IAG3B,MAAO,CAAEX,WAAUC,WACrB","x_google_ignoreList":[0]}