import { Account } from "~/shared/types/account"; import { Schedule, TimeSlot } from "~/shared/types/schedule"; const locations = [ { name: "Stage", description: "Inside the main building." }, { name: "Clubhouse", description: "That big red building in the middle of the park." }, { name: "Summerhouse", description: "Next to the campfire by the lake" }, { name: "Campfire", description: "Next to the big tree by the lake." }, { name: "Outside", description: "Takes place somewhere outside." } ] const events = [ { name: "Arcade", description: "Play retro games!", slots: [ "d1 12:00 4h clubhouse", "d2 12:00 4h clubhouse", "d3 12:00 4h clubhouse", ] }, { name: "Bonfire Stories", description: "Share your stories as we sit cosily around the campfire.", slots: ["d2 18:00 2h campfire"] }, { name: "DJ Alpha", slots: ["d2 20:00 2h stage"] }, { name: "DJ Bravo", slots: ["d3 20:00 2h stage"] }, { name: "DJ Charlie", slots: ["d3 22:00 2h stage"] }, { name: "Fursuit Games", description: "Playful time for the suiters.", slots: ["d4 18:00 2h clubhouse"], }, { name: "Fishing Trip", slots: ["d3 12:00 3h30m outside"]}, { name: "Opening", slots: ["d1 18:30 1h30m stage"]}, { name: "Closing", slots: ["d5 16:00 1h stage"]}, { name: "Board Games", slots: [ "d1 12:00 4h summerhouse", "d2 12:00 4h summerhouse", "d3 12:00 4h summerhouse", "d4 12:00 4h summerhouse", ] }, { name: "📷meet", slots: ["d3 19:00 1h10m summerhouse"]}, { name: "Karaoke", slots: [ "d3 21:00 2h clubhouse", "d4 21:00 2h clubhouse", ], }, { name: "Dance", slots: ["d1 20:00 3h stage"]}, { name: "Charity Auction", slots: ["d4 13:00 2h stage"]}, { name: "Tournament", slots: ["d2 17:00 2h stage"]}, { name: "Canoe Trip", slots: ["d4 11:00 4h30m outside"]}, { name: "Dinner", slots: [ "d1 16:00 1h campfire", "d2 16:00 1h campfire", "d3 16:00 1h campfire", "d4 16:00 1h campfire", ], }, { name: "Film Night", slots: ["d4 21:00 2h stage"]}, { name: "Photo", slots: ["d3 18:00 45m stage"]}, { name: "Artist Alley", slots: ["d4 12:00 4h clubhouse"]}, { name: "Feedback Panel", slots: ["d5 18:00 4h clubhouse"]}, ]; function toId(name: string) { return name.toLowerCase().replace(/ /g, "-"); } function toIso(date: Date) { return date.toISOString().replace(":00.000Z", "Z"); } function toSlot(origin: Date, id: string, shorthand: string, index: number): TimeSlot { const [day, start, duration, location] = shorthand.split(" "); const [startHours, startMinutes] = start.split(":").map(time => parseInt(time, 10)); const dayNumber = parseInt(day.slice(1)); const startDate = new Date(origin); startDate.setUTCDate(startDate.getUTCDate() + dayNumber); startDate.setUTCHours(startDate.getUTCHours() + startHours); startDate.setUTCMinutes(startDate.getUTCMinutes() + startMinutes); const [_, durationHours, durationMinutes] = /(?:(\d+)h)?(?:(\d+)m)?/.exec(duration)!; const durationTotal = parseInt(durationHours ?? "0") * 60 + parseInt(durationMinutes ?? "0") const endDate = new Date(startDate.getTime() + durationTotal * 60e3); return { id: `${id}-${index}`, start: toIso(startDate), end: toIso(endDate), locations: [location], }; } export function generateDemoSchedule(): Schedule { const origin = new Date(); const utcOffset = 1; origin.setUTCDate(origin.getUTCDate() - origin.getUTCDay() + 1); // Go to Monday origin.setUTCHours(utcOffset); origin.setUTCMinutes(0); origin.setUTCSeconds(0); origin.setUTCMilliseconds(0); return { events: events.map( ({ name, description, slots }) => ({ id: toId(name), name, description, slots: slots.map((shorthand, index) => toSlot(origin, toId(name), shorthand, index)) }) ), locations: locations.map( ({ name, description }) => ({ id: toId(name), name, description }) ), }; } const names = [ "Leo", "Lisa", "Jack", "Emily", "Roy", "Sofia", "Adam", "Eve", "Max", "Rose", "Hugo", "Maria", "David", "Zoe", "Hunter", "Ria", "Sonny", "Amy", "Kai", "Megan", "Toby", "Katie", "Bob", "Lucy", ]; // MINSTD random implementation for reproducible random numbers. let seed = 1; function random() { const a = 48271; const c = 0; const m = 2 ** 31 -1; return (seed = (a * seed + c) % m | 0) / 2 ** 31; } export function generateDemoAccounts(): Account[] { seed = 1; const accounts: Account[] = []; for (const name of names) { accounts.push({ id: accounts.length, name, type: (["regular", "crew", "admin"] as const)[Math.floor(random() ** 5 * 3)], }); } // These have a much higher probability of being in someone's interested list. const desiredEvent = ["opening", "closing", "fursuit-games"]; for (const account of accounts) { const interestedIds: string[] = []; for (const id of desiredEvent) { if (random() < 0.5) { interestedIds.push(id); } } const eventsToAdd = Math.floor(random() * 10); while (interestedIds.length < eventsToAdd) { const event = events[Math.floor(random() * events.length)]; const eventId = toId(event.name); if (interestedIds.some(id => id.replace(/-\d+$/, "") === eventId)) { continue; } if (event.slots.length === 1 || random() < 0.8) { interestedIds.push(toId(event.name)) } else { for (const index of event.slots.map((_, index) => index)) { if (random() < 0.5) { interestedIds.push(toId(`${toId(event.name)}-${index}`)); } } } } if (interestedIds.length) { account.interestedIds = interestedIds; } } return accounts; }