/** * Circle feed — the artists this site features (auto-boosts), sourced from * ActivityPub. Cards link to the source post. Available whenever the site * auto-boosts at least one account; otherwise next() -> postsRoutes. * GET /cirkel */ import express from 'express'; import { renderPage } from '../middleware/render.js'; import { apEnabled } from '../services/SettingsService.js'; import ActivityPubService from '../services/ActivityPubService.js'; const router = express.Router(); function safeUrl(u) { return typeof u === 'string' && /^https?:\/\//i.test(u) ? u : null; } function safeJson(s) { try { return s ? JSON.parse(s) : []; } catch { return []; } } // The cover image + (separately) a cover video from a remote note's media. NEVER use a video/audio // item as the cover image — that produced a broken for an animated cover that federated as an // MP4 (the video becomes a