{"version":3,"file":"jcampconverter.min.js","sources":["../src/complexChromatogram.js","../src/convertToFloatArray.js","../src/parse/fastParseXYData.js","../src/parse/parsePeakTable.js","../src/parse/parseXYA.js","../node_modules/is-any-array/src/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/nmr-processing/src/constants/gyromagneticRatio.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":["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] = parseFloat(\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(parseFloat(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 {\n      if (endLine) 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      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            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 parseFloat\n        currentData.x.push(parseFloat(values[j]) * spectrum.xFactor);\n        currentData.y.push(parseFloat(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(\n          parseFloat(values[j]),\n        );\n      }\n    } else {\n      result.logs.push(`Format error: ${values}`);\n    }\n  }\n}\n","export default function parseXYA(spectrum, value) {\n  let removeSymbolRegExp = /(\\(+|\\)+|<+|>+|\\s+)/g;\n\n  spectrum.isXYAdata = true;\n  let values;\n  let currentData = { x: [], y: [] };\n  spectrum.data = currentData;\n\n  let lines = value.split(/,? *,?[;\\r\\n]+ */);\n\n  for (let i = 1; i < lines.length; i++) {\n    values = lines[i].trim().replace(removeSymbolRegExp, '').split(',');\n    currentData.x.push(parseFloat(values[0]));\n    currentData.y.push(parseFloat(values[1]));\n  }\n}\n","const toString = Object.prototype.toString;\r\n\r\nexport default function isAnyArray(object) {\r\n  return toString.call(object).endsWith('Array]');\r\n}\r\n","(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 isArray from 'is-any-array';\nimport quickSelectMedian from 'median-quickselect';\n\nfunction median(input) {\n  if (!isArray(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 default median;\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: 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: minZ,\n    maxZ: 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","// sources:\n// https://en.wikipedia.org/wiki/Gyromagnetic_ratio\n\n// TODO: #13 can we have a better source and more digits ? @jwist\n\nexport 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","export default function profiling(result, action, options) {\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    delete entry.tmp;\n  }\n}\n","import { gyromagneticRatio } from 'nmr-processing';\n\nexport default function postProcessingNMR(entriesFlat) {\n  // specific NMR functions\n  let observeFrequency = 0;\n  let shiftOffsetVal = 0;\n\n  for (let entry of entriesFlat) {\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) {\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.startsWith('F') && !nucleus) {\n            if (symbol === 'F1') entry.ntuples.nucleus[i] = entry.tmp.$NUC2;\n            if (symbol === 'F2') entry.ntuples.nucleus[i] = entry.tmp.$NUC1;\n          }\n          if (symbol === 'F2') {\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 { 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]*/;\nconst numberRegExp = /^[-+]?[0-9]*\\.?[0-9]+(e[-+]?[0-9]+)?$/;\n\nclass Spectrum {}\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 *\n * @param {text} jcamp\n * @param {object} [options]\n * @param {number} [options.keepRecordsRegExp=/^$/] By default we don't keep meta information\n * @param {number} [options.canonicDataLabels=true] Canonize the Labels (uppercase without symbol)\n * @param {number} [options.canonicMetadataLabels=false] Canonize the metadata Labels (uppercase without symbol)\n * @param {number} [options.dynamicTyping=false] Convert numbers to Number\n * @param {number} [options.withoutXY=false] Remove the XY data\n * @param {number} [options.chromatogram=false] Special post-processing for GC / HPLC / MS\n * @param {number} [options.keepSpectra=false] Force to keep the spectra in case of 2D\n * @param {number} [options.noContour=false] Don't calculate countour in case of 2D\n * @param {number} [options.nbContourLevels=7] Number of positive / negative contour levels to calculate\n * @param {number} [options.noiseMultiplier=5] Define for 2D the level as 5 times the median as default\n * @param {number} [options.profiling=false] Add profiling information\n */\n\nexport default function convert(jcamp, options = {}) {\n  options = Object.assign({}, defaultOptions, options);\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 = new 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          spectrum.deltaX =\n            (spectrum.lastX - spectrum.firstX) / (spectrum.nbPoints - 1);\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          spectrum.deltaX =\n            (spectrum.lastX - spectrum.firstX) / (spectrum.nbPoints - 1);\n\n          fastParseXYData(spectrum, dataValue, result);\n        } else {\n          parsePeakTable(spectrum, dataValue, result);\n        }\n        currentEntry.spectra.push(spectrum);\n        spectrum = new 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 = new Spectrum();\n      }\n      continue;\n    }\n    if (canonicDataLabel === 'PEAKASSIGNMENTS') {\n      if (options.wantXY) {\n        if (dataValue.match(/.*(XYA).*/)) {\n          // ex: (XYA)\n          parseXYA(spectrum, dataValue);\n        }\n        currentEntry.spectra.push(spectrum);\n        spectrum = new 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.toLowerCase().indexOf('nd') > -1) {\n        currentEntry.twoD = true;\n      }\n    } else if (canonicDataLabel === 'NTUPLES') {\n      if (dataValue.toLowerCase().indexOf('nd') > -1) {\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 = parseFloat(dataValue);\n    } else if (canonicDataLabel === 'LASTX') {\n      spectrum.lastX = parseFloat(dataValue);\n    } else if (canonicDataLabel === 'FIRSTY') {\n      spectrum.firstY = parseFloat(dataValue);\n    } else if (canonicDataLabel === 'LASTY') {\n      spectrum.lastY = parseFloat(dataValue);\n    } else if (canonicDataLabel === 'NPOINTS') {\n      spectrum.nbPoints = parseFloat(dataValue);\n    } else if (canonicDataLabel === 'XFACTOR') {\n      spectrum.xFactor = parseFloat(dataValue);\n    } else if (canonicDataLabel === 'YFACTOR') {\n      spectrum.yFactor = parseFloat(dataValue);\n    } else if (canonicDataLabel === 'MAXX') {\n      spectrum.maxX = parseFloat(dataValue);\n    } else if (canonicDataLabel === 'MINX') {\n      spectrum.minX = parseFloat(dataValue);\n    } else if (canonicDataLabel === 'MAXY') {\n      spectrum.maxY = parseFloat(dataValue);\n    } else if (canonicDataLabel === 'MINY') {\n      spectrum.minY = parseFloat(dataValue);\n    } else if (canonicDataLabel === 'DELTAX') {\n      spectrum.deltaX = parseFloat(dataValue);\n    } else if (\n      canonicDataLabel === '.OBSERVEFREQUENCY' ||\n      canonicDataLabel === '$SFO1'\n    ) {\n      if (!spectrum.observeFrequency) {\n        spectrum.observeFrequency = parseFloat(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 = parseFloat(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 = parseFloat(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 = parseFloat(dataValue.replace(/^.*=/, ''));\n      spectrum.pageSymbol = spectrum.page.replace(/[=].*/, '');\n    } else if (canonicDataLabel === 'RETENTIONTIME') {\n      spectrum.pageValue = parseFloat(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        if (value.match(numberRegExp)) {\n          value = Number.parseFloat(value);\n        }\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","export default function createTree(jcamp, options = {}) {\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      }\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":["GC_MS_FIELDS","complexChromatogram","result","spectra","length","chromatogram","times","Array","series","ms","dimension","data","existingGCMSFields","i","label","convertMSFieldToLabel","push","spectrum","pageValue","j","parseFloat","x","y","isMSField","canonicDataLabel","indexOf","value","toLowerCase","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","removeSymbolRegExp","isXYAdata","toString","prototype","a","d","e","f","g","h","c","b","_ref","module","exports","window","median","input","object","call","endsWith","TypeError","quickSelectMedian","slice","add2D","options","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","time","Date","now","start","simpleChromatogram","intensity","postProcessing","entriesFlat","observeFrequency","shiftOffsetVal","entry","ntuples","symbol","xUnits","toUpperCase","includes","shift","nucleus","startsWith","tmp","$NUC2","$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","numberRegExp","Spectrum","defaultOptions","keepRecordsRegExp","canonicDataLabels","canonicMetadataLabels","dynamicTyping","withoutXY","jcamp","assign","entries","tmpResult","children","parentsStack","ldrs","ldr","position","dataLabel","substring","dataValue","infos","datatable","parentEntry","info","meta","title","dataType","dataClass","xType","shiftOffsetNum","vartype","varform","page","sampleDescription","pop","match","target","Number","isArray","flatten","current","flat","stack","ntupleLevel","spaces","line","labelLine","join","finished","undefined"],"mappings":"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"}