// The new P5 namespace is the validated DAILY leaf, never a twelve-hex name // alone. Plain {limit,since} keys remain legacy account limits. const ID = /^[a-f0-9]{12}$/; const RESET = /^([01]\d|2[0-3]):[0-5]\d$/; const ZONE = /^[A-Za-z][A-Za-z0-9_+-]*(\/[A-Za-z0-9_+-]+)*$/; const SINCE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/; export function isDailyModelQuota(key, value) { if (typeof key !== 'string' || !ID.test(key) || !value || typeof value !== 'object' || Array.isArray(value) || Object.keys(value).some(k => !['limit','since','reset','timeZone'].includes(k)) || !Number.isSafeInteger(value.limit) || value.limit < 0 || typeof value.since !== 'string' || !SINCE.test(value.since) || Number.isNaN(Date.parse(value.since)) || new Date(value.since).toISOString() !== value.since || typeof value.reset !== 'string' || !RESET.test(value.reset) || typeof value.timeZone !== 'string' || !ZONE.test(value.timeZone)) return false; try { new Intl.DateTimeFormat('en-US', { timeZone:value.timeZone }); return true; } catch { return false; } }