From 8b2147242e7716ae1f6124be3458faa5b684c235 Mon Sep 17 00:00:00 2001
From: Rohan Matta
Date: Thu, 20 Aug 2026 21:28:24 -0400
Subject: [PATCH 01/69] Explore ranking: widen candidate pool, smooth time
decay, org diversity cap, seeded daily nudge, popularity/org-history signals,
ranking docs
---
apps/web/src/actions/events.ts | 177 +++++++++++++++++++++++++++------
docs/ranking.md | 146 +++++++++++++++++++++++++++
2 files changed, 294 insertions(+), 29 deletions(-)
create mode 100644 docs/ranking.md
diff --git a/apps/web/src/actions/events.ts b/apps/web/src/actions/events.ts
index 241c098..51428fb 100644
--- a/apps/web/src/actions/events.ts
+++ b/apps/web/src/actions/events.ts
@@ -12,6 +12,7 @@ import {
gt,
ilike,
inArray,
+ interactions,
lt,
ne,
notifications,
@@ -45,6 +46,61 @@ export interface FeedEvent {
isSaved: boolean;
}
+// Upcoming events scored before slicing out the requested page — must be
+// well above any realistic page size so personalization has real candidates
+// to work with. See docs/ranking.md.
+const CANDIDATE_POOL_SIZE = 100;
+
+// An event is "soon" if it's within this many days. The first page always
+// includes at least SOON_QUOTA such events, even if their score is weak.
+const SOON_WINDOW_DAYS = 1;
+const SOON_QUOTA = 3;
+
+// Max events from one org before the rest get pushed later in the ranking.
+const ORG_DIVERSITY_CAP = 3;
+
+// Org affinity when you've RSVP'd to the org before but don't follow/belong
+// to it (full affinity is 1.0).
+const ORG_PAST_INTERACTION_AFFINITY = 0.5;
+
+// View count treated as "maximally popular" (log-scaled, caps at 1.0).
+const POPULARITY_VIEW_CAP = 50;
+const POPULARITY_WEIGHT = 0.5;
+
+// Small per-event nudge, seeded per user-per-day (not per request) so it
+// varies the feed over time without ever reshuffling on refresh.
+const RANDOM_WEIGHT = 0.5;
+
+// Deterministic pseudo-random value in [0, 1) for a seed string.
+function seededRandom(seed: string): number {
+ let hash = 0;
+ for (let i = 0; i < seed.length; i++) {
+ hash = (hash << 5) - hash + seed.charCodeAt(i);
+ hash |= 0;
+ }
+ return (hash >>> 0) / 0xffffffff;
+}
+
+function diversifyByOrg(list: T[], cap: number): T[] {
+ const counts = new Map();
+ const primary: T[] = [];
+ const deferred: T[] = [];
+ for (const item of list) {
+ if (!item.orgId) {
+ primary.push(item);
+ continue;
+ }
+ const count = counts.get(item.orgId) ?? 0;
+ if (count < cap) {
+ counts.set(item.orgId, count + 1);
+ primary.push(item);
+ } else {
+ deferred.push(item);
+ }
+ }
+ return [...primary, ...deferred];
+}
+
export async function getFeedEvents(params?: {
search?: string;
tags?: string[];
@@ -96,6 +152,20 @@ export async function getFeedEvents(params?: {
...memberOrgRows.map((o) => o.orgId),
]);
+ // Orgs the user has RSVP'd to before but doesn't follow/belong to — a
+ // weaker org-affinity signal than myOrgIds.
+ const interactedOrgRows = await db
+ .select({ orgId: events.orgId })
+ .from(rsvps)
+ .innerJoin(events, eq(rsvps.eventId, events.id))
+ .where(eq(rsvps.userId, userId));
+ const interactedOrgIds = new Set(
+ interactedOrgRows.map((r) => r.orgId).filter((id): id is string => id !== null),
+ );
+
+ // Day string (UTC) that seeds the random nudge — flips once a day.
+ const today = new Date().toISOString().slice(0, 10);
+
// Build base query conditions — only show published events in the feed
const conditions = [gt(events.datetime, new Date()), eq(events.status, "published")];
@@ -157,7 +227,9 @@ export async function getFeedEvents(params?: {
.where(and(...conditions));
const total = countResult?.count ?? 0;
- // Fetch events with scoring
+ // Score a bounded pool of upcoming events, not just the requested page —
+ // otherwise personalization could never surface anything past the
+ // soonest `limit` events. See docs/ranking.md.
const rawEvents = await db
.select({
id: events.id,
@@ -175,17 +247,13 @@ export async function getFeedEvents(params?: {
.leftJoin(organizations, eq(events.orgId, organizations.id))
.where(and(...conditions))
.orderBy(events.datetime)
- .limit(limit)
- .offset(offset);
-
- // Enrich each event with tags, rsvp counts, friend attendance, user state
- //
- // Ranking, in plain English: an event scores higher if (1) its tags match
- // your interests, (2) it's happening soon, (3) friends of yours are
- // attending, (4) it belongs to an org you follow or belong to, or (5) it
- // was posted recently. Scores are deterministic — no randomness — so
- // refreshing Explore without new data (RSVPs, new events, etc.) never
- // reorders the feed. Ties break by soonest event first.
+ .limit(CANDIDATE_POOL_SIZE);
+
+ // Enrich each event with tags, rsvp counts, friend attendance, user state,
+ // and a weighted relevance score (interests, timing, friends, org
+ // affinity, recency, popularity, a small daily nudge). Full breakdown,
+ // including the org-diversity cap and soon-event guarantee applied below:
+ // docs/ranking.md.
const enriched: (FeedEvent & { score: number; _rawDatetime: Date })[] = await Promise.all(
rawEvents.map(async (event) => {
// Get tags
@@ -200,6 +268,18 @@ export async function getFeedEvents(params?: {
.from(rsvps)
.where(eq(rsvps.eventId, event.id));
+ // Get view count for the popularity signal
+ const [viewCount] = await db
+ .select({ count: sql`count(*)::int` })
+ .from(interactions)
+ .where(
+ and(
+ eq(interactions.itemId, event.id),
+ eq(interactions.itemType, "event"),
+ eq(interactions.interactionType, "view"),
+ ),
+ );
+
// Get friends attending
let friendsAttending: { id: string; displayName: string; avatarUrl: string | null }[] = [];
if (friendIds.length > 0) {
@@ -230,8 +310,7 @@ export async function getFeedEvents(params?: {
// Score for sorting
const tagNames = tags.map((t) => t.tag);
- // Fraction of this event's tags that match the user's interests — how
- // relevant is this event to you, not how much of your profile it covers.
+ // Fraction of this event's tags that match your interests.
const matchedTags = tagNames.filter((t) => myInterestTags.includes(t)).length;
const interestRelevance =
myInterestTags.length === 0
@@ -243,30 +322,41 @@ export async function getFeedEvents(params?: {
const now = Date.now();
const eventTime = event.datetime.getTime();
const daysUntil = (eventTime - now) / (1000 * 60 * 60 * 24);
- const timeProximity =
- daysUntil <= 1
- ? 1.0
- : daysUntil <= 3
- ? 0.8
- : daysUntil <= 7
- ? 0.6
- : daysUntil <= 14
- ? 0.3
- : 0.1;
+ // Half-life decay: 1.0 right now, halving every 4 days out.
+ const timeProximity = 2 ** (-daysUntil / 4);
const friendRsvpScore = Math.min(1.0, friendsAttending.length / 3.0);
- const orgAffinity = event.orgId && myOrgIds.has(event.orgId) ? 1.0 : 0.0;
+ // Full affinity if you follow/belong to the org, weaker if you've
+ // just RSVP'd to it before.
+ const orgAffinity = !event.orgId
+ ? 0
+ : myOrgIds.has(event.orgId)
+ ? 1.0
+ : interactedOrgIds.has(event.orgId)
+ ? ORG_PAST_INTERACTION_AFFINITY
+ : 0;
const hoursSinceCreated = (now - event.createdAt.getTime()) / (1000 * 60 * 60);
const recencyBoost = hoursSinceCreated <= 24 ? 1.0 : hoursSinceCreated <= 72 ? 0.5 : 0.0;
+ // Log-scaled view count, capped at 1.0 around POPULARITY_VIEW_CAP.
+ const popularityScore = Math.min(
+ 1.0,
+ Math.log((viewCount?.count ?? 0) + 1) / Math.log(POPULARITY_VIEW_CAP + 1),
+ );
+
+ // Deterministic per user-per-day-per-event nudge — see RANDOM_WEIGHT.
+ const randomNudge = seededRandom(`${userId}:${today}:${event.id}`);
+
const score =
3.0 * interestRelevance +
2.0 * timeProximity +
4.0 * friendRsvpScore +
1.0 * orgAffinity +
- 1.0 * recencyBoost;
+ 1.0 * recencyBoost +
+ POPULARITY_WEIGHT * popularityScore +
+ RANDOM_WEIGHT * randomNudge;
return {
id: event.id,
@@ -288,15 +378,44 @@ export async function getFeedEvents(params?: {
}),
);
- // Sort by score descending; ties break by soonest event first, so
- // refreshing Explore with no new data never reorders the feed.
+ // Sort by score descending; ties break by soonest first, so refreshing
+ // with no new data never reorders the feed.
enriched.sort((a, b) => {
if (b.score !== a.score) return b.score - a.score;
return a._rawDatetime.getTime() - b._rawDatetime.getTime();
});
+ // Cap events per org — anything past the cap keeps its score order, just later.
+ const ranked = diversifyByOrg(enriched, ORG_DIVERSITY_CAP);
+
+ // Guarantee SOON_QUOTA imminent events on the first page by merging them
+ // in rather than overriding score order outright — this only backfills
+ // what score order left out.
+ let page = ranked.slice(offset, offset + limit);
+ if (offset === 0) {
+ const isSoon = (e: (typeof ranked)[number]) =>
+ (e._rawDatetime.getTime() - Date.now()) / (1000 * 60 * 60 * 24) <= SOON_WINDOW_DAYS;
+
+ const soonInPage = page.filter(isSoon).length;
+ if (soonInPage < SOON_QUOTA) {
+ const pageIds = new Set(page.map((e) => e.id));
+ const missingSoon = ranked
+ .filter((e) => isSoon(e) && !pageIds.has(e.id))
+ .slice(0, SOON_QUOTA - soonInPage);
+
+ if (missingSoon.length > 0) {
+ const merged = [...page];
+ const stride = Math.max(1, Math.floor(merged.length / (missingSoon.length + 1)));
+ missingSoon.forEach((event, i) => {
+ merged.splice(Math.min(merged.length, stride * (i + 1)), 0, event);
+ });
+ page = merged.slice(0, limit);
+ }
+ }
+ }
+
return {
- events: enriched.map(({ score: _score, _rawDatetime, ...event }) => event),
+ events: page.map(({ score: _score, _rawDatetime, ...event }) => event),
total,
};
}
diff --git a/docs/ranking.md b/docs/ranking.md
new file mode 100644
index 0000000..d906a0e
--- /dev/null
+++ b/docs/ranking.md
@@ -0,0 +1,146 @@
+# Explore feed ranking
+
+This describes how `getFeedEvents()` (`apps/web/src/actions/events.ts`) orders the Explore
+feed. It's a plain SQL + in-memory weighted score — no ML, no external service.
+
+## The formula, in plain English
+
+Every upcoming event gets a score built from seven signals, each roughly between 0 and 1,
+multiplied by a weight:
+
+| Signal | Weight | What it measures |
+|---|---|---|
+| Interest relevance | 3.0 | What fraction of this event's tags match your onboarding interests |
+| Time proximity | 2.0 | How soon the event is — decays smoothly the further out it is |
+| Friend RSVPs | 4.0 | How many of your friends are going (caps out at 3+) |
+| Org affinity | 1.0 | Whether you follow/belong to the hosting org, or have RSVP'd to it before |
+| Recency | 1.0 | Whether the event was posted in the last 1–3 days |
+| Popularity | 0.5 | How many views the event has gotten, log-scaled |
+| Random nudge | 0.5 | A small per-user-per-day nudge so the feed varies over time |
+
+```
+score = 3.0 × interest_relevance
+ + 2.0 × time_proximity
+ + 4.0 × friend_rsvp_score
+ + 1.0 × org_affinity
+ + 1.0 × recency_boost
+ + 0.5 × popularity_score
+ + 0.5 × random_nudge
+```
+
+Events are sorted by this score, highest first. Friend RSVPs carry the most weight — "people
+you know are going" is the strongest signal on a campus app. Popularity and the random nudge
+are deliberately small: they nudge the feed, they don't dominate it.
+
+### Interest relevance
+
+`matched tags / total tags on the event`. No interests set yet? Everyone gets a neutral 0.5
+instead of 0, so a user with no interests still sees a normal feed, not everything at the
+bottom.
+
+### Time proximity — smooth decay
+
+```
+time_proximity = 2 ^ (-days_until / 4)
+```
+
+An event right now scores 1.0, halving every 4 days out (day 4 ≈ 0.5, day 14 ≈ 0.09, day 30
+≈ 0.004). This replaced an earlier bucketed version (`≤1 day = 1.0, ≤3 days = 0.8, …`) whose
+score could visibly jump as an event crossed a bucket boundary. The smooth curve keeps the
+same intuition — sooner is better, distant events fade but never hit zero — without the jump.
+
+### Friend RSVPs
+
+`min(1.0, friends attending / 3)`. Three or more friends going is treated as maximally
+compelling; it doesn't climb further past that.
+
+### Org affinity — tiered
+
+- **1.0** if you follow or belong to the event's org.
+- **0.5** if you don't, but you've RSVP'd to that org's events before
+ (`ORG_PAST_INTERACTION_AFFINITY` in `events.ts`) — a weaker signal of interest.
+- **0** otherwise, or if the event has no org.
+
+### Recency boost
+
+1.0 if posted in the last 24 hours, 0.5 if posted in the last 3 days, 0 otherwise — surfaces
+newly-posted events before other signals catch up.
+
+### Popularity
+
+```
+popularity_score = min(1.0, log(view_count + 1) / log(POPULARITY_VIEW_CAP + 1))
+```
+
+Grows logarithmically with view count (logged via `interactions`, see
+`apps/web/src/actions/interactions.ts`), capping at 1.0 around `POPULARITY_VIEW_CAP` (50)
+views. It's a live per-request count, not a batch job, so it stays cheap.
+
+### Random nudge — seeded per user, per day
+
+```
+random_nudge = seededRandom(`${userId}:${today}:${event.id}`)
+```
+
+A deterministic hash of the user, the current UTC date, and the event ID, normalized to
+`[0, 1)`. Not `Math.random()` — the same user looking at the same event on the same day
+always gets the same nudge, so refreshing Explore never reshuffles it. The nudge changes
+once a day, so events that would otherwise tie get some variety over time. Ties still break
+by soonest event first.
+
+## Candidate pool: why scoring needs more than one page
+
+The DB query first pulls a bounded pool of the ~100 soonest upcoming events
+(`CANDIDATE_POOL_SIZE`), scores all of them, sorts by score, and only then slices out the
+requested page (`limit`/`offset`). If scoring only ever ran against the 20 events the caller
+asked for, personalization would have nothing to work with — the soonest 20 would always be
+exactly what's returned, just reshuffled. Widening the pool first lets a highly relevant
+event further down the calendar outrank a less relevant one that merely happens sooner. The
+size is a bound to keep the query cheap, not a hard limit on how far ranking can see — 100
+events is comfortably more than a demo dataset needs.
+
+## Org diversity cap
+
+After sorting by score, results are capped at `ORG_DIVERSITY_CAP` (3) events per org — once
+an org hits 3, its remaining events are pushed later (not dropped), so one heavily-posting
+org can't dominate the top of the feed. Events without an org are never capped.
+
+## Guaranteeing imminent events aren't buried
+
+Friend RSVPs (weight 4.0) can outweigh time proximity (weight 2.0), so an event with strong
+social signal three weeks out could in principle outscore one happening tomorrow with no
+friends attending yet. To keep "what's happening soon" reliably visible, the first page
+(`offset === 0`) always includes at least `SOON_QUOTA` (3) events within `SOON_WINDOW_DAYS`
+(1) day, even if their score wouldn't naturally place them there.
+
+This is a **merge**, not a score override: if the sorted first page already has enough soon
+events, nothing changes. Otherwise the highest-scoring soon events missing from the page are
+interleaved into it at evenly-spaced positions — everything else keeps its normal score
+order. It only backfills what score order left out, the way feeds inject a freshness quota
+without letting it take over the whole ranking.
+
+All the tunable constants above (`SOON_WINDOW_DAYS`, `SOON_QUOTA`, `ORG_DIVERSITY_CAP`,
+`POPULARITY_VIEW_CAP`, `POPULARITY_WEIGHT`, `RANDOM_WEIGHT`, `ORG_PAST_INTERACTION_AFFINITY`)
+live at the top of `events.ts`.
+
+## Edge cases
+
+- **No interests**: `interest_relevance` defaults to 0.5 for every event.
+- **No friends**: `friend_rsvp_score` is 0; the friends-attending lookup is skipped entirely.
+- **No org follows/memberships/past RSVPs**: `org_affinity` is 0.
+
+None of these throw or produce an empty feed — a brand-new user with zero signals still gets
+a full feed, ranked by time proximity, recency, popularity, and the random nudge alone.
+
+## Not implemented (deferred)
+
+- **Cursor-based pagination** — the API still uses offset/limit; Explore doesn't paginate
+ past the first page today, so this hasn't been needed yet.
+- **Behavioral tag-weight blending & nightly aggregation job** — `user_preference_vectors`
+ exists in the schema but is never read or written. Blending onboarding interests with
+ interaction history needs a batch job — real added infrastructure, deliberately out of
+ scope for this MVP pass. Popularity above is the lightweight, no-batch-job alternative.
+- **Similar Events / co-RSVP item-item similarity** — a separate feature, not part of
+ `getFeedEvents()`.
+- **Position-bias correction** (downweighting previously-seen items) — would need
+ per-request interaction-log reads; not implemented.
From f61da831be646adb40db0b06e5fdf66778d9b7bd Mon Sep 17 00:00:00 2001
From: Rohan Matta
Date: Thu, 20 Aug 2026 22:36:20 -0400
Subject: [PATCH 02/69] minor comment fixes
---
apps/web/src/actions/events.ts | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/apps/web/src/actions/events.ts b/apps/web/src/actions/events.ts
index 51428fb..e7afa14 100644
--- a/apps/web/src/actions/events.ts
+++ b/apps/web/src/actions/events.ts
@@ -385,12 +385,10 @@ export async function getFeedEvents(params?: {
return a._rawDatetime.getTime() - b._rawDatetime.getTime();
});
- // Cap events per org — anything past the cap keeps its score order, just later.
+ // Cap events per org
const ranked = diversifyByOrg(enriched, ORG_DIVERSITY_CAP);
- // Guarantee SOON_QUOTA imminent events on the first page by merging them
- // in rather than overriding score order outright — this only backfills
- // what score order left out.
+ // Guarantee SOON_QUOTA imminent events on the first page
let page = ranked.slice(offset, offset + limit);
if (offset === 0) {
const isSoon = (e: (typeof ranked)[number]) =>
From 7430f6c16e94237416766fb9ba1be009445753db Mon Sep 17 00:00:00 2001
From: Rohan Matta
Date: Thu, 20 Aug 2026 22:37:36 -0400
Subject: [PATCH 03/69] ranking description edits
---
docs/ranking.md | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/docs/ranking.md b/docs/ranking.md
index d906a0e..be723cf 100644
--- a/docs/ranking.md
+++ b/docs/ranking.md
@@ -131,16 +131,3 @@ live at the top of `events.ts`.
None of these throw or produce an empty feed — a brand-new user with zero signals still gets
a full feed, ranked by time proximity, recency, popularity, and the random nudge alone.
-
-## Not implemented (deferred)
-
-- **Cursor-based pagination** — the API still uses offset/limit; Explore doesn't paginate
- past the first page today, so this hasn't been needed yet.
-- **Behavioral tag-weight blending & nightly aggregation job** — `user_preference_vectors`
- exists in the schema but is never read or written. Blending onboarding interests with
- interaction history needs a batch job — real added infrastructure, deliberately out of
- scope for this MVP pass. Popularity above is the lightweight, no-batch-job alternative.
-- **Similar Events / co-RSVP item-item similarity** — a separate feature, not part of
- `getFeedEvents()`.
-- **Position-bias correction** (downweighting previously-seen items) — would need
- per-request interaction-log reads; not implemented.
From 7e6cdcfcb045a8ed46939443daa6b4acc2210221 Mon Sep 17 00:00:00 2001
From: prishaakapasi
Date: Mon, 24 Aug 2026 18:07:01 -0600
Subject: [PATCH 04/69] Error states, consistent search, and handle sparse
ingested events
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
TIG-247.
ErrorState was sitting in the shared states file unused by anything, so
every server action failure was invisible. Wired it into Explore (retry
button instead of an empty feed, which reads as "no events" and is a
totally different message) and into the notification dropdown, which had
an actual `// silently fail` in it.
Worse than the missing UI: RSVP and save were updating optimistically and
never rolling back. If the server threw, the button stayed flipped while
the DB disagreed. Both revert now and toast.
Didn't toast on the notification failure — it polls every 60s so that
would just be spam. It shows the error inside the dropdown when you open
it instead.
Search: Explore needed you to press Enter, Orgs debounced as you typed.
No reason for them to differ, so Explore debounces now too, plus a result
count when a search or filter is active.
Ingested events: the server swaps in the literal string "TBD" when an
event has no location, and the card was rendering that next to a map pin,
which just looks broken. Treats it as absent now. Org, flyer, description
and tags were already conditional so a sparse event degrades fine.
Settings on a phone: TOP_BAR_CLEARANCE reserved 140px on the right to
clear the floating bell/avatar, which is over a third of a 375px screen.
Drops below the bar on phones instead, only insets from the right at sm+.
Fixes the Events page heading too since it uses the same constant.
---
.../src/app/(app)/explore/explore-client.tsx | 96 ++++++++++++++-----
apps/web/src/components/events/event-card.tsx | 11 ++-
.../layout/notification-dropdown.tsx | 18 +++-
apps/web/src/components/layout/page-shell.tsx | 11 ++-
4 files changed, 105 insertions(+), 31 deletions(-)
diff --git a/apps/web/src/app/(app)/explore/explore-client.tsx b/apps/web/src/app/(app)/explore/explore-client.tsx
index e779ae0..0277081 100644
--- a/apps/web/src/app/(app)/explore/explore-client.tsx
+++ b/apps/web/src/app/(app)/explore/explore-client.tsx
@@ -2,7 +2,7 @@
import { ExternalLink } from "lucide-react";
import Link from "next/link";
-import { useCallback, useMemo, useState, useTransition } from "react";
+import { useCallback, useMemo, useRef, useState, useTransition } from "react";
import { toast } from "sonner";
import {
type FeedEvent,
@@ -12,7 +12,7 @@ import {
toggleSave,
} from "~/actions/events";
import { SearchInput } from "~/components/common/search-input";
-import { EmptyState, EventCardSkeletonList } from "~/components/common/states";
+import { EmptyState, ErrorState, EventCardSkeletonList } from "~/components/common/states";
import { EventCard } from "~/components/events/event-card";
import { EventFilters } from "~/components/events/event-filters";
import { PageHeading, PageShell, SectionHeading } from "~/components/layout/page-shell";
@@ -80,16 +80,26 @@ export function ExploreClient({
const [hiddenIds, setHiddenIds] = useState>(new Set());
const [searchQuery, setSearchQuery] = useState(initialSearch);
const [isPending, startTransition] = useTransition();
+ /** Set when a feed fetch fails, so the list can offer a retry. */
+ const [loadError, setLoadError] = useState(false);
+ const searchTimeout = useRef>(null);
const firstName = useMemo(() => userName.split(" ")[0] || "there", [userName]);
const refreshEvents = useCallback((filters: string[], search: string) => {
startTransition(async () => {
- const result = await getFeedEvents({
- tags: filters.length > 0 ? filters : undefined,
- search: search || undefined,
- });
- setEvents(result.events);
- setTotal(result.total);
+ try {
+ const result = await getFeedEvents({
+ tags: filters.length > 0 ? filters : undefined,
+ search: search || undefined,
+ });
+ setEvents(result.events);
+ setTotal(result.total);
+ setLoadError(false);
+ } catch {
+ // Surfaced as an ErrorState with a retry rather than an empty feed,
+ // which reads as "no events" and is a very different thing.
+ setLoadError(true);
+ }
});
}, []);
@@ -104,22 +114,48 @@ export function ExploreClient({
[activeFilters, searchQuery, refreshEvents],
);
- const handleSearch = useCallback(() => {
- if (searchQuery.trim()) refreshEvents(activeFilters, searchQuery.trim());
- }, [searchQuery, activeFilters, refreshEvents]);
+ /*
+ * Debounced as you type, matching Orgs. Explore used to require Enter, so
+ * the two search fields behaved differently for no reason.
+ */
+ const handleSearchChange = useCallback(
+ (value: string) => {
+ setSearchQuery(value);
+ if (searchTimeout.current) clearTimeout(searchTimeout.current);
+ searchTimeout.current = setTimeout(() => {
+ refreshEvents(activeFilters, value.trim());
+ }, 300);
+ },
+ [activeFilters, refreshEvents],
+ );
+ /** Roll the optimistic update back if the server rejects it. */
const handleSaveToggle = useCallback(async (eventId: string) => {
- const result = await toggleSave(eventId);
- setEvents((prev) => prev.map((e) => (e.id === eventId ? { ...e, isSaved: result.saved } : e)));
+ try {
+ const result = await toggleSave(eventId);
+ setEvents((prev) =>
+ prev.map((e) => (e.id === eventId ? { ...e, isSaved: result.saved } : e)),
+ );
+ } catch {
+ toast.error("Couldn't update saved events. Please try again.");
+ setEvents((prev) => prev.map((e) => (e.id === eventId ? { ...e, isSaved: !e.isSaved } : e)));
+ }
}, []);
const handleRsvpToggle = useCallback(async (eventId: string) => {
- const result = await toggleRsvp(eventId);
- setEvents((prev) =>
- prev.map((e) =>
- e.id === eventId ? { ...e, isRsvped: result.rsvped, rsvpCount: result.count } : e,
- ),
- );
+ try {
+ const result = await toggleRsvp(eventId);
+ setEvents((prev) =>
+ prev.map((e) =>
+ e.id === eventId ? { ...e, isRsvped: result.rsvped, rsvpCount: result.count } : e,
+ ),
+ );
+ } catch {
+ toast.error("Couldn't update your RSVP. Please try again.");
+ setEvents((prev) =>
+ prev.map((e) => (e.id === eventId ? { ...e, isRsvped: !e.isRsvped } : e)),
+ );
+ }
}, []);
const upcomingList = useMemo(
@@ -158,17 +194,29 @@ export function ExploreClient({
label="Search events"
placeholder="Search for events or people"
value={searchQuery}
- onChange={(e) => setSearchQuery(e.target.value)}
- onKeyDown={(e) => {
- if (e.key === "Enter") handleSearch();
- }}
+ onChange={(e) => handleSearchChange(e.target.value)}
/>
+ {/* Result count, so a filtered feed says how filtered it is */}
+ {(searchQuery.trim() || activeFilters.length > 0) && !loadError && (
+
+ {isPending
+ ? "Searching…"
+ : `${events.length} ${events.length === 1 ? "event" : "events"} match`}
+
+ )}
+
{/* Feed */}
- {isPending && events.length === 0 ? (
+ {loadError ? (
+
refreshEvents(activeFilters, searchQuery.trim())}
+ />
+ ) : isPending && events.length === 0 ? (
) : events.length === 0 ? (
friend.displayName);
const remainingFriends = friendsAttending.length - displayedFriendNames.length;
@@ -305,7 +312,7 @@ export function EventCard({
- {location && (
+ {hasLocation && (
{location}
@@ -542,7 +549,7 @@ export function EventCard({
{/* Location & Time */}
- {location && (
+ {hasLocation && (
diff --git a/apps/web/src/components/layout/notification-dropdown.tsx b/apps/web/src/components/layout/notification-dropdown.tsx
index ca76cff..83d860d 100644
--- a/apps/web/src/components/layout/notification-dropdown.tsx
+++ b/apps/web/src/components/layout/notification-dropdown.tsx
@@ -10,6 +10,7 @@ import {
markAllNotificationsRead,
markNotificationRead,
} from "~/actions/notifications";
+import { ErrorState } from "~/components/common/states";
import { Popover, PopoverContent, PopoverTrigger } from "~/components/ui/popover";
import { cn } from "~/lib/utils";
@@ -31,13 +32,21 @@ export function NotificationDropdown() {
const [open, setOpen] = useState(false);
const [limit, setLimit] = useState(20);
+ const [loadFailed, setLoadFailed] = useState(false);
+
const fetchNotifications = useCallback(async () => {
try {
const data = await getNotifications();
setItems(data.items);
setUnreadCount(data.unreadCount);
+ setLoadFailed(false);
} catch {
- // silently fail
+ /*
+ * Recorded rather than swallowed. This polls on a 60s interval, so a
+ * toast per failure would be spam — the dropdown says so instead, and
+ * only when you open it.
+ */
+ setLoadFailed(true);
}
}, []);
@@ -114,6 +123,13 @@ export function NotificationDropdown() {
}}
/>
))
+ ) : loadFailed ? (
+ /* An empty list and a failed fetch mean very different things. */
+
) : (
diff --git a/apps/web/src/components/layout/page-shell.tsx b/apps/web/src/components/layout/page-shell.tsx
index 71dc261..a118013 100644
--- a/apps/web/src/components/layout/page-shell.tsx
+++ b/apps/web/src/components/layout/page-shell.tsx
@@ -57,15 +57,18 @@ export function PageShell({
}
/**
- * Right padding that keeps a page's top-right control clear of the TopBar.
+ * Keeps a page's top-right control clear of the floating TopBar.
*
* The TopBar (notification bell + avatar) is absolutely positioned over the
* content area on every route, so anything sharing that band — a page heading's
* trailing action — collides with it once the viewport is narrower than the
- * shell's max width. Roughly 24px page padding + 36px bell + 12px gap + 40px
- * avatar + 24px padding, rounded up.
+ * shell's max width.
+ *
+ * From `sm` up it reserves ~140px on the right: 24px page padding + 36px bell +
+ * 12px gap + 40px avatar + 24px padding, rounded up. On phones that would eat
+ * over a third of the screen, so the content drops *below* the bar instead.
*/
-export const TOP_BAR_CLEARANCE = "pr-[140px]";
+export const TOP_BAR_CLEARANCE = "pt-14 sm:pt-0 sm:pr-[140px]";
/**
* Page-level `
`. One ramp for every page — previously these ranged from
From a7559d8bfae28828ace031a4bc20b622b4b65f5d Mon Sep 17 00:00:00 2001
From: prishaakapasi
Date: Tue, 25 Aug 2026 11:50:42 -0600
Subject: [PATCH 05/69] Two-column feed, card polish, and search race fixes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Home feed now matches the Figma: event cards in a two-column grid with
the highlights rail pinned to the right, so only the feed shifts when the
nav rail expands. The shell runs full width instead of max-w-7xl. With a
capped shell the whole row re-centred and the rail travelled with it.
Card, on Explore and the map's expanded view alike:
- utility icons (save, share, hide, open) go coral, hovering to a coral
wash rather than the ghost variant's full-strength turquoise --accent
- tags alternate yellow/turquoise, friends line reads "… added this event
to their calendar!", description gains a See Details link
- footer wraps as two units with the redundant Users glyph dropped, so
"4 attending" stops breaking across two lines in a narrow column
- the map modal picks up the shared date formatter and the "+ Calendar"
action; buildGCalUrl was extracted for that call site and never wired up
Fixes from review:
- feed requests carry a monotonic id and a queued search is cancelled when
filters change, so a debounce armed with the previous filters can no
longer land last and overwrite the feed
- save/RSVP flip optimistically and genuinely revert on failure; the catch
used to invert a value that was still correct. Handlers rethrow so the
card announces success only once the request resolves, instead of
showing a success toast beside the error one
- the result count uses the returned total, not the 20-row page length
- getFeedEvents carries rawDatetime through; it was declared on FeedEvent
for calendar links but dropped with the sort key
Rail backdrop goes near-opaque over the map, where 50% let street names
read straight through the nav labels.
---
apps/web/src/actions/events.ts | 3 +
.../src/app/(app)/explore/explore-client.tsx | 166 +++++++++----
.../map/_components/event-detail-modal.tsx | 26 +-
apps/web/src/components/common/states.tsx | 5 +-
apps/web/src/components/events/event-card.tsx | 231 ++++++++++++------
apps/web/src/components/layout/sidebar.tsx | 18 +-
6 files changed, 320 insertions(+), 129 deletions(-)
diff --git a/apps/web/src/actions/events.ts b/apps/web/src/actions/events.ts
index ca169b2..974440b 100644
--- a/apps/web/src/actions/events.ts
+++ b/apps/web/src/actions/events.ts
@@ -440,6 +440,9 @@ export async function getFeedEvents(params?: {
return {
events: enriched.map(({ score: _score, _rawDatetime, ...event }) => ({
...event,
+ // Carried through so the feed card can build its "+ Calendar" link; the
+ // sort key was being dropped here and the button never rendered.
+ rawDatetime: _rawDatetime.toISOString(),
attendees: attendeesByEvent.get(event.id) ?? [],
})),
total,
diff --git a/apps/web/src/app/(app)/explore/explore-client.tsx b/apps/web/src/app/(app)/explore/explore-client.tsx
index 0277081..0af7406 100644
--- a/apps/web/src/app/(app)/explore/explore-client.tsx
+++ b/apps/web/src/app/(app)/explore/explore-client.tsx
@@ -2,7 +2,7 @@
import { ExternalLink } from "lucide-react";
import Link from "next/link";
-import { useCallback, useMemo, useRef, useState, useTransition } from "react";
+import { useCallback, useEffect, useMemo, useRef, useState, useTransition } from "react";
import { toast } from "sonner";
import {
type FeedEvent,
@@ -17,6 +17,7 @@ import { EventCard } from "~/components/events/event-card";
import { EventFilters } from "~/components/events/event-filters";
import { PageHeading, PageShell, SectionHeading } from "~/components/layout/page-shell";
import { Button } from "~/components/ui/button";
+import { buildGCalUrl } from "~/lib/calendar";
import { formatEventDateTime, formatRelativeDay } from "~/lib/date-format";
interface ExploreClientProps {
@@ -71,7 +72,12 @@ export function ExploreClient({
}: ExploreClientProps) {
const fallbackEvents = initialEvents.length > 0 ? initialEvents : [demoEvent];
const [events, setEvents] = useState(fallbackEvents);
- const [_total, setTotal] = useState(initialEvents.length > 0 ? initialTotal : 1);
+ /*
+ * The full match count, not the page size. `getFeedEvents` pages at 20 while
+ * returning a separate count over every match, so reporting `events.length`
+ * capped the message at "20 events match" no matter how many there were.
+ */
+ const [total, setTotal] = useState(initialEvents.length > 0 ? initialTotal : 1);
const [activeFilters, setActiveFilters] = useState([]);
/*
* Hidden events stay in the list as collapsed stubs rather than being
@@ -83,19 +89,36 @@ export function ExploreClient({
/** Set when a feed fetch fails, so the list can offer a retry. */
const [loadError, setLoadError] = useState(false);
const searchTimeout = useRef>(null);
+ /*
+ * Monotonic id for feed requests. Only the most recently issued one may write
+ * to state: two fetches can be in flight at once (type, then toggle a filter),
+ * and without this the slower-but-older response lands last and wins.
+ */
+ const latestRequest = useRef(0);
const firstName = useMemo(() => userName.split(" ")[0] || "there", [userName]);
+ /** Drop a queued debounced search — it carries whatever filters were active when it was armed. */
+ const cancelPendingSearch = useCallback(() => {
+ if (searchTimeout.current) {
+ clearTimeout(searchTimeout.current);
+ searchTimeout.current = null;
+ }
+ }, []);
+
const refreshEvents = useCallback((filters: string[], search: string) => {
+ const requestId = ++latestRequest.current;
startTransition(async () => {
try {
const result = await getFeedEvents({
tags: filters.length > 0 ? filters : undefined,
search: search || undefined,
});
+ if (requestId !== latestRequest.current) return;
setEvents(result.events);
setTotal(result.total);
setLoadError(false);
} catch {
+ if (requestId !== latestRequest.current) return;
// Surfaced as an ErrorState with a retry rather than an empty feed,
// which reads as "no events" and is a very different thing.
setLoadError(true);
@@ -103,15 +126,26 @@ export function ExploreClient({
});
}, []);
+ // A queued search outliving the component would fetch for a dead screen.
+ useEffect(() => cancelPendingSearch, [cancelPendingSearch]);
+
const handleFilterToggle = useCallback(
(filterId: string) => {
const next = activeFilters.includes(filterId)
? activeFilters.filter((f) => f !== filterId)
: [...activeFilters, filterId];
setActiveFilters(next);
- refreshEvents(next, searchQuery);
+ /*
+ * Cancel first. A search queued moments ago captured the *previous*
+ * filters, so letting it fire would re-fetch without the chip the user
+ * just clicked and overwrite this result — the feed and the active
+ * filters would disagree until the next interaction. The fetch below
+ * already carries the current query, so nothing is lost by dropping it.
+ */
+ cancelPendingSearch();
+ refreshEvents(next, searchQuery.trim());
},
- [activeFilters, searchQuery, refreshEvents],
+ [activeFilters, searchQuery, refreshEvents, cancelPendingSearch],
);
/*
@@ -129,20 +163,38 @@ export function ExploreClient({
[activeFilters, refreshEvents],
);
- /** Roll the optimistic update back if the server rejects it. */
+ /*
+ * Flip the card first so the bookmark reacts on click, then reconcile with
+ * whatever the server actually stored. Without the leading flip there was
+ * nothing to roll back, and the `catch` inverted a value that was still
+ * correct — leaving the UI disagreeing with the database.
+ *
+ * Rethrown so the card knows not to announce success; the error toast here
+ * is the only feedback the failure gets.
+ */
const handleSaveToggle = useCallback(async (eventId: string) => {
+ setEvents((prev) => prev.map((e) => (e.id === eventId ? { ...e, isSaved: !e.isSaved } : e)));
try {
const result = await toggleSave(eventId);
setEvents((prev) =>
prev.map((e) => (e.id === eventId ? { ...e, isSaved: result.saved } : e)),
);
- } catch {
+ } catch (error) {
toast.error("Couldn't update saved events. Please try again.");
setEvents((prev) => prev.map((e) => (e.id === eventId ? { ...e, isSaved: !e.isSaved } : e)));
+ throw error;
}
}, []);
+ /** Same optimistic-then-reconcile shape as `handleSaveToggle`, plus the count. */
const handleRsvpToggle = useCallback(async (eventId: string) => {
+ const flip = (e: FeedEvent) => ({
+ ...e,
+ isRsvped: !e.isRsvped,
+ rsvpCount: Math.max(0, e.rsvpCount + (e.isRsvped ? -1 : 1)),
+ });
+
+ setEvents((prev) => prev.map((e) => (e.id === eventId ? flip(e) : e)));
try {
const result = await toggleRsvp(eventId);
setEvents((prev) =>
@@ -150,11 +202,10 @@ export function ExploreClient({
e.id === eventId ? { ...e, isRsvped: result.rsvped, rsvpCount: result.count } : e,
),
);
- } catch {
+ } catch (error) {
toast.error("Couldn't update your RSVP. Please try again.");
- setEvents((prev) =>
- prev.map((e) => (e.id === eventId ? { ...e, isRsvped: !e.isRsvped } : e)),
- );
+ setEvents((prev) => prev.map((e) => (e.id === eventId ? flip(e) : e)));
+ throw error;
}
}, []);
@@ -168,11 +219,18 @@ export function ExploreClient({
* with its own internal scroll only kicks in at xl, where the right rail
* appears. Nesting a scroll container inside the page scroller on a phone
* made the feed feel stuck.
+ *
+ * The shell runs full width rather than `wide` (max-w-7xl) so the row's right
+ * edge is the content area's right edge. That is what keeps the highlights
+ * rail still while the nav rail expands: only the shell's *left* edge moves,
+ * so the greeting, search field and cards slide right and the feed narrows,
+ * while the rail — pinned to the right by `ml-auto` — does not budge. With a
+ * capped shell the whole row re-centred and the rail travelled with it.
*/
return (
-
- {/* CENTER — Feed */}
-
+
+ {/* CENTER — Feed. Capped so cards stay card-sized on very wide displays. */}
+
@@ -186,13 +244,13 @@ export function ExploreClient({
>
}
>
- Hi
+ Hello
{firstName},
handleSearchChange(e.target.value)}
/>
@@ -204,7 +262,7 @@ export function ExploreClient({
{isPending
? "Searching…"
- : `${events.length} ${events.length === 1 ? "event" : "events"} match`}
+ : `${total} ${total === 1 ? "event matches" : "events match"}`}
)}
@@ -214,7 +272,10 @@ export function ExploreClient({
refreshEvents(activeFilters, searchQuery.trim())}
+ onRetry={() => {
+ cancelPendingSearch();
+ refreshEvents(activeFilters, searchQuery.trim());
+ }}
/>
) : isPending && events.length === 0 ? (
@@ -228,31 +289,50 @@ export function ExploreClient({
}
/>
) : (
- events.map((event, index) => (
- handleSaveToggle(event.id)}
- onRsvpToggle={() => handleRsvpToggle(event.id)}
- onShare={() => {
- navigator.clipboard.writeText(`${window.location.origin}/events/${event.id}`);
- toast.success("Link copied to clipboard");
- }}
- isHidden={hiddenIds.has(event.id)}
- onHide={() => {
- setHiddenIds((prev) => new Set(prev).add(event.id));
- }}
- onUnhide={() => {
- setHiddenIds((prev) => {
- const next = new Set(prev);
- next.delete(event.id);
- return next;
- });
- }}
- />
- ))
+ /*
+ * Two columns from `sm` up. Cards stretch to the row height so a
+ * short description doesn't leave its neighbour's RSVP row floating
+ * at a different height.
+ */
+
+ {events.map((event, index) => (
+ handleSaveToggle(event.id)}
+ onRsvpToggle={() => handleRsvpToggle(event.id)}
+ onShare={() => {
+ navigator.clipboard.writeText(`${window.location.origin}/events/${event.id}`);
+ toast.success("Link copied to clipboard");
+ }}
+ isHidden={hiddenIds.has(event.id)}
+ onHide={() => {
+ setHiddenIds((prev) => new Set(prev).add(event.id));
+ }}
+ onUnhide={() => {
+ setHiddenIds((prev) => {
+ const next = new Set(prev);
+ next.delete(event.id);
+ return next;
+ });
+ }}
+ />
+ ))}
+
)}
@@ -265,7 +345,7 @@ export function ExploreClient({
*/}
{/* Find My Friends */}
diff --git a/apps/web/src/app/(app)/map/_components/event-detail-modal.tsx b/apps/web/src/app/(app)/map/_components/event-detail-modal.tsx
index d07a80d..43a7eb3 100644
--- a/apps/web/src/app/(app)/map/_components/event-detail-modal.tsx
+++ b/apps/web/src/app/(app)/map/_components/event-detail-modal.tsx
@@ -7,6 +7,8 @@ import { type EventDetail, getEvent, toggleRsvp, toggleSave } from "~/actions/ev
import { EventCard } from "~/components/events/event-card";
import { Button } from "~/components/ui/button";
import { Dialog, DialogClose, DialogContent, DialogTitle } from "~/components/ui/dialog";
+import { buildGCalUrl } from "~/lib/calendar";
+import { formatEventDateTime } from "~/lib/date-format";
interface EventDetailModalProps {
eventId: string | null;
@@ -101,14 +103,13 @@ export function EventDetailModal({ eventId, onClose }: EventDetailModalProps) {
title={event.title}
orgId={event.orgId}
orgName={event.orgName}
- datetime={`${event.datetime.toLocaleDateString("en-US", {
- weekday: "short",
- month: "short",
- day: "numeric",
- })} · ${event.datetime.toLocaleTimeString("en-US", {
- hour: "numeric",
- minute: "2-digit",
- })}`}
+ /*
+ * The shared formatter, not a hand-rolled one. This built
+ * "Wed, Aug 26 · 7:54 AM" while the feed built "Wed, Aug 26 at
+ * 7:54 AM", so the same event read differently depending on where
+ * you opened it — the exact thing this modal exists to avoid.
+ */
+ datetime={formatEventDateTime(event.datetime)}
location={event.locationName}
description={event.description}
tags={event.tags}
@@ -117,6 +118,15 @@ export function EventDetailModal({ eventId, onClose }: EventDetailModalProps) {
friendsAttending={event.friendsAttending}
isSaved={event.isSaved}
isRsvped={event.isRsvped}
+ /* The "+ Calendar" action the feed card has — `buildGCalUrl` was
+ extracted here for this call site and then never wired up. */
+ calendarUrl={buildGCalUrl({
+ title: event.title,
+ description: event.description,
+ datetime: event.datetime,
+ endDatetime: event.endDatetime,
+ locationName: event.locationName,
+ })}
onSaveToggle={handleSave}
onRsvpToggle={handleRsvp}
onShare={handleShare}
diff --git a/apps/web/src/components/common/states.tsx b/apps/web/src/components/common/states.tsx
index 83179b4..483526b 100644
--- a/apps/web/src/components/common/states.tsx
+++ b/apps/web/src/components/common/states.tsx
@@ -123,9 +123,10 @@ export function EventCardSkeleton({ className, ...props }: React.ComponentProps<
);
}
-export function EventCardSkeletonList({ count = 3 }: { count?: number }) {
+/** Mirrors the Explore feed's two-column grid so loading doesn't reflow the page. */
+export function EventCardSkeletonList({ count = 4 }: { count?: number }) {
return (
-
+
Loading events…
{Array.from({ length: count }, (_, i) => (
// biome-ignore lint/suspicious/noArrayIndexKey: fixed-length placeholder list
diff --git a/apps/web/src/components/events/event-card.tsx b/apps/web/src/components/events/event-card.tsx
index 9da21bd..46de7cf 100644
--- a/apps/web/src/components/events/event-card.tsx
+++ b/apps/web/src/components/events/event-card.tsx
@@ -13,7 +13,6 @@ import {
Plus,
Share2,
Trash2,
- Users,
} from "lucide-react";
import Link from "next/link";
import { useEffect, useRef } from "react";
@@ -39,6 +38,15 @@ export const CATEGORY_COLORS: Record void;
- onRsvpToggle?: () => void;
+ /*
+ * Actions render only when a handler is supplied.
+ *
+ * These may be async. The card awaits the returned promise and only
+ * announces success once it resolves, so a rejected save/RSVP shows the
+ * owner's error toast alone instead of a success toast beside it.
+ */
+ onSaveToggle?: () => void | Promise;
+ onRsvpToggle?: () => void | Promise;
onShare?: () => void;
onHide?: () => void;
/** When true the card collapses to a stub that can be restored. */
@@ -243,14 +257,19 @@ export function EventCard({
size="sm"
aria-pressed={isRsvped}
className="rounded-full px-6"
- onClick={() => {
+ onClick={async () => {
logInteraction({
itemId: id,
interactionType: "rsvp",
metadata: { source, position },
});
- onRsvpToggle();
- if (isRsvped) toast(`Removed your RSVP to ${title}`);
+ const wasRsvped = isRsvped;
+ try {
+ await onRsvpToggle();
+ } catch {
+ return; // the owner already surfaced the failure
+ }
+ if (wasRsvped) toast(`Removed your RSVP to ${title}`);
else toast.success(`You're going to ${title}`);
}}
>
@@ -270,11 +289,17 @@ export function EventCard({
{
- onSaveToggle();
- toast(isSaved ? `Removed ${title} from saved` : `Saved ${title}`);
+ onClick={async () => {
+ const wasSaved = isSaved;
+ try {
+ await onSaveToggle();
+ } catch {
+ return;
+ }
+ toast(wasSaved ? `Removed ${title} from saved` : `Saved ${title}`);
}}
>
{isSaved ? (
@@ -288,13 +313,20 @@ export function EventCard({
)}
-
+
@@ -426,23 +458,29 @@ export function EventCard({
{
+ onClick={async (e) => {
e.preventDefault();
logInteraction({
itemId: id,
interactionType: "save",
metadata: { source, position },
});
- onSaveToggle();
- toast(isSaved ? `Removed ${title} from saved` : `Saved ${title}`);
+ const wasSaved = isSaved;
+ try {
+ await onSaveToggle();
+ } catch {
+ return;
+ }
+ toast(wasSaved ? `Removed ${title} from saved` : `Saved ${title}`);
}}
>
{isSaved ? (
-
+
) : (
-
+
)}
)}
@@ -450,6 +488,7 @@ export function EventCard({
{
e.preventDefault();
@@ -461,7 +500,7 @@ export function EventCard({
onShare();
}}
>
-
+
)}
{/* Hide was previously an unreachable prop — no control ever called it. */}
@@ -469,6 +508,7 @@ export function EventCard({
{
e.preventDefault();
@@ -481,13 +521,19 @@ export function EventCard({
toast(`Hid ${title}`, { description: "Use Unhide to bring it back." });
}}
>
-
+
)}
-
+
-
+
@@ -581,7 +627,7 @@ export function EventCard({
key={tag}
className={cn(
"rounded-[10px] px-2 py-px font-dm-sans text-[12px] text-black",
- compact && i === 1 ? "bg-forum-turquoise-50" : "bg-forum-yellow-50",
+ (compact ? i === 1 : i > 0) ? "bg-forum-turquoise-50" : "bg-forum-yellow-50",
)}
>
{tag}
@@ -598,31 +644,43 @@ export function EventCard({
) : (
-
+
- {displayedFriendNames.join(
- displayedFriendNames.length === 2 && remainingFriends === 0 ? " and " : ", ",
- )}
-
- {remainingFriends > 0 && + {remainingFriends} more }
- {friendsAttending.length === 1 ? "is" : "are"} also going.
+ {displayedFriendNames.join(", ")}
+ {remainingFriends > 0 && ` + ${remainingFriends} other`}
+ {" "}
+ added this event to their calendar!
))}
- {/* Description — full card only */}
+ {/* Description — full card only. Clamped to the mock's three lines, with
+ "See Details" carrying the rest. */}
{!compact && description && (
-
- {description}
-
+ <>
+
+ {description}
+
+
+ See Details
+
+ >
)}
{/* Footer actions — right gutter keeps clear of the corner avatar cluster */}
- {(onRsvpToggle || onLocate) && (
+ {(onRsvpToggle || onLocate || calendarUrl) && (
0 && "pr-20",
)}
>
@@ -637,53 +695,78 @@ export function EventCard({
) : (
/* Avatar stack + "N attending", clickable to see the full list. */
-
- {attendees.length > 0 &&
}
- {rsvpCount ? (
-
-
+ (attendees.length > 0 || Boolean(rsvpCount)) && (
+
+ {attendees.length > 0 &&
}
+ {rsvpCount ? (
f.id))}
+ /* Sized to the card's own metadata scale — 14px bold black
+ shouted over the title's own details — and kept on one
+ line, which is what wrapped to "4 / attending". */
+ className="whitespace-nowrap text-[12px] font-medium text-forum-dark-gray"
/>
-
- ) : null}
-
+ ) : null}
+
+ )
)}
- {onRsvpToggle && (
-
{
- e.preventDefault();
- logInteraction({
- itemId: id,
- interactionType: "rsvp",
- metadata: { source, position },
- });
- onRsvpToggle();
- // Confirm the action explicitly — the label flip alone was easy
- // to miss, especially far down the feed.
- if (isRsvped) {
- toast(`Removed your RSVP to ${title}`);
- } else {
- toast.success(`You're going to ${title}`);
- }
- }}
- >
- {isRsvped ? (
- <>
-
- RSVP'd
- >
- ) : (
- "RSVP"
- )}
-
- )}
+ {/* Calendar + RSVP, gathered at the card's bottom-right as in the mock. */}
+
+ {calendarUrl && (
+
+
+
+ Calendar
+
+
+ )}
+ {onRsvpToggle && (
+
{
+ e.preventDefault();
+ logInteraction({
+ itemId: id,
+ interactionType: "rsvp",
+ metadata: { source, position },
+ });
+ const wasRsvped = isRsvped;
+ try {
+ await onRsvpToggle();
+ } catch {
+ return;
+ }
+ // Confirm the action explicitly — the label flip alone was easy
+ // to miss, especially far down the feed.
+ if (wasRsvped) {
+ toast(`Removed your RSVP to ${title}`);
+ } else {
+ toast.success(`You're going to ${title}`);
+ }
+ }}
+ >
+ {isRsvped ? (
+ <>
+
+ RSVP'd
+ >
+ ) : (
+ "RSVP"
+ )}
+
+ )}
+
)}
diff --git a/apps/web/src/components/layout/sidebar.tsx b/apps/web/src/components/layout/sidebar.tsx
index 3edad80..8bf9aad 100644
--- a/apps/web/src/components/layout/sidebar.tsx
+++ b/apps/web/src/components/layout/sidebar.tsx
@@ -84,8 +84,22 @@ export function Sidebar({ floating = false }: { floating?: boolean }) {
"w-[64px] group-hover/rail:w-[200px] group-focus-within/rail:w-[200px]",
)}
>
- {/* Rail backdrop — #ECFCFC at 50%. */}
-
+ {/*
+ Rail backdrop — #ECFCFC.
+
+ Half opacity reads fine over the app's near-white pages, but the map
+ is a dense, high-contrast canvas: at 50% the streets and building
+ labels ran straight through the nav labels. Over the map the panel
+ goes nearly solid and blurs what's behind it, so "Home" is read
+ against a flat tint rather than Nassau Street.
+ */}
+
{NAV_ITEMS.map(({ href, icon, label }) => {
From 1bbedac7a16bcdb79b1466277277c83e5507f5b9 Mon Sep 17 00:00:00 2001
From: Rohan Matta
Date: Tue, 25 Aug 2026 18:00:27 -0400
Subject: [PATCH 06/69] Ranking window updates, pagination fixes, updated
ranking description
---
apps/web/src/actions/events.ts | 382 +++++++++++++++++++--------------
docs/ranking.md | 70 ++++--
2 files changed, 268 insertions(+), 184 deletions(-)
diff --git a/apps/web/src/actions/events.ts b/apps/web/src/actions/events.ts
index e7afa14..cf781cc 100644
--- a/apps/web/src/actions/events.ts
+++ b/apps/web/src/actions/events.ts
@@ -46,16 +46,25 @@ export interface FeedEvent {
isSaved: boolean;
}
-// Upcoming events scored before slicing out the requested page — must be
-// well above any realistic page size so personalization has real candidates
-// to work with. See docs/ranking.md.
-const CANDIDATE_POOL_SIZE = 100;
-
-// An event is "soon" if it's within this many days. The first page always
-// includes at least SOON_QUOTA such events, even if their score is weak.
+// Default lookahead when no `dateRange` filter is given, rounded up to end
+// of day. A calendar-distance bound, not a row count, so it never depends
+// on how many other events happen to be scheduled sooner. See docs/ranking.md.
+const CANDIDATE_HORIZON_DAYS = 14;
+
+// Defensive-only cap on result size within the horizon — not a ranking
+// boundary, and not expected to bind at realistic campus-event scale.
+const CANDIDATE_POOL_SAFETY_VALVE = 5000;
+
+// An event is "soon" if it's within this many days. At least SOON_QUOTA
+// such events always land within the first SOON_INJECTION_WINDOW positions
+// of the feed, even if their score is weak.
const SOON_WINDOW_DAYS = 1;
const SOON_QUOTA = 3;
+// Fixed window, independent of the request's `limit` — so the same
+// underlying order results no matter what page size a given call uses.
+const SOON_INJECTION_WINDOW = 20;
+
// Max events from one org before the rest get pushed later in the ranking.
const ORG_DIVERSITY_CAP = 3;
@@ -206,30 +215,28 @@ export async function getFeedEvents(params?: {
conditions.push(eq(events.locationId, params.locationId));
}
- if (params?.dateRange) {
- const now = new Date();
- let end: Date;
- if (params.dateRange === "today") {
- end = new Date(now);
- end.setHours(23, 59, 59, 999);
- } else if (params.dateRange === "week") {
- end = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);
- } else {
- end = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000);
- }
- conditions.push(lt(events.datetime, end));
+ // No explicit dateRange filter defaults to the candidate horizon, so
+ // there's one date-bounding path instead of a separate "no filter"
+ // branch — see docs/ranking.md.
+ const now = new Date();
+ let dateRangeEnd: Date;
+ if (params?.dateRange === "today") {
+ dateRangeEnd = new Date(now);
+ dateRangeEnd.setHours(23, 59, 59, 999);
+ } else if (params?.dateRange === "week") {
+ dateRangeEnd = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);
+ } else if (params?.dateRange === "month") {
+ dateRangeEnd = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000);
+ } else {
+ dateRangeEnd = new Date(now);
+ dateRangeEnd.setDate(dateRangeEnd.getDate() + CANDIDATE_HORIZON_DAYS);
+ dateRangeEnd.setHours(23, 59, 59, 999);
}
+ conditions.push(lt(events.datetime, dateRangeEnd));
- // Get total count
- const [countResult] = await db
- .select({ count: sql`count(*)::int` })
- .from(events)
- .where(and(...conditions));
- const total = countResult?.count ?? 0;
-
- // Score a bounded pool of upcoming events, not just the requested page —
- // otherwise personalization could never surface anything past the
- // soonest `limit` events. See docs/ranking.md.
+ // Score every candidate within the horizon, not just the requested page —
+ // batched enrichment below keeps this cheap regardless of pool size. See
+ // docs/ranking.md.
const rawEvents = await db
.select({
id: events.id,
@@ -247,136 +254,169 @@ export async function getFeedEvents(params?: {
.leftJoin(organizations, eq(events.orgId, organizations.id))
.where(and(...conditions))
.orderBy(events.datetime)
- .limit(CANDIDATE_POOL_SIZE);
+ .limit(CANDIDATE_POOL_SAFETY_VALVE);
- // Enrich each event with tags, rsvp counts, friend attendance, user state,
- // and a weighted relevance score (interests, timing, friends, org
- // affinity, recency, popularity, a small daily nudge). Full breakdown,
- // including the org-diversity cap and soon-event guarantee applied below:
- // docs/ranking.md.
- const enriched: (FeedEvent & { score: number; _rawDatetime: Date })[] = await Promise.all(
- rawEvents.map(async (event) => {
- // Get tags
- const tags = await db
- .select({ tag: eventTags.tag })
+ if (rawEvents.length === 0) {
+ return { events: [], total: 0 };
+ }
+
+ // Matches exactly what was fetched, so it's always consistent with what
+ // offset/limit can reach — unlike a separate unbounded COUNT(*).
+ const total = rawEvents.length;
+
+ if (rawEvents.length === CANDIDATE_POOL_SAFETY_VALVE) {
+ console.warn(
+ `getFeedEvents: candidate pool hit CANDIDATE_POOL_SAFETY_VALVE (${CANDIDATE_POOL_SAFETY_VALVE}); total may be an undercount.`,
+ );
+ }
+
+ const candidateIds = rawEvents.map((e) => e.id);
+
+ // Batch every per-candidate lookup into one query each, instead of one
+ // query per candidate. Grouped in memory afterward by eventId/itemId.
+ const [tagRows, rsvpCountRows, viewCountRows, friendRsvpRows, userRsvpRows, userSaveRows] =
+ await Promise.all([
+ db
+ .select({ eventId: eventTags.eventId, tag: eventTags.tag })
.from(eventTags)
- .where(eq(eventTags.eventId, event.id));
+ .where(inArray(eventTags.eventId, candidateIds)),
- // Get RSVP count
- const [rsvpCount] = await db
- .select({ count: sql`count(*)::int` })
+ db
+ .select({ eventId: rsvps.eventId, count: sql`count(*)::int` })
.from(rsvps)
- .where(eq(rsvps.eventId, event.id));
+ .where(inArray(rsvps.eventId, candidateIds))
+ .groupBy(rsvps.eventId),
- // Get view count for the popularity signal
- const [viewCount] = await db
- .select({ count: sql`count(*)::int` })
+ db
+ .select({ eventId: interactions.itemId, count: sql`count(*)::int` })
.from(interactions)
.where(
and(
- eq(interactions.itemId, event.id),
+ inArray(interactions.itemId, candidateIds),
eq(interactions.itemType, "event"),
eq(interactions.interactionType, "view"),
),
- );
-
- // Get friends attending
- let friendsAttending: { id: string; displayName: string; avatarUrl: string | null }[] = [];
- if (friendIds.length > 0) {
- friendsAttending = await db
- .select({
- id: users.id,
- displayName: users.displayName,
- avatarUrl: users.avatarUrl,
- })
- .from(rsvps)
- .innerJoin(users, eq(rsvps.userId, users.id))
- .where(and(eq(rsvps.eventId, event.id), inArray(rsvps.userId, friendIds)));
- }
-
- // Check if user has RSVP'd or saved
- const [userRsvp] = await db
- .select()
+ )
+ .groupBy(interactions.itemId),
+
+ friendIds.length === 0
+ ? []
+ : db
+ .select({
+ eventId: rsvps.eventId,
+ id: users.id,
+ displayName: users.displayName,
+ avatarUrl: users.avatarUrl,
+ })
+ .from(rsvps)
+ .innerJoin(users, eq(rsvps.userId, users.id))
+ .where(and(inArray(rsvps.eventId, candidateIds), inArray(rsvps.userId, friendIds))),
+
+ db
+ .select({ eventId: rsvps.eventId })
.from(rsvps)
- .where(and(eq(rsvps.userId, userId), eq(rsvps.eventId, event.id)))
- .limit(1);
+ .where(and(eq(rsvps.userId, userId), inArray(rsvps.eventId, candidateIds))),
- const [userSave] = await db
- .select()
+ db
+ .select({ eventId: savedEvents.eventId })
.from(savedEvents)
- .where(and(eq(savedEvents.userId, userId), eq(savedEvents.eventId, event.id)))
- .limit(1);
-
- // Score for sorting
- const tagNames = tags.map((t) => t.tag);
-
- // Fraction of this event's tags that match your interests.
- const matchedTags = tagNames.filter((t) => myInterestTags.includes(t)).length;
- const interestRelevance =
- myInterestTags.length === 0
- ? 0.5
- : tagNames.length === 0
- ? 0
- : matchedTags / tagNames.length;
-
- const now = Date.now();
- const eventTime = event.datetime.getTime();
- const daysUntil = (eventTime - now) / (1000 * 60 * 60 * 24);
- // Half-life decay: 1.0 right now, halving every 4 days out.
- const timeProximity = 2 ** (-daysUntil / 4);
-
- const friendRsvpScore = Math.min(1.0, friendsAttending.length / 3.0);
-
- // Full affinity if you follow/belong to the org, weaker if you've
- // just RSVP'd to it before.
- const orgAffinity = !event.orgId
- ? 0
- : myOrgIds.has(event.orgId)
- ? 1.0
- : interactedOrgIds.has(event.orgId)
- ? ORG_PAST_INTERACTION_AFFINITY
- : 0;
-
- const hoursSinceCreated = (now - event.createdAt.getTime()) / (1000 * 60 * 60);
- const recencyBoost = hoursSinceCreated <= 24 ? 1.0 : hoursSinceCreated <= 72 ? 0.5 : 0.0;
-
- // Log-scaled view count, capped at 1.0 around POPULARITY_VIEW_CAP.
- const popularityScore = Math.min(
- 1.0,
- Math.log((viewCount?.count ?? 0) + 1) / Math.log(POPULARITY_VIEW_CAP + 1),
- );
+ .where(and(eq(savedEvents.userId, userId), inArray(savedEvents.eventId, candidateIds))),
+ ]);
+
+ const tagsByEvent = new Map();
+ for (const row of tagRows) {
+ const list = tagsByEvent.get(row.eventId);
+ if (list) list.push(row.tag);
+ else tagsByEvent.set(row.eventId, [row.tag]);
+ }
- // Deterministic per user-per-day-per-event nudge — see RANDOM_WEIGHT.
- const randomNudge = seededRandom(`${userId}:${today}:${event.id}`);
-
- const score =
- 3.0 * interestRelevance +
- 2.0 * timeProximity +
- 4.0 * friendRsvpScore +
- 1.0 * orgAffinity +
- 1.0 * recencyBoost +
- POPULARITY_WEIGHT * popularityScore +
- RANDOM_WEIGHT * randomNudge;
-
- return {
- id: event.id,
- title: event.title,
- description: event.description,
- orgId: event.orgId,
- orgName: event.orgName,
- datetime: formatEventDateTime(event.datetime),
- location: event.locationName ?? "TBD",
- tags: tagNames,
- flyerUrl: event.flyerUrl,
- rsvpCount: rsvpCount?.count ?? 0,
- friendsAttending,
- isRsvped: !!userRsvp,
- isSaved: !!userSave,
- score,
- _rawDatetime: event.datetime,
- };
- }),
- );
+ const rsvpCountByEvent = new Map(rsvpCountRows.map((r) => [r.eventId, r.count]));
+ const viewCountByEvent = new Map(viewCountRows.map((r) => [r.eventId, r.count]));
+
+ const friendsByEvent = new Map<
+ string,
+ { id: string; displayName: string; avatarUrl: string | null }[]
+ >();
+ for (const row of friendRsvpRows) {
+ const entry = { id: row.id, displayName: row.displayName, avatarUrl: row.avatarUrl };
+ const list = friendsByEvent.get(row.eventId);
+ if (list) list.push(entry);
+ else friendsByEvent.set(row.eventId, [entry]);
+ }
+
+ const userRsvpEventIds = new Set(userRsvpRows.map((r) => r.eventId));
+ const userSaveEventIds = new Set(userSaveRows.map((r) => r.eventId));
+
+ // Enrich each event and compute its weighted relevance score. Full
+ // formula breakdown: docs/ranking.md.
+ const enriched: (FeedEvent & { score: number; _rawDatetime: Date })[] = rawEvents.map((event) => {
+ const tagNames = tagsByEvent.get(event.id) ?? [];
+ const rsvpCount = rsvpCountByEvent.get(event.id) ?? 0;
+ const viewCount = viewCountByEvent.get(event.id) ?? 0;
+ const friendsAttending = friendsByEvent.get(event.id) ?? [];
+
+ // Fraction of this event's tags that match your interests.
+ const matchedTags = tagNames.filter((t) => myInterestTags.includes(t)).length;
+ const interestRelevance =
+ myInterestTags.length === 0 ? 0.5 : tagNames.length === 0 ? 0 : matchedTags / tagNames.length;
+
+ const now = Date.now();
+ const eventTime = event.datetime.getTime();
+ const daysUntil = (eventTime - now) / (1000 * 60 * 60 * 24);
+ // Half-life decay: 1.0 right now, halving every 4 days out.
+ const timeProximity = 2 ** (-daysUntil / 4);
+
+ const friendRsvpScore = Math.min(1.0, friendsAttending.length / 3.0);
+
+ // Full affinity if you follow/belong to the org, weaker if you've
+ // just RSVP'd to it before.
+ const orgAffinity = !event.orgId
+ ? 0
+ : myOrgIds.has(event.orgId)
+ ? 1.0
+ : interactedOrgIds.has(event.orgId)
+ ? ORG_PAST_INTERACTION_AFFINITY
+ : 0;
+
+ const hoursSinceCreated = (now - event.createdAt.getTime()) / (1000 * 60 * 60);
+ const recencyBoost = hoursSinceCreated <= 24 ? 1.0 : hoursSinceCreated <= 72 ? 0.5 : 0.0;
+
+ // Log-scaled view count, capped at 1.0 around POPULARITY_VIEW_CAP.
+ const popularityScore = Math.min(
+ 1.0,
+ Math.log(viewCount + 1) / Math.log(POPULARITY_VIEW_CAP + 1),
+ );
+
+ // Deterministic per user-per-day-per-event nudge — see RANDOM_WEIGHT.
+ const randomNudge = seededRandom(`${userId}:${today}:${event.id}`);
+
+ const score =
+ 3.0 * interestRelevance +
+ 2.0 * timeProximity +
+ 4.0 * friendRsvpScore +
+ 1.0 * orgAffinity +
+ 1.0 * recencyBoost +
+ POPULARITY_WEIGHT * popularityScore +
+ RANDOM_WEIGHT * randomNudge;
+
+ return {
+ id: event.id,
+ title: event.title,
+ description: event.description,
+ orgId: event.orgId,
+ orgName: event.orgName,
+ datetime: formatEventDateTime(event.datetime),
+ location: event.locationName ?? "TBD",
+ tags: tagNames,
+ flyerUrl: event.flyerUrl,
+ rsvpCount,
+ friendsAttending,
+ isRsvped: userRsvpEventIds.has(event.id),
+ isSaved: userSaveEventIds.has(event.id),
+ score,
+ _rawDatetime: event.datetime,
+ };
+ });
// Sort by score descending; ties break by soonest first, so refreshing
// with no new data never reorders the feed.
@@ -388,30 +428,42 @@ export async function getFeedEvents(params?: {
// Cap events per org
const ranked = diversifyByOrg(enriched, ORG_DIVERSITY_CAP);
- // Guarantee SOON_QUOTA imminent events on the first page
- let page = ranked.slice(offset, offset + limit);
- if (offset === 0) {
- const isSoon = (e: (typeof ranked)[number]) =>
- (e._rawDatetime.getTime() - Date.now()) / (1000 * 60 * 60 * 24) <= SOON_WINDOW_DAYS;
-
- const soonInPage = page.filter(isSoon).length;
- if (soonInPage < SOON_QUOTA) {
- const pageIds = new Set(page.map((e) => e.id));
- const missingSoon = ranked
- .filter((e) => isSoon(e) && !pageIds.has(e.id))
- .slice(0, SOON_QUOTA - soonInPage);
-
- if (missingSoon.length > 0) {
- const merged = [...page];
- const stride = Math.max(1, Math.floor(merged.length / (missingSoon.length + 1)));
- missingSoon.forEach((event, i) => {
- merged.splice(Math.min(merged.length, stride * (i + 1)), 0, event);
- });
- page = merged.slice(0, limit);
- }
+ // Guarantee SOON_QUOTA imminent events land within the first
+ // SOON_INJECTION_WINDOW positions. This finalizes ONE stable order over
+ // the whole pool before pagination, so every page is a plain slice of
+ // the same array — no event can be duplicated or dropped across pages.
+ // See docs/ranking.md.
+ const isSoon = (e: (typeof ranked)[number]) =>
+ (e._rawDatetime.getTime() - Date.now()) / (1000 * 60 * 60 * 24) <= SOON_WINDOW_DAYS;
+
+ const windowSize = Math.min(SOON_INJECTION_WINDOW, ranked.length);
+ const front = ranked.slice(0, windowSize);
+ const tail = ranked.slice(windowSize);
+
+ let finalOrder = ranked;
+ const soonInFront = front.filter(isSoon).length;
+
+ if (soonInFront < SOON_QUOTA) {
+ const frontIds = new Set(front.map((e) => e.id));
+ const missingSoon = tail
+ .filter((e) => isSoon(e) && !frontIds.has(e.id))
+ .slice(0, SOON_QUOTA - soonInFront);
+
+ if (missingSoon.length > 0) {
+ const missingIds = new Set(missingSoon.map((e) => e.id));
+ const mergedFront = [...front];
+ const stride = Math.max(1, Math.floor(mergedFront.length / (missingSoon.length + 1)));
+ missingSoon.forEach((event, i) => {
+ mergedFront.splice(Math.min(mergedFront.length, stride * (i + 1)), 0, event);
+ });
+ finalOrder = [...mergedFront, ...tail.filter((e) => !missingIds.has(e.id))];
}
}
+ // finalOrder.length === ranked.length always — pure reorder, nothing
+ // added or dropped. Pagination is a plain slice of this one stable order.
+ const page = finalOrder.slice(offset, offset + limit);
+
return {
events: page.map(({ score: _score, _rawDatetime, ...event }) => event),
total,
diff --git a/docs/ranking.md b/docs/ranking.md
index be723cf..0ff8b43 100644
--- a/docs/ranking.md
+++ b/docs/ranking.md
@@ -90,14 +90,38 @@ by soonest event first.
## Candidate pool: why scoring needs more than one page
-The DB query first pulls a bounded pool of the ~100 soonest upcoming events
-(`CANDIDATE_POOL_SIZE`), scores all of them, sorts by score, and only then slices out the
-requested page (`limit`/`offset`). If scoring only ever ran against the 20 events the caller
-asked for, personalization would have nothing to work with — the soonest 20 would always be
-exactly what's returned, just reshuffled. Widening the pool first lets a highly relevant
-event further down the calendar outrank a less relevant one that merely happens sooner. The
-size is a bound to keep the query cheap, not a hard limit on how far ranking can see — 100
-events is comfortably more than a demo dataset needs.
+The DB query pulls every upcoming, published event matching the feed's filters — not just the
+requested page (`limit`/`offset`) — scores all of them, sorts by score, and only then slices
+out the requested page. If scoring only ever ran against the 20 events the caller asked for,
+personalization would have nothing to work with — the soonest 20 would always be exactly
+what's returned, just reshuffled. Scoring the full candidate set lets a highly relevant event
+further down the calendar outrank a less relevant one that merely happens sooner, no matter
+how many other events are scheduled in between.
+
+`total` is simply the size of that candidate set, so it always agrees with what `limit`/`offset`
+can actually reach — there's no separate count that could promise more than pagination can
+deliver. Enrichment (tags, rsvp/view counts, friend attendance, user state) is batched via
+`inArray(...)` across the whole candidate set rather than queried per event, so a wider pool
+doesn't multiply query count — it stays at a fixed handful of queries regardless of how many
+candidates are scored.
+
+### Bounded by calendar distance, not row count
+
+When no explicit `dateRange` filter is applied, candidates are bounded to the next
+`CANDIDATE_HORIZON_DAYS` (14) days, rounded up to the end of that day. This replaced an earlier
+version that capped the candidate pool at a fixed row count (the soonest 100 events) — that
+approach meant a highly relevant event could be excluded from ranking entirely just because 100
+*other* events happened to be scheduled sooner, regardless of how strong its interest/friend/org
+signal was. A calendar-distance bound doesn't have that failure mode: every event within the
+next two weeks is always a candidate, no matter how many other events fall before it. An
+explicit `dateRange` param (`today`/`week`/`month`) overrides the default horizon with its own
+narrower or wider window.
+
+Events further out than the horizon never enter ranking by default — this is an intentional
+product choice (Explore surfaces what's happening soon, not the whole semester's calendar), not
+a scale workaround. `CANDIDATE_POOL_SAFETY_VALVE` (5000) is a separate, purely defensive row
+limit on top of the horizon, in case an unusually dense window ever produced a pathological
+result size — it isn't expected to bind at realistic campus-event scale.
## Org diversity cap
@@ -109,17 +133,25 @@ org can't dominate the top of the feed. Events without an org are never capped.
Friend RSVPs (weight 4.0) can outweigh time proximity (weight 2.0), so an event with strong
social signal three weeks out could in principle outscore one happening tomorrow with no
-friends attending yet. To keep "what's happening soon" reliably visible, the first page
-(`offset === 0`) always includes at least `SOON_QUOTA` (3) events within `SOON_WINDOW_DAYS`
-(1) day, even if their score wouldn't naturally place them there.
-
-This is a **merge**, not a score override: if the sorted first page already has enough soon
-events, nothing changes. Otherwise the highest-scoring soon events missing from the page are
-interleaved into it at evenly-spaced positions — everything else keeps its normal score
-order. It only backfills what score order left out, the way feeds inject a freshness quota
-without letting it take over the whole ranking.
-
-All the tunable constants above (`SOON_WINDOW_DAYS`, `SOON_QUOTA`, `ORG_DIVERSITY_CAP`,
+friends attending yet. To keep "what's happening soon" reliably visible, the first
+`SOON_INJECTION_WINDOW` (20) positions of the ranked, diversified feed always include at least
+`SOON_QUOTA` (3) events within `SOON_WINDOW_DAYS` (1) day, even if their score wouldn't
+naturally place them there.
+
+This window is a fixed size, independent of the `limit`/`offset` a given request happens to
+use — the whole feed is reordered into one final, stable sequence first, and *then* sliced into
+pages. That means two requests for the same feed with different page sizes see the same
+underlying order, and no event can appear on two different pages or be silently dropped by the
+guarantee.
+
+This is a **merge**, not a score override: if the front of the feed already has enough soon
+events, nothing changes. Otherwise the highest-scoring soon events missing from that window are
+interleaved into it at evenly-spaced positions, removed from their original later position —
+everything else keeps its normal score order. It only backfills what score order left out, the
+way feeds inject a freshness quota without letting it take over the whole ranking.
+
+All the tunable constants above (`SOON_WINDOW_DAYS`, `SOON_QUOTA`, `SOON_INJECTION_WINDOW`,
+`ORG_DIVERSITY_CAP`, `CANDIDATE_HORIZON_DAYS`, `CANDIDATE_POOL_SAFETY_VALVE`,
`POPULARITY_VIEW_CAP`, `POPULARITY_WEIGHT`, `RANDOM_WEIGHT`, `ORG_PAST_INTERACTION_AFFINITY`)
live at the top of `events.ts`.
From 800b4ee59bc71d646a5c299740bfa7f2379ea4ac Mon Sep 17 00:00:00 2001
From: Rohan Matta
Date: Thu, 27 Aug 2026 21:08:41 -0400
Subject: [PATCH 07/69] fixed org cap vs soon event minimum conflict
---
apps/web/src/actions/events.ts | 30 +++++++++++++++++++++++-------
docs/ranking.md | 5 +++++
2 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/apps/web/src/actions/events.ts b/apps/web/src/actions/events.ts
index 773acc4..40ed474 100644
--- a/apps/web/src/actions/events.ts
+++ b/apps/web/src/actions/events.ts
@@ -571,10 +571,10 @@ export async function getFeedEvents(params?: {
const ranked = diversifyByOrg(enriched, ORG_DIVERSITY_CAP);
// Guarantee SOON_QUOTA imminent events land within the first
- // SOON_INJECTION_WINDOW positions. This finalizes ONE stable order over
- // the whole pool before pagination, so every page is a plain slice of
- // the same array — no event can be duplicated or dropped across pages.
- // See docs/ranking.md.
+ // SOON_INJECTION_WINDOW positions, without exceeding ORG_DIVERSITY_CAP
+ // there. This finalizes ONE stable order over the whole pool before
+ // pagination, so every page is a plain slice of the same array — no
+ // event can be duplicated or dropped across pages. See docs/ranking.md.
const isSoon = (e: (typeof ranked)[number]) =>
(e._rawDatetime.getTime() - Date.now()) / (1000 * 60 * 60 * 24) <= SOON_WINDOW_DAYS;
@@ -587,9 +587,25 @@ export async function getFeedEvents(params?: {
if (soonInFront < SOON_QUOTA) {
const frontIds = new Set(front.map((e) => e.id));
- const missingSoon = tail
- .filter((e) => isSoon(e) && !frontIds.has(e.id))
- .slice(0, SOON_QUOTA - soonInFront);
+
+ // Org counts already in front — a candidate whose org is already at
+ // the cap is skipped, so injection can't push an org past it.
+ const frontOrgCounts = new Map();
+ for (const e of front) {
+ if (e.orgId) frontOrgCounts.set(e.orgId, (frontOrgCounts.get(e.orgId) ?? 0) + 1);
+ }
+
+ const missingSoon: (typeof ranked)[number][] = [];
+ for (const e of tail) {
+ if (missingSoon.length >= SOON_QUOTA - soonInFront) break;
+ if (!isSoon(e) || frontIds.has(e.id)) continue;
+ if (e.orgId) {
+ const count = frontOrgCounts.get(e.orgId) ?? 0;
+ if (count >= ORG_DIVERSITY_CAP) continue;
+ frontOrgCounts.set(e.orgId, count + 1);
+ }
+ missingSoon.push(e);
+ }
if (missingSoon.length > 0) {
const missingIds = new Set(missingSoon.map((e) => e.id));
diff --git a/docs/ranking.md b/docs/ranking.md
index 0ff8b43..58dbb2d 100644
--- a/docs/ranking.md
+++ b/docs/ranking.md
@@ -150,6 +150,11 @@ interleaved into it at evenly-spaced positions, removed from their original late
everything else keeps its normal score order. It only backfills what score order left out, the
way feeds inject a freshness quota without letting it take over the whole ranking.
+The injection never breaks the org diversity cap above: a soon event whose org already has
+`ORG_DIVERSITY_CAP` events in the front window is skipped, even if that means fewer than
+`SOON_QUOTA` soon events end up there. "Max 3 per org near the top" holds regardless of the
+soon-event guarantee — the two rules compose rather than one silently overriding the other.
+
All the tunable constants above (`SOON_WINDOW_DAYS`, `SOON_QUOTA`, `SOON_INJECTION_WINDOW`,
`ORG_DIVERSITY_CAP`, `CANDIDATE_HORIZON_DAYS`, `CANDIDATE_POOL_SAFETY_VALVE`,
`POPULARITY_VIEW_CAP`, `POPULARITY_WEIGHT`, `RANDOM_WEIGHT`, `ORG_PAST_INTERACTION_AFFINITY`)
From 6fc78b51f36614ffa048082f118bec2d38a72cbb Mon Sep 17 00:00:00 2001
From: DIodide
Date: Mon, 28 Sep 2026 02:33:37 -0400
Subject: [PATCH 08/69] ci: remove broken listserv scrape and pipeline-poll
workflows
scrape_listserv.yml failed daily and printed listserv subjects into public Actions logs; pipeline-poll.yml was disabled and broken.
---
.github/workflows/pipeline-poll.yml | 16 -----------
.github/workflows/scrape_listserv.yml | 41 ---------------------------
2 files changed, 57 deletions(-)
delete mode 100644 .github/workflows/pipeline-poll.yml
delete mode 100644 .github/workflows/scrape_listserv.yml
diff --git a/.github/workflows/pipeline-poll.yml b/.github/workflows/pipeline-poll.yml
deleted file mode 100644
index e1645cf..0000000
--- a/.github/workflows/pipeline-poll.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: Pipeline Poll
-
-on:
- schedule:
- - cron: "*/15 * * * *" # Every 15 minutes
- workflow_dispatch: {} # Allow manual trigger
-
-jobs:
- poll:
- runs-on: ubuntu-latest
- steps:
- - name: Trigger pipeline poll
- run: |
- curl -sf -X POST "${{ secrets.FASTAPI_URL }}/pipeline/poll" \
- -H "Authorization: Bearer ${{ secrets.ADMIN_API_KEY }}" \
- -H "Content-Type: application/json"
diff --git a/.github/workflows/scrape_listserv.yml b/.github/workflows/scrape_listserv.yml
deleted file mode 100644
index 2452246..0000000
--- a/.github/workflows/scrape_listserv.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-name: Scrape WhitmanWire
-
-on:
- schedule:
- # Runs at 8:00 AM UTC (4:00 AM Eastern Time) every day
- - cron: '0 8 * * *'
- workflow_dispatch: # Allows you to click a "Run workflow" button in GitHub's UI
-
-jobs:
- scrape-and-commit:
- runs-on: ubuntu-latest
- # This permission is required so the bot can push the JSON file back to your repo
- permissions:
- contents: write
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
-
- - name: Set up Python
- uses: actions/setup-python@v5
- with:
- python-version: '3.11' # The script uses standard libraries, so this is fine
-
- - name: Run Scraper
- env:
- # Pulls securely from GitHub Secrets
- LISTSERV_EMAIL: ${{ secrets.LISTSERV_EMAIL }}
- LISTSERV_PASSWORD: ${{ secrets.LISTSERV_PASSWORD }}
- run: |
- python3 apps/listserv-scraper/src/scrape_listserv.py --list WHITMANWIRE --limit 100 --fetch-bodies
-
- - name: Commit and push changes
- run: |
- git config --global user.name "github-actions[bot]"
- git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
- # Stage the specific data folder where the script saves its output
- git add apps/listserv-scraper/data/
- # Commit the changes; if there are no new emails, it fails gracefully instead of crashing
- git commit -m "chore: update WhitmanWire scraped data" || echo "No changes to commit"
- git push
\ No newline at end of file
From 1728706c64c66c28b66c99f41f76f55e8ef29fcf Mon Sep 17 00:00:00 2001
From: DIodide
Date: Mon, 28 Sep 2026 02:33:41 -0400
Subject: [PATCH 09/69] chore: ignore tokens, cookies, and tsbuildinfo; untrack
tsconfig.tsbuildinfo
---
.gitignore | 5 +++++
apps/web/tsconfig.tsbuildinfo | 1 -
2 files changed, 5 insertions(+), 1 deletion(-)
delete mode 100644 apps/web/tsconfig.tsbuildinfo
diff --git a/.gitignore b/.gitignore
index 6399e95..6dcca7a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -57,3 +57,8 @@ Thumbs.db
*.ntvs*
*.njsproj
*.sln
+
+# ---- Secrets / local artifacts ----
+gmail_token.json
+**/cookies.json
+*.tsbuildinfo
diff --git a/apps/web/tsconfig.tsbuildinfo b/apps/web/tsconfig.tsbuildinfo
deleted file mode 100644
index d0d8916..0000000
--- a/apps/web/tsconfig.tsbuildinfo
+++ /dev/null
@@ -1 +0,0 @@
-{"fileNames":["../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es5.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2015.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2016.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2017.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2018.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2019.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2020.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2021.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2022.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2023.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2024.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.esnext.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.dom.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2015.core.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2017.date.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2017.object.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2017.string.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2019.array.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2019.object.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2019.string.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2020.date.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2020.string.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2020.number.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2021.string.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2022.array.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2022.error.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2022.object.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2022.string.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2023.array.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2023.collection.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2023.intl.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2024.collection.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2024.object.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2024.promise.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2024.regexp.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.es2024.string.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.esnext.array.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.esnext.collection.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.esnext.intl.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.esnext.disposable.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.esnext.promise.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.esnext.decorators.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.esnext.iterator.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.esnext.float16.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.esnext.error.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.decorators.d.ts","../../../../../../../private/tmp/bunx-501-typescript@latest/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../node_modules/.bun/@types+react@19.2.14/node_modules/@types/react/global.d.ts","../../node_modules/.bun/csstype@3.2.3/node_modules/csstype/index.d.ts","../../node_modules/.bun/@types+react@19.2.14/node_modules/@types/react/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/styled-jsx/types/css.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/styled-jsx/types/macro.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/styled-jsx/types/style.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/styled-jsx/types/global.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/styled-jsx/types/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/get-page-files.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/compatibility/disposable.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/compatibility/indexable.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/compatibility/iterators.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/compatibility/index.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/globals.typedarray.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/buffer.buffer.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/globals.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/web-globals/abortcontroller.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/web-globals/domexception.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/web-globals/events.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/header.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/readable.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/file.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/fetch.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/formdata.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/connector.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/client.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/errors.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/dispatcher.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/global-dispatcher.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/global-origin.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/pool-stats.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/pool.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/handlers.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/balanced-pool.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/agent.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/mock-interceptor.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/mock-agent.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/mock-client.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/mock-pool.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/mock-errors.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/proxy-agent.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/env-http-proxy-agent.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/retry-handler.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/retry-agent.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/api.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/interceptors.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/util.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/cookies.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/patch.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/websocket.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/eventsource.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/filereader.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/diagnostics-channel.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/content-type.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/cache.d.ts","../../node_modules/.bun/undici-types@6.21.0/node_modules/undici-types/index.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/web-globals/fetch.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/web-globals/navigator.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/web-globals/storage.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/assert.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/assert/strict.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/async_hooks.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/buffer.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/child_process.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/cluster.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/console.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/constants.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/crypto.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/dgram.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/dns.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/dns/promises.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/domain.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/events.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/fs.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/fs/promises.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/http.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/http2.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/https.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/inspector.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/inspector.generated.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/module.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/net.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/os.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/path.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/perf_hooks.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/process.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/punycode.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/querystring.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/readline.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/readline/promises.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/repl.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/sea.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/sqlite.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/stream.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/stream/promises.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/stream/consumers.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/stream/web.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/string_decoder.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/test.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/timers.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/timers/promises.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/tls.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/trace_events.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/tty.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/url.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/util.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/v8.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/vm.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/wasi.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/worker_threads.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/zlib.d.ts","../../node_modules/.bun/@types+node@22.19.13/node_modules/@types/node/index.d.ts","../../node_modules/.bun/@types+react@19.2.14/node_modules/@types/react/canary.d.ts","../../node_modules/.bun/@types+react@19.2.14/node_modules/@types/react/experimental.d.ts","../../node_modules/.bun/@types+react-dom@19.2.3+273cdfb19a04c3e9/node_modules/@types/react-dom/index.d.ts","../../node_modules/.bun/@types+react-dom@19.2.3+273cdfb19a04c3e9/node_modules/@types/react-dom/canary.d.ts","../../node_modules/.bun/@types+react-dom@19.2.3+273cdfb19a04c3e9/node_modules/@types/react-dom/experimental.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/fallback.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/compiled/webpack/webpack.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/modern-browserslist-target.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/entry-constants.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/constants.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/config.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/load-custom-routes.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/image-config.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/webpack/plugins/subresource-integrity-plugin.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/body-streams.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/cache-control.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/setup-exception-listeners.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/worker.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/constants.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/bundler.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/experimental/ppr.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/page-types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/segment-config/app/app-segment-config.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/segment-config/pages/pages-segment-config.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/analysis/get-page-static-info.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/webpack/loaders/get-module-build-info.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/webpack/plugins/middleware-plugin.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/require-hook.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/node-polyfill-crypto.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/node-environment-baseline.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/node-environment-extensions/error-inspect.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/node-environment-extensions/console-file.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/node-environment-extensions/console-exit.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/node-environment-extensions/console-dim.external.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/node-environment-extensions/unhandled-rejection.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/node-environment-extensions/random.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/node-environment-extensions/date.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/node-environment-extensions/web-crypto.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/node-environment-extensions/node-crypto.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/node-environment-extensions/fast-set-immediate.external.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/node-environment.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/page-extensions-type.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-kind.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-definitions/route-definition.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-definitions/app-page-route-definition.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/cache-handlers/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/response-cache/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/resume-data-cache/cache-store.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/resume-data-cache/resume-data-cache.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/app-router-headers.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/render-result.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/instrumentation/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/coalesced-function.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/router/utils/middleware-route-matcher.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/router-utils/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/trace/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/trace/trace.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/trace/shared.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/trace/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/load-jsconfig.d.ts","../../node_modules/.bun/@next+env@16.1.6/node_modules/@next/env/dist/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/webpack/plugins/telemetry-plugin/use-cache-tracker-utils.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/webpack/plugins/telemetry-plugin/telemetry-plugin.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/telemetry/storage.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/build-context.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/bloom-filter.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/webpack-config.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/swc/generated-native.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/swc/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/dev/parse-version-info.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/next-devtools/shared/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/dev/dev-indicator-server-state.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/next-devtools/dev-overlay/cache-indicator.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/parse-stack.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/next-devtools/server/shared.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/next-devtools/shared/stack-frame.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/next-devtools/dev-overlay/utils/get-error-by-type.d.ts","../../node_modules/.bun/@types+react@19.2.14/node_modules/@types/react/jsx-runtime.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/next-devtools/dev-overlay/container/runtime-error/render-error.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/next-devtools/dev-overlay/shared.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/dev/debug-channel.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/dev/hot-reloader-types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/i18n-provider.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/web/next-url.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/compiled/@edge-runtime/cookies/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/web/spec-extension/cookies.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/web/spec-extension/request.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/after/builtin-request-context.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/web/spec-extension/fetch-event.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/web/spec-extension/response.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/segment-config/middleware/middleware-config.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/web/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/webpack/plugins/pages-manifest-plugin.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/router/utils/parse-url.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-definitions/locale-route-definition.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-definitions/pages-route-definition.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/webpack/plugins/flight-manifest-plugin.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/webpack/plugins/next-font-manifest-plugin.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/deep-readonly.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/next-devtools/userspace/pages/pages-dev-overlay-setup.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/render.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/mitt.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/with-router.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/router.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/route-loader.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/page-loader.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/router/router.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/router-context.shared-runtime.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/loadable-context.shared-runtime.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/loadable.shared-runtime.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/image-config-context.shared-runtime.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/readonly-url-search-params.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/hooks-client-context.shared-runtime.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/head-manager-context.shared-runtime.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/app-router-types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/flight-data-helpers.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/router-reducer/ppr-navigations.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/segment-cache/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/segment-cache/navigation.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/segment-cache/cache-key.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/router-reducer/fetch-server-response.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/router-reducer/router-reducer-types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/app-router-context.shared-runtime.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/server-inserted-html.shared-runtime.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-modules/pages/vendored/contexts/entrypoints.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-modules/pages/module.compiled.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/templates/pages.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-modules/pages/module.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-modules/pages/builtin/_error.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/load-default-error-components.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/base-http/node.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/response-cache/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-definitions/pages-api-route-definition.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-matches/pages-api-route-match.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-matchers/route-matcher.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-matcher-providers/route-matcher-provider.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-matcher-managers/route-matcher-manager.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/normalizers/normalizer.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/normalizers/locale-route-normalizer.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/normalizers/request/pathname-normalizer.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/normalizers/request/suffix.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/normalizers/request/rsc.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/normalizers/request/next-data.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/normalizers/request/segment-prefix-rsc.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/static-paths/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/base-server.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/async-callback-set.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/router/utils/route-regex.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/router/utils/route-matcher.d.ts","../../node_modules/.bun/sharp@0.34.5/node_modules/sharp/lib/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/image-optimizer.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/next-server.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/lru-cache.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/dev-bundler-service.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/use-cache/cache-life.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/dev/static-paths-worker.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/dev/next-dev-server.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/next.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/render-server.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/router-server.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/router/utils/path-match.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/router-utils/filesystem.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/router-utils/router-server-context.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-modules/route-module.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/load-components.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/web/adapter.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/webpack/loaders/metadata/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/webpack/loaders/next-app-loader/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/app-dir-module.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/web/spec-extension/adapters/request-cookies.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/async-storage/draft-mode-provider.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/web/spec-extension/adapters/headers.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/cache-signal.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/dynamic-rendering.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/request/fallback-params.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/work-unit-async-storage-instance.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/lazy-result.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/implicit-tags.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/staged-rendering.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/work-unit-async-storage.external.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/router/utils/parse-relative-url.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/app-render.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-modules/app-page/vendored/contexts/entrypoints.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/error-boundary.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/layout-router.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/render-from-template-context.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/action-async-storage-instance.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/action-async-storage.external.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/client-page.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/client-segment.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/request/search-params.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/hooks-server-context.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/http-access-fallback/error-boundary.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/metadata/types/alternative-urls-types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/metadata/types/extra-types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/metadata/types/metadata-types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/metadata/types/manifest-types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/metadata/types/opengraph-types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/metadata/types/twitter-types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/metadata/types/metadata-interface.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/metadata/types/resolvers.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/metadata/types/icons.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/metadata/resolve-metadata.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/metadata/metadata.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/lib/framework/boundary-components.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/rsc/preloads.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/rsc/postpone.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/rsc/taint.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/segment-cache/segment-value-encoding.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/collect-segment-data.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/next-devtools/userspace/app/segment-explorer-node.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/entry-base.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/templates/app-page.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/rendering-mode.d.ts","../../node_modules/.bun/@types+react@19.2.14/node_modules/@types/react/jsx-dev-runtime.d.ts","../../node_modules/.bun/@types+react@19.2.14/node_modules/@types/react/compiler-runtime.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/entrypoints.d.ts","../../node_modules/.bun/@types+react-dom@19.2.3+273cdfb19a04c3e9/node_modules/@types/react-dom/client.d.ts","../../node_modules/.bun/@types+react-dom@19.2.3+273cdfb19a04c3e9/node_modules/@types/react-dom/static.d.ts","../../node_modules/.bun/@types+react-dom@19.2.3+273cdfb19a04c3e9/node_modules/@types/react-dom/server.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/entrypoints.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-modules/app-page/module.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-modules/app-page/module.compiled.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-definitions/app-route-route-definition.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/async-storage/work-store.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/web/http.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-modules/app-route/shared-modules.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/redirect-status-code.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/redirect-error.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/templates/app-route.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-modules/app-route/module.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-modules/app-route/module.compiled.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/segment-config/app/app-segments.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/utils.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/router-utils/build-prefetch-segment-data-route.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/turborepo-access-trace/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/turborepo-access-trace/result.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/turborepo-access-trace/helpers.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/turborepo-access-trace/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/export/routes/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/export/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/export/worker.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/worker.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/lib/incremental-cache/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/after/after.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/after/after-context.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/work-async-storage-instance.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/create-error-handler.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/action-revalidation-kind.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/app-render/work-async-storage.external.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/request/params.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/route-matches/route-match.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/request-meta.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/cli/next-test.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/size-limit.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/config-shared.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/base-http/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/api-utils/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/build/adapter/build-complete.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/html-context.shared-runtime.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/utils.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/pages/_app.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/app.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/web/spec-extension/unstable-cache.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/web/spec-extension/revalidate.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/web/spec-extension/unstable-no-store.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/use-cache/cache-tag.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/cache.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/pages/_document.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/document.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/dynamic.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dynamic.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/pages/_error.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/error.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/head.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/head.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/request/cookies.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/request/headers.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/request/draft-mode.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/headers.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/get-img-props.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/image-component.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/shared/lib/image-external.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/image.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/link.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/link.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/unrecognized-action-error.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/redirect.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/not-found.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/forbidden.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/unauthorized.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/unstable-rethrow.server.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/unstable-rethrow.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/navigation.react-server.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/components/navigation.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/navigation.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/router.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/client/script.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/script.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/web/spec-extension/user-agent.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/compiled/@edge-runtime/primitives/url.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/web/spec-extension/image-response.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/compiled/@vercel/og/satori/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/compiled/@vercel/og/emoji/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/compiled/@vercel/og/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/after/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/server/request/connection.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/server.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/types/global.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/types/compiled.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/image-types/global.d.ts","./.next/dev/types/routes.d.ts","./next-env.d.ts","../../node_modules/.bun/@t3-oss+env-core@0.13.10+10bb0f8eb665a8bc/node_modules/@t3-oss/env-core/dist/standard.d.ts","../../node_modules/.bun/@t3-oss+env-core@0.13.10+10bb0f8eb665a8bc/node_modules/@t3-oss/env-core/dist/index.d.ts","../../node_modules/.bun/@t3-oss+env-nextjs@0.13.10+10bb0f8eb665a8bc/node_modules/@t3-oss/env-nextjs/dist/index.d.ts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/json-schema.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/standard-schema.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/registries.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/to-json-schema.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/util.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/versions.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/schemas.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/checks.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/errors.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/core.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/parse.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/regexes.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ar.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/az.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/be.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/bg.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ca.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/cs.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/da.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/de.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/en.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/eo.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/es.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/fa.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/fi.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/fr.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/fr-ca.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/he.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/hu.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/hy.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/id.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/is.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/it.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ja.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ka.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/kh.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/km.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ko.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/lt.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/mk.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ms.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/nl.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/no.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ota.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ps.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/pl.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/pt.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ru.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/sl.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/sv.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ta.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/th.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/tr.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ua.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/uk.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ur.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/uz.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/vi.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/zh-cn.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/zh-tw.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/yo.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/index.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/doc.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/api.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/json-schema-processors.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/json-schema-generator.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/index.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/errors.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/parse.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/schemas.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/checks.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/compat.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/from-json-schema.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/iso.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/coerce.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.d.cts","../../node_modules/.bun/zod@4.3.6/node_modules/zod/index.d.cts","./src/env.ts","./next.config.ts","../../node_modules/.bun/postgres@3.4.8/node_modules/postgres/types/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/entity.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/migrator.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/logger.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/operations.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/table.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/utils.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/casing.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/subquery.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/query-builders/select.types.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sql/sql.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/column.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/checks.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/binary.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/boolean.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/char.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/custom.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/date.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/datetime.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/decimal.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/double.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/enum.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/float.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/int.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/json.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/mediumint.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/real.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/serial.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/smallint.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/text.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/time.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/date.common.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/timestamp.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/tinyint.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/varbinary.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/varchar.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/year.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/all.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/indexes.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/primary-keys.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/unique-constraint.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/table.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/foreign-keys.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/common.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/bigint.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/columns/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sql/expressions/conditions.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sql/expressions/select.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sql/expressions/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sql/functions/aggregate.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sql/functions/vector.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sql/functions/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sql/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/query-builders/query-builder.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/expressions.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/relations.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/query-promise.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/query-builders/delete.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/runnable-query.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/subquery.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/view-base.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/query-builders/select.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/query-builders/query-builder.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/query-builders/update.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/query-builders/insert.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/dialect.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/query-builders/count.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/query-builders/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/query-builders/query.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/db.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/session.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/view-common.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/view.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/query-builders/select.types.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/alias.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/schema.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/alias.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/errors.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/view-common.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/utils.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/mysql-core/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/checks.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/foreign-keys.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/indexes.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/common.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/bigserial.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/boolean.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/char.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/cidr.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/custom.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/date.common.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/date.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/double-precision.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/inet.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/sequence.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/int.common.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/integer.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/timestamp.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/interval.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/json.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/jsonb.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/line.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/macaddr.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/macaddr8.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/numeric.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/point.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/postgis_extension/geometry.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/real.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/serial.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/smallint.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/smallserial.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/text.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/time.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/uuid.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/varchar.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/vector_extension/bit.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/vector_extension/halfvec.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/vector_extension/sparsevec.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/vector_extension/vector.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/all.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/roles.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/policies.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/primary-keys.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/unique-constraint.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/table.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/view-base.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/subquery.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/session.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/session.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/query-builders/select.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/query-builders/query-builder.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/view-common.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/view.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/query-builders/select.types.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/alias.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/query-builders/delete.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/query-builders/update.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/query-builders/insert.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/query-builders/refresh-materialized-view.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/query-builders/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/enum.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/schema.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/utils.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/utils/array.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/utils/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/binary.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/boolean.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/char.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/custom.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/date.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/datetime.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/decimal.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/double.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/enum.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/float.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/int.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/json.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/mediumint.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/real.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/serial.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/smallint.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/text.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/time.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/date.common.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/timestamp.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/tinyint.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/varbinary.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/varchar.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/vector.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/year.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/all.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/indexes.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/primary-keys.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/unique-constraint.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/table.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/common.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/bigint.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/columns/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/query-builders/delete.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/query-builders/update.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/query-builders/insert.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/dialect.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore/session.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore/driver.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/query-builders/count.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/subquery.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/query-builders/select.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/query-builders/query-builder.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/query-builders/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/db.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/session.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/query-builders/select.types.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/alias.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/schema.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/utils.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/singlestore-core/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/checks.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/columns/custom.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/indexes.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/primary-keys.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/unique-constraint.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/query-builders/count.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/query-builders/query.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/subquery.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/view-base.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/db.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/query-builders/raw.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/session.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/query-builders/delete.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/query-builders/update.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/query-builders/insert.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/query-builders/select.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/query-builders/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/dialect.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/query-builders/query-builder.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/view.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/utils.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/columns/integer.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/columns/numeric.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/columns/real.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/columns/text.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/columns/all.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/table.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/foreign-keys.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/columns/common.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/columns/blob.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/columns/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/query-builders/select.types.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/alias.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/sqlite-core/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/column-builder.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/bigint.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/columns/index.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/dialect.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/query-builders/count.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/query-builders/query.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/query-builders/raw.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/pg-core/db.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/postgres-js/session.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/postgres-js/driver.d.ts","../../node_modules/.bun/drizzle-orm@0.38.4+a35bdf041f4b637a/node_modules/drizzle-orm/postgres-js/index.d.ts","../database/src/schema/index.ts","../database/src/db.ts","../database/src/index.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/lib/symbols.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/lib/index.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/lib/vendored/cookie.d.ts","../../node_modules/.bun/oauth4webapi@3.8.5/node_modules/oauth4webapi/build/index.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/lib/utils/cookie.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/warnings.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/lib/utils/logger.d.ts","../../node_modules/.bun/preact@10.24.3/node_modules/preact/src/jsx.d.ts","../../node_modules/.bun/preact@10.24.3/node_modules/preact/src/index.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/providers/credentials.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/providers/provider-types.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/providers/nodemailer.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/providers/email.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/providers/oauth.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/providers/webauthn.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/providers/index.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/adapters.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/lib/utils/webauthn-utils.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/types.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/lib/utils/env.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/jwt.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/lib/utils/actions.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/index.d.ts","../../node_modules/.bun/next-auth@5.0.0-beta.30+8ca1904f0da21ea1/node_modules/next-auth/lib/types.d.ts","../../node_modules/.bun/next-auth@5.0.0-beta.30+8ca1904f0da21ea1/node_modules/next-auth/lib/index.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/errors.d.ts","../../node_modules/.bun/next-auth@5.0.0-beta.30+8ca1904f0da21ea1/node_modules/next-auth/index.d.ts","../../node_modules/.bun/@auth+core@0.41.0/node_modules/@auth/core/providers/microsoft-entra-id.d.ts","../../node_modules/.bun/next-auth@5.0.0-beta.30+8ca1904f0da21ea1/node_modules/next-auth/providers/microsoft-entra-id.d.ts","./src/auth.ts","./src/middleware.ts","./src/actions/events.ts","./src/actions/friends.ts","./src/actions/interactions.ts","./src/actions/map.ts","./src/actions/notifications.ts","./src/actions/orgs.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/abort-handler.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/abort.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/auth/auth.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/auth/httpapikeyauth.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/identity/identity.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/response.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/command.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/endpoint.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/feature-ids.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/logger.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/uri.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/http.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/util.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/middleware.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/auth/httpsigner.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/auth/identityproviderconfig.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/auth/httpauthscheme.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/auth/httpauthschemeprovider.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/auth/index.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/transform/exact.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/externals-check/browser-externals-check.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/blob/blob-payload-input-types.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/crypto.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/checksum.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/client.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/connection/config.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/transfer.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/connection/manager.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/connection/pool.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/connection/index.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/eventstream.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/encode.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/endpoints/shared.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/endpoints/endpointruleobject.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/endpoints/errorruleobject.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/endpoints/treeruleobject.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/endpoints/rulesetobject.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/endpoints/index.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/extensions/checksum.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/extensions/defaultclientconfiguration.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/shapes.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/retry.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/extensions/retry.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/extensions/defaultextensionconfiguration.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/extensions/index.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/http/httphandlerinitialization.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/identity/apikeyidentity.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/identity/awscredentialidentity.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/identity/tokenidentity.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/identity/index.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/pagination.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/profile.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/serde.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/schema/sentinels.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/schema/static-schemas.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/schema/traits.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/schema/schema.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/schema/schema-deprecated.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/signature.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/stream.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/streaming-payload/streaming-blob-common-types.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/streaming-payload/streaming-blob-payload-input-types.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/streaming-payload/streaming-blob-payload-output-types.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/transform/type-transform.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/transform/client-method-transforms.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/transform/client-payload-blob-type-narrow.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/transform/mutable.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/transform/no-undefined.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/waiter.d.ts","../../node_modules/.bun/@smithy+types@4.13.0/node_modules/@smithy/types/dist-types/index.d.ts","../../node_modules/.bun/@smithy+node-config-provider@4.3.11/node_modules/@smithy/node-config-provider/dist-types/fromenv.d.ts","../../node_modules/.bun/@smithy+shared-ini-file-loader@4.4.6/node_modules/@smithy/shared-ini-file-loader/dist-types/gethomedir.d.ts","../../node_modules/.bun/@smithy+shared-ini-file-loader@4.4.6/node_modules/@smithy/shared-ini-file-loader/dist-types/getprofilename.d.ts","../../node_modules/.bun/@smithy+shared-ini-file-loader@4.4.6/node_modules/@smithy/shared-ini-file-loader/dist-types/getssotokenfilepath.d.ts","../../node_modules/.bun/@smithy+shared-ini-file-loader@4.4.6/node_modules/@smithy/shared-ini-file-loader/dist-types/getssotokenfromfile.d.ts","../../node_modules/.bun/@smithy+shared-ini-file-loader@4.4.6/node_modules/@smithy/shared-ini-file-loader/dist-types/constants.d.ts","../../node_modules/.bun/@smithy+shared-ini-file-loader@4.4.6/node_modules/@smithy/shared-ini-file-loader/dist-types/loadsharedconfigfiles.d.ts","../../node_modules/.bun/@smithy+shared-ini-file-loader@4.4.6/node_modules/@smithy/shared-ini-file-loader/dist-types/loadssosessiondata.d.ts","../../node_modules/.bun/@smithy+shared-ini-file-loader@4.4.6/node_modules/@smithy/shared-ini-file-loader/dist-types/parseknownfiles.d.ts","../../node_modules/.bun/@smithy+shared-ini-file-loader@4.4.6/node_modules/@smithy/shared-ini-file-loader/dist-types/externaldatainterceptor.d.ts","../../node_modules/.bun/@smithy+shared-ini-file-loader@4.4.6/node_modules/@smithy/shared-ini-file-loader/dist-types/types.d.ts","../../node_modules/.bun/@smithy+shared-ini-file-loader@4.4.6/node_modules/@smithy/shared-ini-file-loader/dist-types/readfile.d.ts","../../node_modules/.bun/@smithy+shared-ini-file-loader@4.4.6/node_modules/@smithy/shared-ini-file-loader/dist-types/index.d.ts","../../node_modules/.bun/@smithy+node-config-provider@4.3.11/node_modules/@smithy/node-config-provider/dist-types/fromsharedconfigfiles.d.ts","../../node_modules/.bun/@smithy+node-config-provider@4.3.11/node_modules/@smithy/node-config-provider/dist-types/fromstatic.d.ts","../../node_modules/.bun/@smithy+node-config-provider@4.3.11/node_modules/@smithy/node-config-provider/dist-types/configloader.d.ts","../../node_modules/.bun/@smithy+node-config-provider@4.3.11/node_modules/@smithy/node-config-provider/dist-types/index.d.ts","../../node_modules/.bun/@aws-sdk+middleware-flexible-checksums@3.973.4/node_modules/@aws-sdk/middleware-flexible-checksums/dist-types/constants.d.ts","../../node_modules/.bun/@aws-sdk+middleware-flexible-checksums@3.973.4/node_modules/@aws-sdk/middleware-flexible-checksums/dist-types/node_request_checksum_calculation_config_options.d.ts","../../node_modules/.bun/@aws-sdk+middleware-flexible-checksums@3.973.4/node_modules/@aws-sdk/middleware-flexible-checksums/dist-types/node_response_checksum_validation_config_options.d.ts","../../node_modules/.bun/@aws-sdk+middleware-flexible-checksums@3.973.4/node_modules/@aws-sdk/middleware-flexible-checksums/dist-types/resolveflexiblechecksumsconfig.d.ts","../../node_modules/.bun/@aws-sdk+middleware-flexible-checksums@3.973.4/node_modules/@aws-sdk/middleware-flexible-checksums/dist-types/configuration.d.ts","../../node_modules/.bun/@aws-sdk+middleware-flexible-checksums@3.973.4/node_modules/@aws-sdk/middleware-flexible-checksums/dist-types/flexiblechecksumsmiddleware.d.ts","../../node_modules/.bun/@aws-sdk+middleware-flexible-checksums@3.973.4/node_modules/@aws-sdk/middleware-flexible-checksums/dist-types/flexiblechecksumsinputmiddleware.d.ts","../../node_modules/.bun/@aws-sdk+middleware-flexible-checksums@3.973.4/node_modules/@aws-sdk/middleware-flexible-checksums/dist-types/flexiblechecksumsresponsemiddleware.d.ts","../../node_modules/.bun/@aws-sdk+middleware-flexible-checksums@3.973.4/node_modules/@aws-sdk/middleware-flexible-checksums/dist-types/getflexiblechecksumsplugin.d.ts","../../node_modules/.bun/@aws-sdk+middleware-flexible-checksums@3.973.4/node_modules/@aws-sdk/middleware-flexible-checksums/dist-types/index.d.ts","../../node_modules/.bun/@aws-sdk+middleware-host-header@3.972.7/node_modules/@aws-sdk/middleware-host-header/dist-types/index.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/check-content-length-header.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/region-redirect-middleware.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/region-redirect-endpoint-middleware.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/s3-expires-middleware.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/abort.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/auth.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/blob/blob-types.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/checksum.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/client.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/command.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/connection.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/identity/identity.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/identity/anonymousidentity.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/feature-ids.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/identity/awscredentialidentity.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/identity/loginidentity.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/identity/tokenidentity.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/identity/index.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/util.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/credentials.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/crypto.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/dns.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/encode.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/endpoint.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/eventstream.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/extensions/index.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/function.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/http.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/logger.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/middleware.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/pagination.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/profile.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/request.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/response.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/retry.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/serde.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/shapes.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/signature.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/stream.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/token.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/transfer.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/uri.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/waiter.d.ts","../../node_modules/.bun/@aws-sdk+types@3.973.5/node_modules/@aws-sdk/types/dist-types/index.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/s3-express/interfaces/s3expressidentity.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/s3-express/classes/s3expressidentitycacheentry.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/s3-express/classes/s3expressidentitycache.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/s3-express/interfaces/s3expressidentityprovider.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/s3-express/classes/s3expressidentityproviderimpl.d.ts","../../node_modules/.bun/@smithy+signature-v4@5.3.11/node_modules/@smithy/signature-v4/dist-types/signaturev4base.d.ts","../../node_modules/.bun/@smithy+signature-v4@5.3.11/node_modules/@smithy/signature-v4/dist-types/signaturev4.d.ts","../../node_modules/.bun/@smithy+signature-v4@5.3.11/node_modules/@smithy/signature-v4/dist-types/constants.d.ts","../../node_modules/.bun/@smithy+signature-v4@5.3.11/node_modules/@smithy/signature-v4/dist-types/getcanonicalheaders.d.ts","../../node_modules/.bun/@smithy+signature-v4@5.3.11/node_modules/@smithy/signature-v4/dist-types/getcanonicalquery.d.ts","../../node_modules/.bun/@smithy+signature-v4@5.3.11/node_modules/@smithy/signature-v4/dist-types/getpayloadhash.d.ts","../../node_modules/.bun/@smithy+signature-v4@5.3.11/node_modules/@smithy/signature-v4/dist-types/moveheaderstoquery.d.ts","../../node_modules/.bun/@smithy+signature-v4@5.3.11/node_modules/@smithy/signature-v4/dist-types/preparerequest.d.ts","../../node_modules/.bun/@smithy+signature-v4@5.3.11/node_modules/@smithy/signature-v4/dist-types/credentialderivation.d.ts","../../node_modules/.bun/@smithy+signature-v4@5.3.11/node_modules/@smithy/signature-v4/dist-types/headerutil.d.ts","../../node_modules/.bun/@smithy+signature-v4@5.3.11/node_modules/@smithy/signature-v4/dist-types/signature-v4a-container.d.ts","../../node_modules/.bun/@smithy+signature-v4@5.3.11/node_modules/@smithy/signature-v4/dist-types/index.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/s3-express/classes/signaturev4s3express.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/s3-express/constants.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/s3-express/functions/s3expressmiddleware.d.ts","../../node_modules/.bun/@smithy+protocol-http@5.3.11/node_modules/@smithy/protocol-http/dist-types/httprequest.d.ts","../../node_modules/.bun/@smithy+protocol-http@5.3.11/node_modules/@smithy/protocol-http/dist-types/httpresponse.d.ts","../../node_modules/.bun/@smithy+protocol-http@5.3.11/node_modules/@smithy/protocol-http/dist-types/httphandler.d.ts","../../node_modules/.bun/@smithy+protocol-http@5.3.11/node_modules/@smithy/protocol-http/dist-types/extensions/httpextensionconfiguration.d.ts","../../node_modules/.bun/@smithy+protocol-http@5.3.11/node_modules/@smithy/protocol-http/dist-types/extensions/index.d.ts","../../node_modules/.bun/@smithy+protocol-http@5.3.11/node_modules/@smithy/protocol-http/dist-types/field.d.ts","../../node_modules/.bun/@smithy+protocol-http@5.3.11/node_modules/@smithy/protocol-http/dist-types/fields.d.ts","../../node_modules/.bun/@smithy+protocol-http@5.3.11/node_modules/@smithy/protocol-http/dist-types/isvalidhostname.d.ts","../../node_modules/.bun/@smithy+protocol-http@5.3.11/node_modules/@smithy/protocol-http/dist-types/types.d.ts","../../node_modules/.bun/@smithy+protocol-http@5.3.11/node_modules/@smithy/protocol-http/dist-types/index.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/s3-express/functions/s3expresshttpsigningmiddleware.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/s3-express/index.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/s3configuration.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/throw-200-exceptions.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/validate-bucket-name.d.ts","../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.18/node_modules/@aws-sdk/middleware-sdk-s3/dist-types/index.d.ts","../../node_modules/.bun/@aws-sdk+middleware-user-agent@3.972.19/node_modules/@aws-sdk/middleware-user-agent/dist-types/configurations.d.ts","../../node_modules/.bun/@aws-sdk+middleware-user-agent@3.972.19/node_modules/@aws-sdk/middleware-user-agent/dist-types/user-agent-middleware.d.ts","../../node_modules/.bun/@aws-sdk+middleware-user-agent@3.972.19/node_modules/@aws-sdk/middleware-user-agent/dist-types/index.d.ts","../../node_modules/.bun/@smithy+config-resolver@4.4.10/node_modules/@smithy/config-resolver/dist-types/endpointsconfig/nodeusedualstackendpointconfigoptions.d.ts","../../node_modules/.bun/@smithy+config-resolver@4.4.10/node_modules/@smithy/config-resolver/dist-types/endpointsconfig/nodeusefipsendpointconfigoptions.d.ts","../../node_modules/.bun/@smithy+config-resolver@4.4.10/node_modules/@smithy/config-resolver/dist-types/endpointsconfig/resolveendpointsconfig.d.ts","../../node_modules/.bun/@smithy+config-resolver@4.4.10/node_modules/@smithy/config-resolver/dist-types/endpointsconfig/resolvecustomendpointsconfig.d.ts","../../node_modules/.bun/@smithy+config-resolver@4.4.10/node_modules/@smithy/config-resolver/dist-types/endpointsconfig/index.d.ts","../../node_modules/.bun/@smithy+config-resolver@4.4.10/node_modules/@smithy/config-resolver/dist-types/regionconfig/config.d.ts","../../node_modules/.bun/@smithy+config-resolver@4.4.10/node_modules/@smithy/config-resolver/dist-types/regionconfig/resolveregionconfig.d.ts","../../node_modules/.bun/@smithy+config-resolver@4.4.10/node_modules/@smithy/config-resolver/dist-types/regionconfig/index.d.ts","../../node_modules/.bun/@smithy+config-resolver@4.4.10/node_modules/@smithy/config-resolver/dist-types/regioninfo/endpointvarianttag.d.ts","../../node_modules/.bun/@smithy+config-resolver@4.4.10/node_modules/@smithy/config-resolver/dist-types/regioninfo/endpointvariant.d.ts","../../node_modules/.bun/@smithy+config-resolver@4.4.10/node_modules/@smithy/config-resolver/dist-types/regioninfo/partitionhash.d.ts","../../node_modules/.bun/@smithy+config-resolver@4.4.10/node_modules/@smithy/config-resolver/dist-types/regioninfo/regionhash.d.ts","../../node_modules/.bun/@smithy+config-resolver@4.4.10/node_modules/@smithy/config-resolver/dist-types/regioninfo/getregioninfo.d.ts","../../node_modules/.bun/@smithy+config-resolver@4.4.10/node_modules/@smithy/config-resolver/dist-types/regioninfo/index.d.ts","../../node_modules/.bun/@smithy+config-resolver@4.4.10/node_modules/@smithy/config-resolver/dist-types/index.d.ts","../../node_modules/.bun/@smithy+eventstream-serde-config-resolver@4.3.11/node_modules/@smithy/eventstream-serde-config-resolver/dist-types/eventstreamserdeconfig.d.ts","../../node_modules/.bun/@smithy+eventstream-serde-config-resolver@4.3.11/node_modules/@smithy/eventstream-serde-config-resolver/dist-types/index.d.ts","../../node_modules/.bun/@smithy+middleware-endpoint@4.4.23/node_modules/@smithy/middleware-endpoint/dist-types/resolveendpointconfig.d.ts","../../node_modules/.bun/@smithy+middleware-endpoint@4.4.23/node_modules/@smithy/middleware-endpoint/dist-types/types.d.ts","../../node_modules/.bun/@smithy+middleware-endpoint@4.4.23/node_modules/@smithy/middleware-endpoint/dist-types/adaptors/getendpointfrominstructions.d.ts","../../node_modules/.bun/@smithy+middleware-endpoint@4.4.23/node_modules/@smithy/middleware-endpoint/dist-types/adaptors/toendpointv1.d.ts","../../node_modules/.bun/@smithy+middleware-endpoint@4.4.23/node_modules/@smithy/middleware-endpoint/dist-types/adaptors/index.d.ts","../../node_modules/.bun/@smithy+middleware-endpoint@4.4.23/node_modules/@smithy/middleware-endpoint/dist-types/endpointmiddleware.d.ts","../../node_modules/.bun/@smithy+middleware-endpoint@4.4.23/node_modules/@smithy/middleware-endpoint/dist-types/getendpointplugin.d.ts","../../node_modules/.bun/@smithy+middleware-endpoint@4.4.23/node_modules/@smithy/middleware-endpoint/dist-types/resolveendpointrequiredconfig.d.ts","../../node_modules/.bun/@smithy+middleware-endpoint@4.4.23/node_modules/@smithy/middleware-endpoint/dist-types/index.d.ts","../../node_modules/.bun/@smithy+util-retry@4.2.11/node_modules/@smithy/util-retry/dist-types/types.d.ts","../../node_modules/.bun/@smithy+util-retry@4.2.11/node_modules/@smithy/util-retry/dist-types/adaptiveretrystrategy.d.ts","../../node_modules/.bun/@smithy+util-retry@4.2.11/node_modules/@smithy/util-retry/dist-types/standardretrystrategy.d.ts","../../node_modules/.bun/@smithy+util-retry@4.2.11/node_modules/@smithy/util-retry/dist-types/configuredretrystrategy.d.ts","../../node_modules/.bun/@smithy+util-retry@4.2.11/node_modules/@smithy/util-retry/dist-types/defaultratelimiter.d.ts","../../node_modules/.bun/@smithy+util-retry@4.2.11/node_modules/@smithy/util-retry/dist-types/config.d.ts","../../node_modules/.bun/@smithy+util-retry@4.2.11/node_modules/@smithy/util-retry/dist-types/constants.d.ts","../../node_modules/.bun/@smithy+util-retry@4.2.11/node_modules/@smithy/util-retry/dist-types/index.d.ts","../../node_modules/.bun/@smithy+middleware-retry@4.4.40/node_modules/@smithy/middleware-retry/dist-types/types.d.ts","../../node_modules/.bun/@smithy+middleware-retry@4.4.40/node_modules/@smithy/middleware-retry/dist-types/standardretrystrategy.d.ts","../../node_modules/.bun/@smithy+middleware-retry@4.4.40/node_modules/@smithy/middleware-retry/dist-types/adaptiveretrystrategy.d.ts","../../node_modules/.bun/@smithy+middleware-retry@4.4.40/node_modules/@smithy/middleware-retry/dist-types/configurations.d.ts","../../node_modules/.bun/@smithy+middleware-retry@4.4.40/node_modules/@smithy/middleware-retry/dist-types/delaydecider.d.ts","../../node_modules/.bun/@smithy+middleware-retry@4.4.40/node_modules/@smithy/middleware-retry/dist-types/omitretryheadersmiddleware.d.ts","../../node_modules/.bun/@smithy+middleware-retry@4.4.40/node_modules/@smithy/middleware-retry/dist-types/retrydecider.d.ts","../../node_modules/.bun/@smithy+middleware-retry@4.4.40/node_modules/@smithy/middleware-retry/dist-types/retrymiddleware.d.ts","../../node_modules/.bun/@smithy+middleware-retry@4.4.40/node_modules/@smithy/middleware-retry/dist-types/index.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/client.d.ts","../../node_modules/.bun/@smithy+util-stream@4.5.17/node_modules/@smithy/util-stream/dist-types/blob/uint8arrayblobadapter.d.ts","../../node_modules/.bun/@smithy+util-stream@4.5.17/node_modules/@smithy/util-stream/dist-types/checksum/checksumstream.d.ts","../../node_modules/.bun/@smithy+util-stream@4.5.17/node_modules/@smithy/util-stream/dist-types/checksum/checksumstream.browser.d.ts","../../node_modules/.bun/@smithy+util-stream@4.5.17/node_modules/@smithy/util-stream/dist-types/checksum/createchecksumstream.browser.d.ts","../../node_modules/.bun/@smithy+util-stream@4.5.17/node_modules/@smithy/util-stream/dist-types/checksum/createchecksumstream.d.ts","../../node_modules/.bun/@smithy+util-stream@4.5.17/node_modules/@smithy/util-stream/dist-types/createbufferedreadable.d.ts","../../node_modules/.bun/@smithy+util-stream@4.5.17/node_modules/@smithy/util-stream/dist-types/getawschunkedencodingstream.d.ts","../../node_modules/.bun/@smithy+util-stream@4.5.17/node_modules/@smithy/util-stream/dist-types/headstream.d.ts","../../node_modules/.bun/@smithy+util-stream@4.5.17/node_modules/@smithy/util-stream/dist-types/sdk-stream-mixin.d.ts","../../node_modules/.bun/@smithy+util-stream@4.5.17/node_modules/@smithy/util-stream/dist-types/splitstream.d.ts","../../node_modules/.bun/@smithy+util-stream@4.5.17/node_modules/@smithy/util-stream/dist-types/stream-type-check.d.ts","../../node_modules/.bun/@smithy+util-stream@4.5.17/node_modules/@smithy/util-stream/dist-types/index.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/protocols/collect-stream-body.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/protocols/extended-encode-uri-component.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/deref.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/middleware/schema-middleware-types.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/middleware/getschemaserdeplugin.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/schemas/schema.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/schemas/listschema.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/schemas/mapschema.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/schemas/operationschema.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/schemas/operation.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/schemas/structureschema.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/schemas/errorschema.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/schemas/normalizedschema.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/schemas/simpleschema.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/schemas/sentinels.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/schemas/translatetraits.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/typeregistry.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/schema/index.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/event-streams/eventstreamserde.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/event-streams/index.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/protocols/serdecontext.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/protocols/httpprotocol.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/protocols/httpbindingprotocol.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/protocols/rpcprotocol.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/protocols/requestbuilder.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/protocols/resolve-path.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/protocols/serde/fromstringshapedeserializer.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/protocols/serde/httpinterceptingshapedeserializer.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/protocols/serde/tostringshapeserializer.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/protocols/serde/httpinterceptingshapeserializer.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/protocols/serde/determinetimestampformat.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/protocols/index.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/collect-stream-body.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/command.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/constants.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/create-aggregated-client.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/default-error-handler.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/defaults-mode.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/emitwarningifunsupportedversion.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/exceptions.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/extended-encode-uri-component.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/extensions/checksum.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/extensions/retry.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/extensions/defaultextensionconfiguration.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/extensions/index.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/get-array-if-single-item.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/get-value-from-text-node.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/is-serializable-header-value.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/nooplogger.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/object-mapping.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/resolve-path.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/ser-utils.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/serde-json.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/serde/copydocumentwithtransform.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/serde/date-utils.d.ts","../../node_modules/.bun/@smithy+uuid@1.1.2/node_modules/@smithy/uuid/dist-types/v4.d.ts","../../node_modules/.bun/@smithy+uuid@1.1.2/node_modules/@smithy/uuid/dist-types/index.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/serde/generateidempotencytoken.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/serde/lazy-json.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/serde/parse-utils.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/serde/quote-header.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/serde/schema-serde-lib/schema-date-utils.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/serde/split-every.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/serde/split-header.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/serde/value/numericvalue.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/serde/index.d.ts","../../node_modules/.bun/@smithy+smithy-client@4.12.3/node_modules/@smithy/smithy-client/dist-types/index.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/client/emitwarningifunsupportedversion.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/client/setcredentialfeature.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/client/setfeature.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/client/settokenfeature.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/client/index.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/httpauthschemes/aws_sdk/resolveawssdksigv4aconfig.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/httpauthschemes/aws_sdk/awssdksigv4signer.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/httpauthschemes/aws_sdk/awssdksigv4asigner.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/httpauthschemes/aws_sdk/node_auth_scheme_preference_options.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/httpauthschemes/aws_sdk/resolveawssdksigv4config.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/httpauthschemes/aws_sdk/index.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/httpauthschemes/utils/getbearertokenenvkey.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/httpauthschemes/index.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/cbor/cbor.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/cbor/cbor-types.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/cbor/parsecborbody.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/cbor/cborcodec.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/cbor/smithyrpcv2cborprotocol.d.ts","../../node_modules/.bun/@smithy+core@3.23.9/node_modules/@smithy/core/dist-types/submodules/cbor/index.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/cbor/awssmithyrpcv2cborprotocol.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/coercing-serializers.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/configurableserdecontext.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/jsonshapedeserializer.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/jsonshapeserializer.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/jsoncodec.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/awsjsonrpcprotocol.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/awsjson1_0protocol.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/awsjson1_1protocol.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/awsrestjsonprotocol.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/awsexpectunion.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/parsejsonbody.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/xml/xmlshapeserializer.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/xml/xmlcodec.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/xml/xmlshapedeserializer.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/query/queryserializersettings.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/query/queryshapeserializer.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/query/awsqueryprotocol.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/query/awsec2queryprotocol.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/xml/awsrestxmlprotocol.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/xml/parsexmlbody.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/submodules/protocols/index.d.ts","../../node_modules/.bun/@aws-sdk+core@3.973.18/node_modules/@aws-sdk/core/dist-types/index.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/endpoint/endpointparameters.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/auth/httpauthschemeprovider.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/models/enums.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/models/models_0.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/abortmultipartuploadcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/completemultipartuploadcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/copyobjectcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/createbucketcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/createbucketmetadataconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/createbucketmetadatatableconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/createmultipartuploadcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/createsessioncommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletebucketanalyticsconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletebucketcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletebucketcorscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletebucketencryptioncommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletebucketintelligenttieringconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletebucketinventoryconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletebucketlifecyclecommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletebucketmetadataconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletebucketmetadatatableconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletebucketmetricsconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletebucketownershipcontrolscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletebucketpolicycommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletebucketreplicationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletebuckettaggingcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletebucketwebsitecommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deleteobjectcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deleteobjectscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deleteobjecttaggingcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/deletepublicaccessblockcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketabaccommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketaccelerateconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketaclcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketanalyticsconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketcorscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketencryptioncommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketintelligenttieringconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketinventoryconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketlifecycleconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketlocationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketloggingcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketmetadataconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketmetadatatableconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketmetricsconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketnotificationconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketownershipcontrolscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketpolicycommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketpolicystatuscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketreplicationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketrequestpaymentcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbuckettaggingcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketversioningcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getbucketwebsitecommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getobjectaclcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getobjectattributescommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getobjectcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getobjectlegalholdcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getobjectlockconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getobjectretentioncommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getobjecttaggingcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getobjecttorrentcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/getpublicaccessblockcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/headbucketcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/headobjectcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/listbucketanalyticsconfigurationscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/listbucketintelligenttieringconfigurationscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/listbucketinventoryconfigurationscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/listbucketmetricsconfigurationscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/listbucketscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/listdirectorybucketscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/listmultipartuploadscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/listobjectscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/listobjectsv2command.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/listobjectversionscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/listpartscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketabaccommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketaccelerateconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketaclcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketanalyticsconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketcorscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketencryptioncommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketintelligenttieringconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketinventoryconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketlifecycleconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketloggingcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketmetricsconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketnotificationconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketownershipcontrolscommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketpolicycommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketreplicationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketrequestpaymentcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbuckettaggingcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketversioningcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putbucketwebsitecommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putobjectaclcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putobjectcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putobjectlegalholdcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putobjectlockconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putobjectretentioncommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putobjecttaggingcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/putpublicaccessblockcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/renameobjectcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/models/models_1.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/restoreobjectcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/selectobjectcontentcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/updatebucketmetadatainventorytableconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/updatebucketmetadatajournaltableconfigurationcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/updateobjectencryptioncommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/uploadpartcommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/uploadpartcopycommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/writegetobjectresponsecommand.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/auth/httpauthextensionconfiguration.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/extensionconfiguration.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/runtimeextensions.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/s3client.d.ts","../../node_modules/.bun/@smithy+util-waiter@4.2.11/node_modules/@smithy/util-waiter/dist-types/waiter.d.ts","../../node_modules/.bun/@smithy+util-waiter@4.2.11/node_modules/@smithy/util-waiter/dist-types/createwaiter.d.ts","../../node_modules/.bun/@smithy+util-waiter@4.2.11/node_modules/@smithy/util-waiter/dist-types/index.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/s3.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/commands/index.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/schemas/schemas_0.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/pagination/interfaces.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/pagination/listbucketspaginator.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/pagination/listdirectorybucketspaginator.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/pagination/listobjectsv2paginator.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/pagination/listpartspaginator.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/pagination/index.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/waiters/waitforbucketexists.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/waiters/waitforbucketnotexists.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/waiters/waitforobjectexists.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/waiters/waitforobjectnotexists.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/waiters/index.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/models/s3serviceexception.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/models/errors.d.ts","../../node_modules/.bun/@aws-sdk+client-s3@3.1004.0/node_modules/@aws-sdk/client-s3/dist-types/index.d.ts","../../node_modules/.bun/@aws-sdk+s3-request-presigner@3.1004.0/node_modules/@aws-sdk/s3-request-presigner/dist-types/getsignedurl.d.ts","../../node_modules/.bun/@aws-sdk+signature-v4-multi-region@3.996.6/node_modules/@aws-sdk/signature-v4-multi-region/dist-types/signaturev4multiregion.d.ts","../../node_modules/.bun/@aws-sdk+signature-v4-multi-region@3.996.6/node_modules/@aws-sdk/signature-v4-multi-region/dist-types/signature-v4-crt-container.d.ts","../../node_modules/.bun/@aws-sdk+signature-v4-multi-region@3.996.6/node_modules/@aws-sdk/signature-v4-multi-region/dist-types/index.d.ts","../../node_modules/.bun/@aws-sdk+s3-request-presigner@3.1004.0/node_modules/@aws-sdk/s3-request-presigner/dist-types/presigner.d.ts","../../node_modules/.bun/@aws-sdk+s3-request-presigner@3.1004.0/node_modules/@aws-sdk/s3-request-presigner/dist-types/index.d.ts","./src/actions/upload.ts","./src/actions/users.ts","./src/app/api/auth/[...nextauth]/route.ts","./src/lib/princeton-departments.ts","../../node_modules/.bun/clsx@2.1.1/node_modules/clsx/clsx.d.mts","../../node_modules/.bun/tailwind-merge@3.5.0/node_modules/tailwind-merge/dist/types.d.ts","./src/lib/utils.ts","./src/types/next-auth.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/compiled/@next/font/dist/types.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/dist/compiled/@next/font/dist/google/index.d.ts","../../node_modules/.bun/next@16.1.6+bf16f8eded5e12ee/node_modules/next/font/google/index.d.ts","../../node_modules/.bun/lucide-react@0.575.0+b1ab299f0a400331/node_modules/lucide-react/dist/lucide-react.d.ts","../../node_modules/.bun/next-themes@0.4.6+bf16f8eded5e12ee/node_modules/next-themes/dist/index.d.ts","../../node_modules/.bun/sonner@2.0.7+bf16f8eded5e12ee/node_modules/sonner/dist/index.d.mts","./src/components/ui/sonner.tsx","./src/app/layout.tsx","./src/app/page.tsx","../../node_modules/.bun/next-auth@5.0.0-beta.30+8ca1904f0da21ea1/node_modules/next-auth/lib/client.d.ts","../../node_modules/.bun/next-auth@5.0.0-beta.30+8ca1904f0da21ea1/node_modules/next-auth/react.d.ts","./src/components/layout/geometric-background.tsx","./src/components/layout/sidebar.tsx","../../node_modules/.bun/@radix-ui+react-accessible-icon@1.1.7+243b16c7711ca280/node_modules/@radix-ui/react-accessible-icon/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-context@1.1.2+26a211c426f3f87c/node_modules/@radix-ui/react-context/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-primitive@2.1.3+243b16c7711ca280/node_modules/@radix-ui/react-primitive/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-collapsible@1.1.12+243b16c7711ca280/node_modules/@radix-ui/react-collapsible/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-accordion@1.2.12+243b16c7711ca280/node_modules/@radix-ui/react-accordion/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-dismissable-layer@1.1.11+243b16c7711ca280/node_modules/@radix-ui/react-dismissable-layer/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-focus-scope@1.1.7+243b16c7711ca280/node_modules/@radix-ui/react-focus-scope/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-portal@1.1.9+243b16c7711ca280/node_modules/@radix-ui/react-portal/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-dialog@1.1.15+243b16c7711ca280/node_modules/@radix-ui/react-dialog/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-alert-dialog@1.1.15+243b16c7711ca280/node_modules/@radix-ui/react-alert-dialog/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-aspect-ratio@1.1.7+243b16c7711ca280/node_modules/@radix-ui/react-aspect-ratio/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-avatar@1.1.10+243b16c7711ca280/node_modules/@radix-ui/react-avatar/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-checkbox@1.3.3+243b16c7711ca280/node_modules/@radix-ui/react-checkbox/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-arrow@1.1.7+243b16c7711ca280/node_modules/@radix-ui/react-arrow/dist/index.d.mts","../../node_modules/.bun/@radix-ui+rect@1.1.1/node_modules/@radix-ui/rect/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-popper@1.2.8+243b16c7711ca280/node_modules/@radix-ui/react-popper/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-roving-focus@1.1.11+243b16c7711ca280/node_modules/@radix-ui/react-roving-focus/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-menu@2.1.16+243b16c7711ca280/node_modules/@radix-ui/react-menu/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-context-menu@2.2.16+243b16c7711ca280/node_modules/@radix-ui/react-context-menu/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-direction@1.1.1+26a211c426f3f87c/node_modules/@radix-ui/react-direction/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-dropdown-menu@2.1.16+243b16c7711ca280/node_modules/@radix-ui/react-dropdown-menu/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-label@2.1.7+243b16c7711ca280/node_modules/@radix-ui/react-label/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-form@0.1.8+243b16c7711ca280/node_modules/@radix-ui/react-form/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-hover-card@1.1.15+243b16c7711ca280/node_modules/@radix-ui/react-hover-card/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-menubar@1.1.16+243b16c7711ca280/node_modules/@radix-ui/react-menubar/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-visually-hidden@1.2.3+243b16c7711ca280/node_modules/@radix-ui/react-visually-hidden/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-navigation-menu@1.2.14+243b16c7711ca280/node_modules/@radix-ui/react-navigation-menu/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-one-time-password-field@0.1.8+243b16c7711ca280/node_modules/@radix-ui/react-one-time-password-field/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-password-toggle-field@0.1.3+243b16c7711ca280/node_modules/@radix-ui/react-password-toggle-field/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-popover@1.1.15+243b16c7711ca280/node_modules/@radix-ui/react-popover/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-progress@1.1.7+243b16c7711ca280/node_modules/@radix-ui/react-progress/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-radio-group@1.3.8+243b16c7711ca280/node_modules/@radix-ui/react-radio-group/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-scroll-area@1.2.10+243b16c7711ca280/node_modules/@radix-ui/react-scroll-area/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-select@2.2.6+243b16c7711ca280/node_modules/@radix-ui/react-select/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-separator@1.1.7+243b16c7711ca280/node_modules/@radix-ui/react-separator/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-slider@1.3.6+243b16c7711ca280/node_modules/@radix-ui/react-slider/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-slot@1.2.3+26a211c426f3f87c/node_modules/@radix-ui/react-slot/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-switch@1.2.6+243b16c7711ca280/node_modules/@radix-ui/react-switch/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-tabs@1.1.13+243b16c7711ca280/node_modules/@radix-ui/react-tabs/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-toast@1.2.15+243b16c7711ca280/node_modules/@radix-ui/react-toast/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-toggle@1.1.10+243b16c7711ca280/node_modules/@radix-ui/react-toggle/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-toggle-group@1.1.11+243b16c7711ca280/node_modules/@radix-ui/react-toggle-group/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-toolbar@1.1.11+243b16c7711ca280/node_modules/@radix-ui/react-toolbar/dist/index.d.mts","../../node_modules/.bun/@radix-ui+react-tooltip@1.2.8+243b16c7711ca280/node_modules/@radix-ui/react-tooltip/dist/index.d.mts","../../node_modules/.bun/radix-ui@1.4.3+243b16c7711ca280/node_modules/radix-ui/dist/index.d.mts","./src/components/ui/popover.tsx","./src/components/layout/notification-dropdown.tsx","./src/components/layout/top-bar.tsx","./src/app/(app)/layout.tsx","./src/components/events/event-cover-art.tsx","./src/components/social/avatar-stack.tsx","./src/components/events/event-card.tsx","./src/app/(app)/events/my-events-client.tsx","./src/app/(app)/events/page.tsx","../../node_modules/.bun/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/types.d.ts","../../node_modules/.bun/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.d.ts","./src/components/ui/button.tsx","./src/components/ui/dialog.tsx","./src/app/(app)/events/[id]/event-detail-client.tsx","./src/app/(app)/events/[id]/page.tsx","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/constants.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/types.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/fp/types.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/types.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/add.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/addbusinessdays.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/adddays.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/addhours.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/addisoweekyears.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/addmilliseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/addminutes.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/addmonths.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/addquarters.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/addseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/addweeks.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/addyears.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/areintervalsoverlapping.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/clamp.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/closestindexto.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/closestto.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/compareasc.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/comparedesc.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/constructfrom.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/constructnow.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/daystoweeks.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceinbusinessdays.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceincalendardays.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceincalendarisoweekyears.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceincalendarisoweeks.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceincalendarmonths.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceincalendarquarters.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceincalendarweeks.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceincalendaryears.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceindays.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceinhours.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceinisoweekyears.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceinmilliseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceinminutes.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceinmonths.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceinquarters.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceinseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceinweeks.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/differenceinyears.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/eachdayofinterval.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/eachhourofinterval.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/eachminuteofinterval.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/eachmonthofinterval.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/eachquarterofinterval.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/eachweekofinterval.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/eachweekendofinterval.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/eachweekendofmonth.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/eachweekendofyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/eachyearofinterval.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/endofday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/endofdecade.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/endofhour.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/endofisoweek.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/endofisoweekyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/endofminute.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/endofmonth.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/endofquarter.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/endofsecond.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/endoftoday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/endoftomorrow.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/endofweek.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/endofyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/endofyesterday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/_lib/format/formatters.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/_lib/format/longformatters.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/format.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/formatdistance.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/formatdistancestrict.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/formatdistancetonow.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/formatdistancetonowstrict.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/formatduration.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/formatiso.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/formatiso9075.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/formatisoduration.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/formatrfc3339.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/formatrfc7231.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/formatrelative.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/fromunixtime.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getdate.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getdayofyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getdaysinmonth.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getdaysinyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getdecade.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/_lib/defaultoptions.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getdefaultoptions.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/gethours.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getisoday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getisoweek.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getisoweekyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getisoweeksinyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getmilliseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getminutes.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getmonth.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getoverlappingdaysinintervals.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getquarter.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/gettime.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getunixtime.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getweek.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getweekofmonth.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getweekyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getweeksinmonth.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/getyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/hourstomilliseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/hourstominutes.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/hourstoseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/interval.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/intervaltoduration.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/intlformat.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/intlformatdistance.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isafter.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isbefore.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isdate.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isequal.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isexists.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isfirstdayofmonth.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isfriday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isfuture.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/islastdayofmonth.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isleapyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/ismatch.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/ismonday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/ispast.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/issameday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/issamehour.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/issameisoweek.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/issameisoweekyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/issameminute.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/issamemonth.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/issamequarter.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/issamesecond.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/issameweek.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/issameyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/issaturday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/issunday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isthishour.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isthisisoweek.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isthisminute.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isthismonth.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isthisquarter.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isthissecond.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isthisweek.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isthisyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isthursday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/istoday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/istomorrow.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/istuesday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isvalid.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/iswednesday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isweekend.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/iswithininterval.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/isyesterday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/lastdayofdecade.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/lastdayofisoweek.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/lastdayofisoweekyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/lastdayofmonth.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/lastdayofquarter.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/lastdayofweek.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/lastdayofyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/_lib/format/lightformatters.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/lightformat.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/max.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/milliseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/millisecondstohours.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/millisecondstominutes.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/millisecondstoseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/min.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/minutestohours.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/minutestomilliseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/minutestoseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/monthstoquarters.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/monthstoyears.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/nextday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/nextfriday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/nextmonday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/nextsaturday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/nextsunday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/nextthursday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/nexttuesday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/nextwednesday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/parse/_lib/types.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/parse/_lib/setter.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/parse/_lib/parser.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/parse/_lib/parsers.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/parse.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/parseiso.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/parsejson.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/previousday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/previousfriday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/previousmonday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/previoussaturday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/previoussunday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/previousthursday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/previoustuesday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/previouswednesday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/quarterstomonths.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/quarterstoyears.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/roundtonearesthours.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/roundtonearestminutes.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/secondstohours.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/secondstomilliseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/secondstominutes.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/set.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/setdate.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/setday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/setdayofyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/setdefaultoptions.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/sethours.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/setisoday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/setisoweek.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/setisoweekyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/setmilliseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/setminutes.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/setmonth.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/setquarter.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/setseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/setweek.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/setweekyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/setyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/startofday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/startofdecade.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/startofhour.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/startofisoweek.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/startofisoweekyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/startofminute.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/startofmonth.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/startofquarter.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/startofsecond.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/startoftoday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/startoftomorrow.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/startofweek.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/startofweekyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/startofyear.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/startofyesterday.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/sub.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/subbusinessdays.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/subdays.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/subhours.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/subisoweekyears.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/submilliseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/subminutes.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/submonths.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/subquarters.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/subseconds.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/subweeks.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/subyears.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/todate.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/transpose.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/weekstodays.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/yearstodays.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/yearstomonths.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/yearstoquarters.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/index.d.ts","../../node_modules/.bun/@date-fns+tz@1.4.1/node_modules/@date-fns/tz/constants/index.d.ts","../../node_modules/.bun/@date-fns+tz@1.4.1/node_modules/@date-fns/tz/date/index.d.ts","../../node_modules/.bun/@date-fns+tz@1.4.1/node_modules/@date-fns/tz/date/mini.d.ts","../../node_modules/.bun/@date-fns+tz@1.4.1/node_modules/@date-fns/tz/tz/index.d.ts","../../node_modules/.bun/@date-fns+tz@1.4.1/node_modules/@date-fns/tz/tzoffset/index.d.ts","../../node_modules/.bun/@date-fns+tz@1.4.1/node_modules/@date-fns/tz/tzscan/index.d.ts","../../node_modules/.bun/@date-fns+tz@1.4.1/node_modules/@date-fns/tz/tzname/index.d.ts","../../node_modules/.bun/@date-fns+tz@1.4.1/node_modules/@date-fns/tz/index.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/af.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ar.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ar-dz.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ar-eg.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ar-ma.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ar-sa.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ar-tn.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/az.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/be.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/be-tarask.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/bg.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/bn.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/bs.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ca.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ckb.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/cs.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/cy.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/da.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/de.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/de-at.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/el.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/en-au.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/en-ca.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/en-gb.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/en-ie.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/en-in.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/en-nz.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/en-us.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/en-za.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/eo.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/es.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/et.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/eu.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/fa-ir.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/fi.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/fr.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/fr-ca.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/fr-ch.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/fy.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/gd.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/gl.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/gu.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/he.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/hi.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/hr.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ht.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/hu.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/hy.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/id.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/is.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/it.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/it-ch.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ja.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ja-hira.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ka.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/kk.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/km.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/kn.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ko.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/lb.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/lt.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/lv.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/mk.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/mn.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ms.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/mt.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/nb.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/nl.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/nl-be.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/nn.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/oc.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/pl.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/pt.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/pt-br.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ro.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ru.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/se.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/sk.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/sl.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/sq.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/sr.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/sr-latn.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/sv.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ta.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/te.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/th.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/tr.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/ug.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/uk.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/uz.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/uz-cyrl.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/vi.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/zh-cn.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/zh-hk.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale/zh-tw.d.ts","../../node_modules/.bun/date-fns@4.1.0/node_modules/date-fns/locale.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/button.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/captionlabel.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/chevron.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/monthcaption.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/week.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/labels/labeldaybutton.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/labels/labelgrid.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/labels/labelgridcell.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/labels/labelmonthdropdown.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/labels/labelnav.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/labels/labelnext.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/labels/labelprevious.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/labels/labelweekday.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/labels/labelweeknumber.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/labels/labelweeknumberheader.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/labels/labelyeardropdown.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/labels/index.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/ui.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/classes/calendarweek.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/classes/calendarmonth.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/types/props.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/types/selection.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/usedaypicker.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/types/deprecated.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/types/index.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/day.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/daybutton.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/dropdown.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/dropdownnav.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/footer.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/month.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/monthgrid.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/months.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/monthsdropdown.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/nav.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/nextmonthbutton.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/option.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/previousmonthbutton.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/root.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/select.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/weekday.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/weekdays.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/weeknumber.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/weeknumberheader.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/weeks.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/yearsdropdown.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/components/custom-components.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/formatters/formatcaption.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/formatters/formatday.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/formatters/formatmonthdropdown.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/formatters/formatweekdayname.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/formatters/formatweeknumber.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/formatters/formatweeknumberheader.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/formatters/formatyeardropdown.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/formatters/index.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/types/shared.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/locale/en-us.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/classes/datelib.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/classes/calendarday.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/classes/index.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/daypicker.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/helpers/getdefaultclassnames.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/helpers/index.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/utils/addtorange.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/utils/datematchmodifiers.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/utils/rangecontainsdayofweek.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/utils/rangecontainsmodifiers.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/utils/rangeincludesdate.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/utils/rangeoverlaps.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/utils/typeguards.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/utils/index.d.ts","../../node_modules/.bun/react-day-picker@9.14.0+b1ab299f0a400331/node_modules/react-day-picker/dist/esm/index.d.ts","./src/components/ui/calendar.tsx","./src/components/ui/input.tsx","./src/components/ui/textarea.tsx","./src/app/(app)/events/[id]/edit/edit-event-form.tsx","./src/app/(app)/events/[id]/edit/page.tsx","./src/components/events/cover-presets.tsx","./src/components/events/event-preview-modal.tsx","./src/app/(app)/events/create/create-event-form.tsx","./src/app/(app)/events/create/page.tsx","./src/components/events/event-filters.tsx","./src/app/(app)/explore/explore-client.tsx","./src/app/(app)/explore/page.tsx","./src/app/(app)/friends/friends-client.tsx","./src/app/(app)/friends/page.tsx","../../node_modules/.bun/@types+geojson@7946.0.16/node_modules/@types/geojson/index.d.ts","../../node_modules/.bun/@types+leaflet@1.9.21/node_modules/@types/leaflet/index.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/hooks.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/attributioncontrol.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/attribution.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/context.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/element.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/events.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/layer.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/path.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/circle.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/div-overlay.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/component.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/control.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/dom.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/generic.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/grid-layer.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/media-overlay.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/pane.d.ts","../../node_modules/.bun/@react-leaflet+core@3.0.0+6cb16f106a3e28aa/node_modules/@react-leaflet/core/lib/index.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/circle.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/circlemarker.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/layergroup.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/featuregroup.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/geojson.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/imageoverlay.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/layerscontrol.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/mapcontainer.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/marker.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/pane.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/polygon.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/polyline.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/popup.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/rectangle.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/scalecontrol.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/svgoverlay.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/tilelayer.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/tooltip.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/videooverlay.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/wmstilelayer.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/zoomcontrol.d.ts","../../node_modules/.bun/react-leaflet@5.0.0+6cb16f106a3e28aa/node_modules/react-leaflet/lib/index.d.ts","./src/app/(app)/map/map-client.tsx","./src/app/(app)/map/page.tsx","./src/app/(app)/orgs/orgs-client.tsx","./src/app/(app)/orgs/page.tsx","./src/app/(app)/orgs/[id]/org-profile-client.tsx","./src/app/(app)/orgs/[id]/page.tsx","./src/components/ui/label.tsx","./src/app/(app)/orgs/create/page.tsx","./src/app/(app)/settings/settings-client.tsx","./src/app/(app)/settings/page.tsx","./src/app/(onboarding)/onboarding/layout.tsx","./src/app/(onboarding)/onboarding/page.tsx","./src/app/5/page.tsx","./src/app/6/page.tsx","./src/app/7/page.tsx","./src/app/8/page.tsx","./src/components/ui/avatar.tsx","./src/components/ui/badge.tsx","./src/components/ui/card.tsx","../../node_modules/.bun/cmdk@1.1.1+243b16c7711ca280/node_modules/cmdk/dist/index.d.ts","./src/components/ui/command.tsx","./src/components/ui/dropdown-menu.tsx","./src/components/ui/scroll-area.tsx","./src/components/ui/select.tsx","./src/components/ui/separator.tsx","./src/components/ui/sheet.tsx","./src/components/ui/skeleton.tsx","./src/components/ui/tabs.tsx","./src/components/ui/tooltip.tsx","./.next/types/routes.d.ts","./.next/types/validator.ts","./.next/dev/types/cache-life.d.ts","./.next/dev/types/validator.ts"],"fileIdsList":[[97,145,162,163],[97,145,162,163,598,840,841],[97,145,162,163,677,841,842],[97,145,162,163,677,744],[97,145,162,163,464,465,466,467],[97,145,162,163,273,508,511,514,1371,1384,1385,1438,1443,1449,1888,1892,1895,1897,1941,1943,1945,1947,1949,1950,1951,1952,1953,1954,1955],[97,145,162,163,273,508,511,1371,1384,1385,1438,1443,1449,1888,1892,1895,1897,1941,1943,1945,1947,1949,1950,1951,1952,1953,1954,1955,1969],[97,145,162,163,512,513,514],[97,145,162,163,273,512,596],[97,145,162,163,273,843,873,1971],[97,145,162,163,273,843,873],[97,145,162,163,273,596,873,1362,1368],[85,97,145,162,163,273,496,875,1369,1375,1380,1435,1707,1884,1885,1886],[97,145,162,163,273,496,875,1887],[85,97,145,162,163,273,486,496,875,1375,1380,1382,1439,1440,1441,1446,1447],[97,145,162,163,273,496,875,1448],[85,97,145,162,163,273,496,875,1369,1375,1380,1435,1707,1884,1885,1886,1889,1890],[97,145,162,163,273,875,880,1891],[85,97,145,162,163,273,486,875,1375,1380,1439,1441],[97,145,162,163,273,875,1442],[85,97,145,162,163,273,486,875,1380,1441,1893],[97,145,162,163,273,873,875,1894],[85,97,145,162,163,273,876,1375,1380],[97,145,162,163,273,876,1896],[97,145,162,163,273,1387,1388,1389,1437],[85,97,145,162,163,273,472,486,878,1375,1380,1899,1939],[97,145,162,163,273,878,1940],[85,97,145,162,163,273,486,496,876,880,1375,1380,1382,1441],[97,145,162,163,273,496,880,1944],[85,97,145,162,163,273,496,880,1369,1375,1380,1446,1885,1886,1946],[85,97,145,162,163,273,486,880,1375,1380,1446,1885],[97,145,162,163,273,880,1942],[97,145,162,163,273,876,1370,1948],[85,97,145,162,163,273,486,496,876,1369,1370,1375,1380],[97,145,162,163,273,1387,1388],[85,97,145,162,163,273,1370,1372,1375,1387],[97,145,162,163,273,1380],[97,145,162,163,273,873],[97,145,162,163,273,512,1379,1383],[97,145,162,163,273,596,843,870,872,1376],[97,145,162,163,273,1375,1380],[85,97,145,162,163,273,486,877,1380,1439,1440],[97,145,162,163,273],[85,97,145,162,163,273,1375,1380],[97,145,162,163,273,1380,1439,1889],[85,97,145,162,163,273,496,876,879,1375,1380,1435],[97,145,162,163,273,486,496,1375,1380,1387],[97,145,162,163,273,486,1380,1387,1436],[85,97,145,162,163,273,1375,1434],[85,97,145,162,163,273,1375,1434,1445],[85,97,145,162,163,273,1375,1380,1446,1883],[85,97,145,162,163,273,1375],[85,97,145,162,163,273,1375,1380,1447,1959],[85,97,145,162,163,273,1375,1380,1434,1446],[85,97,145,162,163,273,1375,1380,1434],[97,145,162,163,273,1375],[97,145,162,163,273,1380,1381,1382],[97,145,162,163,273,518,595],[97,145,162,163,273,1373,1374],[97,145,162,163,870,1376],[97,145,162,163,859,862],[97,145,162,163,844,845,850,859,860,862,863,864,865],[97,145,162,163,850,862],[97,145,162,163,844],[97,145,162,163,862],[97,145,162,163,862,866],[97,145,162,163,849,866],[97,145,162,163,848,858,860,862],[97,145,162,163,852,859,862],[97,145,162,163,854,855,859,862],[97,145,162,163,853,856,857,858,862],[97,145,162,163,859],[97,145,162,163,856,862],[97,145,162,163,844,847,854,859,862,866],[97,145,162,163,846,847,848,849,850,859,861,866],[97,145,162,163,950,1042,1228],[97,145,162,163,950,1042,1226,1227,1342],[97,145,162,163,950,1042,1087,1184,1230,1342],[97,145,162,163,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1331,1332,1333,1334,1335,1336,1337,1338],[97,145,162,163,950,1042,1087,1184,1230,1330,1342],[97,145,162,163,950,1042,1087,1184,1330,1342],[97,145,162,163,950,1042],[97,145,162,163,950,1022,1042,1052,1339],[97,145,162,163,1227,1229,1230,1330,1340,1341,1342,1346,1347,1348,1354,1359,1360,1361],[97,145,162,163,1184,1229,1360],[97,145,162,163,950,1042,1229],[97,145,162,163,950,1042,1229,1230],[97,145,162,163,1184],[97,145,162,163,1349,1350,1351,1352,1353],[97,145,162,163,950,1042,1342],[97,145,162,163,950,1042,1296,1349],[97,145,162,163,950,1042,1297,1349],[97,145,162,163,950,1042,1300,1349],[97,145,162,163,950,1042,1302,1349],[97,145,162,163,1340],[97,145,162,163,950,1042,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1331,1332,1333,1334,1335,1336,1337,1338,1342,1345],[97,145,162,163,177,950,977,978,1022,1042,1052,1058,1061,1076,1078,1087,1104,1184,1227,1228,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1331,1332,1333,1334,1335,1336,1337,1338,1341],[97,145,162,163,950,1042,1135],[97,145,162,163,1355,1356,1357,1358],[97,145,162,163,1290,1342,1345],[97,145,162,163,1291,1342,1345],[97,145,162,163,1189,1197,1225],[97,145,162,163,1185,1186,1187,1188],[97,145,162,163,1022],[97,145,162,163,950,1042,1191],[97,145,162,163,950,1042,1190],[97,145,162,163,1190,1191,1192,1193,1194],[97,145,162,163,967],[97,145,162,163,950,967,1042],[97,145,162,163,950,1022,1039,1042],[97,145,162,163,1195,1196],[97,145,162,163,950,1042,1203],[97,145,162,163,1204,1205,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1221,1222,1223,1224],[97,145,162,163,1209,1210],[97,145,162,163,950,1042,1149,1209],[97,145,162,163,950,1042,1206,1207,1208],[97,145,162,163,950,1042,1206,1209],[97,145,162,163,950,1042,1135,1206,1209],[97,145,162,163,1221],[97,145,162,163,950,1042,1149,1218,1220],[97,145,162,163,950,1042,1206,1219],[97,145,162,163,950,1042,1149,1217],[97,145,162,163,950,1042,1206,1216,1218],[97,145,162,163,950,1042,1206,1217],[97,145,162,163,950,968,971,1042],[97,145,162,163,950,972,1042],[97,145,162,163,950,972,973,974,975,1042],[97,145,162,163,968,969,970,971,973,976],[97,145,162,163,967,968],[97,145,162,163,950,968,1042],[97,145,162,163,979,980,981,982,1054,1055,1056,1057],[97,145,162,163,950,980,1042],[97,145,162,163,1024],[97,145,162,163,1023],[97,145,162,163,1022,1023,1025,1026],[97,145,162,163,950,1042,1052],[97,145,162,163,950,1022,1023,1026,1042],[97,145,162,163,1023,1024,1025,1026,1027,1040,1041,1042,1053],[97,145,162,163,1022,1023],[97,145,162,163,950,1042,1054],[97,145,162,163,950,1042,1055],[97,145,162,163,1059,1060],[97,145,162,163,950,1022,1042,1059],[97,145,162,163,950,1042,1184],[97,145,162,163,1363,1367],[97,145,162,163,950,1042,1366],[97,145,162,163,1364,1365],[97,145,162,163,950,1022,1042],[97,145,162,163,950,1039,1042],[97,145,162,163,950,996,997,1042],[97,145,162,163,990],[97,145,162,163,950,992,1042],[97,145,162,163,990,991,993,994,995],[97,145,162,163,983,984,985,986,987,988,989,992,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021],[97,145,162,163,996,997],[97,145,162,163,1708],[97,145,162,163,1709],[97,145,162,163,1708,1709,1710,1711,1712,1713,1714],[85,97,145,162,163],[85,97,145,162,163,1391,1392,1393],[85,97,145,162,163,1391,1398],[85,97,145,162,163,1392],[85,97,145,162,163,1391,1392],[85,97,145,162,163,273,1391,1392],[85,97,145,162,163,1391,1392,1407],[85,97,145,162,163,1391,1392,1395,1396,1397],[85,97,145,162,163,273,1391,1392,1411],[85,97,145,162,163,1391,1392,1395,1397,1405],[85,97,145,162,163,1391,1392,1395,1396,1397,1405,1406],[85,97,145,162,163,273,1391,1392,1406,1407],[85,97,145,162,163,1391,1392,1395,1415],[85,97,145,162,163,1392,1406],[85,97,145,162,163,1391,1392,1395,1396,1397,1405],[85,97,145,162,163,1391,1392,1403,1404],[85,97,145,162,163,1391,1392,1406],[85,97,145,162,163,1391,1392,1395],[85,97,145,162,163,1391,1392,1406,1430],[85,97,145,162,163,1391,1392,1406,1424,1431],[97,145,162,163,1899],[85,97,145,162,163,1899,1907],[85,97,145,162,163,1904,1909],[85,97,145,162,163,1899],[97,145,162,163,1899,1904],[97,145,162,163,1899,1903,1904,1906],[85,97,145,162,163,1903],[85,97,145,162,163,1899,1903,1904,1906,1907,1909,1910],[97,145,162,163,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916],[97,145,162,163,1899,1903,1904,1905],[97,145,162,163,1899,1906],[97,145,162,163,1899,1903],[97,145,162,163,1899,1904,1906],[97,145,162,163,1062,1063,1064,1065],[97,145,162,163,950,1042,1064],[97,145,162,163,1066,1069,1075],[97,145,162,163,1067,1068],[97,145,162,163,1070],[97,145,162,163,950,1042,1072,1073],[97,145,162,163,1072,1073,1074],[97,145,162,163,1071],[97,145,162,163,950,1042,1149],[97,145,162,163,1198,1199,1200,1201,1202],[97,145,162,163,950,1042,1052,1199],[97,145,162,163,950,1042,1135,1149,1201],[97,145,162,163,1136],[97,145,162,163,950,1042,1117],[97,145,162,163,950,1042,1052,1135,1139],[97,145,162,163,950,1042,1135,1137,1138],[97,145,162,163,1118,1119,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148],[97,145,162,163,950,1042,1135,1139],[97,145,162,163,950,1042,1138],[97,145,162,163,950,1042,1146],[97,145,162,163,1120,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134],[97,145,162,163,950,1042,1121],[97,145,162,163,950,1042,1128],[97,145,162,163,950,1042,1123],[97,145,162,163,950,1042,1129],[97,145,162,163,1174],[97,145,162,163,1171,1172,1175,1176,1177,1178,1179,1180,1181,1182],[97,145,162,163,1077],[97,145,162,163,950,1042,1079,1080],[97,145,162,163,1081,1082],[97,145,162,163,1079,1080,1083,1084,1085,1086],[97,145,162,163,950,1042,1095,1097],[97,145,162,163,1097,1098,1099,1100,1101,1102,1103],[97,145,162,163,950,1042,1099],[97,145,162,163,950,1042,1096],[97,145,162,163,950,951,964,965,1042],[97,145,162,163,950,963,1042],[97,145,162,163,951,964,965,966],[97,145,162,163,1045],[97,145,162,163,1046],[97,145,162,163,950,1042,1048],[97,145,162,163,950,1042,1043,1044],[97,145,162,163,1043,1044,1045,1047,1048,1049,1050,1051],[97,145,162,163,952,953,954,955,957,958,959,960,961,962],[97,145,162,163,950,956,1042],[97,145,162,163,950,957,1042],[97,145,162,163,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038],[97,145,162,163,950,1028,1042],[97,145,162,163,1149],[97,145,162,163,950,1042,1087],[97,145,162,163,1105],[97,145,162,163,950,1042,1159,1160],[97,145,162,163,1161],[97,145,162,163,950,1042,1105,1150,1151,1152,1153,1154,1155,1156,1157,1158,1162,1163,1164,1165,1166,1167,1168,1169,1170,1183],[97,145,162,163,882],[97,145,162,163,881],[97,145,162,163,885,894,895,896],[97,145,162,163,894,897],[97,145,162,163,885,892],[97,145,162,163,885,897],[97,145,162,163,883,884,895,896,897,898],[97,145,162,163,177,901],[97,145,162,163,903],[97,145,162,163,886,887,893,894],[97,145,162,163,886,894],[97,145,162,163,906,908,909],[97,145,162,163,906,907],[97,145,162,163,911],[97,145,162,163,883],[97,145,162,163,888,913],[97,145,162,163,913],[97,145,162,163,913,914,915,916,917],[97,145,162,163,916],[97,145,162,163,890],[97,145,162,163,913,914,915],[97,145,162,163,886,892,894],[97,145,162,163,903,904],[97,145,162,163,919],[97,145,162,163,919,923],[97,145,162,163,919,920,923,924],[97,145,162,163,893,922],[97,145,162,163,900],[97,145,162,163,882,891],[97,145,159,161,162,163,890,892],[97,145,162,163,885],[97,145,162,163,885,927,928,929],[97,145,162,163,882,886,887,888,889,890,891,892,893,894,899,902,903,904,905,907,910,911,912,918,921,922,925,926,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,946,947,948,949],[97,145,162,163,883,887,888,889,890,893,897],[97,145,162,163,887,905],[97,145,162,163,921],[97,145,162,163,886,888,894,933,935,937],[97,145,162,163,886,888,894,933,934,935,936],[97,145,162,163,937],[97,145,162,163,892,893,907,937],[97,145,162,163,886,892],[97,145,162,163,892,911],[97,145,162,163,893,903,904],[97,145,159,162,163,177,901,933],[97,145,162,163,886,887,943,944],[97,145,159,160,162,163,887,892,905,933,942,943,944,945],[97,145,162,163,887,905,921],[97,145,162,163,892],[97,145,162,163,950,1042,1088],[97,145,162,163,950,1042,1090],[97,145,162,163,1088],[97,145,162,163,1088,1089,1090,1091,1092,1093,1094],[97,145,162,163,177,950,1042],[97,145,162,163,1108],[97,145,162,163,177,1107,1109],[97,145,162,163,177],[97,145,162,163,1106,1107,1110,1111,1112,1113,1114,1115,1116],[97,145,162,163,1343],[97,145,162,163,1343,1344],[97,145,162,163,1173],[97,145,162,163,516],[97,145,162,163,517],[97,145,162,163,1898],[97,142,143,145,162,163],[97,144,145,162,163],[145,162,163],[97,145,150,162,163,180],[97,145,146,151,156,162,163,165,177,188],[97,145,146,147,156,162,163,165],[92,93,94,97,145,162,163],[97,145,148,162,163,189],[97,145,149,150,157,162,163,166],[97,145,150,162,163,177,185],[97,145,151,153,156,162,163,165],[97,144,145,152,162,163],[97,145,153,154,162,163],[97,145,155,156,162,163],[97,144,145,156,162,163],[97,145,156,157,158,162,163,177,188],[97,145,156,157,158,162,163,172,177,180],[97,138,145,153,156,159,162,163,165,177,188],[97,145,156,157,159,160,162,163,165,177,185,188],[97,145,159,161,162,163,177,185,188],[95,96,97,98,99,100,101,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194],[97,145,156,162,163],[97,145,162,163,164,188],[97,145,153,156,162,163,165,177],[97,145,162,163,166],[97,145,162,163,167],[97,144,145,162,163,168],[97,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194],[97,145,162,163,170],[97,145,162,163,171],[97,145,156,162,163,172,173],[97,145,162,163,172,174,189,191],[97,145,157,162,163],[97,145,156,162,163,177,178,180],[97,145,162,163,179,180],[97,145,162,163,177,178],[97,145,162,163,180],[97,145,162,163,181],[97,142,145,162,163,177,182,188],[97,145,156,162,163,183,184],[97,145,162,163,183,184],[97,145,150,162,163,165,177,185],[97,145,162,163,186],[97,145,162,163,165,187],[97,145,159,162,163,171,188],[97,145,150,162,163,189],[97,145,162,163,177,190],[97,145,162,163,164,191],[97,145,162,163,192],[97,138,145,162,163],[97,138,145,156,158,162,163,168,177,180,188,190,191,193],[97,145,162,163,177,194],[85,89,97,145,162,163,196,197,198,200,459,505],[85,89,97,145,162,163,196,197,198,199,416,459,505],[85,89,97,145,162,163,196,197,199,200,459,505],[85,97,145,162,163,200,416,417],[85,97,145,162,163,200,416],[85,89,97,145,162,163,197,198,199,200,459,505],[85,89,97,145,162,163,196,198,199,200,459,505],[83,84,97,145,162,163],[97,145,162,163,1373,1444],[97,145,162,163,1373],[85,97,145,162,163,1398],[97,145,162,163,1453],[97,145,162,163,1451,1453],[97,145,162,163,1451],[97,145,162,163,1453,1517,1518],[97,145,162,163,1453,1520],[97,145,162,163,1453,1521],[97,145,162,163,1538],[97,145,162,163,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630,1631,1632,1633,1634,1639,1640,1641,1642,1643,1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706],[97,145,162,163,1453,1614],[97,145,162,163,1451,1716,1717,1718,1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,1779,1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808,1809,1810],[97,145,162,163,1453,1518,1638],[97,145,162,163,1451,1635,1636],[97,145,162,163,1637],[97,145,162,163,1453,1635],[97,145,162,163,1450,1451,1452],[97,145,162,163,599,603,608,609,653],[97,145,162,163,599,604,609],[97,145,162,163,599,604,608,609,679,744,795,829],[97,145,162,163,599,603,604,608,830],[97,145,162,163,599],[97,145,162,163,646],[97,145,162,163,599,601,602,603,604,606,609,650,652,653,654,674,675,676,830],[97,145,162,163,639,658,671],[97,145,162,163,599,608,639],[97,145,162,163,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,630,631,632,633,634,642],[97,145,162,163,599,609,641,830],[97,145,162,163,599,604,609,641,830],[97,145,162,163,599,604,608,609,639,640,830],[97,145,162,163,599,604,608,609,639,641,830],[97,145,162,163,599,604,609,639,641,830],[97,145,162,163,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,630,631,632,633,634,641,642],[97,145,162,163,599,609,621,641,830],[97,145,162,163,599,604,609,629,830],[97,145,162,163,599,604,606,608,639,651,653,657,658,663,664,665,666,668,671],[97,145,162,163,599,600,604,608,639,641,653,655,661,662,668,671],[97,145,162,163,599,639,643],[97,145,162,163,610,636,637,638,639,640,643,657,663,665,667,668,669,670,672,673,678],[97,145,162,163,599,608,639,643],[97,145,162,163,599,608,639,658,668],[97,145,162,163,599,604,606,608,639,641,654,663,668,671],[97,145,162,163,655,659,660,661,662,671],[97,145,162,163,599,603,608,639,641,651,654,656,660,661,663,668,671],[97,145,162,163,599,606,608,651,657,659,663,671],[97,145,162,163,599,604,608,639,653,654,663,668],[97,145,162,163,599,604,606,607,608,636,639,643,651,654,657,658,663,668,671],[97,145,162,163,602,603,604,606,607,608,639,643,651,658,659,668,670],[97,145,162,163,599,604,606,608,609,639,641,654,663,668,671],[97,145,162,163,599,639,670],[97,145,162,163,599,604,608,653,663,667,671],[97,145,162,163,606,607,608],[97,145,162,163,599,603,610,635,636,637,638,640,641,830],[97,145,162,163,609,610,636,637,638,639,640,659,670,677,679,830],[97,145,162,163,599,608],[97,145,162,163,599,607,608,643,651,658,660,669,830],[97,145,162,163,603,608,609],[97,145,162,163,723,724,732],[97,145,162,163,599,650,723],[97,145,162,163,684,685,686,687,688,690,691,692,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,831],[97,145,162,163,599,609,683,694,830],[97,145,162,163,599,609,683,830],[97,145,162,163,599,604,609,683,830],[97,145,162,163,599,604,608,609,681,682,723,830],[97,145,162,163,599,604,608,609,683,723,830],[97,145,162,163,599,683,830],[97,145,162,163,599,604,609,683,689,830],[97,145,162,163,599,604,609,683,723,830],[97,145,162,163,683,684,685,686,687,688,690,691,692,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,739,831],[97,145,162,163,599,683,693,830],[97,145,162,163,599,609,683,696,830],[97,145,162,163,599,609,683,723,830],[97,145,162,163,599,609,683,689,696,723,830],[97,145,162,163,599,604,609,683,689,723,830],[97,145,162,163,599,604,606,608,651,653,723,724,725,727,731,732,737,738,832,833,834,835,836],[97,145,162,163,599,600,604,608,653,723,727,731,732,738,832],[97,145,162,163,599,723,832],[97,145,162,163,680,681,682,693,719,720,721,722,723,725,727,730,731,733,738,740,741,743,832,833,837],[97,145,162,163,599,608,723,832],[97,145,162,163,599,608,719,723],[97,145,162,163,599,604,608,723,727],[97,145,162,163,599,606,607,608,654,656,723,727,732,833],[97,145,162,163,728,729,732,734,735,736,737],[97,145,162,163,599,603,606,607,608,651,654,656,682,683,723,727,729,732,735,833],[97,145,162,163,599,606,608,651,725,728,732,832,833],[97,145,162,163,599,604,608,653,654,656,723,727,833],[97,145,162,163,599,608,654,656,726],[97,145,162,163,599,608,654,656,727,731,833],[97,145,162,163,599,604,606,607,608,651,654,656,723,724,725,727,732,832,833],[97,145,162,163,602,603,604,606,607,608,651,723,724,727,728,731,832],[97,145,162,163,599,603,604,606,607,608,609,654,656,683,723,724,727,732,833],[97,145,162,163,599,608,693,723,731,739],[97,145,162,163,599,604,650,653,726,732,833,837],[97,145,162,163,599,603,680,681,682,683,718,720,721,722,830],[97,145,162,163,609,677,680,681,682,720,721,722,723,731,744,830,832],[97,145,162,163,742],[97,145,162,163,599,604,607,608,651,683,724,729,730,830],[97,145,162,163,598,599,604,837,838],[97,145,162,163,838,839],[97,145,162,163,598,599,601,604,608,653,727,732,744,833],[97,145,162,163,599,650],[97,145,162,163,602,603,604,606,608,609,830],[97,145,162,163,599,603,604,608,609,646,652],[97,145,162,163,830],[97,145,162,163,677],[97,145,162,163,774,791],[97,145,162,163,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,764,765,766,767,768,769,776],[97,145,162,163,599,609,775,830],[97,145,162,163,599,604,609,775,830],[97,145,162,163,599,604,609,774,830],[97,145,162,163,599,604,608,609,774,775,830],[97,145,162,163,599,604,609,774,775,830],[97,145,162,163,599,604,609,650,775,830],[97,145,162,163,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,764,765,766,767,768,769,775,776],[97,145,162,163,599,609,755,775,830],[97,145,162,163,599,604,609,763,830],[97,145,162,163,599,606,608,651,653,774,781,783,784,785,788,790,791],[97,145,162,163,599,600,604,608,653,774,775,778,779,780,790,791],[97,145,162,163,771,772,773,774,777,781,785,788,789,790,792,793,794],[97,145,162,163,599,608,774,777],[97,145,162,163,599,774,777],[97,145,162,163,599,608,774,790],[97,145,162,163,599,604,606,608,654,774,775,781,790,791],[97,145,162,163,778,779,780,786,787,791],[97,145,162,163,599,603,608,654,656,774,775,779,781,790,791],[97,145,162,163,599,606,608,651,781,785,786,791],[97,145,162,163,599,604,606,607,608,651,654,774,777,781,785,790,791],[97,145,162,163,602,603,604,606,607,608,651,774,777,786,790],[97,145,162,163,599,604,606,608,609,654,774,775,781,790,791],[97,145,162,163,599,774],[97,145,162,163,599,604,608,653,781,789,791],[97,145,162,163,599,603,770,771,772,773,775,830],[97,145,162,163,609,771,772,773,774,795,830],[97,145,162,163,599,601,604,653,781,782,789],[97,145,162,163,599,601,604,608,653,781,790,791],[97,145,162,163,608,609],[97,145,162,163,644,645],[97,145,162,163,647,648],[97,145,162,163,608,609,651],[97,145,162,163,608,646,649],[97,145,162,163,599,603,604,605,606,607,609],[97,145,162,163,804,822,827],[97,145,162,163,599,608,822],[97,145,162,163,797,817,818,819,820,825],[97,145,162,163,599,604,609,824,830],[97,145,162,163,599,604,608,609,822,823,830],[97,145,162,163,599,604,608,609,822,824,830],[97,145,162,163,797,817,818,819,820,824,825],[97,145,162,163,599,604,609,816,822,824,830],[97,145,162,163,599,609,824,830],[97,145,162,163,599,604,609,822,824,830],[97,145,162,163,599,604,606,608,651,653,801,802,803,804,807,812,813,822,827],[97,145,162,163,599,600,604,608,653,807,812,822,826,827],[97,145,162,163,599,822,826],[97,145,162,163,796,798,799,800,803,805,807,812,813,815,816,822,823,826,828],[97,145,162,163,599,608,822,826],[97,145,162,163,599,608,807,815,822],[97,145,162,163,599,604,606,607,608,654,656,807,813,822,824,827],[97,145,162,163,808,809,810,811,814,827],[97,145,162,163,599,604,606,607,608,651,654,656,798,807,809,813,814,822,824,827],[97,145,162,163,599,606,608,651,803,811,813,827],[97,145,162,163,599,604,608,653,654,656,807,813,822],[97,145,162,163,599,608,654,656,726,813],[97,145,162,163,599,604,606,607,608,651,654,656,803,804,807,813,822,826,827],[97,145,162,163,602,603,604,606,607,608,651,804,807,811,815,822,826],[97,145,162,163,599,604,606,607,608,609,654,656,804,807,813,822,824,827],[97,145,162,163,599,608,653,654,726,805,806,813,827],[97,145,162,163,599,603,796,798,799,800,821,823,824,830],[97,145,162,163,599,822,824],[97,145,162,163,677,796,798,799,800,815,822,823,829],[97,145,162,163,599,607,608,651,804,814,824,830],[97,145,162,163,599,602,604,608,609],[97,145,162,163,601,603,608,609],[97,145,162,163,508,512,859,862,866,867,868,869],[85,97,145,162,163,859,862,869],[97,145,162,163,508,512,862,866,867],[97,145,162,163,508],[97,145,162,163,871],[85,97,145,162,163,859,862,1386],[97,145,162,163,462],[97,145,162,163,205,207,211,222,412,442,455],[97,145,162,163,207,217,218,219,221,455],[97,145,162,163,207,254,256,258,259,262,455,457],[97,145,162,163,207,211,213,214,215,245,340,412,432,433,441,455,457],[97,145,162,163,455],[97,145,162,163,218,310,421,430,450],[97,145,162,163,207],[97,145,162,163,201,310,450],[97,145,162,163,264],[97,145,162,163,263,455],[97,145,159,162,163,410,421,510],[97,145,159,162,163,378,390,430,449],[97,145,159,162,163,321],[97,145,162,163,435],[97,145,162,163,434,435,436],[97,145,162,163,434],[91,97,145,159,162,163,201,207,211,214,216,218,222,223,236,237,264,340,351,431,442,455,459],[97,145,162,163,205,207,220,254,255,260,261,455,510],[97,145,162,163,220,510],[97,145,162,163,205,237,365,455,510],[97,145,162,163,510],[97,145,162,163,207,220,221,510],[97,145,162,163,257,510],[97,145,162,163,223,432,440],[97,145,162,163,171,273,450],[97,145,162,163,273,450],[85,97,145,162,163,273],[85,97,145,162,163,382],[97,145,162,163,308,318,319,450,487,494],[97,145,162,163,307,427,488,489,490,491,493],[97,145,162,163,426],[97,145,162,163,426,427],[97,145,162,163,245,310,311,315],[97,145,162,163,310],[97,145,162,163,310,314,316],[97,145,162,163,310,311,312,313],[97,145,162,163,492],[85,97,145,162,163,208,481],[85,97,145,162,163,188],[85,97,145,162,163,220,300],[85,97,145,162,163,220,442],[97,145,162,163,298,302],[85,97,145,162,163,299,461],[97,145,162,163,1377],[85,89,97,145,159,162,163,195,196,197,198,199,200,459,503,504],[97,145,159,162,163],[97,145,159,162,163,211,244,296,341,362,364,437,438,442,455,456],[97,145,162,163,236,439],[97,145,162,163,459],[97,145,162,163,206],[85,97,145,162,163,367,380,389,399,401,449],[97,145,162,163,171,367,380,398,399,400,449,509],[97,145,162,163,392,393,394,395,396,397],[97,145,162,163,394],[97,145,162,163,398],[97,145,162,163,271,272,273,275],[85,97,145,162,163,265,266,267,268,274],[97,145,162,163,271,274],[97,145,162,163,269],[97,145,162,163,270],[85,97,145,162,163,273,299,461],[85,97,145,162,163,273,460,461],[85,97,145,162,163,273,461],[97,145,162,163,341,444],[97,145,162,163,444],[97,145,159,162,163,456,461],[97,145,162,163,386],[97,144,145,162,163,385],[97,145,162,163,246,310,327,364,373,376,378,379,420,449,452,456],[97,145,162,163,292,310,407],[97,145,162,163,378,449],[85,97,145,162,163,378,383,384,386,387,388,389,390,391,402,403,404,405,406,408,409,449,450,510],[97,145,162,163,372],[97,145,159,162,163,171,208,244,247,268,293,294,341,351,362,363,420,443,455,456,457,459,510],[97,145,162,163,449],[97,144,145,162,163,218,294,351,375,443,445,446,447,448,456],[97,145,162,163,378],[97,144,145,162,163,244,281,327,368,369,370,371,372,373,374,376,377,449,450],[97,145,159,162,163,281,282,368,456,457],[97,145,162,163,218,341,351,364,443,449,456],[97,145,159,162,163,455,457],[97,145,159,162,163,177,452,456,457],[97,145,159,162,163,171,188,201,211,220,246,247,249,278,283,288,292,293,294,296,325,327,329,332,334,337,338,339,340,362,364,442,443,450,452,455,456,457],[97,145,159,162,163,177],[97,145,162,163,207,208,209,216,452,453,454,459,461,510],[97,145,162,163,205,455],[97,145,162,163,277],[97,145,159,162,163,177,188,239,262,264,265,266,267,268,275,276,510],[97,145,162,163,171,188,201,239,254,287,288,289,325,326,327,332,340,341,347,350,352,362,364,443,450,452,455],[97,145,162,163,216,223,236,340,351,443,455],[97,145,159,162,163,188,208,211,327,345,452,455],[97,145,162,163,366],[97,145,159,162,163,277,348,349,359],[97,145,162,163,452,455],[97,145,162,163,373,375],[97,145,162,163,294,327,442,461],[97,145,159,162,163,171,250,254,326,332,347,350,354,452],[97,145,159,162,163,223,236,254,355],[97,145,162,163,207,249,357,442,455],[97,145,159,162,163,188,268,455],[97,145,159,162,163,220,248,249,250,259,277,356,358,442,455],[91,97,145,159,162,163,294,361,459,461],[97,145,162,163,324,362],[97,145,159,162,163,171,188,211,222,223,236,246,247,283,287,288,289,293,325,326,327,329,341,342,344,346,362,364,442,443,450,451,452,461],[97,145,159,162,163,177,223,347,353,359,452],[97,145,162,163,226,227,228,229,230,231,232,233,234,235],[97,145,162,163,278,333],[97,145,162,163,335],[97,145,162,163,333],[97,145,162,163,335,336],[97,145,159,162,163,211,214,244,245,456],[97,145,159,162,163,171,206,208,246,292,293,294,295,323,362,452,457,459,461],[97,145,159,162,163,171,188,210,245,295,327,373,443,451,456],[97,145,162,163,368],[97,145,162,163,369],[97,145,162,163,310,340,420],[97,145,162,163,370],[97,145,162,163,238,242],[97,145,159,162,163,211,238,246],[97,145,162,163,241,242],[97,145,162,163,243],[97,145,162,163,238,239],[97,145,162,163,238,290],[97,145,162,163,238],[97,145,162,163,278,331,451],[97,145,162,163,330],[97,145,162,163,239,450,451],[97,145,162,163,328,451],[97,145,162,163,239,450],[97,145,162,163,420],[97,145,162,163,211,240,246,294,310,327,361,364,367,373,380,381,411,412,415,419,442,452,456],[97,145,162,163,303,306,308,309,318,319],[85,97,145,162,163,198,200,273,413,414],[85,97,145,162,163,198,200,273,413,414,418],[97,145,162,163,429],[97,145,162,163,218,282,294,361,364,378,386,390,422,423,424,425,427,428,431,442,449,455],[97,145,162,163,318],[97,145,159,162,163,323],[97,145,162,163,323],[97,145,159,162,163,246,291,296,320,322,361,452,459,461],[97,145,162,163,303,304,305,306,308,309,318,319,460],[91,97,145,159,162,163,171,188,238,239,247,293,294,327,359,360,362,442,443,452,455,456,459],[97,145,162,163,282,284,287,443],[97,145,159,162,163,278,455],[97,145,162,163,281,378],[97,145,162,163,280],[97,145,162,163,282,283],[97,145,162,163,279,281,455],[97,145,159,162,163,210,282,284,285,286,455,456],[85,97,145,162,163,310,317,450],[97,145,162,163,203,204],[85,97,145,162,163,208],[85,97,145,162,163,307,450],[85,91,97,145,162,163,293,294,459,461],[97,145,162,163,208,481,482],[85,97,145,162,163,302],[85,97,145,162,163,171,188,206,261,297,299,301,461],[97,145,162,163,220,450,456],[97,145,162,163,343,450],[85,97,145,157,159,162,163,171,205,206,256,302,459,460],[85,97,145,162,163,196,197,198,199,200,459,505],[85,86,87,88,89,97,145,162,163],[97,145,150,162,163],[97,145,162,163,251,252,253],[97,145,162,163,251],[85,89,97,145,159,161,162,163,171,195,196,197,198,199,200,201,206,247,354,398,457,458,461,505],[97,145,162,163,469],[97,145,162,163,471],[97,145,162,163,473],[97,145,162,163,1378],[97,145,162,163,475],[97,145,162,163,477,478,479],[97,145,162,163,483],[90,97,145,162,163,463,468,470,472,474,476,480,484,486,496,497,499,508,509,510,511],[97,145,162,163,485],[97,145,162,163,495],[97,145,162,163,299],[97,145,162,163,498],[97,144,145,162,163,282,284,285,287,500,501,502,505,506,507],[97,145,162,163,195],[97,145,162,163,851],[97,145,162,163,852],[97,145,162,163,1390,1393,1394,1397,1398,1399,1400,1401,1402,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433],[97,145,162,163,1869],[97,145,162,163,1830],[97,145,162,163,1870],[97,145,162,163,1707,1811,1867,1868],[97,145,162,163,1830,1831,1869,1870],[97,145,162,163,1812,1813,1814,1815,1816,1837,1838,1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,1854,1855,1856,1857],[85,97,145,162,163,1836,1871],[85,97,145,162,163,1836],[85,97,145,162,163,1831],[85,97,145,162,163,1871],[85,97,145,162,163,1839],[97,145,162,163,1859,1860,1861,1862,1863,1864,1865],[97,145,162,163,1836],[97,145,162,163,1873],[97,145,162,163,1715,1828,1829,1834,1836,1858,1866,1871,1872,1874,1882],[97,145,162,163,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827],[97,145,162,163,1836,1869],[97,145,162,163,1815,1816,1828,1829,1832,1834,1867],[97,145,162,163,1832,1833,1835,1867],[85,97,145,162,163,1829,1867,1869],[97,145,162,163,1832,1867],[85,97,145,162,163,1828,1829,1858,1866],[85,97,145,162,163,1831,1832,1833,1867,1870],[97,145,162,163,1875,1876,1877,1878,1879,1880,1881],[85,97,145,162,163,1899,1917],[85,97,145,162,163,1899,1917,1920],[85,97,145,162,163,1898,1899,1917,1920],[97,145,162,163,1900,1901,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938],[85,97,145,162,163,1898,1899,1917],[97,145,162,163,177,195],[97,110,114,145,162,163,188],[97,110,145,162,163,177,188],[97,105,145,162,163],[97,107,110,145,162,163,185,188],[97,145,162,163,165,185],[97,105,145,162,163,195],[97,107,110,145,162,163,165,188],[97,102,103,106,109,145,156,162,163,177,188],[97,110,117,145,162,163],[97,102,108,145,162,163],[97,110,131,132,145,162,163],[97,106,110,145,162,163,180,188,195],[97,131,145,162,163,195],[97,104,105,145,162,163,195],[97,110,145,162,163],[97,104,105,106,107,108,109,110,111,112,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,132,133,134,135,136,137,145,162,163],[97,110,125,145,162,163],[97,110,117,118,145,162,163],[97,108,110,118,119,145,162,163],[97,109,145,162,163],[97,102,105,110,145,162,163],[97,110,114,118,119,145,162,163],[97,114,145,162,163],[97,108,110,113,145,162,163,188],[97,102,107,110,117,145,162,163],[97,105,110,131,145,162,163,193,195],[97,145,162,163,594],[97,145,162,163,585],[97,145,162,163,585,588],[97,145,162,163,580,583,585,586,587,588,589,590,591,592,593],[97,145,162,163,519,521,588],[97,145,162,163,585,586],[97,145,162,163,520,585,587],[97,145,162,163,521,523,525,526,527,528],[97,145,162,163,523,525,527,528],[97,145,162,163,523,525,527],[97,145,162,163,520,523,525,526,528],[97,145,162,163,519,521,522,523,524,525,526,527,528,529,530,580,581,582,583,584],[97,145,162,163,519,521,522,525],[97,145,162,163,521,522,525],[97,145,162,163,525,528],[97,145,162,163,519,520,522,523,524,526,527,528],[97,145,162,163,519,520,521,525,585],[97,145,162,163,525,526,527,528],[97,145,162,163,527],[97,145,162,163,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"8fd575e12870e9944c7e1d62e1f5a73fcf23dd8d3a321f2a2c74c20d022283fe","impliedFormat":1},{"version":"2ab096661c711e4a81cc464fa1e6feb929a54f5340b46b0a07ac6bbf857471f0","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"87dc0f382502f5bbce5129bdc0aea21e19a3abbc19259e0b43ae038a9fc4e326","affectsGlobalScope":true,"impliedFormat":1},{"version":"b1cb28af0c891c8c96b2d6b7be76bd394fddcfdb4709a20ba05a7c1605eea0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2fef54945a13095fdb9b84f705f2b5994597640c46afeb2ce78352fab4cb3279","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac77cb3e8c6d3565793eb90a8373ee8033146315a3dbead3bde8db5eaf5e5ec6","affectsGlobalScope":true,"impliedFormat":1},{"version":"56e4ed5aab5f5920980066a9409bfaf53e6d21d3f8d020c17e4de584d29600ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ece9f17b3866cc077099c73f4983bddbcb1dc7ddb943227f1ec070f529dedd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a6282c8827e4b9a95f4bf4f5c205673ada31b982f50572d27103df8ceb8013c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1c9319a09485199c1f7b0498f2988d6d2249793ef67edda49d1e584746be9032","affectsGlobalScope":true,"impliedFormat":1},{"version":"e3a2a0cee0f03ffdde24d89660eba2685bfbdeae955a6c67e8c4c9fd28928eeb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"60037901da1a425516449b9a20073aa03386cce92f7a1fd902d7602be3a7c2e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"d4b1d2c51d058fc21ec2629fff7a76249dec2e36e12960ea056e3ef89174080f","affectsGlobalScope":true,"impliedFormat":1},{"version":"22adec94ef7047a6c9d1af3cb96be87a335908bf9ef386ae9fd50eeb37f44c47","affectsGlobalScope":true,"impliedFormat":1},{"version":"196cb558a13d4533a5163286f30b0509ce0210e4b316c56c38d4c0fd2fb38405","affectsGlobalScope":true,"impliedFormat":1},{"version":"73f78680d4c08509933daf80947902f6ff41b6230f94dd002ae372620adb0f60","affectsGlobalScope":true,"impliedFormat":1},{"version":"c5239f5c01bcfa9cd32f37c496cf19c61d69d37e48be9de612b541aac915805b","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"7e29f41b158de217f94cb9676bf9cbd0cd9b5a46e1985141ed36e075c52bf6ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac51dd7d31333793807a6abaa5ae168512b6131bd41d9c5b98477fc3b7800f9f","impliedFormat":1},{"version":"dc0a7f107690ee5cd8afc8dbf05c4df78085471ce16bdd9881642ec738bc81fe","impliedFormat":1},{"version":"acd8fd5090ac73902278889c38336ff3f48af6ba03aa665eb34a75e7ba1dccc4","impliedFormat":1},{"version":"d6258883868fb2680d2ca96bc8b1352cab69874581493e6d52680c5ffecdb6cc","impliedFormat":1},{"version":"1b61d259de5350f8b1e5db06290d31eaebebc6baafd5f79d314b5af9256d7153","impliedFormat":1},{"version":"f258e3960f324a956fc76a3d3d9e964fff2244ff5859dcc6ce5951e5413ca826","impliedFormat":1},{"version":"643f7232d07bf75e15bd8f658f664d6183a0efaca5eb84b48201c7671a266979","impliedFormat":1},{"version":"21da358700a3893281ce0c517a7a30cbd46be020d9f0c3f2834d0a8ad1f5fc75","impliedFormat":1},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"9855e02d837744303391e5623a531734443a5f8e6e8755e018c41d63ad797db2","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c906fb15bd2aabc9ed1e3f44eb6a8661199d6c320b3aa196b826121552cb3695","impliedFormat":1},{"version":"22295e8103f1d6d8ea4b5d6211e43421fe4564e34d0dd8e09e520e452d89e659","impliedFormat":1},{"version":"f949f7f6c7802a338039cfc2156d1fe285cdd1e092c64437ebe15ae8edc854e0","impliedFormat":1},{"version":"6b4e081d55ac24fc8a4631d5dd77fe249fa25900abd7d046abb87d90e3b45645","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"83e63d6ccf8ec004a3bb6d58b9bb0104f60e002754b1e968024b320730cc5311","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"bceb58df66ab8fb00170df20cd813978c5ab84be1d285710c4eb005d8e9d8efb","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"814118df420c4e38fe5ae1b9a3bafb6e9c2aa40838e528cde908381867be6466","impliedFormat":1},{"version":"a3fc63c0d7b031693f665f5494412ba4b551fe644ededccc0ab5922401079c95","impliedFormat":1},{"version":"f27524f4bef4b6519c604bdb23bf4465bddcccbf3f003abb901acbd0d7404d99","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"6b039f55681caaf111d5eb84d292b9bee9e0131d0db1ad0871eef0964f533c73","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"c8d3e5a18ba35629954e48c4cc8f11dc88224650067a172685c736b27a34a4dc","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"2b55d426ff2b9087485e52ac4bc7cfafe1dc420fc76dad926cd46526567c501a","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"47613031a5a31510831304405af561b0ffaedb734437c595256bb61a90f9311b","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"8a1a0d0a4a06a8d278947fcb66bf684f117bf147f89b06e50662d79a53be3e9f","affectsGlobalScope":true,"impliedFormat":1},{"version":"9f663c2f91127ef7024e8ca4b3b4383ff2770e5f826696005de382282794b127","impliedFormat":1},{"version":"9f55299850d4f0921e79b6bf344b47c420ce0f507b9dcf593e532b09ea7eeea1","impliedFormat":1},{"version":"2beff543f6e9a9701df88daeee3cdd70a34b4a1c11cb4c734472195a5cb2af54","impliedFormat":1},{"version":"2e07abf27aa06353d46f4448c0bbac73431f6065eef7113128a5cd804d0c384d","impliedFormat":1},{"version":"be1cc4d94ea60cbe567bc29ed479d42587bf1e6cba490f123d329976b0fe4ee5","impliedFormat":1},{"version":"42bc0e1a903408137c3df2b06dfd7e402cdab5bbfa5fcfb871b22ebfdb30bd0b","impliedFormat":1},{"version":"9894dafe342b976d251aac58e616ac6df8db91fb9d98934ff9dd103e9e82578f","impliedFormat":1},{"version":"413df52d4ea14472c2fa5bee62f7a40abd1eb49be0b9722ee01ee4e52e63beb2","impliedFormat":1},{"version":"db6d2d9daad8a6d83f281af12ce4355a20b9a3e71b82b9f57cddcca0a8964a96","impliedFormat":1},{"version":"446a50749b24d14deac6f8843e057a6355dd6437d1fac4f9e5ce4a5071f34bff","impliedFormat":1},{"version":"182e9fcbe08ac7c012e0a6e2b5798b4352470be29a64fdc114d23c2bab7d5106","impliedFormat":1},{"version":"5c9b31919ea1cb350a7ae5e71c9ced8f11723e4fa258a8cc8d16ae46edd623c7","impliedFormat":1},{"version":"4aa42ce8383b45823b3a1d3811c0fdd5f939f90254bc4874124393febbaf89f6","impliedFormat":1},{"version":"96ffa70b486207241c0fcedb5d9553684f7fa6746bc2b04c519e7ebf41a51205","impliedFormat":1},{"version":"3677988e03b749874eb9c1aa8dc88cd77b6005e5c4c39d821cda7b80d5388619","impliedFormat":1},{"version":"a86f82d646a739041d6702101afa82dcb935c416dd93cbca7fd754fd0282ce1f","impliedFormat":1},{"version":"ad0d1d75d129b1c80f911be438d6b61bfa8703930a8ff2be2f0e1f8a91841c64","impliedFormat":1},{"version":"ce75b1aebb33d510ff28af960a9221410a3eaf7f18fc5f21f9404075fba77256","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"02436d7e9ead85e09a2f8e27d5f47d9464bced31738dec138ca735390815c9f0","impliedFormat":1},{"version":"f4625edcb57b37b84506e8b276eb59ca30d31f88c6656d29d4e90e3bc58e69df","impliedFormat":1},{"version":"78a2869ad0cbf3f9045dda08c0d4562b7e1b2bfe07b19e0db072f5c3c56e9584","impliedFormat":1},{"version":"f8d5ff8eafd37499f2b6a98659dd9b45a321de186b8db6b6142faed0fea3de77","impliedFormat":1},{"version":"c86fe861cf1b4c46a0fb7d74dffe596cf679a2e5e8b1456881313170f092e3fa","impliedFormat":1},{"version":"c685d9f68c70fe11ce527287526585a06ea13920bb6c18482ca84945a4e433a7","impliedFormat":1},{"version":"540cc83ab772a2c6bc509fe1354f314825b5dba3669efdfbe4693ecd3048e34f","impliedFormat":1},{"version":"121b0696021ab885c570bbeb331be8ad82c6efe2f3b93a6e63874901bebc13e3","impliedFormat":1},{"version":"4e01846df98d478a2a626ec3641524964b38acaac13945c2db198bf9f3df22ee","impliedFormat":1},{"version":"678d6d4c43e5728bf66e92fc2269da9fa709cb60510fed988a27161473c3853f","impliedFormat":1},{"version":"ffa495b17a5ef1d0399586b590bd281056cee6ce3583e34f39926f8dcc6ecdb5","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"aa14cee20aa0db79f8df101fc027d929aec10feb5b8a8da3b9af3895d05b7ba2","impliedFormat":1},{"version":"493c700ac3bd317177b2eb913805c87fe60d4e8af4fb39c41f04ba81fae7e170","impliedFormat":1},{"version":"aeb554d876c6b8c818da2e118d8b11e1e559adbe6bf606cc9a611c1b6c09f670","impliedFormat":1},{"version":"acf5a2ac47b59ca07afa9abbd2b31d001bf7448b041927befae2ea5b1951d9f9","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"d71291eff1e19d8762a908ba947e891af44749f3a2cbc5bd2ec4b72f72ea795f","impliedFormat":1},{"version":"c0480e03db4b816dff2682b347c95f2177699525c54e7e6f6aa8ded890b76be7","impliedFormat":1},{"version":"e2a37ac938c4bede5bb284b9d2d042da299528f1e61f6f57538f1bd37d760869","impliedFormat":1},{"version":"76def37aff8e3a051cf406e10340ffba0f28b6991c5d987474cc11137796e1eb","impliedFormat":1},{"version":"b620391fe8060cf9bedc176a4d01366e6574d7a71e0ac0ab344a4e76576fcbb8","impliedFormat":1},{"version":"3e7efde639c6a6c3edb9847b3f61e308bf7a69685b92f665048c45132f51c218","impliedFormat":1},{"version":"df45ca1176e6ac211eae7ddf51336dc075c5314bc5c253651bae639defd5eec5","impliedFormat":1},{"version":"106c6025f1d99fd468fd8bf6e5bda724e11e5905a4076c5d29790b6c3745e50c","impliedFormat":1},{"version":"ee8df1cb8d0faaca4013a1b442e99130769ce06f438d18d510fed95890067563","impliedFormat":1},{"version":"bfb7f8475428637bee12bdd31bd9968c1c8a1cc2c3e426c959e2f3a307f8936f","impliedFormat":1},{"version":"6f491d0108927478d3247bbbc489c78c2da7ef552fd5277f1ab6819986fdf0b1","impliedFormat":1},{"version":"594fe24fc54645ab6ccb9dba15d3a35963a73a395b2ef0375ea34bf181ccfd63","impliedFormat":1},{"version":"7cb0ee103671d1e201cd53dda12bc1cd0a35f1c63d6102720c6eeb322cb8e17e","impliedFormat":1},{"version":"15a234e5031b19c48a69ccc1607522d6e4b50f57d308ecb7fe863d44cd9f9eb3","impliedFormat":1},{"version":"148679c6d0f449210a96e7d2e562d589e56fcde87f843a92808b3ff103f1a774","impliedFormat":1},{"version":"6459054aabb306821a043e02b89d54da508e3a6966601a41e71c166e4ea1474f","impliedFormat":1},{"version":"2f9c89cbb29d362290531b48880a4024f258c6033aaeb7e59fbc62db26819650","impliedFormat":1},{"version":"bb37588926aba35c9283fe8d46ebf4e79ffe976343105f5c6d45f282793352b2","impliedFormat":1},{"version":"05c97cddbaf99978f83d96de2d8af86aded9332592f08ce4a284d72d0952c391","impliedFormat":1},{"version":"72179f9dd22a86deaad4cc3490eb0fe69ee084d503b686985965654013f1391b","impliedFormat":1},{"version":"2e6114a7dd6feeef85b2c80120fdbfb59a5529c0dcc5bfa8447b6996c97a69f5","impliedFormat":1},{"version":"7b6ff760c8a240b40dab6e4419b989f06a5b782f4710d2967e67c695ef3e93c4","impliedFormat":1},{"version":"c8f004e6036aa1c764ad4ec543cf89a5c1893a9535c80ef3f2b653e370de45e6","impliedFormat":1},{"version":"dd80b1e600d00f5c6a6ba23f455b84a7db121219e68f89f10552c54ba46e4dc9","impliedFormat":1},{"version":"b064c36f35de7387d71c599bfcf28875849a1dbc733e82bd26cae3d1cd060521","impliedFormat":1},{"version":"05c7280d72f3ed26f346cbe7cbbbb002fb7f15739197cbbee6ab3fd1a6cb9347","impliedFormat":1},{"version":"8de9fe97fa9e00ec00666fa77ab6e91b35d25af8ca75dabcb01e14ad3299b150","impliedFormat":1},{"version":"803cd2aaf1921c218916c2c7ee3fce653e852d767177eb51047ff15b5b253893","impliedFormat":1},{"version":"dba114fb6a32b355a9cfc26ca2276834d72fe0e94cd2c3494005547025015369","impliedFormat":1},{"version":"7ab12b2f1249187223d11a589f5789c75177a0b597b9eb7f8e2e42d045393347","impliedFormat":1},{"version":"ad37fb4be61c1035b68f532b7220f4e8236cf245381ce3b90ac15449ecfe7305","impliedFormat":1},{"version":"93436bd74c66baba229bfefe1314d122c01f0d4c1d9e35081a0c4f0470ac1a6c","impliedFormat":1},{"version":"f974e4a06953682a2c15d5bd5114c0284d5abf8bc0fe4da25cb9159427b70072","impliedFormat":1},{"version":"50256e9c31318487f3752b7ac12ff365c8949953e04568009c8705db802776fb","impliedFormat":1},{"version":"7d73b24e7bf31dfb8a931ca6c4245f6bb0814dfae17e4b60c9e194a631fe5f7b","impliedFormat":1},{"version":"d130c5f73768de51402351d5dc7d1b36eaec980ca697846e53156e4ea9911476","impliedFormat":1},{"version":"413586add0cfe7369b64979d4ec2ed56c3f771c0667fbde1bf1f10063ede0b08","impliedFormat":1},{"version":"06472528e998d152375ad3bd8ebcb69ff4694fd8d2effaf60a9d9f25a37a097a","impliedFormat":1},{"version":"50b5bc34ce6b12eccb76214b51aadfa56572aa6cc79c2b9455cdbb3d6c76af1d","impliedFormat":1},{"version":"b7e16ef7f646a50991119b205794ebfd3a4d8f8e0f314981ebbe991639023d0e","impliedFormat":1},{"version":"42c169fb8c2d42f4f668c624a9a11e719d5d07dacbebb63cbcf7ef365b0a75b3","impliedFormat":1},{"version":"a401617604fa1f6ce437b81689563dfdc377069e4c58465dbd8d16069aede0a5","impliedFormat":1},{"version":"6e9082e91370de5040e415cd9f24e595b490382e8c7402c4e938a8ce4bccc99f","impliedFormat":1},{"version":"8695dec09ad439b0ceef3776ea68a232e381135b516878f0901ed2ea114fd0fe","impliedFormat":1},{"version":"304b44b1e97dd4c94697c3313df89a578dca4930a104454c99863f1784a54357","impliedFormat":1},{"version":"d682336018141807fb602709e2d95a192828fcb8d5ba06dda3833a8ea98f69e3","impliedFormat":1},{"version":"6124e973eab8c52cabf3c07575204efc1784aca6b0a30c79eb85fe240a857efa","impliedFormat":1},{"version":"0d891735a21edc75df51f3eb995e18149e119d1ce22fd40db2b260c5960b914e","impliedFormat":1},{"version":"3b414b99a73171e1c4b7b7714e26b87d6c5cb03d200352da5342ab4088a54c85","impliedFormat":1},{"version":"4fbd3116e00ed3a6410499924b6403cc9367fdca303e34838129b328058ede40","impliedFormat":1},{"version":"b01bd582a6e41457bc56e6f0f9de4cb17f33f5f3843a7cf8210ac9c18472fb0f","impliedFormat":1},{"version":"0a437ae178f999b46b6153d79095b60c42c996bc0458c04955f1c996dc68b971","impliedFormat":1},{"version":"74b2a5e5197bd0f2e0077a1ea7c07455bbea67b87b0869d9786d55104006784f","impliedFormat":1},{"version":"4a7baeb6325920044f66c0f8e5e6f1f52e06e6d87588d837bdf44feb6f35c664","impliedFormat":1},{"version":"12d218a49dbe5655b911e6cc3c13b2c655e4c783471c3b0432137769c79e1b3c","impliedFormat":1},{"version":"7274fbffbd7c9589d8d0ffba68157237afd5cecff1e99881ea3399127e60572f","impliedFormat":1},{"version":"6b0fc04121360f752d196ba35b6567192f422d04a97b2840d7d85f8b79921c92","impliedFormat":1},{"version":"65a15fc47900787c0bd18b603afb98d33ede930bed1798fc984d5ebb78b26cf9","impliedFormat":1},{"version":"9d202701f6e0744adb6314d03d2eb8fc994798fc83d91b691b75b07626a69801","impliedFormat":1},{"version":"a365c4d3bed3be4e4e20793c999c51f5cd7e6792322f14650949d827fbcd170f","impliedFormat":1},{"version":"c5426dbfc1cf90532f66965a7aa8c1136a78d4d0f96d8180ecbfc11d7722f1a5","impliedFormat":1},{"version":"9c82171d836c47486074e4ca8e059735bf97b205e70b196535b5efd40cbe1bc5","impliedFormat":1},{"version":"f374cb24e93e7798c4d9e83ff872fa52d2cdb36306392b840a6ddf46cb925cb6","impliedFormat":1},{"version":"42b81043b00ff27c6bd955aea0f6e741545f2265978bf364b614702b72a027ab","impliedFormat":1},{"version":"de9d2df7663e64e3a91bf495f315a7577e23ba088f2949d5ce9ec96f44fba37d","impliedFormat":1},{"version":"c7af78a2ea7cb1cd009cfb5bdb48cd0b03dad3b54f6da7aab615c2e9e9d570c5","impliedFormat":1},{"version":"1ee45496b5f8bdee6f7abc233355898e5bf9bd51255db65f5ff7ede617ca0027","impliedFormat":1},{"version":"97e5ccc7bb88419005cbdf812243a5b3186cdef81b608540acabe1be163fc3e4","affectsGlobalScope":true,"impliedFormat":1},{"version":"3fbdd025f9d4d820414417eeb4107ffa0078d454a033b506e22d3a23bc3d9c41","affectsGlobalScope":true,"impliedFormat":1},{"version":"a8f8e6ab2fa07b45251f403548b78eaf2022f3c2254df3dc186cb2671fe4996d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fa6c12a7c0f6b84d512f200690bfc74819e99efae69e4c95c4cd30f6884c526e","impliedFormat":1},{"version":"f1c32f9ce9c497da4dc215c3bc84b722ea02497d35f9134db3bb40a8d918b92b","impliedFormat":1},{"version":"b73c319af2cc3ef8f6421308a250f328836531ea3761823b4cabbd133047aefa","affectsGlobalScope":true,"impliedFormat":1},{"version":"e433b0337b8106909e7953015e8fa3f2d30797cea27141d1c5b135365bb975a6","impliedFormat":1},{"version":"9f9bb6755a8ce32d656ffa4763a8144aa4f274d6b69b59d7c32811031467216e","impliedFormat":1},{"version":"5c32bdfbd2d65e8fffbb9fbda04d7165e9181b08dad61154961852366deb7540","impliedFormat":1},{"version":"ddff7fc6edbdc5163a09e22bf8df7bef75f75369ebd7ecea95ba55c4386e2441","impliedFormat":1},{"version":"6b3453eebd474cc8acf6d759f1668e6ce7425a565e2996a20b644c72916ecf75","impliedFormat":1},{"version":"0c05e9842ec4f8b7bfebfd3ca61604bb8c914ba8da9b5337c4f25da427a005f2","impliedFormat":1},{"version":"89cd3444e389e42c56fd0d072afef31387e7f4107651afd2c03950f22dc36f77","impliedFormat":1},{"version":"7f2aa4d4989a82530aaac3f72b3dceca90e9c25bee0b1a327e8a08a1262435ad","impliedFormat":1},{"version":"e39a304f882598138a8022106cb8de332abbbb87f3fee71c5ca6b525c11c51fc","impliedFormat":1},{"version":"faed7a5153215dbd6ebe76dfdcc0af0cfe760f7362bed43284be544308b114cf","impliedFormat":1},{"version":"fcdf3e40e4a01b9a4b70931b8b51476b210c511924fcfe3f0dae19c4d52f1a54","impliedFormat":1},{"version":"345c4327b637d34a15aba4b7091eb068d6ab40a3dedaab9f00986253c9704e53","impliedFormat":1},{"version":"3a788c7fb7b1b1153d69a4d1d9e1d0dfbcf1127e703bdb02b6d12698e683d1fb","impliedFormat":1},{"version":"2e4f37ffe8862b14d8e24ae8763daaa8340c0df0b859d9a9733def0eee7562d9","impliedFormat":1},{"version":"d38530db0601215d6d767f280e3a3c54b2a83b709e8d9001acb6f61c67e965fc","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"4805f6161c2c8cefb8d3b8bd96a080c0fe8dbc9315f6ad2e53238f9a79e528a6","impliedFormat":1},{"version":"b83cb14474fa60c5f3ec660146b97d122f0735627f80d82dd03e8caa39b4388c","impliedFormat":1},{"version":"2b5b70d7782fe028487a80a1c214e67bd610532b9f978b78fa60f5b4a359f77e","impliedFormat":1},{"version":"7ee86fbb3754388e004de0ef9e6505485ddfb3be7640783d6d015711c03d302d","impliedFormat":1},{"version":"1a82deef4c1d39f6882f28d275cad4c01f907b9b39be9cbc472fcf2cf051e05b","impliedFormat":1},{"version":"7580e62139cb2b44a0270c8d01abcbfcba2819a02514a527342447fa69b34ef1","impliedFormat":1},{"version":"b73cbf0a72c8800cf8f96a9acfe94f3ad32ca71342a8908b8ae484d61113f647","impliedFormat":1},{"version":"bae6dd176832f6423966647382c0d7ba9e63f8c167522f09a982f086cd4e8b23","impliedFormat":1},{"version":"20865ac316b8893c1a0cc383ccfc1801443fbcc2a7255be166cf90d03fac88c9","impliedFormat":1},{"version":"c9958eb32126a3843deedda8c22fb97024aa5d6dd588b90af2d7f2bfac540f23","impliedFormat":1},{"version":"461d0ad8ae5f2ff981778af912ba71b37a8426a33301daa00f21c6ccb27f8156","impliedFormat":1},{"version":"e927c2c13c4eaf0a7f17e6022eee8519eb29ef42c4c13a31e81a611ab8c95577","impliedFormat":1},{"version":"fcafff163ca5e66d3b87126e756e1b6dfa8c526aa9cd2a2b0a9da837d81bbd72","impliedFormat":1},{"version":"70246ad95ad8a22bdfe806cb5d383a26c0c6e58e7207ab9c431f1cb175aca657","impliedFormat":1},{"version":"f00f3aa5d64ff46e600648b55a79dcd1333458f7a10da2ed594d9f0a44b76d0b","impliedFormat":1},{"version":"772d8d5eb158b6c92412c03228bd9902ccb1457d7a705b8129814a5d1a6308fc","impliedFormat":1},{"version":"802e797bcab5663b2c9f63f51bdf67eff7c41bc64c0fd65e6da3e7941359e2f7","impliedFormat":1},{"version":"8b4327413e5af38cd8cb97c59f48c3c866015d5d642f28518e3a891c469f240e","impliedFormat":1},{"version":"7e6ac205dcb9714f708354fd863bffa45cee90740706cc64b3b39b23ebb84744","impliedFormat":1},{"version":"61dc6e3ac78d64aa864eedd0a208b97b5887cc99c5ba65c03287bf57d83b1eb9","impliedFormat":1},{"version":"4b20fcf10a5413680e39f5666464859fc56b1003e7dfe2405ced82371ebd49b6","impliedFormat":1},{"version":"c06ef3b2569b1c1ad99fcd7fe5fba8d466e2619da5375dfa940a94e0feea899b","impliedFormat":1},{"version":"f7d628893c9fa52ba3ab01bcb5e79191636c4331ee5667ecc6373cbccff8ae12","impliedFormat":1},{"version":"1d879125d1ec570bf04bc1f362fdbe0cb538315c7ac4bcfcdf0c1e9670846aa6","impliedFormat":1},{"version":"f730b468deecf26188ad62ee8950dc29aa2aea9543bb08ed714c3db019359fd9","impliedFormat":1},{"version":"933aee906d42ea2c53b6892192a8127745f2ec81a90695df4024308ba35a8ff4","impliedFormat":1},{"version":"d663134457d8d669ae0df34eabd57028bddc04fc444c4bc04bc5215afc91e1f4","impliedFormat":1},{"version":"144bc326e90b894d1ec78a2af3ffb2eb3733f4d96761db0ca0b6239a8285f972","impliedFormat":1},{"version":"a3e3f0efcae272ab8ee3298e4e819f7d9dd9ff411101f45444877e77cfeca9a4","impliedFormat":1},{"version":"43e96a3d5d1411ab40ba2f61d6a3192e58177bcf3b133a80ad2a16591611726d","impliedFormat":1},{"version":"58659b06d33fa430bee1105b75cf876c0a35b2567207487c8578aec51ca2d977","impliedFormat":1},{"version":"71d9eb4c4e99456b78ae182fb20a5dfc20eb1667f091dbb9335b3c017dd1c783","impliedFormat":1},{"version":"cfa846a7b7847a1d973605fbb8c91f47f3a0f0643c18ac05c47077ebc72e71c7","impliedFormat":1},{"version":"30e6520444df1a004f46fdc8096f3fe06f7bbd93d09c53ada9dcdde59919ccca","impliedFormat":1},{"version":"6c800b281b9e89e69165fd11536195488de3ff53004e55905e6c0059a2d8591e","impliedFormat":1},{"version":"7d4254b4c6c67a29d5e7f65e67d72540480ac2cfb041ca484847f5ae70480b62","impliedFormat":1},{"version":"a58beefce74db00dbb60eb5a4bb0c6726fb94c7797c721f629142c0ae9c94306","impliedFormat":1},{"version":"41eeb453ccb75c5b2c3abef97adbbd741bd7e9112a2510e12f03f646dc9ad13d","impliedFormat":1},{"version":"502fa5863df08b806dbf33c54bee8c19f7e2ad466785c0fc35465d7c5ff80995","impliedFormat":1},{"version":"c91a2d08601a1547ffef326201be26db94356f38693bb18db622ae5e9b3d7c92","impliedFormat":1},{"version":"888cda0fa66d7f74e985a3f7b1af1f64b8ff03eb3d5e80d051c3cbdeb7f32ab7","impliedFormat":1},{"version":"60681e13f3545be5e9477acb752b741eae6eaf4cc01658a25ec05bff8b82a2ef","impliedFormat":1},{"version":"9586918b63f24124a5ca1d0cc2979821a8a57f514781f09fc5aa9cae6d7c0138","impliedFormat":1},{"version":"a57b1802794433adec9ff3fed12aa79d671faed86c49b09e02e1ac41b4f1d33a","impliedFormat":1},{"version":"ad10d4f0517599cdeca7755b930f148804e3e0e5b5a3847adce0f1f71bbccd74","impliedFormat":1},{"version":"1042064ece5bb47d6aba91648fbe0635c17c600ebdf567588b4ca715602f0a9d","impliedFormat":1},{"version":"c49469a5349b3cc1965710b5b0f98ed6c028686aa8450bcb3796728873eb923e","impliedFormat":1},{"version":"4a889f2c763edb4d55cb624257272ac10d04a1cad2ed2948b10ed4a7fda2a428","impliedFormat":1},{"version":"7bb79aa2fead87d9d56294ef71e056487e848d7b550c9a367523ee5416c44cfa","impliedFormat":1},{"version":"d88ea80a6447d7391f52352ec97e56b52ebec934a4a4af6e2464cfd8b39c3ba8","impliedFormat":1},{"version":"55095860901097726220b6923e35a812afdd49242a1246d7b0942ee7eb34c6e4","impliedFormat":1},{"version":"96171c03c2e7f314d66d38acd581f9667439845865b7f85da8df598ff9617476","impliedFormat":1},{"version":"27ff4196654e6373c9af16b6165120e2dd2169f9ad6abb5c935af5abd8c7938c","impliedFormat":1},{"version":"bb8f2dbc03533abca2066ce4655c119bff353dd4514375beb93c08590c03e023","impliedFormat":1},{"version":"d193c8a86144b3a87b22bc1f5534b9c3e0f5a187873ec337c289a183973a58fe","impliedFormat":1},{"version":"1a6e6ba8a07b74e3ad237717c0299d453f9ceb795dbc2f697d1f2dd07cb782d2","impliedFormat":1},{"version":"58d70c38037fc0f949243388ff7ae20cf43321107152f14a9d36ca79311e0ada","impliedFormat":1},{"version":"f56bdc6884648806d34bc66d31cdb787c4718d04105ce2cd88535db214631f82","impliedFormat":1},{"version":"190da5eac6478d61ab9731ab2146fbc0164af2117a363013249b7e7992f1cccb","impliedFormat":1},{"version":"01479d9d5a5dda16d529b91811375187f61a06e74be294a35ecce77e0b9e8d6c","impliedFormat":1},{"version":"49f95e989b4632c6c2a578cc0078ee19a5831832d79cc59abecf5160ea71abad","impliedFormat":1},{"version":"9666533332f26e8995e4d6fe472bdeec9f15d405693723e6497bf94120c566c8","impliedFormat":1},{"version":"ce0df82a9ae6f914ba08409d4d883983cc08e6d59eb2df02d8e4d68309e7848b","impliedFormat":1},{"version":"796273b2edc72e78a04e86d7c58ae94d370ab93a0ddf40b1aa85a37a1c29ecd7","impliedFormat":1},{"version":"5df15a69187d737d6d8d066e189ae4f97e41f4d53712a46b2710ff9f8563ec9f","impliedFormat":1},{"version":"1a4dc28334a926d90ba6a2d811ba0ff6c22775fcc13679521f034c124269fd40","impliedFormat":1},{"version":"f05315ff85714f0b87cc0b54bcd3dde2716e5a6b99aedcc19cad02bf2403e08c","impliedFormat":1},{"version":"8a8c64dafaba11c806efa56f5c69f611276471bef80a1db1f71316ec4168acef","impliedFormat":1},{"version":"43ba4f2fa8c698f5c304d21a3ef596741e8e85a810b7c1f9b692653791d8d97a","impliedFormat":1},{"version":"5fad3b31fc17a5bc58095118a8b160f5260964787c52e7eb51e3d4fcf5d4a6f0","impliedFormat":1},{"version":"72105519d0390262cf0abe84cf41c926ade0ff475d35eb21307b2f94de985778","impliedFormat":1},{"version":"d0a4cac61fa080f2be5ebb68b82726be835689b35994ba0e22e3ed4d2bc45e3b","impliedFormat":1},{"version":"c857e0aae3f5f444abd791ec81206020fbcc1223e187316677e026d1c1d6fe08","impliedFormat":1},{"version":"ccf6dd45b708fb74ba9ed0f2478d4eb9195c9dfef0ff83a6092fa3cf2ff53b4f","impliedFormat":1},{"version":"2d7db1d73456e8c5075387d4240c29a2a900847f9c1bff106a2e490da8fbd457","impliedFormat":1},{"version":"2b15c805f48e4e970f8ec0b1915f22d13ca6212375e8987663e2ef5f0205e832","impliedFormat":1},{"version":"205a31b31beb7be73b8df18fcc43109cbc31f398950190a0967afc7a12cb478c","impliedFormat":1},{"version":"8fca3039857709484e5893c05c1f9126ab7451fa6c29e19bb8c2411a2e937345","impliedFormat":1},{"version":"35069c2c417bd7443ae7c7cafd1de02f665bf015479fec998985ffbbf500628c","impliedFormat":1},{"version":"dba6c7006e14a98ec82999c6f89fbbbfd1c642f41db148535f3b77b8018829b8","impliedFormat":1},{"version":"7f897b285f22a57a5c4dc14a27da2747c01084a542b4d90d33897216dceeea2e","impliedFormat":1},{"version":"7e0b7f91c5ab6e33f511efc640d36e6f933510b11be24f98836a20a2dc914c2d","impliedFormat":1},{"version":"045b752f44bf9bbdcaffd882424ab0e15cb8d11fa94e1448942e338c8ef19fba","impliedFormat":1},{"version":"2894c56cad581928bb37607810af011764a2f511f575d28c9f4af0f2ef02d1ab","impliedFormat":1},{"version":"0a72186f94215d020cb386f7dca81d7495ab6c17066eb07d0f44a5bf33c1b21a","impliedFormat":1},{"version":"d96b39301d0ded3f1a27b47759676a33a02f6f5049bfcbde81e533fd10f50dcb","impliedFormat":1},{"version":"2ded4f930d6abfaa0625cf55e58f565b7cbd4ab5b574dd2cb19f0a83a2f0be8b","impliedFormat":1},{"version":"0aedb02516baf3e66b2c1db9fef50666d6ed257edac0f866ea32f1aa05aa474f","impliedFormat":1},{"version":"ca0f4d9068d652bad47e326cf6ba424ac71ab866e44b24ddb6c2bd82d129586a","affectsGlobalScope":true,"impliedFormat":1},{"version":"04d36005fcbeac741ac50c421181f4e0316d57d148d37cc321a8ea285472462b","impliedFormat":1},{"version":"9e2739b32f741859263fdba0244c194ca8e96da49b430377930b8f721d77c000","impliedFormat":1},{"version":"56ccb49443bfb72e5952f7012f0de1a8679f9f75fc93a5c1ac0bafb28725fc5f","impliedFormat":1},{"version":"20fa37b636fdcc1746ea0738f733d0aed17890d1cd7cb1b2f37010222c23f13e","impliedFormat":1},{"version":"d90b9f1520366d713a73bd30c5a9eb0040d0fb6076aff370796bc776fd705943","impliedFormat":1},{"version":"bc03c3c352f689e38c0ddd50c39b1e65d59273991bfc8858a9e3c0ebb79c023b","impliedFormat":1},{"version":"19df3488557c2fc9b4d8f0bac0fd20fb59aa19dec67c81f93813951a81a867f8","affectsGlobalScope":true,"impliedFormat":1},{"version":"b25350193e103ae90423c5418ddb0ad1168dc9c393c9295ef34980b990030617","affectsGlobalScope":true,"impliedFormat":1},{"version":"bef86adb77316505c6b471da1d9b8c9e428867c2566270e8894d4d773a1c4dc2","impliedFormat":1},{"version":"a46dba563f70f32f9e45ae015f3de979225f668075d7a427f874e0f6db584991","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"2652448ac55a2010a1f71dd141f828b682298d39728f9871e1cdf8696ef443fd","impliedFormat":1},{"version":"02c4fc9e6bb27545fa021f6056e88ff5fdf10d9d9f1467f1d10536c6e749ac50","impliedFormat":1},{"version":"120599fd965257b1f4d0ff794bc696162832d9d8467224f4665f713a3119078b","impliedFormat":1},{"version":"5433f33b0a20300cca35d2f229a7fc20b0e8477c44be2affeb21cb464af60c76","impliedFormat":1},{"version":"db036c56f79186da50af66511d37d9fe77fa6793381927292d17f81f787bb195","impliedFormat":1},{"version":"bd4131091b773973ca5d2326c60b789ab1f5e02d8843b3587effe6e1ea7c9d86","impliedFormat":1},{"version":"c7f6485931085bf010fbaf46880a9b9ec1a285ad9dc8c695a9e936f5a48f34b4","impliedFormat":1},{"version":"14f6b927888a1112d662877a5966b05ac1bf7ed25d6c84386db4c23c95a5363b","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"622694a8522b46f6310c2a9b5d2530dde1e2854cb5829354e6d1ff8f371cf469","impliedFormat":1},{"version":"d24ff95760ea2dfcc7c57d0e269356984e7046b7e0b745c80fea71559f15bdd8","impliedFormat":1},{"version":"a9e6c0ff3f8186fccd05752cf75fc94e147c02645087ac6de5cc16403323d870","impliedFormat":1},{"version":"49c346823ba6d4b12278c12c977fb3a31c06b9ca719015978cb145eb86da1c61","impliedFormat":1},{"version":"bfac6e50eaa7e73bb66b7e052c38fdc8ccfc8dbde2777648642af33cf349f7f1","impliedFormat":1},{"version":"92f7c1a4da7fbfd67a2228d1687d5c2e1faa0ba865a94d3550a3941d7527a45d","impliedFormat":1},{"version":"f53b120213a9289d9a26f5af90c4c686dd71d91487a0aa5451a38366c70dc64b","impliedFormat":1},{"version":"83fe880c090afe485a5c02262c0b7cdd76a299a50c48d9bde02be8e908fb4ae6","impliedFormat":1},{"version":"13c1b657932e827a7ed510395d94fc8b743b9d053ab95b7cd829b2bc46fb06db","impliedFormat":1},{"version":"57d67b72e06059adc5e9454de26bbfe567d412b962a501d263c75c2db430f40e","impliedFormat":1},{"version":"6511e4503cf74c469c60aafd6589e4d14d5eb0a25f9bf043dcbecdf65f261972","impliedFormat":1},{"version":"078131f3a722a8ad3fc0b724cd3497176513cdcb41c80f96a3acbda2a143b58e","impliedFormat":1},{"version":"8c70ddc0c22d85e56011d49fddfaae3405eb53d47b59327b9dd589e82df672e7","impliedFormat":1},{"version":"a67b87d0281c97dfc1197ef28dfe397fc2c865ccd41f7e32b53f647184cc7307","impliedFormat":1},{"version":"771ffb773f1ddd562492a6b9aaca648192ac3f056f0e1d997678ff97dbb6bf9b","impliedFormat":1},{"version":"232f70c0cf2b432f3a6e56a8dc3417103eb162292a9fd376d51a3a9ea5fbbf6f","impliedFormat":1},{"version":"9e155d2255348d950b1f65643fb26c0f14f5109daf8bd9ee24a866ad0a743648","affectsGlobalScope":true,"impliedFormat":1},{"version":"0b103e9abfe82d14c0ad06a55d9f91d6747154ef7cacc73cf27ecad2bfb3afcf","impliedFormat":1},{"version":"7a883e9c84e720810f86ef4388f54938a65caa0f4d181a64e9255e847a7c9f51","impliedFormat":1},{"version":"a0ba218ac1baa3da0d5d9c1ec1a7c2f8676c284e6f5b920d6d049b13fa267377","impliedFormat":1},{"version":"8a0e762ceb20c7e72504feef83d709468a70af4abccb304f32d6b9bac1129b2c","impliedFormat":1},{"version":"d408d6f32de8d1aba2ff4a20f1aa6a6edd7d92c997f63b90f8ad3f9017cf5e46","impliedFormat":1},{"version":"9252d498a77517aab5d8d4b5eb9d71e4b225bbc7123df9713e08181de63180f6","impliedFormat":1},{"version":"b1f1d57fde8247599731b24a733395c880a6561ec0c882efaaf20d7df968c5af","impliedFormat":1},{"version":"9d622ea608d43eb463c0c4538fd5baa794bc18ea0bb8e96cd2ab6fd483d55fe2","impliedFormat":1},{"version":"35e6379c3f7cb27b111ad4c1aa69538fd8e788ab737b8ff7596a1b40e96f4f90","impliedFormat":1},{"version":"1fffe726740f9787f15b532e1dc870af3cd964dbe29e191e76121aa3dd8693f2","impliedFormat":1},{"version":"371bf6127c1d427836de95197155132501cb6b69ef8709176ce6e0b85d059264","impliedFormat":1},{"version":"2bafd700e617d3693d568e972d02b92224b514781f542f70d497a8fdf92d52a2","affectsGlobalScope":true,"impliedFormat":1},{"version":"5542d8a7ea13168cb573be0d1ba0d29460d59430fb12bb7bf4674efd5604e14c","impliedFormat":1},{"version":"af48e58339188d5737b608d41411a9c054685413d8ae88b8c1d0d9bfabdf6e7e","impliedFormat":1},{"version":"616775f16134fa9d01fc677ad3f76e68c051a056c22ab552c64cc281a9686790","impliedFormat":1},{"version":"65c24a8baa2cca1de069a0ba9fba82a173690f52d7e2d0f1f7542d59d5eb4db0","impliedFormat":1},{"version":"f9fe6af238339a0e5f7563acee3178f51db37f32a2e7c09f85273098cee7ec49","impliedFormat":1},{"version":"1de8c302fd35220d8f29dea378a4ae45199dc8ff83ca9923aca1400f2b28848a","impliedFormat":1},{"version":"77e71242e71ebf8528c5802993697878f0533db8f2299b4d36aa015bae08a79c","impliedFormat":1},{"version":"98a787be42bd92f8c2a37d7df5f13e5992da0d967fab794adbb7ee18370f9849","impliedFormat":1},{"version":"332248ee37cca52903572e66c11bef755ccc6e235835e63d3c3e60ddda3e9b93","impliedFormat":1},{"version":"94e8cc88ae2ef3d920bb3bdc369f48436db123aa2dc07f683309ad8c9968a1e1","impliedFormat":1},{"version":"4545c1a1ceca170d5d83452dd7c4994644c35cf676a671412601689d9a62da35","impliedFormat":1},{"version":"320f4091e33548b554d2214ce5fc31c96631b513dffa806e2e3a60766c8c49d9","impliedFormat":1},{"version":"a2d648d333cf67b9aeac5d81a1a379d563a8ffa91ddd61c6179f68de724260ff","impliedFormat":1},{"version":"d90d5f524de38889d1e1dbc2aeef00060d779f8688c02766ddb9ca195e4a713d","impliedFormat":1},{"version":"a3f41ed1b4f2fc3049394b945a68ae4fdefd49fa1739c32f149d32c0545d67f5","impliedFormat":1},{"version":"b0309e1eda99a9e76f87c18992d9c3689b0938266242835dd4611f2b69efe456","impliedFormat":1},{"version":"47699512e6d8bebf7be488182427189f999affe3addc1c87c882d36b7f2d0b0e","impliedFormat":1},{"version":"6ceb10ca57943be87ff9debe978f4ab73593c0c85ee802c051a93fc96aaf7a20","impliedFormat":1},{"version":"1de3ffe0cc28a9fe2ac761ece075826836b5a02f340b412510a59ba1d41a505a","impliedFormat":1},{"version":"e46d6cc08d243d8d0d83986f609d830991f00450fb234f5b2f861648c42dc0d8","impliedFormat":1},{"version":"1c0a98de1323051010ce5b958ad47bc1c007f7921973123c999300e2b7b0ecc0","impliedFormat":1},{"version":"ff863d17c6c659440f7c5c536e4db7762d8c2565547b2608f36b798a743606ca","impliedFormat":1},{"version":"5412ad0043cd60d1f1406fc12cb4fb987e9a734decbdd4db6f6acf71791e36fe","impliedFormat":1},{"version":"ad036a85efcd9e5b4f7dd5c1a7362c8478f9a3b6c3554654ca24a29aa850a9c5","impliedFormat":1},{"version":"fedebeae32c5cdd1a85b4e0504a01996e4a8adf3dfa72876920d3dd6e42978e7","impliedFormat":1},{"version":"b6c1f64158da02580f55e8a2728eda6805f79419aed46a930f43e68ad66a38fc","impliedFormat":1},{"version":"cdf21eee8007e339b1b9945abf4a7b44930b1d695cc528459e68a3adc39a622e","impliedFormat":1},{"version":"bc9ee0192f056b3d5527bcd78dc3f9e527a9ba2bdc0a2c296fbc9027147df4b2","impliedFormat":1},{"version":"330896c1a2b9693edd617be24fbf9e5895d6e18c7955d6c08f028f272b37314d","impliedFormat":1},{"version":"1d9c0a9a6df4e8f29dc84c25c5aa0bb1da5456ebede7a03e03df08bb8b27bae6","impliedFormat":1},{"version":"84380af21da938a567c65ef95aefb5354f676368ee1a1cbb4cae81604a4c7d17","impliedFormat":1},{"version":"1af3e1f2a5d1332e136f8b0b95c0e6c0a02aaabd5092b36b64f3042a03debf28","impliedFormat":1},{"version":"30d8da250766efa99490fc02801047c2c6d72dd0da1bba6581c7e80d1d8842a4","impliedFormat":1},{"version":"03566202f5553bd2d9de22dfab0c61aa163cabb64f0223c08431fb3fc8f70280","impliedFormat":1},{"version":"4c0a1233155afb94bd4d7518c75c84f98567cd5f13fc215d258de196cdb40d91","impliedFormat":1},{"version":"e7765aa8bcb74a38b3230d212b4547686eb9796621ffb4367a104451c3f9614f","impliedFormat":1},{"version":"1de80059b8078ea5749941c9f863aa970b4735bdbb003be4925c853a8b6b4450","impliedFormat":1},{"version":"1d079c37fa53e3c21ed3fa214a27507bda9991f2a41458705b19ed8c2b61173d","impliedFormat":1},{"version":"5bf5c7a44e779790d1eb54c234b668b15e34affa95e78eada73e5757f61ed76a","impliedFormat":1},{"version":"5835a6e0d7cd2738e56b671af0e561e7c1b4fb77751383672f4b009f4e161d70","impliedFormat":1},{"version":"5c634644d45a1b6bc7b05e71e05e52ec04f3d73d9ac85d5927f647a5f965181a","impliedFormat":1},{"version":"4b7f74b772140395e7af67c4841be1ab867c11b3b82a51b1aeb692822b76c872","impliedFormat":1},{"version":"27be6622e2922a1b412eb057faa854831b95db9db5035c3f6d4b677b902ab3b7","impliedFormat":1},{"version":"a68d4b3182e8d776cdede7ac9630c209a7bfbb59191f99a52479151816ef9f9e","impliedFormat":99},{"version":"39644b343e4e3d748344af8182111e3bbc594930fff0170256567e13bbdbebb0","impliedFormat":99},{"version":"ed7fd5160b47b0de3b1571c5c5578e8e7e3314e33ae0b8ea85a895774ee64749","impliedFormat":99},{"version":"63a7595a5015e65262557f883463f934904959da563b4f788306f699411e9bac","impliedFormat":1},{"version":"4ba137d6553965703b6b55fd2000b4e07ba365f8caeb0359162ad7247f9707a6","impliedFormat":1},{"version":"6de125ea94866c736c6d58d68eb15272cf7d1020a5b459fea1c660027eca9a90","affectsGlobalScope":true,"impliedFormat":1},{"version":"8fac4a15690b27612d8474fb2fc7cc00388df52d169791b78d1a3645d60b4c8b","affectsGlobalScope":true,"impliedFormat":1},{"version":"064ac1c2ac4b2867c2ceaa74bbdce0cb6a4c16e7c31a6497097159c18f74aa7c","impliedFormat":1},{"version":"3dc14e1ab45e497e5d5e4295271d54ff689aeae00b4277979fdd10fa563540ae","impliedFormat":1},{"version":"d3b315763d91265d6b0e7e7fa93cfdb8a80ce7cdd2d9f55ba0f37a22db00bdb8","impliedFormat":1},{"version":"b789bf89eb19c777ed1e956dbad0925ca795701552d22e68fd130a032008b9f9","impliedFormat":1},{"version":"7e45e1db82ba1489acd6bb4bbdb8f3f70c31af5b0f7b245c1936efac7fc58b7a","affectsGlobalScope":true},"7ad303e40d4fddf44f156129e397511953a71481c5cfd86b1862649aaaf240cc",{"version":"155d2e6caadb7de14cd4c337164f7febade2bcefb7645c7094158cd80e4b9c1f","impliedFormat":99},{"version":"fcc60c64e9ff115a2ddb9fcaeb19d45668b353ccafc55054588c0ffb5bfb7a53","impliedFormat":99},{"version":"0c2f0f87ad46e9b8f458f4392e355a07d8231d07ab4648c9cb8b108d3c947bb0","impliedFormat":99},{"version":"c1a2e05eb6d7ca8d7e4a7f4c93ccf0c2857e842a64c98eaee4d85841ee9855e6","impliedFormat":1},{"version":"835fb2909ce458740fb4a49fc61709896c6864f5ce3db7f0a88f06c720d74d02","impliedFormat":1},{"version":"6e5857f38aa297a859cab4ec891408659218a5a2610cd317b6dcbef9979459cc","impliedFormat":1},{"version":"ead8e39c2e11891f286b06ae2aa71f208b1802661fcdb2425cffa4f494a68854","impliedFormat":1},{"version":"82919acbb38870fcf5786ec1292f0f5afe490f9b3060123e48675831bd947192","impliedFormat":1},{"version":"e222701788ec77bd57c28facbbd142eadf5c749a74d586bc2f317db7e33544b1","impliedFormat":1},{"version":"09154713fae0ed7befacdad783e5bd1970c06fc41a5f866f7f933b96312ce764","impliedFormat":1},{"version":"8d67b13da77316a8a2fabc21d340866ddf8a4b99e76a6c951cc45189142df652","impliedFormat":1},{"version":"a91c8d28d10fee7fe717ddf3743f287b68770c813c98f796b6e38d5d164bd459","impliedFormat":1},{"version":"68add36d9632bc096d7245d24d6b0b8ad5f125183016102a3dad4c9c2438ccb0","impliedFormat":1},{"version":"3a819c2928ee06bbcc84e2797fd3558ae2ebb7e0ed8d87f71732fb2e2acc87b4","impliedFormat":1},{"version":"f6f827cd43e92685f194002d6b52a9408309cda1cec46fb7ca8489a95cbd2fd4","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"a270a1a893d1aee5a3c1c8c276cd2778aa970a2741ee2ccf29cc3210d7da80f5","impliedFormat":1},{"version":"add0ce7b77ba5b308492fa68f77f24d1ed1d9148534bdf05ac17c30763fc1a79","impliedFormat":1},{"version":"8926594ee895917e90701d8cbb5fdf77fc238b266ac540f929c7253f8ad6233d","impliedFormat":1},{"version":"2f67911e4bf4e0717dc2ded248ce2d5e4398d945ee13889a6852c1233ea41508","impliedFormat":1},{"version":"d8430c275b0f59417ea8e173cfb888a4477b430ec35b595bf734f3ec7a7d729f","impliedFormat":1},{"version":"69364df1c776372d7df1fb46a6cb3a6bf7f55e700f533a104e3f9d70a32bec18","impliedFormat":1},{"version":"6042774c61ece4ba77b3bf375f15942eb054675b7957882a00c22c0e4fe5865c","impliedFormat":1},{"version":"5a3bd57ed7a9d9afef74c75f77fce79ba3c786401af9810cdf45907c4e93f30e","impliedFormat":1},{"version":"ed8763205f02fb65e84eff7432155258df7f93b7d938f01785cb447d043d53f3","impliedFormat":1},{"version":"30db853bb2e60170ba11e39ab48bacecb32d06d4def89eedf17e58ebab762a65","impliedFormat":1},{"version":"e27451b24234dfed45f6cf22112a04955183a99c42a2691fb4936d63cfe42761","impliedFormat":1},{"version":"2316301dd223d31962d917999acf8e543e0119c5d24ec984c9f22cb23247160c","impliedFormat":1},{"version":"58d65a2803c3b6629b0e18c8bf1bc883a686fcf0333230dd0151ab6e85b74307","impliedFormat":1},{"version":"e818471014c77c103330aee11f00a7a00b37b35500b53ea6f337aefacd6174c9","impliedFormat":1},{"version":"d4a5b1d2ff02c37643e18db302488cd64c342b00e2786e65caac4e12bda9219b","impliedFormat":1},{"version":"29f823cbe0166e10e7176a94afe609a24b9e5af3858628c541ff8ce1727023cd","impliedFormat":1},{"version":"3fd172aef12c427cf98f20701da30f3b23474e3bdbe2ce785d94d6d85ef3f39c","signature":"006af7eb85660808798fc5a67cd482fdd7fc3bc2df91f878305c3797f74ac53a"},{"version":"e092ace4da05d4ccd824eda722142294cf5f5e477a01550ca99d767b4eda6794","signature":"fa9847d3846959d7231be0be11c108636098fe8a2defa0a1fe5005fbcc027de9"},{"version":"5ec6ba1674cf73d6a2d42e8ec00ded92f0211a92ae1bf5b1af1dbd1eb84e6ffe","impliedFormat":1},{"version":"c6fe327c538417b8dd5b9bb32abcd7911534b10da3a4514f3445cdb28cf3abf2","impliedFormat":99},{"version":"bb0519ff5ef245bbf829d51ad1f90002de702b536691f25334136864be259ec5","impliedFormat":99},{"version":"0065cdb7ac9f5b19921632de63f888ec2cc11ad57f7fc868f44bf0faad2fce3e","impliedFormat":99},{"version":"1921b8b1513bb282e741587ec802ef76a643a3a56b9ee07f549911eab532ee2e","impliedFormat":99},{"version":"16de02d4e7ae55933e1e310af296e8802753f2f9c60bf7436413b51cae0a451c","impliedFormat":99},{"version":"03200d03f2b750f0bc64cbbeac20d5bacb986dc6b2de4e464b47589ad9c6b740","impliedFormat":99},{"version":"8c1adc3171d0287f3a26f4891a7d1834c89999573a9b444aa5ff519dcc43a2b7","impliedFormat":99},{"version":"015916d335054556670a8c67266c493ce792a2c23a530a6b430f1662a65b73a8","impliedFormat":99},{"version":"e443ee5820e3d882fcbe364d1ba590754050c9bcffc981ca73775e4ad4321b1d","impliedFormat":99},{"version":"1e3db23414e1d91cb97b22fa004c2ae45c2e137ebc5d383e02e161970ec00cb0","impliedFormat":99},{"version":"49fcfda71ea42a9475b530479a547f93d4e88c2deb0c713845243f5c08af8d76","impliedFormat":99},{"version":"4f97089fe15655ae448c9d005bb9a87cc4e599b155edc9e115738c87aa788464","impliedFormat":99},{"version":"2fff037c771e3fe6108b14137e56827197944b855aa2df40f21fa2d8a2758e1e","impliedFormat":99},{"version":"22929f9874783b059156ee3cfa864d6f718e1abf9c139f298a037ae0274186f6","impliedFormat":99},{"version":"c72a7c316459b2e872ca4a9aca36cc05d1354798cee10077c57ff34a34440ac2","impliedFormat":99},{"version":"3e5bbf8893b975875f5325ebf790ab1ab38a4173f295ffea2ed1f108d9b1512c","impliedFormat":99},{"version":"9e4a38448c1d26d4503cf408cc96f81b7440a3f0a95d2741df2459fe29807f67","impliedFormat":99},{"version":"84124d21216da35986f92d4d7d1192ca54620baeca32b267d6d7f08b5db00df9","impliedFormat":99},{"version":"c08976f55a00ddbb3b13a68a9a0d418117f35c6e2d40f1f6f55468fc180a01f0","impliedFormat":99},{"version":"25f5bf39f0785a2976d0af5ac02f5c18ca759cde62bc48dd1d0d99871d9ad86f","impliedFormat":99},{"version":"877c73fdbe90937b3c16b5827526a428bf053957a202ac8c2fd88d6eab437764","impliedFormat":99},{"version":"e324b2143fa6e32fac37ed9021b88815e181b045a9f17dbb555b72d55e47cdc1","impliedFormat":99},{"version":"3e90ea83e3803a3da248229e3027a01428c3b3de0f3029f86c121dc76c5cdcc2","impliedFormat":99},{"version":"9368c3e26559a30ad3431d461f3e1b9060ab1d59413f9576e37e19aaf2458041","impliedFormat":99},{"version":"915e5bb8e0e5e65f1dc5f5f36b53872ffcdcaef53903e1c5db7338ea0d57587a","impliedFormat":99},{"version":"92cf986f065f18496f7fcb4f135bff8692588c5973e6c270d523191ef13525ad","impliedFormat":99},{"version":"652f2bd447e7135918bc14c74b964e5fe48f0ba10ff05e96ed325c45ac2e65fb","impliedFormat":99},{"version":"cc2156d0ec0f00ff121ce1a91e23bd2f35b5ab310129ad9f920ddaf1a18c2a4d","impliedFormat":99},{"version":"7b371e5d6e44e49b5c4ff88312ae00e11ab798cfcdd629dee13edc97f32133d8","impliedFormat":99},{"version":"e9166dab89930e97bb2ce6fc18bcc328de1287b1d6e42c2349a0f136fc1f73e6","impliedFormat":99},{"version":"6dc0813d9091dfaed7d19df0c5a079ee72e0248ce5e412562c5633913900be25","impliedFormat":99},{"version":"e704c601079399b3f2ec4acdfc4c761f5fe42f533feaaab7d2c1c1528248ca3e","impliedFormat":99},{"version":"49104d28daa32b15716179e61d76b343635c40763d75fe11369f681a8346b976","impliedFormat":99},{"version":"6d414a0690dd5e23448958babe29b6aeb984faf8ff79248310f6c9718a9196ad","impliedFormat":99},{"version":"0bfdb8230777769f3953fd41cf29c3cb61262a0be678dd5c899e859c0d159efe","impliedFormat":99},{"version":"97e685ac984fc93dcdae6c24f733a7a466274c103fdcf5d3b028eaa9245f59d6","impliedFormat":99},{"version":"68526ea8f3bbf75a95f63a3629bebe3eb8a8d2f81af790ce40bc6aad352a0c12","impliedFormat":99},{"version":"bcab57f5fe8791f2576249dfcc21a688ecf2a5929348cfe94bf3eb152cff8205","impliedFormat":99},{"version":"b5428f35f4ebf7ea46652b0158181d9c709e40a0182e93034b291a9dc53718d8","impliedFormat":99},{"version":"0afcd28553038bca2db622646c1e7fcf3fb6a1c4d3b919ef205a6014edeeae0f","impliedFormat":99},{"version":"ee016606dd83ceedc6340f36c9873fbc319a864948bc88837e71bd3b99fdb4f6","impliedFormat":99},{"version":"0e09ffe659fdd2e452e1cbe4159a51059ae4b2de7c9a02227553f69b82303234","impliedFormat":99},{"version":"4126cb6e6864f09ca50c23a6986f74e8744e6216f08c0e1fe91ab16260dab248","impliedFormat":99},{"version":"4927dba9193c224e56aa3e71474d17623d78a236d58711d8f517322bd752b320","impliedFormat":99},{"version":"3d3f189177511d1452e7095471e3e7854b8c44d94443485dc21f6599c2161921","impliedFormat":99},{"version":"99f169da66be3a487ce1fe30b11f33ed2bdf57893729caaea453517d9a7fa523","impliedFormat":99},{"version":"043195af0b52aadd10713870dd60369df0377ed153104b26e6bac1213b19f63e","impliedFormat":99},{"version":"ad17a36132569045ab97c8e5badf8febb556011a8ed7b2776ff823967d6d5aca","impliedFormat":99},{"version":"698d2b22251dbbfc0735e2d6ed350addead9ad031fac48b8bb316e0103d865db","impliedFormat":99},{"version":"ff10facf373a13d2864ff4de38c4892d74be27d9c6468dac49c08adabbf9b0eb","impliedFormat":99},{"version":"97b1cf4599cc3bc2e84b997aa1af60d91ca489d96bea0e20aaff0e52a5504b29","impliedFormat":99},{"version":"853dfbcd0999d3edc6be547d83dc0e0d75bf44530365b9583e75519d35984c35","impliedFormat":99},{"version":"abbb31e3da98902306359386224021bfb6cfa2496c89bbbde7ee2065cf58297c","impliedFormat":99},{"version":"6139824680a34eba08979f2e21785a761870384a4df16c143b19288aced9c346","impliedFormat":99},{"version":"c7d89156a4f0313c66377afd14063a9e5be3f8e01a7b5fae4723ef07a2628e55","impliedFormat":99},{"version":"e2381c64702025b4d57b005e94ed0b994b5592488d76f1e5f67f59d1860ebb70","impliedFormat":99},{"version":"a64e28f2333ea0324632cf81fd73dc0f7090525547a76308cb1dfe5dab96596a","impliedFormat":99},{"version":"d7dfcb039ff9cff38ccd48d2cc1ba95ca45c316670eddbcf81784e21b7128692","impliedFormat":99},{"version":"8ec3b354ca25fa7524ac376da4480ffb141157ed6900a830cfe40d1ab0f2162a","impliedFormat":99},{"version":"d204b9ae964f73721d593e97c54fc55f7fd67de826ce9e9f14b1e762190f23d1","impliedFormat":99},{"version":"c010c1317efa90a9b10d67f0ad6b96bde45818b6cdca32afababcf7a2dd7ecc3","impliedFormat":99},{"version":"5ba3ed0ee7a5a9b20e92f626ee6ba11fe28c76e2df22bad25769461d2a4fc753","impliedFormat":99},{"version":"7db31e5afa6ffa20d6e65505d1af449415e8a489d628f93a9a1f487d89a218c6","impliedFormat":99},{"version":"db5968a602bb6c07ab2d608e3035489d443f3556209ded7c0679e0c9c7b671ed","impliedFormat":99},{"version":"d010efe139c8bb78497dc7185dddbbcefc84d3059b5d8549c26221257818a961","impliedFormat":99},{"version":"85059ed9b6605d92c753daf3a534855ba944be69ff1a12ab4eca28cefbabd07a","impliedFormat":99},{"version":"687208233ae7a969baa2d0c565c9f24eb4cb1e64d6cfb30f71afec9e929e58c2","impliedFormat":99},{"version":"ea68a96f4e2ba9ca97d557b7080fbdb7f6e6cf781bb6d2e084e54da2ac2bb36c","impliedFormat":99},{"version":"05f2d8f571ded41b2d9c3881fc8b76c780d36310069d51a8dc73fb8500d4e3d0","impliedFormat":99},{"version":"f3ed9a4ec3123351b2a8cba473e9a6f173eab5458309f380fe0039642f70bcae","impliedFormat":99},{"version":"21f96085ed19d415725c5a7d665de964f8283cacef43957de10bdd0333721cc4","impliedFormat":99},{"version":"e8d4da9e0859c6d41c4f1c3f4d0e70446554ba6a6ab91e470f01af6a2dcac9bf","impliedFormat":99},{"version":"7e6eaf770849f6cf68949b3c7caf9a7d2b7b28890978806ae1ff9120db07168c","impliedFormat":99},{"version":"a10fd5d76a2aaba572bec4143a35ff58912e81f107aa9e6d97f0cd11e4f12483","impliedFormat":99},{"version":"1215f54401c4af167783d0f88f5bfb2dcb6f0dacf48495607920229a84005538","impliedFormat":99},{"version":"9d1352fbed9d30513e1306cfdbdfc07af8e9e950973a97417b081075c5ff8e1a","impliedFormat":99},{"version":"07603bb68d27ff41499e4ed871cde4f6b4bb519c389dcf25d7f0256dfaa56554","impliedFormat":99},{"version":"6bd4aa523d61e94da44cee0ee0f3b6c8d5f1a91ef0bd9e8a8cf14530b0a1a6df","impliedFormat":99},{"version":"6b6e2508f79513e01386273e63d0fc3617613d80a5aca950a2b0fc33d90ad0b4","impliedFormat":99},{"version":"52869a2597d5c33241d1debc4dfb0c1c0a5a05b8a7b5f85de5cfe0e553e86f47","impliedFormat":99},{"version":"2fe93aef0ee58eaa1b22a9b93c8d8279fe94490160703e1aabeff026591f8300","impliedFormat":99},{"version":"bbb02e695c037f84947e56da3485bb0d0da9493ed005fa59e4b3c5bc6d448529","impliedFormat":99},{"version":"d388e0c1c9a42d59ce88412d3f6ce111f63ce2ff558e0a3f84510092431dfee0","impliedFormat":99},{"version":"326a980e72f7b9426be0805774c04838e95195b467bea2072189cefe708e9be7","impliedFormat":99},{"version":"35ea0a1e995aef5ae19b1553548a793c76eb31bdf7fef30bc74656660c3a09c3","impliedFormat":99},{"version":"ba666b3ab51c8bc916c0cebc11a23f4afec6c504c767fd5f0228358f7d285322","impliedFormat":99},{"version":"c10972922d1887fe48ed1722e04ab963e85e1ac12263a167edef9b804a2af097","impliedFormat":99},{"version":"6efeacbd1759ea57a4c7264eb766c531ae0ab2c00385294be58bc5031ef43ad1","impliedFormat":99},{"version":"1c261f5504d0175be4f1b6b99f101f4c3a129a5a29fc768e65c52d6861ca5784","impliedFormat":99},{"version":"f0e69b5877b378d47cbac219992b851e2bbc0f7e3a3d3579d67496dabd341ec4","impliedFormat":99},{"version":"b5ea27f19a54feca5621f5ba36a51026128ea98e7777e5d47f08b79637527cf5","impliedFormat":99},{"version":"b54890769fa3c34ab3eb7e315b474f52d5237c86c35f17d59eb21541e7078f11","impliedFormat":99},{"version":"c133db4b6c17a96db7fa36607c59151dec1e5364d9444cbe15e8c0ea4943861e","impliedFormat":99},{"version":"3a0514f77606d399838431166a0da6dbd9f3c7914eae5bbfbd603e3b6a552959","impliedFormat":99},{"version":"fa568f8d605595e1cffbfca3e8c8c492cf88ae2c6ed151f6c64acf0f9e8c25d8","impliedFormat":99},{"version":"c76fb65cb2eb09a0ee91f02ff5b43a607b94a12c34d16d005b2c0afc62870766","impliedFormat":99},{"version":"cf7af60a0d4308a150df0ab01985aabb1128638df2c22dd81a2f5b74495a3e45","impliedFormat":99},{"version":"913bbf31f6b3a7388b0c92c39aec4e2b5dba6711bf3b04d065bd80c85b6da007","impliedFormat":99},{"version":"42d8c168ca861f0a5b3c4c1a91ff299f07e07c2dd31532cd586fd1ee7b5e3ae6","impliedFormat":99},{"version":"a29faa7cb35193109ec1777562ca52c72e7382ffe9916b26859b5874ad61ff29","impliedFormat":99},{"version":"15bdf2eeef95500ba9f1602896e288cb425e50462b77a07fa4ca23f1068abb21","impliedFormat":99},{"version":"452db58fd828ab87401f6cecc9a44e75fa40716cc4be80a6f66cf0a43c5a60cc","impliedFormat":99},{"version":"54592d0215a3fd239a6aa773b1e1a448dc598b7be6ce9554629cd006ee63a9d6","impliedFormat":99},{"version":"9ee28966bb038151e21e240234f81c6ba5be6fde90b07a9e57d4d84ae8bc030c","impliedFormat":99},{"version":"ad639ad2ec93535c23cfa42fbd23d0d44be0fb50668dd57ee9b38b913e912430","impliedFormat":99},{"version":"956e43b28b5244b27fdb431a1737a90f68c042e162673769330947a8d727d399","impliedFormat":99},{"version":"92a2034da56c329a965c55fd7cffb31ccb293627c7295a114a2ccd19ab558d28","impliedFormat":99},{"version":"c1b7957cd42a98ab392ef9027565404e5826d290a2b3239a81fbac51970b2e63","impliedFormat":99},{"version":"4861ee34a633706bcbba4ea64216f52c82c0b972f3e790b14cf02202994d87c5","impliedFormat":99},{"version":"7af4e33f8b95528de005282d6cca852c48d293655dd7118ad3ce3d4e2790146f","impliedFormat":99},{"version":"df345b8d5bf736526fb45ae28992d043b2716838a128d73a47b18efffe90ffa7","impliedFormat":99},{"version":"a6e18a521af3c12bb42bf2da73d0ef1a82420425726c662d068d8d4d813b16c5","impliedFormat":99},{"version":"dcc38f415a89780b34d827b45493d6dbadb05447d194feb4498172e508c416ac","impliedFormat":99},{"version":"7e917e3b599572a2dd9cfa58ff1f68fda9e659537c077a2c08380b2f2b14f523","impliedFormat":99},{"version":"20b108e922abd1c1966c3f7eb79e530d9ac2140e5f51bfa90f299ad5a3180cf9","impliedFormat":99},{"version":"2bc82315d4e4ed88dc470778e2351a11bc32d57e5141807e4cdb612727848740","impliedFormat":99},{"version":"e2dd1e90801b6cd63705f8e641e41efd1e65abd5fce082ef66d472ba1e7b531b","impliedFormat":99},{"version":"a3cb22545f99760ba147eec92816f8a96222fbb95d62e00706a4c0637176df28","impliedFormat":99},{"version":"287671a0fe52f3e017a58a7395fd8e00f1d7cd9af974a8c4b2baf35cfda63cfa","impliedFormat":99},{"version":"e2cdad7543a43a2fb6ed9b5928821558a03665d3632c95e3212094358ae5896b","impliedFormat":99},{"version":"e3588e9db86c6eaa572c313a23bf10f7f2f8370e62972996ac79b99da065acaa","impliedFormat":99},{"version":"1f4700278d1383d6b53ef1f5aecd88e84d1b7e77578761838ffac8e305655c29","impliedFormat":99},{"version":"6362a4854c52419f71f14d3fee88b3b434d1e89dcd58a970e9a82602c0fd707a","impliedFormat":99},{"version":"fb1cc1e09d57dfeb315875453a228948b904cbe1450aaf8fda396ff58364a740","impliedFormat":99},{"version":"50652ed03ea16011bb20e5fa5251301bb7e88c80a6bf0c2ea7ed469be353923b","impliedFormat":99},{"version":"4a6c2ac831cff2d8fa846dfb010ee5f7afce3f1b9bd294298ee54fdc555f1161","impliedFormat":99},{"version":"6b7606e690f511bd1fa9218487aceb2f8693218eed5328a7af87a8f34e88936e","impliedFormat":99},{"version":"730cb342a128f5a8a036ffbd6dbc1135b623ce2100cefe1e1817bb8845bc7100","impliedFormat":99},{"version":"73468feda625fe017c2904c4d753e8e4e2e292502af8bcd4db59ff56a762692a","impliedFormat":99},{"version":"b88c76c82d8a827a54c5469c1374e1a815537e0e86bd39888d5fd0668b81984f","impliedFormat":99},{"version":"e66c6ebecadb0c6a35fe2fcabb3cbce17f72501c4ef6ea67082e257ebbc955d7","impliedFormat":99},{"version":"ac56b2f316b70d6a727fdbbcfa8d124bcd1798c293487acb2b27a43b5c886bb0","impliedFormat":99},{"version":"d849376baf73ec0b17ffd29de702a2fdbbe0c0390ec91bebf12b6732bf430d29","impliedFormat":99},{"version":"81332669fc268ee900f4ca16eee6a78ec60ab38c3ef7620305c2767fbc66aaec","impliedFormat":99},{"version":"0f9c9f7d13a5cf1c63eb56318b6ae4dfa2accef1122b2e88b5ed1c22a4f24e3b","impliedFormat":99},{"version":"8a0030523b607b2aea7e60a562abc1dba63ac19fef9f71ac82139f3425cb1f55","impliedFormat":99},{"version":"666f957cb4e73a2a1226d3f0eee0b255b9a2267d143b8bfe861e83c80b7b2d45","impliedFormat":99},{"version":"30bdde113367d16dfa032328192fa1d32421bb20a2715714c6895f5c7eed5c4e","impliedFormat":99},{"version":"2d4530d6228c27906cb4351f0b6af52ff761a7fab728622c5f67e946f55f7f00","impliedFormat":99},{"version":"77dabe31d44c48782c529d5c9acddc41f799bf9b424b259596131efc77355478","impliedFormat":99},{"version":"88ca3a19c8b99e409299e1173d2fe1b79c5960e966f2f3a7db6788969414f546","impliedFormat":99},{"version":"c693f9c0fda89d41e7670429d30ddcda570f9ad63a7301379695916524eb6d2e","impliedFormat":99},{"version":"66a83abc49216ddee4049056ee2b345c08c912529e93aa725d6cae384561de83","impliedFormat":99},{"version":"6b514d5159d0d189675a1d5a707ba068a6da6bc097afb2828aae0c98d8b32f08","impliedFormat":99},{"version":"39d7dbcfec85393fedc8c7cf62ee93f7e97c67605279492b085723b54ccaca8e","impliedFormat":99},{"version":"81882f1fa8d1e43debb7fa1c71f50aa14b81de8c94a7a75db803bb714a9d4e27","impliedFormat":99},{"version":"d2c74e0608352d6eb35b35633cdbce7ed49c3c4498720c9dd8053fdc47a9db8a","impliedFormat":99},{"version":"bca335fd821572e3f8f1522f6c3999b0bc1fe3782b4d443c317df57c925543ed","impliedFormat":99},{"version":"73332a05f142e33969f9a9b4fb9c12b08b57f09ada25eb3bb94194ca035dc83d","impliedFormat":99},{"version":"c366621e6a8febe9bbca8c26275a1272d99a45440156ca11c860df7aa9d97e6d","impliedFormat":99},{"version":"d9397a54c21d12091a2c9f1d6e40d23baa327ae0b5989462a7a4c6e88e360781","impliedFormat":99},{"version":"dc0e2f7f4d1f850eb20e226de8e751d29d35254b36aa34412509e74d79348b75","impliedFormat":99},{"version":"c7bc760336ac14f9423c83ca2eec570a2be6f73d2ce7f890c6cce76c931c8e15","impliedFormat":99},{"version":"dea1773a15722931fbfe48c14a2a1e1ad4b06a9d9f315b6323ee112c0522c814","impliedFormat":99},{"version":"b26e3175cf5cee8367964e73647d215d1bf38be594ac5362a096c611c0e2eea8","impliedFormat":99},{"version":"4280093ace6386de2a0d941b04cff77dda252f59a0c08282bd3d41ccc79f1a50","impliedFormat":99},{"version":"fe17427083904947a4125a325d5e2afa3a3d34adaedf6630170886a74803f4a2","impliedFormat":99},{"version":"0246f9f332b3c3171dcdd10edafab6eccb918c04b2509a74e251f82e8d423fb7","impliedFormat":99},{"version":"f6ef33c2ff6bbdf1654609a6ca52e74600d16d933fda1893f969fc922160d4d7","impliedFormat":99},{"version":"1abd22816a0d992fd33b3465bf17a5c8066bf13a8c6ca4fc0cd28884b495762d","impliedFormat":99},{"version":"82032a08169ea01cf01aa5fd3f7a02f1f417697df5e42fc27d811d23450bc28d","impliedFormat":99},{"version":"9c8cbd1871126e98602502444cffb28997e6aa9fbc62d85a844d9fd142e9ae1b","impliedFormat":99},{"version":"b0e20abc4a73df8f97b3f1223cc330e9ba3b2062db1908aa2a97754a792139ac","impliedFormat":99},{"version":"bc1f2428d738ab789339030078adf313100471c37d8d69f6cf512a5715333afc","impliedFormat":99},{"version":"dc500c6a23c9432849c82478bdab762fa7bdf9245298c2279a7063dd05ae9f9a","impliedFormat":99},{"version":"cd1b6a2503fc554dcab602e053565c4696e4262b641b897664d840a61f519229","impliedFormat":99},{"version":"af1580cd202df0e33fc592fe1d75d720c15930a4127a87633542b33811316724","impliedFormat":99},{"version":"af6106fc6900a51b49a8e6f4c5a8f18295eb9ae34efbea3c2b7db45e42b41b5e","impliedFormat":99},{"version":"cd090c8806133525e1085f6b820618194d0133e6fc328d03956969d211a9c885","impliedFormat":99},{"version":"9ea6fea875302b2bb3976f7431680affc45a4319499d057ce12be04e4f487bf9","impliedFormat":99},{"version":"66e0c3f9875da7be383d0c78c8b8940b6ebae3c6a0fbfd7e77698b5e8ade3b05","impliedFormat":99},{"version":"da38d326fe6a72491cad23ea22c4c94dfc244363b6a3ec8a03b5ad5f4ee6337b","impliedFormat":99},{"version":"da587bf084b08ea4e36a134ec5fb19ae71a0f32ec3ec2a22158029cb2b671e28","impliedFormat":99},{"version":"517a31c520e08c51cfe6d372bc0f5a6bf7bd6287b670bcaa180a1e05c6d4c4da","impliedFormat":99},{"version":"0263d94b7d33716a01d3e3a348b56c2c59e6d897d89b4210bdbf27311127223c","impliedFormat":99},{"version":"520ed22a4f728091f7703465c1437b948b51f82ffcaa49751c505c60a9e18977","impliedFormat":99},{"version":"a2e6a99c0fb4257e9301d592da0834a2cb321b9b1e0a81498424036109295f8b","impliedFormat":99},{"version":"c6b5ae9f99f1fccadc23d56307a28c8490c48e687678f2cafa006b3b9b8e73e4","impliedFormat":99},{"version":"eae178ee8d7292bcd23be2b773dda60b055bc008a0ddce2acc1bfe30cc36cf04","impliedFormat":99},{"version":"e0b5f197fb47b39a4689ad356b8488e335bbf399b283492c0ffae0cfda88837b","impliedFormat":99},{"version":"adb7aa4b8d8b423d0d7e78b6a8affb88c3a32a98e21cd54fcafd570ad8588d0c","impliedFormat":99},{"version":"643e22362c15304f344868ec0e7c0b4a1bc2b56c8b81d5b9f0ee0a6f3c690fff","impliedFormat":99},{"version":"f89e713e33bfcc7cc1d505a1e76f260b7aae72f8ba83f800ab47b5db2fed8653","impliedFormat":99},{"version":"4c3be904cab639b22989d13a9c4ea1184388af2ff27c4f5b39960628a76629db","impliedFormat":99},{"version":"307009cbc7927f6c2e7b482db913589f8093108b8bd4a450cfe749b80476aea0","impliedFormat":99},{"version":"a5bf6d947ce6a4f1935e692c376058493dbfbd9f69d9b60bbaf43fd5d22c324b","impliedFormat":99},{"version":"b25d054d2a30e62f72f8d17885e19fe84d8026e169e488c6f0dc0ea9425b2e07","impliedFormat":99},{"version":"7deb9fb41fbf45e79da80de7e0eb10437cd81a36024edff239aa59228849b2d3","impliedFormat":99},{"version":"71f3db4a80ef331c45612b9e3649440da41a885eaf727b3bfe5b5723c7d5a4a1","impliedFormat":99},{"version":"687208233ae7a969baa2d0c565c9f24eb4cb1e64d6cfb30f71afec9e929e58c2","impliedFormat":99},{"version":"71af68459ff292520dd77bf861bfb70e3b154878a3e8db97841476deb9523f8a","impliedFormat":99},{"version":"956aeea3c94b894b3ae95a9691c1a8fa6f9eae47d30817a59c14908113322caa","impliedFormat":99},{"version":"87cbb57d0f80470800378bff30f8bc7e2c99a7b30a818bf7ccbf049407714a10","impliedFormat":99},{"version":"cc411cd97607f993efb008c8b8a67207e50fdd927b7e33657e8e332c2326c9f3","impliedFormat":99},{"version":"b144c6cdf6525af185cd417dc85fd680a386f0840d7135932a8b6839fdee4da6","impliedFormat":99},{"version":"2125e8c5695ddfded3b93c3537b379df2b4dcd3cdad97fa6ec87d51beda0bef1","impliedFormat":99},{"version":"572ee8f367fe4068ccb83f44028ddb124c93e3b2dcc20d65e27544d77a0b84d3","impliedFormat":99},{"version":"7d604c1d876ef8b7fec441cf799296fd0d8f66844cf2232d82cf36eb2ddff8fe","impliedFormat":99},{"version":"7b86b536d3e8ca578f8fbc7e48500f89510925aeda67ed82d5b5a3213baf5685","impliedFormat":99},{"version":"861596a3b58ade9e9733374bd6b45e5833b8b80fd2eb9fe504368fc8f73ae257","impliedFormat":99},{"version":"a3da7cf20826f3344ad9a8a56da040186a1531cace94e2788a2db795f277df94","impliedFormat":99},{"version":"900a9da363740d29e4df6298e09fad18ae01771d4639b4024aa73841c6a725da","impliedFormat":99},{"version":"4e979a85e80e332414f45089ff02f396683c0b5919598032a491eb7b981fedfd","impliedFormat":99},{"version":"6d3496cac1c65b8a645ecbb3e45ec678dd4d39ce360eecbcb6806a33e3d9a7ae","impliedFormat":99},{"version":"d4066ba263b829f8fc098b6ae66eaa476a585dbd965852026949d41bd5b5e389","impliedFormat":99},{"version":"442f6a9e83bb7d79ff61877dc5f221eea37f1d8609d8848dfbc6228ebc7a8e90","impliedFormat":99},{"version":"90872e27aa3f2f4247daba68e779c119305eb1caf596f01d0f0518a813d06f50","impliedFormat":99},{"version":"7e4fc245cc369ba9c1a39df427563e008b8bfe5bf73c6c3f5d3a928d926a8708","impliedFormat":99},{"version":"2dd4989deea8669628ef01af137d9494c12bbfc5ff2bbe033369631932c558cb","impliedFormat":99},{"version":"d39330cb139d83d5fa5071995bb615ea48aa093018646d4985acd3c04b4e443d","impliedFormat":99},{"version":"663800dc36a836040573a5bb161d044da01e1eaf827ccc71a40721c532125a80","impliedFormat":99},{"version":"f6f1f1b294dec911359b563193a4c018e6397a98da6c6df801e8a7aefb3440b4","impliedFormat":99},{"version":"fa9c4f35c92322c61ec9a7f90dd2a290c35723348891f1459946186b189a129a","impliedFormat":99},{"version":"687208233ae7a969baa2d0c565c9f24eb4cb1e64d6cfb30f71afec9e929e58c2","impliedFormat":99},{"version":"f716500cce26a598e550ac0908723b9c452e0929738c55a3c7fe3c348416c3d0","impliedFormat":99},{"version":"259c8370338f84e745354f27bad9712418b180fbe3d9c0ab68f8bdc50a057467","impliedFormat":99},{"version":"48b83bd0962dac0e99040e91a49f794d341c7271e1744d84e1077e43ecda9e04","impliedFormat":99},{"version":"d7c98c7c260b3f68f766ec9bbd19d354db2254c190c5c6258ae6147283d308f0","impliedFormat":99},{"version":"ffa53626a9de934a9447b4152579a54a61b2ea103dbbf02b0f65519bfef98cdd","impliedFormat":99},{"version":"c427b591bfddecf5501efa905b408291a189ae579a06e4794407c8e94c8709fc","impliedFormat":99},{"version":"b6e9b15869788861fff21ec7f371bda9a2e1a1b15040cc005db4d2e792ece5ca","impliedFormat":99},{"version":"22c844fbe7c52ee4e27da1e33993c3bbb60f378fa27bb8348f32841baecb9086","impliedFormat":99},{"version":"dee6934166088b55fe84eae24de63d2e7aae9bfe918dfe635b252f682ceca95a","impliedFormat":99},{"version":"c39b9c4f5cc37a8ed51bef12075f5d023135e11a9b215739fd0dd87ee8da804a","impliedFormat":99},{"version":"db027bc9edef650cff3cbe542959f0d4ef8532073308c04a5217af25fc4f5860","impliedFormat":99},{"version":"a4e026fe4d88d36f577fbd38a390bd846a698206b6d0ca669a70c226e444af1b","impliedFormat":99},{"version":"165f3c6426e7dfff8fb0c34952d11d3b8528cb18502a7350d2eeb967177b2eb7","impliedFormat":99},{"version":"fa910f88f55844718a277ee9519206abce66629de2692676c3e2ad1c9278bdfd","impliedFormat":99},{"version":"9a7914a6000dbd6feaea9bc51065664d0fef0b5c608b7f66a7b229213e4805ef","impliedFormat":99},{"version":"9ae87bd743e93b6384efbfa306bde1fa70b6ff27533983e1e1fe08a4ef7037b8","impliedFormat":99},{"version":"5f7c0a4aad7a3406db65d674a5de9e36e0d08773f638b0f49d70e441de7127c0","impliedFormat":99},{"version":"4a43776782d9bce9cc167e176b4a4bb46e542619502ce1848d6f15946d54eaf7","impliedFormat":99},{"version":"56f4ae4e34cbff1e4158ccada4feea68a357bae86adb3bedaa65260d0af579df","impliedFormat":99},{"version":"a4f90a12cbfac13b45d256697ce70a6b4227790ca2bf3898ffd2359c19eab4eb","impliedFormat":99},{"version":"6801ebe0b7ab3b24832bc352e939302f481496b5d90b3bc128c00823990d7c7d","impliedFormat":99},{"version":"8395cc6350a8233a4da1c471bdac6b63d5ed0a0605da9f1e0c50818212145b5b","impliedFormat":99},{"version":"b58dda762d6bd8608d50e1a9cc4b4a1663a9d4aa50a9476d592a6ecdc6194af4","impliedFormat":99},{"version":"bc14cb4f3868dab2a0293f54a8fe10aa23c0428f37aece586270e35631dd6b67","impliedFormat":99},{"version":"e4cd3aaedb12ae158c239abb2a5597ab4fa38900d7e057448237eb07f56fe83f","impliedFormat":99},{"version":"99b6b07b5b54123e22e01e721a4d27eabecb7714060ec8ab60b79db5224cfcc0","impliedFormat":99},{"version":"b478cef88033c3b939a6b8a9076af57fc7030e7fd957557f82f2f57eddfc2b51","impliedFormat":99},{"version":"2fac70f99da22181acfda399eed248b47395a8eeb33c9c82d75ca966aee58912","impliedFormat":99},"6cbebe05d949bf347a387add363b5c7f35b8daf7fc7e12e27032a5f0f8aa29f7","203ce57939c2c458647e1a21acd8e9980ae6a405dffceca960b5ebd591de7bbc","32864147a60495514aad74c15a4ea4a0815a51912d3be3fc02ada35d501fcd58",{"version":"cc2958d8abd86edcdf05542bb1b40ba659db5bc5a2560720cde08e8950e63bc1","impliedFormat":99},{"version":"e44e0ea195d68c0aea951809bda325322085008c0622fc4ee44db5359f37b747","impliedFormat":99},{"version":"fa2c48fd724dd8f0e11dfb04f20d727a2595890bfa95419c83b21ed575ed77d1","impliedFormat":99},{"version":"6d23ffe7f1b73f16b08f5baeca430e6655b46fdc5862fd7bff1483b71fc6b28d","impliedFormat":99},{"version":"20be44c04e883d5fe7840d630a8d0656e95b00c2d6eebab9ab253275e7170534","impliedFormat":99},{"version":"3b674288fbdc0ff0ed2b7fc2839014c2ff209c84999fd06b6339347d0f976a85","impliedFormat":99},{"version":"87561cc8a2d7444adf4eed4b3f15bef8c6098cceb0e7617fba1cc45d187ac8c8","impliedFormat":99},{"version":"fd40c454d56e1d14e60ce13f3bc60c7fdb9bc70c6ef9c7bfafec1f0eb5d8075b","impliedFormat":1},{"version":"155ced96d70533d95c481061e2691802fae7cfb96869d7c85ac8622f53b51cb7","impliedFormat":1},{"version":"3689b6f599705380d2ceaccb4e58eec5c9439a7a5635d6e37c1ba66ed7c34b35","impliedFormat":99},{"version":"6cf0d3cc668cdbb01358ef7c2e41bbcc14d8d8e4ca424a1b6d2838d9a1cae8ce","impliedFormat":99},{"version":"b7bd70307671536c735389e0a1748555c438c392dfceb6f2ac3aa0a50ca82530","impliedFormat":99},{"version":"661c403f4c5bbf259e03f4fdc3a9e3f51ad562684f702e1b842e6c5336de0752","impliedFormat":99},{"version":"415dd92247ca21db682f75ba7e6289ab2d093cd34c6f471c6c789afd047ad4f3","impliedFormat":99},{"version":"b52f7568bb9b00bcee6c4929938226541c09d86b849b8ba8db2fe2a8bba46f49","impliedFormat":99},{"version":"39d80ec3c018d7ffe7c99ddd3a7b6844b3376c15e52937a7687d2c2828830fd0","impliedFormat":99},{"version":"828f8b38dff4e5c47b0112cb437da379c720f0360d40d392457c9775f30c8ae8","impliedFormat":99},{"version":"d42e1872d53ebb213e7bbe15e5fecdcaa9a490d2f2a2b035ee9cf4a6d3f1e44e","impliedFormat":99},{"version":"2262d96c02073dcb17a31ae8c738651ebff75f102522eae686f5462658b687a8","impliedFormat":99},{"version":"21053659ad72fe51b9dfbde4fa14dbbac0912359fa37c9a5aa75f188782b2ee8","impliedFormat":99},{"version":"e297bdcb7db008d8d7d0481f2c935a9f7f0a338f41b7e5d1cec6a7744140a4ff","impliedFormat":99},{"version":"ef816ad6735a271c4c8035a1914c3a9beaaa90b3c174da312d26bce8736e56ec","impliedFormat":99},{"version":"7202026e24c5e5b7b6e5fe6b99455a91058ef82e74a5cdf6a3a4136b7ae9c080","impliedFormat":99},{"version":"69dbe5d61d2f298046513598f55bd1e719c50dfd6af2f9feea6fc84f8aa3c4bf","impliedFormat":99},{"version":"6a78643fbbf1b0bd954a53d4edfa217b6a5f92d357fa9cdf8d2ee430f96b9472","impliedFormat":99},{"version":"2ebe2f0255b6f301ba7bc0e10c3dda289c6cf1876f289f7a8f6444613d988e5e","impliedFormat":99},{"version":"012b5083a47ccbe050763f8df2be89daa50c1606e9a0bb31f64276d508c02d78","impliedFormat":99},{"version":"de26853ee5a0a36c848c094e5b7a25a4d4ade07476d28f12c811f5c8dbcd3d1f","impliedFormat":99},{"version":"bd3b918f0ebf8accddff2889f2d7b8cddc2628d9fdd2806d265c59645f2874d9","impliedFormat":99},"9c80adb9b94cdb996ad6757420ffb60c3b768cc2b65b6b16ed298c0a71268d14","6d7916e61cc8718bf0840eb09eed213a322c1894c7f130dc2120b1b3e59c004d","55ca30ca12903241dee906430a453fa47eebc77df2543f2d1d7e3f60e452f299","0b9347131e948209a28622195a2bec680a48b133840c10b8b2f80955c093b030",{"version":"1e697c5ff827818bc1dc55d3a7650ee45783f5a0a67c0f904e1ce4b529b9e91d","signature":"2f4883d6e89c133419e0cd4367c0fcdd5648259db19fa03bb125fcbb8b56d54c"},"4311e34c102642ba3b247e4e050e10e0a2201403e48142eb873360c21ffbe82a","616a8f76b3c6b0b5ac7e436a2acdf0c7780c5fdda84848191869f9b13967ca51","b4a99eeee8430c194668786b4ae219023ebd7b11287b49a0361aa317dbc0ea61",{"version":"b40885a4e39fb67eb251fb009bf990f3571ccf7279dccad26c2261b4e5c8ebcd","impliedFormat":1},{"version":"2d0e63718a9ab15554cca1ef458a269ff938aea2ad379990a018a49e27aadf40","impliedFormat":1},{"version":"530e5c7e4f74267b7800f1702cf0c576282296a960acbdb2960389b2b1d0875b","impliedFormat":1},{"version":"1c483cc60a58a0d4c9a068bdaa8d95933263e6017fbea33c9f99790cf870f0a8","impliedFormat":1},{"version":"07863eea4f350458f803714350e43947f7f73d1d67a9ddf747017065d36b073a","impliedFormat":1},{"version":"396c2c14fa408707235d761a965bd84ce3d4fc3117c3b9f1404d6987d98a30d6","impliedFormat":1},{"version":"0c46e15efeb2ff6db7c6830c801204e1048ccf0c8cc9ab1556b0b95832c9d1c9","impliedFormat":1},{"version":"c475aa6e8f0a20c76b5684658e0adaf7e1ba275a088ee6a5641e1f7fe9130b8a","impliedFormat":1},{"version":"a42db31dacd0fa00d7b13608396ca4c9a5494ae794ad142e9fb4aa6597e5ca54","impliedFormat":1},{"version":"4d2b263907b8c03c5b2df90e6c1f166e9da85bd87bf439683f150afc91fce7e7","impliedFormat":1},{"version":"db6eec0bf471520d5de8037e42a77349c920061fb0eb82d7dc8917262cbf0f17","impliedFormat":1},{"version":"4bd6bce02977ca4e4e4e83359f51327e04e796d1053ab5aca8a38d239796fd22","impliedFormat":1},{"version":"ca70001e8ea975754a3994379faca469a99f81d00e1ff5b95cabac5e993359aa","impliedFormat":1},{"version":"b70bd59e0e52447f0c0afe7935145ef53de813368f9dd02832fa01bb872c1846","impliedFormat":1},{"version":"3bdc578841f58bfd1087e14f81394ece5efd56b953362ef100bdd5bd179cd625","impliedFormat":1},{"version":"2bc15addade46dc6480df2817c6761d84794c67819b81e9880ab5ce82afb1289","impliedFormat":1},{"version":"247d6e003639b4106281694e58aa359613b4a102b02906c277e650269eaecede","impliedFormat":1},{"version":"fe37c7dc4acc6be457da7c271485fcd531f619d1e0bfb7df6a47d00fca76f19c","impliedFormat":1},{"version":"159af954f2633a12fdee68605009e7e5b150dbeb6d70c46672fd41059c154d53","impliedFormat":1},{"version":"a1b36a1f91a54daf2e89e12b834fa41fb7338bc044d1f08a80817efc93c99ee5","impliedFormat":1},{"version":"8bb4a5b632dd5a868f3271750895cb61b0e20cff82032d87e89288faee8dd6e2","impliedFormat":1},{"version":"2a3e6dfb299953d5c8ba2aca69d61021bd6da24acea3d301c5fa1d6492fcb0ec","impliedFormat":1},{"version":"017de6fdabea79015d493bf71e56cbbff092525253c1d76003b3d58280cd82a0","impliedFormat":1},{"version":"cf94e5027dd533d4ee448b6076be91bc4186d70f9dc27fac3f3db58f1285d0be","impliedFormat":1},{"version":"74293f7ca4a5ddf3dab767560f1ac03f500d43352b62953964bf73ee8e235d3d","impliedFormat":1},{"version":"6745b52ab638aaf33756400375208300271d69a4db9d811007016e60a084830f","impliedFormat":1},{"version":"90ee466f5028251945ee737787ee5e920ee447122792ad3c68243f15efa08414","impliedFormat":1},{"version":"34c17533b08bd962570d7bdb838fcaf5bcf7b913c903bc9241b0696a635b8115","impliedFormat":1},{"version":"1d567a058fe33c75604d2f973f5f10010131ab2b46cf5dddd2f7f5ee64928f07","impliedFormat":1},{"version":"5af5ebe8c9b84f667cd047cfcf1942d53e3b369dbd63fbea2a189bbf381146c6","impliedFormat":1},{"version":"5e126f7796301203e1d1048c1e5709ff9251f872a19f5ac0ee1f375d8128ef9b","impliedFormat":1},{"version":"147734cfd0973548fb6ef75d1e7d2c0b56bb59aad72b280784e811d914dc47d6","impliedFormat":1},{"version":"d2594d95d465026ebbee361f4819dc7b3146f4a8b42091ffb5dd90f9ceb345ab","impliedFormat":1},{"version":"e399d54c1b272a400ed446ca35d5e43d6b820723c2e5727b188ebea261e7cc2e","impliedFormat":1},{"version":"123568587c36c9f2a75091d8cdf8f287193855ba5aa10797b4fc320c80920b7f","impliedFormat":1},{"version":"6deffa531bdb8817b363505e88d957653d0c454f42c69e31588d00102cd1a076","impliedFormat":1},{"version":"973551068756351486afe706b240eb4dc83678ab2d829a1c6b1a19871394fd5f","impliedFormat":1},{"version":"e647d13de80e1b6b4e1d94363ea6f5f8f77dfb95d562748b488a7248af25aabf","impliedFormat":1},{"version":"9b7b0209a8841f5ffa60ccdfae26f7dc70ea4e7e446a603ef4732e84f1bb1b4f","impliedFormat":1},{"version":"5edc4b81a61ea5e0319b32d8f581d9643cb747cf44477b16af048f62d358c433","impliedFormat":1},{"version":"d47c9f84b00def208cbfdd820f8d10425ead9dbf36350d77fb55d5ef6857dabc","impliedFormat":1},{"version":"7629bedb475a5f5d04cdf8c69f29f2cf52a1d92dd13c39661c3e865ad997bd7e","impliedFormat":1},{"version":"20cf19c8028a7b958e9c2000281d0f4c4cd12502fef7d63b088d44647cdd607b","impliedFormat":1},{"version":"799780c3726407eaa2e09e709c376ec459582f6f9c41d9643f863580cecf7ff8","impliedFormat":1},{"version":"37280465f8f9b2ea21d490979952b18b7f4d1f0d8fab2d627618fb2cfa1828e3","impliedFormat":1},{"version":"52e29afa525973fc7cff28c4b6b359d91ad030d4aa198f060f813d4abcadb099","affectsGlobalScope":true,"impliedFormat":1},{"version":"a890cccdc380629c6cd9e9d92fff4ca69b9adddde84cc503296ada99429b5a3b","impliedFormat":1},{"version":"168b6da36cf7b832173d7832e017bc6c6c7b4023bf6b2de293efb991b96bca44","impliedFormat":1},{"version":"05b39d7219bb2f55f865bca39a3772e1c0a396ea562967929d6b666560c85617","impliedFormat":1},{"version":"bcae62618c23047e36d373f0feac5b13f09689e4cd08e788af13271dbe73a139","impliedFormat":1},{"version":"2c49c6d7da43f6d21e2ca035721c31b642ebf12a1e5e64cbf25f9e2d54723c36","impliedFormat":1},{"version":"5ae003688265a1547bbcb344bf0e26cb994149ac2c032756718e9039302dfac8","impliedFormat":1},{"version":"e1744dbace6ba2051a32da3c6b40e0fc690810a87b9ad4a1925b59f8f7157a34","impliedFormat":1},{"version":"ba8a615335e3dfdf0773558357f15edfff0461db9aa0aef99c6b60ebd7c40344","impliedFormat":1},{"version":"6921769648e4b83bb10e8fcf7011ea2d8f7de5d056daacf661648935a407376e","impliedFormat":1},{"version":"dd21167f276d648aa8a6d0aacd796e205d822406a51420b7d7f5aa18a6d9d6d9","impliedFormat":1},{"version":"3dea56c1745af2c31af0c84ecc6082044dc14cfa4d7366251e5bf91693eecd8b","impliedFormat":1},{"version":"eb6360635bc14b96a243bd5134e471f3ad26b0ecaf52d9d28621e443edb56e5c","impliedFormat":1},{"version":"e6f25eb7de8d9854badecb42caec553fb50c7ec37926473e3fb7f6df45bc945f","impliedFormat":1},{"version":"62a64260ea1dada7d643377c1a0ef3495363f4cca36adf7345e8566e7d7f419b","impliedFormat":1},{"version":"8b15e8af2fc862870418d0a082a9da2c2511b962844874cf3c2bad6b2763ca10","impliedFormat":1},{"version":"3d399835c3b3626e8e00fefc37868efe23dbb660cce8742486347ad29d334edd","impliedFormat":1},{"version":"b262699ba3cc0cae81dae0d9ff1262accf9832b2b7ee6548c626d74076bff8fe","impliedFormat":1},{"version":"057cac07c7bc5abdcfba44325fcea4906dff7919a3d7d82d4ec40f8b4c90cf2f","impliedFormat":1},{"version":"d94034601782f828aa556791279c86c37f09f7034a2ab873eefe136f77a6046b","impliedFormat":1},{"version":"fd25b101370ee175be080544387c4f29c137d4e23cad4de6c40c044bed6ecf99","impliedFormat":1},{"version":"8175f51ec284200f7bd403cb353d578e49a719e80416c18e9a12ebf2c4021b2b","impliedFormat":1},{"version":"e3acb4eb63b7fc659d7c2ac476140f7c85842a516b98d0e8698ba81650a1abd4","impliedFormat":1},{"version":"04d4c47854061cc5cefc3089f38e006375ae283c559ab2ce00763bca2e49516b","impliedFormat":1},{"version":"6a2146116c2fa9ca4fefa5c1d3de821462fc22e5330cda1196be15d439728c51","impliedFormat":1},{"version":"3b10140aae26eca9f0619c299921e202351c891b34e7245762e0641469864ffd","impliedFormat":1},{"version":"c0c0b22cefd1896b92d805556fcabda18720d24981b8cb74e08ffea1f73f96c2","impliedFormat":1},{"version":"ceec94a0cd2b3a121166b6bfe968a069f33974b48d9c3b45f6158e342396e6b2","impliedFormat":1},{"version":"49e35a90f8bd2aa4533286d7013d9c9ff4f1d9f2547188752c4a88c040e42885","impliedFormat":1},{"version":"3261b6d56270a3d8535f34c2fdad217cfba860d0f74f154f0a6a2031d0c8daf9","impliedFormat":1},{"version":"7eca5b6e1cd1c28637103d2b6c44e8b89035a53e515ff31ae3babc82e6c8e1f9","impliedFormat":1},{"version":"49c9c8316d59f6175e6e0439b1d5ef1218f02ce622d1a599449de30645559eed","impliedFormat":1},{"version":"e4c48be0ffac936fb60b19394739847145674582cbc7e24000d9fd35ab037365","impliedFormat":1},{"version":"215de2c70639abaf351b8ff69041e44a767ecffc5e8d2ac13ca3f201853fa1fb","impliedFormat":1},{"version":"d228c7773484140fac7286c9ca4f0e04db4a62acb792a606a2dda24bef70dc21","impliedFormat":1},{"version":"8e464886b1ff36711539ffa15ec2482472220271100768c1d98acfdf355a23ba","impliedFormat":1},{"version":"fb0135c4906ff44d3064feebd84bae323ebb7b59b8ce7053d34e7283d27c9076","impliedFormat":1},{"version":"178c8707a575baddc8f529a6dbd5d574a090e3498b2d525753db7938c74227c3","impliedFormat":1},{"version":"ae81e464a7db70637d07b93582b051487c7d119ac7e1bab1b1582a96e631b3f7","impliedFormat":1},{"version":"148634fcee440c7bd8c1339b97455aaadc196b0229ffc8dc8b85965a7d65b380","impliedFormat":1},{"version":"d3c60c4cf88594f84f7f5ca5f87d59090787bfcf032e86d4f03d58394b826910","impliedFormat":1},{"version":"f3c3f17825c6a78681186da04c2f3a0f1c60cfa95f3d4b82bbbd6ebd57214a6a","impliedFormat":1},{"version":"eb45a1782ef50423c1ffac4d2a89c60004f4e2d25ed8e7dcb9e24e6cf984ccdb","impliedFormat":1},{"version":"e4c94ea55cac34117f423db62a62df7121006b0e69ab77d27f98cef27973f876","impliedFormat":1},{"version":"97e4a153ac1feffdc4cbdf8f2b8ecfe8a2c651c3ba949fd5fbcc1e29d8e7d283","impliedFormat":1},{"version":"0b801e25d3e163d246c70e059cd529e5edd280692c6b384c20314825b23511bb","impliedFormat":1},{"version":"97f2a8c88656c95104fe635a2c254b0ec431591d26838e1fbc2a6db6b822a1df","impliedFormat":1},{"version":"d120b9af0cd364387d676de7c662643006ea2d942f7d5af18ca3024fee73c149","impliedFormat":1},{"version":"274097c2dff5959c9a6242b87aa858e772f0d269dd2847e44e4f6c5c0922937f","impliedFormat":1},{"version":"9a5ce34f28948d1b84dea73942e10b8a36fa10dc958356589c8f03aea866c96d","impliedFormat":1},{"version":"75897ed38868fdd8ce289475d2812e4d3e5cb64bcf812e44ebbf3f5e21ae486d","impliedFormat":1},{"version":"d994fb6705faaae18b9d71ba2d89b4a7e5e77c2b801a3dae51c0821da4a90acb","impliedFormat":1},{"version":"b30cc18b84468d3fa20ac04ca5ba9bed5a03431fc8a22bcf2c266c132baa1d3f","impliedFormat":1},{"version":"fda3e93361b17be4f24a12ac951b3c87cbae8e81b351d849caec342c94f932fa","impliedFormat":1},{"version":"f0ce99f229795d96ffbcee89e1de6c6d9dc52b4c31bfe6fe002893e243c305b4","impliedFormat":1},{"version":"680bd67092c080fefa2045bba990378e0c0f2ad5ed56b7fe928b4287413d7842","impliedFormat":1},{"version":"0840cd0220ad530dbc6e8549161e9304dac9d520c3b78caeeeb6af194a9f0588","impliedFormat":1},{"version":"a54f60678f44415d01a810ca27244e04b4dde3d9b6d9492874262f1a95e56c7d","impliedFormat":1},{"version":"84058607d19ac1fdef225a04832d7480478808c094cbaedbceda150fa87c7e25","impliedFormat":1},{"version":"27abd2f2ed5aaac951b12b8332aac7970c9cf0cfd88c458f0f016228180b4293","impliedFormat":1},{"version":"901c640dced9243875645e850705362cb0a9a7f2eea1a82bb95ed53d162f38dd","impliedFormat":1},{"version":"ebb0d92294fe20f62a07925ce590a93012d6323a6c77ddce92b7743fa1e9dd20","impliedFormat":1},{"version":"b499f398b4405b9f073b99ad853e47a6394ae6e1b7397c5d2f19c23a4081f213","impliedFormat":1},{"version":"ef2cbb05dee40c0167de4e459b9da523844707ab4b3b32e40090c649ad5616e9","impliedFormat":1},{"version":"068a22b89ecc0bed7182e79724a3d4d3d05daacfe3b6e6d3fd2fa3d063d94f44","impliedFormat":1},{"version":"e70d18d1352550a028f48d74e126a919c830267b38c76ddae4dc1571476a462a","impliedFormat":1},{"version":"5624b09ca38ea604954f0422a9354e79ada3100305362a0da79555b3dd86f578","impliedFormat":1},{"version":"24830e279f5773a4108e0cbde02bdcb6c20b1d347ff1509f63eed031bf8b3190","impliedFormat":1},{"version":"8899fd9f8ab5ce2b3af7ba0e1a47eede6a2a30a269283cc4a934ab755d0aadaa","impliedFormat":1},{"version":"f10759ece76e17645f840c7136b99cf9a2159b3eabf58e3eac9904cadc22eee5","impliedFormat":1},{"version":"363dd28f6a218239fbd45bbcc37202ad6a9a40b533b3e208e030137fa8037b03","impliedFormat":1},{"version":"c6986e90cf95cf639f7f55d8ca49c7aaf0d561d47e6d70ab6879e40f73518c8d","impliedFormat":1},{"version":"224d293a02b7d22edb77b4ab89c0d4f63b95ecd7c0698776719f33863a77ffdc","impliedFormat":1},{"version":"1518707348d7bd6154e30d49487ba92d47b6bd9a32d320cd8e602b59700b5317","impliedFormat":1},{"version":"ede55f9bac348427d5b32a45ad7a24cc6297354289076d50c68f1692add61bce","impliedFormat":1},{"version":"d53a7e00791305f0bd04ea6e4d7ea9850ccc3538877f070f55308b3222f0a793","impliedFormat":1},{"version":"4ea5b45c6693288bb66b2007041a950a9d2fe765e376738377ba445950e927f6","impliedFormat":1},{"version":"7f25e826bfabe77a159a5fec52af069c13378d0a09d2712c6373ff904ba55d4b","impliedFormat":1},{"version":"7ffef1ed1c2bc7d9cf2fc134a7e8c68b10416cdbe8e70da8a4bd7ad5c8698d9c","impliedFormat":1},{"version":"63c0926fcd1c3d6d9456f73ab17a6affcdfc41f7a0fa5971428a57e9ea5cf9e0","impliedFormat":1},{"version":"eb524eabfa1809d54dd289374c0ce0ed4f145abb878687e4fd5e67f91d7d08a6","impliedFormat":1},{"version":"4ef0a17c5bcae3d68227136b562a4d54a4db18cfa058354e52a9ac167d275bbb","impliedFormat":1},{"version":"b748dd4ccc072a2b7194b898dc8996a2cb56bfa15ccdb60ac0d2f9eaa8e28e9d","impliedFormat":1},{"version":"64269ed536e2647e12239481e8287509f9ee029cbb11169793796519cc37ecd4","impliedFormat":1},{"version":"c06fd8688dd064796b41170733bba3dcacfaf7e711045859364f4f778263fc7b","impliedFormat":1},{"version":"b0a8bf71fea54a788588c181c0bffbdd2c49904075a7c9cb8c98a3106ad6aa6d","impliedFormat":1},{"version":"434c5a40f2d5defeede46ae03fb07ed8b8c1d65e10412abd700291b24953c578","impliedFormat":1},{"version":"c5a6184688526f9cf53e3c9f216beb2123165bfa1ffcbfc7b1c3a925d031abf7","impliedFormat":1},{"version":"cd548f9fcd3cebe99b5ba91ae0ec61c3eae50bed9bc3cfd29d42dcfc201b68b5","affectsGlobalScope":true,"impliedFormat":1},{"version":"14a8ec10f9faf6e0baff58391578250a51e19d2e14abcc6fc239edb0fb4df7c5","impliedFormat":1},{"version":"81b0cf8cd66ae6736fd5496c5bbb9e19759713e29c9ed414b00350bd13d89d70","impliedFormat":1},{"version":"4992afbc8b2cb81e0053d989514a87d1e6c68cc7dedfe71f4b6e1ba35e29b77a","impliedFormat":1},{"version":"1810b0b14614e53075d4d1b3e6be512bde19b1ed3a287925c0d24bae8585fa1b","impliedFormat":1},{"version":"1c390420d6e444195fd814cb9dc2d9ca65e86eb2df9c1e14ff328098e1dc48ae","impliedFormat":1},{"version":"ec8b45e83323be47c740f3b573760a6f444964d19bbe20d34e3bca4b0304b3ad","impliedFormat":1},{"version":"ab8b86168ceb965a16e6fc39989b601c0857e1fd3fd63ff8289230163b114171","impliedFormat":1},{"version":"62d2f0134c9b53d00823c0731128d446defe4f2434fb84557f4697de70a62789","impliedFormat":1},{"version":"12056fec06740770f1d14d47dad75ba54a9a8e0f40e766b38172a44b42112886","impliedFormat":1},{"version":"ec8db3ff5638196d3debc149d61fb4d604e73e12ffd28ea02a326ad40d2240bf","impliedFormat":1},{"version":"e8c0a909df5d29c77c9b5037b9a25ec6be0b70e0d3f5ce95ae0923f2582d6c1c","impliedFormat":1},{"version":"9fad83dff123fb56c6d11f8973ebc6cffec784f5d5c0cc2572344df246bfa0dc","impliedFormat":1},{"version":"c7865dbee3c1955c9c91b107ac95e51c27ee67dc2b85893ee91d4ce46f37ea99","impliedFormat":1},{"version":"5776c61de0f11da1c3cf8aafc3df524e8445201c96a7c5065a36dc74c2dc0ef6","impliedFormat":1},{"version":"c110c6e2b6a8494ff722db0c32ff143bcf0ed04ecdb993a58b8d4c1ef5d8e1d3","impliedFormat":1},{"version":"7f0f90d0ffdd54875c464b940afaa0f711396f65392f20e9ffafc0af12ccbf14","impliedFormat":1},{"version":"483255952a9b6240575a67f7beb4768bd850999a32d44d2c6d0ae6dfcdafe35c","impliedFormat":1},{"version":"a1957cc53ce2402d4dc5c51b7ccc76b30581ab67bea12a030a76300be67c51d8","impliedFormat":1},{"version":"8149e534c91fc2bcb3bf59f7c1fab7584382abfc5348055e7f84d2552c3de987","impliedFormat":1},{"version":"c280ec77789efcf60ea1f6fd7159774422f588104dae9dfa438c9c921f5ab168","impliedFormat":1},{"version":"2826b3526af4f0e2c8f303e7a9a9a6bb8632e4a96fece2c787f2df286a696cea","impliedFormat":1},{"version":"77ced89806322a43991a88a9bd267d6dc9e03fd207a65e879804fa760292a03b","impliedFormat":1},{"version":"c8ff3a75cd1c990cbe56080b1d254695c989136c9521cb1252c739788fe55c83","impliedFormat":1},{"version":"485f7d76af9e2b5af78aac874b0ac5563c2ae8c0a7833f62b24d837df8561fb9","impliedFormat":1},{"version":"8bdf41d41ff195838a5f9e92e5cb3dfcdc4665bcca9882b8d2f82a370a52384e","impliedFormat":1},{"version":"4f42e9c177a3c68913560c086a889285cd51c20b4d54a44bae77c17dee7cfa46","impliedFormat":1},{"version":"fe8a3e5492c807cc5cfc8dda4e6464aff0f991dc54db09be5d620fb4968ba101","impliedFormat":1},{"version":"31f931c21c7a121317c5b4d0223e6c13f616312ddb481409e54393340bd61ed9","impliedFormat":1},{"version":"654bcc87bc095d6a2248a5889ec057b38cae6052744b48f4d2922a7efac4554f","impliedFormat":1},{"version":"cad0f26943006174f5e7508c0542873c87ef77fa71d265968e5aa1239ad4459c","impliedFormat":1},{"version":"0be66c79867b62eabb489870ba9661c60c32a5b7295cce269e07e88e7bee5bf3","impliedFormat":1},{"version":"eed82e8db4b66b1ea1746a64cd8699a7779138b8e45d495306016ce918b28440","impliedFormat":1},{"version":"3a19286bcc9303c9352c03d68bb4b63cecbf5c9b7848465847bb6c9ceafa1484","impliedFormat":1},{"version":"6cdf8f9ca64918a2f3c2679bc146d55f07490f7f5e91310b642bc1a587f2e17e","impliedFormat":1},{"version":"3b55c93b5d7a44834d9d0060ca8bad7166cf83e13ef0ed0e736da4c3dbe490a2","impliedFormat":1},{"version":"d1f8a829c5e90734bb47a1d1941b8819aeee6e81a2a772c3c0f70b30e3693fa9","impliedFormat":1},{"version":"3517c54fba6f0623919137ab4bdb3b3c16e64b8578f025b0372b99be48227ad7","impliedFormat":1},{"version":"19b3d0c212d241c237f79009b4cd0051e54971747fd89dc70a74f874d1192534","impliedFormat":1},{"version":"0d0202235a9c54a36e08502ddee21ad24013eff328831630b438ca927ff15b11","impliedFormat":1},{"version":"f17963b9935dd2142c08b006da53afeeaca2c9a600485f6eb9c018b96687275b","impliedFormat":1},{"version":"1afd33ee26eb73a31cca8870ef7da768d1f13827957847d68d0270ce4568b4c2","impliedFormat":1},{"version":"6efcc75514c15981e76e399a93eb7d86a779299c618968a099b755cc8d2b7334","impliedFormat":1},{"version":"a24adc6e8aa778f0b66578f842a3c4fb7bdca5f8bb183c5e90c9746676a33454","impliedFormat":1},{"version":"a797a41988e5ba36b6707939953b0c0395ed92b91c1189359d384ca66e8fa0ab","impliedFormat":1},{"version":"a9452e81c28c642c2f095844c3473d979eba5ae89726ad52b15ea86b3e112ee2","impliedFormat":1},{"version":"dc4a2cf12254395c8ae3fb4c61e6fd9f7c16110be66483599f9641941416988f","impliedFormat":1},{"version":"82b4045609dc0918319f835de4f6cb6a931fd729602292921c443a732a6bb811","impliedFormat":1},{"version":"ce0a7ad957db8370d5a33da5f9e10d3d05a58a626e1d1166a2b92fcacc0d82e4","impliedFormat":1},{"version":"aa81389bf581bb4c15c0ed2136640d3998d0984d8bf6e0b59194ba92d98c6a72","impliedFormat":1},{"version":"e5eb4863b7fc8515078dc09cd2f98fd179ff1a55216ecdc57d2dec7ce13e36c1","impliedFormat":1},{"version":"81785a3ea03d6db981ddfcf8fb1bd1377f985564def845c55e49e16f171deec4","impliedFormat":1},{"version":"537a2b61594512c5e75fad7e29d25c23922e27e5a1506eb4fce74fe858472a6e","impliedFormat":1},{"version":"8f9a2a6ddbd11ecbbc430ae8ce25528e696206f799ef1f22528569caf6ce580c","impliedFormat":1},{"version":"e05e03e1687d7f80f1569fdae117bb7b97feef1e839a61e1b3c61ffca8cc67c9","impliedFormat":1},{"version":"b311d973a0028d6bc19dfbaae891ad3f7c5057684eb105cfbeec992ab71fbc13","impliedFormat":1},{"version":"8a49e533b98d5c18a8d515cd3ae3bab9d02b6d4a9ac916e1dba9092ca0ebff15","impliedFormat":1},{"version":"fcb26ad5a6c39ce71dfac5dc16b3ed0e1a06a6dc8b9ac69112c935ad95fcad69","impliedFormat":1},{"version":"6acdef608420511aa0c9e3290b37d671bab4f719ffc2a2992c2e63a24605a657","impliedFormat":1},{"version":"291df5da0d84d1452cd68abfbcca08a3f96af610bf0e748528ba8d25784ce2b1","impliedFormat":1},{"version":"176cda558a7f76813f463a46af4607a81f10de5330c0f7a43d55982163aa0493","impliedFormat":1},{"version":"6621af294bd4af8f3f9dd9bd99bd83ed8d2facd16faa6690a5b02d305abd98ab","impliedFormat":1},{"version":"5eada4495ab95470990b51f467c78d47aecfccc42365df4b1e7e88a2952af1a3","impliedFormat":1},{"version":"6b08ada439e3c7fba3e6d18c19f934e7bbea3f34979f2490074f0623b849e8e4","impliedFormat":1},{"version":"40e9c2028b34c6c1e3281818d062f7008705254ee992d9857d051c603391e0f4","impliedFormat":1},{"version":"bf1e1d7d28afe2f0e6936aaf30e34efc70cc0714d79721c88e3fc2253d5da40b","impliedFormat":1},{"version":"4a34de405e3017bf9e153850386aacdf6d26bbcd623073d13ab3c42c2ae7314c","impliedFormat":1},{"version":"993bcd7e2dd9479781f33daab41ec297b8d6e6ccc4c8f9b629a60cc41e07e5c8","impliedFormat":1},{"version":"273b6c8dad70cb34aaeb6af95e9326e7e3670f10a0277c6832a42b5b7728a2c0","impliedFormat":1},{"version":"dfa99386b9a1c1803eb20df3f6d3adc9e44effc84fa7c2ab6537ed1cb5cc8cfb","impliedFormat":1},{"version":"4cb85ba4cf75f1b950bd228949ae508f229296de60cf999593e4dd776f7e84e8","impliedFormat":1},{"version":"e39730c031200579280cae4ea331ec4e0aa42f8f7ad19c3ec4b0b90414e40113","impliedFormat":1},{"version":"e90bd7922cb6d591efd7330d0ba8247ec3edf4c511b81346fd49fff5184e6935","impliedFormat":1},{"version":"1b581d7fcfacd6bbdabb2ceae32af31e59bf7ef61a2c78de1a69ca879b104168","impliedFormat":1},{"version":"4720efe0341867600b139bca9a8fa7858b56b3a13a4a665bd98c77052ca64ea4","impliedFormat":1},{"version":"a0f62f1335e4c627a04eed453d4fa709f19ef60fd11c65e1fdfc96de9df374a5","impliedFormat":1},{"version":"37446d15751f05bb3ecde3ad5346b2ccfa7f4578411e9e699b38a867327ffbf9","impliedFormat":1},{"version":"11792ab82e35e82f93690040fd634689cad71e98ab56e0e31c3758662fc85736","impliedFormat":1},{"version":"8551ca11a261b2384e0db64bbd09ee78a2043a908251746db3a522b6a646e960","impliedFormat":1},{"version":"6c53c05df974ece61aca769df915345dc6d5b7649a01dc715b7da1809ce00a77","impliedFormat":1},{"version":"18c505381728b8cc6ea6986728403c1969f0d81216ed04163a867780af89f839","impliedFormat":1},{"version":"d121a48de03095d7dd5cd09d39e1a1c4892b520dad4c1d9c339c5d5008cfb536","impliedFormat":1},{"version":"3a6ce66cd39bc030697a52508cfda7c248167467848964cc40bd992bd9ce71e0","impliedFormat":1},{"version":"b4ec75c8a71c180e886ffccb4b5391a5217d7e7077038de966e2b79553850412","impliedFormat":1},{"version":"f8117362c4a91da9e2a29466d682334fe522d4e5d6cc652d95c38797b41f4546","impliedFormat":1},{"version":"ecf85664c5bbbb0db1190cd1a57ebdedf7ecbc0dbbbfd548106f069e0c38666c","impliedFormat":1},{"version":"b43a0693d7162abf3a5b3b9e78acfafd0d4713af4d54d1778900e30c11bc4f83","impliedFormat":1},{"version":"efb3cb71ed3e03cee59cd95bffa5c7eb365b0c637dd4d8efc358d8a34b396052","impliedFormat":1},{"version":"aed88228359e87a1b1a4d3d45f5b6555724c01ac81ecd34aa56d4a0a01ba6910","impliedFormat":1},{"version":"6365e9d7645838ef3e98c0a9f52c03ce6b00962a67f1e3e945f155a6b12e0578","impliedFormat":1},{"version":"f4dc28fbbba727722cb1fd82f51a7b9540fbe410ed04ddf35cab191d6aa2ba10","impliedFormat":1},{"version":"4adc1491e1338de6745d009222786747f50d67ac34d901420fbaefbf1b51b58c","impliedFormat":1},{"version":"4cfbd2a7a4afee212bfb0c9c3cb6e4c7d48366e0565bf5b43a4cd96c91cf14bf","impliedFormat":1},{"version":"37c175e28375e157933b40ca98eeb608e05f2583821a0fae564dc04614d2d95e","impliedFormat":1},{"version":"3f20a041a051abfb2b47a66611cf4bcbf263605f5469ed7e8b51b3977892d83f","impliedFormat":1},{"version":"7de33f94f482eee2f6d1d8f24427b737e2c4006792ec4c2b87da0a426e741c4d","impliedFormat":1},{"version":"79134a050ccec1692c31f1dacccd05ce4fcdacdf98f0fa56546b98eb8bdefead","impliedFormat":1},{"version":"24f1b6865be734484de2baf99146122137654c5f5f28086c5cee97b998bfcd5c","impliedFormat":1},{"version":"398feb1537ae0409646b0489bac99a9f0d757a2048f0009255f8e35e9c0f9828","impliedFormat":1},{"version":"3da4432a9c24123f98f6f1ddc5cda9c9eedf0a8853d06321803dbc5a116e5270","impliedFormat":1},{"version":"afc60e07200c5eae65b702f95d83096de54d99fa6eb2e0154e83b5e11c520bda","impliedFormat":1},{"version":"f4651affee2900f19746d1bf0fb1c45e77f57576197561ddc90b7272835c3f37","impliedFormat":1},{"version":"19527fc5a08c68414a234b02ae9b9619cdb4b811435d12c0af528e5640236f6b","impliedFormat":1},{"version":"20a629bc3f82d238f596230637365b8aec8284c963d13dafdd4c8e2746be5e64","impliedFormat":1},{"version":"01c48e5bf524d3fc2a3fa5c08a2e18d113ad1985bc3caea0503a4ea3a9eee64a","impliedFormat":1},{"version":"68969a0efd9030866f60c027aedbd600f66ea09e1c9290853cc24c2dcc92000f","impliedFormat":1},{"version":"4dbfad496657abd078dc75749cd7853cdc0d58f5be6dfb39f3e28be4fe7e7af5","impliedFormat":1},{"version":"348d2fe7d7b187f09ea6488ead5eae9bfbdb86742a2bad53b03dff593a7d40d1","impliedFormat":1},{"version":"becdfb07610e16293af2937e5f315a760f90a40fec4ffd76eb46ebcb0b3d6e16","impliedFormat":1},{"version":"710926665f4ada6c854b47da86b727005cc0e0831097d43f8c30727a7499788c","impliedFormat":1},{"version":"3888f0e43cd987a0dfa4fc16dd2096459deea150be49a2d30d6cf29d47801c92","impliedFormat":1},{"version":"f4300c38f9809cf811d5a9196893e91639a9e2bb6edf9a4f7e640c3c4ce765ec","impliedFormat":1},{"version":"676c3327721e3410b7387b13af857f4be96f2be91b3813a724eedc06b9ce52d7","impliedFormat":1},{"version":"10716e50bcd2a25cecf2dd993f0aadf76f12a390d2f7e91dc2cac794831e865e","impliedFormat":1},{"version":"81a8f1f6218d0acc8cd2cf8b5089d21b45cf812bb5820affe3bab058b46cba7b","impliedFormat":1},{"version":"fa69921924cf112fa523a18215a3bfb352ac3f498b46e66b879e50ca46cc9203","impliedFormat":1},{"version":"8063a2c518e5c3b33a895cb891984acaabc0a248f8ad40748adedbe8d2580fb6","impliedFormat":1},{"version":"ccfb77fcac04c34442ffca82ae90c8dd2a0ec1689ace547fab9a0ae337dd4752","impliedFormat":1},{"version":"7b464488950d74ca5037da375308fc0c94a539378fd0e9554556df45483aad02","impliedFormat":1},{"version":"970fd4f27197b7495991371a8898067f7490f17da6883d5284c737182409bfdf","impliedFormat":1},{"version":"2d97de1377bad99c7b9df395330201195ef1d7f861a07087f2d42aa0d4daccbd","impliedFormat":1},{"version":"c790db6044ce1bbafc46f13bde46b9f0065de155b26a199f442fe064f6b05d63","impliedFormat":1},{"version":"f405e934163ed30905b4682eb542bb2d446e59c477871be9d29f92ab474d522a","impliedFormat":1},{"version":"8294ddd1c6ea4ed9ec190a2d41500539c1623e274d5a67786d6b09849cb98d45","impliedFormat":1},{"version":"666d6d6d9f2298f8d8d17ac7a34ac9ca9a59e09fc97b1ae505df6ab4934e2dbe","impliedFormat":1},{"version":"f3941ac359b8377c0ccce596a2bd3cde8986279f42d75290b0272f3ab1aa604d","impliedFormat":1},{"version":"de3d39262355af808ff74b3df62aaad0ad3cbde76c13fb4fa6fb6e4cc817e78e","impliedFormat":1},{"version":"a5042497dfcd9aa8864af2db95b386bd345559edac65c3d8910684ce68e551fc","impliedFormat":1},{"version":"757f7967151a9b1f043aba090f09c1bdb0abe54f229efd3b7a656eb6da616bf4","impliedFormat":1},{"version":"786691c952fe3feac79aca8f0e7e580d95c19afc8a4c6f8765e99fb756d8d9d7","impliedFormat":1},{"version":"734614c9c05d178ceb1acf2808e1ca7c092cf39d435efc47417d8f744f3e4c0b","impliedFormat":1},{"version":"d65a7ea85e27f032d99e183e664a92f5be67c7bc7b31940957af6beaaf696844","impliedFormat":1},{"version":"5c26ad04f6048b6433f87556619fd2e50ba6601dcdf3276c826c65681197f79d","impliedFormat":1},{"version":"9c752e91fe237ce4857fbbef141bee357821e1e50c2f33a72c6df845703c87d5","impliedFormat":1},{"version":"f926160895757a498af7715653e2aedb952c2579a7cb5cc79d7b13538f9090bd","impliedFormat":1},{"version":"255be579a134ab321af2fefb52ace369a11ffb4df09d1fbfc1ed1a43c1e5eec5","impliedFormat":1},{"version":"ab0926fedbd1f97ec02ed906cf4b1cf74093ab7458a835c3617dba60f1950ba3","impliedFormat":1},{"version":"f1a661906cd0e7fa5b049b15bdef4b20a99abca08faac457eeb2b6407f30d12f","impliedFormat":1},{"version":"7f5a6eac3d3d334e2f2eba41f659e9618c06361958762869055e22219f341554","impliedFormat":1},{"version":"626291e7b45a4b6871649c908fbbc5ac98009a5182e2594fbfe80b860f513c77","impliedFormat":1},{"version":"4093c47f69ea7acf0931095d5e01bfe1a0fa78586dbf13f4ae1142f190d82cc4","impliedFormat":1},{"version":"4fc9939c86a7d80ab6a361264e5666336d37e080a00d831d9358ad83575267da","impliedFormat":1},{"version":"f4ba385eedea4d7be1feeeac05aaa05d6741d931251a85ab48e0610271d001ce","impliedFormat":1},{"version":"348d5347f700d1e6000cbdd1198730979e65bfb7d6c12cc1adedf19f0c7f7fca","impliedFormat":1},{"version":"6fa6ceb04be38c932343d6435eb6a4054c3170829993934b013b110273fe40af","impliedFormat":1},{"version":"396e7b817fc4f5461b92f9a03325c2ebb09711aebcee5c41c5fd3e738eb78526","impliedFormat":1},{"version":"4116c4d61baab4676b52f2558f26fe9c9b5ca02c2792f9c36a577e7813029551","impliedFormat":1},{"version":"a294d0b1a9b16f85768553fdbf1d47f360dbff03649a84015c83fd3a582ba527","impliedFormat":1},{"version":"8f2644578a3273f43fd700803b89b842d2cd09c1fba2421db45737357e50f5b1","impliedFormat":1},{"version":"639f94fe145a72ce520d3d7b9b3b6c9049624d90cbf85cff46fb47fb28d1d8fe","impliedFormat":1},{"version":"8327a51d574987a2b0f61ea40df4adddf959f67bc48c303d4b33d47ba3be114a","impliedFormat":1},{"version":"00e1da5fce4ae9975f7b3ca994dcb188cf4c21aee48643e1d6d4b44e72df21ee","impliedFormat":1},{"version":"b991d92a0c3a48764edd073a5d28b6b4591ec9b7d4b2381067a57f36293637d0","impliedFormat":1},{"version":"51b4ab145645785c8ced29238192f870dbb98f1968a7c7ef2580cd40663b2940","impliedFormat":1},{"version":"100802c3378b835a3ce31f5d108de149bd152b45b555f22f50c2cafb3a962ead","impliedFormat":1},{"version":"fd4fef81d1930b60c464872e311f4f2da3586a2a398a1bdf346ffc7b8863150f","impliedFormat":1},{"version":"354f47aa8d895d523ebc47aea561b5fedb44590ac2f0eae94b56839a0f08056a","impliedFormat":1},{"version":"b152c7b474d7e084e78fa5eb610261a0bfe0810e4fd7290e848fdc88812f4504","impliedFormat":1},{"version":"67f2cd6e208e68fdfa366967d1949575df6ccf90c104fc9747b3f1bdb69ad55a","impliedFormat":1},{"version":"603395070ec53375882d53b585430e8f2dc6f77f4b381b22680d26c0a9595edc","impliedFormat":1},{"version":"cef16d87ff9aed3c5b96b47e0ac4277916c1c530f10eedfce4acaeacefddd3bb","impliedFormat":1},{"version":"fab33f402019d670257c8c833ffd78a7c9a99b4f7c23271e656cdbea1e89571f","impliedFormat":1},{"version":"976d20bb5533077a2135f456a2b48b7adb7149e78832b182066930bad94f053a","impliedFormat":1},{"version":"589713fefe7282fd008a2672c5fbacc4a94f31138bae6a03db2c7b5453dc8788","impliedFormat":1},{"version":"26f7f55345682291a8280c99bb672e386722961063c890c77120aaca462ac2f9","impliedFormat":1},{"version":"bdc2312da906d4129217238545d7e01e1d00b191beea1a9529b660de8b78834f","impliedFormat":1},{"version":"62b753ed351fba7e0f6b57103529ce90f2e11b949b8fc69c39464fe958535c25","impliedFormat":1},{"version":"514321f6616d04f0c879ac9f06374ed9cb8eac63e57147ac954e8c0e7440ce00","impliedFormat":1},{"version":"3c583256798adf31ef79fd5e51cd28a6fc764db87c105b0270214642cf1988aa","impliedFormat":1},{"version":"abdb70e24d3b39bf89aa07e769b33667c2d6f4ddcb4724735d72a941de6d4631","impliedFormat":1},{"version":"151aa7caace0a8e58772bff6e3505d06191508692d8638cd93e7ca5ecfa8cd1b","impliedFormat":1},{"version":"3d59b606bca764ce06d7dd69130c48322d4a93a3acb26bb2968d4e79e1461c3c","impliedFormat":1},{"version":"0231f8c8413370642c1c061e66b5a03f075084edebf22af88e30f5ce8dbf69f4","impliedFormat":1},{"version":"474d9ca594140dffc0585ce4d4acdcfba9d691f30ae2cafacc86c97981101f5c","impliedFormat":1},{"version":"8e1884a47d3cfddccf98bc921d13042988da5ebfd94664127fa02384d5267fc3","impliedFormat":1},{"version":"ea7d883df1c6b48eb839eb9b17c39d9cecf2e967a5214a410920a328e0edd14e","impliedFormat":1},{"version":"82f75b2de1456b0be46945c6c68547f032f11238d07db45bbc9c93fca6abfe41","impliedFormat":1},{"version":"812e55580eb591f3c04245345be8c9dce378b26238fb59d704e54a61e6e37c83","impliedFormat":1},{"version":"1de7ee494c7ac185e6abf94428afe270e98a59f1bb4768e4bea7804645a0d57d","impliedFormat":1},{"version":"2c12f912bab4b1eb797b2fded3f295fee98736f8053a08d0032becbecb4b34b1","impliedFormat":1},{"version":"2b234fce994b272403881b675d6ae2e2afb2a8be8bdec71002ff8ff2d5b59bd0","impliedFormat":1},{"version":"97ba9ccb439e5269a46562c6201063fbf6310922012fd58172304670958c21f6","impliedFormat":1},{"version":"50edac457bdc21b0c2f56e539b62b768f81b36c6199a87fbb63a89865b2348f0","impliedFormat":1},{"version":"d090654a3a57a76b5988f15b7bb7edc2cdc9c056a00985c7edd1c47a13881680","impliedFormat":1},{"version":"12a6a37d9676938a3a443a6bd9e8321d7221b6ad67b4485753322dc82a91e2a1","impliedFormat":1},{"version":"6c4833182ba7a753200bf30986d254653c1ac58855d784edd8dfe82f5db98954","impliedFormat":1},{"version":"69eeee4818209fdb59544d6f74bd6ff024944bdd4050a33577f62376d5cada8e","impliedFormat":1},{"version":"fa05a4a765755e92c1dcab306ef3648fa4aa108494b6e10d2329db8b89e89908","impliedFormat":1},{"version":"ea385ec05b32ad43bbd1002a7c553bbc6935754504d60dc38ee64cc8b3c21768","impliedFormat":1},{"version":"d61821435a95c7a660d5850ce6fe9c4400787595009853d982343b8089724319","impliedFormat":1},{"version":"b88051ee09b2f0ff102fe72162c5ed85e82c5dc30e6db074cc631daa93f8e0f1","impliedFormat":1},{"version":"25091d25f74760301f1e094456e2e6af52ceb6ef1ece48910463528e499992d8","impliedFormat":1},{"version":"ed79978235b685e7e9d2ac149c6ddaf602ce7e3a30725c20023e57f011760593","impliedFormat":1},{"version":"3345fc785abb65f2263f91ba092bb77470d949eddb41fc208256b964c2ccd5cb","impliedFormat":1},{"version":"dacdfa1d138a592734377df139ae70f203669bc3f9ac45e931aa0e6f2e567c8a","impliedFormat":1},{"version":"8a49075f007383f24df5b52376e41198e341a7b715da34a90b2c54b8fc8d4bcc","impliedFormat":1},{"version":"0fee2c30562deb6c5e38f79586610c0bcaea41e2d366565e292fff7e00a52f4a","impliedFormat":1},{"version":"38ad4b4ce64de9b9947c535a21c98a4e59011742594c2ab5e1ab47171acec5fd","impliedFormat":1},{"version":"849cc0c9a354475fcf8b7a485aadc26a5f1cc60b3fccdb4fa8723adeffdbdb25","impliedFormat":1},{"version":"a931f855f3a485577e65a2e7a3d41e6df929806af57ecbad99a161162b50cc15","impliedFormat":1},{"version":"853d02f4f46ca9700fefd0d45062f5b82c9335ba2224ca4d7bd34d6ae4fc4a7f","impliedFormat":1},{"version":"5f9ab7ba179f92fa3c5dddafec778a621fe9f64e2ba8c264ddf76fe5cf9eaf93","impliedFormat":1},{"version":"a0bce0fb40b88d17305f113ed02c4014329be52e8168b01fe825c049e9a37028","impliedFormat":1},{"version":"364e53fe15122e9d37aa8ee2c8eb037cde59bf5890b46a8205f4516b529501c0","impliedFormat":1},{"version":"1a577fdc45901cf461d4edc7697860c63a60526f60b7b2ba8ff7c89a9e7a1932","impliedFormat":1},{"version":"8eed7ad4a7d2c71be756f3272c4e83533db74bf48db8bf99ec6f8c4f8a388078","impliedFormat":1},{"version":"c35bd33a53356146889d87a05b34fc5a130ba93bc1bb36d021c0a7c817c4cc8d","impliedFormat":1},{"version":"129e22e3a18299b28b3c4b1831609d8caff450eae041a82639acc8635bbd2b15","impliedFormat":1},{"version":"cee6f683bf65ed4412b1a1cabfb7ad76fe242f52da68360c2e8a109b888fb1ad","impliedFormat":1},{"version":"e8fd94fd60c3464978e320d46dd600b57b5f4cc0c12452406c888db9f202c50c","impliedFormat":1},{"version":"b3cc1bb7311f35569b531e781d4a42d2b91f8dfd8bc194cc310c8b61011d6e43","impliedFormat":1},{"version":"fdc54d3bd2897fc993e5f5958cdb8e8dee07242087f5730e2fab9dc64d5fd9fa","impliedFormat":1},{"version":"8ca2d01f5f3d4d4067aadea230570afa4c91e24e485fbe2e9d53ead3b33f80d0","impliedFormat":1},{"version":"e0f69e399a1c3b367058918f3a6f9e5f29a0db26330c28208173556a8c48a0a3","impliedFormat":1},{"version":"e3c7c91b478879b40968129e9319cca8c7bfa7bc838f80329f7a150c03651d3c","impliedFormat":1},{"version":"26e50bcb0b06b83867f30b69ea99f926076c292cfed812e52db9e91d12ce1083","impliedFormat":1},{"version":"546592d6570239f12eaae6e68396db0e137efde4600765189ee277f6995bfe10","impliedFormat":1},{"version":"73bf1badc6969cf5eba2018b20dce1cc0dc00b056e66870abdca1f7b1275a648","impliedFormat":1},{"version":"a26c0a065b5de2cf0e826df7fedc3cf3df1d2bbab7ab395933234ef8adcf11df","impliedFormat":1},{"version":"23ec18c2cfd1219e227c34a2c286332708606c1d7dab8e32206e0028cbad60d6","impliedFormat":1},{"version":"ee689c67c5fa83d00452540077ee0862def738d4c86322b6f86411cfa06d7c6f","impliedFormat":1},{"version":"da27512313d85ef30b2dbc916b227ade032b09171f1e9b3af4c2897540e7f464","impliedFormat":1},{"version":"65ae87773d95fc56bce2c756dfcbcc73d8d05ac15a9ae73e7d81322850879fc8","impliedFormat":1},{"version":"fbce5d54e8610bc041463fc4e034f40e6f0b7889d9de27e7cda2135f254ddcb4","impliedFormat":1},{"version":"6b567540de9240ef5b14e86239dd821be6e90274df164ef61a11921344019410","impliedFormat":1},{"version":"c2f426df0b5346a824013c507c611656884f4681e23782ae5bc396cd6ad6fe00","impliedFormat":1},{"version":"f737d4c256faf88b0b84255da24ac95de364db1c5564d67856fc2be2571e477d","impliedFormat":1},{"version":"082be20017cd0774d12bf0a928d0834bcc83454e706dfb3ebf2c314b8065cdc8","impliedFormat":1},{"version":"7e0b933925fa33fca25738c4daabc959f315f1ca3b2431a724069db01ab4e53f","impliedFormat":1},{"version":"34dce1ce616534c11ce825f1acf55cbe45bf7f38b48ddf451fe0ebdb8b04924d","impliedFormat":1},{"version":"42aacda77a8ad883d423c7b39342cd036a35bba6c058b0b067f75af5ec0eaf6b","impliedFormat":1},{"version":"677b3a027ec7df033eb7df33eecfe77e066debd14d983a22916bcc67214b222c","impliedFormat":1},{"version":"547fbf3353abf40a827b1b48b832f9139e41cc600dac954cd4dd1c8faf1df517","impliedFormat":1},{"version":"dc0a609a8ab9995e439c887be9327c272400a3aadd76dae41f6c4eae9af723b8","impliedFormat":1},{"version":"0e792560a03e247d4f6ee7dcc6f9a7dbf07e55caa6faad2219875ba02480e769","impliedFormat":1},{"version":"c0c5ebf4cc5ef8ed64733c3dea8de54fbb45bb0a40306d26d840e50a954327cd","impliedFormat":1},{"version":"408c753ef793f71dffa590cfc3a95e5246ab67238f71083b7a96056b986e8964","impliedFormat":1},{"version":"6650fd077aa1900d99c2a52af9dd79971322e2991e70e463331d0cd60fe9f914","impliedFormat":1},{"version":"dd293cb09436d09cdd150565d54a3cd72674850eb842a11487cc3799357b9cf8","impliedFormat":1},{"version":"e32ceea1db1cf16192a7fd97fdc689dc625ad1c57555a2dc18e7b5c019216482","impliedFormat":1},{"version":"0359c9ffe72d124c521a64dcb4f37a6391e9234e0496a38f62ba9b18be1f1d89","impliedFormat":1},{"version":"7d65b692913489b7a0179ef6266bb52985d7545fa5baacac4a803149b27b98f2","impliedFormat":1},{"version":"b1cdc896fa6216d1ff898423395f5ca6bf3b1118411b7f5ccc732c8acbd37e19","impliedFormat":1},{"version":"8d986fc98555e4b017177816f51b86236a357ff9c468f4c86e5b4096775f1639","impliedFormat":1},{"version":"37441514e58c1412999e02a2931b179a4e9330a5b67dd8f75b3dbee19e1b33db","impliedFormat":1},{"version":"a1c9f45912f4ad052795e0ef5743d8e1a8400efb0393a13c47c2b6320bdd9406","impliedFormat":1},{"version":"6402c4b62a62f59d78ad558c0abaa7a8059e966f083c99b89fd4b24302353413","impliedFormat":1},{"version":"a8378c2611bbac166238618fb9bc0af95b77ac59447d9046af1c4188ad758c1b","impliedFormat":1},{"version":"c745295efc9d176836701a358fcab80c77ca7a63f4c8e7bfaf0da3a0910607be","impliedFormat":1},{"version":"9074405ae056ee3066a3cdba3ad29eed41ce32c74838b6ca09e14ba8ed9e3123","impliedFormat":1},{"version":"d486cfb79e7cb30710b2f3cc8c02909fe71b34e26938ba536100ff207e38749f","impliedFormat":1},{"version":"c1cd76a69f98ae809c871a3c9825a79bf51252a95f8d039d13dbb60c97d2f33a","impliedFormat":1},{"version":"d668cba43ed8e4364f2625bfc373f51ca7a0ef4333aadee0b953c6a8ce0ad953","impliedFormat":1},{"version":"5c93658c69d22c1e0281a1672bf9a0f3efed19e46ec0456c1fd269a15354bc2e","impliedFormat":1},{"version":"b80ab976d1968b44e78d7c6312fa7895989e30604712001e504ec74c95d50c0f","impliedFormat":1},{"version":"7cdbc72e654c4cc3a95cf44a0f050a5affa822d626501731ea688deb0662b027","impliedFormat":1},{"version":"af12968b48a6d0d45a4737c6a02cdadae2ace6738b65a1c3425928677154db38","impliedFormat":1},{"version":"198e2304a766d645a7940a2c6ee7687030c07a8c3bb2e84184e4acaa0a87f325","impliedFormat":1},{"version":"ab9ea3afaee16b10a6d7d2fdde5c3c66a154e1f93266832a439ea4ae8f92ed3c","impliedFormat":1},{"version":"94ef22b94d7cafa97366308aba95caee00b8c740567c518dae3dcfd09c58a4d1","impliedFormat":1},{"version":"66332888aba679ae44ff8405d814a794a8328730d008ab5ca2c3b0629a1acc38","impliedFormat":1},{"version":"de9d02955efdcff476bd95184b75e321d962b8fc22f51b2033da443ffa33c029","impliedFormat":1},{"version":"8134618a47361a523fc5daea803db42a8f0751944e8a314128cdb4d51a4d0359","impliedFormat":1},{"version":"3cac1d701152a399417ca60ec47f9ca83fe96a4c519bfc4b9ceb79578a894bc3","impliedFormat":1},{"version":"ed74d99ed075aa260bb80cdc4286fd04d5ca8fff5ba7611c22c0d4891418d08b","impliedFormat":1},{"version":"dba5745334b583e1b8f7ef055939cc750c546c250a74b95e0ede1ad5b863400a","impliedFormat":1},{"version":"801f5c06b1bdb1f520fa9d12ad1cb1f0f5a60233ede2d6313a1894f4c48208af","impliedFormat":1},{"version":"afe7e63907fb014390c8b2fc1bea86232a17431faccfbd8248e9ecf848c698e4","impliedFormat":1},{"version":"82035374d5288745dd1225e6a0bcbfc5c7dbd53b2823f432c56de707a2a3847b","impliedFormat":1},{"version":"dea06d130aa40f953867c2b6d5bad2376091c55b64a4a2d2781acb009541e100","impliedFormat":1},{"version":"c92258027ef4f99109f802bd82af908afa731ccc379373b5ee69cf420b40f060","impliedFormat":1},{"version":"ba19ddf03bdbd63a4a44ebb761439016507911f153b1b618b7aaca18801b1e1d","impliedFormat":1},{"version":"73f6fd0ee5da5198efd378a07383da0337b8e73a30a53420a46a4a098ea34f26","impliedFormat":1},{"version":"1b5962b26e6698523cbd71a11281f59f6c4f57099fdebb11cf68fe77abac8c1c","impliedFormat":1},{"version":"f2a46afafc384ab188f6ce5cf2cdb4859236e111958f8d49a1a3941088c8983d","impliedFormat":1},{"version":"afda2e399d17b76e199f56029d053308fa3d93a90b9565b06a81be01fb86865c","impliedFormat":1},{"version":"5080b4699f7e121f9edc746e4b6cbb10c61ac0ed707425ca572ac0d67b593563","impliedFormat":1},{"version":"26090d8875766d8cbccdc70d81573a0a0cd2af336c2ab991021706ae24e3920b","impliedFormat":1},{"version":"6141b4f6daf9d8770f32c174fb185714e97851a345b5734256b2f615f6bfcbb5","impliedFormat":1},{"version":"cd454337b92454283ac6fa6a271d8688a9a875b32386a33c747fd0cb67407843","impliedFormat":1},{"version":"6981a0c4763b53c9852eabe40e5f6abcf1c39b26844142bb32033f6a4c82b057","impliedFormat":1},{"version":"849bd9fa53e4829fda3a678780e1f227a729adc357f521c8be47a9aaa053b82e","impliedFormat":1},{"version":"1749042b52c8e5fe166dd24318d18ab56db865cca56829a69ac42e6bb55b001f","impliedFormat":1},{"version":"5f8eaa67e3d8b40ab42257d96a714fafc809ab526142230a09f58635c192cd22","impliedFormat":1},{"version":"eb99fa95f75e0f7b38661b5dec9f23ac9543393b120a1434530d95e69d4e79b1","impliedFormat":1},{"version":"b62db23755af69ece75a6533bfdf73dfec00fd362f60aa84c1a779868cfecbfe","impliedFormat":1},{"version":"1f686b1909ddaced1a28e5d0b68b91f43a3ec11e048e504a5672946235ccc4a6","impliedFormat":1},{"version":"3831835fb9a201fedcd846eafe14e6571894bdbca4a546d74172064ee6a8bb8d","impliedFormat":1},{"version":"c4ad21dfe866d96f982607c7b12cc8439b692a84859afc6474b46b07ae912db7","impliedFormat":1},{"version":"be0914604acbe35e8de9ff368fc7bd8fa75ae8f30be048a5d7bad09f28b40d1e","impliedFormat":1},{"version":"2b9d55a7e074cd9858332bc24dede0ac521b21a9ee586394c4c4895efe9cda95","impliedFormat":1},{"version":"1369e4f275724ddf731bc351f6c8e580ed7eae969317b6d3060fe348304fb6fe","impliedFormat":1},{"version":"f43678d8b19945df13814b6838120b7c7b8dfdce7569296b1b1976eaf085c705","impliedFormat":1},{"version":"e13307ee0b3a31b312f610895bf0e322cdb69f786568a256a9d547b2c03d6203","impliedFormat":1},{"version":"7e206779ef1fd0a3d07f2206196f2d73ac66d9451822c0b38a168faad5ea8106","impliedFormat":1},{"version":"13baee3bc1768b9923c49f08193495c4e6781262a64d59a2e63c141b771a9fcb","impliedFormat":1},{"version":"5bfe6ebae188356b862d8466e5449a78f78f1ec44651d1e00ffdb71fa194aae6","impliedFormat":1},{"version":"771dc53932d5d89ba9324d52e961157cc726084d122a8a0310c34ad397660a62","impliedFormat":1},{"version":"274bea8a69abcb66240bf52e156eac557019a956f50b0db70387863b57115eb9","impliedFormat":1},{"version":"f390fa9fba362e116cd59e005bec3c9a40dd6c0d47f02ba50b5e6c3e62700198","impliedFormat":1},{"version":"b6914c5199969e2aa490bd347dfc5e289813b260dba1331d06c55b3cbcab9b6f","impliedFormat":1},{"version":"40dffdf672c4e9c313d0b2537907b4a7b749c995c2c0c475807877eb2e499f48","impliedFormat":1},{"version":"fc24fbef61c285e202f2484229976dfc67b0e7b7a27fef7a95ffdf8d63057593","impliedFormat":1},{"version":"45ead3296fc43b8929db6cf82e2b55f909428ca150ab55b7cbf64a4504a5b5f1","impliedFormat":1},{"version":"93979165f85cc256e159ba859693bde5f4b4ebceb2da65ea4695662e21fb52e1","impliedFormat":1},{"version":"ef700e2d818d6ccd0439eb84bb4db7aa4b05ea406e32d67c33238d7ad27de42f","impliedFormat":1},{"version":"ad05d2d60f1bccc4fffc28e239cd9df3290ff079f3ab8d0e8cb52739a2827a10","impliedFormat":1},{"version":"b0c47ecc1d22d613ff438a1cbcf55a15092a25a08264dc30af1f4948495c125f","impliedFormat":1},{"version":"fdc64b163f42e37dbe762f9b64dc2d6914549f3400f7fb18d77b58f569a64914","impliedFormat":1},{"version":"440195a83a763349c6c007ed7e0d738fd1b7eb7e1773c764ba4a53a47b590700","impliedFormat":1},{"version":"4cb733b1156a4c30cd662b72b3c79fd23763036b0e552f63c24e791983f493ca","impliedFormat":1},{"version":"761a9b0b1d366d94da1884decf722053122a5808c713dafe7fcaf22d8f9643d3","impliedFormat":1},{"version":"10d960eb8b8e27876c99d38fa27665927a7c122c38773121f8f1ada4738d0320","impliedFormat":1},{"version":"266aeb59e78be75a52cd41e3ce6f05eb0763c47d383cd081711010513217a05b","impliedFormat":1},{"version":"d4936aaa2e2fd93908a9e96e7e48bf05caa4973a0f25938cf02938403461b4d4","impliedFormat":1},{"version":"be93596d4f187f67d7845f895d10073ccbac95214f7ebf8671a438249b6e9787","impliedFormat":1},{"version":"24da93576c3e6b7f3f1c31b67fa59bec695594f3d780ef175c06ecd2f7f326b7","impliedFormat":1},{"version":"8ec695c9c1352c4be7c0a69befdd73ee700e92941d6306f5cbdd56688f564647","impliedFormat":1},{"version":"9d74f18aad3b7c8a0336eacd427c659bd8bf57444426f6f0e41f8fca1ceee97a","impliedFormat":1},{"version":"a4e6bafb319f30c835ef3fd3afe64de01d84e82850a98c5d07db7ee901d34f4f","impliedFormat":1},{"version":"50d28622be744b35a9cd858facdf1f0717f889f938eff8a0c35135613d324677","impliedFormat":1},{"version":"75b1c7f76848840325e9bda20ba8ba8328a4fd8dce56831b55b68cdd955a4c01","impliedFormat":1},{"version":"f93026b391c4f31b8e6f11e49b2dcaa40953788d25010dc190a751acdd7b442a","impliedFormat":1},{"version":"666f484aea575137508bdf1156d7d91e929a54abaee307a4bdfeddf59c5d383b","impliedFormat":1},{"version":"1eefe69c9db42deb567764f73d45d6a468993428bf147d1e3244585b42313c05","impliedFormat":1},{"version":"5f375f1e6566d3f9a8da008710738e9826ae2dc229d5e49faea13731ace6d506","impliedFormat":1},{"version":"980f3c0431cc8689000e35012e23a248dd781e3e5282057126624a7137a3bf42","impliedFormat":1},{"version":"9b8202cbccd1249e8640ea844c0dabbb99a604a6ba52feee963e557680ed285c","impliedFormat":1},{"version":"27ecce15e099f4934bf92a9ab29be90c03a9a4d443b4ed5446ebf6e953f69ce5","impliedFormat":1},{"version":"473f53747832bc2588d9e9e0347d3fbcc8aa8e61124b4b4ed54185f930e4f80e","impliedFormat":1},{"version":"bf96e903108160a97d684bb1d0991faad9a0c9a209759a7338ea22fbd4510f75","impliedFormat":1},{"version":"ea99aa2e537966df22f8192e99929ee81719c1cf0b9d9d83d0c6fed53325ccc6","impliedFormat":1},{"version":"f236fcba859b43f1738611471ff3824bfb7b8dee5b76b5385e717968c9137568","impliedFormat":1},{"version":"ee0ff5abedfc526345058f7d0bdb94f038db1d2b85e527a72f8b1d50fd8585d1","impliedFormat":1},{"version":"61029abbe36480fb1b2ab39f2ae333b909e9e25ccf3e192b50909cf26140bcbe","impliedFormat":1},{"version":"d0060157c0e676a2da04b924645eba5892a702e9640c27b9d0aa84e8aa036421","impliedFormat":1},{"version":"92806a9f12a08152730a0d4ccd78c086b20bba8a0fa0cb5eca9e5f8152124f4d","impliedFormat":1},{"version":"b5e6f565409b4ed7e2aecf4e66f2a10574297814e882e68395e8149677d52a5e","impliedFormat":1},{"version":"e27fdbe93134e041e958d04c558e5e8a546367e32f1ed8ad99e57d10018ffeeb","impliedFormat":1},{"version":"b6c59ec90dec5c2db22d3effeabb68023cea59e5351ff94146d139757d36b8d6","impliedFormat":1},{"version":"74a907fa14655328575b29e4dbdf58440dd07c081d9d245f785c4143d10510c8","impliedFormat":1},{"version":"c624b65789f71d3fe13d03b599adbaaf8b17644382f519510097537736df461b","impliedFormat":1},{"version":"3fbeaff576ce5b8035224fbcb98ec13b7cdd16cdbbf8ee7b4052d3d6330683fb","impliedFormat":1},{"version":"cc8eac1829ee2ec61323b3af1967790ceb9d0815ef8c40c340bc8090c17a9064","impliedFormat":1},{"version":"5947f213795a08df7324841661f27341937a5603edcd63fa2d2d66fb11864ec9","impliedFormat":1},{"version":"2d9f4d58554a246616eeaa090a2fb0dddccf412e88617975138389fb15770ca9","impliedFormat":1},{"version":"500561aaec426c1d47bcb10a78c275b7b59cb489c19eb72e1daf4d7d241e4f4a","impliedFormat":1},{"version":"c40c187aa66f4567b5a6b1c82d2dbb4678323a2d4e45f9cd12ba56014df9a930","impliedFormat":1},{"version":"e61b139483dcba16956ba1d374a0216d9f6d20976e1b1d89f1eca7bc766616e8","impliedFormat":1},{"version":"611797579d28f185d4d10d0f6740c486a8b2702c5c1e81d4e6c139434fa7c8d0","impliedFormat":1},{"version":"33cfd7f2d3d56a8b16fad1bd3c12918e5efe753ca01de022252bf8229517fbda","impliedFormat":1},{"version":"87b266d84f88f6e75394ff6cf0998bd25ad6349fb8816f64c42d33a5c19789c4","impliedFormat":1},{"version":"3274e8af4780f7e39a70aca92a6788fec71e9e094d0321d127d44bbd27b27865","impliedFormat":1},{"version":"77b40c7e3f40305a8e92e17daee0db2959c41a576367f5b290fbf5b1455fe7ba","impliedFormat":1},{"version":"8ed8df53be6f8aa62ff077fb2caf0695d29c3e4f1c26c9b12e8eafdf61f49dc9","impliedFormat":1},"e91775fbb42fb88fc91770264003be5720e963a36888c24f018d4288d9cf6537","6e68cbc2ca9ba934750992a76c57839df758d5d9450f895e395682b52f89e8a9","11ddbf5b0e371aaf5323696b76319d2111f51ffeb0077fef50c91277b0cb27a9",{"version":"091d4355d6a6f6b66478034a7d98b7e235f0a80bf3b932a98388b272ed24550a","signature":"afe9018b3de3e7d2a4d4ef5601952f0434785ba6524179a20d6af905924ff54f"},{"version":"c57b441e0c0a9cbdfa7d850dae1f8a387d6f81cbffbc3cd0465d530084c2417d","impliedFormat":99},{"version":"8658354b90861a76abc7b3c04ece2124295c7da0cc4c4d31c2c78d8607188d03","impliedFormat":1},{"version":"4acbc7165a8d54738ff62b51414e772c08fe78434e524e6d8770180d3ba2925f","signature":"512960c0e955a2324b34354dac25e3e4d431a1af4cd33077935eda5e95c8b7e1"},"9bec3cc06b0092aa1492c0eeffd92370dc1c201ac7eaf5c1afb47f93d22334de",{"version":"fe93c474ab38ac02e30e3af073412b4f92b740152cf3a751fdaee8cbea982341","impliedFormat":1},{"version":"f5705d196b442afbdbd971b6e44bad96f4e32afb53cebfa2e5afe3140017bfc6","impliedFormat":1},{"version":"1e00b8bf9e3766c958218cd6144ffe08418286f89ff44ba5a2cc830c03dd22c7","impliedFormat":1},{"version":"2bcc0421514a6402d22bbcb618a6b487a563c8cfc65a7f987f3f524a7f6e8de5","impliedFormat":1},{"version":"6c05d0fcee91437571513c404e62396ee798ff37a2d8bef2104accdc79deb9c0","impliedFormat":1},{"version":"6aa2859da46f726a22040725e684ea964d7469a6b26f1c0a6634bb65e79062b0","impliedFormat":99},{"version":"f28cba0be08c0873d121f6f35107c9e0b209ef649b0d0625c32e46cf0b2ed9a2","signature":"933fa1ee8f2a4d203589011944fc76d755d90af71b43ae3c1a174bbe7cac4cfa"},{"version":"2d32ab7e2fe85318e581bde281e55054959b72ef5f9b42d01d02faa32a22041d","signature":"816bec54b98a990e8cc5a4aa99624cff4b38aa4c9b855ece91a8db8a170cf8f6"},"12a054ec622d6b6a33acc8174a402d081a89dddda7c2af74ce4a9c88eb1c41aa",{"version":"d6056b480feb3370ff004ca083aed2b9dd36b391fc3cef6da7038574bcdb5577","impliedFormat":99},{"version":"d00b7ef279b5e11236738e99e985ced45d75dbf417eab19110519d7fcf029be9","impliedFormat":99},{"version":"9f772f3859eccf48a3ae64207dec19b491fd1833298c76f84725909da9dcc645","signature":"b0290cc267d99d4310b608a913ac18b42d494a8daf7d2dfecf1299bebbd02c86"},{"version":"28f8e10b7b260376efbc71ce450738ae4f5bf7d0d8af26ac6b4ea272d3912e48","signature":"ff53dc24dd9f26eaca109b151c98025c3e47f72426866ab0bcd101e453dbc9dd"},{"version":"024829c0b317972acf4f871bf701525f81896ad74015f1a52d46ae6036205cb9","impliedFormat":99},{"version":"a9373d52584b48809ffd61d74f5b3dfd127da846e3c4ee3c415560386df3994b","impliedFormat":99},{"version":"caf4af98bf464ad3e10c46cf7d340556f89197aab0f87f032c7b84eb8ddb24d9","impliedFormat":99},{"version":"0943a6e4e026d0de8a4969ee975a7283e0627bf41aa4635d8502f6f24365ac9b","impliedFormat":99},{"version":"1461efc4aefd3e999244f238f59c9b9753a7e3dfede923ebe2b4a11d6e13a0d0","impliedFormat":99},{"version":"7ec047b73f621c526468517fea779fec2007dd05baa880989def59126c98ef79","impliedFormat":99},{"version":"8dd450de6d756cee0761f277c6dc58b0b5a66b8c274b980949318b8cad26d712","impliedFormat":99},{"version":"904d6ad970b6bd825449480488a73d9b98432357ab38cf8d31ffd651ae376ff5","impliedFormat":99},{"version":"dfcf16e716338e9fe8cf790ac7756f61c85b83b699861df970661e97bf482692","impliedFormat":99},{"version":"31c30cc54e8c3da37c8e2e40e5658471f65915df22d348990d1601901e8c9ff3","impliedFormat":99},{"version":"36d8011f1437aecf0e6e88677d933e4fb3403557f086f4ac00c5a4cb6d028ac2","impliedFormat":99},{"version":"8085954ba165e611c6230596078063627f3656fed3fb68ad1e36a414c4d7599a","impliedFormat":99},{"version":"2c57db2bf2dbd9e8ef4853be7257d62a1cb72845f7b976bb4ee827d362675f96","impliedFormat":99},{"version":"6b5f886fe41e2e767168e491fe6048398ed6439d44e006d9f51cc31265f08978","impliedFormat":99},{"version":"56a87e37f91f5625eb7d5f8394904f3f1e2a90fb08f347161dc94f1ae586bdd0","impliedFormat":99},{"version":"6b863463764ae572b9ada405bf77aac37b5e5089a3ab420d0862e4471051393b","impliedFormat":99},{"version":"68b6a7501a56babd7bcd840e0d638ee7ec582f1e70b3c36ebf32e5e5836913c8","impliedFormat":99},{"version":"89783bd45ab35df55203b522f8271500189c3526976af533a599a86caaf31362","impliedFormat":99},{"version":"6da2e0928bdab05861abc4e4abebea0c7cf0b67e25374ba35a94df2269563dd8","impliedFormat":99},{"version":"e7b00bec016013bcde74268d837a8b57173951add2b23c8fd12ffe57f204d88f","impliedFormat":99},{"version":"26e6c521a290630ea31f0205a46a87cab35faac96e2b30606f37bae7bcda4f9d","impliedFormat":99},{"version":"71acd198e19fa38447a3cbc5c33f2f5a719d933fccf314aaff0e8b0593271324","impliedFormat":99},{"version":"044047026c70439867589d8596ffe417b56158a1f054034f590166dd793b676b","impliedFormat":99},{"version":"89ad9a4e8044299f356f38879a1c2176bc60c997519b442c92cc5a70b731a360","impliedFormat":99},{"version":"fd4f58cd6b5fc8ce8af0d04bfef5142f15c4bafaac9a9899c6daa056f10bb517","impliedFormat":99},{"version":"2a00cea77767cb26393ee6f972fd32941249a0d65b246bfcb20a780a2b919a21","impliedFormat":99},{"version":"440cb5b34e06fabe3dcb13a3f77b98d771bf696857c8e97ce170b4f345f8a26b","impliedFormat":99},{"version":"5bc7f0946c94e23765bd1b8f62dc3ab65d7716285ca7cf45609f57777ddb436f","impliedFormat":99},{"version":"7d5a5e603a68faea3d978630a84cacad7668f11e14164c4dd10224fa1e210f56","impliedFormat":99},{"version":"2535fc1a5fe64892783ff8f61321b181c24f824e688a4a05ae738da33466605b","impliedFormat":99},{"version":"cbfd5ef0c8fdb4983202252b5f5758a579f4500edc3b9ad413da60cffb5c3564","impliedFormat":99},{"version":"9f7a3c434912fd3feb87af4aabdf0d1b614152ecb5e7b2aa1fff3429879cdd51","impliedFormat":99},{"version":"99d1a601593495371e798da1850b52877bf63d0678f15722d5f048e404f002e4","impliedFormat":99},{"version":"1179ef8174e0e4a09d35576199df04803b1db17c0fb35b9326442884bc0b0cce","impliedFormat":99},{"version":"9c580c6eae94f8c9a38373566e59d5c3282dc194aa266b23a50686fe10560159","impliedFormat":99},{"version":"cc3738ba01d9af5ba1206a313896837ff8779791afcd9869e582783550f17f38","impliedFormat":99},{"version":"a80ec72f5e178862476deaeed532c305bdfcd3627014ae7ac2901356d794fc93","impliedFormat":99},{"version":"4a5aa16151dbec524bb043a5cbce2c3fec75957d175475c115a953aca53999a9","impliedFormat":99},{"version":"7a14bf21ae8a29d64c42173c08f026928daf418bed1b97b37ac4bb2aa197b89b","impliedFormat":99},{"version":"c5013d60cbff572255ccc87c314c39e198c8cc6c5aa7855db7a21b79e06a510f","impliedFormat":99},{"version":"69ec8d900cfec3d40e50490fedbbea5c1b49d32c38adbc236e73a3b8978c0b11","impliedFormat":99},{"version":"7fd629484ba6772b686885b443914655089246f75a13dd685845d0abae337671","impliedFormat":99},{"version":"13dcccb62e8537329ac0448f088ab16fe5b0bbed71e56906d28d202072759804","impliedFormat":99},{"version":"233267a4a036c64aee95f66a0d31e3e0ef048cccc57dd66f9cf87582b38691e4","impliedFormat":99},{"version":"ccb9fbe369885d02cf6c2b2948fb5060451565d37b04356bbe753807f98e0682","impliedFormat":99},{"version":"e315bd8fb2f01946aac364fc5ded80ffabd87140f41e459f5e07bda332ff5507","signature":"590403bf8f288144f710d154479daa9109d50411dd41796d6cd09f4addf08a1b"},"e06c5f8f4e91a7f36e5f954c105fb1626d3499c591f61bc5549613b6df6aa314","8425550282c6369119de2b9d9171885a9bdd59d94376624f83404b68517ced56","8175a3156fcf1032a9e70b94b1122b0f0b544bf7baf163792eed9922db0cd567",{"version":"d0e332751d07e4599cca66c8b9b449b83f3d9d47c3726abd1e44062407ffc4e7","signature":"8df1ce4e8207552c62106a06bed8dbbeff796b21ee57b7ca62b28feacfb81d0f"},{"version":"02ca718b40c7cc403c57ae7bda885ef77655674ecf6fe9920a64f190d92bd945","signature":"f3c5abf3271a5d39d21b909bf6b8a91b9df885c96abfc65c13278893fc6b4c2c"},{"version":"7954216b2cd3ec51521d32740034c628777a4500d0bff884cdd73e72f936b4b5","signature":"10cd8d0a7b7fa217786362beb88f75ced3e688f913754eb335f13e97bd35a1d3"},"26345bb7ed9ed3308f66a7496b91505d90751c42f6229fe59812be0cb897b18b","2f564e53d1dccb76f0a871d5b01f7e7b851b6f4e3cc82ae0838e9afd3cd9f25f",{"version":"2fbe402f0ee5aa8ab55367f88030f79d46211c0a0f342becaa9f648bf8534e9d","impliedFormat":1},{"version":"b94258ef37e67474ac5522e9c519489a55dcb3d4a8f645e335fc68ea2215fe88","impliedFormat":1},{"version":"339b2a9d9209903ea5ae413d22fb9b82dda935c401b43607b7978dcb403cf014","signature":"9dd2ebb1ebeb8f29dbe4adbddb0b4c635504c5c9aba583e2b0185824f25074d4"},{"version":"254296e2a83f0a46217379767aa18a97711f5274919b1eb598906de62c00fd82","signature":"8047d41253a201e8ede65a6208e86605d1b0908864f3c27bc03e996a5383db96"},"152b516c9d5439b349f6eefce48f79da487a9454ddd0d53b5b4b3c0dea749041","ad8ccd4fdcab47b11e4f39d6554d892e74a5ca454a98a56298d220805e7833e2",{"version":"2cef84bf00cbdb452fdc5d8ecfe7b8c0aa3fa788bdc4ad8961e2e636530dbb60","impliedFormat":99},{"version":"24104650185414f379d5cc35c0e2c19f06684a73de5b472bae79e0d855771ecf","impliedFormat":99},{"version":"799003c0ab928582fca04977f47b8d85b43a8de610f4eef0ad2d069fbb9f9399","impliedFormat":99},{"version":"b13dd41c344a23e085f81b2f5cd96792e6b35ae814f32b25e39d9841844ad240","impliedFormat":99},{"version":"17d8b4e6416e48b6e23b73d05fd2fde407e2af8fddbe9da2a98ede14949c3489","impliedFormat":99},{"version":"6d17b2b41f874ab4369b8e04bdbe660163ea5c8239785c850f767370604959e3","impliedFormat":99},{"version":"04b4c044c8fe6af77b6c196a16c41e0f7d76b285d036d79dcaa6d92e24b4982b","impliedFormat":99},{"version":"30bdeead5293c1ddfaea4097d3e9dd5a6b0bc59a1e07ff4714ea1bbe7c5b2318","impliedFormat":99},{"version":"e7df226dcc1b0ce76b32f160556f3d1550124c894aae2d5f73cefaaf28df7779","impliedFormat":99},{"version":"f2b7eef5c46c61e6e72fba9afd7cc612a08c0c48ed44c3c5518559d8508146a2","impliedFormat":99},{"version":"00f0ba57e829398d10168b7db1e16217f87933e61bd8612b53a894bd7d6371da","impliedFormat":99},{"version":"126b20947d9fa74a88bb4e9281462bda05e529f90e22d08ee9f116a224291e84","impliedFormat":99},{"version":"40d9e43acee39702745eb5c641993978ac40f227475eacc99a83ba893ad995db","impliedFormat":99},{"version":"8a66b69b21c8de9cb88b4b6d12f655d5b7636e692a014c5aa1bd81745c8c51d5","impliedFormat":99},{"version":"ebbb846bdd5a78fdacff59ae04cea7a097912aeb1a2b34f8d88f4ebb84643069","impliedFormat":99},{"version":"7321adb29ffd637acb33ee67ea035f1a97d0aa0b14173291cc2fd58e93296e04","impliedFormat":99},{"version":"320816f1a4211188f07a782bdb6c1a44555b3e716ce13018f528ad7387108d5f","impliedFormat":99},{"version":"b2cc8a474b7657f4a03c67baf6bff75e26635fd4b5850675e8cad524a09ddd0c","impliedFormat":99},{"version":"0d081e9dc251063cc69611041c17d25847e8bdbe18164baaa89b7f1f1633c0ab","impliedFormat":99},{"version":"a64c25d8f4ec16339db49867ea2324e77060782993432a875d6e5e8608b0de1e","impliedFormat":99},{"version":"0739310b6b777f3e2baaf908c0fbc622c71160e6310eb93e0d820d86a52e2e23","impliedFormat":99},{"version":"37b32e4eadd8cd3c263e7ac1681c58b2ac54f3f77bb34c5e4326cc78516d55a9","impliedFormat":99},{"version":"9b7a8974e028c4ed6f7f9abb969e3eb224c069fd7f226e26fcc3a5b0e2a1eba8","impliedFormat":99},{"version":"e8100b569926a5592146ed68a0418109d625a045a94ed878a8c5152b1379237c","impliedFormat":99},{"version":"594201c616c318b7f3149a912abd8d6bdf338d765b7bcbde86bca2e66b144606","impliedFormat":99},{"version":"03e380975e047c5c6ded532cf8589e6cc85abb7be3629e1e4b0c9e703f2fd36f","impliedFormat":99},{"version":"fae14b53b7f52a8eb3274c67c11f261a58530969885599efe3df0277b48909e1","impliedFormat":99},{"version":"c41206757c428186f2e0d1fd373915c823504c249336bdc9a9c9bbdf9da95fef","impliedFormat":99},{"version":"e961f853b7b0111c42b763a6aa46fc70d06a697db3d8ed69b38f7ba0ae42a62b","impliedFormat":99},{"version":"3db90f79e36bcb60b3f8de1bc60321026800979c150e5615047d598c787a64b7","impliedFormat":99},{"version":"639b6fb3afbb8f6067c1564af2bd284c3e883f0f1556d59bd5eb87cdbbdd8486","impliedFormat":99},{"version":"49795f5478cb607fd5965aa337135a8e7fd1c58bc40c0b6db726adf186dd403f","impliedFormat":99},{"version":"7d8890e6e2e4e215959e71d5b5bd49482cf7a23be68d48ea446601a4c99bd511","impliedFormat":99},{"version":"d56f72c4bb518de5702b8b6ae3d3c3045c99e0fd48b3d3b54c653693a8378017","impliedFormat":99},{"version":"4c9ac40163e4265b5750510d6d2933fb7b39023eed69f7b7c68b540ad960826e","impliedFormat":99},{"version":"8dfab17cf48e7be6e023c438a9cdf6d15a9b4d2fa976c26e223ba40c53eb8da8","impliedFormat":99},{"version":"38bdf7ccacfd8e418de3a7b1e3cecc29b5625f90abc2fa4ac7843a290f3bf555","impliedFormat":99},{"version":"9819e46a914735211fbc04b8dc6ba65152c62e3a329ca0601a46ba6e05b2c897","impliedFormat":99},{"version":"50f0dc9a42931fb5d65cdd64ba0f7b378aedd36e0cfca988aa4109aad5e714cb","impliedFormat":99},{"version":"894f23066f9fafccc6e2dd006ed5bd85f3b913de90f17cf1fe15a2eb677fd603","impliedFormat":99},{"version":"abdf39173867e6c2d6045f120a316de451bbb6351a6929546b8470ddf2e4b3b9","impliedFormat":99},{"version":"aa2cb4053f948fbd606228195bbe44d78733861b6f7204558bbee603202ee440","impliedFormat":99},{"version":"6911b41bfe9942ac59c2da1bbcbe5c3c1f4e510bf65cae89ed00f434cc588860","impliedFormat":99},{"version":"7b81bc4d4e2c764e85d869a8dd9fe3652b34b45c065482ac94ffaacc642b2507","impliedFormat":99},{"version":"895df4edb46ccdcbce2ec982f5eed292cf7ea3f7168f1efea738ee346feab273","impliedFormat":99},{"version":"8692bb1a4799eda7b2e3288a6646519d4cebb9a0bddf800085fc1bd8076997a0","impliedFormat":99},{"version":"239c9e98547fe99711b01a0293f8a1a776fc10330094aa261f3970aaba957c82","impliedFormat":99},{"version":"34833ec50360a32efdc12780ae624e9a710dd1fd7013b58c540abf856b54285a","impliedFormat":99},{"version":"647538e4007dcc351a8882067310a0835b5bb8559d1cfa5f378e929bceb2e64d","impliedFormat":99},{"version":"992d6b1abcc9b6092e5a574d51d441238566b6461ade5de53cb9718e4f27da46","impliedFormat":99},{"version":"938702305649bf1050bd79f3803cf5cc2904596fc1edd4e3b91033184eae5c54","impliedFormat":99},{"version":"1e931d3c367d4b96fe043e792196d9c2cf74f672ff9c0b894be54e000280a79d","impliedFormat":99},{"version":"05bec322ea9f6eb9efcd6458bb47087e55bd688afdd232b78379eb5d526816ed","impliedFormat":99},{"version":"4c449a874c2d2e5e5bc508e6aa98f3140218e78c585597a21a508a647acd780a","impliedFormat":99},{"version":"dae15e326140a633d7693e92b1af63274f7295ea94fb7c322d5cbe3f5e48be88","impliedFormat":99},{"version":"c2b0a869713bca307e58d81d1d1f4b99ebfc7ec8b8f17e80dde40739aa8a2bc6","impliedFormat":99},{"version":"6e4b4ff6c7c54fa9c6022e88f2f3e675eac3c6923143eb8b9139150f09074049","impliedFormat":99},{"version":"69559172a9a97bbe34a32bff8c24ef1d8c8063feb5f16a6d3407833b7ee504cf","impliedFormat":99},{"version":"86b94a2a3edcb78d9bfcdb3b382547d47cb017e71abe770c9ee8721e9c84857f","impliedFormat":99},{"version":"e3fafafda82853c45c0afc075fea1eaf0df373a06daf6e6c7f382f9f61b2deb3","impliedFormat":99},{"version":"a4ba4b31de9e9140bc49c0addddbfaf96b943a7956a46d45f894822e12bf5560","impliedFormat":99},{"version":"d8a7926fc75f2ed887f17bae732ee31a4064b8a95a406c87e430c58578ee1f67","impliedFormat":99},{"version":"9886ffbb134b0a0059fd82219eba2a75f8af341d98bc6331b6ef8a921e10ec68","impliedFormat":99},{"version":"c2ead057b70d0ae7b87a771461a6222ebdb187ba6f300c974768b0ae5966d10e","impliedFormat":99},{"version":"46687d985aed8485ab2c71085f82fafb11e69e82e8552cf5d3849c00e64a00a5","impliedFormat":99},{"version":"999ca66d4b5e2790b656e0a7ce42267737577fc7a52b891e97644ec418eff7ec","impliedFormat":99},{"version":"ec948ee7e92d0888f92d4a490fdd0afb27fbf6d7aabebe2347a3e8ac82c36db9","impliedFormat":99},{"version":"03ef2386c683707ce741a1c30cb126e8c51a908aa0acc01c3471fafb9baaacd5","impliedFormat":99},{"version":"66a372e03c41d2d5e920df5282dadcec2acae4c629cb51cab850825d2a144cea","impliedFormat":99},{"version":"ddf9b157bd4c06c2e4646c9f034f36267a0fbd028bd4738214709de7ea7c548b","impliedFormat":99},{"version":"3e795aac9be23d4ad9781c00b153e7603be580602e40e5228e2dafe8a8e3aba1","impliedFormat":99},{"version":"98c461ec5953dfb1b5d5bca5fee0833c8a932383b9e651ca6548e55f1e2c71c3","impliedFormat":99},{"version":"5c42107b46cb1d36b6f1dee268df125e930b81f9b47b5fa0b7a5f2a42d556c10","impliedFormat":99},{"version":"7e32f1251d1e986e9dd98b6ff25f62c06445301b94aeebdf1f4296dbd2b8652f","impliedFormat":99},{"version":"2f7e328dda700dcb2b72db0f58c652ae926913de27391bd11505fc5e9aae6c33","impliedFormat":99},{"version":"3de7190e4d37da0c316db53a8a60096dbcd06d1a50677ccf11d182fa26882080","impliedFormat":99},{"version":"a9d6f87e59b32b02c861aade3f4477d7277c30d43939462b93f48644fa548c58","impliedFormat":99},{"version":"2bce8fd2d16a9432110bbe0ba1e663fd02f7d8b8968cd10178ea7bc306c4a5df","impliedFormat":99},{"version":"798bedbf45a8f1e55594e6879cd46023e8767757ecce1d3feaa78d16ad728703","impliedFormat":99},{"version":"62723d5ac66f7ed6885a3931dd5cfa017797e73000d590492988a944832e8bc2","impliedFormat":99},{"version":"03db8e7df7514bf17fc729c87fff56ca99567b9aa50821f544587a666537c233","impliedFormat":99},{"version":"9b1f311ba4409968b68bf20b5d892dbd3c5b1d65c673d5841c7dbde351bc0d0b","impliedFormat":99},{"version":"2d1e8b5431502739fe335ceec0aaded030b0f918e758a5d76f61effa0965b189","impliedFormat":99},{"version":"e725839b8f884dab141b42e9d7ff5659212f6e1d7b4054caa23bc719a4629071","impliedFormat":99},{"version":"4fa38a0b8ae02507f966675d0a7d230ed67c92ab8b5736d99a16c5fbe2b42036","impliedFormat":99},{"version":"50ec1e8c23bad160ddedf8debeebc722becbddda127b8fdce06c23eacd3fe689","impliedFormat":99},{"version":"9a0aea3a113064fd607f41375ade308c035911d3c8af5ae9db89593b5ca9f1f9","impliedFormat":99},{"version":"8d643903b58a0bf739ce4e6a8b0e5fb3fbdfaacbae50581b90803934b27d5b89","impliedFormat":99},{"version":"19de2915ccebc0a1482c2337b34cb178d446def2493bf775c4018a4ea355adb8","impliedFormat":99},{"version":"9be8fc03c8b5392cd17d40fd61063d73f08d0ee3457ecf075dcb3768ae1427bd","impliedFormat":99},{"version":"a2d89a8dc5a993514ca79585039eea083a56822b1d9b9d9d85b14232e4782cbe","impliedFormat":99},{"version":"f526f20cae73f17e8f38905de4c3765287575c9c4d9ecacee41cfda8c887da5b","impliedFormat":99},{"version":"d9ec0978b7023612b9b83a71fee8972e290d02f8ff894e95cdd732cd0213b070","impliedFormat":99},{"version":"7ab10c473a058ec8ac4790b05cae6f3a86c56be9b0c0a897771d428a2a48a9f9","impliedFormat":99},{"version":"451d7a93f8249d2e1453b495b13805e58f47784ef2131061821b0e456a9fd0e1","impliedFormat":99},{"version":"21c56fe515d227ed4943f275a8b242d884046001722a4ba81f342a08dbe74ae2","impliedFormat":99},{"version":"d8311f0c39381aa1825081c921efde36e618c5cf46258c351633342a11601208","impliedFormat":99},{"version":"6b50c3bcc92dc417047740810596fcb2df2502aa3f280c9e7827e87896da168a","impliedFormat":99},{"version":"18a6b318d1e7b31e5749a52be0cf9bbce1b275f63190ef32e2c79db0579328ca","impliedFormat":99},{"version":"6a2d0af2c27b993aa85414f3759898502aa198301bc58b0d410948fe908b07b0","impliedFormat":99},{"version":"2da11b6f5c374300e5e66a6b01c3c78ec21b5d3fec0748a28cc28e00be73e006","impliedFormat":99},{"version":"0729691b39c24d222f0b854776b00530877217bfc30aac1dc7fa2f4b1795c536","impliedFormat":99},{"version":"ca45bb5c98c474d669f0e47615e4a5ae65d90a2e78531fda7862ee43e687a059","impliedFormat":99},{"version":"c1c058b91d5b9a24c95a51aea814b0ad4185f411c38ac1d5eef0bf3cebec17dc","impliedFormat":99},{"version":"3ab0ed4060b8e5b5e594138aab3e7f0262d68ad671d6678bcda51568d4fc4ccc","impliedFormat":99},{"version":"e2bf1faba4ff10a6020c41df276411f641d3fdce5c6bae1db0ec84a0bf042106","impliedFormat":99},{"version":"80b0a8fe14d47a71e23d7c3d4dcee9584d4282ef1d843b70cab1a42a4ea1588c","impliedFormat":99},{"version":"a0f02a73f6e3de48168d14abe33bf5970fdacdb52d7c574e908e75ad571e78f7","impliedFormat":99},{"version":"c728002a759d8ec6bccb10eed56184e86aeff0a762c1555b62b5d0fa9d1f7d64","impliedFormat":99},{"version":"586f94e07a295f3d02f847f9e0e47dbf14c16e04ccc172b011b3f4774a28aaea","impliedFormat":99},{"version":"cfe1a0f4ed2df36a2c65ea6bc235dbb8cf6e6c25feb6629989f1fa51210b32e7","impliedFormat":99},{"version":"8ba69c9bf6de79c177329451ffde48ddab7ec495410b86972ded226552f664df","impliedFormat":99},{"version":"15111cbe020f8802ad1d150524f974a5251f53d2fe10eb55675f9df1e82dbb62","impliedFormat":99},{"version":"782dc153c56a99c9ed07b2f6f497d8ad2747764966876dbfef32f3e27ce11421","impliedFormat":99},{"version":"cc2db30c3d8bb7feb53a9c9ff9b0b859dd5e04c83d678680930b5594b2bf99cb","impliedFormat":99},{"version":"46909b8c85a6fd52e0807d18045da0991e3bdc7373435794a6ba425bc23cc6be","impliedFormat":99},{"version":"e4e511ff63bb6bd69a2a51e472c6044298bca2c27835a34a20827bc3ef9b7d13","impliedFormat":99},{"version":"2c86f279d7db3c024de0f21cd9c8c2c972972f842357016bfbbd86955723b223","impliedFormat":99},{"version":"112c895cff9554cf754f928477c7d58a21191c8089bffbf6905c87fe2dc6054f","impliedFormat":99},{"version":"8cfc293b33082003cacbf7856b8b5e2d6dd3bde46abbd575b0c935dc83af4844","impliedFormat":99},{"version":"d2c5c53f85ce0474b3a876d76c4fc44ff7bb766b14ed1bf495f9abac181d7f5f","impliedFormat":99},{"version":"3c523f27926905fcbe20b8301a0cc2da317f3f9aea2273f8fc8d9ae88b524819","impliedFormat":99},{"version":"9ca0d706f6b039cc52552323aeccb4db72e600b67ddc7a54cebc095fc6f35539","impliedFormat":99},{"version":"a64909a9f75081342ddd061f8c6b49decf0d28051bc78e698d347bdcb9746577","impliedFormat":99},{"version":"7d8d55ae58766d0d52033eae73084c4db6a93c4630a3e17f419dd8a0b2a4dcd8","impliedFormat":99},{"version":"b8b5c8ba972d9ffff313b3c8a3321e7c14523fc58173862187e8d1cb814168ac","impliedFormat":99},{"version":"9c42c0fa76ee36cf9cc7cc34b1389fbb4bd49033ec124b93674ec635fabf7ffe","impliedFormat":99},{"version":"6184c8da9d8107e3e67c0b99dedb5d2dfe5ccf6dfea55c2a71d4037caf8ca196","impliedFormat":99},{"version":"4030ceea7bf41449c1b86478b786e3b7eadd13dfe5a4f8f5fe2eb359260e08b3","impliedFormat":99},{"version":"7bf516ec5dfc60e97a5bde32a6b73d772bd9de24a2e0ec91d83138d39ac83d04","impliedFormat":99},{"version":"e6a6fb3e6525f84edf42ba92e261240d4efead3093aca3d6eb1799d5942ba393","impliedFormat":99},{"version":"45df74648934f97d26800262e9b2af2f77ef7191d4a5c2eb1df0062f55e77891","impliedFormat":99},{"version":"3fe361e4e567f32a53af1f2c67ad62d958e3d264e974b0a8763d174102fe3b29","impliedFormat":99},{"version":"28b520acee4bc6911bfe458d1ad3ebc455fa23678463f59946ad97a327c9ab2b","impliedFormat":99},{"version":"121b39b1a9ad5d23ed1076b0db2fe326025150ef476dccb8bf87778fcc4f6dd7","impliedFormat":99},{"version":"f791f92a060b52aa043dde44eb60307938f18d4c7ac13df1b52c82a1e658953f","impliedFormat":99},{"version":"df09443e7743fd6adc7eb108e760084bacdf5914403b7aac5fbd4dc4e24e0c2c","impliedFormat":99},{"version":"eeb4ff4aa06956083eaa2aad59070361c20254b865d986bc997ee345dbd44cbb","impliedFormat":99},{"version":"ed84d5043444d51e1e5908f664addc4472c227b9da8401f13daa565f23624b6e","impliedFormat":99},{"version":"146bf888b703d8baa825f3f2fb1b7b31bda5dff803e15973d9636cdda33f4af3","impliedFormat":99},{"version":"b4ec8b7a8d23bdf7e1c31e43e5beac3209deb7571d2ccf2a9572865bf242da7c","impliedFormat":99},{"version":"3fba0d61d172091638e56fba651aa1f8a8500aac02147d29bd5a9cc0bc8f9ec2","impliedFormat":99},{"version":"a5a57deb0351b03041e0a1448d3a0cc5558c48e0ed9b79b69c99163cdca64ad8","impliedFormat":99},{"version":"9bcecf0cbc2bfc17e33199864c19549905309a0f9ecc37871146107aac6e05ae","impliedFormat":99},{"version":"d6a211db4b4a821e93c978add57e484f2a003142a6aef9dbfa1fe990c66f337b","impliedFormat":99},{"version":"bd4d10bd44ce3f630dd9ce44f102422cb2814ead5711955aa537a52c8d2cae14","impliedFormat":99},{"version":"08e4c39ab1e52eea1e528ee597170480405716bae92ebe7a7c529f490afff1e0","impliedFormat":99},{"version":"625bb2bc3867557ea7912bd4581288a9fca4f3423b8dffa1d9ed57fafc8610e3","impliedFormat":99},{"version":"d1992164ecc334257e0bef56b1fd7e3e1cea649c70c64ffc39999bb480c0ecdf","impliedFormat":99},{"version":"a53ff2c4037481eb357e33b85e0d78e8236e285b6428b93aa286ceea1db2f5dc","impliedFormat":99},{"version":"4fe608d524954b6857d78857efce623852fcb0c155f010710656f9db86e973a5","impliedFormat":99},{"version":"b53b62a9838d3f57b70cc456093662302abb9962e5555f5def046172a4fe0d4e","impliedFormat":99},{"version":"9866369eb72b6e77be2a92589c9df9be1232a1a66e96736170819e8a1297b61f","impliedFormat":99},{"version":"43abfbdf4e297868d780b8f4cfdd8b781b90ecd9f588b05e845192146a86df34","impliedFormat":99},{"version":"582419791241fb851403ae4a08d0712a63d4c94787524a7419c2bc8e0eb1b031","impliedFormat":99},{"version":"18437eeb932fe48590b15f404090db0ab3b32d58f831d5ffc157f63b04885ee5","impliedFormat":99},{"version":"0c5eaedf622d7a8150f5c2ec1f79ac3d51eea1966b0b3e61bfdea35e8ca213a7","impliedFormat":99},{"version":"fac39fc7a9367c0246de3543a6ee866a0cf2e4c3a8f64641461c9f2dac0d8aae","impliedFormat":99},{"version":"3b9f559d0200134f3c196168630997caedeadc6733523c8b6076a09615d5dec8","impliedFormat":99},{"version":"932af64286d9723da5ef7b77a0c4229829ce8e085e6bcc5f874cb0b83e8310d4","impliedFormat":99},{"version":"adeb9278f11f5561157feee565171c72fd48f5fe34ed06f71abf24e561fcaa1e","impliedFormat":99},{"version":"2269fef79b4900fc6b08c840260622ca33524771ff24fda5b9101ad98ea551f3","impliedFormat":99},{"version":"73d47498a1b73d5392d40fb42a3e7b009ae900c8423f4088c4faa663cc508886","impliedFormat":99},{"version":"7efc34cdc4da0968c3ba687bc780d5cacde561915577d8d1c1e46c7ac931d023","impliedFormat":99},{"version":"3c20a3bb0c50c819419f44aa55acc58476dad4754a16884cef06012d02b0722f","impliedFormat":99},{"version":"4569abf6bc7d51a455503670f3f1c0e9b4f8632a3b030e0794c61bfbba2d13be","impliedFormat":99},{"version":"98b2297b4dc1404078a54b61758d8643e4c1d7830af724f3ed2445d77a7a2d57","impliedFormat":99},{"version":"952ba89d75f1b589e07070fea2d8174332e3028752e76fd46e1c16cc51e6e2af","impliedFormat":99},{"version":"b6c9a2deefb6a57ff68d2a38d33c34407b9939487fc9ee9f32ba3ecf2987a88a","impliedFormat":99},{"version":"f6b371377bab3018dac2bca63e27502ecbd5d06f708ad7e312658d3b5315d948","impliedFormat":99},{"version":"31947dd8f1c8eeb7841e1f139a493a73bd520f90e59a6415375d0d8e6a031f01","impliedFormat":99},{"version":"95cd83b807e10b1af408e62caf5fea98562221e8ddca9d7ccc053d482283ddda","impliedFormat":99},{"version":"19287d6b76288c2814f1633bdd68d2b76748757ffd355e73e41151644e4773d6","impliedFormat":99},{"version":"fc4e6ec7dade5f9d422b153c5d8f6ad074bd9cc4e280415b7dc58fb5c52b5df1","impliedFormat":99},{"version":"3aea973106e1184db82d8880f0ca134388b6cbc420f7309d1c8947b842886349","impliedFormat":99},{"version":"765e278c464923da94dda7c2b281ece92f58981642421ae097862effe2bd30fa","impliedFormat":99},{"version":"de260bed7f7d25593f59e859bd7c7f8c6e6bb87e8686a0fcafa3774cb5ca02d8","impliedFormat":99},{"version":"b5c341ce978f5777fbe05bc86f65e9906a492fa6b327bda3c6aae900c22e76c6","impliedFormat":99},{"version":"686ddbfaf88f06b02c6324005042f85317187866ca0f8f4c9584dd9479653344","impliedFormat":99},{"version":"7f789c0c1db29dd3aab6e159d1ba82894a046bf8df595ac48385931ae6ad83e0","impliedFormat":99},{"version":"8eb3057d4fe9b59b2492921b73a795a2455ebe94ccb3d01027a7866612ead137","impliedFormat":99},{"version":"1e43c5d7aee1c5ec20611e28b5417f5840c75d048de9d7f1800d6808499236f8","impliedFormat":99},{"version":"d42610a5a2bee4b71769968a24878885c9910cd049569daa2d2ee94208b3a7a5","impliedFormat":99},{"version":"f6ed95506a6ed2d40ed5425747529befaa4c35fcbbc1e0d793813f6d725690fa","impliedFormat":99},{"version":"a6fcc1cd6583939506c906dff1276e7ebdc38fbe12d3e108ba38ad231bd18d97","impliedFormat":99},{"version":"ed13354f0d96fb6d5878655b1fead51722b54875e91d5e53ef16de5b71a0e278","impliedFormat":99},{"version":"1193b4872c1fb65769d8b164ca48124c7ebacc33eae03abf52087c2b29e8c46c","impliedFormat":99},{"version":"af682dfabe85688289b420d939020a10eb61f0120e393d53c127f1968b3e9f66","impliedFormat":99},{"version":"0dca04006bf13f72240c6a6a502df9c0b49c41c3cab2be75e81e9b592dcd4ea8","impliedFormat":99},{"version":"79d6ac4a2a229047259116688f9cd62fda25422dee3ad304f77d7e9af53a41ef","impliedFormat":99},{"version":"64534c17173990dc4c3d9388d16675a059aac407031cfce8f7fdffa4ee2de988","impliedFormat":99},{"version":"ba46d160a192639f3ca9e5b640b870b1263f24ac77b6895ab42960937b42dcbb","impliedFormat":99},{"version":"5e5ddd6fc5b590190dde881974ab969455e7fad61012e32423415ae3d085b037","impliedFormat":99},{"version":"1c16fd00c42b60b96fe0fa62113a953af58ddf0d93b0a49cb4919cf5644616f0","impliedFormat":99},{"version":"eb240c0e6b412c57f7d9a9f1c6cd933642a929837c807b179a818f6e8d3a4e44","impliedFormat":99},{"version":"4a7bde5a1155107fc7d9483b8830099f1a6072b6afda5b78d91eb5d6549b3956","impliedFormat":99},{"version":"3c1baaffa9a24cc7ef9eea6b64742394498e0616b127ca630aca0e11e3298006","impliedFormat":99},{"version":"87ca1c31a326c898fa3feb99ec10750d775e1c84dbb7c4b37252bcf3742c7b21","impliedFormat":99},{"version":"d7bd26af1f5457f037225602035c2d7e876b80d02663ab4ca644099ad3a55888","impliedFormat":99},{"version":"2ad0a6b93e84a56b64f92f36a07de7ebcb910822f9a72ad22df5f5d642aff6f3","impliedFormat":99},{"version":"523d1775135260f53f672264937ee0f3dc42a92a39de8bee6c48c7ea60b50b5a","impliedFormat":99},{"version":"e441b9eebbc1284e5d995d99b53ed520b76a87cab512286651c4612d86cd408e","impliedFormat":99},{"version":"76f853ee21425c339a79d28e0859d74f2e53dee2e4919edafff6883dd7b7a80f","impliedFormat":99},{"version":"00cf042cd6ba1915648c8d6d2aa00e63bbbc300ea54d28ed087185f0f662e080","impliedFormat":99},{"version":"f57e6707d035ab89a03797d34faef37deefd3dd90aa17d90de2f33dce46a2c56","impliedFormat":99},{"version":"cc8b559b2cf9380ca72922c64576a43f000275c72042b2af2415ce0fb88d7077","impliedFormat":99},{"version":"1a337ca294c428ba8f2eb01e887b28d080ee4a4307ae87e02e468b1d26af4a74","impliedFormat":99},{"version":"5a15362fc2e72765a908c0d4dd89e3ab3b763e8bc8c23f19234a709ecfd202fe","impliedFormat":99},{"version":"2dffdfe62ac8af0943853234519616db6fd8958fc7ff631149fd8364e663f361","impliedFormat":99},{"version":"5dbdb2b2229b5547d8177c34705272da5a10b8d0033c49efbc9f6efba5e617f2","impliedFormat":99},{"version":"6fc0498cd8823d139004baff830343c9a0d210c687b2402c1384fb40f0aa461c","impliedFormat":99},{"version":"8492306a4864a1dc6fc7e0cc0de0ae9279cbd37f3aae3e9dc1065afcdc83dddc","impliedFormat":99},{"version":"c011b378127497d6337a93f020a05f726db2c30d55dc56d20e6a5090f05919a6","impliedFormat":99},{"version":"f4556979e95a274687ae206bbab2bb9a71c3ad923b92df241d9ab88c184b3f40","impliedFormat":99},{"version":"50e82bb6e238db008b5beba16d733b77e8b2a933c9152d1019cf8096845171a4","impliedFormat":99},{"version":"d6011f8b8bbf5163ef1e73588e64a53e8bf1f13533c375ec53e631aad95f1375","impliedFormat":99},{"version":"693cd7936ac7acfa026d4bcb5801fce71cec49835ba45c67af1ef90dbfd30af7","impliedFormat":99},{"version":"195e2cf684ecddfc1f6420564535d7c469f9611ce7a380d6e191811f84556cd2","impliedFormat":99},{"version":"1dc6b6e7b2a7f2962f31c77f4713f3a5a132bbe14c00db75d557568fe82e4311","impliedFormat":99},{"version":"add93b1180e9aaac2dae4ef3b16f7655893e2ecbe62bd9e48366c305f0063d89","impliedFormat":99},{"version":"594bd896fe37c970aafb7a376ebeec4c0d636b62a5f611e2e27d30fb839ad8a5","impliedFormat":99},{"version":"b1c6a6faf60542ba4b4271db045d7faea56e143b326ef507d2797815250f3afc","impliedFormat":99},{"version":"8c8b165beb794260f462679329b131419e9f5f35212de11c4d53e6d4d9cbedf6","impliedFormat":99},{"version":"ee5a4cf57d49fcf977249ab73c690a59995997c4672bb73fcaaf2eed65dbd1b2","impliedFormat":99},{"version":"f9f36051f138ab1c40b76b230c2a12b3ce6e1271179f4508da06a959f8bee4c1","impliedFormat":99},{"version":"9dc2011a3573d271a45c12656326530c0930f92539accbec3531d65131a14a14","impliedFormat":99},{"version":"091521ce3ede6747f784ae6f68ad2ea86bbda76b59d2bf678bcad2f9d141f629","impliedFormat":99},{"version":"202c2be951f53bafe943fb2c8d1245e35ed0e4dfed89f48c9a948e4d186dd6d4","impliedFormat":99},{"version":"c618aead1d799dbf4f5b28df5a6b9ce13d72722000a0ec3fe90a8115b1ea9226","impliedFormat":99},{"version":"9b0bf59708549c3e77fddd36530b95b55419414f88bbe5893f7bc8b534617973","impliedFormat":99},{"version":"7e216f67c4886f1bde564fb4eebdd6b185f262fe85ad1d6128cad9b229b10354","impliedFormat":99},{"version":"cd51e60b96b4d43698df74a665aa7a16604488193de86aa60ec0c44d9f114951","impliedFormat":99},{"version":"b63341fb6c7ba6f2aeabd9fc46b43e6cc2d2b9eec06534cfd583d9709f310ec2","impliedFormat":99},{"version":"be2af50c81b15bcfe54ad60f53eb1c72dae681c72d0a9dce1967825e1b5830a3","impliedFormat":99},{"version":"be5366845dfb9726f05005331b9b9645f237f1ddc594c0def851208e8b7d297b","impliedFormat":99},{"version":"5ddd536aaeadd4bf0f020492b3788ed209a7050ce27abec4e01c7563ff65da81","impliedFormat":99},{"version":"e243b24da119c1ef0d79af2a45217e50682b139cb48e7607efd66cc01bd9dcda","impliedFormat":99},{"version":"5b1398c8257fd180d0bf62e999fe0a89751c641e87089a83b24392efda720476","impliedFormat":99},{"version":"1588b1359f8507a16dbef67cd2759965fc2e8d305e5b3eb71be5aa9506277dff","impliedFormat":99},{"version":"4c99f2524eee1ec81356e2b4f67047a4b7efaf145f1c4eb530cd358c36784423","impliedFormat":99},{"version":"b30c6b9f6f30c35d6ef84daed1c3781e367f4360171b90598c02468b0db2fc3d","impliedFormat":99},{"version":"79c0d32274ccfd45fae74ac61d17a2be27aea74c70806d22c43fc625b7e9f12a","impliedFormat":99},{"version":"1b7e3958f668063c9d24ac75279f3e610755b0f49b1c02bb3b1c232deb958f54","impliedFormat":99},{"version":"779d4022c3d0a4df070f94858a33d9ebf54af3664754536c4ce9fd37c6f4a8db","impliedFormat":99},{"version":"e662f063d46aa8c088edffdf1d96cb13d9a2cbf06bc38dc6fc62b4d125fb7b49","impliedFormat":99},{"version":"d1d612df1e41c90d9678b07740d13d4f8e6acec2f17390d4ff4be5c889a6d37d","impliedFormat":99},{"version":"c95933fe140918892d569186f17b70ef6b1162f851a0f13f6a89e8f4d599c5a1","impliedFormat":99},{"version":"1d8d30677f87c13c2786980a80750ac1e281bdb65aa013ea193766fe9f0edd74","impliedFormat":99},{"version":"4661673cbc984b8a6ee5e14875a71ed529b64e7f8e347e12c0db4cecc25ad67d","impliedFormat":99},{"version":"7f980a414274f0f23658baa9a16e21d828535f9eac538e2eab2bb965325841db","impliedFormat":99},{"version":"20fb747a339d3c1d4a032a31881d0c65695f8167575e01f222df98791a65da9b","impliedFormat":99},{"version":"dd4e7ebd3f205a11becf1157422f98db675a626243d2fbd123b8b93efe5fb505","impliedFormat":99},{"version":"43ec6b74c8d31e88bb6947bb256ad78e5c6c435cbbbad991c3ff39315b1a3dba","impliedFormat":99},{"version":"b27242dd3af2a5548d0c7231db7da63d6373636d6c4e72d9b616adaa2acef7e1","impliedFormat":99},{"version":"e0ee7ba0571b83c53a3d6ec761cf391e7128d8f8f590f8832c28661b73c21b68","impliedFormat":99},{"version":"072bfd97fc61c894ef260723f43a416d49ebd8b703696f647c8322671c598873","impliedFormat":99},{"version":"e70875232f5d5528f1650dd6f5c94a5bed344ecf04bdbb998f7f78a3c1317d02","impliedFormat":99},{"version":"8e495129cb6cd8008de6f4ff8ce34fe1302a9e0dcff8d13714bd5593be3f7898","impliedFormat":99},{"version":"57ae71d27ee71b7d1f2c6d867ddafbbfbaa629ad75565e63a508dbaa3ef9f859","impliedFormat":99},{"version":"60924ca0c60f0674f208bfa1eaaa54e6973ced7650df7c7a81ae069730ef665a","impliedFormat":99},{"version":"e3181c7595a89dd03ba9a20eb5065fa37e0b0a514261bed774f6ae2241634470","impliedFormat":99},{"version":"c42d5cbf94816659c01f7c2298d0370247f1a981f8ca6370301b7a03b3ced950","impliedFormat":99},{"version":"18c18ab0341fd5fdfefb5d992c365be1696bfe000c7081c964582b315e33f8f2","impliedFormat":99},{"version":"dafbd4199902d904e3d4a233b5faf5dc4c98847fcd8c0ddd7617b2aed50e90d8","impliedFormat":99},{"version":"9fc866f9783d12d0412ed8d68af5e4c9e44f0072d442b0c33c3bda0a5c8cae15","impliedFormat":99},{"version":"5fc13d24a2d0328eac00c4e73cc052a987fbced2151bc0d3b7eb8f3ba4d0f4e2","impliedFormat":99},{"version":"0345bc0b1067588c4ea4c48e34425d3284498c629bc6788ebc481c59949c9037","impliedFormat":99},{"version":"e30f5b5d77c891bc16bd65a2e46cd5384ea57ab3d216c377f482f535db48fc8f","impliedFormat":99},{"version":"f113afe92ee919df8fc29bca91cab6b2ffbdd12e4ac441d2bb56121eb5e7dbe3","impliedFormat":99},{"version":"49d567cc002efb337f437675717c04f207033f7067825b42bb59c9c269313d83","impliedFormat":99},{"version":"1d248f707d02dc76555298a934fba0f337f5028bb1163ce59cd7afb831c9070f","impliedFormat":99},{"version":"5d8debffc9e7b842dc0f17b111673fe0fc0cca65e67655a2b543db2150743385","impliedFormat":99},{"version":"5fccbedc3eb3b23bc6a3a1e44ceb110a1f1a70fa8e76941dce3ae25752caa7a9","impliedFormat":99},{"version":"f4031b95f3bab2b40e1616bd973880fb2f1a97c730bac5491d28d6484fac9560","impliedFormat":99},{"version":"dbe75b3c5ed547812656e7945628f023c4cd0bc1879db0db3f43a57fb8ec0e2b","impliedFormat":99},{"version":"b754718a546a1939399a6d2a99f9022d8a515f2db646bab09f7d2b5bff3cbb82","impliedFormat":99},{"version":"2eef10fb18ed0b4be450accf7a6d5bcce7b7f98e02cac4e6e793b7ad04fc0d79","impliedFormat":99},{"version":"c46f471e172c3be12c0d85d24876fedcc0c334b0dab48060cdb1f0f605f09fed","impliedFormat":99},{"version":"7d6ddeead1d208588586c58c26e4a23f0a826b7a143fb93de62ed094d0056a33","impliedFormat":99},{"version":"7c5782291ff6e7f2a3593295681b9a411c126e3736b83b37848032834832e6b9","impliedFormat":99},{"version":"3a3f09df6258a657dd909d06d4067ee360cd2dccc5f5d41533ae397944a11828","impliedFormat":99},{"version":"ea54615be964503fec7bce04336111a6fa455d3e8d93d44da37b02c863b93eb8","impliedFormat":99},{"version":"2a83694bc3541791b64b0e57766228ea23d92834df5bf0b0fcb93c5bb418069c","impliedFormat":99},{"version":"b5913641d6830e7de0c02366c08b1d26063b5758132d8464c938e78a45355979","impliedFormat":99},{"version":"46c095d39c1887979d9494a824eda7857ec13fb5c20a6d4f7d02c2975309bf45","impliedFormat":99},{"version":"f6e02ca076dc8e624aa38038e3488ebd0091e2faea419082ed764187ba8a6500","impliedFormat":99},{"version":"4d49e8a78aba1d4e0ad32289bf8727ae53bc2def9285dff56151a91e7d770c3e","impliedFormat":99},{"version":"63315cf08117cc728eab8f3eec8801a91d2cd86f91d0ae895d7fd928ab54596d","impliedFormat":99},{"version":"a14a6f3a5636bcaebfe9ec2ccfa9b07dc94deb1f6c30358e9d8ea800a1190d5e","impliedFormat":99},{"version":"21206e7e81876dabf2a7af7aa403f343af1c205bdcf7eff24d9d7f4eee6214c4","impliedFormat":99},{"version":"cd0a9f0ffec2486cad86b7ef1e4da42953ffeb0eb9f79f536e16ff933ec28698","impliedFormat":99},{"version":"f609a6ec6f1ab04dba769e14d6b55411262fd4627a099e333aa8876ea125b822","impliedFormat":99},{"version":"6d8052bb814be030c64cb22ca0e041fe036ad3fc8d66208170f4e90d0167d354","impliedFormat":99},{"version":"851f72a5d3e8a2bf7eeb84a3544da82628f74515c92bdf23c4a40af26dcc1d16","impliedFormat":99},{"version":"59692a7938aab65ea812a8339bbc63c160d64097fe5a457906ea734d6f36bcd4","impliedFormat":99},{"version":"8cb3b95e610c44a9986a7eab94d7b8f8462e5de457d5d10a0b9c6dd16bde563b","impliedFormat":99},{"version":"f571713abd9a676da6237fe1e624d2c6b88c0ca271c9f1acc1b4d8efeea60b66","impliedFormat":99},{"version":"16c5d3637d1517a3d17ed5ebcfbb0524f8a9997a7b60f6100f7c5309b3bb5ac8","impliedFormat":99},{"version":"ca1ec669726352c8e9d897f24899abf27ad15018a6b6bcf9168d5cd1242058ab","impliedFormat":99},{"version":"bffb1b39484facf6d0c5d5feefe6c0736d06b73540b9ce0cf0f12da2edfd8e1d","impliedFormat":99},{"version":"f1663c030754f6171b8bb429096c7d2743282de7733bccd6f67f84a4c588d96e","impliedFormat":99},{"version":"dd09693285e58504057413c3adc84943f52b07d2d2fd455917f50fa2a63c9d69","impliedFormat":99},{"version":"d94c94593d03d44a03810a85186ae6d61ebeb3a17a9b210a995d85f4b584f23d","impliedFormat":99},{"version":"c7c3bf625a8cb5a04b1c0a2fbe8066ecdbb1f383d574ca3ffdabe7571589a935","impliedFormat":99},{"version":"7a2f39a4467b819e873cd672c184f45f548511b18f6a408fe4e826136d0193bb","impliedFormat":99},{"version":"f8a0ae0d3d4993616196619da15da60a6ec5a7dfaf294fe877d274385eb07433","impliedFormat":99},{"version":"2cca80de38c80ef6c26deb4e403ca1ff4efbe3cf12451e26adae5e165421b58d","impliedFormat":99},{"version":"0070d3e17aa5ad697538bf865faaff94c41f064db9304b2b949eb8bcccb62d34","impliedFormat":99},{"version":"53df93f2db5b7eb8415e98242c1c60f6afcac2db44bce4a8830c8f21eee6b1dd","impliedFormat":99},{"version":"d67bf28dc9e6691d165357424c8729c5443290367344263146d99b2f02a72584","impliedFormat":99},{"version":"932557e93fbdf0c36cc29b9e35950f6875425b3ac917fa0d3c7c2a6b4f550078","impliedFormat":99},{"version":"e3dc7ec1597fb61de7959335fb7f8340c17bebf2feb1852ed8167a552d9a4a25","impliedFormat":99},{"version":"b64e15030511c5049542c2e0300f1fe096f926cf612662884f40227267f5cd9f","impliedFormat":99},{"version":"1932796f09c193783801972a05d8fb1bfef941bb46ac76fbe1abb0b3bfb674fa","impliedFormat":99},{"version":"d9575d5787311ee7d61ad503f5061ebcfaf76b531cfecce3dc12afb72bb2d105","impliedFormat":99},{"version":"5b41d96c9a4c2c2d83f1200949f795c3b6a4d2be432b357ad1ab687e0f0de07c","impliedFormat":99},{"version":"38ec829a548e869de4c5e51671245a909644c8fb8e7953259ebb028d36b4dd06","impliedFormat":99},{"version":"20c2c5e44d37dac953b516620b5dba60c9abd062235cdf2c3bfbf722d877a96b","impliedFormat":99},{"version":"875fe6f7103cf87c1b741a0895fda9240fed6353d5e7941c8c8cbfb686f072b4","impliedFormat":99},{"version":"c0ccccf8fbcf5d95f88ed151d0d8ce3015aa88cf98d4fd5e8f75e5f1534ee7ae","impliedFormat":99},{"version":"1b1f4aba21fd956269ced249b00b0e5bfdbd5ebd9e628a2877ab1a2cf493c919","impliedFormat":99},{"version":"939e3299952dff0869330e3324ba16efe42d2cf25456d7721d7f01a43c1b0b34","impliedFormat":99},{"version":"f0a9b52faec508ba22053dedfa4013a61c0425c8b96598cef3dea9e4a22637c6","impliedFormat":99},{"version":"d5b302f50db61181adc6e209af46ae1f27d7ef3d822de5ea808c9f44d7d219fd","impliedFormat":99},{"version":"19131632ba492c83e8eeadf91a481def0e0b39ffc3f155bc20a7f640e0570335","impliedFormat":99},{"version":"4581c03abea21396c3e1bb119e2fd785a4d91408756209cbeed0de7070f0ab5b","impliedFormat":99},{"version":"ebcd3b99e17329e9d542ef2ccdd64fddab7f39bc958ee99bbdb09056c02d6e64","impliedFormat":99},{"version":"4b148999deb1d95b8aedd1a810473a41d9794655af52b40e4894b51a8a4e6a6d","impliedFormat":99},{"version":"1781cc99a0f3b4f11668bb37cca7b8d71f136911e87269e032f15cf5baa339bf","impliedFormat":99},{"version":"33f1b7fa96117d690035a235b60ecd3cd979fb670f5f77b08206e4d8eb2eb521","impliedFormat":99},{"version":"01429b306b94ff0f1f5548ce5331344e4e0f5872b97a4776bd38fd2035ad4764","impliedFormat":99},{"version":"c1bc4f2136de7044943d784e7a18cb8411c558dbb7be4e4b4876d273cbd952af","impliedFormat":99},{"version":"5470f84a69b94643697f0d7ec2c8a54a4bea78838aaa9170189b9e0a6e75d2cf","impliedFormat":99},{"version":"36aaa44ee26b2508e9a6e93cd567e20ec700940b62595caf962249035e95b5e3","impliedFormat":99},{"version":"f8343562f283b7f701f86ad3732d0c7fd000c20fe5dc47fa4ed0073614202b4d","impliedFormat":99},{"version":"a53c572630a78cd99a25b529069c1e1370f8a5d8586d98e798875f9052ad7ad1","impliedFormat":99},{"version":"4ad3451d066711dde1430c544e30e123f39e23c744341b2dfd3859431c186c53","impliedFormat":99},{"version":"8069cbef9efa7445b2f09957ffbc27b5f8946fdbade4358fb68019e23df4c462","impliedFormat":99},{"version":"cd8b4e7ad04ba9d54eb5b28ac088315c07335b837ee6908765436a78d382b4c3","impliedFormat":99},{"version":"d533d8f8e5c80a30c51f0cbfe067b60b89b620f2321d3a581b5ba9ac8ffd7c3a","impliedFormat":99},{"version":"33f49f22fdda67e1ddbacdcba39e62924793937ea7f71f4948ed36e237555de3","impliedFormat":99},{"version":"710c31d7c30437e2b8795854d1aca43b540cb37cefd5900f09cfcd9e5b8540c4","impliedFormat":99},{"version":"b2c03a0e9628273bc26a1a58112c311ffbc7a0d39938f3878837ab14acf3bc41","impliedFormat":99},{"version":"a93beb0aa992c9b6408e355ea3f850c6f41e20328186a8e064173106375876c2","impliedFormat":99},{"version":"efdcba88fcd5421867898b5c0e8ea6331752492bd3547942dea96c7ebcb65194","impliedFormat":99},{"version":"a98e777e7a6c2c32336a017b011ba1419e327320c3556b9139413e48a8460b9a","impliedFormat":99},{"version":"ea44f7f8e1fe490516803c06636c1b33a6b82314366be1bd6ffa4ba89bc09f86","impliedFormat":99},{"version":"c25f22d78cc7f46226179c33bef0e4b29c54912bde47b62e5fdaf9312f22ffcb","impliedFormat":99},{"version":"d57579cfedc5a60fda79be303080e47dfe0c721185a5d95276523612228fcefc","impliedFormat":99},{"version":"a41630012afe0d4a9ff14707f96a7e26e1154266c008ddbd229e3f614e4d1cf7","impliedFormat":99},{"version":"298a858633dfa361bb8306bbd4cfd74f25ab7cc20631997dd9f57164bc2116d1","impliedFormat":99},{"version":"921782c45e09940feb232d8626a0b8edb881be2956520c42c44141d9b1ddb779","impliedFormat":99},{"version":"06117e4cc7399ce1c2b512aa070043464e0561f956bda39ef8971a2fcbcdbf2e","impliedFormat":99},{"version":"daccf332594b304566c7677c2732fed6e8d356da5faac8c5f09e38c2f607a4ab","impliedFormat":99},{"version":"4386051a0b6b072f35a2fc0695fecbe4a7a8a469a1d28c73be514548e95cd558","impliedFormat":99},{"version":"78e41de491fe25947a7fd8eeef7ebc8f1c28c1849a90705d6e33f34b1a083b90","impliedFormat":99},{"version":"3ccd198e0a693dd293ed22e527c8537c76b8fe188e1ebf20923589c7cfb2c270","impliedFormat":99},{"version":"2ebf2ee015d5c8008428493d4987e2af9815a76e4598025dd8c2f138edc1dcae","impliedFormat":99},{"version":"0dcc8f61382c9fcdafd48acc54b6ffda69ca4bb7e872f8ad12fb011672e8b20c","impliedFormat":99},{"version":"9db563287eb527ead0bcb9eb26fbec32f662f225869101af3cabcb6aee9259cf","impliedFormat":99},{"version":"068489bec523be43f12d8e4c5c337be4ff6a7efb4fe8658283673ae5aae14b85","impliedFormat":99},{"version":"838212d0dc5b97f7c5b5e29a89953de3906f72fce13c5ae3c5ade346f561d226","impliedFormat":99},{"version":"ddc78d29af824ad7587152ea523ed5d60f2bc0148d8741c5dacf9b5b44587b1b","impliedFormat":99},{"version":"019b522e3783e5519966927ceeb570eefcc64aba3f9545828a5fb4ae1fde53c6","impliedFormat":99},{"version":"b34623cc86497a5123de522afba770390009a56eebddba38d2aa5798b70b0a87","impliedFormat":99},{"version":"d2a8cbeb0c0caaf531342062b4b5c227118862879f6a25033e31fad00797b7eb","impliedFormat":99},{"version":"14891c20f15be1d0d42ecbbd63de1c56a4d745e3ea2b4c56775a4d5d36855630","impliedFormat":99},{"version":"e55a1f6b198a39e38a3cea3ffe916aab6fde7965c827db3b8a1cacf144a67cd9","impliedFormat":99},{"version":"f7910ccfe56131e99d52099d24f3585570dc9df9c85dd599a387b4499596dd4d","impliedFormat":99},{"version":"9409ac347c5779f339112000d7627f17ede6e39b0b6900679ce5454d3ad2e3c9","impliedFormat":99},{"version":"22dfe27b0aa1c669ce2891f5c89ece9be18074a867fe5dd8b8eb7c46be295ca1","impliedFormat":99},{"version":"684a5c26ce2bb7956ef6b21e7f2d1c584172cd120709e5764bc8b89bac1a10eb","impliedFormat":99},{"version":"93761e39ce9d3f8dd58c4327e615483f0713428fa1a230883eb812292d47bbe8","impliedFormat":99},{"version":"c66be51e3d121c163a4e140b6b520a92e1a6a8a8862d44337be682e6f5ec290a","impliedFormat":99},{"version":"66e486a9c9a86154dc9780f04325e61741f677713b7e78e515938bf54364fee2","impliedFormat":99},{"version":"d211bc80b6b6e98445df46fe9dd3091944825dd924986a1c15f9c66d7659c495","impliedFormat":99},{"version":"8dd2b72f5e9bf88939d066d965144d07518e180efec3e2b6d06ae5e725d84c7d","impliedFormat":99},{"version":"949cb88e315ab1a098c3aa4a8b02496a32b79c7ef6d189eee381b96471a7f609","impliedFormat":99},{"version":"bc43af2a5fa30a36be4a3ed195ff29ffb8067bf4925aa350ace9d9f18f380cc2","impliedFormat":99},{"version":"36844f94161a10af6586f50b95d40baa244215fea31055f27bcbea42cd30373e","impliedFormat":99},{"version":"8428e71f6d1b63acf55ceb56244aad9cf07678cf9626166e4aded15e3d252f8a","impliedFormat":99},{"version":"11505212ab24aa0f06d719a09add4be866e26f0fc15e96a1a2a8522c0c6a73a8","impliedFormat":99},{"version":"55828c4ddfee3bc66d533123ff52942ae67a2115f7395b2a2e0a22cea3ca64e7","impliedFormat":99},{"version":"c44bb0071cededc08236d57d1131c44339c1add98b029a95584dfe1462533575","impliedFormat":99},{"version":"7a4935af71877da3bbc53938af00e5d4f6d445ef850e1573a240447dcb137b5c","impliedFormat":99},{"version":"4e313033202712168ecc70a6d830964ad05c9c93f81d806d7a25d344f6352565","impliedFormat":99},{"version":"8a1fc69eaf8fc8d447e6f776fbfa0c1b12245d7f35f1dbfb18fbc2d941f5edd8","impliedFormat":99},{"version":"afb9b4c8bd38fb43d38a674de56e6f940698f91114fded0aa119de99c6cd049a","impliedFormat":99},{"version":"1d277860f19b8825d027947fca9928ee1f3bfaa0095e85a97dd7a681b0698dfc","impliedFormat":99},{"version":"6d32122bb1e7c0b38b6f126d166dff1f74c8020f8ba050248d182dcafc835d08","impliedFormat":99},{"version":"cfac5627d337b82d2fbeff5f0f638b48a370a8d72d653327529868a70c5bc0f8","impliedFormat":99},{"version":"8a826bc18afa4c5ed096ceb5d923e2791a5bae802219e588a999f535b1c80492","impliedFormat":99},{"version":"73e94021c55ab908a1b8c53792e03bf7e0d195fee223bdc5567791b2ccbfcdec","impliedFormat":99},{"version":"5f73eb47b37f3a957fe2ac6fe654648d60185908cab930fc01c31832a5cb4b10","impliedFormat":99},{"version":"cb6372a2460010a342ba39e06e1dcfd722e696c9d63b4a71577f9a3c72d09e0a","impliedFormat":99},{"version":"1e289698069f553f36bbf12ee0084c492245004a69409066faceb173d2304ec4","impliedFormat":99},{"version":"f1ca71145e5c3bba4d7f731db295d593c3353e9a618b40c4af0a4e9a814bb290","impliedFormat":99},{"version":"ac12a6010ff501e641f5a8334b8eaf521d0e0739a7e254451b6eea924c3035c7","impliedFormat":99},{"version":"97395d1e03af4928f3496cc3b118c0468b560765ab896ce811acb86f6b902b5c","impliedFormat":99},{"version":"7dcfbd6a9f1ce1ddf3050bd469aa680e5259973b4522694dc6291afe20a2ae28","impliedFormat":99},{"version":"6e545419ad200ae4614f8e14d32b7e67e039c26a872c0f93437b0713f54cde53","impliedFormat":99},{"version":"efc225581aae9bb47d421a1b9f278db0238bc617b257ce6447943e59a2d1621e","impliedFormat":99},{"version":"8833b88e26156b685bc6f3d6a014c2014a878ffbd240a01a8aee8a9091014e9c","impliedFormat":99},{"version":"7a2a42a1ac642a9c28646731bd77d9849cb1a05aa1b7a8e648f19ab7d72dd7dc","impliedFormat":99},{"version":"4d371c53067a3cc1a882ff16432b03291a016f4834875b77169a2d10bb1b023e","impliedFormat":99},{"version":"99b38f72e30976fd1946d7b4efe91aa227ecf0c9180e1dd6502c1d39f37445b4","impliedFormat":99},{"version":"df1bcf0b1c413e2945ce63a67a1c5a7b21dbbec156a97d55e9ea0eed90d2c604","impliedFormat":99},{"version":"6e2011a859fa435b1196da1720be944ed59c668bb42d2f2711b49a506b3e4e90","impliedFormat":99},{"version":"b4bfa90fac90c6e0d0185d2fe22f059fec67587cc34281f62294f9c4615a8082","impliedFormat":99},{"version":"036d363e409ebe316a6366aff5207380846f8f82e100c2e3db4af5fe0ad0c378","impliedFormat":99},{"version":"5ae6642588e4a72e5a62f6111cb750820034a7fbe56b5d8ec2bcb29df806ce52","impliedFormat":99},{"version":"6fca09e1abc83168caf36b751dec4ddda308b5714ec841c3ff0f3dc07b93c1b8","impliedFormat":99},{"version":"2f7268e6ac610c7122b6b416e34415ce42b51c56d080bef41786d2365f06772d","impliedFormat":99},{"version":"9a07957f75128ed0be5fc8a692a14da900878d5d5c21880f7c08f89688354aa4","impliedFormat":99},{"version":"8b6f3ae84eab35c50cf0f1b608c143fe95f1f765df6f753cd5855ae61b3efbe2","impliedFormat":99},{"version":"992491d83ff2d1e7f64a8b9117daee73724af13161f1b03171f0fa3ffe9b4e3e","impliedFormat":99},{"version":"12bcf6af851be8dd5f3e66c152bb77a83829a6a8ba8c5acc267e7b15e11aa9ab","impliedFormat":99},{"version":"e2704efc7423b077d7d9a21ddb42f640af1565e668d5ec85f0c08550eff8b833","impliedFormat":99},{"version":"e0513c71fd562f859a98940633830a7e5bcd7316b990310e8bb68b1d41d676a3","impliedFormat":99},{"version":"712071b9066a2d8f4e11c3b8b3d5ada6253f211a90f06c6e131cff413312e26d","impliedFormat":99},{"version":"5a187a7bc1e7514ef1c3d6eaafa470fc45541674d8fca0f9898238728d62666a","impliedFormat":99},{"version":"0c06897f7ab3830cef0701e0e083b2c684ed783ae820b306aedd501f32e9562d","impliedFormat":99},{"version":"56cc6eae48fd08fa709cf9163d01649f8d24d3fea5806f488d2b1b53d25e1d6c","impliedFormat":99},{"version":"57a925b13947b38c34277d93fb1e85d6f03f47be18ca5293b14082a1bd4a48f5","impliedFormat":99},{"version":"9d9d64c1fa76211dd529b6a24061b8d724e2110ee55d3829131bca47f3fe4838","impliedFormat":99},{"version":"c13042e244bb8cf65586e4131ef7aed9ca33bf1e029a43ed0ebab338b4465553","impliedFormat":99},{"version":"54be9b9c71a17cb2519b841fad294fa9dc6e0796ed86c8ac8dd9d8c0d1c3a631","impliedFormat":99},{"version":"10881be85efd595bef1d74dfa7b9a76a5ab1bfed9fb4a4ca7f73396b72d25b90","impliedFormat":99},{"version":"925e71eaa87021d9a1215b5cf5c5933f85fe2371ddc81c32d1191d7842565302","impliedFormat":99},{"version":"faed0b3f8979bfbfb54babcff9d91bd51fda90931c7716effa686b4f30a09575","impliedFormat":99},{"version":"53c72d68328780f711dbd39de7af674287d57e387ddc5a7d94f0ffd53d8d3564","impliedFormat":99},{"version":"51129924d359cdebdccbf20dbabc98c381b58bfebe2457a7defed57002a61316","impliedFormat":99},{"version":"7270a757071e3bc7b5e7a6175f1ac9a4ddf4de09f3664d80cb8805138f7d365b","impliedFormat":99},{"version":"ea7b5c6a79a6511cdeeedc47610370be1b0e932e93297404ef75c90f05fc1b61","impliedFormat":99},{"version":"acd75a4056cf2918c6e6b80d1f8d7780cfcd2c10358a301780cb5549c5e254a5","signature":"051d28ed0ca5cb2e080e7e1dbd70ff09b23282f7efcce90d0a6b41c06f5676f7"},{"version":"7f1ded250d18216a01ec45229788c816b09d9b9d41ac2985f1b0d731717561d5","signature":"70a3bd866076cd4e17ae6302aa68b2cf4c55d7a4215e4d3f9a141f6d69a946ba"},{"version":"6156112e60229643e2bf29c37fb7d2546cbc1a8f47c2eeacff53f46f59dd4251","signature":"e5cc53b814108a8860b9bc6d5bfa6e7dc05a464076fe37bd9864120c95226fbb"},"13736b4e1a6df745b084fb97e8a85f3f33f8582961bfd23edaa3ac7475f7970d","dd07dcf5a84c85200e4077b8aaf4aa5595cd1c724185e522b50556664fba5fd5",{"version":"ab889c9f73c689854a011e23da5cb77179e6d3f4bc98ebf9c2d31e149b587554","signature":"513776dee0c78fd705262aa54bd276c1bf7de893e9fb94efc6ad9ffdef821be9"},{"version":"a74b936fe392be0dc657e02ebb1720cfc5a55e5e996fe45d4713e832b97669fc","signature":"fa22b47868bb5c05559d278a684f442bbdd99dfd6eddb04f2d4844fa2a8cbe9c"},"45460eacae6d1f7595d9454cebcafb050144092bdfeb6fa860168fc0803231ba","a246884bb1d009216e79098bea534163eae296cbb033aecfa572bf15f891f890",{"version":"4383d79bea604eb2ae1662c49c0c7c0af05fddbe0f33262f443ecbe402283a22","signature":"97174d47f98a52e6af5c71f0f38a866c8b4d116efe62f9639f44cf04d55ac708"},{"version":"03924912e32cfc973c0cbf88c6daf80f121f402350263630dec0a49374d9677c","signature":"7cc0c6088727ff4b898eb14716426e7864b1346b0b69ae60ae4d3e0d2f1724be"},"660615309c69b64025edf5791b6688011e96cf3db98e1f99aa75be2d9db74f71","2e94e7f91f161511c0252330b036b7c9f1c6479becf9ce1112b4c60d5610135a","fd59a63e73b7c79a17531901e3fa88fb1a48df92cda7a4763d224e8694ff2249",{"version":"d30e67059f5c545c5f8f0cc328a36d2e03b8c4a091b4301bc1d6afb2b1491a3a","impliedFormat":1},{"version":"a356d9a0ba90d10ec6c0fa33386c0b0e2843fd6f0a49513c44f7809926ac25ff","impliedFormat":1},{"version":"980ce2b93e7a6acb3ddf674ef7ce38190048c532e51e21f91fa0b4e76bd9da24","impliedFormat":99},{"version":"782d3adbf885a766ca59ac64614b94be24ddf43364aee8fcf0aaeac78f22c409","impliedFormat":99},{"version":"9a3563739f42de842bf6416a4291fd974f41247cf536ce9a46f8e2d27ff3c9ac","impliedFormat":99},{"version":"8fcbab45a764abd33e19fde93b7bbafdd7a84f7eaf24c4d75a8b47a1153c2367","impliedFormat":99},{"version":"7e462fd642d79001523b2750ee16b439dfee35e3fc8d29befd9c9b85a8473555","impliedFormat":99},{"version":"b0c2fde8e0877c3d412550846ae6eb32c5be23bcade4db9752680fdfc8ee2912","impliedFormat":99},{"version":"4528dccc5a895a9f83e4a5d374d13f974d4e7dd5b767b9255db3a16c4a8b6af1","impliedFormat":99},{"version":"35d4cc70e2aebadb8983c4ebee05fb39b2d4251f283626cf2d877777878a25f1","impliedFormat":99},{"version":"3a8e5767ddb941a6e3a3349be35372ba82741e48b2ad0bc5012096f01259271a","impliedFormat":99},{"version":"877eebb657ae8f9ff4fea6d6160d7dbd7cb86c44b4e5969a34faa0f6bb178281","impliedFormat":99},{"version":"7d4cbd66f135c4dee1dc0e8e83d1c64012afd1e60b3e9fb0c614837614c2150e","impliedFormat":99},{"version":"0e85b2d7628363eea950d41358445a657fd52e5c90c665f89d85ded309a8513d","impliedFormat":99},{"version":"113aef5576cd65f310927b17ae5f6ac8745c542a660bace5f019034d536fbd04","impliedFormat":99},{"version":"c3eadb01eeb845c16e05003ba361c48ffaa5aa282b0cc3391cd1f512716cb8f7","impliedFormat":99},{"version":"a2c1678ec68c42795e2ac068a7d026b61680357d2a881c9df211dd0f83d077fd","impliedFormat":99},{"version":"d913ea1d0389ac20bd683211b0189f2fe4b50daf1aec40579a9de9adcaac321c","impliedFormat":99},{"version":"a7af5f01007f450dc8cf2cdbbb11f4d4bf8bf3faa869d21267db5de74ebf665a","impliedFormat":99},{"version":"723ac403322245c7270585a8f878f9a835f4da110f3b0b23e7971d404587685b","impliedFormat":99},{"version":"092ce9ed3440c57a829d2b47f767d6ab08828bc63fd9a4fa2aaec93e905eb9dd","impliedFormat":99},{"version":"8e34268962765c29f02f67e508ae6fb4485533675b316e3624c45f3b4f4d4a59","impliedFormat":99},{"version":"e02ed9f98527f807856ac9dc722a076064cb59f798b28106597527eb36f6ec88","impliedFormat":99},{"version":"0b67d1d5f611d99afc9ba55060a37e947664d61a5152469895ed5b64551c5e12","impliedFormat":99},{"version":"ce4088bd3b3fed9def201b87d072fcbdc8e0b43366a9489949abeca20c55464e","impliedFormat":99},{"version":"f3d31927b7a3d0f2f119a05a102af2bdd1fc4f759fe43d508a64a80b3b341f6b","impliedFormat":99},{"version":"9af1ebdf1ad0f65d11b952adc31dca4b56344c9ab41a5d0fb75dc6c3279e14b1","impliedFormat":99},{"version":"b3d7be31ee4d5386773e05a57ff97f74fc2559116cec17d21a6d0e26065d4b8c","impliedFormat":99},{"version":"9a4496ad6d48bc801a122c11e94ee1e3f0710bda38b125573f67f5cb0add1733","impliedFormat":99},{"version":"7c8d0fe14db06e4c48dc3697f26975e209fc0ac05480c1502e62af6ada3137a5","impliedFormat":99},{"version":"3f51976480d40cb1b00bd5ce27fbb8c8d6c72ff06e5203c2c06d83ec060d7052","impliedFormat":99},{"version":"dc21879e45f3a023b5fe459c3da5f2f3cf995f21a1ac533049d8950ce394c045","impliedFormat":99},{"version":"622d6ce66ac838d5d7e968daf4ae760cf49797e3fbfaa2b21d01e0fb5d625bc9","impliedFormat":99},{"version":"ecfa30418b2200ba6496b5f59b4c09a95cce9ea37c1daaf5a5db9bb306ee038f","impliedFormat":99},{"version":"01e02b5605d954a0329fe44d775c8fde41fa1b494b2506b524f461def33b3d7b","impliedFormat":99},{"version":"d6e7c7254b9a5168f868503a28d54368537783c4989dc060176de6f8d3042bf7","impliedFormat":99},{"version":"b5fced0ac3ffee12413503b6887a047181054a5a133ab2946b81e7d252f09181","impliedFormat":99},{"version":"c874e98cd875727ea62fdcd978ac9e067ce07cf7493aa4b8b193fdc3b7318eea","impliedFormat":99},{"version":"455e843c1f8e0df452f101c9ec0b63ab8e749f296c947249f8bbc29bff58c83c","impliedFormat":99},{"version":"dc52fbf76167f89ba36d883dae3935675700a59f9977d063a8b781947fae76b0","impliedFormat":99},{"version":"f2c5a01d18de21ad039c0eaed43c8ef57b02f4de1f4d85223eaa0c562f124736","impliedFormat":99},{"version":"fc741907f6d8158b2c4722932d745b11dd41f9355a5b325c8cd3cdfbd966d76d","impliedFormat":99},"25745a2c79a4d5d7b5d128177ce03f7358c28aa2bf70b6433887a2a6dde20ef7","baa22ff52c16a4ab5fab2c6ef4366e431a72a41709ab123ac1980628a1b901d5","f5d4ffc1b39bcba657f7404d7edf77c182c6256e5e3a35e29390d9a99fdb7ef2","bca3c534efd9b5b08398bce917b2b4256fbfc8003408a07cd513597f3d863848","8f5abcc97f07326da58351b54e16fc60dc680201c0d0b7fd3ce1154892f2c574","d9ebe6b59c7489248676f57341643b64e41ee6efa1462ed1b4ed96cd0872dfb4",{"version":"e154e018646d99a0e4107a74828eb1745f84c1e3aafb863029ea2a5e1cd1b6ac","signature":"abf0b13c2c88ee938716674e9fd67f41a7fa6d4fa85499af45b6ec26210f21cf"},"274df0e5a562b102ea5b5e87ba84bb1f7eaa5c6480ba50809f57deb8eec7432d","958c45d561de261549daa9bc7c4f9ab9fdc17b21c57d153011795df988cf5742","8a270b41b9ba9defeec3ee866160bcd90f7944946eb29a6a5bce10ea193f7d12",{"version":"63043409bc7a31fb27bfc7c73afeb36238d89ae28817d6ae8fc90ebcedd43b79","signature":"c08b9fe852c46acaffbc43b47080e27ecab72f929dab3a85973f52252f302463"},{"version":"01fc82a3359d781f977a2916df84efb89321e9c4057752352da10d3a5dcba7e0","signature":"29513b6352d2d740d78b54d8d73d4bcbe7eb408c9fc503d1311ee21ef8756589"},{"version":"05a9d6540ef741652bd9becd9a2d218eb43ae841e38d3f85c01ebc438dd9029f","signature":"116cb2ef8eb74a0b7fd55a7d93fe3312a7d3c9750e4fadd78df4c141b8233572"},{"version":"917ca018b4d1821fb2bf4b6ee44f26f620efbce2fae150a41dec5260d4467d1a","signature":"3c351d1261d931f5a07952d51f4583d1d367c80abac2af13577fd7424626a4d0"},{"version":"1530fa3f4ab93e6b9abaf9ce10293b4abe78f48b74e2f9b306a09a92f4f13a67","signature":"7a7bebe366b2a6661df9bf30ea384d6cf5c87acf7a3462c3a250183186adf9f8"},{"version":"035c64a5fa4c934ac27bfe5242487401f4ff81b77e3a4094cc3ed63fb51a63bc","signature":"d928c43e05435394e96e3878d73c6a97dfb5012d614efcfefa12ab1358502ded"},{"version":"6b63ea6ae36c53b3494a29c13de49add8a085c1dc58dbba7e093d9ca200826e4","signature":"ac4cfce599c3c9942052e08a8482e08ac0a50429b79bfd7227c9eedd3dc82fdc"},{"version":"181217ea421e7a48370c353ae752ca8833ab93313d76d2a8b0c146cc5163cdbf","signature":"31867d7c31228cc9833c1826e7b59cb3ceef9613646ea62826dfcf3621208595"},{"version":"14118caa314970a9575b73fc13996b2a8c9271644fe7a468e5b1b2618cc84392","signature":"93662c477d6d94c6cf275a3694a41156b325b5aa0d48b8aec62bd58cc2a5b0ff"},{"version":"bb703864a1bc9ca5ac3589ffd83785f6dc86f7f6c485c97d7ffd53438777cb9e","impliedFormat":1},{"version":"b26e0ef9faea0ad5737c183cd6a9a957dc2aad94420b5a4dc92c57c6ce48ba95","signature":"d91b1443560552e2d079f559df72b9dc545959873c87f85ed11c3a51b8d3835f"},{"version":"78e75c5b0ebcf4f0bba0b9bdeafc8d7d87c3ea0ecd9c7abfa00a99c2fbf0896c","signature":"78723aac9dbb9cf70a8411ebb6da133979dfa04c4e2624ce2d8f9ac9f161717d"},{"version":"e33869405701d7075ef4cfa8dbcdc60d5c71c186720b8946412ff3092efae3a4","signature":"78c5e55bb06044bd49cc71556d13636efb0077fffca196a52839e262547a0967"},{"version":"35722e2a5e2ead858a4894f7e905a73b80f78c63fad6981470b2ec71b01ff63e","signature":"8d6ef4f9f6a9e08e661b745e5f7c21dba9920c180c9cd72f76e603072bc26730"},{"version":"f98e6ea68f71e08f196fc40d67ed2b55a08c01efc2b12a8e3093c46872104210","signature":"ba2edbbfaf7e6a0d52ed18c52da2fb3ff433b32c678e442c6bd2774f9f7df107"},{"version":"2c4ffffc44e329d8a3e4720430e72270c4e0994b9ab2b48a982ad5db236699cc","signature":"16d76352de9b6144ec42ac488de89e491e17c774f12c775926a02e7b85368dc6"},{"version":"e3bd46b60fec62fbe72b7c9a22da75206d507d70700e976fb45778be250d0822","signature":"b3ee5184dbf154ca01ff12e4703e5dc467ad7c79d8b16c98b8361118de54cea4"},{"version":"2615009bbe6abd96104c99e4ac69cdb785d8a70b0487a0f72b96e191b8788099","signature":"345573144694c5e01040c615287218cf50d8134015a6cab82670c896d4f3fa84"},{"version":"23cdcb1a6d380e523909ab3fc4ef9b6b4d8d44aa1c72220b1bd1cb6582a9b4db","signature":"6dcbf33437c1505aa89ba3082e2f64d612007f376a2e6aa4a0a5a05f42afc228"},{"version":"7e45e1db82ba1489acd6bb4bbdb8f3f70c31af5b0f7b245c1936efac7fc58b7a","affectsGlobalScope":true},"7405ee0fddb85fd19260092991d868c837587097f23697c1b87886023ac51d64","d1986184a09a52db8228cb2bb2a61a8c05c9354e5b93cec8e2628d8579c892d7","fa736f12f51a230fdc181ce01856a9bec5399ad49718e1d7431616909f0c0450"],"root":[514,515,596,597,[873,880],[1369,1372],1375,1376,[1383,1385],1388,1389,[1435,1443],[1446,1449],[1884,1897],[1940,1958],[1960,1972]],"options":{"allowJs":true,"esModuleInterop":true,"jsx":4,"module":99,"skipLibCheck":true,"strict":true,"target":4},"referencedMap":[[81,1],[82,1],[13,1],[14,1],[16,1],[15,1],[2,1],[17,1],[18,1],[19,1],[20,1],[21,1],[22,1],[23,1],[24,1],[3,1],[25,1],[26,1],[4,1],[27,1],[31,1],[28,1],[29,1],[30,1],[32,1],[33,1],[34,1],[5,1],[35,1],[36,1],[37,1],[38,1],[6,1],[42,1],[39,1],[40,1],[41,1],[43,1],[7,1],[44,1],[49,1],[50,1],[45,1],[46,1],[47,1],[48,1],[8,1],[54,1],[51,1],[52,1],[53,1],[55,1],[9,1],[56,1],[57,1],[58,1],[60,1],[59,1],[61,1],[62,1],[10,1],[63,1],[64,1],[65,1],[11,1],[66,1],[67,1],[68,1],[69,1],[70,1],[1,1],[71,1],[72,1],[12,1],[76,1],[74,1],[79,1],[78,1],[73,1],[77,1],[75,1],[80,1],[842,2],[843,3],[841,4],[1971,5],[514,1],[1972,6],[1969,1],[1970,7],[515,8],[597,9],[875,10],[876,10],[877,11],[878,11],[879,11],[880,10],[1369,12],[1370,10],[1887,13],[1888,14],[1448,15],[1449,16],[1891,17],[1892,18],[1442,19],[1443,20],[1894,21],[1895,22],[1896,23],[1897,24],[1438,25],[1940,26],[1941,27],[1944,28],[1945,29],[1947,30],[1942,31],[1943,32],[1949,33],[1948,34],[1950,35],[1951,36],[1952,37],[1953,37],[1954,37],[1955,37],[1371,38],[1384,39],[1385,38],[873,40],[1889,41],[1441,42],[1439,43],[1893,44],[1890,45],[1388,43],[1436,46],[1389,47],[1437,48],[1440,43],[1956,49],[1957,50],[1446,50],[1884,51],[1958,52],[1960,53],[1447,54],[1961,55],[1885,52],[1946,49],[1435,49],[1962,49],[1963,55],[1964,49],[1965,55],[1966,56],[1383,57],[1967,50],[1886,52],[1968,49],[596,58],[1372,43],[1375,59],[874,38],[1376,60],[860,61],[869,1],[866,62],[864,63],[845,64],[844,1],[865,65],[848,65],[863,66],[850,67],[861,68],[846,1],[853,69],[856,70],[859,71],[871,72],[855,73],[857,74],[854,1],[858,61],[862,75],[849,1],[1339,76],[1228,77],[1231,78],[1232,78],[1233,78],[1234,78],[1235,78],[1236,78],[1237,78],[1238,78],[1239,78],[1240,78],[1241,78],[1242,78],[1243,78],[1244,78],[1245,78],[1246,78],[1247,78],[1248,78],[1249,78],[1250,78],[1251,78],[1252,78],[1253,78],[1254,78],[1255,78],[1256,78],[1257,78],[1258,78],[1259,78],[1260,78],[1261,78],[1262,78],[1263,78],[1264,78],[1265,78],[1266,78],[1267,78],[1268,78],[1269,78],[1270,78],[1271,78],[1272,78],[1273,78],[1274,78],[1275,78],[1276,78],[1277,78],[1278,78],[1279,78],[1280,78],[1281,78],[1282,78],[1283,78],[1284,78],[1285,78],[1286,78],[1287,78],[1288,78],[1289,78],[1290,78],[1291,78],[1347,79],[1292,78],[1293,78],[1294,78],[1295,78],[1296,78],[1297,78],[1298,78],[1299,78],[1300,78],[1301,78],[1302,78],[1303,78],[1304,78],[1305,78],[1306,78],[1307,78],[1308,78],[1309,78],[1310,78],[1311,78],[1312,78],[1313,78],[1314,78],[1315,78],[1316,78],[1317,78],[1318,78],[1319,78],[1320,78],[1321,78],[1322,78],[1323,78],[1324,78],[1325,78],[1326,78],[1327,78],[1328,78],[1329,78],[1331,80],[1332,81],[1333,81],[1334,81],[1335,81],[1336,81],[1337,81],[1338,81],[1227,82],[1340,83],[1362,84],[1229,1],[1361,85],[1230,86],[1330,87],[1360,88],[1354,89],[1349,90],[1350,91],[1351,92],[1352,93],[1353,94],[1341,95],[1346,96],[1342,97],[1348,98],[1359,99],[1355,100],[1356,100],[1357,101],[1358,101],[1226,102],[1185,1],[1189,103],[1186,104],[1187,104],[1188,104],[1192,105],[1191,106],[1195,107],[1193,108],[1190,109],[1194,110],[1197,111],[1196,1],[1204,112],[1205,1],[1206,82],[1225,113],[1214,1],[1211,114],[1212,114],[1210,115],[1213,115],[1209,116],[1207,117],[1208,118],[1215,82],[1222,119],[1221,120],[1219,82],[1220,121],[1223,122],[1224,82],[1217,123],[1218,124],[1216,124],[972,125],[968,1],[974,126],[973,126],[975,126],[976,127],[977,128],[969,129],[970,129],[971,130],[978,82],[979,82],[1058,131],[981,132],[980,82],[982,82],[1025,133],[1024,134],[1027,135],[1040,110],[1041,108],[1053,136],[1042,137],[1054,138],[1023,104],[1026,139],[1055,140],[1056,82],[1057,141],[1059,82],[1061,142],[1060,143],[1363,144],[1368,145],[1367,146],[1366,147],[1365,148],[1364,149],[983,82],[984,82],[985,82],[986,82],[987,82],[988,82],[989,82],[998,150],[999,82],[1000,1],[1001,82],[1002,82],[1003,82],[1004,82],[992,1],[1005,1],[1006,82],[991,151],[993,152],[990,82],[996,153],[994,151],[995,152],[1022,154],[1007,82],[1008,152],[1009,82],[1010,82],[1011,1],[1012,82],[1013,82],[1014,82],[1015,82],[1016,82],[1017,82],[1018,155],[1019,82],[1020,82],[997,82],[1021,82],[1708,1],[1709,156],[1710,157],[1715,158],[1711,157],[1714,1],[1712,1],[1713,1],[256,1],[1390,159],[1394,160],[1399,161],[1403,162],[1400,162],[1401,163],[1402,164],[1393,163],[1408,165],[1391,159],[1398,166],[1409,159],[1395,162],[1410,165],[1396,162],[1412,167],[1413,168],[1411,162],[1407,169],[1414,170],[1416,171],[1417,172],[1418,159],[1419,173],[1405,174],[1397,162],[1392,159],[1420,163],[1421,175],[1406,163],[1422,163],[1423,173],[1424,162],[1425,163],[1426,159],[1427,163],[1428,175],[1429,176],[1431,177],[1430,162],[1432,178],[1433,168],[1415,162],[1404,1],[1902,179],[1908,180],[1910,181],[1903,182],[1911,183],[1909,184],[1912,1],[1904,185],[1905,183],[1913,186],[1914,179],[1917,187],[1906,188],[1915,189],[1916,190],[1907,191],[1066,192],[1062,108],[1063,108],[1065,193],[1064,82],[1076,194],[1067,108],[1069,195],[1068,82],[1071,196],[1070,1],[1074,197],[1075,198],[1072,199],[1073,199],[1199,1],[1198,1],[1201,200],[1203,201],[1200,202],[1202,203],[1136,98],[1137,204],[1118,205],[1119,1],[1140,206],[1139,207],[1149,208],[1142,136],[1143,1],[1141,209],[1148,98],[1144,210],[1145,210],[1147,211],[1146,210],[1138,82],[1120,82],[1135,212],[1122,213],[1121,82],[1129,214],[1124,215],[1125,215],[1130,82],[1127,82],[1126,215],[1123,82],[1132,82],[1131,215],[1128,215],[1133,82],[1134,216],[1171,82],[1172,1],[1175,217],[1183,218],[1176,1],[1177,1],[1178,1],[1179,1],[1180,1],[1181,1],[1182,1],[1077,82],[1078,219],[1081,220],[1083,221],[1082,82],[1084,220],[1085,220],[1087,222],[1079,82],[1086,82],[1080,1],[1098,223],[1099,109],[1100,1],[1104,224],[1101,82],[1102,82],[1103,225],[1097,226],[1096,82],[966,227],[951,82],[964,228],[965,82],[967,229],[1046,230],[1047,231],[1048,82],[1049,232],[1045,233],[1043,82],[1044,82],[1052,234],[1050,1],[1051,82],[956,1],[960,1],[952,1],[953,1],[954,1],[955,1],[963,235],[957,236],[958,82],[959,237],[962,1],[961,82],[1030,1],[1036,82],[1031,82],[1032,82],[1033,82],[1037,82],[1039,238],[1034,82],[1035,82],[1038,82],[1029,239],[1028,82],[1105,82],[1150,240],[1151,241],[1152,1],[1153,242],[1154,1],[1155,1],[1156,1],[1157,82],[1158,240],[1159,82],[1161,243],[1162,244],[1160,82],[1163,1],[1164,1],[1184,245],[1165,1],[1166,82],[1167,1],[1168,240],[1169,1],[1170,1],[881,246],[882,247],[883,1],[884,1],[897,248],[898,249],[895,250],[896,251],[899,252],[902,253],[904,254],[905,255],[887,256],[906,1],[910,257],[908,258],[909,1],[903,1],[912,259],[888,260],[914,261],[915,262],[918,263],[917,264],[913,265],[916,266],[911,267],[919,268],[920,269],[924,270],[925,271],[923,272],[901,273],[889,1],[892,274],[926,275],[927,276],[928,276],[885,1],[930,277],[929,276],[950,278],[890,1],[894,279],[931,280],[932,1],[886,1],[922,281],[938,282],[937,283],[934,1],[935,284],[936,1],[933,285],[921,286],[939,287],[940,288],[941,253],[942,253],[943,289],[907,1],[945,290],[946,291],[900,1],[947,1],[948,292],[944,1],[891,293],[893,267],[949,246],[1089,294],[1093,1],[1091,295],[1094,1],[1092,296],[1095,297],[1090,82],[1088,1],[1106,1],[1108,82],[1107,298],[1109,299],[1110,300],[1111,298],[1112,298],[1113,301],[1117,302],[1114,298],[1115,301],[1116,1],[1344,303],[1345,304],[1343,82],[1174,305],[1173,1],[517,306],[516,1],[518,307],[1898,1],[1899,308],[142,309],[143,309],[144,310],[97,311],[145,312],[146,313],[147,314],[92,1],[95,315],[93,1],[94,1],[148,316],[149,317],[150,318],[151,319],[152,320],[153,321],[154,321],[155,322],[156,323],[157,324],[158,325],[98,1],[96,1],[159,326],[160,327],[161,328],[195,329],[162,330],[163,1],[164,331],[165,332],[166,333],[167,334],[168,335],[169,336],[170,337],[171,338],[172,339],[173,339],[174,340],[175,1],[176,341],[177,342],[179,343],[178,344],[180,345],[181,346],[182,347],[183,348],[184,349],[185,350],[186,351],[187,352],[188,353],[189,354],[190,355],[191,356],[192,357],[99,1],[100,1],[101,1],[139,358],[140,1],[141,1],[193,359],[194,360],[199,361],[416,159],[200,362],[198,363],[418,364],[417,365],[196,366],[414,1],[197,367],[83,1],[85,368],[413,159],[273,159],[1445,369],[1444,370],[1373,1],[1959,371],[84,1],[1538,372],[1517,373],[1614,1],[1518,374],[1454,372],[1455,372],[1456,372],[1457,372],[1458,372],[1459,372],[1460,372],[1461,372],[1462,372],[1463,372],[1464,372],[1465,372],[1466,372],[1467,372],[1468,372],[1469,372],[1470,372],[1471,372],[1450,1],[1472,372],[1473,372],[1474,1],[1475,372],[1476,372],[1478,372],[1477,372],[1479,372],[1480,372],[1481,372],[1482,372],[1483,372],[1484,372],[1485,372],[1486,372],[1487,372],[1488,372],[1489,372],[1490,372],[1491,372],[1492,372],[1493,372],[1494,372],[1495,372],[1496,372],[1497,372],[1499,372],[1500,372],[1501,372],[1498,372],[1502,372],[1503,372],[1504,372],[1505,372],[1506,372],[1507,372],[1508,372],[1509,372],[1510,372],[1511,372],[1512,372],[1513,372],[1514,372],[1515,372],[1516,372],[1519,375],[1520,372],[1521,372],[1522,376],[1523,377],[1524,372],[1525,372],[1526,372],[1527,372],[1530,372],[1528,372],[1529,372],[1452,1],[1531,372],[1532,372],[1533,372],[1534,372],[1535,372],[1536,372],[1537,372],[1539,378],[1540,372],[1541,372],[1542,372],[1544,372],[1543,372],[1545,372],[1546,372],[1547,372],[1548,372],[1549,372],[1550,372],[1551,372],[1552,372],[1553,372],[1554,372],[1556,372],[1555,372],[1557,372],[1558,1],[1559,1],[1560,1],[1707,379],[1561,372],[1562,372],[1563,372],[1564,372],[1565,372],[1566,372],[1567,1],[1568,372],[1569,1],[1570,372],[1571,372],[1572,372],[1573,372],[1574,372],[1575,372],[1576,372],[1577,372],[1578,372],[1579,372],[1580,372],[1581,372],[1582,372],[1583,372],[1584,372],[1585,372],[1586,372],[1587,372],[1588,372],[1589,372],[1590,372],[1591,372],[1592,372],[1593,372],[1594,372],[1595,372],[1596,372],[1597,372],[1598,372],[1599,372],[1600,372],[1601,372],[1602,1],[1603,372],[1604,372],[1605,372],[1606,372],[1607,372],[1608,372],[1609,372],[1610,372],[1611,372],[1612,372],[1613,372],[1615,380],[1811,381],[1716,374],[1718,374],[1719,374],[1720,374],[1721,374],[1722,374],[1717,374],[1723,374],[1725,374],[1724,374],[1726,374],[1727,374],[1728,374],[1729,374],[1730,374],[1731,374],[1732,374],[1733,374],[1735,374],[1734,374],[1736,374],[1737,374],[1738,374],[1739,374],[1740,374],[1741,374],[1742,374],[1743,374],[1744,374],[1745,374],[1746,374],[1747,374],[1748,374],[1749,374],[1750,374],[1752,374],[1753,374],[1751,374],[1754,374],[1755,374],[1756,374],[1757,374],[1758,374],[1759,374],[1760,374],[1761,374],[1762,374],[1763,374],[1764,374],[1765,374],[1767,374],[1766,374],[1769,374],[1768,374],[1770,374],[1771,374],[1772,374],[1773,374],[1774,374],[1775,374],[1776,374],[1777,374],[1778,374],[1779,374],[1780,374],[1781,374],[1782,374],[1784,374],[1783,374],[1785,374],[1786,374],[1787,374],[1789,374],[1788,374],[1790,374],[1791,374],[1792,374],[1793,374],[1794,374],[1795,374],[1797,374],[1796,374],[1798,374],[1799,374],[1800,374],[1801,374],[1802,374],[1451,372],[1803,374],[1804,374],[1806,374],[1805,374],[1807,374],[1808,374],[1809,374],[1810,374],[1616,372],[1617,372],[1618,1],[1619,1],[1620,1],[1621,372],[1622,1],[1623,1],[1624,1],[1625,1],[1626,1],[1627,372],[1628,372],[1629,372],[1630,372],[1631,372],[1632,372],[1633,372],[1634,372],[1639,382],[1637,383],[1638,384],[1636,385],[1635,372],[1640,372],[1641,372],[1642,372],[1643,372],[1644,372],[1645,372],[1646,372],[1647,372],[1648,372],[1649,372],[1650,1],[1651,1],[1652,372],[1653,372],[1654,1],[1655,1],[1656,1],[1657,372],[1658,372],[1659,372],[1660,372],[1661,378],[1662,372],[1663,372],[1664,372],[1665,372],[1666,372],[1667,372],[1668,372],[1669,372],[1670,372],[1671,372],[1672,372],[1673,372],[1674,372],[1675,372],[1676,372],[1677,372],[1678,372],[1679,372],[1680,372],[1681,372],[1682,372],[1683,372],[1684,372],[1685,372],[1686,372],[1687,372],[1688,372],[1689,372],[1690,372],[1691,372],[1692,372],[1693,372],[1694,372],[1695,372],[1696,372],[1697,372],[1698,372],[1699,372],[1700,372],[1701,372],[1702,372],[1453,386],[1703,1],[1704,1],[1705,1],[1706,1],[674,387],[605,388],[830,389],[609,390],[599,1],[675,391],[652,392],[677,393],[601,391],[600,1],[672,394],[610,395],[635,396],[642,397],[611,397],[612,397],[613,398],[641,399],[614,400],[629,397],[615,401],[616,401],[617,397],[618,397],[619,398],[620,397],[643,402],[621,397],[622,397],[623,403],[624,397],[625,397],[626,403],[627,398],[628,397],[630,404],[631,403],[632,397],[633,398],[634,397],[667,405],[663,406],[640,407],[679,408],[636,409],[637,407],[664,410],[655,411],[665,412],[662,413],[660,414],[666,415],[659,416],[671,417],[661,418],[673,419],[668,420],[657,421],[639,422],[638,407],[678,423],[658,424],[669,1],[670,425],[602,426],[733,427],[680,428],[718,429],[831,430],[684,431],[685,431],[686,432],[687,431],[683,433],[688,434],[689,435],[690,436],[691,431],[739,437],[832,438],[692,431],[694,439],[695,430],[697,440],[698,441],[699,441],[700,432],[701,431],[702,431],[703,441],[704,432],[705,432],[706,441],[707,431],[708,430],[709,431],[710,432],[711,442],[696,443],[712,431],[713,432],[714,431],[715,431],[716,431],[717,431],[837,444],[833,445],[681,446],[744,447],[682,448],[720,449],[721,446],[834,450],[734,451],[738,452],[736,453],[729,454],[835,455],[836,456],[737,457],[728,458],[732,459],[735,460],[719,391],[740,461],[693,391],[727,462],[725,421],[723,463],[722,446],[741,464],[742,1],[743,465],[724,424],[730,1],[731,466],[839,467],[840,468],[838,469],[651,470],[607,471],[654,391],[653,472],[656,473],[726,474],[792,475],[770,476],[776,477],[745,477],[746,477],[747,478],[775,479],[748,480],[763,477],[749,481],[750,481],[751,477],[752,477],[753,482],[754,477],[777,483],[755,477],[756,477],[757,484],[758,477],[759,477],[760,484],[761,478],[762,477],[764,485],[765,484],[766,477],[767,478],[768,477],[769,477],[789,486],[781,487],[795,488],[771,489],[772,490],[784,491],[778,492],[788,493],[780,494],[787,495],[786,496],[791,497],[779,498],[793,499],[790,500],[785,421],[774,501],[773,490],[794,502],[783,503],[782,504],[644,505],[646,506],[645,505],[647,505],[649,507],[648,508],[650,509],[608,510],[828,511],[796,512],[821,513],[825,514],[824,515],[797,516],[826,517],[817,518],[818,519],[819,519],[820,520],[805,521],[813,522],[823,523],[829,524],[798,525],[799,523],[801,526],[808,527],[812,528],[810,529],[814,530],[802,531],[806,532],[811,533],[827,534],[809,535],[807,536],[803,421],[822,537],[800,538],[816,539],[804,424],[815,540],[606,424],[603,541],[604,542],[676,1],[1380,159],[870,543],[1386,544],[868,545],[867,546],[872,547],[1387,548],[1381,159],[463,549],[468,5],[458,550],[220,551],[260,552],[442,553],[255,554],[237,1],[412,1],[218,1],[431,555],[286,556],[219,1],[340,557],[263,558],[264,559],[411,560],[428,561],[322,562],[436,563],[437,564],[435,565],[434,1],[432,566],[262,567],[221,568],[365,1],[366,569],[292,570],[222,571],[293,570],[288,570],[209,570],[258,572],[257,1],[441,573],[453,1],[245,1],[387,574],[388,575],[382,159],[490,1],[390,1],[391,576],[383,577],[495,578],[494,579],[489,1],[307,1],[427,580],[426,1],[488,581],[384,159],[316,582],[312,583],[317,584],[315,1],[314,585],[313,1],[491,1],[487,1],[493,586],[492,1],[311,583],[482,587],[485,588],[301,589],[300,590],[299,591],[498,159],[298,592],[280,1],[501,1],[1378,593],[1377,1],[504,1],[503,159],[505,594],[202,1],[438,595],[439,596],[440,597],[215,1],[248,1],[214,598],[201,1],[403,159],[207,599],[402,600],[401,601],[392,1],[393,1],[400,1],[395,1],[398,602],[394,1],[396,603],[399,604],[397,603],[217,1],[212,1],[213,570],[268,1],[274,605],[275,606],[272,607],[270,608],[271,609],[266,1],[409,576],[295,576],[462,610],[469,611],[473,612],[445,613],[444,1],[283,1],[506,614],[457,615],[385,616],[386,617],[380,618],[371,1],[408,619],[447,159],[372,620],[410,621],[405,622],[404,1],[406,1],[377,1],[364,623],[446,624],[449,625],[374,626],[378,627],[369,628],[423,629],[456,630],[326,631],[341,632],[210,633],[455,634],[206,635],[276,636],[267,1],[277,637],[353,638],[265,1],[352,639],[91,1],[346,640],[247,1],[367,641],[342,1],[211,1],[241,1],[350,642],[216,1],[278,643],[376,644],[443,645],[375,1],[349,1],[269,1],[355,646],[356,647],[433,1],[358,648],[360,649],[359,650],[250,1],[348,633],[362,651],[325,652],[347,653],[354,654],[225,1],[229,1],[228,1],[227,1],[232,1],[226,1],[235,1],[234,1],[231,1],[230,1],[233,1],[236,655],[224,1],[334,656],[333,1],[338,657],[335,658],[337,659],[339,657],[336,658],[246,660],[296,661],[452,662],[507,1],[477,663],[479,664],[373,665],[478,666],[450,624],[389,624],[223,1],[327,667],[242,668],[243,669],[244,670],[240,671],[422,671],[290,671],[328,672],[291,672],[239,673],[238,1],[332,674],[331,675],[330,676],[329,677],[451,678],[421,679],[420,680],[381,681],[415,682],[419,683],[430,684],[429,685],[425,686],[324,687],[321,688],[323,689],[320,690],[361,691],[351,1],[467,1],[363,692],[424,1],[279,693],[370,595],[368,694],[281,695],[284,696],[502,1],[282,697],[285,697],[465,1],[464,1],[466,1],[500,1],[287,698],[448,1],[318,699],[310,159],[261,1],[205,700],[294,1],[471,159],[204,1],[481,701],[309,159],[475,576],[308,702],[460,703],[306,701],[208,1],[483,704],[304,159],[305,159],[297,1],[203,1],[303,705],[302,706],[249,707],[379,338],[289,338],[357,1],[344,708],[343,1],[407,583],[319,159],[454,598],[461,709],[86,159],[89,710],[90,711],[87,159],[88,1],[259,712],[254,713],[253,1],[252,714],[251,1],[459,715],[470,716],[472,717],[474,718],[1379,719],[476,720],[480,721],[513,722],[484,722],[512,723],[486,724],[496,725],[497,726],[499,727],[508,728],[511,598],[510,1],[509,729],[847,1],[598,301],[852,730],[851,731],[1434,732],[1870,733],[1831,734],[1830,735],[1869,736],[1871,737],[1812,159],[1813,159],[1814,159],[1858,738],[1837,739],[1838,739],[1839,740],[1840,159],[1841,159],[1842,741],[1815,742],[1843,159],[1844,159],[1845,743],[1846,159],[1847,159],[1848,159],[1849,159],[1850,159],[1851,159],[1816,742],[1852,159],[1853,159],[1854,742],[1855,159],[1856,159],[1857,743],[1872,740],[1859,733],[1860,733],[1861,733],[1862,733],[1863,733],[1864,1],[1865,733],[1866,744],[1873,745],[1874,746],[1883,747],[1828,748],[1817,749],[1818,733],[1819,749],[1820,733],[1821,1],[1822,733],[1823,1],[1824,733],[1825,733],[1826,733],[1827,733],[1868,733],[1835,750],[1836,751],[1832,752],[1833,753],[1867,754],[1829,159],[1834,755],[1875,749],[1876,749],[1882,756],[1877,733],[1878,749],[1879,749],[1880,733],[1881,749],[1901,182],[1918,757],[1919,757],[1921,758],[1922,759],[1900,179],[1923,757],[1939,760],[1920,757],[1924,182],[1925,182],[1926,757],[1927,159],[1928,757],[1929,761],[1930,757],[1931,757],[1932,182],[1933,757],[1934,757],[1935,757],[1936,757],[1937,757],[1938,182],[345,762],[1382,159],[1374,1],[117,763],[127,764],[116,763],[137,765],[108,766],[107,767],[136,729],[130,768],[135,769],[110,770],[124,771],[109,772],[133,773],[105,774],[104,729],[134,775],[106,776],[111,777],[112,1],[115,777],[102,1],[138,778],[128,779],[119,780],[120,781],[122,782],[118,783],[121,784],[131,729],[113,785],[114,786],[123,787],[103,301],[126,779],[125,777],[129,1],[132,788],[595,789],[589,790],[593,791],[590,791],[586,790],[594,792],[591,793],[592,791],[587,794],[588,795],[582,796],[526,797],[528,798],[581,1],[527,799],[585,800],[584,801],[583,802],[519,1],[529,797],[530,1],[521,803],[525,804],[520,1],[522,805],[523,806],[524,1],[531,807],[532,807],[533,807],[534,807],[535,807],[536,807],[537,807],[538,807],[539,807],[540,807],[541,807],[542,807],[543,807],[545,807],[544,807],[546,807],[547,807],[548,807],[549,807],[580,808],[550,807],[551,807],[552,807],[553,807],[554,807],[555,807],[556,807],[557,807],[558,807],[559,807],[560,807],[561,807],[562,807],[564,807],[563,807],[565,807],[566,807],[567,807],[568,807],[569,807],[570,807],[571,807],[572,807],[573,807],[574,807],[575,807],[576,807],[579,807],[577,807],[578,807]],"affectedFilesPendingEmit":[1972,1970,597,875,876,877,878,879,880,1369,1370,1887,1888,1448,1449,1891,1892,1442,1443,1894,1895,1896,1897,1438,1940,1941,1944,1945,1947,1942,1943,1949,1948,1950,1951,1952,1953,1954,1955,1371,1384,1385,873,1889,1441,1439,1893,1890,1388,1436,1389,1437,1440,1956,1957,1446,1884,1958,1960,1447,1961,1885,1946,1435,1962,1963,1964,1965,1966,1383,1967,1886,1968,596,1372,1375,874],"version":"5.9.3"}
\ No newline at end of file
From 7a86144ca707e05dc34eb75cb3a9a6547e3c76bd Mon Sep 17 00:00:00 2001
From: DIodide
Date: Mon, 28 Sep 2026 02:34:08 -0400
Subject: [PATCH 10/69] fix(database): refuse to seed production or non-local
databases
Seed creates users with plausible real NetIDs. Abort when NODE_ENV=production or DATABASE_URL host is not localhost/127.0.0.1 unless ALLOW_REMOTE_SEED=1.
---
apps/database/src/seed.ts | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/apps/database/src/seed.ts b/apps/database/src/seed.ts
index c65e564..2becf24 100644
--- a/apps/database/src/seed.ts
+++ b/apps/database/src/seed.ts
@@ -31,6 +31,41 @@ type TagEmbeddingRecord = {
embedding: number[];
};
+/* ── safety guard ──
+ * The seed inserts users with plausible real Princeton NetIDs. Never let it
+ * touch a production or remote database by accident. The postgres client is
+ * lazy, so no connection has been opened yet when this runs.
+ */
+function assertSafeSeedTarget() {
+ if (process.env.ALLOW_REMOTE_SEED === "1") return;
+
+ const refuse = (reason: string): never => {
+ console.error(`\nRefusing to seed: ${reason}`);
+ console.error(
+ "The seed creates demo users with realistic NetIDs and must only run against a local dev database.",
+ );
+ console.error("If you really mean it, re-run with ALLOW_REMOTE_SEED=1.\n");
+ process.exit(1);
+ };
+
+ if (process.env.NODE_ENV === "production") {
+ refuse("NODE_ENV is 'production'.");
+ }
+
+ let host: string;
+ try {
+ host = new URL(process.env.DATABASE_URL ?? "").hostname;
+ } catch {
+ return refuse("DATABASE_URL is missing or not a valid URL.");
+ }
+ const localHosts = new Set(["localhost", "127.0.0.1", "[::1]", "::1"]);
+ if (!localHosts.has(host)) {
+ refuse(`DATABASE_URL host '${host}' is not localhost/127.0.0.1.`);
+ }
+}
+
+assertSafeSeedTarget();
+
/* ── helpers ── */
function days(n: number) {
return n * 24 * 60 * 60 * 1000;
From 0fab5f64db6f957ac6651aae636818035c55d04a Mon Sep 17 00:00:00 2001
From: DIodide
Date: Mon, 28 Sep 2026 02:34:19 -0400
Subject: [PATCH 11/69] chore: remove apps/mpu-scraper
It scraped officer/member personal data using browser cookies and contained an execSync shell injection. Org data will come from the shared InboxEngine service.
---
README.md | 1 -
apps/mpu-scraper/.gitignore | 2 -
apps/mpu-scraper/package.json | 8 -
apps/mpu-scraper/src/index.ts | 524 ---------------------------------
apps/mpu-scraper/tsconfig.json | 14 -
bun.lock | 6 -
6 files changed, 555 deletions(-)
delete mode 100644 apps/mpu-scraper/.gitignore
delete mode 100644 apps/mpu-scraper/package.json
delete mode 100644 apps/mpu-scraper/src/index.ts
delete mode 100644 apps/mpu-scraper/tsconfig.json
diff --git a/README.md b/README.md
index 61baefe..42b61e3 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,6 @@ This is a [Turborepo](https://turbo.build) monorepo managed with [Bun](https://b
| `apps/admin-web` | Admin dashboard — Vite + React |
| `backends/fastapi` | FastAPI backend (Python 3.12, managed with `uv`) |
| `apps/listserv-scraper` | Python scraper for Princeton listserv archives |
-| `apps/mpu-scraper` | Scraper for MyPrincetonU events |
New to the project? Follow **Quick start** below — it gets `apps/web` running locally,
which is the primary thing you need. The Python backend and scrapers are optional
diff --git a/apps/mpu-scraper/.gitignore b/apps/mpu-scraper/.gitignore
deleted file mode 100644
index e7eec9a..0000000
--- a/apps/mpu-scraper/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-cookies.json
-data/
diff --git a/apps/mpu-scraper/package.json b/apps/mpu-scraper/package.json
deleted file mode 100644
index 7b3c7ca..0000000
--- a/apps/mpu-scraper/package.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "name": "@the-forum/mpu-scraper",
- "version": "0.0.1",
- "private": true,
- "scripts": {
- "scrape": "bun run src/index.ts"
- }
-}
diff --git a/apps/mpu-scraper/src/index.ts b/apps/mpu-scraper/src/index.ts
deleted file mode 100644
index e7836a6..0000000
--- a/apps/mpu-scraper/src/index.ts
+++ /dev/null
@@ -1,524 +0,0 @@
-/**
- * MyPrincetonU Club Officers Scraper
- *
- * Scrapes all club/org officer data from my.princeton.edu's CampusGroups API.
- *
- * Usage:
- * 1. Export your browser cookies to apps/mpu-scraper/cookies.json
- * (only CG.SessionID and cg_uid are required)
- * 2. bun run scrape
- *
- * Output: apps/mpu-scraper/data/club_officers.json
- */
-
-import { execSync } from "node:child_process";
-import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
-import { join } from "node:path";
-
-// ---------------------------------------------------------------------------
-// Types
-// ---------------------------------------------------------------------------
-
-interface CookieEntry {
- name: string;
- value: string;
- domain?: string;
- path?: string;
-}
-
-interface ClubListItem {
- id: number;
- name: string;
- email: string | null;
- groupTypeValue: string;
- categoryTagIds: string[];
- published: boolean;
- countMembers: number;
- countOfficers: number;
-}
-
-interface ClubAboutOfficer {
- position: string;
- student: {
- id: number;
- firstName: string;
- lastName: string;
- profilePhotoFileName: string | null;
- profilePhotoSubFolder: string;
- uid: string;
- };
-}
-
-interface ClubAboutResponse {
- club: {
- id: number;
- name: string;
- email: string | null;
- mission: string | null;
- whatWeDo: string | null;
- goals: string | null;
- websiteUrl: string | null;
- instagram: string | null;
- facebook: string | null;
- twitter: string | null;
- youtube: string | null;
- linkedin: string | null;
- discord: string | null;
- groupTypeValue: string;
- categories: { name: string }[];
- officers: ClubAboutOfficer[] | null;
- };
-}
-
-interface UserProfile {
- email: string | null;
- accountType: string | null;
- yearOfGraduation: string | null;
-}
-
-interface OfficerEntry {
- position: string;
- first_name: string;
- last_name: string;
- student_id: number;
- uid: string;
- email: string | null;
- net_id: string | null;
-}
-
-interface MemberEntry {
- first_name: string;
- last_name: string;
- email: string;
- student_type: string;
- year_of_graduation: string;
- student_id: string;
- uid: string;
-}
-
-interface ClubOfficerRecord {
- club_id: number;
- club_name: string;
- club_email: string | null;
- group_type: string;
- categories: string[];
- mission: string | null;
- website: string | null;
- instagram: string | null;
- member_count: number;
- officer_count: number;
- officers: OfficerEntry[];
- president: (OfficerEntry & { email: string | null }) | null;
- members: MemberEntry[];
-}
-
-// ---------------------------------------------------------------------------
-// Config
-// ---------------------------------------------------------------------------
-
-const BASE = "https://my.princeton.edu";
-const ROOT_DIR = join(import.meta.dir, "..");
-const COOKIE_FILE = join(ROOT_DIR, "cookies.json");
-const DATA_DIR = join(ROOT_DIR, "data");
-const OUTPUT_FILE = join(DATA_DIR, "club_officers.json");
-const PAGE_SIZE = 50;
-const DELAY_MS = 200;
-
-// ---------------------------------------------------------------------------
-// Cookie loading
-// ---------------------------------------------------------------------------
-
-function loadCookieString(): string {
- if (!existsSync(COOKIE_FILE)) {
- console.error(`ERROR: Cookie file not found at ${COOKIE_FILE}`);
- console.error("Export your my.princeton.edu cookies from the browser and save them there.");
- process.exit(1);
- }
-
- const raw: CookieEntry[] = JSON.parse(readFileSync(COOKIE_FILE, "utf-8"));
- const essential = new Set(["CG.SessionID", "cg_uid", "AWSALB", "AWSALBCORS"]);
- return raw
- .filter((c) => essential.has(c.name))
- .map((c) => `${c.name}=${c.value}`)
- .join("; ");
-}
-
-// ---------------------------------------------------------------------------
-// HTTP helpers
-// ---------------------------------------------------------------------------
-
-const cookies = loadCookieString();
-
-async function fetchJson(path: string): Promise {
- const url = path.startsWith("http") ? path : `${BASE}${path}`;
- try {
- const res = await fetch(url, {
- headers: {
- Cookie: cookies,
- "X-Requested-With": "XMLHttpRequest",
- Accept: "application/json",
- },
- redirect: "follow",
- signal: AbortSignal.timeout(15_000),
- });
- if (!res.ok) return null;
- const text = await res.text();
- return JSON.parse(text) as T;
- } catch {
- return null;
- }
-}
-
-function sleep(ms: number): Promise {
- return new Promise((r) => setTimeout(r, ms));
-}
-
-// ---------------------------------------------------------------------------
-// LDAP lookup — resolves email → Princeton netID
-// ---------------------------------------------------------------------------
-
-function ldapLookupNetId(email: string): string | null {
- try {
- const result = execSync(
- `ldapsearch -x -H ldaps://ldap.princeton.edu -b "o=Princeton University,c=US" "(mail=${email})" uid`,
- { timeout: 10_000, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] },
- );
- const match = result.match(/^uid:\s*(\S+)/m);
- return match?.[1]?.toLowerCase() ?? null;
- } catch {
- return null;
- }
-}
-
-// ---------------------------------------------------------------------------
-// Scraping logic
-// ---------------------------------------------------------------------------
-
-async function verifySession(): Promise {
- const data = await fetchJson<{ jwt: string; csrf_token: string }>(
- "/mobile_ws/v18/mobile_session",
- );
- return data !== null && "jwt" in data;
-}
-
-async function fetchAllClubs(): Promise {
- const clubs: ClubListItem[] = [];
- let page = 1;
-
- while (true) {
- const data = await fetchJson<{
- data: ClubListItem[];
- _metadata: { total: number };
- }>(`/mobile_ws/v18/mobile_clubs_listing?page=${page}&pageSize=${PAGE_SIZE}`);
-
- if (!data?.data) {
- console.error(` ERROR: unexpected response on page ${page}`);
- break;
- }
-
- const total = data._metadata.total;
- clubs.push(...data.data);
- console.log(` Page ${page}: got ${data.data.length} clubs (${clubs.length}/${total})`);
-
- if (data.data.length < PAGE_SIZE || clubs.length >= total) break;
- page++;
- await sleep(DELAY_MS);
- }
-
- return clubs;
-}
-
-async function fetchClubOfficers(club: ClubListItem): Promise {
- const about = await fetchJson(
- `/mobile_ws/v18/mobile_club_about?id=${club.id}`,
- );
-
- if (!about?.club) return null;
-
- const info = about.club;
- const officers = info.officers ?? [];
-
- const president = officers.find((o) => o.position?.toLowerCase() === "president");
-
- return {
- club_id: club.id,
- club_name: info.name.trim(),
- club_email: info.email,
- group_type: info.groupTypeValue,
- categories: (info.categories ?? []).map((c) => c.name),
- mission: info.mission,
- website: info.websiteUrl,
- instagram: info.instagram,
- member_count: club.countMembers ?? 0,
- officer_count: club.countOfficers ?? 0,
- officers: officers.map((o) => ({
- position: o.position,
- first_name: o.student.firstName,
- last_name: o.student.lastName,
- student_id: o.student.id,
- uid: o.student.uid,
- email: null, // populated in email resolution pass
- net_id: null, // populated in LDAP resolution pass
- })),
- president: president
- ? {
- first_name: president.student.firstName,
- last_name: president.student.lastName,
- student_id: president.student.id,
- uid: president.student.uid,
- email: null,
- net_id: null,
- position: president.position,
- }
- : null,
- members: [], // populated in member fetching pass
- };
-}
-
-interface MemberListingItem {
- fields: string;
- counter: string;
- [key: `p${number}`]: string;
-}
-
-async function fetchClubMembers(clubId: number): Promise {
- const data = await fetchJson(
- `/mobile_ws/v17/mobile_group_page_members?range=0&limit=5000¶m=${clubId}`,
- );
-
- if (!data || !Array.isArray(data) || data.length === 0) return [];
-
- const fields = data[0].fields.replace(/,$/, "").split(",");
- const idx = (name: string) => fields.indexOf(name);
-
- return data.map((item) => ({
- first_name: item[`p${idx("firstName")}`] ?? "",
- last_name: item[`p${idx("lastName")}`] ?? "",
- email: item[`p${idx("student_email")}`] ?? "",
- student_type: item[`p${idx("studentType")}`] ?? "",
- year_of_graduation: item[`p${idx("yearOfGraduation")}`] ?? "",
- student_id: item[`p${idx("studentId")}`] ?? "",
- uid: item[`p${idx("studentUid")}`] ?? "",
- }));
-}
-
-// ---------------------------------------------------------------------------
-// Main
-// ---------------------------------------------------------------------------
-
-async function main() {
- console.log("MyPrincetonU Club Officers Scraper");
- console.log("==================================\n");
-
- // 1. Verify session
- console.log("Verifying session...");
- const alive = await verifySession();
- if (!alive) {
- console.error("Session invalid or expired. Re-export your cookies.");
- process.exit(1);
- }
- console.log(" Session OK\n");
-
- // 2. Fetch all clubs
- console.log("Fetching club list...");
- const clubs = await fetchAllClubs();
- console.log(`\nTotal clubs: ${clubs.length}\n`);
-
- // 3. Fetch officers for each club
- console.log(`Fetching officer details for ${clubs.length} clubs...`);
- const results: ClubOfficerRecord[] = [];
- const errors: { id: number; name: string }[] = [];
-
- for (let i = 0; i < clubs.length; i++) {
- const club = clubs[i];
- const record = await fetchClubOfficers(club);
-
- if (record) {
- results.push(record);
- } else {
- errors.push({ id: club.id, name: club.name.trim() });
- }
-
- if ((i + 1) % 50 === 0 || i === clubs.length - 1) {
- const withPres = results.filter((r) => r.president).length;
- console.log(
- ` [${i + 1}/${clubs.length}] ${results.length} ok, ${withPres} have president, ${errors.length} errors`,
- );
- }
-
- await sleep(DELAY_MS);
- }
-
- // 4. Fetch member lists for each club
- console.log(`\nFetching member lists for ${results.length} clubs...`);
- let totalMembers = 0;
-
- for (let i = 0; i < results.length; i++) {
- const r = results[i];
- r.members = await fetchClubMembers(r.club_id);
- totalMembers += r.members.length;
-
- if ((i + 1) % 50 === 0 || i === results.length - 1) {
- console.log(` [${i + 1}/${results.length}] ${totalMembers} total members scraped`);
- }
-
- await sleep(DELAY_MS);
- }
-
- // 5. Resolve officer emails via profile endpoint
- // Deduplicate by uid so we don't fetch the same person multiple times
- const uniqueUids: string[] = [];
- const seen = new Set();
-
- for (const r of results) {
- for (const o of r.officers) {
- if (o.uid && !seen.has(o.uid)) {
- seen.add(o.uid);
- uniqueUids.push(o.uid);
- }
- }
- }
-
- const uidToEmail = new Map();
-
- console.log(`\nResolving emails for ${uniqueUids.length} unique officers...`);
-
- let resolved = 0;
- let emailErrors = 0;
-
- for (let i = 0; i < uniqueUids.length; i++) {
- const uid = uniqueUids[i];
-
- const profile = await fetchJson(
- `/mobile_ws/v18/mobile_profile2?uid=${uid}&view=full`,
- );
-
- if (profile?.email) {
- uidToEmail.set(uid, profile.email);
- resolved++;
- } else {
- emailErrors++;
- }
-
- if ((i + 1) % 100 === 0 || i === uniqueUids.length - 1) {
- console.log(
- ` [${i + 1}/${uniqueUids.length}] ${resolved} emails resolved, ${emailErrors} failed`,
- );
- }
-
- await sleep(DELAY_MS);
- }
-
- // Populate emails back into all officer records
- for (const r of results) {
- for (const o of r.officers) {
- o.email = uidToEmail.get(o.uid) ?? null;
- }
- if (r.president) {
- r.president.email = uidToEmail.get(r.president.uid) ?? null;
- }
- }
-
- // 6. Resolve netIDs via Princeton LDAP
- // Deduplicate emails so we don't query the same one twice
- const emailToNetId = new Map();
- const uniqueEmails: string[] = [];
-
- for (const r of results) {
- for (const o of r.officers) {
- if (o.email && !emailToNetId.has(o.email)) {
- emailToNetId.set(o.email, null);
- uniqueEmails.push(o.email);
- }
- }
- }
-
- console.log(`\nResolving netIDs via LDAP for ${uniqueEmails.length} unique emails...`);
-
- let netIdResolved = 0;
- let netIdFailed = 0;
-
- for (let i = 0; i < uniqueEmails.length; i++) {
- const email = uniqueEmails[i];
- const netId = ldapLookupNetId(email);
-
- if (netId) {
- emailToNetId.set(email, netId);
- netIdResolved++;
- } else {
- netIdFailed++;
- }
-
- if ((i + 1) % 100 === 0 || i === uniqueEmails.length - 1) {
- console.log(
- ` [${i + 1}/${uniqueEmails.length}] ${netIdResolved} resolved, ${netIdFailed} failed`,
- );
- }
- }
-
- // Populate netIDs back into all officer records
- for (const r of results) {
- for (const o of r.officers) {
- if (o.email) {
- o.net_id = emailToNetId.get(o.email) ?? null;
- }
- }
- if (r.president?.email) {
- r.president.net_id = emailToNetId.get(r.president.email) ?? null;
- }
- }
-
- // 7. Write output
- mkdirSync(DATA_DIR, { recursive: true });
-
- const output = {
- scraped_at: new Date().toISOString(),
- total_clubs: clubs.length,
- clubs_with_officers: results.filter((r) => r.officers.length > 0).length,
- clubs_with_president: results.filter((r) => r.president).length,
- unique_officers: uidToEmail.size,
- officers_with_email: resolved,
- officers_with_net_id: netIdResolved,
- total_members_scraped: totalMembers,
- clubs_with_members: results.filter((r) => r.members.length > 0).length,
- errors: errors.length,
- clubs: results,
- };
-
- writeFileSync(OUTPUT_FILE, JSON.stringify(output, null, 2));
- console.log(`\nResults saved to ${OUTPUT_FILE}`);
-
- // 8. Summary
- console.log(`\n${"=".repeat(60)}`);
- console.log("SUMMARY");
- console.log("=".repeat(60));
- console.log(`Total clubs: ${output.total_clubs}`);
- console.log(`Clubs with officers: ${output.clubs_with_officers}`);
- console.log(`Clubs with president: ${output.clubs_with_president}`);
- console.log(`Unique officers: ${output.unique_officers}`);
- console.log(`Officers with email: ${output.officers_with_email}`);
- console.log(`Officers with netID: ${output.officers_with_net_id}`);
- console.log(`Total members scraped: ${output.total_members_scraped}`);
- console.log(`Clubs with members: ${output.clubs_with_members}`);
- console.log(`Errors: ${output.errors}`);
-
- const presidents = results.filter((r) => r.president);
- if (presidents.length > 0) {
- console.log("\nSample presidents:");
- for (const r of presidents.slice(0, 10)) {
- const p = r.president as NonNullable;
- console.log(
- ` ${r.club_name.padEnd(40)} → ${p.first_name} ${p.last_name} <${p.email ?? "?"}> (netID: ${p.net_id ?? "?"})`,
- );
- }
- }
-
- if (errors.length > 0) {
- console.log("\nFirst few errors:");
- for (const e of errors.slice(0, 5)) {
- console.log(` ${e.name} (ID ${e.id})`);
- }
- }
-}
-
-main();
diff --git a/apps/mpu-scraper/tsconfig.json b/apps/mpu-scraper/tsconfig.json
deleted file mode 100644
index ac3c17e..0000000
--- a/apps/mpu-scraper/tsconfig.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "compilerOptions": {
- "target": "ESNext",
- "module": "ESNext",
- "moduleResolution": "bundler",
- "strict": true,
- "esModuleInterop": true,
- "skipLibCheck": true,
- "outDir": "dist",
- "rootDir": "src",
- "types": ["bun-types"]
- },
- "include": ["src"]
-}
diff --git a/bun.lock b/bun.lock
index 239b6c4..1a1cff8 100644
--- a/bun.lock
+++ b/bun.lock
@@ -48,10 +48,6 @@
"name": "@the-forum/listserv-scraper",
"version": "0.0.1",
},
- "apps/mpu-scraper": {
- "name": "@the-forum/mpu-scraper",
- "version": "0.0.1",
- },
"apps/web": {
"name": "@the-forum/web",
"version": "0.1.0",
@@ -792,8 +788,6 @@
"@the-forum/listserv-scraper": ["@the-forum/listserv-scraper@workspace:apps/listserv-scraper"],
- "@the-forum/mpu-scraper": ["@the-forum/mpu-scraper@workspace:apps/mpu-scraper"],
-
"@the-forum/web": ["@the-forum/web@workspace:apps/web"],
"@ts-morph/common": ["@ts-morph/common@0.27.0", "", { "dependencies": { "fast-glob": "^3.3.3", "minimatch": "^10.0.1", "path-browserify": "^1.0.1" } }, "sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ=="],
From 716f47d71a62fe37e6088baddf5a9632fccd987b Mon Sep 17 00:00:00 2001
From: DIodide
Date: Mon, 28 Sep 2026 02:34:31 -0400
Subject: [PATCH 12/69] chore: pin typescript 5.9 as a root devDependency
Without it, bunx tsc from the repo root resolved typescript@latest (TS 7).
---
bun.lock | 1 +
package.json | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/bun.lock b/bun.lock
index 1a1cff8..69399bc 100644
--- a/bun.lock
+++ b/bun.lock
@@ -10,6 +10,7 @@
"husky": "^9.1.7",
"lint-staged": "^15.3.0",
"turbo": "^2.4.4",
+ "typescript": "~5.9.3",
},
},
"apps/admin-web": {
diff --git a/package.json b/package.json
index f8f6c30..f013dfe 100644
--- a/package.json
+++ b/package.json
@@ -22,7 +22,8 @@
"@types/bun": "^1.3.14",
"husky": "^9.1.7",
"lint-staged": "^15.3.0",
- "turbo": "^2.4.4"
+ "turbo": "^2.4.4",
+ "typescript": "~5.9.3"
},
"workspaces": ["apps/*", "backends/*"],
"lint-staged": {
From 0a39792990ed3c5ea85c5808e615047dc40b1c1a Mon Sep 17 00:00:00 2001
From: DIodide
Date: Mon, 28 Sep 2026 02:38:34 -0400
Subject: [PATCH 13/69] Render all event dates and times in America/New_York
Centralize date helpers in lib/date-format.ts (zoned parts, date keys,
wall-clock to instant conversion, formatters) and use them for the
explore header, event detail, map timeline/labels/day bucketing, map
list cards, and notification timestamps. Server-rendered card strings
now also use Eastern time instead of the host's UTC.
---
apps/web/src/actions/map.ts | 6 +-
.../(app)/events/[id]/event-detail-client.tsx | 22 +--
.../src/app/(app)/explore/explore-client.tsx | 9 +-
.../map/_components/event-list-panel.tsx | 9 +-
.../web/src/app/(app)/map/_lib/map-helpers.ts | 98 ++++------
apps/web/src/app/(app)/map/map-client.tsx | 6 +-
.../layout/notification-dropdown.tsx | 14 +-
apps/web/src/lib/date-format.ts | 179 +++++++++++++++++-
8 files changed, 230 insertions(+), 113 deletions(-)
diff --git a/apps/web/src/actions/map.ts b/apps/web/src/actions/map.ts
index 04044a2..f46b8a2 100644
--- a/apps/web/src/actions/map.ts
+++ b/apps/web/src/actions/map.ts
@@ -16,6 +16,7 @@ import {
users,
} from "@the-forum/database";
import { auth } from "~/auth";
+import { formatTime } from "~/lib/date-format";
export interface MapEvent {
id: string;
@@ -129,10 +130,7 @@ export async function getMapEvents(opts?: {
locationId: r.locationId ?? "",
locationName: r.locationName ?? "TBD",
rawDatetime: r.datetime.toISOString(),
- datetime: r.datetime.toLocaleTimeString("en-US", {
- hour: "numeric",
- minute: "2-digit",
- }),
+ datetime: formatTime(r.datetime),
tags: tagsByEvent.get(r.id) ?? [],
}));
}
diff --git a/apps/web/src/app/(app)/events/[id]/event-detail-client.tsx b/apps/web/src/app/(app)/events/[id]/event-detail-client.tsx
index d03f725..504ddf9 100644
--- a/apps/web/src/app/(app)/events/[id]/event-detail-client.tsx
+++ b/apps/web/src/app/(app)/events/[id]/event-detail-client.tsx
@@ -42,6 +42,7 @@ import {
DialogTrigger,
} from "~/components/ui/dialog";
import { buildGCalUrl } from "~/lib/calendar";
+import { formatLongDate, formatTime } from "~/lib/date-format";
import { cn } from "~/lib/utils";
interface EventDetailClientProps {
@@ -61,17 +62,6 @@ export function EventDetailClient({ event, similarEvents }: EventDetailClientPro
const color = getCategoryColor(event.tags);
- const formatDate = (d: Date) =>
- d.toLocaleDateString("en-US", {
- weekday: "long",
- month: "long",
- day: "numeric",
- year: "numeric",
- });
-
- const formatTime = (d: Date) =>
- d.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" });
-
const handleRsvp = () => {
const prev = isRsvped;
setIsRsvped(!prev);
@@ -129,7 +119,11 @@ export function EventDetailClient({ event, similarEvents }: EventDetailClientPro
{event.flyerUrl ? (
-
+
) : (
)}
@@ -243,12 +237,12 @@ export function EventDetailClient({ event, similarEvents }: EventDetailClientPro
- {formatDate(event.datetime)}
+ {formatLongDate(event.datetime)}
{formatTime(event.datetime)}
- {event.endDatetime && ` - ${formatTime(event.endDatetime)}`}
+ {event.endDatetime && ` – ${formatTime(event.endDatetime)}`} ET
diff --git a/apps/web/src/app/(app)/explore/explore-client.tsx b/apps/web/src/app/(app)/explore/explore-client.tsx
index 5beb846..2662ddc 100644
--- a/apps/web/src/app/(app)/explore/explore-client.tsx
+++ b/apps/web/src/app/(app)/explore/explore-client.tsx
@@ -18,7 +18,7 @@ import { EventFilters } from "~/components/events/event-filters";
import { PageHeading, PageShell, SectionHeading } from "~/components/layout/page-shell";
import { Button } from "~/components/ui/button";
import { buildGCalUrl } from "~/lib/calendar";
-import { formatRelativeDay } from "~/lib/date-format";
+import { formatLongDate, formatRelativeDay } from "~/lib/date-format";
interface ExploreClientProps {
initialEvents: FeedEvent[];
@@ -31,12 +31,7 @@ interface ExploreClientProps {
}
function getTodayString() {
- return new Date().toLocaleDateString("en-US", {
- weekday: "long",
- day: "numeric",
- month: "long",
- year: "numeric",
- });
+ return formatLongDate(new Date());
}
export function ExploreClient({
diff --git a/apps/web/src/app/(app)/map/_components/event-list-panel.tsx b/apps/web/src/app/(app)/map/_components/event-list-panel.tsx
index 04f0dd8..ca89559 100644
--- a/apps/web/src/app/(app)/map/_components/event-list-panel.tsx
+++ b/apps/web/src/app/(app)/map/_components/event-list-panel.tsx
@@ -5,6 +5,7 @@ import type { MapEvent } from "~/actions/map";
import { EmptyState } from "~/components/common/states";
import { EventCard } from "~/components/events/event-card";
import { Button } from "~/components/ui/button";
+import { formatEventDateTime } from "~/lib/date-format";
import { cn } from "~/lib/utils";
interface EventListPanelProps {
@@ -71,13 +72,7 @@ export function EventListPanel({
id={event.id}
title={event.title}
orgName={event.orgName}
- datetime={new Date(event.rawDatetime).toLocaleString("en-US", {
- weekday: "short",
- month: "short",
- day: "numeric",
- hour: "numeric",
- minute: "2-digit",
- })}
+ datetime={formatEventDateTime(new Date(event.rawDatetime))}
location={event.locationName}
tags={event.tags}
friendsAttending={event.friendsAttending}
diff --git a/apps/web/src/app/(app)/map/_lib/map-helpers.ts b/apps/web/src/app/(app)/map/_lib/map-helpers.ts
index d3bdcff..bf2ad5b 100644
--- a/apps/web/src/app/(app)/map/_lib/map-helpers.ts
+++ b/apps/web/src/app/(app)/map/_lib/map-helpers.ts
@@ -1,3 +1,10 @@
+import {
+ addDaysToDateKey,
+ formatTime,
+ formatWeekdayTime,
+ toZonedDateKey,
+ zonedDayDiff,
+} from "~/lib/date-format";
import type { RelativeLabel, TimeGroup } from "./map-types";
/* ═══ Tag colors ═══ */
@@ -36,22 +43,21 @@ export function getEventColor(tags: string[]) {
}
/* ═══ Time helpers ═══ */
+/*
+ * Day comparisons use Princeton calendar days (America/New_York). The old
+ * `setHours(0, 0, 0, 0)` bucketing used the viewer's local zone, so the same
+ * event could read "Tomorrow" on one laptop and "Later Today" on another.
+ */
export function getTimeGroup(rawDatetime: string): TimeGroup {
- const eventTime = new Date(rawDatetime).getTime();
- const now = Date.now();
- const diffMs = eventTime - now;
+ const eventDate = new Date(rawDatetime);
+ const diffMs = eventDate.getTime() - Date.now();
const diffH = diffMs / (1000 * 60 * 60);
if (diffMs < 0 && diffMs > -2 * 60 * 60 * 1000) return "now";
if (diffH <= 0) return "later-today";
if (diffH <= 3) return "soon";
- const eventDay = new Date(rawDatetime);
- const today = new Date();
- eventDay.setHours(0, 0, 0, 0);
- today.setHours(0, 0, 0, 0);
- const dayDiff = Math.round((eventDay.getTime() - today.getTime()) / (1000 * 60 * 60 * 24));
-
+ const dayDiff = zonedDayDiff(eventDate);
if (dayDiff === 0) return "later-today";
if (dayDiff === 1) return "tomorrow";
return "this-week";
@@ -59,8 +65,7 @@ export function getTimeGroup(rawDatetime: string): TimeGroup {
export function getRelativeLabel(rawDatetime: string): RelativeLabel {
const eventTime = new Date(rawDatetime);
- const now = new Date();
- const diffMs = eventTime.getTime() - now.getTime();
+ const diffMs = eventTime.getTime() - Date.now();
const diffMin = Math.round(diffMs / (1000 * 60));
const diffH = Math.round(diffMs / (1000 * 60 * 60));
const group = getTimeGroup(rawDatetime);
@@ -69,32 +74,10 @@ export function getRelativeLabel(rawDatetime: string): RelativeLabel {
if (diffMin > 0 && diffMin < 60) return { label: `${diffMin}m`, urgency: "soon" };
if (diffH > 0 && diffH <= 3) return { label: `${diffH}h`, urgency: "soon" };
- const eventDay = new Date(rawDatetime);
- const today = new Date();
- eventDay.setHours(0, 0, 0, 0);
- today.setHours(0, 0, 0, 0);
- const dayDiff = Math.round((eventDay.getTime() - today.getTime()) / (1000 * 60 * 60 * 24));
-
- if (dayDiff === 0) {
- return {
- label: eventTime.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" }),
- urgency: "later-today",
- };
- }
- if (dayDiff === 1) {
- return {
- label: `Tmrw ${eventTime.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" })}`,
- urgency: "tomorrow",
- };
- }
- return {
- label: eventTime.toLocaleDateString("en-US", {
- weekday: "short",
- hour: "numeric",
- minute: "2-digit",
- }),
- urgency: "this-week",
- };
+ const dayDiff = zonedDayDiff(eventTime);
+ if (dayDiff === 0) return { label: formatTime(eventTime), urgency: "later-today" };
+ if (dayDiff === 1) return { label: `Tmrw ${formatTime(eventTime)}`, urgency: "tomorrow" };
+ return { label: formatWeekdayTime(eventTime), urgency: "this-week" };
}
export const GROUP_LABELS: Record
= {
@@ -116,8 +99,13 @@ export const URGENCY_STYLES: Record
};
/* ═══ Date helpers ═══ */
-export function toDateStr(d: Date): string {
- return d.toISOString().split("T")[0] ?? "";
+/**
+ * Princeton calendar day ("YYYY-MM-DD") an event's ISO timestamp falls on.
+ * Slicing the ISO string gave the UTC date, which moved every event after
+ * 8pm Eastern onto the next day of the timeline.
+ */
+export function eventDateKey(rawDatetime: string): string {
+ return toZonedDateKey(new Date(rawDatetime));
}
export function getTimelineDays(days: number): {
@@ -128,28 +116,18 @@ export function getTimelineDays(days: number): {
isToday: boolean;
isPast: boolean;
}[] {
- const today = new Date();
- today.setHours(0, 0, 0, 0);
- const result: {
- dateStr: string;
- dayName: string;
- dayNum: number;
- monthShort: string;
- isToday: boolean;
- isPast: boolean;
- }[] = [];
- for (let i = 0; i < days; i++) {
- const d = new Date(today);
- d.setDate(d.getDate() + i);
- const dateStr = toDateStr(d);
- result.push({
+ const todayKey = toZonedDateKey(new Date());
+ return Array.from({ length: days }, (_, i) => {
+ const dateStr = addDaysToDateKey(todayKey, i);
+ // Noon UTC on a date is that same calendar date — a safe anchor for labels.
+ const anchor = new Date(`${dateStr}T12:00:00Z`);
+ return {
dateStr,
- dayName: d.toLocaleDateString("en-US", { weekday: "short" }),
- dayNum: d.getDate(),
- monthShort: d.toLocaleDateString("en-US", { month: "short" }),
+ dayName: anchor.toLocaleDateString("en-US", { timeZone: "UTC", weekday: "short" }),
+ dayNum: anchor.getUTCDate(),
+ monthShort: anchor.toLocaleDateString("en-US", { timeZone: "UTC", month: "short" }),
isToday: i === 0,
isPast: false,
- });
- }
- return result;
+ };
+ });
}
diff --git a/apps/web/src/app/(app)/map/map-client.tsx b/apps/web/src/app/(app)/map/map-client.tsx
index 86b4922..b0ace5d 100644
--- a/apps/web/src/app/(app)/map/map-client.tsx
+++ b/apps/web/src/app/(app)/map/map-client.tsx
@@ -5,7 +5,7 @@ import { useCallback, useMemo, useRef, useState, useTransition } from "react";
import type { MapRef } from "react-map-gl/mapbox";
import type { MapEvent } from "~/actions/map";
import { cn } from "~/lib/utils";
-import { getTimeGroup } from "./_lib/map-helpers";
+import { eventDateKey, getTimeGroup } from "./_lib/map-helpers";
/* Dynamic import for MapView — mapbox-gl accesses `window` at module init */
const MapView = dynamic(
@@ -78,7 +78,7 @@ export function MapClient({ initialEvents }: MapClientProps) {
const filteredEvents = useMemo(() => {
let result = events;
if (selectedDate) {
- result = result.filter((e) => e.rawDatetime.startsWith(selectedDate));
+ result = result.filter((e) => eventDateKey(e.rawDatetime) === selectedDate);
}
if (searchQuery.trim()) {
const q = searchQuery.toLowerCase();
@@ -118,7 +118,7 @@ export function MapClient({ initialEvents }: MapClientProps) {
const eventCountByDate = useMemo(() => {
const counts = new Map();
for (const event of events) {
- const d = event.rawDatetime.slice(0, 10);
+ const d = eventDateKey(event.rawDatetime);
counts.set(d, (counts.get(d) ?? 0) + 1);
}
return counts;
diff --git a/apps/web/src/components/layout/notification-dropdown.tsx b/apps/web/src/components/layout/notification-dropdown.tsx
index 83d860d..477033e 100644
--- a/apps/web/src/components/layout/notification-dropdown.tsx
+++ b/apps/web/src/components/layout/notification-dropdown.tsx
@@ -12,19 +12,9 @@ import {
} from "~/actions/notifications";
import { ErrorState } from "~/components/common/states";
import { Popover, PopoverContent, PopoverTrigger } from "~/components/ui/popover";
+import { formatTimeAgo } from "~/lib/date-format";
import { cn } from "~/lib/utils";
-function formatTimeAgo(isoDate: string) {
- const diff = Date.now() - new Date(isoDate).getTime();
- const minutes = Math.floor(diff / 60000);
- if (minutes < 1) return "just now";
- if (minutes < 60) return `${minutes}m ago`;
- const hours = Math.floor(minutes / 60);
- if (hours < 24) return `${hours}h ago`;
- const days = Math.floor(hours / 24);
- return `${days}d ago`;
-}
-
export function NotificationDropdown() {
const router = useRouter();
const [items, setItems] = useState([]);
@@ -229,7 +219,7 @@ function NotificationRow({
{restText}
- {formatTimeAgo(item.createdAt)}
+ {formatTimeAgo(new Date(item.createdAt))}
diff --git a/apps/web/src/lib/date-format.ts b/apps/web/src/lib/date-format.ts
index 3f16f28..c69a2f1 100644
--- a/apps/web/src/lib/date-format.ts
+++ b/apps/web/src/lib/date-format.ts
@@ -1,4 +1,20 @@
+/**
+ * Date/time helpers for The Forum.
+ *
+ * Every event happens in Princeton, so every date and time is rendered in
+ * America/New_York regardless of where the code runs. Server actions execute
+ * in UTC on the host and browsers can be anywhere (a student abroad, a laptop
+ * still set to home time), so relying on the runtime's local zone put evening
+ * events on the wrong day and showed 6pm talks as 10pm.
+ *
+ * Use these helpers — never bare `toLocaleString()` / `getHours()` — for
+ * anything a user reads or anything that buckets events by calendar day.
+ */
+
+export const EVENT_TIME_ZONE = "America/New_York";
+
const EVENT_DATE_FORMATTER = new Intl.DateTimeFormat("en-US", {
+ timeZone: EVENT_TIME_ZONE,
weekday: "short",
month: "short",
day: "numeric",
@@ -6,10 +22,95 @@ const EVENT_DATE_FORMATTER = new Intl.DateTimeFormat("en-US", {
minute: "2-digit",
});
+const PARTS_FORMATTER = new Intl.DateTimeFormat("en-US", {
+ timeZone: EVENT_TIME_ZONE,
+ year: "numeric",
+ month: "2-digit",
+ day: "2-digit",
+ hour: "2-digit",
+ minute: "2-digit",
+ second: "2-digit",
+ hourCycle: "h23",
+});
+
function partValue(parts: Intl.DateTimeFormatPart[], type: Intl.DateTimeFormatPartTypes) {
return parts.find((part) => part.type === type)?.value ?? "";
}
+/** Wall-clock components of `date` as seen in Princeton. */
+export function getZonedParts(date: Date) {
+ const parts = PARTS_FORMATTER.formatToParts(date);
+ const num = (type: Intl.DateTimeFormatPartTypes) => Number(partValue(parts, type));
+ return {
+ year: num("year"),
+ month: num("month"),
+ day: num("day"),
+ hour: num("hour") % 24,
+ minute: num("minute"),
+ second: num("second"),
+ };
+}
+
+function pad(n: number) {
+ return n.toString().padStart(2, "0");
+}
+
+/** "YYYY-MM-DD" for the Princeton calendar day `date` falls on. */
+export function toZonedDateKey(date: Date) {
+ const { year, month, day } = getZonedParts(date);
+ return `${year}-${pad(month)}-${pad(day)}`;
+}
+
+/** "HH:MM" (24h) Princeton wall-clock time — the value an `
` expects. */
+export function toZonedTimeValue(date: Date) {
+ const { hour, minute } = getZonedParts(date);
+ return `${pad(hour)}:${pad(minute)}`;
+}
+
+/** Shift a "YYYY-MM-DD" key by whole calendar days. */
+export function addDaysToDateKey(key: string, days: number) {
+ const [y, m, d] = key.split("-").map(Number);
+ const utc = new Date(Date.UTC(y ?? 1970, (m ?? 1) - 1, (d ?? 1) + days));
+ return utc.toISOString().slice(0, 10);
+}
+
+/** Whole calendar days between two Princeton dates (b − a). */
+function dateKeyDiff(a: string, b: string) {
+ const toUtc = (key: string) => {
+ const [y, m, d] = key.split("-").map(Number);
+ return Date.UTC(y ?? 1970, (m ?? 1) - 1, d ?? 1);
+ };
+ return Math.round((toUtc(b) - toUtc(a)) / 86_400_000);
+}
+
+/** Calendar-day distance from `now` to `date`, in Princeton. 0 = today, 1 = tomorrow. */
+export function zonedDayDiff(date: Date, now = new Date()) {
+ return dateKeyDiff(toZonedDateKey(now), toZonedDateKey(date));
+}
+
+/** Milliseconds Princeton is offset from UTC at `instant` (e.g. −4h in EDT). */
+function zoneOffsetMs(instant: number) {
+ const p = getZonedParts(new Date(instant));
+ const asUtc = Date.UTC(p.year, p.month - 1, p.day, p.hour, p.minute, p.second);
+ return asUtc - Math.floor(instant / 1000) * 1000;
+}
+
+/**
+ * The instant at which it is `time` ("HH:MM") on `dateKey` ("YYYY-MM-DD") in
+ * Princeton. Used by the event forms so an organizer anywhere in the world who
+ * enters "6:00 PM" gets 6pm Eastern, across DST changes.
+ */
+export function zonedDateTimeToDate(dateKey: string, time: string) {
+ const [y, mo, d] = dateKey.split("-").map(Number);
+ const [h, mi] = time.split(":").map(Number);
+ const guess = Date.UTC(y ?? 1970, (mo ?? 1) - 1, d ?? 1, h ?? 0, mi ?? 0);
+ const first = guess - zoneOffsetMs(guess);
+ // Re-check at the corrected instant in case the guess straddled a DST switch.
+ const second = guess - zoneOffsetMs(first);
+ return new Date(second);
+}
+
+/** "Fri, Mar 3 at 6:00 PM" — the standard event line on cards. */
export function formatEventDateTime(date: Date) {
const parts = EVENT_DATE_FORMATTER.formatToParts(date);
const weekday = partValue(parts, "weekday");
@@ -22,22 +123,88 @@ export function formatEventDateTime(date: Date) {
return `${weekday}, ${month} ${day} at ${hour}:${minute} ${dayPeriod}`;
}
+/** "Monday, September 28, 2026" */
+export function formatLongDate(date: Date) {
+ return date.toLocaleDateString("en-US", {
+ timeZone: EVENT_TIME_ZONE,
+ weekday: "long",
+ month: "long",
+ day: "numeric",
+ year: "numeric",
+ });
+}
+
+/** "Mon, Sep 28, 2026" */
+export function formatMediumDate(date: Date) {
+ return date.toLocaleDateString("en-US", {
+ timeZone: EVENT_TIME_ZONE,
+ weekday: "short",
+ month: "short",
+ day: "numeric",
+ year: "numeric",
+ });
+}
+
+/** "6:00 PM" */
+export function formatTime(date: Date) {
+ return date.toLocaleTimeString("en-US", {
+ timeZone: EVENT_TIME_ZONE,
+ hour: "numeric",
+ minute: "2-digit",
+ });
+}
+
+/** "Mon" */
+export function formatWeekdayShort(date: Date) {
+ return date.toLocaleDateString("en-US", { timeZone: EVENT_TIME_ZONE, weekday: "short" });
+}
+
+/** "Mon 6:00 PM" */
+export function formatWeekdayTime(date: Date) {
+ return date.toLocaleString("en-US", {
+ timeZone: EVENT_TIME_ZONE,
+ weekday: "short",
+ hour: "numeric",
+ minute: "2-digit",
+ });
+}
+
+/** "Sep 28" */
+export function formatMonthDay(date: Date) {
+ return date.toLocaleDateString("en-US", {
+ timeZone: EVENT_TIME_ZONE,
+ month: "short",
+ day: "numeric",
+ });
+}
+
/**
* "today" / "tomorrow" / "on Fri, Mar 3" — for sentences like
* "TigerApps Social is happening tomorrow!".
*
- * Compares calendar days rather than elapsed hours, so an event at 9am
- * tomorrow reads as "tomorrow" even though it's under 24 hours away.
+ * Compares Princeton calendar days rather than elapsed hours, so an event at
+ * 9am tomorrow reads as "tomorrow" even though it's under 24 hours away.
*/
export function formatRelativeDay(date: Date, now = new Date()) {
- const startOf = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
- const days = Math.round((startOf(date) - startOf(now)) / 86_400_000);
+ const days = zonedDayDiff(date, now);
if (days === 0) return "today";
if (days === 1) return "tomorrow";
if (days === -1) return "yesterday";
if (days > 1 && days < 7) {
- return `on ${date.toLocaleDateString("en-US", { weekday: "long" })}`;
+ return `on ${date.toLocaleDateString("en-US", { timeZone: EVENT_TIME_ZONE, weekday: "long" })}`;
}
- return `on ${date.toLocaleDateString("en-US", { month: "short", day: "numeric" })}`;
+ return `on ${formatMonthDay(date)}`;
+}
+
+/** "just now" / "5m ago" / "3h ago" / "2d ago", then a date for anything older than a week. */
+export function formatTimeAgo(date: Date, now = new Date()) {
+ const minutes = Math.floor((now.getTime() - date.getTime()) / 60_000);
+ if (minutes < 1) return "just now";
+ if (minutes < 60) return `${minutes}m ago`;
+ const hours = Math.floor(minutes / 60);
+ if (hours < 24) return `${hours}h ago`;
+ const days = Math.floor(hours / 24);
+ if (days < 7) return `${days}d ago`;
+ return formatMonthDay(date);
}
From d274b449760e8a8bb25992984cea56405db22576 Mon Sep 17 00:00:00 2001
From: DIodide
Date: Mon, 28 Sep 2026 02:38:56 -0400
Subject: [PATCH 14/69] Say friends are going instead of claiming a calendar
add
Friends shown on event cards have RSVP'd; the app never reads anyone's
calendar. Also pluralize the '+ N others' overflow.
---
apps/web/src/components/events/event-card.tsx | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/apps/web/src/components/events/event-card.tsx b/apps/web/src/components/events/event-card.tsx
index 46de7cf..f693c2f 100644
--- a/apps/web/src/components/events/event-card.tsx
+++ b/apps/web/src/components/events/event-card.tsx
@@ -165,6 +165,9 @@ export function EventCard({
const displayedFriendNames = friendsAttending.slice(0, 2).map((friend) => friend.displayName);
const remainingFriends = friendsAttending.length - displayedFriendNames.length;
+ // Friends shown here have RSVP'd — nothing is read from anyone's calendar.
+ const othersLabel = `+ ${remainingFriends} ${remainingFriends === 1 ? "other" : "others"}`;
+ const goingVerb = friendsAttending.length === 1 ? "is going!" : "are going!";
// Track view — IntersectionObserver fires after 1s of visibility
useEffect(() => {
@@ -381,9 +384,9 @@ export function EventCard({
{displayedFriendNames.join(", ")}
{remainingFriends > 0 && (
- + {remainingFriends} other
+ {othersLabel}
)}{" "}
- added this event to their calendar!
+ {goingVerb}
)}
@@ -648,9 +651,9 @@ export function EventCard({
{displayedFriendNames.join(", ")}
- {remainingFriends > 0 && ` + ${remainingFriends} other`}
+ {remainingFriends > 0 && ` ${othersLabel}`}
{" "}
- added this event to their calendar!
+ {goingVerb}
))}
From 0ed6f8a8f9738e602f5fead87888146e5c3d6b87 Mon Sep 17 00:00:00 2001
From: DIodide
Date: Mon, 28 Sep 2026 02:39:07 -0400
Subject: [PATCH 15/69] Explore friends rail: 'is going to' instead of 'added
to their calendar'
Copy-only change in explore-client.tsx, kept in its own commit so it can
be dropped cleanly if it conflicts with the data-layer work there.
---
apps/web/src/app/(app)/explore/explore-client.tsx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/apps/web/src/app/(app)/explore/explore-client.tsx b/apps/web/src/app/(app)/explore/explore-client.tsx
index 2662ddc..d598aee 100644
--- a/apps/web/src/app/(app)/explore/explore-client.tsx
+++ b/apps/web/src/app/(app)/explore/explore-client.tsx
@@ -341,7 +341,7 @@ export function ExploreClient({
Find My Friends
{friendsEvents.length === 0 ? (
- None of your friends have added an event yet.
+ None of your friends have RSVP'd to an event yet.
) : (
/* Hairline dividers instead of gaps — keeps a longer list calm. */
@@ -370,8 +370,8 @@ export function ExploreClient({
{friend?.displayName.split(" ")[0] ?? "A friend"}
{" "}
- added {event.title} {" "}
- to their calendar.
+ is going to{" "}
+ {event.title} .
{event.location} @ {event.datetime}
From 36a806216061dc0fabe3c66ba21ff5dc2d1331dd Mon Sep 17 00:00:00 2001
From: DIodide
Date: Mon, 28 Sep 2026 02:40:35 -0400
Subject: [PATCH 16/69] Fix Explore ranking from PR #38: one stable order, then
paginate
Addresses the open review points on PR #38:
- Fix the missing closing brace in diversifyByOrg (compile error).
- Return the finalized, paginated page instead of the full enriched list.
- Apply scoring, the org-diversity cap and the soon-event quota to the whole
candidate list in a single greedy pass (finalizeFeedOrder), then slice.
Soon injection only picks events whose org is under the cap.
- Org cap is now a sliding window (max 3 per org in any 20 positions)
rather than deferring over-cap events to the very end.
- Candidate pool: all published upcoming events within a 45-day horizon
(cap 1000), plus a personalised second stage (followed orgs, friend
RSVPs, interest tags) only if the first stage saturates.
- Enrichment is batched with one inArray query per signal across the
candidate set; attendee rosters are loaded for the returned page only.
- Responses carry asOf; later pages reuse it as 'now' so every page is a
slice of the same ranking.
Ranking logic moves to lib/feed-ranking.ts (pure) and lib/feed.ts (data),
getFeedEvents validates its params with zod, and docs/ranking.md is updated.
Co-authored-by: Rohan Matta
---
apps/web/src/actions/events.ts | 521 ++----------------
.../src/app/(app)/explore/explore-client.tsx | 67 +++
apps/web/src/app/(app)/explore/page.tsx | 1 +
apps/web/src/lib/feed-ranking.ts | 244 ++++++++
apps/web/src/lib/feed.ts | 397 +++++++++++++
apps/web/src/lib/social-graph.ts | 21 +
apps/web/src/lib/sql-helpers.ts | 12 +
apps/web/src/lib/validation.ts | 25 +
docs/ranking.md | 156 +++---
9 files changed, 896 insertions(+), 548 deletions(-)
create mode 100644 apps/web/src/lib/feed-ranking.ts
create mode 100644 apps/web/src/lib/feed.ts
create mode 100644 apps/web/src/lib/social-graph.ts
create mode 100644 apps/web/src/lib/sql-helpers.ts
create mode 100644 apps/web/src/lib/validation.ts
diff --git a/apps/web/src/actions/events.ts b/apps/web/src/actions/events.ts
index c619deb..178234d 100644
--- a/apps/web/src/actions/events.ts
+++ b/apps/web/src/actions/events.ts
@@ -10,10 +10,7 @@ import {
eventTags,
friendships,
gt,
- ilike,
inArray,
- interactions,
- lt,
ne,
notifications,
or,
@@ -23,12 +20,15 @@ import {
rsvps,
savedEvents,
sql,
- userInterests,
users,
} from "@the-forum/database";
import { revalidatePath } from "next/cache";
+import { z } from "zod";
import { auth } from "~/auth";
import { formatEventDateTime } from "~/lib/date-format";
+import { type FeedPage, loadRankedFeed } from "~/lib/feed";
+import { loadFriendIds } from "~/lib/social-graph";
+import { eventTagSchema, orgCategorySchema, parseInput } from "~/lib/validation";
export interface FeedEvent {
id: string;
@@ -55,83 +55,6 @@ export interface FeedEvent {
isSaved: boolean;
}
-// Default lookahead when no `dateRange` filter is given, rounded up to end
-// of day. A calendar-distance bound, not a row count, so it never depends
-// on how many other events happen to be scheduled sooner. See docs/ranking.md.
-const CANDIDATE_HORIZON_DAYS = 14;
-
-// Defensive-only cap on result size within the horizon — not a ranking
-// boundary, and not expected to bind at realistic campus-event scale.
-const CANDIDATE_POOL_SAFETY_VALVE = 5000;
-
-// An event is "soon" if it's within this many days. At least SOON_QUOTA
-// such events always land within the first SOON_INJECTION_WINDOW positions
-// of the feed, even if their score is weak.
-const SOON_WINDOW_DAYS = 1;
-const SOON_QUOTA = 3;
-
-// Fixed window, independent of the request's `limit` — so the same
-// underlying order results no matter what page size a given call uses.
-const SOON_INJECTION_WINDOW = 20;
-
-// Max events from one org before the rest get pushed later in the ranking.
-const ORG_DIVERSITY_CAP = 3;
-
-// Org affinity when you've RSVP'd to the org before but don't follow/belong
-// to it (full affinity is 1.0).
-const ORG_PAST_INTERACTION_AFFINITY = 0.5;
-
-// View count treated as "maximally popular" (log-scaled, caps at 1.0).
-const POPULARITY_VIEW_CAP = 50;
-const POPULARITY_WEIGHT = 0.5;
-
-// Small per-event nudge, seeded per user-per-day (not per request) so it
-// varies the feed over time without ever reshuffling on refresh.
-const RANDOM_WEIGHT = 0.5;
-
-// Deterministic pseudo-random value in [0, 1) for a seed string.
-function seededRandom(seed: string): number {
- let hash = 0;
- for (let i = 0; i < seed.length; i++) {
- hash = (hash << 5) - hash + seed.charCodeAt(i);
- hash |= 0;
- }
- return (hash >>> 0) / 0xffffffff;
-}
-
-function diversifyByOrg(list: T[], cap: number): T[] {
- const counts = new Map();
- const primary: T[] = [];
- const deferred: T[] = [];
- for (const item of list) {
- if (!item.orgId) {
- primary.push(item);
- continue;
- }
- const count = counts.get(item.orgId) ?? 0;
- if (count < cap) {
- counts.set(item.orgId, count + 1);
- primary.push(item);
- } else {
- deferred.push(item);
- }
- }
- return [...primary, ...deferred];
-/** Accepted friendships are stored one-directional, so both columns are read. */
-async function loadFriendIds(userId: string): Promise {
- const [outgoing, incoming] = await Promise.all([
- db
- .select({ friendId: friendships.friendId })
- .from(friendships)
- .where(and(eq(friendships.userId, userId), eq(friendships.status, "accepted"))),
- db
- .select({ friendId: friendships.userId })
- .from(friendships)
- .where(and(eq(friendships.friendId, userId), eq(friendships.status, "accepted"))),
- ]);
- return [...outgoing, ...incoming].map((r) => r.friendId);
-}
-
interface EventEnrichment {
tags: Map;
attendees: Map>;
@@ -221,7 +144,19 @@ async function loadEventEnrichment(
return result;
}
-export async function getFeedEvents(params?: {
+const feedParamsSchema = z.object({
+ search: z.string().trim().max(200).optional(),
+ tags: z.array(eventTagSchema).max(eventTagSchema.options.length).optional(),
+ orgCategory: orgCategorySchema.optional(),
+ locationId: z.string().max(100).optional(),
+ dateRange: z.enum(["today", "week", "month"]).optional(),
+ limit: z.number().int().min(1).max(50).default(20),
+ offset: z.number().int().min(0).max(5000).default(0),
+ asOf: z.iso.datetime().optional(),
+});
+
+/** Loosely typed on purpose — the schema above is what actually validates it. */
+export interface FeedParams {
search?: string;
tags?: string[];
orgCategory?: string;
@@ -229,409 +164,33 @@ export async function getFeedEvents(params?: {
dateRange?: "today" | "week" | "month";
limit?: number;
offset?: number;
-}): Promise<{ events: FeedEvent[]; total: number }> {
+ asOf?: string;
+}
+
+/**
+ * One page of the ranked Explore feed. Ranking, org-diversity and the
+ * soon-event quota are applied to the whole candidate list before paginating;
+ * see `~/lib/feed.ts` and docs/ranking.md.
+ *
+ * Pass the returned `asOf` back with the next `offset` so later pages are
+ * slices of the same ranking.
+ */
+export async function getFeedEvents(params?: FeedParams): Promise {
const session = await auth();
if (!session?.user?.id) throw new Error("Unauthorized");
- const userId = session.user.id;
- const limit = params?.limit ?? 20;
- const offset = params?.offset ?? 0;
-
- // Get user's interests for scoring
- const myInterests = await db
- .select({ tag: userInterests.tag })
- .from(userInterests)
- .where(eq(userInterests.userId, userId));
- const myInterestTags = myInterests.map((i) => i.tag);
-
- // Get user's friend IDs
- const friendRows = await db
- .select({ friendId: friendships.friendId })
- .from(friendships)
- .where(and(eq(friendships.userId, userId), eq(friendships.status, "accepted")));
- const reverseFriendRows = await db
- .select({ friendId: friendships.userId })
- .from(friendships)
- .where(and(eq(friendships.friendId, userId), eq(friendships.status, "accepted")));
- const friendIds = [
- ...friendRows.map((f) => f.friendId),
- ...reverseFriendRows.map((f) => f.friendId),
- ];
-
- // Get orgs the user follows or belongs to, for the org-affinity signal
- const followedOrgRows = await db
- .select({ orgId: orgFollowers.orgId })
- .from(orgFollowers)
- .where(eq(orgFollowers.userId, userId));
- const memberOrgRows = await db
- .select({ orgId: orgMembers.orgId })
- .from(orgMembers)
- .where(eq(orgMembers.userId, userId));
- const myOrgIds = new Set([
- ...followedOrgRows.map((o) => o.orgId),
- ...memberOrgRows.map((o) => o.orgId),
- ]);
-
- // Orgs the user has RSVP'd to before but doesn't follow/belong to — a
- // weaker org-affinity signal than myOrgIds.
- const interactedOrgRows = await db
- .select({ orgId: events.orgId })
- .from(rsvps)
- .innerJoin(events, eq(rsvps.eventId, events.id))
- .where(eq(rsvps.userId, userId));
- const interactedOrgIds = new Set(
- interactedOrgRows.map((r) => r.orgId).filter((id): id is string => id !== null),
- );
-
- // Day string (UTC) that seeds the random nudge — flips once a day.
- const today = new Date().toISOString().slice(0, 10);
-
- // Build base query conditions — only show published events in the feed
- const conditions = [gt(events.datetime, new Date()), eq(events.status, "published")];
-
- if (params?.search) {
- const searchCondition = or(
- ilike(events.title, `%${params.search}%`),
- ilike(events.description, `%${params.search}%`),
- );
-
- if (searchCondition) {
- conditions.push(searchCondition);
- }
- }
-
- if (params?.tags && params.tags.length > 0) {
- const typedTags = params.tags as (typeof eventTags.$inferSelect.tag)[];
- const eventsWithTags = db
- .select({ eventId: eventTags.eventId })
- .from(eventTags)
- .where(inArray(eventTags.tag, typedTags));
- conditions.push(inArray(events.id, eventsWithTags));
- }
-
- if (params?.orgCategory) {
- const orgsInCategory = db
- .select({ id: organizations.id })
- .from(organizations)
- .where(
- eq(
- organizations.category,
- params.orgCategory as typeof organizations.$inferSelect.category,
- ),
- );
- conditions.push(inArray(events.orgId, orgsInCategory));
- }
-
- if (params?.locationId) {
- conditions.push(eq(events.locationId, params.locationId));
- }
-
- // No explicit dateRange filter defaults to the candidate horizon, so
- // there's one date-bounding path instead of a separate "no filter"
- // branch — see docs/ranking.md.
- const now = new Date();
- let dateRangeEnd: Date;
- if (params?.dateRange === "today") {
- dateRangeEnd = new Date(now);
- dateRangeEnd.setHours(23, 59, 59, 999);
- } else if (params?.dateRange === "week") {
- dateRangeEnd = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);
- } else if (params?.dateRange === "month") {
- dateRangeEnd = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000);
- } else {
- dateRangeEnd = new Date(now);
- dateRangeEnd.setDate(dateRangeEnd.getDate() + CANDIDATE_HORIZON_DAYS);
- dateRangeEnd.setHours(23, 59, 59, 999);
- }
- conditions.push(lt(events.datetime, dateRangeEnd));
-
- // Score every candidate within the horizon, not just the requested page —
- // batched enrichment below keeps this cheap regardless of pool size. See
- // docs/ranking.md.
- const rawEvents = await db
- .select({
- id: events.id,
- title: events.title,
- description: events.description,
- datetime: events.datetime,
- flyerUrl: events.flyerUrl,
- locationName: campusLocations.name,
- orgId: events.orgId,
- orgName: organizations.name,
- createdAt: events.createdAt,
- })
- .from(events)
- .leftJoin(campusLocations, eq(events.locationId, campusLocations.id))
- .leftJoin(organizations, eq(events.orgId, organizations.id))
- .where(and(...conditions))
- .orderBy(events.datetime)
- .limit(CANDIDATE_POOL_SAFETY_VALVE);
-
- if (rawEvents.length === 0) {
- return { events: [], total: 0 };
- }
-
- // Matches exactly what was fetched, so it's always consistent with what
- // offset/limit can reach — unlike a separate unbounded COUNT(*).
- const total = rawEvents.length;
-
- if (rawEvents.length === CANDIDATE_POOL_SAFETY_VALVE) {
- console.warn(
- `getFeedEvents: candidate pool hit CANDIDATE_POOL_SAFETY_VALVE (${CANDIDATE_POOL_SAFETY_VALVE}); total may be an undercount.`,
- );
- }
-
- const candidateIds = rawEvents.map((e) => e.id);
-
- // Batch every per-candidate lookup into one query each, instead of one
- // query per candidate. Grouped in memory afterward by eventId/itemId.
- const [tagRows, rsvpCountRows, viewCountRows, friendRsvpRows, userRsvpRows, userSaveRows] =
- await Promise.all([
- db
- .select({ eventId: eventTags.eventId, tag: eventTags.tag })
- .from(eventTags)
- .where(inArray(eventTags.eventId, candidateIds)),
-
- db
- .select({ eventId: rsvps.eventId, count: sql`count(*)::int` })
- .from(rsvps)
- .where(inArray(rsvps.eventId, candidateIds))
- .groupBy(rsvps.eventId),
-
- db
- .select({ eventId: interactions.itemId, count: sql`count(*)::int` })
- .from(interactions)
- .where(
- and(
- inArray(interactions.itemId, candidateIds),
- eq(interactions.itemType, "event"),
- eq(interactions.interactionType, "view"),
- ),
- )
- .groupBy(interactions.itemId),
-
- friendIds.length === 0
- ? []
- : db
- .select({
- eventId: rsvps.eventId,
- id: users.id,
- displayName: users.displayName,
- avatarUrl: users.avatarUrl,
- })
- .from(rsvps)
- .innerJoin(users, eq(rsvps.userId, users.id))
- .where(and(inArray(rsvps.eventId, candidateIds), inArray(rsvps.userId, friendIds))),
-
- db
- .select({ eventId: rsvps.eventId })
- .from(rsvps)
- .where(and(eq(rsvps.userId, userId), inArray(rsvps.eventId, candidateIds))),
-
- db
- .select({ eventId: savedEvents.eventId })
- .from(savedEvents)
- .where(and(eq(savedEvents.userId, userId), inArray(savedEvents.eventId, candidateIds))),
- ]);
-
- const tagsByEvent = new Map();
- for (const row of tagRows) {
- const list = tagsByEvent.get(row.eventId);
- if (list) list.push(row.tag);
- else tagsByEvent.set(row.eventId, [row.tag]);
- }
-
- const rsvpCountByEvent = new Map(rsvpCountRows.map((r) => [r.eventId, r.count]));
- const viewCountByEvent = new Map(viewCountRows.map((r) => [r.eventId, r.count]));
-
- const friendsByEvent = new Map<
- string,
- { id: string; displayName: string; avatarUrl: string | null }[]
- >();
- for (const row of friendRsvpRows) {
- const entry = { id: row.id, displayName: row.displayName, avatarUrl: row.avatarUrl };
- const list = friendsByEvent.get(row.eventId);
- if (list) list.push(entry);
- else friendsByEvent.set(row.eventId, [entry]);
- }
-
- const userRsvpEventIds = new Set(userRsvpRows.map((r) => r.eventId));
- const userSaveEventIds = new Set(userSaveRows.map((r) => r.eventId));
-
- // Enrich each event and compute its weighted relevance score. Full
- // formula breakdown: docs/ranking.md.
- const enriched: (FeedEvent & { score: number; _rawDatetime: Date })[] = rawEvents.map((event) => {
- const tagNames = tagsByEvent.get(event.id) ?? [];
- const rsvpCount = rsvpCountByEvent.get(event.id) ?? 0;
- const viewCount = viewCountByEvent.get(event.id) ?? 0;
- const friendsAttending = friendsByEvent.get(event.id) ?? [];
-
- // Fraction of this event's tags that match your interests.
- const matchedTags = tagNames.filter((t) => myInterestTags.includes(t)).length;
- const interestRelevance =
- myInterestTags.length === 0 ? 0.5 : tagNames.length === 0 ? 0 : matchedTags / tagNames.length;
-
- const now = Date.now();
- const eventTime = event.datetime.getTime();
- const daysUntil = (eventTime - now) / (1000 * 60 * 60 * 24);
- // Half-life decay: 1.0 right now, halving every 4 days out.
- const timeProximity = 2 ** (-daysUntil / 4);
-
- const friendRsvpScore = Math.min(1.0, friendsAttending.length / 3.0);
-
- // Full affinity if you follow/belong to the org, weaker if you've
- // just RSVP'd to it before.
- const orgAffinity = !event.orgId
- ? 0
- : myOrgIds.has(event.orgId)
- ? 1.0
- : interactedOrgIds.has(event.orgId)
- ? ORG_PAST_INTERACTION_AFFINITY
- : 0;
-
- const hoursSinceCreated = (now - event.createdAt.getTime()) / (1000 * 60 * 60);
- const recencyBoost = hoursSinceCreated <= 24 ? 1.0 : hoursSinceCreated <= 72 ? 0.5 : 0.0;
-
- // Log-scaled view count, capped at 1.0 around POPULARITY_VIEW_CAP.
- const popularityScore = Math.min(
- 1.0,
- Math.log(viewCount + 1) / Math.log(POPULARITY_VIEW_CAP + 1),
- );
-
- // Deterministic per user-per-day-per-event nudge — see RANDOM_WEIGHT.
- const randomNudge = seededRandom(`${userId}:${today}:${event.id}`);
-
- const score =
- 3.0 * interestRelevance +
- 2.0 * timeProximity +
- 4.0 * friendRsvpScore +
- 1.0 * orgAffinity +
- 1.0 * recencyBoost +
- POPULARITY_WEIGHT * popularityScore +
- RANDOM_WEIGHT * randomNudge;
-
- return {
- id: event.id,
- title: event.title,
- description: event.description,
- orgId: event.orgId,
- orgName: event.orgName,
- datetime: formatEventDateTime(event.datetime),
- location: event.locationName ?? "TBD",
- tags: tagNames,
- flyerUrl: event.flyerUrl,
- rsvpCount,
- friendsAttending,
- isRsvped: userRsvpEventIds.has(event.id),
- isSaved: userSaveEventIds.has(event.id),
- score,
- _rawDatetime: event.datetime,
- };
- });
-
- // Sort by score descending; ties break by soonest first, so refreshing
- // with no new data never reorders the feed.
- /*
- * Attendees for the "N attending" control on each card.
- *
- * One query for the whole page rather than one per event — the enrichment
- * above already issues several queries per event, and adding another to that
- * loop is what pushes the connection pool over on a full feed.
- */
- const feedIds = enriched.map((e) => e.id);
- const attendeeRows =
- feedIds.length === 0
- ? []
- : await db
- .select({
- eventId: rsvps.eventId,
- id: users.id,
- displayName: users.displayName,
- avatarUrl: users.avatarUrl,
- })
- .from(rsvps)
- .innerJoin(users, eq(rsvps.userId, users.id))
- .where(inArray(rsvps.eventId, feedIds));
-
- const attendeesByEvent = new Map();
- for (const { eventId, ...person } of attendeeRows) {
- const list = attendeesByEvent.get(eventId);
- if (list) list.push(person);
- else attendeesByEvent.set(eventId, [person]);
- }
-
- // Sort by score descending; ties break by soonest event first, so
- // refreshing Explore with no new data never reorders the feed.
- enriched.sort((a, b) => {
- if (b.score !== a.score) return b.score - a.score;
- return a._rawDatetime.getTime() - b._rawDatetime.getTime();
+ const input = parseInput(feedParamsSchema, params ?? {});
+
+ return loadRankedFeed(session.user.id, {
+ search: input.search || undefined,
+ tags: input.tags,
+ orgCategory: input.orgCategory,
+ locationId: input.locationId,
+ dateRange: input.dateRange,
+ limit: input.limit,
+ offset: input.offset,
+ asOf: input.asOf ? new Date(input.asOf) : undefined,
});
-
- // Cap events per org
- const ranked = diversifyByOrg(enriched, ORG_DIVERSITY_CAP);
-
- // Guarantee SOON_QUOTA imminent events land within the first
- // SOON_INJECTION_WINDOW positions, without exceeding ORG_DIVERSITY_CAP
- // there. This finalizes ONE stable order over the whole pool before
- // pagination, so every page is a plain slice of the same array — no
- // event can be duplicated or dropped across pages. See docs/ranking.md.
- const isSoon = (e: (typeof ranked)[number]) =>
- (e._rawDatetime.getTime() - Date.now()) / (1000 * 60 * 60 * 24) <= SOON_WINDOW_DAYS;
-
- const windowSize = Math.min(SOON_INJECTION_WINDOW, ranked.length);
- const front = ranked.slice(0, windowSize);
- const tail = ranked.slice(windowSize);
-
- let finalOrder = ranked;
- const soonInFront = front.filter(isSoon).length;
-
- if (soonInFront < SOON_QUOTA) {
- const frontIds = new Set(front.map((e) => e.id));
-
- // Org counts already in front — a candidate whose org is already at
- // the cap is skipped, so injection can't push an org past it.
- const frontOrgCounts = new Map();
- for (const e of front) {
- if (e.orgId) frontOrgCounts.set(e.orgId, (frontOrgCounts.get(e.orgId) ?? 0) + 1);
- }
-
- const missingSoon: (typeof ranked)[number][] = [];
- for (const e of tail) {
- if (missingSoon.length >= SOON_QUOTA - soonInFront) break;
- if (!isSoon(e) || frontIds.has(e.id)) continue;
- if (e.orgId) {
- const count = frontOrgCounts.get(e.orgId) ?? 0;
- if (count >= ORG_DIVERSITY_CAP) continue;
- frontOrgCounts.set(e.orgId, count + 1);
- }
- missingSoon.push(e);
- }
-
- if (missingSoon.length > 0) {
- const missingIds = new Set(missingSoon.map((e) => e.id));
- const mergedFront = [...front];
- const stride = Math.max(1, Math.floor(mergedFront.length / (missingSoon.length + 1)));
- missingSoon.forEach((event, i) => {
- mergedFront.splice(Math.min(mergedFront.length, stride * (i + 1)), 0, event);
- });
- finalOrder = [...mergedFront, ...tail.filter((e) => !missingIds.has(e.id))];
- }
- }
-
- // finalOrder.length === ranked.length always — pure reorder, nothing
- // added or dropped. Pagination is a plain slice of this one stable order.
- const page = finalOrder.slice(offset, offset + limit);
-
- return {
- events: enriched.map(({ score: _score, _rawDatetime, ...event }) => ({
- ...event,
- // Carried through so the feed card can build its "+ Calendar" link; the
- // sort key was being dropped here and the button never rendered.
- rawDatetime: _rawDatetime.toISOString(),
- attendees: attendeesByEvent.get(event.id) ?? [],
- })),
- total,
- };
}
/** The attendee shape shared by the feed, the detail page and `toggleRsvp`. */
diff --git a/apps/web/src/app/(app)/explore/explore-client.tsx b/apps/web/src/app/(app)/explore/explore-client.tsx
index 5beb846..1de879b 100644
--- a/apps/web/src/app/(app)/explore/explore-client.tsx
+++ b/apps/web/src/app/(app)/explore/explore-client.tsx
@@ -23,6 +23,8 @@ import { formatRelativeDay } from "~/lib/date-format";
interface ExploreClientProps {
initialEvents: FeedEvent[];
initialTotal: number;
+ /** The instant the first page was ranked at — echoed back so later pages slice the same ranking. */
+ initialAsOf: string;
savedEvents: FeedEvent[];
friendsEvents: FriendsEvent[];
initialSearch?: string;
@@ -42,6 +44,7 @@ function getTodayString() {
export function ExploreClient({
initialEvents,
initialTotal,
+ initialAsOf,
savedEvents,
friendsEvents,
initialSearch = "",
@@ -60,6 +63,14 @@ export function ExploreClient({
* capped the message at "20 events match" no matter how many there were.
*/
const [total, setTotal] = useState(initialTotal);
+ /*
+ * Pagination. `nextOffset` counts rows the server has handed us (not
+ * `events.length`, which is after de-duplication), and `asOf` pins later
+ * pages to the ranking page 1 came from.
+ */
+ const [nextOffset, setNextOffset] = useState(initialEvents.length);
+ const [asOf, setAsOf] = useState(initialAsOf);
+ const [isLoadingMore, setIsLoadingMore] = useState(false);
const [activeFilters, setActiveFilters] = useState([]);
/*
* Hidden events stay in the list as collapsed stubs rather than being
@@ -77,6 +88,11 @@ export function ExploreClient({
* and without this the slower-but-older response lands last and wins.
*/
const latestRequest = useRef(0);
+ /** Filters + search the current list was fetched with; "Load more" must reuse them. */
+ const currentQuery = useRef<{ filters: string[]; search: string }>({
+ filters: [],
+ search: initialSearch.trim(),
+ });
const firstName = useMemo(() => userName.split(" ")[0] || "there", [userName]);
/** Drop a queued debounced search — it carries whatever filters were active when it was armed. */
@@ -89,6 +105,8 @@ export function ExploreClient({
const refreshEvents = useCallback((filters: string[], search: string) => {
const requestId = ++latestRequest.current;
+ currentQuery.current = { filters, search };
+ setIsLoadingMore(false);
startTransition(async () => {
try {
const result = await getFeedEvents({
@@ -98,6 +116,8 @@ export function ExploreClient({
if (requestId !== latestRequest.current) return;
setEvents(result.events);
setTotal(result.total);
+ setNextOffset(result.events.length);
+ setAsOf(result.asOf);
setLoadError(false);
} catch {
if (requestId !== latestRequest.current) return;
@@ -108,6 +128,41 @@ export function ExploreClient({
});
}, []);
+ /*
+ * Append the next page. Shares `latestRequest` with `refreshEvents`, so a
+ * filter or search change while this is in flight discards the stale page.
+ * Rows already on screen are skipped in case the ranking shifted between
+ * requests (e.g. a friend RSVP'd in the meantime).
+ */
+ const loadMore = useCallback(async () => {
+ const requestId = latestRequest.current;
+ const { filters, search } = currentQuery.current;
+ setIsLoadingMore(true);
+ try {
+ const result = await getFeedEvents({
+ tags: filters.length > 0 ? filters : undefined,
+ search: search || undefined,
+ offset: nextOffset,
+ asOf,
+ });
+ if (requestId !== latestRequest.current) return;
+ setEvents((prev) => {
+ const seen = new Set(prev.map((e) => e.id));
+ return [...prev, ...result.events.filter((e) => !seen.has(e.id))];
+ });
+ setTotal(result.total);
+ setNextOffset(nextOffset + result.events.length);
+ setAsOf(result.asOf);
+ } catch {
+ if (requestId !== latestRequest.current) return;
+ toast.error("Couldn't load more events. Please try again.");
+ } finally {
+ if (requestId === latestRequest.current) setIsLoadingMore(false);
+ }
+ }, [nextOffset, asOf]);
+
+ const hasMore = nextOffset < total;
+
// A queued search outliving the component would fetch for a dead screen.
useEffect(() => cancelPendingSearch, [cancelPendingSearch]);
@@ -328,6 +383,18 @@ export function ExploreClient({
))}
)}
+
+ {hasMore && !loadError && events.length > 0 && (
+
+ {isLoadingMore ? "LOADING…" : "LOAD MORE EVENTS"}
+
+ )}
diff --git a/apps/web/src/app/(app)/explore/page.tsx b/apps/web/src/app/(app)/explore/page.tsx
index 82c711f..40cb922 100644
--- a/apps/web/src/app/(app)/explore/page.tsx
+++ b/apps/web/src/app/(app)/explore/page.tsx
@@ -20,6 +20,7 @@ export default async function ExplorePage({
>> 0) / 0x100000000;
+}
+
+export interface ScoringContext {
+ userId: string;
+ /** The instant the ranking is computed for (see `asOf` in docs/ranking.md). */
+ now: number;
+ interestTags: ReadonlySet;
+ /** Orgs the viewer follows or belongs to. */
+ myOrgIds: ReadonlySet;
+ /** Orgs whose events the viewer has RSVP'd to before. */
+ interactedOrgIds: ReadonlySet;
+}
+
+export interface ScoringInput {
+ id: string;
+ orgId: string | null;
+ startsAt: number;
+ createdAt: number;
+ tags: readonly string[];
+ friendsAttendingCount: number;
+ viewCount: number;
+}
+
+export function scoreEvent(event: ScoringInput, ctx: ScoringContext): number {
+ // Fraction of this event's tags that match your interests. No interests set
+ // yet → neutral 0.5 so a brand-new user still gets a normal feed.
+ const matched = event.tags.filter((t) => ctx.interestTags.has(t)).length;
+ const interestRelevance =
+ ctx.interestTags.size === 0 ? 0.5 : event.tags.length === 0 ? 0 : matched / event.tags.length;
+
+ // Half-life decay: 1.0 right now, halving every TIME_HALF_LIFE_DAYS days out.
+ const daysUntil = Math.max(0, (event.startsAt - ctx.now) / DAY_MS);
+ const timeProximity = 2 ** (-daysUntil / TIME_HALF_LIFE_DAYS);
+
+ const friendRsvpScore = Math.min(1.0, event.friendsAttendingCount / 3.0);
+
+ const orgAffinity = !event.orgId
+ ? 0
+ : ctx.myOrgIds.has(event.orgId)
+ ? 1.0
+ : ctx.interactedOrgIds.has(event.orgId)
+ ? ORG_PAST_INTERACTION_AFFINITY
+ : 0;
+
+ const hoursSinceCreated = (ctx.now - event.createdAt) / HOUR_MS;
+ const recencyBoost = hoursSinceCreated <= 24 ? 1.0 : hoursSinceCreated <= 72 ? 0.5 : 0.0;
+
+ const popularityScore = Math.min(
+ 1.0,
+ Math.log(event.viewCount + 1) / Math.log(POPULARITY_VIEW_CAP + 1),
+ );
+
+ // Seeded per user, per (UTC) day, per event — varies over time but never on refresh.
+ const day = new Date(ctx.now).toISOString().slice(0, 10);
+ const randomNudge = seededRandom(`${ctx.userId}:${day}:${event.id}`);
+
+ return (
+ WEIGHTS.interest * interestRelevance +
+ WEIGHTS.time * timeProximity +
+ WEIGHTS.friends * friendRsvpScore +
+ WEIGHTS.org * orgAffinity +
+ WEIGHTS.recency * recencyBoost +
+ WEIGHTS.popularity * popularityScore +
+ WEIGHTS.random * randomNudge
+ );
+}
+
+/** Score desc, then soonest first, then id — a total order, so sorting is fully deterministic. */
+export function compareScored(
+ a: { id: string; score: number; startsAt: number },
+ b: { id: string; score: number; startsAt: number },
+): number {
+ if (b.score !== a.score) return b.score - a.score;
+ if (a.startsAt !== b.startsAt) return a.startsAt - b.startsAt;
+ return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
+}
+
+export interface OrderingOptions {
+ now: number;
+ orgCap?: number;
+ orgWindow?: number;
+ soonQuota?: number;
+ soonWindowDays?: number;
+ soonInjectionWindow?: number;
+}
+
+/**
+ * Turn a score-sorted list into the final feed order, over the WHOLE candidate
+ * list, before any pagination. Every page is then a plain slice of this one
+ * array, so nothing can be duplicated or skipped across pages.
+ *
+ * Greedy, one position at a time:
+ * - An item is *allowed* at a position if its org has fewer than `orgCap`
+ * items in the previous `orgWindow - 1` positions (events without an org
+ * are never capped).
+ * - Within the first `soonInjectionWindow` positions, the soon quota is
+ * spread evenly (for 3 in 20: by positions 5, 10 and 15). When the quota is
+ * behind schedule, the highest-scoring *allowed* soon event is placed.
+ * Soon injection never breaks the org cap — if no allowed soon event
+ * exists, the quota is simply left unmet.
+ * - Otherwise the highest-scoring allowed item is placed.
+ * - If no remaining item is allowed (the rest of the feed is all from orgs
+ * already at the cap in this window), the highest-scoring remaining item is
+ * placed anyway. That only happens at the tail, where there is nothing else
+ * left to show.
+ *
+ * The result is a permutation of the input: same length, nothing dropped.
+ */
+export function finalizeFeedOrder(
+ sorted: readonly T[],
+ opts: OrderingOptions,
+): T[] {
+ const orgCap = opts.orgCap ?? ORG_DIVERSITY_CAP;
+ const orgWindow = opts.orgWindow ?? ORG_DIVERSITY_WINDOW;
+ const soonQuota = opts.soonQuota ?? SOON_QUOTA;
+ const soonCutoff = opts.now + (opts.soonWindowDays ?? SOON_WINDOW_DAYS) * DAY_MS;
+ const front = Math.min(opts.soonInjectionWindow ?? SOON_INJECTION_WINDOW, sorted.length);
+
+ const isSoon = (item: T) => item.startsAt <= soonCutoff;
+
+ // Target positions for the soon quota, spread evenly through the front window.
+ const soonTargets: number[] = [];
+ for (let k = 0; k < soonQuota; k++) {
+ soonTargets.push(Math.floor(((k + 1) * front) / (soonQuota + 1)));
+ }
+
+ const used = new Array(sorted.length).fill(false);
+ const windowCounts = new Map();
+ const result: T[] = [];
+ let firstUnused = 0;
+ let soonPlaced = 0;
+
+ const allowed = (item: T) => !item.orgId || (windowCounts.get(item.orgId) ?? 0) < orgCap;
+
+ const findFirst = (predicate: (item: T) => boolean): number => {
+ for (let i = firstUnused; i < sorted.length; i++) {
+ const item = sorted[i] as T;
+ if (!used[i] && predicate(item)) return i;
+ }
+ return -1;
+ };
+
+ for (let position = 0; position < sorted.length; position++) {
+ // Slide the org window: drop the item that just fell out of it.
+ if (position >= orgWindow) {
+ const leaving = result[position - orgWindow] as T;
+ if (leaving.orgId) {
+ windowCounts.set(leaving.orgId, (windowCounts.get(leaving.orgId) ?? 1) - 1);
+ }
+ }
+
+ let pick = -1;
+ if (position < front) {
+ const requiredByNow = soonTargets.filter((t) => t <= position).length;
+ if (soonPlaced < requiredByNow) {
+ pick = findFirst((item) => isSoon(item) && allowed(item));
+ }
+ }
+ if (pick === -1) pick = findFirst(allowed);
+ if (pick === -1) pick = findFirst(() => true);
+
+ const item = sorted[pick] as T;
+ used[pick] = true;
+ while (firstUnused < sorted.length && used[firstUnused]) firstUnused++;
+
+ result.push(item);
+ if (position < front && isSoon(item)) soonPlaced++;
+ if (item.orgId) windowCounts.set(item.orgId, (windowCounts.get(item.orgId) ?? 0) + 1);
+ }
+
+ return result;
+}
diff --git a/apps/web/src/lib/feed.ts b/apps/web/src/lib/feed.ts
new file mode 100644
index 0000000..17b196f
--- /dev/null
+++ b/apps/web/src/lib/feed.ts
@@ -0,0 +1,397 @@
+import {
+ events,
+ and,
+ campusLocations,
+ db,
+ eq,
+ eventTags,
+ gt,
+ gte,
+ ilike,
+ inArray,
+ interactions,
+ lt,
+ or,
+ orgFollowers,
+ orgMembers,
+ organizations,
+ rsvps,
+ savedEvents,
+ sql,
+ userInterests,
+ users,
+} from "@the-forum/database";
+import type { FeedEvent } from "~/actions/events";
+import { formatEventDateTime } from "~/lib/date-format";
+import {
+ CANDIDATE_HORIZON_DAYS,
+ CANDIDATE_POOL_CAP,
+ PERSONAL_CANDIDATE_CAP,
+ type ScoringContext,
+ compareScored,
+ finalizeFeedOrder,
+ scoreEvent,
+} from "~/lib/feed-ranking";
+import { loadFriendIds } from "~/lib/social-graph";
+import { containsPattern } from "~/lib/sql-helpers";
+
+type EventTag = typeof eventTags.$inferSelect.tag;
+type OrgCategory = typeof organizations.$inferSelect.category;
+
+export interface FeedQuery {
+ search?: string;
+ tags?: EventTag[];
+ orgCategory?: OrgCategory;
+ locationId?: string;
+ dateRange?: "today" | "week" | "month";
+ limit: number;
+ offset: number;
+ /**
+ * The instant page 1 was ranked at, echoed back by the client for later
+ * pages so every page is a slice of the same ranking. Ignored if missing or
+ * older than ASOF_MAX_AGE_MS.
+ */
+ asOf?: Date;
+}
+
+export interface FeedPage {
+ events: FeedEvent[];
+ /** Size of the ranked candidate list — exactly what offset/limit can reach. */
+ total: number;
+ /** ISO timestamp the ranking was computed for; pass it back as `asOf` for the next page. */
+ asOf: string;
+}
+
+/** A stale `asOf` is ignored, so a tab left open overnight gets a fresh feed. */
+const ASOF_MAX_AGE_MS = 30 * 60 * 1000;
+
+function resolveNow(asOf: Date | undefined): number {
+ const realNow = Date.now();
+ if (!asOf) return realNow;
+ const t = asOf.getTime();
+ if (Number.isNaN(t) || t > realNow + 60_000 || realNow - t > ASOF_MAX_AGE_MS) return realNow;
+ return t;
+}
+
+function dateRangeEnd(now: number, dateRange: FeedQuery["dateRange"]): Date {
+ if (dateRange === "today") {
+ const end = new Date(now);
+ end.setHours(23, 59, 59, 999);
+ return end;
+ }
+ if (dateRange === "week") return new Date(now + 7 * 24 * 60 * 60 * 1000);
+ if (dateRange === "month") return new Date(now + 30 * 24 * 60 * 60 * 1000);
+ const end = new Date(now);
+ end.setDate(end.getDate() + CANDIDATE_HORIZON_DAYS);
+ end.setHours(23, 59, 59, 999);
+ return end;
+}
+
+/**
+ * Rank the Explore feed for `userId` and return one page of it.
+ *
+ * 1. Candidate generation (docs/ranking.md, "Candidate pool").
+ * 2. Batched enrichment of every candidate — one `inArray` query per signal.
+ * 3. Score, sort, then finalize ONE order over the whole list (org cap +
+ * soon-event quota) before slicing out the requested page.
+ * 4. Attendee rosters are loaded for the returned page only.
+ */
+export async function loadRankedFeed(userId: string, query: FeedQuery): Promise {
+ const now = resolveNow(query.asOf);
+ const nowDate = new Date(now);
+ const asOf = nowDate.toISOString();
+
+ // ── Viewer context ──────────────────────────────────────
+ const [interestRows, friendIds, followedOrgRows, memberOrgRows, interactedOrgRows] =
+ await Promise.all([
+ db
+ .select({ tag: userInterests.tag })
+ .from(userInterests)
+ .where(eq(userInterests.userId, userId)),
+ loadFriendIds(userId),
+ db
+ .select({ orgId: orgFollowers.orgId })
+ .from(orgFollowers)
+ .where(eq(orgFollowers.userId, userId)),
+ db.select({ orgId: orgMembers.orgId }).from(orgMembers).where(eq(orgMembers.userId, userId)),
+ // Orgs the user has RSVP'd to before — a weaker org-affinity signal.
+ db
+ .selectDistinct({ orgId: events.orgId })
+ .from(rsvps)
+ .innerJoin(events, eq(rsvps.eventId, events.id))
+ .where(eq(rsvps.userId, userId)),
+ ]);
+
+ const interestTags = interestRows.map((r) => r.tag);
+ const myOrgIds = new Set([
+ ...followedOrgRows.map((o) => o.orgId),
+ ...memberOrgRows.map((o) => o.orgId),
+ ]);
+ const interactedOrgIds = new Set(
+ interactedOrgRows.map((r) => r.orgId).filter((id): id is string => id !== null),
+ );
+
+ // ── Candidate generation ────────────────────────────────
+ const conditions = [
+ gt(events.datetime, nowDate),
+ lt(events.datetime, dateRangeEnd(now, query.dateRange)),
+ eq(events.status, "published"),
+ ];
+
+ if (query.search) {
+ const pattern = containsPattern(query.search);
+ const searchCondition = or(ilike(events.title, pattern), ilike(events.description, pattern));
+ if (searchCondition) conditions.push(searchCondition);
+ }
+ if (query.tags && query.tags.length > 0) {
+ conditions.push(
+ inArray(
+ events.id,
+ db
+ .select({ eventId: eventTags.eventId })
+ .from(eventTags)
+ .where(inArray(eventTags.tag, query.tags)),
+ ),
+ );
+ }
+ if (query.orgCategory) {
+ conditions.push(
+ inArray(
+ events.orgId,
+ db
+ .select({ id: organizations.id })
+ .from(organizations)
+ .where(eq(organizations.category, query.orgCategory)),
+ ),
+ );
+ }
+ if (query.locationId) {
+ conditions.push(eq(events.locationId, query.locationId));
+ }
+
+ const candidateColumns = {
+ id: events.id,
+ title: events.title,
+ description: events.description,
+ datetime: events.datetime,
+ flyerUrl: events.flyerUrl,
+ locationName: campusLocations.name,
+ orgId: events.orgId,
+ orgName: organizations.name,
+ createdAt: events.createdAt,
+ };
+
+ // Stage 1: everything within the horizon, soonest first, up to the cap.
+ const timeOrdered = await db
+ .select(candidateColumns)
+ .from(events)
+ .leftJoin(campusLocations, eq(events.locationId, campusLocations.id))
+ .leftJoin(organizations, eq(events.orgId, organizations.id))
+ .where(and(...conditions))
+ .orderBy(events.datetime, events.id)
+ .limit(CANDIDATE_POOL_CAP);
+
+ let candidates = timeOrdered;
+
+ // Stage 2 (only if stage 1 saturated): events past the stage-1 cutoff that
+ // carry a personal signal, so a dense calendar can't wall them off.
+ const lastTimeOrdered = timeOrdered[timeOrdered.length - 1];
+ if (timeOrdered.length === CANDIDATE_POOL_CAP && lastTimeOrdered) {
+ const personalSignals = [
+ myOrgIds.size > 0 ? inArray(events.orgId, [...myOrgIds]) : undefined,
+ friendIds.length > 0
+ ? inArray(
+ events.id,
+ db
+ .select({ eventId: rsvps.eventId })
+ .from(rsvps)
+ .where(inArray(rsvps.userId, friendIds)),
+ )
+ : undefined,
+ interestTags.length > 0
+ ? inArray(
+ events.id,
+ db
+ .select({ eventId: eventTags.eventId })
+ .from(eventTags)
+ .where(inArray(eventTags.tag, interestTags)),
+ )
+ : undefined,
+ ].filter((c) => c !== undefined);
+
+ if (personalSignals.length > 0) {
+ const personal = await db
+ .select(candidateColumns)
+ .from(events)
+ .leftJoin(campusLocations, eq(events.locationId, campusLocations.id))
+ .leftJoin(organizations, eq(events.orgId, organizations.id))
+ .where(
+ and(
+ ...conditions,
+ gte(events.datetime, lastTimeOrdered.datetime),
+ or(...personalSignals),
+ ),
+ )
+ .orderBy(events.datetime, events.id)
+ .limit(PERSONAL_CANDIDATE_CAP);
+
+ const seen = new Set(timeOrdered.map((e) => e.id));
+ candidates = [...timeOrdered, ...personal.filter((e) => !seen.has(e.id))];
+ }
+
+ console.warn(
+ `loadRankedFeed: time-ordered candidate pool hit CANDIDATE_POOL_CAP (${CANDIDATE_POOL_CAP}); ` +
+ `ranked ${candidates.length} candidates after personalised expansion.`,
+ );
+ }
+
+ if (candidates.length === 0) return { events: [], total: 0, asOf };
+
+ // ── Batched enrichment (one query per signal, whole candidate set) ──
+ const candidateIds = candidates.map((e) => e.id);
+ const [tagRows, rsvpCountRows, viewCountRows, friendRsvpRows, myRsvpRows, mySaveRows] =
+ await Promise.all([
+ db
+ .select({ eventId: eventTags.eventId, tag: eventTags.tag })
+ .from(eventTags)
+ .where(inArray(eventTags.eventId, candidateIds)),
+ db
+ .select({ eventId: rsvps.eventId, count: sql`count(*)::int` })
+ .from(rsvps)
+ .where(inArray(rsvps.eventId, candidateIds))
+ .groupBy(rsvps.eventId),
+ db
+ .select({ eventId: interactions.itemId, count: sql`count(*)::int` })
+ .from(interactions)
+ .where(
+ and(
+ inArray(interactions.itemId, candidateIds),
+ eq(interactions.itemType, "event"),
+ eq(interactions.interactionType, "view"),
+ ),
+ )
+ .groupBy(interactions.itemId),
+ friendIds.length === 0
+ ? Promise.resolve([])
+ : db
+ .select({
+ eventId: rsvps.eventId,
+ id: users.id,
+ displayName: users.displayName,
+ avatarUrl: users.avatarUrl,
+ })
+ .from(rsvps)
+ .innerJoin(users, eq(rsvps.userId, users.id))
+ .where(and(inArray(rsvps.eventId, candidateIds), inArray(rsvps.userId, friendIds))),
+ db
+ .select({ eventId: rsvps.eventId })
+ .from(rsvps)
+ .where(and(eq(rsvps.userId, userId), inArray(rsvps.eventId, candidateIds))),
+ db
+ .select({ eventId: savedEvents.eventId })
+ .from(savedEvents)
+ .where(and(eq(savedEvents.userId, userId), inArray(savedEvents.eventId, candidateIds))),
+ ]);
+
+ const tagsByEvent = groupBy(
+ tagRows,
+ (r) => r.eventId,
+ (r) => r.tag,
+ );
+ const friendsByEvent = groupBy(
+ friendRsvpRows,
+ (r) => r.eventId,
+ (r) => ({ id: r.id, displayName: r.displayName, avatarUrl: r.avatarUrl }),
+ );
+ const rsvpCountByEvent = new Map(rsvpCountRows.map((r) => [r.eventId, r.count]));
+ const viewCountByEvent = new Map(viewCountRows.map((r) => [r.eventId, r.count]));
+ const myRsvps = new Set(myRsvpRows.map((r) => r.eventId));
+ const mySaves = new Set(mySaveRows.map((r) => r.eventId));
+
+ // ── Score, sort, finalize ───────────────────────────────
+ const ctx: ScoringContext = {
+ userId,
+ now,
+ interestTags: new Set(interestTags),
+ myOrgIds,
+ interactedOrgIds,
+ };
+
+ const scored = candidates.map((event) => {
+ const tags = tagsByEvent.get(event.id) ?? [];
+ const friendsAttending = friendsByEvent.get(event.id) ?? [];
+ const startsAt = event.datetime.getTime();
+ const score = scoreEvent(
+ {
+ id: event.id,
+ orgId: event.orgId,
+ startsAt,
+ createdAt: event.createdAt.getTime(),
+ tags,
+ friendsAttendingCount: friendsAttending.length,
+ viewCount: viewCountByEvent.get(event.id) ?? 0,
+ },
+ ctx,
+ );
+ return { event, tags, friendsAttending, startsAt, score, id: event.id, orgId: event.orgId };
+ });
+ scored.sort(compareScored);
+
+ const ordered = finalizeFeedOrder(scored, { now });
+ const page = ordered.slice(query.offset, query.offset + query.limit);
+
+ // ── Attendee rosters: final page only ───────────────────
+ const pageIds = page.map((p) => p.id);
+ const attendeeRows =
+ pageIds.length === 0
+ ? []
+ : await db
+ .select({
+ eventId: rsvps.eventId,
+ id: users.id,
+ displayName: users.displayName,
+ avatarUrl: users.avatarUrl,
+ })
+ .from(rsvps)
+ .innerJoin(users, eq(rsvps.userId, users.id))
+ .where(inArray(rsvps.eventId, pageIds))
+ .orderBy(rsvps.createdAt);
+ const attendeesByEvent = groupBy(
+ attendeeRows,
+ (r) => r.eventId,
+ (r) => ({ id: r.id, displayName: r.displayName, avatarUrl: r.avatarUrl }),
+ );
+
+ return {
+ events: page.map(({ event, tags, friendsAttending }) => ({
+ id: event.id,
+ title: event.title,
+ description: event.description,
+ orgId: event.orgId,
+ orgName: event.orgName,
+ datetime: formatEventDateTime(event.datetime),
+ rawDatetime: event.datetime.toISOString(),
+ location: event.locationName ?? "TBD",
+ tags,
+ flyerUrl: event.flyerUrl,
+ rsvpCount: rsvpCountByEvent.get(event.id) ?? 0,
+ friendsAttending,
+ attendees: attendeesByEvent.get(event.id) ?? [],
+ isRsvped: myRsvps.has(event.id),
+ isSaved: mySaves.has(event.id),
+ })),
+ total: ordered.length,
+ asOf,
+ };
+}
+
+function groupBy(rows: readonly R[], key: (row: R) => string, value: (row: R) => V) {
+ const map = new Map();
+ for (const row of rows) {
+ const k = key(row);
+ const list = map.get(k);
+ if (list) list.push(value(row));
+ else map.set(k, [value(row)]);
+ }
+ return map;
+}
diff --git a/apps/web/src/lib/social-graph.ts b/apps/web/src/lib/social-graph.ts
new file mode 100644
index 0000000..87d434d
--- /dev/null
+++ b/apps/web/src/lib/social-graph.ts
@@ -0,0 +1,21 @@
+import { and, db, eq, friendships } from "@the-forum/database";
+
+/**
+ * Accepted friend ids for a user. Friendships are stored one-directional
+ * (requester → recipient), so both columns are read.
+ *
+ * Server-only: imported by server actions and `~/lib/feed.ts`.
+ */
+export async function loadFriendIds(userId: string): Promise {
+ const [outgoing, incoming] = await Promise.all([
+ db
+ .select({ friendId: friendships.friendId })
+ .from(friendships)
+ .where(and(eq(friendships.userId, userId), eq(friendships.status, "accepted"))),
+ db
+ .select({ friendId: friendships.userId })
+ .from(friendships)
+ .where(and(eq(friendships.friendId, userId), eq(friendships.status, "accepted"))),
+ ]);
+ return [...new Set([...outgoing, ...incoming].map((r) => r.friendId))];
+}
diff --git a/apps/web/src/lib/sql-helpers.ts b/apps/web/src/lib/sql-helpers.ts
new file mode 100644
index 0000000..0148a96
--- /dev/null
+++ b/apps/web/src/lib/sql-helpers.ts
@@ -0,0 +1,12 @@
+/**
+ * Escape `%`, `_` and `\` so user input is matched literally inside an
+ * ILIKE pattern (Postgres' default LIKE escape character is `\`).
+ */
+export function escapeLike(input: string): string {
+ return input.replace(/[\\%_]/g, (ch) => `\\${ch}`);
+}
+
+/** `%input%` with wildcards in the input escaped. */
+export function containsPattern(input: string): string {
+ return `%${escapeLike(input)}%`;
+}
diff --git a/apps/web/src/lib/validation.ts b/apps/web/src/lib/validation.ts
new file mode 100644
index 0000000..dee7c06
--- /dev/null
+++ b/apps/web/src/lib/validation.ts
@@ -0,0 +1,25 @@
+import { eventTagEnum, orgCategoryEnum } from "@the-forum/database";
+import { z } from "zod";
+
+/**
+ * Parse server-action input, throwing a readable Error on failure.
+ *
+ * Server actions are public HTTP endpoints — TypeScript types on their
+ * parameters are not enforced at runtime, so every action runs its input
+ * through a schema before touching the database.
+ */
+export function parseInput(schema: S, input: unknown): z.output {
+ const result = schema.safeParse(input);
+ if (!result.success) {
+ const issue = result.error.issues[0];
+ const path = issue?.path.length ? `${issue.path.join(".")}: ` : "";
+ throw new Error(`Invalid input — ${path}${issue?.message ?? "validation failed"}`);
+ }
+ return result.data;
+}
+
+/** Any 8-4-4-4-12 hex id (Postgres `uuid`). */
+export const idSchema = z.guid();
+
+export const eventTagSchema = z.enum(eventTagEnum.enumValues);
+export const orgCategorySchema = z.enum(orgCategoryEnum.enumValues);
diff --git a/docs/ranking.md b/docs/ranking.md
index 58dbb2d..e9bb89d 100644
--- a/docs/ranking.md
+++ b/docs/ranking.md
@@ -1,6 +1,6 @@
# Explore feed ranking
-This describes how `getFeedEvents()` (`apps/web/src/actions/events.ts`) orders the Explore
+This describes how `getFeedEvents()` (`apps/web/src/actions/events.ts`, implemented in `apps/web/src/lib/feed.ts`) orders the Explore
feed. It's a plain SQL + in-memory weighted score — no ML, no external service.
## The formula, in plain English
@@ -58,7 +58,7 @@ compelling; it doesn't climb further past that.
- **1.0** if you follow or belong to the event's org.
- **0.5** if you don't, but you've RSVP'd to that org's events before
- (`ORG_PAST_INTERACTION_AFFINITY` in `events.ts`) — a weaker signal of interest.
+ (`ORG_PAST_INTERACTION_AFFINITY` in `lib/feed-ranking.ts`) — a weaker signal of interest.
- **0** otherwise, or if the event has no org.
### Recency boost
@@ -88,77 +88,99 @@ always gets the same nudge, so refreshing Explore never reshuffles it. The nudge
once a day, so events that would otherwise tie get some variety over time. Ties still break
by soonest event first.
-## Candidate pool: why scoring needs more than one page
-
-The DB query pulls every upcoming, published event matching the feed's filters — not just the
-requested page (`limit`/`offset`) — scores all of them, sorts by score, and only then slices
-out the requested page. If scoring only ever ran against the 20 events the caller asked for,
-personalization would have nothing to work with — the soonest 20 would always be exactly
-what's returned, just reshuffled. Scoring the full candidate set lets a highly relevant event
-further down the calendar outrank a less relevant one that merely happens sooner, no matter
-how many other events are scheduled in between.
-
-`total` is simply the size of that candidate set, so it always agrees with what `limit`/`offset`
-can actually reach — there's no separate count that could promise more than pagination can
-deliver. Enrichment (tags, rsvp/view counts, friend attendance, user state) is batched via
-`inArray(...)` across the whole candidate set rather than queried per event, so a wider pool
-doesn't multiply query count — it stays at a fixed handful of queries regardless of how many
-candidates are scored.
-
-### Bounded by calendar distance, not row count
-
-When no explicit `dateRange` filter is applied, candidates are bounded to the next
-`CANDIDATE_HORIZON_DAYS` (14) days, rounded up to the end of that day. This replaced an earlier
-version that capped the candidate pool at a fixed row count (the soonest 100 events) — that
-approach meant a highly relevant event could be excluded from ranking entirely just because 100
-*other* events happened to be scheduled sooner, regardless of how strong its interest/friend/org
-signal was. A calendar-distance bound doesn't have that failure mode: every event within the
-next two weeks is always a candidate, no matter how many other events fall before it. An
-explicit `dateRange` param (`today`/`week`/`month`) overrides the default horizon with its own
-narrower or wider window.
-
-Events further out than the horizon never enter ranking by default — this is an intentional
-product choice (Explore surfaces what's happening soon, not the whole semester's calendar), not
-a scale workaround. `CANDIDATE_POOL_SAFETY_VALVE` (5000) is a separate, purely defensive row
-limit on top of the horizon, in case an unusually dense window ever produced a pathological
-result size — it isn't expected to bind at realistic campus-event scale.
+## Where the code lives
+
+| File | What |
+|---|---|
+| `apps/web/src/actions/events.ts` → `getFeedEvents()` | Server action: auth + zod validation of params, then delegates |
+| `apps/web/src/lib/feed.ts` → `loadRankedFeed()` | Candidate generation, batched enrichment, pagination |
+| `apps/web/src/lib/feed-ranking.ts` | Pure scoring + ordering (`scoreEvent`, `finalizeFeedOrder`) and every tunable constant |
+
+## Pipeline
+
+1. **Candidate generation** — which events get ranked at all (below).
+2. **Batched enrichment** — tags, RSVP counts, view counts, friends attending, and the viewer's
+ own RSVP/save state for *every* candidate, one `inArray(...)` query per signal (six queries
+ total, independent of pool size). No per-event queries.
+3. **Score + sort** — score desc, then soonest first, then event id. A total order, so the sort is
+ fully deterministic.
+4. **Finalize one order over the whole list** — org-diversity cap and soon-event quota
+ (below) are applied to the complete ranked list, *before* pagination.
+5. **Paginate** — the requested page is `finalOrder.slice(offset, offset + limit)`.
+6. **Attendee rosters** — the full "N attending" list is loaded for the returned page only.
+
+`total` is the length of the finalized list, so it always agrees with what `offset`/`limit` can
+reach.
+
+## Candidate pool
+
+Scoring has to see more than one page — if only the 20 soonest events were scored, a highly
+relevant event further out could never outrank a weak one that merely happens sooner.
+
+**Stage 1 — calendar horizon.** Every published, visible, upcoming event matching the filters
+within the next `CANDIDATE_HORIZON_DAYS` (45) days, rounded up to end of day, soonest first, up
+to `CANDIDATE_POOL_CAP` (1000) rows. An explicit `dateRange` filter (`today`/`week`/`month`)
+replaces the default horizon. At the expected scale (hundreds of events per semester) the cap
+never binds and stage 1 *is* the whole pool. Scoring 1000 candidates in memory is a few
+milliseconds; the batched enrichment queries stay well below Postgres' bind-parameter limit.
+
+**Stage 2 — personalised expansion (only if stage 1 saturates).** If stage 1 returns exactly
+`CANDIDATE_POOL_CAP` rows, a second query over the same filters and horizon fetches up to
+`PERSONAL_CANDIDATE_CAP` (500) events *at or after* the stage-1 cutoff that carry a personal
+signal: hosted by an org the viewer follows/belongs to, RSVP'd by a friend, or tagged with one
+of the viewer's interests. These are merged (de-duplicated) into the pool. So a dense calendar
+can crowd out generic far-future events, but not the ones this particular viewer is likely to
+care about — unlike the old "100 soonest" hard wall. A warning is logged when this path runs,
+as the signal to revisit the constants.
+
+Events beyond the horizon never enter ranking by default — a product choice (Explore is about
+the next several weeks), not a scale workaround.
## Org diversity cap
-After sorting by score, results are capped at `ORG_DIVERSITY_CAP` (3) events per org — once
-an org hits 3, its remaining events are pushed later (not dropped), so one heavily-posting
-org can't dominate the top of the feed. Events without an org are never capped.
+At most `ORG_DIVERSITY_CAP` (3) events from one org in any `ORG_DIVERSITY_WINDOW` (20)
+consecutive feed positions — i.e. no page is dominated by one heavy-posting org. Events without
+an org are never capped. Over-cap events are *deferred*, not dropped: they re-enter as soon as
+the window slides past the org's earlier events. (The original PR #38 version deferred every
+over-cap event to the very end of the feed; the sliding window keeps a followed org's 4th event
+reachable a page later instead of behind hundreds of others.)
+
+The only time the cap is exceeded is at the tail, when *every* remaining event is from an org
+already at the cap in the current window — there is nothing else left to show, so the
+highest-scoring remaining event is placed.
## Guaranteeing imminent events aren't buried
-Friend RSVPs (weight 4.0) can outweigh time proximity (weight 2.0), so an event with strong
-social signal three weeks out could in principle outscore one happening tomorrow with no
-friends attending yet. To keep "what's happening soon" reliably visible, the first
-`SOON_INJECTION_WINDOW` (20) positions of the ranked, diversified feed always include at least
-`SOON_QUOTA` (3) events within `SOON_WINDOW_DAYS` (1) day, even if their score wouldn't
-naturally place them there.
-
-This window is a fixed size, independent of the `limit`/`offset` a given request happens to
-use — the whole feed is reordered into one final, stable sequence first, and *then* sliced into
-pages. That means two requests for the same feed with different page sizes see the same
-underlying order, and no event can appear on two different pages or be silently dropped by the
-guarantee.
-
-This is a **merge**, not a score override: if the front of the feed already has enough soon
-events, nothing changes. Otherwise the highest-scoring soon events missing from that window are
-interleaved into it at evenly-spaced positions, removed from their original later position —
-everything else keeps its normal score order. It only backfills what score order left out, the
-way feeds inject a freshness quota without letting it take over the whole ranking.
-
-The injection never breaks the org diversity cap above: a soon event whose org already has
-`ORG_DIVERSITY_CAP` events in the front window is skipped, even if that means fewer than
-`SOON_QUOTA` soon events end up there. "Max 3 per org near the top" holds regardless of the
-soon-event guarantee — the two rules compose rather than one silently overriding the other.
-
-All the tunable constants above (`SOON_WINDOW_DAYS`, `SOON_QUOTA`, `SOON_INJECTION_WINDOW`,
-`ORG_DIVERSITY_CAP`, `CANDIDATE_HORIZON_DAYS`, `CANDIDATE_POOL_SAFETY_VALVE`,
-`POPULARITY_VIEW_CAP`, `POPULARITY_WEIGHT`, `RANDOM_WEIGHT`, `ORG_PAST_INTERACTION_AFFINITY`)
-live at the top of `events.ts`.
+Friend RSVPs (weight 4.0) can outweigh time proximity (weight 2.0), so an event with strong social
+signal three weeks out could outscore one happening tomorrow. To keep "what's happening soon"
+visible, the first `SOON_INJECTION_WINDOW` (20) positions include at least `SOON_QUOTA` (3)
+events starting within `SOON_WINDOW_DAYS` (1) day, spread evenly (by positions 5, 10 and 15).
+Soon events that already rank there naturally count toward the quota; only a shortfall causes
+the highest-scoring *missing* soon event to be pulled forward.
+
+**The quota never breaks the org cap.** A soon event is only pulled forward if its org is under
+the cap in the current window; if no such soon event exists, the quota is left unmet. "Max 3
+per org per page" wins over "3 soon events near the top".
+
+The window is fixed, independent of `limit`/`offset`, so page size never changes the order.
+
+## Pagination and `asOf`
+
+Both rules above are part of one greedy pass (`finalizeFeedOrder`) over the full ranked list,
+producing a permutation of it (nothing added or dropped). Pages are plain slices of that array,
+so within one ranking no event can appear on two pages or be skipped.
+
+Scores depend on "now" (time proximity, recency, which events count as soon, the daily nudge
+seed, and which events have already started). To keep page 2 a slice of the *same* ranking as
+page 1, every response includes `asOf` — the instant it was ranked for — and the client sends it
+back with the next `offset`. The server reuses it as "now" if it is at most 30 minutes old
+(otherwise it ranks fresh). Data that changes between requests (a new RSVP, a new event) can
+still shift the order slightly; the client de-duplicates by id when appending as a safety net.
+
+All tunable constants (`CANDIDATE_HORIZON_DAYS`, `CANDIDATE_POOL_CAP`, `PERSONAL_CANDIDATE_CAP`,
+`WEIGHTS`, `TIME_HALF_LIFE_DAYS`, `ORG_PAST_INTERACTION_AFFINITY`, `POPULARITY_VIEW_CAP`,
+`ORG_DIVERSITY_CAP`, `ORG_DIVERSITY_WINDOW`, `SOON_WINDOW_DAYS`, `SOON_QUOTA`,
+`SOON_INJECTION_WINDOW`) live at the top of `apps/web/src/lib/feed-ranking.ts`.
## Edge cases
From 321645e3d41e778cb4248ec8838a8cd5aab75df9 Mon Sep 17 00:00:00 2001
From: DIodide
Date: Mon, 28 Sep 2026 02:42:09 -0400
Subject: [PATCH 17/69] Add shared profile options with dynamic class years
Class years are computed from the current Princeton academic year
(rolling over after Commencement) plus Grad/Other, instead of a
hardcoded list that had already gone stale. Interest and campus-region
options are shared between onboarding and settings, keyed by the
existing event_tag / campus_region enum values. Friends list no longer
renders 'Grad' as "'ad".
---
.../src/app/(app)/friends/friends-client.tsx | 6 +-
apps/web/src/lib/profile-options.ts | 93 +++++++++++++++++++
2 files changed, 97 insertions(+), 2 deletions(-)
create mode 100644 apps/web/src/lib/profile-options.ts
diff --git a/apps/web/src/app/(app)/friends/friends-client.tsx b/apps/web/src/app/(app)/friends/friends-client.tsx
index b441bc2..a54c1cd 100644
--- a/apps/web/src/app/(app)/friends/friends-client.tsx
+++ b/apps/web/src/app/(app)/friends/friends-client.tsx
@@ -16,6 +16,7 @@ import { SearchInput } from "~/components/common/search-input";
import { EmptyState, LoadingState } from "~/components/common/states";
import { Button } from "~/components/ui/button";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
+import { classYearShort } from "~/lib/profile-options";
function Avatar({
name,
@@ -197,7 +198,7 @@ export function FriendsClient({ initialFriends, initialPending }: FriendsClientP
@{user.netId}
- {user.classYear && ` · '${user.classYear.slice(-2)}`}
+ {classYearShort(user.classYear) && ` · ${classYearShort(user.classYear)}`}
{isFriend ? (
@@ -249,7 +250,8 @@ export function FriendsClient({ initialFriends, initialPending }: FriendsClientP
@{friend.netId}
- {friend.classYear && ` · '${friend.classYear.slice(-2)}`}
+ {classYearShort(friend.classYear) &&
+ ` · ${classYearShort(friend.classYear)}`}
{/*
diff --git a/apps/web/src/lib/profile-options.ts b/apps/web/src/lib/profile-options.ts
new file mode 100644
index 0000000..c009d11
--- /dev/null
+++ b/apps/web/src/lib/profile-options.ts
@@ -0,0 +1,93 @@
+import { getZonedParts } from "~/lib/date-format";
+
+/**
+ * Option lists shared by onboarding and settings.
+ *
+ * Values must match the `event_tag` / `campus_region` pgEnums in
+ * apps/database/src/schema. They're inlined because these are client
+ * components and can't import the server-only database package.
+ */
+
+export const INTEREST_OPTIONS = [
+ { value: "free food", label: "Free Food" },
+ { value: "career", label: "Career & Recruiting" },
+ { value: "research", label: "Research" },
+ { value: "academics", label: "Academics" },
+ { value: "tech", label: "Tech & Coding" },
+ { value: "stem", label: "Science & Engineering" },
+ { value: "entrepreneurship", label: "Entrepreneurship" },
+ { value: "politics", label: "Politics & Advocacy" },
+ { value: "visual arts", label: "Art & Design" },
+ { value: "performing arts", label: "Theater & Performance" },
+ { value: "music", label: "Music" },
+ { value: "literature", label: "Literature & Writing" },
+ { value: "culture", label: "Culture & Identity" },
+ { value: "religion", label: "Faith & Religion" },
+ { value: "community service", label: "Community Service" },
+ { value: "sustainability", label: "Sustainability" },
+ { value: "wellness", label: "Wellness & Mental Health" },
+ { value: "athletics", label: "Fitness & Sports" },
+ { value: "outdoors", label: "Outdoor & Adventure" },
+ { value: "gaming", label: "Gaming & Esports" },
+ { value: "social event", label: "Social Events" },
+ { value: "speaker event", label: "Speakers & Talks" },
+] as const;
+
+const INTEREST_VALUES = new Set(INTEREST_OPTIONS.map((o) => o.value));
+
+export function isInterestValue(value: string) {
+ return INTEREST_VALUES.has(value);
+}
+
+export function interestLabel(value: string) {
+ return INTEREST_OPTIONS.find((o) => o.value === value)?.label ?? value;
+}
+
+export const CAMPUS_REGION_OPTIONS = [
+ { value: "central", label: "Central Campus", desc: "Nassau Hall, Frist, 1879" },
+ { value: "east", label: "Science Area", desc: "Jadwin, Friend, EQuad" },
+ { value: "south", label: "Prospect Ave", desc: "Eating clubs, Terrace" },
+ { value: "west", label: "Residential Colleges", desc: "Butler, Whitman, Yeh …" },
+ { value: "north", label: "Arts Corridor", desc: "McCarter, Lewis Center" },
+ { value: "off-campus", label: "Athletics Area", desc: "Lenz, DeNunzio, Dillon" },
+] as const;
+
+const REGION_VALUES = new Set(CAMPUS_REGION_OPTIONS.map((o) => o.value));
+
+export function isRegionValue(value: string) {
+ return REGION_VALUES.has(value);
+}
+
+/**
+ * Undergraduate class years currently on campus, plus graduate/other.
+ *
+ * Princeton's year turns over at Commencement (late May), so from June on the
+ * rising seniors are next year's class. In September 2026 this yields
+ * 2027–2030; hardcoding the list meant it silently went stale every year.
+ */
+export function getClassYearOptions(now = new Date()): string[] {
+ const { year, month } = getZonedParts(now);
+ const seniorClass = month >= 6 ? year + 1 : year;
+ const undergrad = Array.from({ length: 4 }, (_, i) => String(seniorClass + i));
+ return [...undergrad, "Grad", "Other"];
+}
+
+/** Keeps a previously saved value selectable after the list has rolled over. */
+export function withCurrentOption(options: string[], current: string | null | undefined) {
+ if (!current || options.includes(current)) return options;
+ return [current, ...options];
+}
+
+/** "'27" for a class year, "Grad" for grad students, nothing otherwise. */
+export function classYearShort(value: string | null | undefined) {
+ if (!value) return null;
+ if (/^\d{4}$/.test(value)) return `'${value.slice(-2)}`;
+ if (value === "Grad") return "Grad";
+ return null;
+}
+
+export function classYearLabel(value: string) {
+ if (value === "Grad") return "Graduate student";
+ if (value === "Other") return "Other / not a student";
+ return `Class of ${value}`;
+}
From 3022e6f0c2cad9d046cc489c54c602d8b44188f0 Mon Sep 17 00:00:00 2001
From: DIodide
Date: Mon, 28 Sep 2026 02:42:09 -0400
Subject: [PATCH 18/69] Settings: real data only, persist interests and regions
- Remove the hardcoded 'Princeton TigerApps / Design Lead' rows, dead
Edit Role buttons, the duplicate Friends/Organizations block with its
non-working search, and the fake 'Suggested tags' (Jane Street etc.)
- Interests: add/remove from the real event_tag list with a filter;
saving stays on the page, toasts success/failure, and refreshes from
the server so the saved state survives a reload (ideas from PR #44,
without its enum rename)
- Send the user's actual regions instead of regions: [] (which wiped
them) and add a campus-region picker
- Editable name (updateProfile accepts displayName), read-only NetID,
dynamic class years, major picker, org-leader toggle
- Organizations panel lists orgs the user actually manages
- Avatar upload checks the S3 response and surfaces errors via toast
- Links to Privacy, Terms and contact
---
apps/web/src/actions/users.ts | 4 +
apps/web/src/app/(app)/settings/page.tsx | 12 +-
.../app/(app)/settings/settings-client.tsx | 637 ++++++++++--------
apps/web/src/lib/upload-image.ts | 51 ++
4 files changed, 422 insertions(+), 282 deletions(-)
create mode 100644 apps/web/src/lib/upload-image.ts
diff --git a/apps/web/src/actions/users.ts b/apps/web/src/actions/users.ts
index 51b04e2..4bf9a67 100644
--- a/apps/web/src/actions/users.ts
+++ b/apps/web/src/actions/users.ts
@@ -22,6 +22,7 @@ export async function completeOnboarding(data: {
major: string;
regions: string[];
isOrgLeader: boolean;
+ displayName?: string;
}) {
const session = await auth();
if (!session?.user?.id) throw new Error("Unauthorized");
@@ -32,6 +33,7 @@ export async function completeOnboarding(data: {
await db
.update(users)
.set({
+ displayName: data.displayName?.trim().slice(0, 255) || undefined,
classYear: data.classYear,
major: data.major,
isOrgLeader: data.isOrgLeader,
@@ -154,6 +156,7 @@ export async function updateProfile(data: {
isOrgLeader?: boolean;
interests?: string[];
regions?: string[];
+ displayName?: string;
}): Promise {
const user = await getCurrentUser();
const userId = user.id;
@@ -161,6 +164,7 @@ export async function updateProfile(data: {
await db
.update(users)
.set({
+ displayName: data.displayName?.trim().slice(0, 255) || undefined,
classYear: data.classYear,
major: data.major,
isOrgLeader: data.isOrgLeader,
diff --git a/apps/web/src/app/(app)/settings/page.tsx b/apps/web/src/app/(app)/settings/page.tsx
index ebc3418..2f9f69b 100644
--- a/apps/web/src/app/(app)/settings/page.tsx
+++ b/apps/web/src/app/(app)/settings/page.tsx
@@ -1,9 +1,17 @@
+import type { Metadata } from "next";
import { getFriends } from "~/actions/friends";
+import { getUserOrgs } from "~/actions/orgs";
import { getUserProfile } from "~/actions/users";
import { SettingsClient } from "./settings-client";
+export const metadata: Metadata = { title: "Settings" };
+
export default async function SettingsPage() {
- const [profile, friends] = await Promise.all([getUserProfile(), getFriends()]);
+ const [profile, friends, managedOrgs] = await Promise.all([
+ getUserProfile(),
+ getFriends(),
+ getUserOrgs(),
+ ]);
- return ;
+ return ;
}
diff --git a/apps/web/src/app/(app)/settings/settings-client.tsx b/apps/web/src/app/(app)/settings/settings-client.tsx
index e3bbff2..eadb559 100644
--- a/apps/web/src/app/(app)/settings/settings-client.tsx
+++ b/apps/web/src/app/(app)/settings/settings-client.tsx
@@ -1,11 +1,11 @@
"use client";
-import { ArrowLeft, ExternalLink, Pencil, Search, X } from "lucide-react";
+import { ArrowLeft, ExternalLink, Pencil, X } from "lucide-react";
import Link from "next/link";
import { useRouter } from "next/navigation";
-import { useRef, useState, useTransition } from "react";
+import { useMemo, useRef, useState, useTransition } from "react";
+import { toast } from "sonner";
import type { FriendProfile } from "~/actions/friends";
-import { getPresignedUploadUrl } from "~/actions/upload";
import { type UserProfile, updateAvatar, updateProfile } from "~/actions/users";
import { Field } from "~/components/common/field";
import { FilterChip } from "~/components/common/filter-chip";
@@ -18,53 +18,39 @@ import {
TOP_BAR_CLEARANCE,
} from "~/components/layout/page-shell";
import { Button } from "~/components/ui/button";
+import { PRINCETON_MAJORS } from "~/lib/princeton-departments";
+import {
+ CAMPUS_REGION_OPTIONS,
+ INTEREST_OPTIONS,
+ classYearLabel,
+ classYearShort,
+ getClassYearOptions,
+ interestLabel,
+ isInterestValue,
+ isRegionValue,
+ withCurrentOption,
+} from "~/lib/profile-options";
+import { IMAGE_ACCEPT, uploadImage } from "~/lib/upload-image";
import { cn } from "~/lib/utils";
-const INTEREST_TAGS = [
- { id: "free food", label: "free food" },
- { id: "tech", label: "technology" },
- { id: "stem", label: "science and engineering" },
- { id: "visual arts", label: "visual arts" },
- { id: "wellness", label: "fitness & health" },
- { id: "academics", label: "academics" },
- { id: "research", label: "research" },
- { id: "career", label: "career" },
- { id: "entrepreneurship", label: "entrepreneurship" },
- { id: "music", label: "music" },
- { id: "social event", label: "social" },
- { id: "athletics", label: "sports" },
- { id: "performing arts", label: "performing arts" },
- { id: "culture", label: "culture" },
- { id: "literature", label: "literature" },
- { id: "community service", label: "service" },
- { id: "religion", label: "religion" },
- { id: "politics", label: "politics" },
- { id: "gaming", label: "gaming" },
- { id: "outdoors", label: "outdoors" },
- { id: "sustainability", label: "sustainability" },
- { id: "speaker event", label: "speaker" },
-];
-
-const SUGGESTION_TAGS = [
- "tech talk",
- "Jane Street",
- "consulting",
- "internship",
- "Citadel",
- "Lockheed Martin",
- "free merch",
- "Bain & Company",
-];
-
-const CLASS_YEARS = ["2025", "2026", "2027", "2028", "2029", "Grad"];
-
interface SettingsClientProps {
profile: UserProfile;
friends: FriendProfile[];
+ /** Organizations the user owns or is an officer of. */
+ managedOrgs: { id: string; name: string }[];
+}
+
+const MAJOR_OPTIONS = PRINCETON_MAJORS.map((d) => (d.degree ? `${d.name} (${d.degree})` : d.name));
+
+const UNDERLINE_CONTROL =
+ "w-full border-b border-forum-medium-gray bg-transparent pb-1.5 font-dm-sans text-[15px] text-black outline-none transition-colors focus:border-forum-cerulean";
+
+function sameSet(a: string[], b: string[]) {
+ return a.length === b.length && a.every((v) => b.includes(v));
}
-/** Single friend row — was duplicated verbatim in both Friends sections. */
function FriendRow({ friend }: { friend: FriendProfile }) {
+ const year = classYearShort(friend.classYear);
return (
@@ -85,65 +71,120 @@ function FriendRow({ friend }: { friend: FriendProfile }) {
@{friend.netId}
- {friend.classYear && (
-
- '{friend.classYear.slice(-2)}
-
- )}
+ {year &&
{year} }
);
}
-export function SettingsClient({ profile, friends }: SettingsClientProps) {
+export function SettingsClient({ profile, friends, managedOrgs }: SettingsClientProps) {
const router = useRouter();
const [isPending, startTransition] = useTransition();
- const [classYear, setClassYear] = useState(profile.classYear ?? "");
- const [major, setMajor] = useState(profile.major ?? "");
- const [isOrgLeader, setIsOrgLeader] = useState(profile.isOrgLeader);
- const [interests, setInterests] = useState(profile.interests);
+ /*
+ * Saved values, derived from props so they refresh after `router.refresh()`
+ * re-renders the server page with what's actually in the database.
+ */
+ const saved = useMemo(
+ () => ({
+ displayName: profile.displayName,
+ classYear: profile.classYear ?? "",
+ major: profile.major ?? "",
+ isOrgLeader: profile.isOrgLeader,
+ interests: profile.interests.filter(isInterestValue),
+ regions: profile.regions.filter(isRegionValue),
+ }),
+ [profile],
+ );
+
+ const [displayName, setDisplayName] = useState(saved.displayName);
+ const [classYear, setClassYear] = useState(saved.classYear);
+ const [major, setMajor] = useState(saved.major);
+ const [isOrgLeader, setIsOrgLeader] = useState(saved.isOrgLeader);
+ const [interests, setInterests] = useState(saved.interests);
+ const [regions, setRegions] = useState(saved.regions);
const [friendSearch, setFriendSearch] = useState("");
- const [orgSearch, setOrgSearch] = useState("");
const [tagSearch, setTagSearch] = useState("");
- const toggleInterest = (id: string) => {
- setInterests((prev) => (prev.includes(id) ? prev.filter((i) => i !== id) : [...prev, id]));
+ const classYearOptions = withCurrentOption(getClassYearOptions(), saved.classYear);
+ const majorOptions = withCurrentOption(MAJOR_OPTIONS, saved.major);
+
+ const nameError = displayName.trim() ? undefined : "Name can't be empty";
+
+ const hasChanges =
+ displayName.trim() !== saved.displayName ||
+ classYear !== saved.classYear ||
+ major !== saved.major ||
+ isOrgLeader !== saved.isOrgLeader ||
+ !sameSet(interests, saved.interests) ||
+ !sameSet(regions, saved.regions);
+
+ const toggleInterest = (value: string) => {
+ setInterests((prev) =>
+ prev.includes(value) ? prev.filter((i) => i !== value) : [...prev, value],
+ );
+ };
+
+ const toggleRegion = (value: string) => {
+ setRegions((prev) =>
+ prev.includes(value) ? prev.filter((r) => r !== value) : [...prev, value],
+ );
};
const handleSave = () => {
+ if (nameError) {
+ toast.error(nameError);
+ return;
+ }
startTransition(async () => {
- await updateProfile({
- classYear,
- major,
- isOrgLeader,
- interests,
- regions: [],
- });
- router.push("/explore");
+ try {
+ await updateProfile({
+ displayName: displayName.trim(),
+ classYear,
+ major,
+ isOrgLeader,
+ interests: interests.filter(isInterestValue),
+ regions: regions.filter(isRegionValue),
+ });
+ toast.success("Settings saved");
+ router.refresh();
+ } catch {
+ toast.error("Couldn't save your settings. Please try again.");
+ }
});
};
+ const handleDiscard = () => {
+ setDisplayName(saved.displayName);
+ setClassYear(saved.classYear);
+ setMajor(saved.major);
+ setIsOrgLeader(saved.isOrgLeader);
+ setInterests(saved.interests);
+ setRegions(saved.regions);
+ setTagSearch("");
+ };
+
const avatarInputRef = useRef(null);
const [avatarPreview, setAvatarPreview] = useState(profile.avatarUrl);
+ const [isUploadingAvatar, setIsUploadingAvatar] = useState(false);
const handleAvatarUpload = async (file: File) => {
- // Preview immediately
- const reader = new FileReader();
- reader.onload = (e) => setAvatarPreview(e.target?.result as string);
- reader.readAsDataURL(file);
-
+ const previous = avatarPreview;
+ const localPreview = URL.createObjectURL(file);
+ setAvatarPreview(localPreview);
+ setIsUploadingAvatar(true);
try {
- const { uploadUrl, publicUrl } = await getPresignedUploadUrl({
- filename: file.name,
- contentType: file.type,
- size: file.size,
- folder: "avatars",
- });
- await fetch(uploadUrl, { method: "PUT", body: file, headers: { "Content-Type": file.type } });
+ const publicUrl = await uploadImage(file, "avatars");
await updateAvatar(publicUrl);
+ setAvatarPreview(publicUrl);
+ toast.success("Profile photo updated");
+ router.refresh();
} catch (err) {
- console.error("Avatar upload failed:", err);
- setAvatarPreview(profile.avatarUrl);
+ setAvatarPreview(previous);
+ toast.error(err instanceof Error ? err.message : "Couldn't update your photo.");
+ } finally {
+ URL.revokeObjectURL(localPreview);
+ setIsUploadingAvatar(false);
+ if (avatarInputRef.current) avatarInputRef.current.value = "";
}
};
@@ -154,6 +195,13 @@ export function SettingsClient({ profile, friends }: SettingsClientProps) {
f.netId.toLowerCase().includes(friendSearch.toLowerCase()),
);
+ const tagQuery = tagSearch.trim().toLowerCase();
+ const availableInterests = INTEREST_OPTIONS.filter(
+ (o) =>
+ !interests.includes(o.value) &&
+ (!tagQuery || o.label.toLowerCase().includes(tagQuery) || o.value.includes(tagQuery)),
+ );
+
return (
{/* Reserves space so these buttons don't collide with the floating TopBar. */}
@@ -163,10 +211,20 @@ export function SettingsClient({ profile, friends }: SettingsClientProps) {
Back
- router.push("/explore")}>
- Exit
+
+ Discard
-
+
{isPending ? "Saving…" : "Save changes"}
@@ -180,9 +238,13 @@ export function SettingsClient({ profile, friends }: SettingsClientProps) {
{/* Avatar */}
-
+
{avatarPreview ? (
-
+
) : (
)}
+ {isUploadingAvatar && (
+
+ Uploading…
+
+ )}
avatarInputRef.current?.click()}
+ disabled={isUploadingAvatar}
>
Edit Photo
@@ -204,8 +272,9 @@ export function SettingsClient({ profile, friends }: SettingsClientProps) {
{
const file = e.target.files?.[0];
if (file) handleAvatarUpload(file);
@@ -213,55 +282,114 @@ export function SettingsClient({ profile, friends }: SettingsClientProps) {
/>
- {/* Name + Class Year inline */}
-
-
-
-
- {profile.displayName}
-
-
-
+
+
+ setDisplayName(e.target.value)}
+ aria-invalid={nameError ? true : undefined}
+ aria-describedby={nameError ? "display-name-error" : undefined}
+ className={UNDERLINE_CONTROL}
+ />
-
+
+
+
NetID
+
+ {profile.netId}
+
+ from your Princeton login
+
+
+
+
+
setClassYear(e.target.value)}
- className="w-full appearance-none border-b border-forum-medium-gray bg-transparent pb-1.5 font-dm-sans text-[15px] text-black outline-none focus:border-forum-cerulean"
+ className={cn(UNDERLINE_CONTROL, "appearance-none")}
>
Select
- {CLASS_YEARS.map((y) => (
+ {classYearOptions.map((y) => (
- {y}
+ {classYearLabel(y)}
+
+ ))}
+
+
+
+
+ setMajor(e.target.value)}
+ className={cn(UNDERLINE_CONTROL, "appearance-none")}
+ >
+ Undeclared / prefer not to say
+ {majorOptions.map((m) => (
+
+ {m}
))}
+
+
+
+ setIsOrgLeader(e.target.checked)}
+ className="mt-0.5 size-4 accent-forum-cerulean"
+ />
+
+ I lead or manage a student organization
+
+ Lets you create an organization page and publish events for it.
+
+
+
+
- {/* ═══ Friends + Organizations — two columns ═══ */}
+ {/* ═══ Friends + Organizations ═══ */}
- {/* Friends column */}
Friends
- setFriendSearch(e.target.value)}
- />
-
-
- {filteredFriends.map((friend) => (
-
-
-
- ))}
-
+ {friends.length > 0 ? (
+ <>
+ setFriendSearch(e.target.value)}
+ />
+
+ {filteredFriends.map((friend) => (
+
+
+
+ ))}
+ {filteredFriends.length === 0 && (
+
+ No friends match “{friendSearch}”.
+
+ )}
+
+ >
+ ) : (
+
+ You haven't added any friends yet.
+
+ )}
@@ -272,24 +400,37 @@ export function SettingsClient({ profile, friends }: SettingsClientProps) {
- {/* Organizations column */}
Organizations
- setOrgSearch(e.target.value)}
- />
-
-
- No organizations yet. Follow orgs from the Orgs page.
-
+ {managedOrgs.length > 0 ? (
+
+ {managedOrgs.map((org) => (
+
+
+
+ {org.name[0]?.toUpperCase()}
+
+ {org.name}
+
+
+ ))}
+
+ ) : (
+
+ You don't manage any organizations yet.
+
+ )}
- Add / edit my organizations
+ Browse organizations
@@ -297,26 +438,27 @@ export function SettingsClient({ profile, friends }: SettingsClientProps) {
- {/* ═══ Interest Tags ═══ */}
+ {/* ═══ Interests ═══ */}
Interest Tags
+
+ Your Explore feed is ranked around these.
+
- {/* Selected topics */}
- Topics
+ Your topics
- {interests.map((tagId) => {
- const tag = INTEREST_TAGS.find((t) => t.id === tagId);
- const label = tag?.label ?? tagId;
+ {interests.map((value) => {
+ const label = interestLabel(value);
return (
toggleInterest(tagId)}
+ onClick={() => toggleInterest(value)}
>
{label}
@@ -325,174 +467,109 @@ export function SettingsClient({ profile, friends }: SettingsClientProps) {
})}
{interests.length === 0 && (
- No topics selected yet.
+ No topics selected yet — add some from the list.
)}
- {/* Search for new tags */}
-
-
- Suggested tags
+
+ Add topics
+ setTagSearch(e.target.value)}
+ className="mb-3 h-10"
+ />
- {SUGGESTION_TAGS.map((tag) => (
-
- {tag}
+ {availableInterests.map((option) => (
+ toggleInterest(option.value)}
+ >
+ {option.label}
))}
+ {availableInterests.length === 0 && (
+
+ {tagQuery ? "No matching topics." : "You've added every topic."}
+
+ )}
-
- {/* Organizations — link to orgs page */}
-
-
- Organizations
-
-
- Manage your organization memberships from the{" "}
-
- Orgs page
-
- .
-
-
- {/* ═══ Friends + Organizations (bottom expanded view) ═══ */}
-
- {/* Friends expanded */}
-
-
-
- {/* Avatar large */}
-
- {profile.avatarUrl ? (
-
- ) : (
-
- {profile.displayName[0]?.toUpperCase()}
-
- )}
-
-
-
-
-
-
-
-
- {friends.map((friend) => (
-
-
- {friend.avatarUrl ? (
-
+
Campus Regions
+
+
+
+ Where you usually are on campus. We use this to surface nearby events.
+
+
+ {CAMPUS_REGION_OPTIONS.map(({ value, label, desc }) => {
+ const selected = regions.includes(value);
+ return (
+
toggleRegion(value)}
+ className={cn(
+ "flex items-center justify-between gap-3 rounded-lg border px-4 py-3 text-left transition-colors",
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-forum-cerulean",
+ selected
+ ? "border-forum-cerulean bg-forum-turquoise/10"
+ : "border-forum-medium-gray hover:border-forum-dark-gray",
+ )}
+ >
+
+
+ {label}
+
+
+ {desc}
+
+
+
- ) : (
-
- {friend.displayName[0]?.toUpperCase()}
-
- )}
-
-
-
- {friend.displayName}
-
-
- @{friend.netId}
-
-
- {friend.classYear && (
-
- '{friend.classYear.slice(-2)}
-
- )}
-
- ))}
-
+
+ );
+ })}
+
+
+
+
-
- ADD / EDIT MY FRIENDS LIST
-
+ {/* ═══ About ═══ */}
+
-
- {/* Organizations expanded */}
-
-
-
-
-
-
-
-
-
- {[1, 2, 3, 4].map((i) => (
-
-
-
-
- Princeton TigerApps
-
-
- Design Lead
-
-
-
- Edit Role
-
-
- ))}
-
-
-
- ADD / EDIT MY ORGANIZATIONS
-
+
+ Terms of Use
-
-
+
+ Contact: it.admin@tigerapps.org
+
+
+
);
}
diff --git a/apps/web/src/lib/upload-image.ts b/apps/web/src/lib/upload-image.ts
new file mode 100644
index 0000000..38a7b18
--- /dev/null
+++ b/apps/web/src/lib/upload-image.ts
@@ -0,0 +1,51 @@
+import { getPresignedUploadUrl } from "~/actions/upload";
+
+/** Mirrors the limits enforced server-side in actions/upload.ts. */
+export const IMAGE_ACCEPT = "image/jpeg,image/png,image/webp";
+const ALLOWED_TYPES = IMAGE_ACCEPT.split(",");
+const MAX_BYTES = 5 * 1024 * 1024;
+
+/**
+ * Upload an image straight to S3 via a presigned PUT and return its public URL.
+ *
+ * Throws an Error whose message is safe to show in a toast. The S3 response is
+ * checked — `fetch` resolves on 4xx/5xx, so without `res.ok` a rejected upload
+ * used to be saved as if it had worked, leaving a broken image URL behind.
+ */
+export async function uploadImage(file: File, folder: "avatars" | "event-flyers") {
+ if (!ALLOWED_TYPES.includes(file.type)) {
+ throw new Error("Please choose a JPEG, PNG, or WebP image.");
+ }
+ if (file.size > MAX_BYTES) {
+ throw new Error("That image is over 5 MB. Please choose a smaller one.");
+ }
+
+ let uploadUrl: string;
+ let publicUrl: string;
+ try {
+ ({ uploadUrl, publicUrl } = await getPresignedUploadUrl({
+ filename: file.name,
+ contentType: file.type,
+ size: file.size,
+ folder,
+ }));
+ } catch {
+ throw new Error("Image uploads aren't available right now. Please try again later.");
+ }
+
+ let res: Response;
+ try {
+ res = await fetch(uploadUrl, {
+ method: "PUT",
+ body: file,
+ headers: { "Content-Type": file.type },
+ });
+ } catch {
+ throw new Error("Upload failed — check your connection and try again.");
+ }
+ if (!res.ok) {
+ throw new Error("Upload failed. Please try again.");
+ }
+
+ return publicUrl;
+}
From 98e097e0d6da93d6ec85ebce9814fcdf16adfd15 Mon Sep 17 00:00:00 2001
From: DIodide
Date: Mon, 28 Sep 2026 02:42:10 -0400
Subject: [PATCH 19/69] Redirect /profile to /settings
It rendered a duplicate of Settings and nothing linked to it.
---
apps/web/src/app/(app)/profile/page.tsx | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/apps/web/src/app/(app)/profile/page.tsx b/apps/web/src/app/(app)/profile/page.tsx
index 0bd9f09..bbf6737 100644
--- a/apps/web/src/app/(app)/profile/page.tsx
+++ b/apps/web/src/app/(app)/profile/page.tsx
@@ -1,9 +1,6 @@
-import { getFriends } from "~/actions/friends";
-import { getUserProfile } from "~/actions/users";
-import { SettingsClient } from "../settings/settings-client";
+import { redirect } from "next/navigation";
-export default async function ProfilePage() {
- const [profile, friends] = await Promise.all([getUserProfile(), getFriends()]);
-
- return ;
+/** `/profile` used to render a second copy of Settings. One page now. */
+export default function ProfilePage() {
+ redirect("/settings");
}
From 899a49a14548bd531d0b690acfc167ec13121b48 Mon Sep 17 00:00:00 2001
From: DIodide
Date: Mon, 28 Sep 2026 02:42:49 -0400
Subject: [PATCH 20/69] feat(web): add Princeton CAS protocol helpers with bun
tests
apps/web/src/lib/cas.ts: state generation + timing-safe compare, return-path sanitizing, service/login/serviceValidate/logout URL builders, service-URL pinning, and serviceValidate XML parsing (fast-xml-parser, removeNSPrefix, processEntities:false) with NetID validation. Adds fast-xml-parser, a 'test' script, and drops the unused @auth/drizzle-adapter dependency.
---
apps/web/package.json | 3 +-
apps/web/src/lib/cas.test.ts | 288 +++++++++++++++++++++++++++++++++++
apps/web/src/lib/cas.ts | 238 +++++++++++++++++++++++++++++
bun.lock | 8 +-
4 files changed, 530 insertions(+), 7 deletions(-)
create mode 100644 apps/web/src/lib/cas.test.ts
create mode 100644 apps/web/src/lib/cas.ts
diff --git a/apps/web/package.json b/apps/web/package.json
index 5a9e26b..c152d92 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -7,10 +7,10 @@
"build": "next build",
"start": "next start",
"lint": "biome check .",
+ "test": "bun test",
"check-types": "tsc --noEmit"
},
"dependencies": {
- "@auth/drizzle-adapter": "^1.11.1",
"@aws-sdk/client-s3": "^3.1004.0",
"@aws-sdk/s3-request-presigner": "^3.1004.0",
"@t3-oss/env-nextjs": "^0.13.10",
@@ -20,6 +20,7 @@
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"date-fns": "^4.1.0",
+ "fast-xml-parser": "^5.4.1",
"lucide-react": "^0.575.0",
"mapbox-gl": "^3.20.0",
"next": "^16.1.6",
diff --git a/apps/web/src/lib/cas.test.ts b/apps/web/src/lib/cas.test.ts
new file mode 100644
index 0000000..4625475
--- /dev/null
+++ b/apps/web/src/lib/cas.test.ts
@@ -0,0 +1,288 @@
+import { describe, expect, test } from "bun:test";
+import {
+ buildLoginUrl,
+ buildLogoutUrl,
+ buildServiceUrl,
+ buildServiceValidateUrl,
+ generateState,
+ isExpectedServiceUrl,
+ isValidState,
+ isValidTicket,
+ normalizeCasBaseUrl,
+ normalizeNetId,
+ parseServiceValidateResponse,
+ safeCompare,
+ sanitizeReturnPath,
+ validateServiceTicket,
+} from "./cas";
+
+const BASE = "https://fed.princeton.edu/cas/";
+const ORIGIN = "https://forum.example.edu";
+
+const success = (user: string, extra = "") => `
+
+
+ ${user}
+ ${extra}
+
+ `;
+
+const failure = `
+ Ticket ST-1 not recognized
+ `;
+
+describe("parseServiceValidateResponse", () => {
+ test("extracts and lowercases the NetID on success", () => {
+ expect(parseServiceValidateResponse(success("IAmin"))).toEqual({ ok: true, netId: "iamin" });
+ });
+
+ test("keeps numeric-looking NetIDs as strings", () => {
+ expect(parseServiceValidateResponse(success("01234"))).toEqual({ ok: true, netId: "01234" });
+ });
+
+ test("ignores attributes block", () => {
+ const attrs =
+ "someone@else.edu X ";
+ expect(parseServiceValidateResponse(success("abc123", attrs))).toEqual({
+ ok: true,
+ netId: "abc123",
+ });
+ });
+
+ test("reports authenticationFailure with its code", () => {
+ expect(parseServiceValidateResponse(failure)).toEqual({
+ ok: false,
+ reason: "failure",
+ code: "INVALID_TICKET",
+ });
+ });
+
+ test("rejects users that aren't valid NetIDs", () => {
+ for (const bad of [
+ "iamin@princeton.edu",
+ "evil user",
+ "",
+ "a".repeat(41),
+ "../etc",
+ "<x>",
+ ]) {
+ expect(parseServiceValidateResponse(success(bad))).toEqual({
+ ok: false,
+ reason: "invalid_user",
+ });
+ }
+ });
+
+ test("does not expand entities", () => {
+ const xml = `
+]>
+
+ &x;
+ `;
+ const result = parseServiceValidateResponse(xml);
+ expect(result.ok).toBe(false);
+ });
+
+ test("rejects malformed / unrelated documents", () => {
+ expect(parseServiceValidateResponse("not xml at all").ok).toBe(false);
+ expect(parseServiceValidateResponse("hi")).toEqual({
+ ok: false,
+ reason: "malformed",
+ });
+ expect(parseServiceValidateResponse(" ").ok).toBe(false);
+ });
+});
+
+describe("normalizeNetId", () => {
+ test("accepts letters, digits, underscore, hyphen", () => {
+ expect(normalizeNetId("Ab_c-9")).toBe("ab_c-9");
+ });
+ test("rejects non-strings", () => {
+ expect(normalizeNetId(123)).toBeNull();
+ expect(normalizeNetId(undefined)).toBeNull();
+ expect(normalizeNetId({ "#text": "x" })).toBeNull();
+ });
+});
+
+describe("sanitizeReturnPath", () => {
+ test("keeps local paths with query and hash", () => {
+ expect(sanitizeReturnPath("/events/create")).toBe("/events/create");
+ expect(sanitizeReturnPath("/explore?search=a%20b#top")).toBe("/explore?search=a%20b#top");
+ });
+
+ test("falls back for anything that could leave the origin", () => {
+ for (const bad of [
+ null,
+ undefined,
+ "",
+ "explore",
+ "https://evil.com",
+ "//evil.com",
+ "/\\evil.com",
+ "/foo\\bar",
+ "/\t/evil.com",
+ "javascript:alert(1)",
+ "/api/auth/cas/login",
+ "/api/auth",
+ `/${"a".repeat(600)}`,
+ ]) {
+ expect(sanitizeReturnPath(bad)).toBe("/explore");
+ }
+ });
+
+ test("uses the supplied fallback", () => {
+ expect(sanitizeReturnPath("https://evil.com", "/")).toBe("/");
+ });
+});
+
+describe("state + ticket helpers", () => {
+ test("generateState is 64 hex chars and unique", () => {
+ const a = generateState();
+ const b = generateState();
+ expect(isValidState(a)).toBe(true);
+ expect(a).not.toBe(b);
+ });
+
+ test("isValidState rejects wrong shapes", () => {
+ expect(isValidState("abc")).toBe(false);
+ expect(isValidState("G".repeat(64))).toBe(false);
+ expect(isValidState(null)).toBe(false);
+ });
+
+ test("safeCompare", () => {
+ expect(safeCompare("abc", "abc")).toBe(true);
+ expect(safeCompare("abc", "abd")).toBe(false);
+ expect(safeCompare("abc", "abcd")).toBe(false);
+ });
+
+ test("isValidTicket", () => {
+ expect(isValidTicket("ST-12345-abcDEF_ghi-cas01.princeton.edu")).toBe(true);
+ expect(isValidTicket("")).toBe(false);
+ expect(isValidTicket("ST-1 2")).toBe(false);
+ expect(isValidTicket("ST-1&service=x")).toBe(false);
+ expect(isValidTicket("x".repeat(513))).toBe(false);
+ expect(isValidTicket(undefined)).toBe(false);
+ });
+});
+
+describe("URL builders", () => {
+ const state = "a".repeat(64);
+ const service = buildServiceUrl(ORIGIN, state);
+
+ test("service URL", () => {
+ expect(service).toBe(`${ORIGIN}/api/auth/cas/callback?state=${state}`);
+ });
+
+ test("login URL encodes the service", () => {
+ expect(buildLoginUrl(BASE, service)).toBe(
+ `${BASE}login?service=${encodeURIComponent(service)}`,
+ );
+ expect(buildLoginUrl("https://fed.princeton.edu/cas", service)).toBe(
+ `${BASE}login?service=${encodeURIComponent(service)}`,
+ );
+ });
+
+ test("serviceValidate URL encodes service and ticket", () => {
+ expect(buildServiceValidateUrl(BASE, service, "ST-1")).toBe(
+ `${BASE}serviceValidate?service=${encodeURIComponent(service)}&ticket=ST-1`,
+ );
+ });
+
+ test("logout URL", () => {
+ expect(buildLogoutUrl(BASE)).toBe(`${BASE}logout`);
+ expect(buildLogoutUrl(BASE, `${ORIGIN}/`)).toBe(
+ `${BASE}logout?service=${encodeURIComponent(`${ORIGIN}/`)}`,
+ );
+ });
+
+ test("normalizeCasBaseUrl", () => {
+ expect(normalizeCasBaseUrl("https://x/cas")).toBe("https://x/cas/");
+ expect(normalizeCasBaseUrl("https://x/cas///")).toBe("https://x/cas/");
+ });
+});
+
+describe("isExpectedServiceUrl", () => {
+ const state = "b".repeat(64);
+ const good = buildServiceUrl(ORIGIN, state);
+
+ test("accepts our own callback URL", () => {
+ expect(isExpectedServiceUrl(good, ORIGIN)).toBe(true);
+ expect(isExpectedServiceUrl(good, `${ORIGIN}/api/auth`)).toBe(true);
+ });
+
+ test("rejects other origins, paths, and extra params", () => {
+ for (const bad of [
+ buildServiceUrl("https://evil.com", state),
+ buildServiceUrl("http://forum.example.edu", state),
+ `${ORIGIN}/api/auth/cas/other?state=${state}`,
+ `${good}&ticket=ST-1`,
+ `${good}&x=1`,
+ `${good}#frag`,
+ `${ORIGIN}/api/auth/cas/callback?state=short`,
+ `${ORIGIN}/api/auth/cas/callback`,
+ "not a url",
+ undefined,
+ 42,
+ ]) {
+ expect(isExpectedServiceUrl(bad, ORIGIN)).toBe(false);
+ }
+ });
+});
+
+describe("validateServiceTicket", () => {
+ const service = buildServiceUrl(ORIGIN, "c".repeat(64));
+
+ const fakeFetch = (body: string, status = 200, seen?: { url?: string }) =>
+ (async (input: RequestInfo | URL) => {
+ if (seen) seen.url = String(input);
+ return new Response(body, { status });
+ }) as unknown as typeof fetch;
+
+ test("calls serviceValidate with the same service and returns the NetID", async () => {
+ const seen: { url?: string } = {};
+ const result = await validateServiceTicket({
+ casBaseUrl: BASE,
+ service,
+ ticket: "ST-42",
+ fetchImpl: fakeFetch(success("TigerUser"), 200, seen),
+ });
+ expect(result).toEqual({ ok: true, netId: "tigeruser" });
+ expect(seen.url).toBe(buildServiceValidateUrl(BASE, service, "ST-42"));
+ });
+
+ test("returns failure for CAS authenticationFailure", async () => {
+ const result = await validateServiceTicket({
+ casBaseUrl: BASE,
+ service,
+ ticket: "ST-42",
+ fetchImpl: fakeFetch(failure),
+ });
+ expect(result.ok).toBe(false);
+ });
+
+ test("rejects malformed tickets without calling CAS", async () => {
+ let called = false;
+ const result = await validateServiceTicket({
+ casBaseUrl: BASE,
+ service,
+ ticket: "bad ticket",
+ fetchImpl: (async () => {
+ called = true;
+ return new Response("");
+ }) as unknown as typeof fetch,
+ });
+ expect(result.ok).toBe(false);
+ expect(called).toBe(false);
+ });
+
+ test("throws on non-2xx so callers treat CAS as unavailable", async () => {
+ await expect(
+ validateServiceTicket({
+ casBaseUrl: BASE,
+ service,
+ ticket: "ST-42",
+ fetchImpl: fakeFetch("oops", 503),
+ }),
+ ).rejects.toThrow("HTTP 503");
+ });
+});
diff --git a/apps/web/src/lib/cas.ts b/apps/web/src/lib/cas.ts
new file mode 100644
index 0000000..06f2116
--- /dev/null
+++ b/apps/web/src/lib/cas.ts
@@ -0,0 +1,238 @@
+/**
+ * Princeton CAS (Central Authentication Service) protocol helpers.
+ *
+ * Pure, framework-agnostic functions so they can be unit-tested with `bun test`
+ * without booting Next.js or validating env vars. Anything that needs env or
+ * request context lives in `~/lib/cas-server.ts` / the route handlers.
+ *
+ * Flow (CAS protocol v2):
+ * 1. /api/auth/cas/login → redirect to `${base}login?service=`
+ * 2. CAS redirects back to `&ticket=ST-…`
+ * 3. Server calls `${base}serviceValidate?service=&ticket=`
+ * and reads `serviceResponse.authenticationSuccess.user` (the NetID).
+ */
+
+import { randomBytes, timingSafeEqual } from "node:crypto";
+import { XMLParser } from "fast-xml-parser";
+
+export const DEFAULT_CAS_BASE_URL = "https://fed.princeton.edu/cas/";
+
+/** Path of our CAS callback route (the CAS "service"). */
+export const CAS_CALLBACK_PATH = "/api/auth/cas/callback";
+
+/** Cookie holding the anti-CSRF `state` for an in-flight login. */
+export const CAS_STATE_COOKIE = "forum_cas_state";
+/** Cookie holding the sanitized local path to return to after login. */
+export const CAS_RETURN_COOKIE = "forum_cas_return";
+/** Both cookies are only needed by the CAS login/callback routes. */
+export const CAS_COOKIE_PATH = "/api/auth/cas";
+/** Lifetime of the state + return cookies (10 minutes). */
+export const CAS_COOKIE_MAX_AGE_SECONDS = 10 * 60;
+
+export const CAS_VALIDATE_TIMEOUT_MS = 15_000;
+
+export const DEFAULT_RETURN_PATH = "/explore";
+
+const NETID_RE = /^[a-z0-9_-]{1,40}$/i;
+const STATE_RE = /^[a-f0-9]{64}$/;
+// CAS service tickets look like `ST-12345-abcDEF…-cas01`. Be permissive about the
+// charset but bounded, and reject anything with whitespace/control characters.
+const TICKET_RE = /^[A-Za-z0-9._:-]{1,512}$/;
+
+/** Ensure the CAS base URL ends in exactly one `/` so path joins are safe. */
+export function normalizeCasBaseUrl(base: string): string {
+ return `${base.replace(/\/+$/, "")}/`;
+}
+
+/** 32 random bytes, hex-encoded (64 chars). */
+export function generateState(): string {
+ return randomBytes(32).toString("hex");
+}
+
+export function isValidState(state: unknown): state is string {
+ return typeof state === "string" && STATE_RE.test(state);
+}
+
+export function isValidTicket(ticket: unknown): ticket is string {
+ return typeof ticket === "string" && TICKET_RE.test(ticket);
+}
+
+/** Constant-time string comparison (length mismatch → false, still no early exit on content). */
+export function safeCompare(a: string, b: string): boolean {
+ const aBuf = Buffer.from(a, "utf8");
+ const bBuf = Buffer.from(b, "utf8");
+ if (aBuf.length !== bBuf.length) {
+ // Compare against itself so timing doesn't depend on where strings differ.
+ timingSafeEqual(aBuf, aBuf);
+ return false;
+ }
+ return timingSafeEqual(aBuf, bBuf);
+}
+
+/** Validate a CAS username and normalize it to a lowercase NetID. */
+export function normalizeNetId(user: unknown): string | null {
+ if (typeof user !== "string") return null;
+ const trimmed = user.trim();
+ if (!NETID_RE.test(trimmed)) return null;
+ return trimmed.toLowerCase();
+}
+
+/**
+ * Sanitize a user-supplied "return to" value into a same-origin path.
+ * Rejects absolute URLs, protocol-relative URLs (`//evil.com`), backslash
+ * tricks (`/\evil.com`), and control characters. Falls back to `fallback`.
+ */
+export function sanitizeReturnPath(
+ value: string | null | undefined,
+ fallback: string = DEFAULT_RETURN_PATH,
+): string {
+ if (!value || typeof value !== "string") return fallback;
+ if (value.length > 512) return fallback;
+ if (!value.startsWith("/")) return fallback;
+ if (value.startsWith("//") || value.startsWith("/\\")) return fallback;
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: intentionally rejecting control chars
+ if (/[\u0000-\u001f\u007f\\]/.test(value)) return fallback;
+ // Never bounce back into the auth flow itself.
+ if (value === "/api/auth" || value.startsWith("/api/auth/")) return fallback;
+ try {
+ // Resolve against a dummy origin; if the origin changes, it wasn't a local path.
+ const url = new URL(value, "http://local.invalid");
+ if (url.origin !== "http://local.invalid") return fallback;
+ return `${url.pathname}${url.search}${url.hash}`;
+ } catch {
+ return fallback;
+ }
+}
+
+/** Build the CAS `service` URL for a login attempt. */
+export function buildServiceUrl(origin: string, state: string): string {
+ const url = new URL(CAS_CALLBACK_PATH, origin);
+ url.search = new URLSearchParams({ state }).toString();
+ return url.toString();
+}
+
+/**
+ * Check that a `service` URL is exactly one we would have generated for
+ * `expectedOrigin`. This prevents redeeming a ticket that CAS issued to a
+ * *different* service (e.g. a malicious site the victim logged into).
+ */
+export function isExpectedServiceUrl(service: unknown, expectedOrigin: string): boolean {
+ if (typeof service !== "string" || service.length > 2048) return false;
+ let url: URL;
+ let origin: string;
+ try {
+ url = new URL(service);
+ origin = new URL(expectedOrigin).origin;
+ } catch {
+ return false;
+ }
+ if (url.origin !== origin) return false;
+ if (url.pathname !== CAS_CALLBACK_PATH) return false;
+ if (url.hash) return false;
+ const keys = [...url.searchParams.keys()];
+ if (keys.length !== 1 || keys[0] !== "state") return false;
+ const state = url.searchParams.get("state");
+ if (!isValidState(state)) return false;
+ // Must round-trip to the exact canonical form we generate.
+ return buildServiceUrl(origin, state) === service;
+}
+
+export function buildLoginUrl(casBaseUrl: string, service: string): string {
+ return `${normalizeCasBaseUrl(casBaseUrl)}login?service=${encodeURIComponent(service)}`;
+}
+
+export function buildServiceValidateUrl(
+ casBaseUrl: string,
+ service: string,
+ ticket: string,
+): string {
+ return `${normalizeCasBaseUrl(casBaseUrl)}serviceValidate?service=${encodeURIComponent(
+ service,
+ )}&ticket=${encodeURIComponent(ticket)}`;
+}
+
+export function buildLogoutUrl(casBaseUrl: string, service?: string): string {
+ const base = `${normalizeCasBaseUrl(casBaseUrl)}logout`;
+ return service ? `${base}?service=${encodeURIComponent(service)}` : base;
+}
+
+export type CasValidationResult =
+ | { ok: true; netId: string }
+ | { ok: false; reason: "failure" | "invalid_user" | "malformed"; code?: string };
+
+const parser = new XMLParser({
+ removeNSPrefix: true,
+ // Don't expand entities (no XXE / billion-laughs style surprises).
+ processEntities: false,
+ // Keep values as strings — a numeric NetID must not become a number.
+ parseTagValue: false,
+ ignoreAttributes: false,
+ attributeNamePrefix: "@_",
+ trimValues: true,
+});
+
+function textOf(node: unknown): unknown {
+ if (node && typeof node === "object" && "#text" in node) {
+ return (node as { "#text": unknown })["#text"];
+ }
+ return node;
+}
+
+/**
+ * Parse a CAS v2 `serviceValidate` XML response.
+ * CAS is the authority on identity: on success we return its `user` as the NetID.
+ */
+export function parseServiceValidateResponse(xml: string): CasValidationResult {
+ let doc: unknown;
+ try {
+ doc = parser.parse(xml);
+ } catch {
+ return { ok: false, reason: "malformed" };
+ }
+ const response = (doc as { serviceResponse?: Record } | null)?.serviceResponse;
+ if (!response || typeof response !== "object") return { ok: false, reason: "malformed" };
+
+ if ("authenticationFailure" in response) {
+ const failure = response.authenticationFailure;
+ const code =
+ failure && typeof failure === "object" && "@_code" in failure
+ ? String((failure as { "@_code": unknown })["@_code"])
+ : undefined;
+ return { ok: false, reason: "failure", code };
+ }
+
+ const success = response.authenticationSuccess;
+ if (!success || typeof success !== "object") return { ok: false, reason: "malformed" };
+ const user = textOf((success as { user?: unknown }).user);
+ const netId = normalizeNetId(user);
+ if (!netId) return { ok: false, reason: "invalid_user" };
+ return { ok: true, netId };
+}
+
+/**
+ * Validate a service ticket against CAS (server-side). Never trust a NetID from
+ * the client — only what CAS returns here.
+ */
+export async function validateServiceTicket(opts: {
+ casBaseUrl: string;
+ service: string;
+ ticket: string;
+ timeoutMs?: number;
+ fetchImpl?: typeof fetch;
+}): Promise {
+ const { casBaseUrl, service, ticket, timeoutMs = CAS_VALIDATE_TIMEOUT_MS } = opts;
+ const fetchImpl = opts.fetchImpl ?? fetch;
+ if (!isValidTicket(ticket)) return { ok: false, reason: "failure", code: "INVALID_TICKET" };
+
+ const res = await fetchImpl(buildServiceValidateUrl(casBaseUrl, service, ticket), {
+ method: "GET",
+ headers: { Accept: "application/xml, text/xml" },
+ cache: "no-store",
+ redirect: "error",
+ signal: AbortSignal.timeout(timeoutMs),
+ });
+ if (!res.ok) {
+ throw new Error(`CAS serviceValidate returned HTTP ${res.status}`);
+ }
+ return parseServiceValidateResponse(await res.text());
+}
diff --git a/bun.lock b/bun.lock
index 69399bc..ff9f376 100644
--- a/bun.lock
+++ b/bun.lock
@@ -53,7 +53,6 @@
"name": "@the-forum/web",
"version": "0.1.0",
"dependencies": {
- "@auth/drizzle-adapter": "^1.11.1",
"@aws-sdk/client-s3": "^3.1004.0",
"@aws-sdk/s3-request-presigner": "^3.1004.0",
"@t3-oss/env-nextjs": "^0.13.10",
@@ -63,6 +62,7 @@
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"date-fns": "^4.1.0",
+ "fast-xml-parser": "^5.4.1",
"lucide-react": "^0.575.0",
"mapbox-gl": "^3.20.0",
"next": "^16.1.6",
@@ -97,9 +97,7 @@
"@antfu/ni": ["@antfu/ni@25.0.0", "", { "dependencies": { "ansis": "^4.0.0", "fzf": "^0.5.2", "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" }, "bin": { "na": "bin/na.mjs", "ni": "bin/ni.mjs", "nr": "bin/nr.mjs", "nci": "bin/nci.mjs", "nlx": "bin/nlx.mjs", "nun": "bin/nun.mjs", "nup": "bin/nup.mjs" } }, "sha512-9q/yCljni37pkMr4sPrI3G4jqdIk074+iukc5aFJl7kmDCCsiJrbZ6zKxnES1Gwg+i9RcDZwvktl23puGslmvA=="],
- "@auth/core": ["@auth/core@0.41.1", "", { "dependencies": { "@panva/hkdf": "^1.2.1", "jose": "^6.0.6", "oauth4webapi": "^3.3.0", "preact": "10.24.3", "preact-render-to-string": "6.5.11" }, "peerDependencies": { "@simplewebauthn/browser": "^9.0.1", "@simplewebauthn/server": "^9.0.2", "nodemailer": "^7.0.7" }, "optionalPeers": ["@simplewebauthn/browser", "@simplewebauthn/server", "nodemailer"] }, "sha512-t9cJ2zNYAdWMacGRMT6+r4xr1uybIdmYa49calBPeTqwgAFPV/88ac9TEvCR85pvATiSPt8VaNf+Gt24JIT/uw=="],
-
- "@auth/drizzle-adapter": ["@auth/drizzle-adapter@1.11.1", "", { "dependencies": { "@auth/core": "0.41.1" } }, "sha512-cQTvDZqsyF7RPhDm/B6SvqdVP9EzQhy3oM4Muu7fjjmSYFLbSR203E6dH631ZHSKDn2b4WZkfMnjPDzRsPSAeA=="],
+ "@auth/core": ["@auth/core@0.41.0", "", { "dependencies": { "@panva/hkdf": "^1.2.1", "jose": "^6.0.6", "oauth4webapi": "^3.3.0", "preact": "10.24.3", "preact-render-to-string": "6.5.11" }, "peerDependencies": { "@simplewebauthn/browser": "^9.0.1", "@simplewebauthn/server": "^9.0.2", "nodemailer": "^6.8.0" }, "optionalPeers": ["@simplewebauthn/browser", "@simplewebauthn/server", "nodemailer"] }, "sha512-Wd7mHPQ/8zy6Qj7f4T46vg3aoor8fskJm6g2Zyj064oQ3+p0xNZXAV60ww0hY+MbTesfu29kK14Zk5d5JTazXQ=="],
"@aws-crypto/crc32": ["@aws-crypto/crc32@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg=="],
@@ -1657,8 +1655,6 @@
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
- "next-auth/@auth/core": ["@auth/core@0.41.0", "", { "dependencies": { "@panva/hkdf": "^1.2.1", "jose": "^6.0.6", "oauth4webapi": "^3.3.0", "preact": "10.24.3", "preact-render-to-string": "6.5.11" }, "peerDependencies": { "@simplewebauthn/browser": "^9.0.1", "@simplewebauthn/server": "^9.0.2", "nodemailer": "^6.8.0" }, "optionalPeers": ["@simplewebauthn/browser", "@simplewebauthn/server", "nodemailer"] }, "sha512-Wd7mHPQ/8zy6Qj7f4T46vg3aoor8fskJm6g2Zyj064oQ3+p0xNZXAV60ww0hY+MbTesfu29kK14Zk5d5JTazXQ=="],
-
"npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="],
"prompts/kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="],
From 8697421b658f5a5aca44ff61b751caf2257260d9 Mon Sep 17 00:00:00 2001
From: DIodide
Date: Mon, 28 Sep 2026 02:43:02 -0400
Subject: [PATCH 21/69] feat(web)!: replace Microsoft Entra ID with Princeton
CAS login
Entra derived netId from the UPN/preferred_username with no domain check, allowing account takeover. Login now goes through Princeton CAS (fed.princeton.edu/cas):
- /api/auth/cas/login stores a 32-byte state + sanitized return path in short-lived httpOnly SameSite=Lax cookies and redirects to CAS.
- /api/auth/cas/callback timing-safe checks state, then calls Auth.js signIn('cas') in-process.
- The 'cas' Credentials provider's authorize() re-validates the ticket with CAS serviceValidate (15s timeout), pins the service URL to our own callback/origin, and upserts the user by NetID without clobbering edited displayName/email. CAS is the sole identity authority.
- Direct POSTs to /api/auth/{signin,callback}/cas are rejected.
- Sign-out clears the Auth.js session, then ends the CAS SSO session via /api/auth/cas/logout.
- New shadcn auth error page (pages.error = /auth/error), public in middleware.
- jwt callback tolerates DB errors, keeping last known token values.
- Env: drop AUTH_AZURE_*; add optional AUTH_URL and CAS_BASE_URL; document AUTH_TRUST_HOST.
---
.env.example | 13 +-
apps/web/.env.local.example | 15 +-
.../src/app/api/auth/[...nextauth]/route.ts | 26 ++-
.../src/app/api/auth/cas/callback/route.ts | 71 ++++++++
apps/web/src/app/api/auth/cas/login/route.ts | 44 +++++
apps/web/src/app/api/auth/cas/logout/route.ts | 22 +++
apps/web/src/app/auth/error/page.tsx | 97 ++++++++++
apps/web/src/app/page.tsx | 34 +---
apps/web/src/auth.ts | 171 +++++++++++-------
apps/web/src/components/layout/mobile-nav.tsx | 2 +-
apps/web/src/components/layout/sidebar.tsx | 2 +-
apps/web/src/env.ts | 16 +-
apps/web/src/lib/cas-server.ts | 38 ++++
apps/web/src/middleware.ts | 5 +-
apps/web/src/types/next-auth.d.ts | 6 +
15 files changed, 451 insertions(+), 111 deletions(-)
create mode 100644 apps/web/src/app/api/auth/cas/callback/route.ts
create mode 100644 apps/web/src/app/api/auth/cas/login/route.ts
create mode 100644 apps/web/src/app/api/auth/cas/logout/route.ts
create mode 100644 apps/web/src/app/auth/error/page.tsx
create mode 100644 apps/web/src/lib/cas-server.ts
diff --git a/.env.example b/.env.example
index f6f89ed..ecb2261 100644
--- a/.env.example
+++ b/.env.example
@@ -12,11 +12,16 @@ POSTGRES_PORT=5434
# ----- Database URL (used by Drizzle & Next.js) -----
DATABASE_URL=postgresql://forum:forum_password@localhost:5434/the_forum
-# ----- Auth.js (Microsoft Entra ID) -----
+# ----- Auth.js + Princeton CAS -----
+# Generate with: openssl rand -base64 32
AUTH_SECRET=your-auth-secret-here
-AUTH_AZURE_AD_CLIENT_ID=your-client-id
-AUTH_AZURE_AD_CLIENT_SECRET=your-client-secret
-AUTH_AZURE_AD_TENANT_ID=YOUR_TENANT_ID_HERE
+# Canonical public URL of the app. Required in production (pins the CAS service
+# URL and Auth.js callbacks to this origin). Optional locally.
+# AUTH_URL=https://forum.example.edu
+# Trust X-Forwarded-Host/Proto from your reverse proxy (not needed on Vercel or when AUTH_URL is set).
+# AUTH_TRUST_HOST=true
+# Princeton CAS server (default shown).
+# CAS_BASE_URL=https://fed.princeton.edu/cas/
# ----- AWS S3 (image uploads) -----
# AWS_S3_BUCKET=the-forum-uploads
diff --git a/apps/web/.env.local.example b/apps/web/.env.local.example
index b4438dc..d316400 100644
--- a/apps/web/.env.local.example
+++ b/apps/web/.env.local.example
@@ -5,14 +5,17 @@
# ----- Database (Docker default — see `bun run db:up`) -----
DATABASE_URL=postgresql://forum:forum_password@localhost:5434/the_forum
-# ----- Auth.js (Microsoft Entra ID / Princeton login) -----
+# ----- Auth.js + Princeton CAS login -----
# Generate AUTH_SECRET yourself: openssl rand -base64 32
AUTH_SECRET=YOUR_AUTH_SECRET_HERE
-# Ask Ibraheem for the client ID + secret
-AUTH_AZURE_AD_CLIENT_ID=YOUR_CLIENT_ID_HERE
-AUTH_AZURE_AD_CLIENT_SECRET=YOUR_CLIENT_SECRET_HERE
-# Princeton tenant ID (not secret)
-AUTH_AZURE_AD_TENANT_ID=2ff60116-7431-425d-b5af-077d7791bda4
+# Login uses Princeton CAS (no client ID/secret needed). CAS redirects back to
+# http://localhost:3000/api/auth/cas/callback in dev.
+# Canonical public URL — set this in production (e.g. https://forum.example.edu).
+# AUTH_URL=http://localhost:3000
+# Only needed behind a reverse proxy without AUTH_URL (Vercel sets this for you).
+# AUTH_TRUST_HOST=true
+# CAS server (default shown)
+# CAS_BASE_URL=https://fed.princeton.edu/cas/
# ----- Mapbox (ask Ibraheem for these) -----
NEXT_PUBLIC_MAPBOX_TOKEN=YOUR_MAPBOX_TOKEN_HERE
diff --git a/apps/web/src/app/api/auth/[...nextauth]/route.ts b/apps/web/src/app/api/auth/[...nextauth]/route.ts
index 16a2015..cf548c6 100644
--- a/apps/web/src/app/api/auth/[...nextauth]/route.ts
+++ b/apps/web/src/app/api/auth/[...nextauth]/route.ts
@@ -1,3 +1,25 @@
-import { handlers } from "~/auth";
+import type { NextRequest } from "next/server";
+import { CAS_PROVIDER_ID, handlers } from "~/auth";
-export const { GET, POST } = handlers;
+export const { GET } = handlers;
+
+/**
+ * The CAS Credentials provider must only be driven by our own
+ * `/api/auth/cas/callback` route (which verifies the `state` cookie and calls
+ * `signIn()` in-process). Refuse direct HTTP POSTs to its Auth.js endpoints.
+ *
+ * Defense in depth only: `authorize()` independently validates the ticket with
+ * CAS and pins the service URL to our origin.
+ */
+const blockedPaths = new Set([
+ `/api/auth/callback/${CAS_PROVIDER_ID}`,
+ `/api/auth/signin/${CAS_PROVIDER_ID}`,
+]);
+
+export function POST(req: NextRequest) {
+ const pathname = req.nextUrl.pathname.replace(/\/+$/, "");
+ if (blockedPaths.has(pathname)) {
+ return new Response("Not found", { status: 404 });
+ }
+ return handlers.POST(req);
+}
diff --git a/apps/web/src/app/api/auth/cas/callback/route.ts b/apps/web/src/app/api/auth/cas/callback/route.ts
new file mode 100644
index 0000000..2e19075
--- /dev/null
+++ b/apps/web/src/app/api/auth/cas/callback/route.ts
@@ -0,0 +1,71 @@
+import { AuthError } from "next-auth";
+import { cookies } from "next/headers";
+import { type NextRequest, NextResponse } from "next/server";
+import { CAS_PROVIDER_ID, signIn } from "~/auth";
+import {
+ CAS_COOKIE_PATH,
+ CAS_RETURN_COOKIE,
+ CAS_STATE_COOKIE,
+ buildServiceUrl,
+ isValidState,
+ isValidTicket,
+ safeCompare,
+ sanitizeReturnPath,
+} from "~/lib/cas";
+import { getAppOrigin } from "~/lib/cas-server";
+
+export const dynamic = "force-dynamic";
+
+/**
+ * GET /api/auth/cas/callback?state=…&ticket=ST-…
+ *
+ * CAS redirects here after login. We verify `state` against the cookie set by
+ * /api/auth/cas/login, then hand the ticket to the Auth.js CAS provider, whose
+ * `authorize()` validates it with CAS (serviceValidate) and upserts the user.
+ * On success `signIn()` sets the session cookie and throws a Next redirect to
+ * the saved return path, which Next turns into the response.
+ */
+export async function GET(req: NextRequest) {
+ const origin = getAppOrigin(req.headers, req.nextUrl.protocol);
+ const fail = (error: string) => {
+ const url = new URL("/auth/error", origin);
+ url.searchParams.set("error", error);
+ const res = NextResponse.redirect(url, 302);
+ res.headers.set("Cache-Control", "no-store");
+ return res;
+ };
+
+ const jar = await cookies();
+ const expectedState = jar.get(CAS_STATE_COOKIE)?.value;
+ const returnPath = sanitizeReturnPath(jar.get(CAS_RETURN_COOKIE)?.value);
+ // One-shot: the state/return cookies are consumed whatever happens next.
+ jar.delete({ name: CAS_STATE_COOKIE, path: CAS_COOKIE_PATH });
+ jar.delete({ name: CAS_RETURN_COOKIE, path: CAS_COOKIE_PATH });
+
+ const state = req.nextUrl.searchParams.get("state");
+ const ticket = req.nextUrl.searchParams.get("ticket");
+
+ if (!expectedState || !isValidState(state) || !safeCompare(state, expectedState)) {
+ return fail("CasState");
+ }
+ if (!isValidTicket(ticket)) {
+ return fail("CasTicket");
+ }
+
+ // Must be byte-for-byte the service we sent to CAS at login.
+ const service = buildServiceUrl(origin, state);
+
+ try {
+ await signIn(CAS_PROVIDER_ID, { ticket, service, redirectTo: returnPath });
+ } catch (error) {
+ // signIn() signals success by throwing Next's redirect — let it propagate.
+ if (error instanceof AuthError) {
+ console.warn(`[auth] CAS sign-in failed: ${error.type}`);
+ return fail(error.type === "CredentialsSignin" ? "CasValidation" : "CasUnavailable");
+ }
+ throw error;
+ }
+
+ // Unreachable in practice: signIn() always redirects.
+ return fail("Default");
+}
diff --git a/apps/web/src/app/api/auth/cas/login/route.ts b/apps/web/src/app/api/auth/cas/login/route.ts
new file mode 100644
index 0000000..a7eaf00
--- /dev/null
+++ b/apps/web/src/app/api/auth/cas/login/route.ts
@@ -0,0 +1,44 @@
+import { cookies } from "next/headers";
+import { type NextRequest, NextResponse } from "next/server";
+import {
+ CAS_COOKIE_MAX_AGE_SECONDS,
+ CAS_COOKIE_PATH,
+ CAS_RETURN_COOKIE,
+ CAS_STATE_COOKIE,
+ buildLoginUrl,
+ buildServiceUrl,
+ generateState,
+ sanitizeReturnPath,
+} from "~/lib/cas";
+import { casBaseUrl, getAppOrigin } from "~/lib/cas-server";
+
+export const dynamic = "force-dynamic";
+
+/**
+ * GET /api/auth/cas/login?callbackUrl=/some/path
+ *
+ * Starts a Princeton CAS login: stores a random `state` (anti login-CSRF) and a
+ * sanitized local return path in short-lived httpOnly cookies, then redirects
+ * to CAS with `service` pointing at our callback.
+ */
+export async function GET(req: NextRequest) {
+ const origin = getAppOrigin(req.headers, req.nextUrl.protocol);
+ const state = generateState();
+ const returnPath = sanitizeReturnPath(req.nextUrl.searchParams.get("callbackUrl"));
+ const service = buildServiceUrl(origin, state);
+
+ const cookieOptions = {
+ httpOnly: true,
+ sameSite: "lax" as const,
+ secure: origin.startsWith("https:"),
+ path: CAS_COOKIE_PATH,
+ maxAge: CAS_COOKIE_MAX_AGE_SECONDS,
+ };
+ const jar = await cookies();
+ jar.set(CAS_STATE_COOKIE, state, cookieOptions);
+ jar.set(CAS_RETURN_COOKIE, returnPath, cookieOptions);
+
+ const res = NextResponse.redirect(buildLoginUrl(casBaseUrl, service), 302);
+ res.headers.set("Cache-Control", "no-store");
+ return res;
+}
diff --git a/apps/web/src/app/api/auth/cas/logout/route.ts b/apps/web/src/app/api/auth/cas/logout/route.ts
new file mode 100644
index 0000000..e361fed
--- /dev/null
+++ b/apps/web/src/app/api/auth/cas/logout/route.ts
@@ -0,0 +1,22 @@
+import { type NextRequest, NextResponse } from "next/server";
+import { buildLogoutUrl } from "~/lib/cas";
+import { casBaseUrl, getAppOrigin } from "~/lib/cas-server";
+
+export const dynamic = "force-dynamic";
+
+/**
+ * GET /api/auth/cas/logout
+ *
+ * Final hop of sign-out: the client first calls Auth.js `signOut()` (which
+ * clears our session cookie via a CSRF-protected POST) with this route as the
+ * redirect target, and we then end the Princeton CAS SSO session too, so the
+ * next person on a shared computer isn't silently signed back in.
+ *
+ * This route itself changes no state on our side.
+ */
+export function GET(req: NextRequest) {
+ const origin = getAppOrigin(req.headers, req.nextUrl.protocol);
+ const res = NextResponse.redirect(buildLogoutUrl(casBaseUrl, `${origin}/`), 302);
+ res.headers.set("Cache-Control", "no-store");
+ return res;
+}
diff --git a/apps/web/src/app/auth/error/page.tsx b/apps/web/src/app/auth/error/page.tsx
new file mode 100644
index 0000000..64a02c8
--- /dev/null
+++ b/apps/web/src/app/auth/error/page.tsx
@@ -0,0 +1,97 @@
+import type { Metadata } from "next";
+import { Button } from "~/components/ui/button";
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "~/components/ui/card";
+
+export const metadata: Metadata = {
+ title: "Sign-in problem — Forum",
+ robots: { index: false },
+};
+
+type ErrorCopy = { title: string; description: string };
+
+/**
+ * Only known codes are rendered; the raw `error` query param is never echoed.
+ * Covers Auth.js' own codes (Configuration, AccessDenied, Verification, …)
+ * plus the ones our CAS routes emit.
+ */
+const ERRORS: Record = {
+ CasState: {
+ title: "Your sign-in session expired",
+ description:
+ "The sign-in link was opened in a different browser, took too long, or was already used. Please try again.",
+ },
+ CasTicket: {
+ title: "Princeton sign-in didn't complete",
+ description: "We didn't receive a valid response from Princeton CAS. Please try again.",
+ },
+ CasValidation: {
+ title: "We couldn't verify your Princeton login",
+ description:
+ "Princeton CAS didn't confirm this sign-in. This can happen if you refreshed or reused an old link. Please try again.",
+ },
+ CasUnavailable: {
+ title: "Sign-in is temporarily unavailable",
+ description:
+ "We couldn't reach Princeton CAS or finish setting up your account. Please try again in a moment.",
+ },
+ AccessDenied: {
+ title: "Access denied",
+ description: "You don't have permission to sign in to Forum.",
+ },
+ Configuration: {
+ title: "Sign-in is misconfigured",
+ description:
+ "Something is wrong on our end. Please try again later, and let the TigerApps team know if it keeps happening.",
+ },
+};
+
+const DEFAULT_ERROR: ErrorCopy = {
+ title: "Something went wrong signing you in",
+ description: "Please try again. If the problem persists, let the TigerApps team know.",
+};
+
+export default async function AuthErrorPage({
+ searchParams,
+}: {
+ searchParams: Promise<{ error?: string | string[] }>;
+}) {
+ const { error } = await searchParams;
+ const code = typeof error === "string" ? error : undefined;
+ const known = code !== undefined && Object.hasOwn(ERRORS, code);
+ const copy = known ? ERRORS[code] : DEFAULT_ERROR;
+
+ return (
+
+
+
+ The Forum
+ {copy.title}
+ {copy.description}
+
+ {code ? (
+
+
+ Error code: {known ? code : "Unknown"}
+
+
+ ) : null}
+
+ {/* Plain : these are route handlers / full navigations, not RSC pages. */}
+
+ Try again
+
+
+ Back to home
+
+
+
+
+ );
+}
diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx
index bc9a232..a2db67c 100644
--- a/apps/web/src/app/page.tsx
+++ b/apps/web/src/app/page.tsx
@@ -1,5 +1,3 @@
-import { signIn } from "~/auth";
-
export default function LandingPage() {
return (
@@ -25,12 +23,8 @@ export default function LandingPage() {
EVENT ORGANIZERS
-