export const CHICKEN_CHILL_FACTOR_POINTS = [ { age: 0, factor: 8 }, { age: 1, factor: 8 }, { age: 7, factor: 7 }, { age: 14, factor: 6 }, { age: 21, factor: 4.5 }, { age: 28, factor: 3.5 }, { age: 35, factor: 3.5 }, { age: 42, factor: 3 }, ] as const; export function chickenChillFactorFromAge(day: number | null | undefined): number | null { const age = Number(day); if (!Number.isFinite(age) || age < 0) return null; const firstPoint = CHICKEN_CHILL_FACTOR_POINTS[0]!; if (age <= firstPoint.age) return firstPoint.factor; for (let idx = 1; idx < CHICKEN_CHILL_FACTOR_POINTS.length; idx += 1) { const previousPoint = CHICKEN_CHILL_FACTOR_POINTS[idx - 1]!; const nextPoint = CHICKEN_CHILL_FACTOR_POINTS[idx]!; if (age > nextPoint.age) continue; const ageRange = nextPoint.age - previousPoint.age; if (ageRange <= 0) return nextPoint.factor; const progress = (age - previousPoint.age) / ageRange; return previousPoint.factor + (nextPoint.factor - previousPoint.factor) * progress; } return CHICKEN_CHILL_FACTOR_POINTS[CHICKEN_CHILL_FACTOR_POINTS.length - 1]!.factor; } export type ExperienceCalc = { averageTemp: number | null; windSpeed: number | null; humidity: number | null; humidityAdjustment: number | null; chillFactor: number | null; chillEffect: number | null; experienceTemp: number | null; }; export function computeExperienceCalc(args: { averageTemp: number | null | undefined; windSpeed: number | null | undefined; humidity: number | null | undefined; dayAge: number | null | undefined; }): ExperienceCalc { const toNumber = (value: number | null | undefined): number | null => value != null && Number.isFinite(Number(value)) ? Number(value) : null; const averageTemp = toNumber(args.averageTemp); const windSpeed = toNumber(args.windSpeed); const humidity = toNumber(args.humidity); const chillFactor = chickenChillFactorFromAge(args.dayAge); const humidityAdjustment = humidity === null ? null : (humidity - 70) / 5; const chillEffect = windSpeed !== null && chillFactor !== null && humidityAdjustment !== null ? windSpeed * chillFactor - humidityAdjustment : null; const experienceTemp = averageTemp !== null && chillEffect !== null ? averageTemp - chillEffect : null; return { averageTemp, windSpeed, humidity, humidityAdjustment, chillFactor, chillEffect, experienceTemp, }; } export function formatChillFactor(value: number | null | undefined): string { if (value === null || value === undefined || !Number.isFinite(Number(value))) return '--'; return Number(value).toFixed(3).replace('.', ',').replace(/0+$/, '').replace(/,$/, ''); }