mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-20 10:14:01 -04:00
106 lines
3.3 KiB
JavaScript
106 lines
3.3 KiB
JavaScript
function normalize(rows, start, end) {
|
|
if (!Array.isArray(rows))
|
|
return [];
|
|
const samples = rows.filter(row => Array.isArray(row) && row.length >= 3 && row.every(value => typeof value === "number" && isFinite(value)) && row[0] >= start && row[0] <= end && row[1] >= 0 && row[1] <= 100);
|
|
samples.sort((a, b) => a[0] - b[0]);
|
|
return samples.filter((sample, index) => index === samples.length - 1 || sample[0] !== samples[index + 1][0]);
|
|
}
|
|
|
|
function windowSamples(rows, start, end, current) {
|
|
const samples = normalize(rows, 0, end);
|
|
const visible = samples.filter(sample => sample[0] >= start);
|
|
const previous = samples.filter(sample => sample[0] < start).pop();
|
|
if (previous && visible[0]?.[0] !== start)
|
|
visible.unshift([start, previous[1], previous[2]]);
|
|
const latest = normalize([current], end, end)[0];
|
|
if (!latest)
|
|
return visible;
|
|
if (visible[visible.length - 1]?.[0] === end)
|
|
visible.pop();
|
|
visible.push(latest);
|
|
return visible;
|
|
}
|
|
|
|
function kind(sample, lowThreshold) {
|
|
switch (sample[2]) {
|
|
case 1:
|
|
case 4:
|
|
case 5:
|
|
return "plugged";
|
|
default:
|
|
return sample[1] <= lowThreshold ? "low" : "normal";
|
|
}
|
|
}
|
|
|
|
function segments(samples, lowThreshold) {
|
|
const result = [];
|
|
let segment = null;
|
|
for (const sample of samples) {
|
|
if (sample[2] === 0) {
|
|
segment = null;
|
|
continue;
|
|
}
|
|
const sampleKind = kind(sample, lowThreshold);
|
|
if (!segment || segment.kind !== sampleKind) {
|
|
if (segment)
|
|
segment.samples.push(sample);
|
|
segment = {
|
|
kind: sampleKind,
|
|
samples: []
|
|
};
|
|
result.push(segment);
|
|
}
|
|
segment.samples.push(sample);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// upowerd writes a state 0 marker every time it loads history, at boot among others
|
|
function gaps(samples) {
|
|
const result = [];
|
|
let last = null;
|
|
let broken = false;
|
|
for (const sample of samples) {
|
|
if (sample[2] === 0) {
|
|
broken = last !== null;
|
|
continue;
|
|
}
|
|
if (broken)
|
|
result.push([last, sample]);
|
|
broken = false;
|
|
last = sample;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function pointAt(samples, time, snap) {
|
|
let nearest = null;
|
|
for (const sample of samples) {
|
|
if (sample[2] !== 0 && (!nearest || Math.abs(sample[0] - time) < Math.abs(nearest[0] - time)))
|
|
nearest = sample;
|
|
}
|
|
if (!nearest)
|
|
return null;
|
|
if (Math.abs(nearest[0] - time) <= snap)
|
|
return nearest;
|
|
const next = samples.findIndex(sample => sample[0] >= time);
|
|
if (next <= 0)
|
|
return null;
|
|
const before = samples[next - 1];
|
|
const after = samples[next];
|
|
if (before[2] === 0 || after[2] === 0)
|
|
return [time, 0, 0];
|
|
return [time, before[1] + (after[1] - before[1]) * (time - before[0]) / (after[0] - before[0]), before[2]];
|
|
}
|
|
|
|
function ticks(start, end, hours) {
|
|
const tick = new Date(start * 1000);
|
|
tick.setHours(tick.getHours() - tick.getHours() % hours, 0, 0, 0);
|
|
const result = [];
|
|
for (; tick.getTime() <= end * 1000; tick.setHours(tick.getHours() + hours)) {
|
|
if (tick.getTime() >= start * 1000)
|
|
result.push(tick.getTime() / 1000);
|
|
}
|
|
return result;
|
|
}
|