Files
lynchmark/tests/7_scheduler/outputs/openrouter_sherlock-think-alpha.js
2025-11-18 17:37:06 +00:00

71 lines
2.3 KiB
JavaScript

async function findAvailableSlots(cal1, cal2, cons) {
const { DateTime: DT, Interval: IV, Duration: D } = await import('https://esm.sh/luxon@3.4.4');
const dur = D.fromObject({ minutes: cons.durationMinutes });
const sr = IV.fromISO(`${cons.searchRange.start}/${cons.searchRange.end}`);
const [h1, m1] = cons.workHours.start.split(':').map(Number);
const [h2, m2] = cons.workHours.end.split(':').map(Number);
let busies = [...cal1, ...cal2].map(e => IV.fromISO(`${e.start}/${e.end}`))
.filter(iv => iv?.overlaps(sr))
.map(iv => iv.intersection(sr))
.filter(iv => iv && !iv.isEmpty)
.sort((a, b) => a.start.toMillis() - b.start.toMillis());
let merged = [];
for (let iv of busies) {
if (!merged.length) {
merged.push(iv);
continue;
}
let last = merged[merged.length - 1];
if (last.end >= iv.start) {
const newEnd = last.end.toMillis() > iv.end.toMillis() ? last.end : iv.end;
merged[merged.length - 1] = IV.fromDateTimes(last.start, newEnd);
} else {
merged.push(iv);
}
}
let frees = [];
let prevEnd = sr.start;
for (let busy of merged) {
if (prevEnd < busy.start) {
frees.push(IV.fromDateTimes(prevEnd, busy.start));
}
prevEnd = busy.end;
}
if (prevEnd < sr.end) {
frees.push(IV.fromDateTimes(prevEnd, sr.end));
}
let workFrees = [];
for (let free of frees) {
let cur = free.start;
while (cur < free.end) {
let dayS = cur.startOf('day');
let dayE = dayS.plus({ days: 1 });
let dInt = IV.fromDateTimes(dayS, dayE);
let dayFree = free.intersection(dInt);
if (dayFree && !dayFree.isEmpty) {
let wS = dayS.plus({ hours: h1, minutes: m1 });
let wE = dayS.plus({ hours: h2, minutes: m2 });
let wInt = IV.fromDateTimes(wS, wE);
let wf = dayFree.intersection(wInt);
if (wf && !wf.isEmpty) {
workFrees.push(wf);
}
}
cur = dayE;
}
}
let slots = [];
const dMs = dur.toMillis();
for (let wf of workFrees) {
let remMs = wf.end.toMillis() - wf.start.toMillis();
let n = Math.floor(remMs / dMs);
let fs = wf.start;
for (let i = 0; i < n; i++) {
let ss = fs.plus(D.fromMillis(i * dMs));
let se = ss.plus(dur);
slots.push({ start: ss.toISO(), end: se.toISO() });
}
}
return slots;
}
export default findAvailableSlots;