data = pipe(
textarea,
($) =>
$.split("\n")
.map((l) =>
l.match(
/@@@[!-]?\s*(?<context>.*?)\s+(?<counter>[-\d\.]+)?\s+(?<timer>\d+)/
)
)
.filter(Boolean)
.map((match) => ({
...match.groups,
counter: +match.groups.counter,
timer: +match.groups.timer
})),
($) => {
let offset = 0;
let rv = [{ ...$[0] }];
for (let i = 1; i < $.length; i++) {
if ($[i].timer < $[i - 1].timer) offset += 10000;
rv.push({ ...$[i], timer: $[i].timer + offset });
}
return rv;
},
($) => {
let min = $[0].timer;
return $.map((d) => ({ ...d, timer: d.timer - min }));
},
($) => {
let rv = [];
for (let i = 0; i < $.length; i++) {
let nextOfType = $.slice(i + 1).find((d) => d.context === $[i].context);
let row = {
...$[i],
start: $[i].timer,
end: nextOfType?.timer ?? $[i].timer
};
delete row.timer;
rv.push(row);
}
return rv;
},
($) => $.map((d) => ({ ...d, duration: d.end - d.start })),
($) => $.filter((d) => d.duration >= minDuration),
($) =>
$.map((d) => ({
...d,
label: `${d.context}${collapse ? "" : ` ${d.counter}`}`
})),
...(search.length > 0
? [
($) =>
$.filter((d) => d.label.toLowerCase().includes(search.toLowerCase()))
]
: [])
)