// Where a clip's source moment lives in the public archive. // // THIS IS THE CANONICAL DEFINITION. The same link was written out by hand in // three separate generators -- build-um.mjs and the two pipeline/ page builders // -- each of them embedding the origin, the channel slug and the lead-in as // literal text inside a string of client JS. Three copies of a URL that has // already been re-pointed once is three chances to re-point it incompletely. // // Plain JS with no dependencies on purpose: the generators are standalone // scripts run from a bare `node`, and must stay that way. The app side // (umtool/lib/archive.ts) imports these constants and builds the URL through // common/lib/momentUrl.ts, so there is one definition of WHERE and one // definition of HOW. export const ARCHIVE_ORIGIN = process.env.ARCHIVE_ORIGIN ?? "https://jeralyzer.pages.dev"; export const ARCHIVE_CHANNEL = process.env.ARCHIVE_CHANNEL ?? "the-quartering"; // A DELIBERATE lead-in: land three seconds before the moment so the um is heard // in context rather than starting mid-word. Removing it does not make the link // more accurate, it makes it unusable -- you arrive after the thing you came // to hear. Integer, which is what keeps floor(t) - LEAD_IN and floor(t - // LEAD_IN) the same number. export const LEAD_IN = 3; /** `https://…/?v=the-quartering%2F` — append the video id, then `&t=`. */ export function archiveMomentBase() { return `${ARCHIVE_ORIGIN}/?v=${encodeURIComponent(`${ARCHIVE_CHANNEL}/`)}`; } /** The viewer deep link for a source moment, with the lead-in applied. */ export function archiveMomentUrl(video, seconds) { const t = Math.max(0, Math.floor(seconds) - LEAD_IN); return `${archiveMomentBase()}${video}&t=${t}`; }