--- /** * `/appendix`: the glossary of LeetCode topic tags the campaign meets without * teaching them as a topic (`appendix.ts`), one card per term, filed A–Z under * a letter index. A card is the target of that tag's badge on every problem * page (`/appendix#`, from `tagTarget()`), so it carries what the badge * shows (the term's icon in the tag's colour from `lib/tag-colors.ts`, over * the same tag universe `ProblemBadges.astro` colours) and lists the problem * pages whose badge links here: the backlinks a per-term page used to have. * Companies file into the same letters: one card per company any problem * page's `companies:` names (`companies.ts`), the target of that company's * pill in the page's company table, whose backlinks are the solved problems * it asked in the last six months, each with how recently. The filter is a * custom element over static markup, the way the Carousel is built; with no * JS the page is the full glossary. */ import { getEntry } from "astro:content"; import data from "blume:data"; import Icon from "blume/components/Icon.astro"; import { withBase } from "blume/components/islands/base-path.ts"; import PageLayout from "blume/components/layout/PageLayout.astro"; import { APPENDIX } from "../appendix.ts"; import { RECENCY, RECENCY_LABEL, companyHref, type Company } from "../companies.ts"; import { tagColors } from "../lib/tag-colors.ts"; import { TOPIC_LANDINGS, tagTarget, type TopicTag } from "../topic-landings.ts"; const { config } = data; const served = new Set(data.routes.map((r: { path: string }) => r.path)); // Problem pages (`. ` titles, the shape sync writes) with their tags. const problems = await Promise.all( data.routes .filter((r: { title: string }) => /^\d+\.\s/u.test(r.title)) .map(async (r: { path: string; title: string; collection: string; entryId: string }) => { const entry = await getEntry(r.collection, r.entryId); const [, num, name] = r.title.match(/^(\d+)\.\s+(.+)$/u)!; return { route: r.path, num: Number(num), name: name!, difficulty: entry?.data.sidebar?.badge as string | undefined, tags: (entry?.data.topics ?? []) as TopicTag[], companies: (entry?.data.companies ?? []) as Company[], }; }), ); const colors = tagColors( [...Object.keys(TOPIC_LANDINGS), ...Object.keys(APPENDIX)], problems.map((p) => p.tags.map((t) => t.slug)), ); /** One card: a glossary term or a company, filed together under its first letter. */ interface Entry { id: string; name: string; icon: string; color?: string; category: string; definition?: string; leetcode?: string; problems: { route: string; num: number; name: string; difficulty?: string; note?: string }[]; } const terms: Entry[] = Object.entries(APPENDIX).map(([slug, term]) => ({ id: slug, ...term, color: colors.get(slug), leetcode: `https://leetcode.com/problem-list/${slug}/`, problems: problems .filter((p) => p.tags.some((tag) => tagTarget(tag, p, served).href === `/appendix#${slug}`)) .sort((a, b) => a.num - b.num), })); // Every company a problem page names; its backlinks most recent window first, // then by number. const companies: Entry[] = [ ...Map.groupBy( problems.flatMap((p) => p.companies.map((c) => ({ ...p, company: c.name, period: c.period }))), (row) => row.company, ), ].map(([name, rows]) => ({ id: companyHref(name).slice("/appendix#".length), name, icon: "building-2", category: "Company", problems: rows .sort((a, b) => RECENCY.indexOf(a.period) - RECENCY.indexOf(b.period) || a.num - b.num) .map((row) => ({ ...row, note: `within ${RECENCY_LABEL[row.period]}` })), })); const sections = new Map(); for (const entry of [...terms, ...companies].sort((a, b) => a.name.localeCompare(b.name))) { const letter = entry.name[0]!.toUpperCase(); sections.set(letter, [...(sections.get(letter) ?? []), entry]); } const LETTERS = [..."ABCDEFGHIJKLMNOPQRSTUVWXYZ"]; // A card's Solved list shows this many rows at a time; a longer one (Array has // dozens) pages through them with numbered buttons under the list. const PAGE_SIZE = 5; // The /progress cards' difficulty palette (--chart-1..3 in theme.css), as on // the changelog, so a Hard reads the same colour everywhere. const DIFFICULTY: Record = { Easy: { label: "Easy", class: "border-chart-1/40 bg-chart-1/10 text-chart-1" }, Medium: { label: "Med.", class: "border-chart-2/40 bg-chart-2/10 text-chart-2" }, Hard: { label: "Hard", class: "border-chart-3/40 bg-chart-3/10 text-chart-3" }, }; const description = "The LeetCode topics the campaign meets without teaching them as a topic, what each one means and the solved problems that use it, and the companies that asked those problems in the last six months."; ---

Appendix

{description}

{ [...sections].map(([letter, group]) => (

{letter}

{group.map((entry) => ( ))}
)) }