const FALLBACK_MANIFEST = { variants: { mobile: { folder: 'mobile-image', images: [] }, desktop: { folder: 'desketop-image', images: [] }, }, }; export async function loadManifest(request) { try { const response = await fetch(new URL('/manifest.json', request.url)); if (!response.ok) return FALLBACK_MANIFEST; return await response.json(); } catch { return FALLBACK_MANIFEST; } } export function detectVariant(request) { const url = new URL(request.url); const params = url.searchParams; const mode = (params.get('mode') || 'auto').toLowerCase(); const orientation = (params.get('orientation') || '').toLowerCase(); const device = (params.get('device') || '').toLowerCase(); const ua = (request.headers.get('user-agent') || '').toLowerCase(); const chMobile = request.headers.get('sec-ch-ua-mobile'); if (mode === 'mobile' || mode === 'desktop') return mode; if (orientation === 'portrait' || orientation === 'vertical') return 'mobile'; if (orientation === 'landscape' || orientation === 'horizontal') return 'desktop'; if (device === 'mobile' || device === 'desktop') return device; if (chMobile === '?1') return 'mobile'; if (chMobile === '?0') return 'desktop'; if (['mobi', 'android', 'iphone', 'ipad', 'ipod', 'phone'].some((token) => ua.includes(token))) return 'mobile'; return 'desktop'; } export function getVariantPayload(manifest, variant) { const data = manifest?.variants?.[variant] || {}; const folder = data.folder || (variant === 'mobile' ? 'mobile-image' : 'desketop-image'); const images = Array.isArray(data.images) ? data.images.filter((name) => typeof name === 'string' && name.toLowerCase().endsWith('.webp')) : []; return { folder, images }; } export function buildAssetUrl(request, folder, filename) { return new URL(`/${folder}/${filename}`, request.url).toString(); } export function pickRandom(items) { return items[Math.floor(Math.random() * items.length)]; }