{"version":3,"file":"jcampconverter.min.js","sources":["../node_modules/ensure-string/lib-esm/index.js","../node_modules/isutf8/dist/index.esm.js","../node_modules/dynamic-typing/src/parseString.js","../src/complexChromatogram.js","../src/convertToFloatArray.js","../src/parse/fastParseXYData.js","../src/parse/parsePeakTable.js","../src/parse/parseXYA.js","../node_modules/is-any-array/lib-esm/index.js","../node_modules/median-quickselect/lib/median-quickselect.min.js","../node_modules/ml-array-median/lib-es6/index.js","../src/2d/add2D.js","../src/2d/convertTo3DZ.js","../src/2d/generateContourLines.js","../node_modules/gyromagnetic-ratio/lib-esm/index.js","../src/profiling.js","../src/simpleChromatogram.js","../src/postProcessing.js","../src/postProcessingNMR.js","../src/prepareNtuplesDatatable.js","../src/prepareSpectrum.js","../src/convert.js","../src/createTree.js"],"sourcesContent":["import isutf8 from 'isutf8';\n/**\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        const { encoding = guessEncoding(blob) } = options;\n        const decoder = new TextDecoder(encoding);\n        return decoder.decode(blob);\n    }\n    throw new TypeError(`blob must be a string, ArrayBuffer or ArrayBufferView`);\n}\nfunction guessEncoding(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 'utf-16be';\n        }\n        if (uint8[0] === 0xff && uint8[1] === 0xfe) {\n            return 'utf-16le';\n        }\n    }\n    //@ts-expect-error an ArrayBuffer is also ok\n    if (!isutf8(blob))\n        return 'latin1';\n    return 'utf-8';\n}\n//# sourceMappingURL=index.js.map","/*\n    https://tools.ietf.org/html/rfc3629\n\n    UTF8-char = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4\n\n    UTF8-1    = %x00-7F\n\n    UTF8-2    = %xC2-DF UTF8-tail\n\n    UTF8-3    = %xE0 %xA0-BF UTF8-tail\n                %xE1-EC 2( UTF8-tail )\n                %xED %x80-9F UTF8-tail\n                %xEE-EF 2( UTF8-tail )\n\n    UTF8-4    = %xF0 %x90-BF 2( UTF8-tail )\n                %xF1-F3 3( UTF8-tail )\n                %xF4 %x80-8F 2( UTF8-tail )\n\n    UTF8-tail = %x80-BF\n*/\n/**\n * Check if a Node.js Buffer or Uint8Array is UTF-8.\n */\nfunction isUtf8(buf) {\n    if (!buf) {\n        return false;\n    }\n    var i = 0;\n    var len = buf.length;\n    while (i < len) {\n        // UTF8-1 = %x00-7F\n        if (buf[i] <= 0x7F) {\n            i++;\n            continue;\n        }\n        // UTF8-2 = %xC2-DF UTF8-tail\n        if (buf[i] >= 0xC2 && buf[i] <= 0xDF) {\n            // if(buf[i + 1] >= 0x80 && buf[i + 1] <= 0xBF) {\n            if (buf[i + 1] >> 6 === 2) {\n                i += 2;\n                continue;\n            }\n            else {\n                return false;\n            }\n        }\n        // UTF8-3 = %xE0 %xA0-BF UTF8-tail\n        // UTF8-3 = %xED %x80-9F UTF8-tail\n        if (((buf[i] === 0xE0 && buf[i + 1] >= 0xA0 && buf[i + 1] <= 0xBF) ||\n            (buf[i] === 0xED && buf[i + 1] >= 0x80 && buf[i + 1] <= 0x9F)) && buf[i + 2] >> 6 === 2) {\n            i += 3;\n            continue;\n        }\n        // UTF8-3 = %xE1-EC 2( UTF8-tail )\n        // UTF8-3 = %xEE-EF 2( UTF8-tail )\n        if (((buf[i] >= 0xE1 && buf[i] <= 0xEC) ||\n            (buf[i] >= 0xEE && buf[i] <= 0xEF)) &&\n            buf[i + 1] >> 6 === 2 &&\n            buf[i + 2] >> 6 === 2) {\n            i += 3;\n            continue;\n        }\n        // UTF8-4 = %xF0 %x90-BF 2( UTF8-tail )\n        //          %xF1-F3 3( UTF8-tail )\n        //          %xF4 %x80-8F 2( UTF8-tail )\n        if (((buf[i] === 0xF0 && buf[i + 1] >= 0x90 && buf[i + 1] <= 0xBF) ||\n            (buf[i] >= 0xF1 && buf[i] <= 0xF3 && buf[i + 1] >> 6 === 2) ||\n            (buf[i] === 0xF4 && buf[i + 1] >= 0x80 && buf[i + 1] <= 0x8F)) &&\n            buf[i + 2] >> 6 === 2 &&\n            buf[i + 3] >> 6 === 2) {\n            i += 4;\n            continue;\n        }\n        return false;\n    }\n    return true;\n}\n\nexport { isUtf8 as default };\n","/**\n * Dynamically type a string\n * @param {string} value String to dynamically type\n * @returns {boolean|string|number}\n */\nexport function parseString(value) {\n  if (value.length === 4 || value.length === 5) {\n    let lowercase = value.toLowerCase();\n\n    if (lowercase === 'true') return true;\n    if (lowercase === 'false') return false;\n  }\n  let number = Number(value);\n  if (number === 0 && !value.includes('0')) {\n    return value;\n  }\n  if (!Number.isNaN(number)) return number;\n  return value;\n}\n","const GC_MS_FIELDS = ['TIC', '.RIC', 'SCANNUMBER'];\n\nexport function complexChromatogram(result) {\n  let spectra = result.spectra;\n  let length = spectra.length;\n  let chromatogram = {\n    times: new Array(length),\n    series: {\n      ms: {\n        dimension: 2,\n        data: new Array(length),\n      },\n    },\n  };\n\n  let existingGCMSFields = [];\n  for (let i = 0; i < GC_MS_FIELDS.length; i++) {\n    let label = convertMSFieldToLabel(GC_MS_FIELDS[i]);\n    if (spectra[0][label]) {\n      existingGCMSFields.push(label);\n      chromatogram.series[label] = {\n        dimension: 1,\n        data: new Array(length),\n      };\n    }\n  }\n\n  for (let i = 0; i < length; i++) {\n    let spectrum = spectra[i];\n    chromatogram.times[i] = spectrum.pageValue;\n    for (let j = 0; j < existingGCMSFields.length; j++) {\n      chromatogram.series[existingGCMSFields[j]].data[i] = Number(\n        spectrum[existingGCMSFields[j]],\n      );\n    }\n    if (spectrum.data) {\n      chromatogram.series.ms.data[i] = [spectrum.data.x, spectrum.data.y];\n    }\n  }\n  result.chromatogram = chromatogram;\n}\n\nexport function isMSField(canonicDataLabel) {\n  return GC_MS_FIELDS.indexOf(canonicDataLabel) !== -1;\n}\n\nexport function convertMSFieldToLabel(value) {\n  return value.toLowerCase().replace(/[^a-z0-9]/g, '');\n}\n","export default function convertToFloatArray(stringArray) {\n  let floatArray = [];\n  for (let i = 0; i < stringArray.length; i++) {\n    floatArray.push(Number(stringArray[i]));\n  }\n  return floatArray;\n}\n","export default function fastParseXYData(spectrum, value) {\n  // TODO need to deal with result\n  //  console.log(value);\n  // we check if deltaX is defined otherwise we calculate it\n\n  let yFactor = spectrum.yFactor;\n  let deltaX = spectrum.deltaX;\n\n  spectrum.isXYdata = true;\n  let currentData = { x: [], y: [] };\n  spectrum.data = currentData;\n\n  let currentX = spectrum.firstX;\n  let currentY = spectrum.firstY;\n\n  // we skip the first line\n  //\n  let endLine = false;\n  let ascii;\n  let i = 0;\n  for (; i < value.length; i++) {\n    ascii = value.charCodeAt(i);\n    if (ascii === 13 || ascii === 10) {\n      endLine = true;\n    } else if (endLine) {\n      break;\n    }\n  }\n\n  // we proceed taking the i after the first line\n  let newLine = true;\n  let isDifference = false;\n  let isLastDifference = false;\n  let lastDifference = 0;\n  let isDuplicate = false;\n  let inComment = false;\n  let currentValue = 0; // can be a difference or a duplicate\n  let lastValue = 0; // must be the real last value\n  let isNegative = false;\n  let inValue = false;\n  let skipFirstValue = false;\n  let decimalPosition = 0;\n  for (; i <= value.length; i++) {\n    if (i === value.length) ascii = 13;\n    else ascii = value.charCodeAt(i);\n    if (inComment) {\n      // we should ignore the text if we are after $$\n      if (ascii === 13 || ascii === 10) {\n        newLine = true;\n        inComment = false;\n      }\n    } else {\n      // when is it a new value ?\n      // when it is not a digit, . or comma\n      // it is a number that is either new or we continue\n      // eslint-disable-next-line no-lonely-if\n      if (ascii <= 57 && ascii >= 48) {\n        // a number\n        inValue = true;\n        if (decimalPosition > 0) {\n          currentValue += (ascii - 48) / Math.pow(10, decimalPosition++);\n        } else {\n          currentValue *= 10;\n          currentValue += ascii - 48;\n        }\n      } else if (ascii === 44 || ascii === 46) {\n        // a \",\" or \".\"\n        inValue = true;\n        decimalPosition++;\n      } else {\n        if (inValue) {\n          // need to process the previous value\n          if (newLine) {\n            newLine = false; // we don't check the X value\n            // console.log(\"NEW LINE\",isDifference, lastDifference);\n            // if new line and lastDifference, the first value is just a check !\n            // that we don't check ...\n            if (isLastDifference) skipFirstValue = true;\n          } else {\n            // need to deal with duplicate and differences\n            // eslint-disable-next-line no-lonely-if\n            if (skipFirstValue) {\n              skipFirstValue = false;\n            } else {\n              if (isDifference) {\n                lastDifference = isNegative ? 0 - currentValue : currentValue;\n                isLastDifference = true;\n                isDifference = false;\n              } else if (!isDuplicate) {\n                lastValue = isNegative ? 0 - currentValue : currentValue;\n              }\n              let duplicate = isDuplicate ? currentValue - 1 : 1;\n              for (let j = 0; j < duplicate; j++) {\n                if (isLastDifference) {\n                  currentY += lastDifference;\n                } else {\n                  currentY = lastValue;\n                }\n                currentData.x.push(currentX);\n                currentData.y.push(currentY * yFactor);\n                currentX += deltaX;\n              }\n            }\n          }\n          isNegative = false;\n          currentValue = 0;\n          decimalPosition = 0;\n          inValue = false;\n          isDuplicate = false;\n        }\n\n        // positive SQZ digits @ A B C D E F G H I (ascii 64-73)\n        if (ascii < 74 && ascii > 63) {\n          inValue = true;\n          isLastDifference = false;\n          currentValue = ascii - 64;\n        } else if (ascii > 96 && ascii < 106) {\n          // negative SQZ digits a b c d e f g h i (ascii 97-105)\n          inValue = true;\n          isLastDifference = false;\n          currentValue = ascii - 96;\n          isNegative = true;\n        } else if (ascii === 115) {\n          // DUP digits S T U V W X Y Z s (ascii 83-90, 115)\n          inValue = true;\n          isDuplicate = true;\n          currentValue = 9;\n        } else if (ascii > 82 && ascii < 91) {\n          inValue = true;\n          isDuplicate = true;\n          currentValue = ascii - 82;\n        } else if (ascii > 73 && ascii < 83) {\n          // positive DIF digits % J K L M N O P Q R (ascii 37, 74-82)\n          inValue = true;\n          isDifference = true;\n          currentValue = ascii - 73;\n        } else if (ascii > 105 && ascii < 115) {\n          // negative DIF digits j k l m n o p q r (ascii 106-114)\n          inValue = true;\n          isDifference = true;\n          currentValue = ascii - 105;\n          isNegative = true;\n        } else if (ascii === 36 && value.charCodeAt(i + 1) === 36) {\n          // $ sign, we need to check the next one\n          inValue = true;\n          inComment = true;\n        } else if (ascii === 37) {\n          // positive DIF digits % J K L M N O P Q R (ascii 37, 74-82)\n          inValue = true;\n          isDifference = true;\n          currentValue = 0;\n          isNegative = false;\n        } else if (ascii === 45) {\n          // a \"-\"\n          // check if after there is a number, decimal or comma\n          let ascii2 = value.charCodeAt(i + 1);\n          if (\n            (ascii2 >= 48 && ascii2 <= 57) ||\n            ascii2 === 44 ||\n            ascii2 === 46\n          ) {\n            inValue = true;\n            if (!newLine) isLastDifference = false;\n            isNegative = true;\n          }\n        } else if (ascii === 13 || ascii === 10) {\n          newLine = true;\n          inComment = false;\n        }\n        // and now analyse the details ... space or tabulation\n        // if \"+\" we just don't care\n      }\n    }\n  }\n}\n","const removeCommentRegExp = /\\$\\$.*/;\nconst peakTableSplitRegExp = /[,\\t ]+/;\n\nexport default function parsePeakTable(spectrum, value, result) {\n  spectrum.isPeaktable = true;\n\n  if (!spectrum.variables || Object.keys(spectrum.variables) === 2) {\n    parseXY(spectrum, value, result);\n  } else {\n    parseXYZ(spectrum, value, result);\n  }\n\n  // we will add the data in the variables\n  if (spectrum.variables) {\n    for (let key in spectrum.variables) {\n      spectrum.variables[key].data = spectrum.data[key];\n    }\n  }\n}\n\nfunction parseXY(spectrum, value, result) {\n  let currentData = { x: [], y: [] };\n  spectrum.data = currentData;\n\n  // counts for around 20% of the time\n  let lines = value.split(/,? *,?[;\\r\\n]+ */);\n\n  for (let i = 1; i < lines.length; i++) {\n    let values = lines[i]\n      .trim()\n      .replace(removeCommentRegExp, '')\n      .split(peakTableSplitRegExp);\n    if (values.length % 2 === 0) {\n      for (let j = 0; j < values.length; j = j + 2) {\n        // takes around 40% of the time to add and parse the 2 values nearly exclusively because of Number\n        currentData.x.push(Number(values[j]) * spectrum.xFactor);\n        currentData.y.push(Number(values[j + 1]) * spectrum.yFactor);\n      }\n    } else {\n      result.logs.push(`Format error: ${values}`);\n    }\n  }\n}\n\nfunction parseXYZ(spectrum, value, result) {\n  let currentData = {};\n  let variables = Object.keys(spectrum.variables);\n  let numberOfVariables = variables.length;\n  variables.forEach((variable) => (currentData[variable] = []));\n  spectrum.data = currentData;\n\n  // counts for around 20% of the time\n  let lines = value.split(/,? *,?[;\\r\\n]+ */);\n\n  for (let i = 1; i < lines.length; i++) {\n    let values = lines[i]\n      .trim()\n      .replace(removeCommentRegExp, '')\n      .split(peakTableSplitRegExp);\n    if (values.length % numberOfVariables === 0) {\n      for (let j = 0; j < values.length; j++) {\n        // todo should try to find a xFactor (y, ...)\n        currentData[variables[j % numberOfVariables]].push(Number(values[j]));\n      }\n    } else {\n      result.logs.push(`Format error: ${values}`);\n    }\n  }\n}\n","/*\n(5.4.4) ##РЕАК ASSIGNMENTS= (STRING). List\nof peak assignments for components or functional groups\nin the forms ##РЕАК ASSIGNMENTS= (ХУА),\n(XYW А), (ХУМА), (XYMW А). Each entry is surrounded Ьу parentheses and starts а new line. У, W (peak\nwidth), and М (multiplicity) values are optional. The\nsymbol А stands for а string detailing the assignment\nand must Ье enclosed Ьу angle brackets. If the peak width\nvalue is included, then the function used to calculate the\npeak width must Ье detailed in а $$ comment on the\nline(s) below ##PEAKASSIGNMENTS=. Priority OPTIONAL. N.B.: ##РЕАК ASSIGNMENTS= is the preferred method of transmitting peak information when\nthe assignments are known.\n */\n\nexport default function parseXYA(spectrum, value) {\n  spectrum.isXYAdata = true;\n  const currentData = {};\n  spectrum.data = currentData;\n\n  let lines = value.split(/\\r?\\n/);\n  const variables = lines[0]\n    .replace(/^.*?([A-Z]+).*$/, '$1')\n    .split('')\n    .map((variable) => variable.toLowerCase());\n\n  for (let i = 1; i < lines.length; i++) {\n    const fields = lines[i].replace(/^\\((.*)\\)$/, '$1').split(/ *, */);\n    for (let j = 0; j < variables.length; j++) {\n      let value = fields[j];\n      switch (variables[j]) {\n        case 'x':\n        case 'y':\n        case 'w':\n          value = Number.parseFloat(value);\n          break;\n        case 'a':\n          value = value.replace(/^<(.*)>$/, '$1');\n          break;\n        case 'm':\n          break;\n        default:\n          continue;\n      }\n      if (!currentData[variables[j]]) {\n        currentData[variables[j]] = [];\n      }\n      currentData[variables[j]].push(value);\n    }\n  }\n}\n","const toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array).\n *\n * @param {any} value - Object to check.\n * @returns {boolean} True if the object is an array.\n */\nexport function isAnyArray(value) {\n    return toString.call(value).endsWith('Array]');\n}\n//# sourceMappingURL=index.js.map","(function(){function a(d){for(var e=0,f=d.length-1,g=void 0,h=void 0,i=void 0,j=c(e,f);!0;){if(f<=e)return d[j];if(f==e+1)return d[e]>d[f]&&b(d,e,f),d[j];for(g=c(e,f),d[g]>d[f]&&b(d,g,f),d[e]>d[f]&&b(d,e,f),d[g]>d[e]&&b(d,g,e),b(d,g,e+1),h=e+1,i=f;!0;){do h++;while(d[e]>d[h]);do i--;while(d[i]>d[e]);if(i<h)break;b(d,h,i)}b(d,e,i),i<=j&&(e=h),i>=j&&(f=i-1)}}var b=function b(d,e,f){var _ref;return _ref=[d[f],d[e]],d[e]=_ref[0],d[f]=_ref[1],_ref},c=function c(d,e){return~~((d+e)/2)};'undefined'!=typeof module&&module.exports?module.exports=a:window.median=a})();\n","import { isAnyArray } from 'is-any-array';\nimport quickSelectMedian from 'median-quickselect';\n\nfunction median(input) {\n  if (!isAnyArray(input)) {\n    throw new TypeError('input must be an array');\n  }\n\n  if (input.length === 0) {\n    throw new TypeError('input must not be empty');\n  }\n\n  return quickSelectMedian(input.slice());\n}\n\nexport { median as default };\n","import convertTo3DZ from './convertTo3DZ';\nimport generateContourLines from './generateContourLines';\n\nexport default function add2D(result, options) {\n  let zData = convertTo3DZ(result.spectra);\n  if (!options.noContour) {\n    result.contourLines = generateContourLines(zData, options);\n    delete zData.z;\n  }\n  result.minMax = zData;\n}\n","import getMedian from 'ml-array-median';\n\nexport default function convertTo3DZ(spectra) {\n  let minZ = spectra[0].data.y[0];\n  let maxZ = minZ;\n  let ySize = spectra.length;\n  let xSize = spectra[0].data.x.length;\n\n  let z = new Array(ySize);\n  for (let i = 0; i < ySize; i++) {\n    z[i] = spectra[i].data.y;\n    for (let j = 0; j < xSize; j++) {\n      let value = z[i][j];\n      if (value < minZ) minZ = value;\n      if (value > maxZ) maxZ = value;\n    }\n  }\n\n  const firstX = spectra[0].data.x[0];\n  const lastX = spectra[0].data.x[spectra[0].data.x.length - 1]; // has to be -2 because it is a 1D array [x,y,x,y,...]\n  const firstY = spectra[0].pageValue;\n  const lastY = spectra[ySize - 1].pageValue;\n\n  // Because the min / max value are the only information about the matrix if we invert\n  // min and max we need to invert the array\n  if (firstX > lastX) {\n    for (let spectrum of z) {\n      spectrum.reverse();\n    }\n  }\n  if (firstY > lastY) {\n    z.reverse();\n  }\n\n  const medians = [];\n  for (let i = 0; i < z.length; i++) {\n    const row = Float64Array.from(z[i]);\n    for (let i = 0; i < row.length; i++) {\n      if (row[i] < 0) row[i] = -row[i];\n    }\n    medians.push(getMedian(row));\n  }\n  const median = getMedian(medians);\n\n  return {\n    z,\n    minX: Math.min(firstX, lastX),\n    maxX: Math.max(firstX, lastX),\n    minY: Math.min(firstY, lastY),\n    maxY: Math.max(firstY, lastY),\n    minZ,\n    maxZ,\n    noise: median,\n  };\n}\n","export default function generateContourLines(zData, options) {\n  let noise = zData.noise;\n  let z = zData.z;\n  let povarHeight0, povarHeight1, povarHeight2, povarHeight3;\n  let isOver0, isOver1, isOver2, isOver3;\n  let nbSubSpectra = z.length;\n  let nbPovars = z[0].length;\n  let pAx, pAy, pBx, pBy;\n\n  let x0 = zData.minX;\n  let xN = zData.maxX;\n  let dx = (xN - x0) / (nbPovars - 1);\n  let y0 = zData.minY;\n  let yN = zData.maxY;\n  let dy = (yN - y0) / (nbSubSpectra - 1);\n  let minZ = zData.minZ;\n  let maxZ = zData.maxZ;\n\n  // System.out.prvarln('y0 '+y0+' yN '+yN);\n  // -------------------------\n  // Povars attribution\n  //\n  // 0----1\n  // |  / |\n  // | /  |\n  // 2----3\n  //\n  // ---------------------d------\n\n  let iter = options.nbContourLevels * 2;\n  let contourLevels = new Array(iter);\n  let lineZValue;\n  for (let level = 0; level < iter; level++) {\n    // multiply by 2 for positif and negatif\n    let contourLevel = {};\n    contourLevels[level] = contourLevel;\n    let side = level % 2;\n    let factor =\n      (maxZ - options.noiseMultiplier * noise) *\n      Math.exp((level >> 1) - options.nbContourLevels);\n    if (side === 0) {\n      lineZValue = factor + options.noiseMultiplier * noise;\n    } else {\n      lineZValue = 0 - factor - options.noiseMultiplier * noise;\n    }\n    let lines = [];\n    contourLevel.zValue = lineZValue;\n    contourLevel.lines = lines;\n\n    if (lineZValue <= minZ || lineZValue >= maxZ) continue;\n\n    for (let iSubSpectra = 0; iSubSpectra < nbSubSpectra - 1; iSubSpectra++) {\n      let subSpectra = z[iSubSpectra];\n      let subSpectraAfter = z[iSubSpectra + 1];\n      for (let povar = 0; povar < nbPovars - 1; povar++) {\n        povarHeight0 = subSpectra[povar];\n        povarHeight1 = subSpectra[povar + 1];\n        povarHeight2 = subSpectraAfter[povar];\n        povarHeight3 = subSpectraAfter[povar + 1];\n\n        isOver0 = povarHeight0 > lineZValue;\n        isOver1 = povarHeight1 > lineZValue;\n        isOver2 = povarHeight2 > lineZValue;\n        isOver3 = povarHeight3 > lineZValue;\n\n        // Example povar0 is over the plane and povar1 and\n        // povar2 are below, we find the varersections and add\n        // the segment\n        if (isOver0 !== isOver1 && isOver0 !== isOver2) {\n          pAx =\n            povar + (lineZValue - povarHeight0) / (povarHeight1 - povarHeight0);\n          pAy = iSubSpectra;\n          pBx = povar;\n          pBy =\n            iSubSpectra +\n            (lineZValue - povarHeight0) / (povarHeight2 - povarHeight0);\n          lines.push(pAx * dx + x0);\n          lines.push(pAy * dy + y0);\n          lines.push(pBx * dx + x0);\n          lines.push(pBy * dy + y0);\n        }\n        // remove push does not help !!!!\n        if (isOver3 !== isOver1 && isOver3 !== isOver2) {\n          pAx = povar + 1;\n          pAy =\n            iSubSpectra +\n            1 -\n            (lineZValue - povarHeight3) / (povarHeight1 - povarHeight3);\n          pBx =\n            povar +\n            1 -\n            (lineZValue - povarHeight3) / (povarHeight2 - povarHeight3);\n          pBy = iSubSpectra + 1;\n          lines.push(pAx * dx + x0);\n          lines.push(pAy * dy + y0);\n          lines.push(pBx * dx + x0);\n          lines.push(pBy * dy + y0);\n        }\n        // test around the diagonal\n        if (isOver1 !== isOver2) {\n          pAx =\n            (povar +\n              1 -\n              (lineZValue - povarHeight1) / (povarHeight2 - povarHeight1)) *\n              dx +\n            x0;\n          pAy =\n            (iSubSpectra +\n              (lineZValue - povarHeight1) / (povarHeight2 - povarHeight1)) *\n              dy +\n            y0;\n          if (isOver1 !== isOver0) {\n            pBx =\n              povar +\n              1 -\n              (lineZValue - povarHeight1) / (povarHeight0 - povarHeight1);\n            pBy = iSubSpectra;\n            lines.push(pAx);\n            lines.push(pAy);\n            lines.push(pBx * dx + x0);\n            lines.push(pBy * dy + y0);\n          }\n          if (isOver2 !== isOver0) {\n            pBx = povar;\n            pBy =\n              iSubSpectra +\n              1 -\n              (lineZValue - povarHeight2) / (povarHeight0 - povarHeight2);\n            lines.push(pAx);\n            lines.push(pAy);\n            lines.push(pBx * dx + x0);\n            lines.push(pBy * dy + y0);\n          }\n          if (isOver1 !== isOver3) {\n            pBx = povar + 1;\n            pBy =\n              iSubSpectra +\n              (lineZValue - povarHeight1) / (povarHeight3 - povarHeight1);\n            lines.push(pAx);\n            lines.push(pAy);\n            lines.push(pBx * dx + x0);\n            lines.push(pBy * dy + y0);\n          }\n          if (isOver2 !== isOver3) {\n            pBx =\n              povar +\n              (lineZValue - povarHeight2) / (povarHeight3 - povarHeight2);\n            pBy = iSubSpectra + 1;\n            lines.push(pAx);\n            lines.push(pAy);\n            lines.push(pBx * dx + x0);\n            lines.push(pBy * dy + y0);\n          }\n        }\n      }\n    }\n  }\n\n  return {\n    minX: zData.minX,\n    maxX: zData.maxX,\n    minY: zData.minY,\n    maxY: zData.maxY,\n    segments: contourLevels,\n  };\n}\n","export const gyromagneticRatio = {\n    '1H': 267.52218744e6,\n    '2H': 41.065e6,\n    '3H': 285.3508e6,\n    '3He': -203.789e6,\n    '7Li': 103.962e6,\n    '13C': 67.28284e6,\n    '14N': 19.331e6,\n    '15N': -27.116e6,\n    '17O': -36.264e6,\n    '19F': 251.662e6,\n    '23Na': 70.761e6,\n    '27Al': 69.763e6,\n    '29Si': -53.19e6,\n    '31P': 108.291e6,\n    '57Fe': 8.681e6,\n    '63Cu': 71.118e6,\n    '67Zn': 16.767e6,\n    '129Xe': -73.997e6,\n};\n//# sourceMappingURL=index.js.map","export default function profiling(result, action, options = {}) {\n  options.logger?.trace(action);\n  if (result.profiling) {\n    result.profiling.push({\n      action,\n      time: Date.now() - options.start,\n    });\n  }\n}\n","export default function simpleChromatogram(result) {\n  let data = result.spectra[0].data;\n  result.chromatogram = {\n    times: data.x.slice(),\n    series: {\n      intensity: {\n        dimension: 1,\n        data: data.y.slice(),\n      },\n    },\n  };\n}\n","import add2D from './2d/add2D';\nimport { complexChromatogram } from './complexChromatogram';\nimport postProcessingNMR from './postProcessingNMR';\nimport profiling from './profiling';\nimport simpleChromatogram from './simpleChromatogram';\n\nexport default function postProcessing(entriesFlat, result, options) {\n  // converting Hz to ppm\n  postProcessingNMR(entriesFlat);\n\n  for (let entry of entriesFlat) {\n    if (Object.keys(entry.ntuples).length > 0) {\n      let newNtuples = [];\n      let keys = Object.keys(entry.ntuples);\n      for (let i = 0; i < keys.length; i++) {\n        let key = keys[i];\n        let values = entry.ntuples[key];\n        for (let j = 0; j < values.length; j++) {\n          if (!newNtuples[j]) newNtuples[j] = {};\n          newNtuples[j][key] = values[j];\n        }\n      }\n      entry.ntuples = newNtuples;\n    }\n\n    if (entry.twoD && options.wantXY) {\n      add2D(entry, options);\n\n      profiling(result, 'Finished countour plot calculation', options);\n\n      if (!options.keepSpectra) {\n        delete entry.spectra;\n      }\n    }\n\n    // maybe it is a GC (HPLC) / MS. In this case we add a new format\n    if (options.chromatogram) {\n      if (entry.spectra.length > 1) {\n        complexChromatogram(entry);\n      } else {\n        simpleChromatogram(entry);\n      }\n      profiling(result, 'Finished chromatogram calculation', options);\n    }\n\n    delete entry.tmp;\n  }\n}\n","import { gyromagneticRatio } from 'gyromagnetic-ratio';\n\nexport default function postProcessingNMR(entriesFlat) {\n  // specific NMR functions\n\n  for (let entry of entriesFlat) {\n    let observeFrequency = 0;\n    let shiftOffsetVal = 0;\n    for (let spectrum of entry.spectra) {\n      if (entry.ntuples && entry.ntuples.symbol) {\n        if (!observeFrequency && spectrum.observeFrequency) {\n          observeFrequency = spectrum.observeFrequency;\n        }\n        if (!shiftOffsetVal && spectrum.shiftOffsetVal) {\n          shiftOffsetVal = spectrum.shiftOffsetVal;\n        }\n      } else {\n        observeFrequency = spectrum.observeFrequency;\n        shiftOffsetVal = spectrum.shiftOffsetVal;\n      }\n\n      if (observeFrequency) {\n        if (spectrum.xUnits && spectrum.xUnits.toUpperCase().includes('HZ')) {\n          spectrum.xUnits = 'PPM';\n          spectrum.xFactor = spectrum.xFactor / observeFrequency;\n          spectrum.firstX = spectrum.firstX / observeFrequency;\n          spectrum.lastX = spectrum.lastX / observeFrequency;\n          spectrum.deltaX = spectrum.deltaX / observeFrequency;\n          for (let i = 0; i < spectrum.data.x.length; i++) {\n            spectrum.data.x[i] /= observeFrequency;\n          }\n        }\n      }\n      if (shiftOffsetVal && spectrum.xUnits.toLowerCase().includes('ppm')) {\n        let shift = spectrum.firstX - shiftOffsetVal;\n        spectrum.firstX = spectrum.firstX - shift;\n        spectrum.lastX = spectrum.lastX - shift;\n        for (let i = 0; i < spectrum.data.x.length; i++) {\n          spectrum.data.x[i] -= shift;\n        }\n      }\n\n      // we will check if some nucleus are missing ...\n      if (entry.ntuples && entry.ntuples.nucleus && entry.ntuples.symbol) {\n        for (let i = 0; i < entry.ntuples.nucleus.length; i++) {\n          let symbol = entry.ntuples.symbol[i];\n          let nucleus = entry.ntuples.nucleus[i];\n          if (symbol.match(/^[F|T]/) && !nucleus) {\n            if (symbol.match(/[F|T]1/)) {\n              // if F1 is defined we will use F2\n              if (entry.tmp.$NUC2) {\n                entry.ntuples.nucleus[i] = entry.tmp.$NUC2;\n              } else {\n                let f2index = entry.ntuples.symbol.indexOf(\n                  symbol.replace(/^([F|T]).*/, '$12'),\n                );\n                if (f2index && entry.ntuples.nucleus[f2index]) {\n                  entry.ntuples.nucleus[i] = entry.ntuples.nucleus[f2index];\n                }\n              }\n            }\n            if (symbol.match(/[F|T]2/)) {\n              entry.ntuples.nucleus[i] = entry.tmp.$NUC1;\n            }\n          }\n          if (symbol.match(/[F|T]2/)) {\n            entry.yType = entry.ntuples.nucleus[0];\n          }\n        }\n      }\n\n      if (\n        observeFrequency &&\n        entry.ntuples &&\n        entry.ntuples.symbol &&\n        entry.ntuples.nucleus\n      ) {\n        let unit = '';\n        let pageSymbolIndex = entry.ntuples.symbol.indexOf(spectrum.pageSymbol);\n        if (entry.ntuples.units && entry.ntuples.units[pageSymbolIndex]) {\n          unit = entry.ntuples.units[pageSymbolIndex];\n        }\n        if (unit !== 'PPM') {\n          if (pageSymbolIndex !== 0) {\n            throw Error('Not sure about this ntuples format');\n          }\n\n          let ratio0 = gyromagneticRatio[entry.ntuples.nucleus[0]];\n          let ratio1 = gyromagneticRatio[entry.ntuples.nucleus[1]];\n          if (!ratio0 || !ratio1) {\n            throw Error('Problem with determination of gyromagnetic ratio');\n          }\n          let ratio = (ratio0 / ratio1) * observeFrequency;\n          spectrum.pageValue /= ratio;\n        }\n      }\n    }\n  }\n}\n","export default function prepareNtuplesDatatable(currentEntry, spectrum, kind) {\n  let xIndex = -1;\n  let yIndex = -1;\n  let firstVariable = '';\n  let secondVariable = '';\n  if (kind.indexOf('++') > 0) {\n    firstVariable = kind.replace(/.*\\(([a-zA-Z0-9]+)\\+\\+.*/, '$1');\n    secondVariable = kind.replace(/.*\\.\\.([a-zA-Z0-9]+).*/, '$1');\n  } else {\n    kind = kind.replace(/[^a-zA-Z]/g, '');\n    firstVariable = kind.charAt(0);\n    secondVariable = kind.charAt(1);\n    spectrum.variables = {};\n    for (let symbol of kind) {\n      let lowerCaseSymbol = symbol.toLowerCase();\n      let index = currentEntry.ntuples.symbol.indexOf(symbol);\n      if (index === -1) throw Error(`Symbol undefined: ${symbol}`);\n      spectrum.variables[lowerCaseSymbol] = {};\n      for (let key in currentEntry.ntuples) {\n        if (currentEntry.ntuples[key][index]) {\n          spectrum.variables[lowerCaseSymbol][key.replace(/^var/, '')] =\n            currentEntry.ntuples[key][index];\n        }\n      }\n    }\n  }\n  xIndex = currentEntry.ntuples.symbol.indexOf(firstVariable);\n  yIndex = currentEntry.ntuples.symbol.indexOf(secondVariable);\n\n  if (xIndex === -1) xIndex = 0;\n  if (yIndex === -1) yIndex = 0;\n\n  if (currentEntry.ntuples.first) {\n    if (currentEntry.ntuples.first.length > xIndex) {\n      spectrum.firstX = currentEntry.ntuples.first[xIndex];\n    }\n    if (currentEntry.ntuples.first.length > yIndex) {\n      spectrum.firstY = currentEntry.ntuples.first[yIndex];\n    }\n  }\n  if (currentEntry.ntuples.last) {\n    if (currentEntry.ntuples.last.length > xIndex) {\n      spectrum.lastX = currentEntry.ntuples.last[xIndex];\n    }\n    if (currentEntry.ntuples.last.length > yIndex) {\n      spectrum.lastY = currentEntry.ntuples.last[yIndex];\n    }\n  }\n  if (\n    currentEntry.ntuples.vardim &&\n    currentEntry.ntuples.vardim.length > xIndex\n  ) {\n    spectrum.nbPoints = currentEntry.ntuples.vardim[xIndex];\n  }\n  if (currentEntry.ntuples.factor) {\n    if (currentEntry.ntuples.factor.length > xIndex) {\n      spectrum.xFactor = currentEntry.ntuples.factor[xIndex];\n    }\n    if (currentEntry.ntuples.factor.length > yIndex) {\n      spectrum.yFactor = currentEntry.ntuples.factor[yIndex];\n    }\n  }\n  if (currentEntry.ntuples.units) {\n    if (currentEntry.ntuples.units.length > xIndex) {\n      if (\n        currentEntry.ntuples.varname &&\n        currentEntry.ntuples.varname[xIndex]\n      ) {\n        spectrum.xUnits = `${currentEntry.ntuples.varname[xIndex]} [${currentEntry.ntuples.units[xIndex]}]`;\n      } else {\n        spectrum.xUnits = currentEntry.ntuples.units[xIndex];\n      }\n    }\n    if (currentEntry.ntuples.units.length > yIndex) {\n      if (\n        currentEntry.ntuples.varname &&\n        currentEntry.ntuples.varname[yIndex]\n      ) {\n        spectrum.yUnits = `${currentEntry.ntuples.varname[yIndex]} [${currentEntry.ntuples.units[yIndex]}]`;\n      } else {\n        spectrum.yUnits = currentEntry.ntuples.units[yIndex];\n      }\n    }\n  }\n}\n","export default function prepareSpectrum(spectrum) {\n  if (!spectrum.xFactor) spectrum.xFactor = 1;\n  if (!spectrum.yFactor) spectrum.yFactor = 1;\n}\n","import { parseString } from 'dynamic-typing';\nimport { ensureString } from 'ensure-string';\n\nimport { isMSField, convertMSFieldToLabel } from './complexChromatogram';\nimport convertToFloatArray from './convertToFloatArray';\nimport fastParseXYData from './parse/fastParseXYData';\nimport parsePeakTable from './parse/parsePeakTable';\nimport parseXYA from './parse/parseXYA';\nimport postProcessing from './postProcessing';\nimport prepareNtuplesDatatable from './prepareNtuplesDatatable';\nimport prepareSpectrum from './prepareSpectrum';\nimport profiling from './profiling';\n\n// the following RegExp can only be used for XYdata, some peakTables have values with a \"E-5\" ...\nconst ntuplesSeparatorRegExp = /[ \\t]*,[ \\t]*/;\n\nconst defaultOptions = {\n  keepRecordsRegExp: /^$/,\n  canonicDataLabels: true,\n  canonicMetadataLabels: false,\n  dynamicTyping: true,\n  withoutXY: false,\n  chromatogram: false,\n  keepSpectra: false,\n  noContour: false,\n  nbContourLevels: 7,\n  noiseMultiplier: 5,\n  profiling: false,\n};\n\n/**\n * Conversion options\n * @typedef {object} ConvertOptions\n * @property {RegExp} [keepRecordsRegExp=/^$/] - By default we don't keep meta information.\n * @property {boolean} [canonicDataLabels=true] - Canonize the Labels (uppercase without symbol).\n * @property {boolean} [canonicMetadataLabels=false] - Canonize the metadata Labels (uppercase without symbol).\n * @property {boolean} [dynamicTyping=false] - Convert numbers to Number.\n * @property {boolean} [withoutXY=false] - Remove the XY data.\n * @property {boolean} [chromatogram=false] - Special post-processing for GC / HPLC / MS.\n * @property {boolean} [keepSpectra=false] - Force to keep the spectra in case of 2D.\n * @property {boolean} [noContour=false] - Don't calculate countour in case of 2D.\n * @property {number} [nbContourLevels=7] - Number of positive / negative contour levels to calculate.\n * @property {number} [noiseMultiplier=5] - Define for 2D the level as 5 times the median as default.\n * @property {import('@types/pino').Logger} [logger] - A logger like 'pino'\n * @property {boolean} [profiling=false] - Add profiling information.\n */\n\n/**\n *\n * @typedef {object} Ntuples\n * @property {string[]} [varname]\n * @property {string[]} [symbol]\n * @property {string[]} [vartype]\n * @property {string[]} [varform]\n * @property {number[]} [vardim]\n * @property {string[]} [units]\n * @property {number[]} [factor]\n * @property {number[]} [first]\n * @property {number[]} [last]\n * @property {number[]} [min]\n * @property {number[]} [max]\n * @property {string[]} [nucleus]\n */\n\n/**\n * @typedef { Record<string, any> } Spectrum\n * @property {Record<string, number[]>} [data]\n * @property {number} [firstX] - first X value\n * @property {number} [lastX] - last X value\n * @property {number} [deltaX] - distance between 2 consecutive x axis values\n * @property {number} [yFactor] - y axis scaling factor\n * @property {number} [xFactor] - x axis scaling factor\n * @property {number} [nbPoints] - Number of points\n */\n\n/**\n *\n * @typedef {object} Entry\n * @property {Spectrum[]} spectra\n * @property {Ntuples} ntuples\n * @property {object} meta\n * @property {object} info\n * @property {object} tmp\n * @property {string} [title]\n * @property {string} [dataType]\n * @property {string} [dataClass]\n * @property {boolean} [twoD]\n */\n\n/**\n *\n * @typedef { object } ConvertResult\n * @property { object[] | boolean } profiling\n * @property { string[] } logs\n * @property { object[] } entries\n * @property { Entry[] } flatten\n */\n\n/**\n * Parse a jcamp.\n * The data can be provide as a string or array buffer. In this later case\n * we will convert it first to a string before parsing.\n * @param {string|ArrayBuffer|Uint8Array} jcamp\n * @param {ConvertOptions} [options]\n * @returns {ConvertResult}\n */\n\nexport function convert(jcamp, options = {}) {\n  jcamp = ensureString(jcamp);\n  options = { ...defaultOptions, ...options };\n\n  options.logger?.debug('Starting jcamp conversion');\n\n  options.wantXY = !options.withoutXY;\n  options.start = Date.now();\n\n  let entriesFlat = [];\n\n  let result = {\n    profiling: options.profiling ? [] : false,\n    logs: [],\n    entries: [],\n  };\n\n  let tmpResult = { children: [] };\n  let currentEntry = tmpResult;\n  let parentsStack = [];\n\n  let spectrum = {};\n\n  if (typeof jcamp !== 'string') {\n    throw new TypeError('the JCAMP should be a string');\n  }\n\n  profiling(result, 'Before split to LDRS', options);\n\n  let ldrs = jcamp.replace(/[\\r\\n]+##/g, '\\n##').split('\\n##');\n\n  profiling(result, 'Split to LDRS', options);\n\n  if (ldrs[0]) ldrs[0] = ldrs[0].replace(/^[\\r\\n ]*##/, '');\n\n  for (let ldr of ldrs) {\n    // This is a new LDR\n    let position = ldr.indexOf('=');\n    let dataLabel = position > 0 ? ldr.substring(0, position) : ldr;\n    let dataValue = position > 0 ? ldr.substring(position + 1).trim() : '';\n\n    let canonicDataLabel = dataLabel.replace(/[_ -]/g, '').toUpperCase();\n\n    if (canonicDataLabel === 'DATATABLE') {\n      let endLine = dataValue.indexOf('\\n');\n      if (endLine === -1) endLine = dataValue.indexOf('\\r');\n      if (endLine > 0) {\n        // ##DATA TABLE= (X++(I..I)), XYDATA\n        // We need to find the variables\n\n        let infos = dataValue.substring(0, endLine).split(/[ ,;\\t]+/);\n        prepareNtuplesDatatable(currentEntry, spectrum, infos[0]);\n\n        spectrum.datatable = infos[0];\n        if (infos[1] && infos[1].indexOf('PEAKS') > -1) {\n          canonicDataLabel = 'PEAKTABLE';\n        } else if (\n          infos[1] &&\n          (infos[1].indexOf('XYDATA') || infos[0].indexOf('++') > 0)\n        ) {\n          canonicDataLabel = 'XYDATA';\n          if (spectrum.nbPoints) {\n            spectrum.deltaX =\n              (spectrum.lastX - spectrum.firstX) / (spectrum.nbPoints - 1);\n          }\n        }\n      }\n    }\n\n    if (canonicDataLabel === 'XYDATA') {\n      if (options.wantXY) {\n        prepareSpectrum(spectrum);\n        // well apparently we should still consider it is a PEAK TABLE if there are no '++' after\n        if (dataValue.match(/.*\\+\\+.*/)) {\n          // ex: (X++(Y..Y))\n          if (spectrum.nbPoints) {\n            spectrum.deltaX =\n              (spectrum.lastX - spectrum.firstX) / (spectrum.nbPoints - 1);\n          }\n\n          fastParseXYData(spectrum, dataValue, result);\n        } else {\n          parsePeakTable(spectrum, dataValue, result);\n        }\n        currentEntry.spectra.push(spectrum);\n        spectrum = {};\n      }\n      continue;\n    } else if (canonicDataLabel === 'PEAKTABLE') {\n      if (options.wantXY) {\n        prepareSpectrum(spectrum);\n        parsePeakTable(spectrum, dataValue, result);\n        currentEntry.spectra.push(spectrum);\n        spectrum = {};\n      }\n      continue;\n    }\n    if (canonicDataLabel === 'PEAKASSIGNMENTS') {\n      if (options.wantXY) {\n        if (dataValue.match(/.*([^A-Z]*).*/)) {\n          // ex: (XYA)\n          parseXYA(spectrum, dataValue);\n        }\n        currentEntry.spectra.push(spectrum);\n        spectrum = {};\n      }\n      continue;\n    }\n\n    if (canonicDataLabel === 'TITLE') {\n      let parentEntry = currentEntry;\n      if (!parentEntry.children) {\n        parentEntry.children = [];\n      }\n      currentEntry = {\n        spectra: [],\n        ntuples: {},\n        info: {},\n        meta: {},\n        tmp: {}, // tmp information we need to keep for postprocessing\n      };\n      parentEntry.children.push(currentEntry);\n      parentsStack.push(parentEntry);\n      entriesFlat.push(currentEntry);\n      currentEntry.title = dataValue;\n    } else if (canonicDataLabel === 'DATATYPE') {\n      currentEntry.dataType = dataValue;\n      if (dataValue.match(/(^nd|\\snd\\s)/i)) {\n        currentEntry.twoD = true;\n      }\n    } else if (canonicDataLabel === 'NTUPLES') {\n      if (dataValue.match(/(^nd|\\snd\\s)/i)) {\n        currentEntry.twoD = true;\n      }\n    } else if (canonicDataLabel === 'DATACLASS') {\n      currentEntry.dataClass = dataValue;\n    } else if (canonicDataLabel === 'XUNITS') {\n      spectrum.xUnits = dataValue;\n    } else if (canonicDataLabel === 'YUNITS') {\n      spectrum.yUnits = dataValue;\n    } else if (canonicDataLabel === 'FIRSTX') {\n      spectrum.firstX = Number(dataValue);\n    } else if (canonicDataLabel === 'LASTX') {\n      spectrum.lastX = Number(dataValue);\n    } else if (canonicDataLabel === 'FIRSTY') {\n      spectrum.firstY = Number(dataValue);\n    } else if (canonicDataLabel === 'LASTY') {\n      spectrum.lastY = Number(dataValue);\n    } else if (canonicDataLabel === 'NPOINTS') {\n      spectrum.nbPoints = Number(dataValue);\n    } else if (canonicDataLabel === 'XFACTOR') {\n      spectrum.xFactor = Number(dataValue);\n    } else if (canonicDataLabel === 'YFACTOR') {\n      spectrum.yFactor = Number(dataValue);\n    } else if (canonicDataLabel === 'MAXX') {\n      spectrum.maxX = Number(dataValue);\n    } else if (canonicDataLabel === 'MINX') {\n      spectrum.minX = Number(dataValue);\n    } else if (canonicDataLabel === 'MAXY') {\n      spectrum.maxY = Number(dataValue);\n    } else if (canonicDataLabel === 'MINY') {\n      spectrum.minY = Number(dataValue);\n    } else if (canonicDataLabel === 'DELTAX') {\n      spectrum.deltaX = Number(dataValue);\n    } else if (\n      canonicDataLabel === '.OBSERVEFREQUENCY' ||\n      canonicDataLabel === '$SFO1'\n    ) {\n      if (!spectrum.observeFrequency) {\n        spectrum.observeFrequency = Number(dataValue);\n      }\n    } else if (canonicDataLabel === '.OBSERVENUCLEUS') {\n      if (!spectrum.xType) {\n        currentEntry.xType = dataValue.replace(/[^a-zA-Z0-9]/g, '');\n      }\n    } else if (canonicDataLabel === '$OFFSET') {\n      // OFFSET for Bruker spectra\n      currentEntry.shiftOffsetNum = 0;\n      if (!spectrum.shiftOffsetVal) {\n        spectrum.shiftOffsetVal = Number(dataValue);\n      }\n    } else if (canonicDataLabel === '$REFERENCEPOINT') {\n      // OFFSET for Varian spectra\n      // if we activate this part it does not work for ACD specmanager\n      //         } else if (canonicDataLabel=='.SHIFTREFERENCE') {   // OFFSET FOR Bruker Spectra\n      //                 var parts = dataValue.split(/ *, */);\n      //                 currentEntry.shiftOffsetNum = parseInt(parts[2].trim());\n      //                 spectrum.shiftOffsetVal = Number(parts[3].trim());\n    } else if (canonicDataLabel === 'VARNAME') {\n      currentEntry.ntuples.varname = dataValue.split(ntuplesSeparatorRegExp);\n    } else if (canonicDataLabel === 'SYMBOL') {\n      currentEntry.ntuples.symbol = dataValue.split(ntuplesSeparatorRegExp);\n    } else if (canonicDataLabel === 'VARTYPE') {\n      currentEntry.ntuples.vartype = dataValue.split(ntuplesSeparatorRegExp);\n    } else if (canonicDataLabel === 'VARFORM') {\n      currentEntry.ntuples.varform = dataValue.split(ntuplesSeparatorRegExp);\n    } else if (canonicDataLabel === 'VARDIM') {\n      currentEntry.ntuples.vardim = convertToFloatArray(\n        dataValue.split(ntuplesSeparatorRegExp),\n      );\n    } else if (canonicDataLabel === 'UNITS') {\n      currentEntry.ntuples.units = dataValue.split(ntuplesSeparatorRegExp);\n    } else if (canonicDataLabel === 'FACTOR') {\n      currentEntry.ntuples.factor = convertToFloatArray(\n        dataValue.split(ntuplesSeparatorRegExp),\n      );\n    } else if (canonicDataLabel === 'FIRST') {\n      currentEntry.ntuples.first = convertToFloatArray(\n        dataValue.split(ntuplesSeparatorRegExp),\n      );\n    } else if (canonicDataLabel === 'LAST') {\n      currentEntry.ntuples.last = convertToFloatArray(\n        dataValue.split(ntuplesSeparatorRegExp),\n      );\n    } else if (canonicDataLabel === 'MIN') {\n      currentEntry.ntuples.min = convertToFloatArray(\n        dataValue.split(ntuplesSeparatorRegExp),\n      );\n    } else if (canonicDataLabel === 'MAX') {\n      currentEntry.ntuples.max = convertToFloatArray(\n        dataValue.split(ntuplesSeparatorRegExp),\n      );\n    } else if (canonicDataLabel === '.NUCLEUS') {\n      if (currentEntry.ntuples) {\n        currentEntry.ntuples.nucleus = dataValue.split(ntuplesSeparatorRegExp);\n      }\n    } else if (canonicDataLabel === 'PAGE') {\n      spectrum.page = dataValue.trim();\n      spectrum.pageValue = Number(dataValue.replace(/^.*=/, ''));\n      spectrum.pageSymbol = spectrum.page.replace(/[=].*/, '');\n    } else if (canonicDataLabel === 'RETENTIONTIME') {\n      spectrum.pageValue = Number(dataValue);\n    } else if (isMSField(canonicDataLabel)) {\n      spectrum[convertMSFieldToLabel(canonicDataLabel)] = dataValue;\n    } else if (canonicDataLabel === 'SAMPLEDESCRIPTION') {\n      spectrum.sampleDescription = dataValue;\n    } else if (canonicDataLabel.startsWith('$NUC')) {\n      if (!currentEntry.tmp[canonicDataLabel] && !dataValue.includes('off')) {\n        currentEntry.tmp[canonicDataLabel] = dataValue.replace(/[<>]/g, '');\n      }\n    } else if (canonicDataLabel === 'END') {\n      currentEntry = parentsStack.pop();\n    }\n\n    if (\n      currentEntry &&\n      currentEntry.info &&\n      currentEntry.meta &&\n      canonicDataLabel.match(options.keepRecordsRegExp)\n    ) {\n      let value = dataValue.trim();\n      let target, label;\n      if (dataLabel.startsWith('$')) {\n        label = options.canonicMetadataLabels\n          ? canonicDataLabel.substring(1)\n          : dataLabel.substring(1);\n        target = currentEntry.meta;\n      } else {\n        label = options.canonicDataLabels ? canonicDataLabel : dataLabel;\n        target = currentEntry.info;\n      }\n\n      if (options.dynamicTyping) {\n        value = parseString(value);\n      }\n      if (target[label]) {\n        if (!Array.isArray(target[label])) {\n          target[label] = [target[label]];\n        }\n        target[label].push(value);\n      } else {\n        target[label] = value;\n      }\n    }\n  }\n\n  profiling(result, 'Finished parsing', options);\n\n  postProcessing(entriesFlat, result, options);\n\n  profiling(result, 'Total time', options);\n\n  /*\n  if (result.children && result.children.length>0) {\n    result = { ...result, ...result.children[0] };\n  }\n  */\n  result.entries = tmpResult.children;\n  result.flatten = entriesFlat;\n\n  return result;\n}\n","import { ensureString } from 'ensure-string';\n\n/**\n *\n * @typedef {object} CreateTreeOptions\n * @property {boolean} [flatten=false]\n */\n\n/**\n *\n * @typedef {object} Tree\n * @property {string} title\n * @property {string} jcamp\n * @property {Tree[]} [children]\n */\n\n/**\n * Parse the jcamp to extract the structure as a tree.\n *\n * @param {string|ArrayBuffer|Uint8Array} jcamp\n * @param {CreateTreeOptions} [options={}]\n * @returns {Tree[]}\n */\nexport function createTree(jcamp, options = {}) {\n  jcamp = ensureString(jcamp);\n  const { flatten = false } = options;\n  if (typeof jcamp !== 'string') {\n    throw new TypeError('the JCAMP should be a string');\n  }\n\n  let lines = jcamp.split(/[\\r\\n]+/);\n  let flat = [];\n  let stack = [];\n  let result = [];\n  let current;\n  let ntupleLevel = 0;\n\n  let spaces = jcamp.includes('## ');\n\n  for (let i = 0; i < lines.length; i++) {\n    let line = lines[i];\n    let labelLine = spaces ? line.replace(/ /g, '') : line;\n\n    if (labelLine.substring(0, 9) === '##NTUPLES') {\n      ntupleLevel++;\n    }\n\n    if (labelLine.substring(0, 7) === '##TITLE') {\n      let title = [labelLine.substring(8).trim()];\n      for (let j = i + 1; j < lines.length; j++) {\n        if (lines[j].startsWith('##')) {\n          break;\n        } else {\n          title.push(lines[j].trim());\n        }\n      }\n      stack.push({\n        title: title.join('\\n'),\n        jcamp: `${line}\\n`,\n        children: [],\n      });\n      current = stack[stack.length - 1];\n      flat.push(current);\n    } else if (labelLine.substring(0, 5) === '##END' && ntupleLevel === 0) {\n      current.jcamp += `${line}\\n`;\n      let finished = stack.pop();\n      if (stack.length !== 0) {\n        current = stack[stack.length - 1];\n        current.children.push(finished);\n      } else {\n        current = undefined;\n        result.push(finished);\n      }\n    } else if (current && current.jcamp) {\n      current.jcamp += `${line}\\n`;\n      let match = labelLine.match(/^##(.*?)=(.+)/);\n      if (match) {\n        let canonicDataLabel = match[1].replace(/[ _-]/g, '').toUpperCase();\n        if (canonicDataLabel === 'DATATYPE') {\n          current.dataType = match[2].trim();\n        }\n        if (canonicDataLabel === 'DATACLASS') {\n          current.dataClass = match[2].trim();\n        }\n      }\n    }\n\n    if (labelLine.substring(0, 5) === '##END' && ntupleLevel > 0) {\n      ntupleLevel--;\n    }\n  }\n  if (flatten) {\n    flat.forEach((entry) => {\n      entry.children = undefined;\n    });\n    return flat;\n  } else {\n    return result;\n  }\n}\n"],"names":["ensureString","blob","options","arguments","length","undefined","ArrayBuffer","isView","encoding","guessEncoding","TextDecoder","decode","TypeError","uint8","Uint8Array","buffer","byteOffset","byteLength","buf","i","len","isutf8","parseString","value","lowercase","toLowerCase","number","Number","includes","isNaN","GC_MS_FIELDS","complexChromatogram","result","spectra","chromatogram","times","Array","series","ms","dimension","data","existingGCMSFields","label","convertMSFieldToLabel","push","spectrum","pageValue","j","x","y","isMSField","canonicDataLabel","indexOf","replace","convertToFloatArray","stringArray","floatArray","fastParseXYData","yFactor","deltaX","isXYdata","currentData","ascii","currentX","firstX","currentY","firstY","endLine","charCodeAt","newLine","isDifference","isLastDifference","lastDifference","isDuplicate","inComment","currentValue","lastValue","isNegative","inValue","skipFirstValue","decimalPosition","Math","pow","duplicate","ascii2","removeCommentRegExp","peakTableSplitRegExp","parsePeakTable","isPeaktable","variables","Object","keys","numberOfVariables","forEach","variable","lines","split","values","trim","logs","parseXYZ","xFactor","parseXY","key","parseXYA","isXYAdata","map","fields","parseFloat","toString","prototype","a","d","e","f","g","h","c","b","_ref","module","exports","window","median","input","call","endsWith","quickSelectMedian","slice","add2D","zData","minZ","maxZ","ySize","xSize","z","lastX","lastY","reverse","medians","row","Float64Array","from","getMedian","minX","min","maxX","max","minY","maxY","noise","convertTo3DZ","noContour","contourLines","povarHeight0","povarHeight1","povarHeight2","povarHeight3","isOver0","isOver1","isOver2","isOver3","pAx","pAy","pBx","pBy","lineZValue","nbSubSpectra","nbPovars","x0","dx","y0","dy","iter","nbContourLevels","contourLevels","level","contourLevel","side","factor","noiseMultiplier","exp","zValue","iSubSpectra","subSpectra","subSpectraAfter","povar","segments","generateContourLines","minMax","gyromagneticRatio","profiling","action","logger","trace","time","Date","now","start","simpleChromatogram","intensity","postProcessing","entriesFlat","entry","observeFrequency","shiftOffsetVal","ntuples","symbol","xUnits","toUpperCase","shift","nucleus","match","tmp","$NUC2","f2index","$NUC1","yType","unit","pageSymbolIndex","pageSymbol","units","Error","ratio0","ratio1","ratio","postProcessingNMR","newNtuples","twoD","wantXY","keepSpectra","prepareNtuplesDatatable","currentEntry","kind","xIndex","yIndex","firstVariable","secondVariable","charAt","lowerCaseSymbol","index","first","last","vardim","nbPoints","varname","yUnits","prepareSpectrum","ntuplesSeparatorRegExp","defaultOptions","keepRecordsRegExp","canonicDataLabels","canonicMetadataLabels","dynamicTyping","withoutXY","jcamp","debug","entries","tmpResult","children","parentsStack","ldrs","ldr","position","dataLabel","substring","dataValue","infos","datatable","parentEntry","info","meta","title","dataType","dataClass","xType","shiftOffsetNum","vartype","varform","page","sampleDescription","startsWith","pop","target","isArray","flatten","current","flat","stack","ntupleLevel","spaces","line","labelLine","join","finished"],"mappings":"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"}