| |
|
|
| |
| function parseCSV(str) { |
| var arr = []; |
| var quote = false; |
|
|
| |
| for (var row = 0, col = 0, c = 0; c < str.length; c++) { |
| var cc = str[c], nc = str[c + 1]; |
| arr[row] = arr[row] || []; |
| arr[row][col] = arr[row][col] || ''; |
|
|
| |
| |
| |
| if (cc == '"' && quote && nc == '"') { arr[row][col] += cc; ++c; continue; } |
|
|
| |
| if (cc == '"') { quote = !quote; continue; } |
|
|
| |
| if (cc == ',' && !quote) { ++col; continue; } |
|
|
| |
| |
| if (cc == '\r' && nc == '\n' && !quote) { ++row; col = 0; ++c; continue; } |
|
|
| |
| |
| if (cc == '\n' && !quote) { ++row; col = 0; continue; } |
| if (cc == '\r' && !quote) { ++row; col = 0; continue; } |
|
|
| |
| arr[row][col] += cc; |
| } |
| return arr; |
| } |
|
|
| |
| async function readFile(filePath, json = false, cache = false) { |
| if (!cache) |
| filePath += `?${new Date().getTime()}`; |
| |
| let response = await fetch(`file=${filePath}`); |
|
|
| if (response.status != 200) { |
| console.error(`Error loading file "${filePath}": ` + response.status, response.statusText); |
| return null; |
| } |
|
|
| if (json) |
| return await response.json(); |
| else |
| return await response.text(); |
| } |
|
|
| |
| async function loadCSV(path) { |
| let text = await readFile(path); |
| return parseCSV(text); |
| } |
|
|
| |
| var dbTimeOut; |
| const debounce = (func, wait = 300) => { |
| return function (...args) { |
| if (dbTimeOut) { |
| clearTimeout(dbTimeOut); |
| } |
|
|
| dbTimeOut = setTimeout(() => { |
| func.apply(this, args); |
| }, wait); |
| } |
| } |
|
|
| |
| function difference(a, b) { |
| if (a.length == 0) { |
| return b; |
| } |
| if (b.length == 0) { |
| return a; |
| } |
|
|
| return [...b.reduce((acc, v) => acc.set(v, (acc.get(v) || 0) - 1), |
| a.reduce((acc, v) => acc.set(v, (acc.get(v) || 0) + 1), new Map()) |
| )].reduce((acc, [v, count]) => acc.concat(Array(Math.abs(count)).fill(v)), []); |
| } |
|
|
| function escapeRegExp(string) { |
| return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); |
| } |
| function escapeHTML(unsafeText) { |
| let div = document.createElement('div'); |
| div.textContent = unsafeText; |
| return div.innerHTML; |
| } |
|
|
| |
| async function processQueue(queue, context, ...args) { |
| for (let i = 0; i < queue.length; i++) { |
| await queue[i].call(context, ...args); |
| } |
| } |
| |
| async function processQueueReturn(queue, context, ...args) |
| { |
| let qeueueReturns = []; |
| for (let i = 0; i < queue.length; i++) { |
| let returnValue = await queue[i].call(context, ...args); |
| if (returnValue) |
| qeueueReturns.push(returnValue); |
| } |
| return qeueueReturns; |
| } |
| |
| async function processParsers(textArea, prompt) { |
| |
| let matchingParsers = PARSERS.filter(parser => parser.triggerCondition()); |
| |
| if (matchingParsers.length === 0) { |
| return null; |
| } |
|
|
| let parseFunctions = matchingParsers.map(parser => parser.parse); |
| |
| return await processQueueReturn(parseFunctions, null, textArea, prompt); |
| } |