@grove-dev/astro 0.1.5 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.d.ts +4 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +56 -22
- package/dist/index.js.map +1 -1
- package/dist/layouts/index.d.ts +25 -0
- package/dist/layouts/index.d.ts.map +1 -0
- package/dist/layouts/index.js +25 -0
- package/dist/layouts/index.js.map +1 -0
- package/dist/lib/display.d.ts +33 -0
- package/dist/lib/display.d.ts.map +1 -0
- package/dist/lib/display.js +104 -0
- package/dist/lib/display.js.map +1 -0
- package/dist/lib/format.d.ts +30 -0
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/format.js +73 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/lib/index.d.ts +26 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +26 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/lenses.d.ts +96 -0
- package/dist/lib/lenses.d.ts.map +1 -0
- package/dist/lib/lenses.js +181 -0
- package/dist/lib/lenses.js.map +1 -0
- package/dist/lib/repo.d.ts +30 -0
- package/dist/lib/repo.d.ts.map +1 -0
- package/dist/lib/repo.js +44 -0
- package/dist/lib/repo.js.map +1 -0
- package/dist/lib/scores.d.ts +38 -0
- package/dist/lib/scores.d.ts.map +1 -0
- package/dist/lib/scores.js +83 -0
- package/dist/lib/scores.js.map +1 -0
- package/dist/lib/search.d.ts +199 -0
- package/dist/lib/search.d.ts.map +1 -0
- package/dist/lib/search.js +357 -0
- package/dist/lib/search.js.map +1 -0
- package/dist/lib/taxonomy-counts.d.ts +25 -0
- package/dist/lib/taxonomy-counts.d.ts.map +1 -0
- package/dist/lib/taxonomy-counts.js +41 -0
- package/dist/lib/taxonomy-counts.js.map +1 -0
- package/package.json +7 -7
- package/src/components/AppsIndexRow.astro +204 -0
- package/src/components/AppsPagination.astro +126 -0
- package/src/components/CategoryGrid.astro +86 -17
- package/src/components/ContributorsGrid.astro +149 -0
- package/src/components/DecisionRow.astro +89 -0
- package/src/components/ExploreByCategory.astro +67 -0
- package/src/components/ExploreByStack.astro +72 -0
- package/src/components/Hero.astro +246 -0
- package/src/components/Icon.astro +223 -0
- package/src/components/ItemCard.astro +306 -30
- package/src/components/MinimalAbout.astro +82 -0
- package/src/components/OriginalCollection.astro +116 -0
- package/src/components/RecordSection.astro +88 -0
- package/src/components/RefinePanel.astro +197 -0
- package/src/components/ScoreBars.astro +92 -22
- package/src/components/SmartLensTabs.astro +71 -0
- package/src/components/StackGrid.astro +132 -0
- package/src/components/WhyThisExists.astro +116 -0
- package/src/index.ts +61 -14
- package/src/layouts/BaseLayout.astro +227 -15
- package/src/layouts/Container.astro +57 -0
- package/src/layouts/Footer.astro +235 -0
- package/src/layouts/Header.astro +159 -0
- package/src/layouts/SectionHeader.astro +58 -0
- package/{templates/default/src/components/layout → src/layouts}/Seo.astro +62 -38
- package/src/layouts/ThemeToggle.astro +110 -0
- package/src/layouts/astro-shim.d.ts +29 -0
- package/src/layouts/index.ts +24 -0
- package/src/lib/display.ts +118 -0
- package/src/lib/format.ts +65 -0
- package/src/lib/index.ts +26 -0
- package/src/lib/lenses.ts +241 -0
- package/src/lib/repo.ts +44 -0
- package/src/lib/scores.ts +94 -0
- package/src/lib/search.ts +481 -0
- package/src/lib/taxonomy-counts.ts +60 -0
- package/src/styles.css +366 -638
- package/templates/default/astro.config.mjs +8 -6
- package/templates/default/content/pages/about.md +66 -0
- package/templates/default/content/pages/methodology.md +103 -0
- package/templates/default/data/generated/records.full.json +8 -0
- package/templates/default/data/generated/records.index.json +7 -0
- package/templates/default/data/generated/records.json +8 -0
- package/templates/default/data/generated/site-config.json +31 -0
- package/templates/default/data/records/.gitkeep +0 -0
- package/templates/default/grove.config.ts +36 -0
- package/templates/default/package.json +6 -5
- package/templates/default/public/llms-full.txt +14 -0
- package/templates/default/public/llms.txt +11 -0
- package/templates/default/src/components/layout/BaseLayout.astro +10 -57
- package/templates/default/src/components/layout/Footer.astro +16 -134
- package/templates/default/src/components/layout/Header.astro +25 -126
- package/templates/default/src/data/records.ts +193 -0
- package/templates/default/src/lib/markdown.ts +171 -0
- package/templates/default/src/pages/about.astro +95 -429
- package/templates/default/src/pages/index.astro +263 -61
- package/templates/default/src/pages/projects/[slug].astro +480 -0
- package/templates/default/src/pages/projects/index.astro +193 -0
- package/templates/default/src/pages/sitemap.xml.ts +73 -61
- package/templates/default/src/pages/submit.astro +122 -411
- package/templates/default/src/styles/global.css +42 -68
- package/src/components/ActiveFilterChips.astro +0 -20
- package/src/components/DirectoryFilters.astro +0 -100
- package/src/components/DirectoryHero.astro +0 -32
- package/src/components/HealthBadge.astro +0 -12
- package/src/components/LensTabs.astro +0 -26
- package/src/components/MethodologyPanel.astro +0 -20
- package/src/components/Pagination.astro +0 -24
- package/src/components/ProjectDetail.astro +0 -166
- package/src/components/SubmitDraft.astro +0 -137
- package/templates/default/src/components/AppCard.astro +0 -248
- package/templates/default/src/components/AppSection.astro +0 -58
- package/templates/default/src/components/AppsIndexRow.astro +0 -230
- package/templates/default/src/components/AppsPagination.astro +0 -147
- package/templates/default/src/components/CategoryGrid.astro +0 -80
- package/templates/default/src/components/ContributorsGrid.astro +0 -105
- package/templates/default/src/components/DecisionRow.astro +0 -219
- package/templates/default/src/components/ExploreByCategory.astro +0 -74
- package/templates/default/src/components/ExploreByStack.astro +0 -102
- package/templates/default/src/components/Hero.astro +0 -176
- package/templates/default/src/components/MinimalAbout.astro +0 -57
- package/templates/default/src/components/OriginalCollection.astro +0 -144
- package/templates/default/src/components/RefinePanel.astro +0 -272
- package/templates/default/src/components/ScoreBars.astro +0 -72
- package/templates/default/src/components/SmartLensTabs.astro +0 -65
- package/templates/default/src/components/StackGrid.astro +0 -95
- package/templates/default/src/components/WhyThisExists.astro +0 -81
- package/templates/default/src/components/icons/Icon.astro +0 -148
- package/templates/default/src/components/layout/SectionHeader.astro +0 -42
- package/templates/default/src/components/layout/ThemeToggle.astro +0 -97
- package/templates/default/src/data/apps.ts +0 -149
- package/templates/default/src/data/categories.ts +0 -27
- package/templates/default/src/data/config.ts +0 -28
- package/templates/default/src/data/contributors.ts +0 -96
- package/templates/default/src/data/stacks.ts +0 -47
- package/templates/default/src/data/stats.ts +0 -65
- package/templates/default/src/data/types.ts +0 -248
- package/templates/default/src/lib/apps-search.ts +0 -228
- package/templates/default/src/lib/format.ts +0 -36
- package/templates/default/src/lib/lenses.ts +0 -98
- package/templates/default/src/lib/repo.ts +0 -12
- package/templates/default/src/lib/scores.ts +0 -51
- package/templates/default/src/lib/taxonomy-counts.ts +0 -31
- package/templates/default/src/pages/apps/[slug].astro +0 -709
- package/templates/default/src/pages/apps/index.astro +0 -669
- package/templates/default/src/pages/contributors.astro +0 -142
|
@@ -1,66 +1,268 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Home page — the showcase's front door.
|
|
4
|
+
*
|
|
5
|
+
* Sections (in order):
|
|
6
|
+
* 1. Hero — brand + search + stats row
|
|
7
|
+
* 2. WhyThisExists — 3 short value-prop points
|
|
8
|
+
* 3. RecordSection "Trending" — hot lens (stars >= 1000 OR pushed <= 30d)
|
|
9
|
+
* 4. RecordSection "Recently added" — new lens (pushed <= 7d OR curated "new")
|
|
10
|
+
* 5. RecordSection "Established" — mature lens (tier=curated, pushed > 365d)
|
|
11
|
+
* 6. StackGrid — browse by stack
|
|
12
|
+
* 7. CategoryGrid — browse by category
|
|
13
|
+
* 8. ContributorsGrid — top contributors (when available)
|
|
14
|
+
* 9. OriginalCollection — origin-card link to the source repo
|
|
15
|
+
*
|
|
16
|
+
* Every section is defensive: with 0 records (fresh scaffold) it
|
|
17
|
+
* renders a graceful empty state instead of throwing.
|
|
18
|
+
*
|
|
19
|
+
* V1 source-of-truth types are from `@grove-dev/core`. The slim
|
|
20
|
+
* `IndexProjectRecord` shape is what the home page consumes (no
|
|
21
|
+
* `as ProjectRecord` casts); the full `Resource` only flows into
|
|
22
|
+
* the detail page.
|
|
23
|
+
*/
|
|
24
|
+
import siteConfig from "../../data/generated/site-config.json";
|
|
25
|
+
import { records, fullRecords, projects, indexSlug, itemLabel } from "../data/records";
|
|
26
|
+
import BaseLayout from "@grove-dev/astro/layouts/BaseLayout.astro";
|
|
27
|
+
import Hero from "@grove-dev/astro/components/Hero.astro";
|
|
28
|
+
import WhyThisExists from "@grove-dev/astro/components/WhyThisExists.astro";
|
|
29
|
+
import RecordSection from "@grove-dev/astro/components/RecordSection.astro";
|
|
30
|
+
import StackGrid from "@grove-dev/astro/components/StackGrid.astro";
|
|
31
|
+
import CategoryGrid from "@grove-dev/astro/components/CategoryGrid.astro";
|
|
32
|
+
import ContributorsGrid from "@grove-dev/astro/components/ContributorsGrid.astro";
|
|
33
|
+
import OriginalCollection from "@grove-dev/astro/components/OriginalCollection.astro";
|
|
34
|
+
import { countByCategory, countByStack } from "@grove-dev/astro";
|
|
35
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
36
|
+
import { fileURLToPath } from "node:url";
|
|
37
|
+
import { dirname, resolve } from "node:path";
|
|
38
|
+
import type { IndexProjectRecord } from "@grove-dev/core";
|
|
39
|
+
|
|
40
|
+
const slug = indexSlug();
|
|
41
|
+
const projectKind = projects;
|
|
42
|
+
|
|
43
|
+
// ── Hero stats ──────────────────────────────────────────────────
|
|
44
|
+
const totalApps = fullRecords.filter((r) => r.kind === "project").length;
|
|
45
|
+
const totalCategories = new Set(projectKind.map((r) => r.category).filter(Boolean))
|
|
46
|
+
.size;
|
|
47
|
+
const totalStacks = new Set(
|
|
48
|
+
projectKind.flatMap((r) => [r.stack, ...(r.stacks ?? [])]).filter(Boolean),
|
|
49
|
+
).size;
|
|
50
|
+
const totalContributors = new Set(
|
|
51
|
+
projectKind
|
|
52
|
+
.map((r) => {
|
|
53
|
+
const url = r.repoUrl ?? r.links?.github ?? "";
|
|
54
|
+
const m = /github\.com\/([^/]+)\//.exec(url);
|
|
55
|
+
return m?.[1];
|
|
56
|
+
})
|
|
57
|
+
.filter(Boolean),
|
|
58
|
+
).size;
|
|
59
|
+
const totalStars = projectKind.reduce(
|
|
60
|
+
(acc, r) => acc + (r.github?.stars ?? 0),
|
|
61
|
+
0,
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
// ── Lens sectioning (Hot / New / Mature) ────────────────────────
|
|
65
|
+
const DAY_MS = 86_400_000;
|
|
66
|
+
function daysSince(iso: string | null | undefined): number {
|
|
67
|
+
if (!iso) return Infinity;
|
|
68
|
+
const d = new Date(iso);
|
|
69
|
+
if (Number.isNaN(d.valueOf())) return Infinity;
|
|
70
|
+
return (Date.now() - d.valueOf()) / DAY_MS;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const hot = projectKind
|
|
74
|
+
.filter((r: IndexProjectRecord) => {
|
|
75
|
+
const stars = r.github?.stars ?? 0;
|
|
76
|
+
const pushedAt = r.github?.pushedAt ?? null;
|
|
77
|
+
const pushed = daysSince(pushedAt);
|
|
78
|
+
const labelledHot = r.curation?.labels?.includes("hot") ?? false;
|
|
79
|
+
return labelledHot || stars >= 1000 || pushed <= 30;
|
|
80
|
+
})
|
|
81
|
+
.slice(0, 6);
|
|
82
|
+
|
|
83
|
+
const newItems = projectKind
|
|
84
|
+
.filter((r: IndexProjectRecord) => {
|
|
85
|
+
const pushedAt = r.github?.pushedAt ?? null;
|
|
86
|
+
const pushed = daysSince(pushedAt);
|
|
87
|
+
const labelledNew = r.curation?.labels?.includes("new") ?? false;
|
|
88
|
+
return pushed <= 7 || labelledNew;
|
|
89
|
+
})
|
|
90
|
+
.slice(0, 6);
|
|
91
|
+
|
|
92
|
+
const mature = projectKind
|
|
93
|
+
.filter((r: IndexProjectRecord) => {
|
|
94
|
+
const tier = r.health?.tier;
|
|
95
|
+
const pushedAt = r.github?.pushedAt ?? null;
|
|
96
|
+
const pushed = daysSince(pushedAt);
|
|
97
|
+
return tier === "curated" && pushed > 365;
|
|
98
|
+
})
|
|
99
|
+
.slice(0, 6);
|
|
100
|
+
|
|
101
|
+
// ── Stack / category aggregates ─────────────────────────────────
|
|
102
|
+
const stackCounts = countByStack(projectKind);
|
|
103
|
+
const stacks = [...stackCounts.entries()]
|
|
104
|
+
.sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
|
|
105
|
+
.slice(0, 12)
|
|
106
|
+
.map(([name, count]) => ({ name, slug: name, count }));
|
|
107
|
+
|
|
108
|
+
const categoryCounts = countByCategory(projectKind);
|
|
109
|
+
const categories = [...categoryCounts.entries()]
|
|
110
|
+
.sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
|
|
111
|
+
.map(([name, count]) => ({ name, slug: name, count }));
|
|
112
|
+
|
|
113
|
+
// ── Contributors (best-effort, from records) ────────────────────
|
|
114
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
115
|
+
const contributorsPath = [
|
|
116
|
+
resolve(here, "..", "..", "data", "generated", "contributors.json"),
|
|
117
|
+
resolve(process.cwd(), "data", "generated", "contributors.json"),
|
|
118
|
+
].find((p) => existsSync(p));
|
|
119
|
+
|
|
120
|
+
interface ContributorsFile {
|
|
121
|
+
contributors?: Array<{
|
|
122
|
+
username: string;
|
|
123
|
+
name?: string;
|
|
124
|
+
avatarUrl?: string;
|
|
125
|
+
profileUrl?: string;
|
|
126
|
+
contributions?: number;
|
|
127
|
+
}>;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let contributors: ContributorsFile["contributors"] = [];
|
|
131
|
+
if (contributorsPath) {
|
|
132
|
+
try {
|
|
133
|
+
const parsed = JSON.parse(readFileSync(contributorsPath, "utf8")) as ContributorsFile;
|
|
134
|
+
contributors = parsed.contributors ?? [];
|
|
135
|
+
} catch {
|
|
136
|
+
contributors = [];
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const hasContributors = contributors && contributors.length > 0;
|
|
140
|
+
|
|
141
|
+
// ── OriginalCollection (repo-stats.json if present) ─────────────
|
|
142
|
+
interface RepoStats {
|
|
143
|
+
originalRepo?: string;
|
|
144
|
+
stars?: number;
|
|
145
|
+
forks?: number;
|
|
146
|
+
contributors?: number;
|
|
147
|
+
description?: string;
|
|
148
|
+
}
|
|
149
|
+
let repoStats: RepoStats = {};
|
|
150
|
+
const repoStatsPath = [
|
|
151
|
+
resolve(here, "..", "..", "data", "generated", "repo-stats.json"),
|
|
152
|
+
resolve(process.cwd(), "data", "generated", "repo-stats.json"),
|
|
153
|
+
].find((p) => existsSync(p));
|
|
154
|
+
if (repoStatsPath) {
|
|
155
|
+
try {
|
|
156
|
+
repoStats = JSON.parse(readFileSync(repoStatsPath, "utf8")) as RepoStats;
|
|
157
|
+
} catch {
|
|
158
|
+
repoStats = {};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const title = `${siteConfig.name} — ${siteConfig.tagline}`;
|
|
23
163
|
const description =
|
|
24
|
-
|
|
164
|
+
siteConfig.description ?? `A growing community knowledge site powered by Grove.`;
|
|
165
|
+
|
|
166
|
+
// ── Render-time helpers ─────────────────────────────────────────
|
|
167
|
+
function detailHrefFor(r: IndexProjectRecord): string {
|
|
168
|
+
return `/${slug}/${r.slug}`;
|
|
169
|
+
}
|
|
25
170
|
---
|
|
26
171
|
|
|
27
|
-
<BaseLayout
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
172
|
+
<BaseLayout
|
|
173
|
+
title={title}
|
|
174
|
+
description={description}
|
|
175
|
+
site={siteConfig}
|
|
176
|
+
submitHref="/submit"
|
|
177
|
+
submitLabel={`Submit ${itemLabel()}`}
|
|
178
|
+
>
|
|
179
|
+
<Hero
|
|
180
|
+
name={siteConfig.name}
|
|
181
|
+
tagline={siteConfig.tagline}
|
|
182
|
+
description={description}
|
|
183
|
+
eyebrow="Curated directory"
|
|
184
|
+
searchPlaceholder={`Search ${slug}...`}
|
|
185
|
+
searchHref={`/${slug}`}
|
|
186
|
+
stats={{
|
|
187
|
+
apps: totalApps,
|
|
188
|
+
categories: totalCategories,
|
|
189
|
+
stacks: totalStacks,
|
|
190
|
+
contributors: totalContributors || undefined,
|
|
191
|
+
stars: totalStars || undefined,
|
|
192
|
+
}}
|
|
193
|
+
ctas={[
|
|
194
|
+
{ label: `Browse ${slug}`, href: `/${slug}`, variant: "primary" },
|
|
195
|
+
{ label: "About", href: "/about", variant: "outline" },
|
|
196
|
+
]}
|
|
197
|
+
/>
|
|
198
|
+
|
|
199
|
+
<WhyThisExists />
|
|
200
|
+
|
|
201
|
+
<RecordSection
|
|
202
|
+
id="hot"
|
|
203
|
+
title="Trending"
|
|
204
|
+
description="The projects getting attention right now — high-star repos and recently active codebases."
|
|
205
|
+
items={hot}
|
|
206
|
+
hrefFor={detailHrefFor}
|
|
207
|
+
viewAllHref={`/${slug}?lens=hot`}
|
|
208
|
+
eyebrow="Hot"
|
|
209
|
+
emptyLabel="No trending projects yet."
|
|
210
|
+
/>
|
|
211
|
+
|
|
212
|
+
<RecordSection
|
|
213
|
+
id="new"
|
|
214
|
+
title="Recently added"
|
|
215
|
+
description="Fresh entries — pushed within the last week or carrying the curated 'new' label."
|
|
216
|
+
items={newItems}
|
|
217
|
+
hrefFor={detailHrefFor}
|
|
218
|
+
viewAllHref={`/${slug}?lens=new`}
|
|
219
|
+
eyebrow="New"
|
|
220
|
+
emptyLabel="No new projects yet."
|
|
221
|
+
/>
|
|
222
|
+
|
|
223
|
+
<RecordSection
|
|
224
|
+
id="mature"
|
|
225
|
+
title="Established"
|
|
226
|
+
description="Long-running curated projects with deep history and stable architecture."
|
|
227
|
+
items={mature}
|
|
228
|
+
hrefFor={detailHrefFor}
|
|
229
|
+
viewAllHref={`/${slug}?lens=mature`}
|
|
230
|
+
eyebrow="Mature"
|
|
231
|
+
emptyLabel="No established projects yet."
|
|
232
|
+
/>
|
|
233
|
+
|
|
234
|
+
{stacks.length > 0 && (
|
|
235
|
+
<StackGrid
|
|
236
|
+
stacks={stacks}
|
|
237
|
+
pathPrefix={`/${slug}`}
|
|
238
|
+
/>
|
|
239
|
+
)}
|
|
240
|
+
|
|
241
|
+
{categories.length > 0 && (
|
|
242
|
+
<CategoryGrid
|
|
243
|
+
categories={categories}
|
|
244
|
+
pathPrefix={`/${slug}`}
|
|
245
|
+
/>
|
|
246
|
+
)}
|
|
247
|
+
|
|
248
|
+
{hasContributors && (
|
|
249
|
+
<ContributorsGrid
|
|
250
|
+
contributors={contributors!}
|
|
251
|
+
total={contributors!.length}
|
|
252
|
+
viewAllHref={siteConfig.repoUrl || undefined}
|
|
253
|
+
viewAllLabel="View on GitHub"
|
|
254
|
+
/>
|
|
255
|
+
)}
|
|
256
|
+
|
|
257
|
+
{repoStats.originalRepo && (
|
|
258
|
+
<OriginalCollection
|
|
259
|
+
repoUrl={repoStats.originalRepo}
|
|
260
|
+
stats={{
|
|
261
|
+
stars: repoStats.stars,
|
|
262
|
+
forks: repoStats.forks,
|
|
263
|
+
contributors: repoStats.contributors,
|
|
264
|
+
description: repoStats.description,
|
|
265
|
+
}}
|
|
266
|
+
/>
|
|
267
|
+
)}
|
|
66
268
|
</BaseLayout>
|