@grove-dev/core 0.2.21 → 0.3.2
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/README.md +16 -142
- package/dist/build-data.d.ts.map +1 -1
- package/dist/build-data.js +40 -4
- package/dist/build-data.js.map +1 -1
- package/dist/config.d.ts +3 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/contributors.d.ts +24 -0
- package/dist/contributors.d.ts.map +1 -0
- package/dist/contributors.js +90 -0
- package/dist/contributors.js.map +1 -0
- package/dist/directory-client.d.ts +11 -0
- package/dist/directory-client.d.ts.map +1 -0
- package/dist/directory-client.js +11 -0
- package/dist/directory-client.js.map +1 -0
- package/dist/directory-display.d.ts +27 -0
- package/dist/directory-display.d.ts.map +1 -0
- package/dist/directory-display.js +104 -0
- package/dist/directory-display.js.map +1 -0
- package/dist/directory-format.d.ts +29 -0
- package/dist/directory-format.d.ts.map +1 -0
- package/dist/directory-format.js +72 -0
- package/dist/directory-format.js.map +1 -0
- package/dist/directory-lenses.d.ts +59 -0
- package/dist/directory-lenses.d.ts.map +1 -0
- package/dist/directory-lenses.js +199 -0
- package/dist/directory-lenses.js.map +1 -0
- package/dist/directory-repo.d.ts +20 -0
- package/dist/directory-repo.d.ts.map +1 -0
- package/dist/directory-repo.js +31 -0
- package/dist/directory-repo.js.map +1 -0
- package/dist/directory-scores.d.ts +37 -0
- package/dist/directory-scores.d.ts.map +1 -0
- package/dist/directory-scores.js +76 -0
- package/dist/directory-scores.js.map +1 -0
- package/dist/directory-search.d.ts +119 -0
- package/dist/directory-search.d.ts.map +1 -0
- package/dist/directory-search.js +398 -0
- package/dist/directory-search.js.map +1 -0
- package/dist/directory-taxonomy.d.ts +11 -0
- package/dist/directory-taxonomy.d.ts.map +1 -0
- package/dist/directory-taxonomy.js +22 -0
- package/dist/directory-taxonomy.js.map +1 -0
- package/dist/index.d.ts +13 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -7
- package/dist/index.js.map +1 -1
- package/dist/llms.d.ts.map +1 -1
- package/dist/llms.js +11 -4
- package/dist/llms.js.map +1 -1
- package/dist/prepare.d.ts +18 -0
- package/dist/prepare.d.ts.map +1 -0
- package/dist/prepare.js +72 -0
- package/dist/prepare.js.map +1 -0
- package/dist/schema.d.ts +54 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +30 -0
- package/dist/schema.js.map +1 -1
- package/dist/sitemap.d.ts.map +1 -1
- package/dist/sitemap.js +4 -1
- package/dist/sitemap.js.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +41 -0
- package/dist/validate.js.map +1 -1
- package/package.json +9 -2
- package/dist/build-data.test.d.ts +0 -2
- package/dist/build-data.test.d.ts.map +0 -1
- package/dist/build-data.test.js +0 -171
- package/dist/build-data.test.js.map +0 -1
- package/dist/decisions.test.d.ts +0 -2
- package/dist/decisions.test.d.ts.map +0 -1
- package/dist/decisions.test.js +0 -205
- package/dist/decisions.test.js.map +0 -1
- package/dist/enrich.test.d.ts +0 -2
- package/dist/enrich.test.d.ts.map +0 -1
- package/dist/enrich.test.js +0 -105
- package/dist/enrich.test.js.map +0 -1
- package/dist/github-client.test.d.ts +0 -2
- package/dist/github-client.test.d.ts.map +0 -1
- package/dist/github-client.test.js +0 -176
- package/dist/github-client.test.js.map +0 -1
- package/dist/github.test.d.ts +0 -2
- package/dist/github.test.d.ts.map +0 -1
- package/dist/github.test.js +0 -73
- package/dist/github.test.js.map +0 -1
- package/dist/health.test.d.ts +0 -2
- package/dist/health.test.d.ts.map +0 -1
- package/dist/health.test.js +0 -183
- package/dist/health.test.js.map +0 -1
- package/dist/importer.test.d.ts +0 -2
- package/dist/importer.test.d.ts.map +0 -1
- package/dist/importer.test.js +0 -173
- package/dist/importer.test.js.map +0 -1
- package/dist/slug.test.d.ts +0 -2
- package/dist/slug.test.d.ts.map +0 -1
- package/dist/slug.test.js +0 -101
- package/dist/slug.test.js.map +0 -1
- package/dist/validate.test.d.ts +0 -2
- package/dist/validate.test.d.ts.map +0 -1
- package/dist/validate.test.js +0 -249
- package/dist/validate.test.js.map +0 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { IndexRecord } from "./schema.js";
|
|
2
|
+
/**
|
|
3
|
+
* URL-driven filter state for the /items discovery page.
|
|
4
|
+
*
|
|
5
|
+
* Multi-value fields use repeated keys in the URL: `?stack=Flutter&stack=React+Native`.
|
|
6
|
+
* Empty / undefined fields mean "no filter on this dimension".
|
|
7
|
+
*/
|
|
8
|
+
export type IndexFilters = {
|
|
9
|
+
q?: string;
|
|
10
|
+
stacks?: string[];
|
|
11
|
+
platforms?: string[];
|
|
12
|
+
categories?: string[];
|
|
13
|
+
tags?: string[];
|
|
14
|
+
labels?: string[];
|
|
15
|
+
licenses?: string[];
|
|
16
|
+
statuses?: string[];
|
|
17
|
+
/** A curated lens (e.g. "good-to-learn", "production-like"). Single value. */
|
|
18
|
+
lens?: string;
|
|
19
|
+
/** Sort order. Single value, defaults to "recently-updated". */
|
|
20
|
+
sort?: IndexSort | undefined;
|
|
21
|
+
/** 1-based page number. */
|
|
22
|
+
page?: number | undefined;
|
|
23
|
+
};
|
|
24
|
+
/** Available sort orders, in UI order. */
|
|
25
|
+
export declare const SORT_OPTIONS: readonly [{
|
|
26
|
+
readonly value: "recently-updated";
|
|
27
|
+
readonly label: "Recently updated";
|
|
28
|
+
}, {
|
|
29
|
+
readonly value: "most-starred";
|
|
30
|
+
readonly label: "Most starred";
|
|
31
|
+
}, {
|
|
32
|
+
readonly value: "recently-added";
|
|
33
|
+
readonly label: "Recently added";
|
|
34
|
+
}, {
|
|
35
|
+
readonly value: "best-overall";
|
|
36
|
+
readonly label: "Best overall";
|
|
37
|
+
}, {
|
|
38
|
+
readonly value: "alphabetical";
|
|
39
|
+
readonly label: "Alphabetical";
|
|
40
|
+
}];
|
|
41
|
+
export type IndexSort = (typeof SORT_OPTIONS)[number]["value"];
|
|
42
|
+
/**
|
|
43
|
+
* Read filters from a URLSearchParams (or anything URLSearchParams-shaped,
|
|
44
|
+
* e.g. the result of `new URL(req.url).searchParams`).
|
|
45
|
+
*/
|
|
46
|
+
export declare function filtersFromSearchParams(sp: URLSearchParams): IndexFilters;
|
|
47
|
+
/**
|
|
48
|
+
* Serialize a filters object back to URLSearchParams.
|
|
49
|
+
* Undefined / empty values are dropped. Defaults (sort, page 1, comfortable
|
|
50
|
+
* density) are also dropped to keep URLs short and canonical.
|
|
51
|
+
*/
|
|
52
|
+
export declare function searchParamsFromFilters(f: IndexFilters): URLSearchParams;
|
|
53
|
+
/** True if any filter is active (i.e. the result list isn't "all items"). */
|
|
54
|
+
export declare function hasAnyFilter(f: IndexFilters): boolean;
|
|
55
|
+
/** How many items per page. Constant for now; future versions may vary. */
|
|
56
|
+
export declare const PAGE_SIZE = 20;
|
|
57
|
+
export declare function applySort(items: IndexRecord[], sort: IndexSort): IndexRecord[];
|
|
58
|
+
/** Slice an array for a given page (1-based). */
|
|
59
|
+
export declare function paginate<T>(items: T[], page: number, pageSize?: number): T[];
|
|
60
|
+
/** Total number of pages given an item count. Always >= 1. */
|
|
61
|
+
export declare function totalPages(itemCount: number, pageSize?: number): number;
|
|
62
|
+
/** Resolve the effective sort from a filters object, applying default. */
|
|
63
|
+
export declare function effectiveSort(f: IndexFilters): IndexSort;
|
|
64
|
+
/** Resolve the effective page from a filters object, applying default. */
|
|
65
|
+
export declare function effectivePage(f: IndexFilters): number;
|
|
66
|
+
/**
|
|
67
|
+
* Return the subset of items that match all active filters (AND across
|
|
68
|
+
* dimensions, OR within a dimension).
|
|
69
|
+
*
|
|
70
|
+
* `q` is a case-insensitive substring search across name, owner,
|
|
71
|
+
* description, and category. Other dimensions are exact match.
|
|
72
|
+
*/
|
|
73
|
+
export declare function filterRecords(items: IndexRecord[], f: IndexFilters): IndexRecord[];
|
|
74
|
+
/** Build a flat list of "active filter" chips for display + removal. */
|
|
75
|
+
export declare function activeFilterChips(f: IndexFilters): {
|
|
76
|
+
key: keyof IndexFilters;
|
|
77
|
+
value: string;
|
|
78
|
+
label: string;
|
|
79
|
+
}[];
|
|
80
|
+
/**
|
|
81
|
+
* Return a new filters object with one (key, value) removed.
|
|
82
|
+
* - scalar keys (`q`, `lens`) → clears the value
|
|
83
|
+
* - multi-value keys → removes the single matching value
|
|
84
|
+
* Used by the "x" button on each active filter chip.
|
|
85
|
+
* Also resets page to 1 so the user doesn't get stranded on a high page
|
|
86
|
+
* that no longer has results.
|
|
87
|
+
*/
|
|
88
|
+
export declare function removeFilter(f: IndexFilters, key: keyof IndexFilters, value: string): IndexFilters;
|
|
89
|
+
/**
|
|
90
|
+
* Build the full list of facet values from the items array, preserving
|
|
91
|
+
* a sensible order (frequency desc, then alphabetical for ties).
|
|
92
|
+
*/
|
|
93
|
+
export declare function buildFacets(items: IndexRecord[]): {
|
|
94
|
+
stacks: {
|
|
95
|
+
value: string;
|
|
96
|
+
count: number;
|
|
97
|
+
}[];
|
|
98
|
+
platforms: {
|
|
99
|
+
value: string;
|
|
100
|
+
count: number;
|
|
101
|
+
}[];
|
|
102
|
+
categories: {
|
|
103
|
+
value: string;
|
|
104
|
+
count: number;
|
|
105
|
+
}[];
|
|
106
|
+
tags: {
|
|
107
|
+
value: string;
|
|
108
|
+
count: number;
|
|
109
|
+
}[];
|
|
110
|
+
labels: {
|
|
111
|
+
value: string;
|
|
112
|
+
count: number;
|
|
113
|
+
}[];
|
|
114
|
+
licenses: {
|
|
115
|
+
value: string;
|
|
116
|
+
count: number;
|
|
117
|
+
}[];
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=directory-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directory-search.d.ts","sourceRoot":"","sources":["../src/directory-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAC7B,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;EAMf,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;AAoB/D;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,eAAe,GAAG,YAAY,CAyBzE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,YAAY,GAAG,eAAe,CAcxE;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,GAAG,OAAO,CAYrD;AAED,2EAA2E;AAC3E,eAAO,MAAM,SAAS,KAAoB,CAAC;AAyB3C,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,WAAW,EAAE,CA8B9E;AAED,iDAAiD;AACjD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAY,GAAG,CAAC,EAAE,CAG/E;AAED,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,SAAY,GAAG,MAAM,CAE1E;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,CAAC,EAAE,YAAY,GAAG,SAAS,CAExD;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAErD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC,EAAE,YAAY,GAAG,WAAW,EAAE,CAiGlF;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,YAAY,GACd;IAAE,GAAG,EAAE,MAAM,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAwC7D;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,CAAC,EAAE,YAAY,EACf,GAAG,EAAE,MAAM,YAAY,EACvB,KAAK,EAAE,MAAM,GACZ,YAAY,CAwBd;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;EAmC/C"}
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
import { labelDisplay, lensDisplay, statusDisplay } from "./directory-display.js";
|
|
2
|
+
/** Available sort orders, in UI order. */
|
|
3
|
+
export const SORT_OPTIONS = [
|
|
4
|
+
{ value: "recently-updated", label: "Recently updated" },
|
|
5
|
+
{ value: "most-starred", label: "Most starred" },
|
|
6
|
+
{ value: "recently-added", label: "Recently added" },
|
|
7
|
+
{ value: "best-overall", label: "Best overall" },
|
|
8
|
+
{ value: "alphabetical", label: "Alphabetical" },
|
|
9
|
+
];
|
|
10
|
+
const DEFAULT_SORT = "recently-updated";
|
|
11
|
+
const DEFAULT_PAGE = 1;
|
|
12
|
+
const DEFAULT_PAGE_SIZE = 20;
|
|
13
|
+
const KEYS = {
|
|
14
|
+
q: "q",
|
|
15
|
+
stacks: "stack",
|
|
16
|
+
platforms: "platform",
|
|
17
|
+
categories: "category",
|
|
18
|
+
tags: "tag",
|
|
19
|
+
labels: "label",
|
|
20
|
+
licenses: "license",
|
|
21
|
+
statuses: "status",
|
|
22
|
+
lens: "lens",
|
|
23
|
+
sort: "sort",
|
|
24
|
+
page: "page",
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Read filters from a URLSearchParams (or anything URLSearchParams-shaped,
|
|
28
|
+
* e.g. the result of `new URL(req.url).searchParams`).
|
|
29
|
+
*/
|
|
30
|
+
export function filtersFromSearchParams(sp) {
|
|
31
|
+
const rawSort = sp.get(KEYS.sort);
|
|
32
|
+
// Backwards-compat: old "most-mature" sort now maps to "best-overall".
|
|
33
|
+
const normalizedSort = rawSort === "most-mature" ? "best-overall" : rawSort;
|
|
34
|
+
const sort = normalizedSort && SORT_OPTIONS.some((o) => o.value === normalizedSort)
|
|
35
|
+
? normalizedSort
|
|
36
|
+
: undefined;
|
|
37
|
+
const rawPage = Number(sp.get(KEYS.page));
|
|
38
|
+
const page = Number.isFinite(rawPage) && rawPage >= 1 ? Math.floor(rawPage) : undefined;
|
|
39
|
+
const q = sp.get(KEYS.q);
|
|
40
|
+
const lens = sp.get(KEYS.lens);
|
|
41
|
+
return {
|
|
42
|
+
...(q !== null ? { q } : {}),
|
|
43
|
+
stacks: sp.getAll(KEYS.stacks).filter(Boolean),
|
|
44
|
+
platforms: sp.getAll(KEYS.platforms).filter(Boolean),
|
|
45
|
+
categories: sp.getAll(KEYS.categories).filter(Boolean),
|
|
46
|
+
tags: sp.getAll(KEYS.tags).filter(Boolean),
|
|
47
|
+
labels: sp.getAll(KEYS.labels).filter(Boolean),
|
|
48
|
+
licenses: sp.getAll(KEYS.licenses).filter(Boolean),
|
|
49
|
+
statuses: sp.getAll(KEYS.statuses).flatMap((s) => s.split(",")).filter(Boolean),
|
|
50
|
+
...(lens !== null ? { lens } : {}),
|
|
51
|
+
...(sort !== undefined ? { sort } : {}),
|
|
52
|
+
...(page !== undefined ? { page } : {}),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Serialize a filters object back to URLSearchParams.
|
|
57
|
+
* Undefined / empty values are dropped. Defaults (sort, page 1, comfortable
|
|
58
|
+
* density) are also dropped to keep URLs short and canonical.
|
|
59
|
+
*/
|
|
60
|
+
export function searchParamsFromFilters(f) {
|
|
61
|
+
const sp = new URLSearchParams();
|
|
62
|
+
if (f.q)
|
|
63
|
+
sp.set(KEYS.q, f.q);
|
|
64
|
+
for (const v of f.stacks ?? [])
|
|
65
|
+
sp.append(KEYS.stacks, v);
|
|
66
|
+
for (const v of f.platforms ?? [])
|
|
67
|
+
sp.append(KEYS.platforms, v);
|
|
68
|
+
for (const v of f.categories ?? [])
|
|
69
|
+
sp.append(KEYS.categories, v);
|
|
70
|
+
for (const v of f.tags ?? [])
|
|
71
|
+
sp.append(KEYS.tags, v);
|
|
72
|
+
for (const v of f.labels ?? [])
|
|
73
|
+
sp.append(KEYS.labels, v);
|
|
74
|
+
for (const v of f.licenses ?? [])
|
|
75
|
+
sp.append(KEYS.licenses, v);
|
|
76
|
+
if (f.statuses?.length)
|
|
77
|
+
sp.set(KEYS.statuses, f.statuses.join(","));
|
|
78
|
+
if (f.lens)
|
|
79
|
+
sp.set(KEYS.lens, f.lens);
|
|
80
|
+
if (f.sort && f.sort !== DEFAULT_SORT)
|
|
81
|
+
sp.set(KEYS.sort, f.sort);
|
|
82
|
+
if (f.page && f.page !== DEFAULT_PAGE)
|
|
83
|
+
sp.set(KEYS.page, String(f.page));
|
|
84
|
+
return sp;
|
|
85
|
+
}
|
|
86
|
+
/** True if any filter is active (i.e. the result list isn't "all items"). */
|
|
87
|
+
export function hasAnyFilter(f) {
|
|
88
|
+
if (f.q && f.q.trim())
|
|
89
|
+
return true;
|
|
90
|
+
if (f.lens)
|
|
91
|
+
return true;
|
|
92
|
+
return Boolean((f.stacks?.length ?? 0) +
|
|
93
|
+
(f.platforms?.length ?? 0) +
|
|
94
|
+
(f.categories?.length ?? 0) +
|
|
95
|
+
(f.tags?.length ?? 0) +
|
|
96
|
+
(f.labels?.length ?? 0) +
|
|
97
|
+
(f.licenses?.length ?? 0) +
|
|
98
|
+
(f.statuses?.length ?? 0));
|
|
99
|
+
}
|
|
100
|
+
/** How many items per page. Constant for now; future versions may vary. */
|
|
101
|
+
export const PAGE_SIZE = DEFAULT_PAGE_SIZE;
|
|
102
|
+
/**
|
|
103
|
+
* Sort items in-place-free: returns a new array. Stable for ties.
|
|
104
|
+
* Apps missing the sort key (e.g. no stars) sink to the bottom rather
|
|
105
|
+
* than vanishing.
|
|
106
|
+
*/
|
|
107
|
+
function recordName(record) {
|
|
108
|
+
return record.kind === "resource" ? record.title : record.name;
|
|
109
|
+
}
|
|
110
|
+
function projectStars(record) {
|
|
111
|
+
return record.kind === "project" ? record.github?.stars ?? 0 : 0;
|
|
112
|
+
}
|
|
113
|
+
function recordUpdatedAt(record) {
|
|
114
|
+
if (record.kind === "project")
|
|
115
|
+
return record.github?.pushedAt ?? null;
|
|
116
|
+
if (record.kind === "resource")
|
|
117
|
+
return record.publishedAt ?? null;
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
function recordAddedAt(record) {
|
|
121
|
+
return record.curation?.reviewedAt ?? null;
|
|
122
|
+
}
|
|
123
|
+
export function applySort(items, sort) {
|
|
124
|
+
const arr = items.slice();
|
|
125
|
+
const ts = (s) => (s ? new Date(s).valueOf() : 0);
|
|
126
|
+
switch (sort) {
|
|
127
|
+
case "most-starred":
|
|
128
|
+
arr.sort((a, b) => projectStars(b) - projectStars(a));
|
|
129
|
+
break;
|
|
130
|
+
case "recently-updated":
|
|
131
|
+
arr.sort((a, b) => ts(recordUpdatedAt(b)) - ts(recordUpdatedAt(a)));
|
|
132
|
+
break;
|
|
133
|
+
case "recently-added":
|
|
134
|
+
arr.sort((a, b) => ts(recordAddedAt(b)) - ts(recordAddedAt(a)));
|
|
135
|
+
break;
|
|
136
|
+
case "best-overall": {
|
|
137
|
+
const reviewed = (a) => (a.curation?.reviewed ? 1 : 0);
|
|
138
|
+
const visible = (a) => (a.visibility === "keep" ? 1 : 0);
|
|
139
|
+
arr.sort((a, b) => {
|
|
140
|
+
const reviewedDelta = reviewed(b) - reviewed(a);
|
|
141
|
+
if (reviewedDelta !== 0)
|
|
142
|
+
return reviewedDelta;
|
|
143
|
+
const visibleDelta = visible(b) - visible(a);
|
|
144
|
+
if (visibleDelta !== 0)
|
|
145
|
+
return visibleDelta;
|
|
146
|
+
return projectStars(b) - projectStars(a);
|
|
147
|
+
});
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
case "alphabetical":
|
|
151
|
+
arr.sort((a, b) => recordName(a).localeCompare(recordName(b)));
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
return arr;
|
|
155
|
+
}
|
|
156
|
+
/** Slice an array for a given page (1-based). */
|
|
157
|
+
export function paginate(items, page, pageSize = PAGE_SIZE) {
|
|
158
|
+
const start = (page - 1) * pageSize;
|
|
159
|
+
return items.slice(start, start + pageSize);
|
|
160
|
+
}
|
|
161
|
+
/** Total number of pages given an item count. Always >= 1. */
|
|
162
|
+
export function totalPages(itemCount, pageSize = PAGE_SIZE) {
|
|
163
|
+
return Math.max(1, Math.ceil(itemCount / pageSize));
|
|
164
|
+
}
|
|
165
|
+
/** Resolve the effective sort from a filters object, applying default. */
|
|
166
|
+
export function effectiveSort(f) {
|
|
167
|
+
return f.sort ?? DEFAULT_SORT;
|
|
168
|
+
}
|
|
169
|
+
/** Resolve the effective page from a filters object, applying default. */
|
|
170
|
+
export function effectivePage(f) {
|
|
171
|
+
return f.page ?? DEFAULT_PAGE;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Return the subset of items that match all active filters (AND across
|
|
175
|
+
* dimensions, OR within a dimension).
|
|
176
|
+
*
|
|
177
|
+
* `q` is a case-insensitive substring search across name, owner,
|
|
178
|
+
* description, and category. Other dimensions are exact match.
|
|
179
|
+
*/
|
|
180
|
+
export function filterRecords(items, f) {
|
|
181
|
+
const q = f.q?.trim().toLowerCase();
|
|
182
|
+
const stacks = f.stacks?.length ? new Set(f.stacks) : null;
|
|
183
|
+
const platforms = f.platforms?.length ? new Set(f.platforms) : null;
|
|
184
|
+
const categories = f.categories?.length ? new Set(f.categories) : null;
|
|
185
|
+
const tags = f.tags?.length ? new Set(f.tags) : null;
|
|
186
|
+
const labels = f.labels?.length ? new Set(f.labels) : null;
|
|
187
|
+
const licenses = f.licenses?.length ? new Set(f.licenses) : null;
|
|
188
|
+
const statuses = f.statuses?.length ? new Set(f.statuses) : null;
|
|
189
|
+
return items.filter((a) => {
|
|
190
|
+
// Text search — match name, owner, description, category, stack,
|
|
191
|
+
// stacks, platforms, tags, backend, architecture, stateManagement,
|
|
192
|
+
// bestFor, whyListed, license, status.
|
|
193
|
+
if (q) {
|
|
194
|
+
const repoUrl = a.kind === "project" ? a.repoUrl : a.links.github ?? "";
|
|
195
|
+
const ownerMatch = /github\.com\/([^/]+)\//.exec(repoUrl ?? "")?.[1]?.toLowerCase() ?? "";
|
|
196
|
+
const projectFields = a.kind === "project"
|
|
197
|
+
? [
|
|
198
|
+
a.stack,
|
|
199
|
+
...a.stacks,
|
|
200
|
+
...a.platforms,
|
|
201
|
+
a.projectType,
|
|
202
|
+
a.difficulty ?? "",
|
|
203
|
+
a.codebaseSize ?? "",
|
|
204
|
+
...a.bestFor,
|
|
205
|
+
...a.whyListed,
|
|
206
|
+
a.github?.license ?? "",
|
|
207
|
+
a.health?.status ? statusDisplay(a.health.status) : "",
|
|
208
|
+
]
|
|
209
|
+
: [];
|
|
210
|
+
const resourceFields = a.kind === "resource"
|
|
211
|
+
? [a.type, a.topic, a.author ?? ""]
|
|
212
|
+
: [];
|
|
213
|
+
const entityFields = a.kind === "entity"
|
|
214
|
+
? [a.type, a.location ?? "", a.parent ?? ""]
|
|
215
|
+
: [];
|
|
216
|
+
const haystack = [
|
|
217
|
+
recordName(a),
|
|
218
|
+
ownerMatch,
|
|
219
|
+
a.description,
|
|
220
|
+
a.category,
|
|
221
|
+
...a.tags,
|
|
222
|
+
...projectFields,
|
|
223
|
+
...resourceFields,
|
|
224
|
+
...entityFields,
|
|
225
|
+
]
|
|
226
|
+
.join(" ")
|
|
227
|
+
.toLowerCase();
|
|
228
|
+
if (!haystack.includes(q))
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
if (stacks) {
|
|
232
|
+
if (a.kind !== "project")
|
|
233
|
+
return false;
|
|
234
|
+
const allStacks = [a.stack, ...a.stacks].filter((stack) => Boolean(stack));
|
|
235
|
+
if (!allStacks.some((s) => stacks.has(s)))
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
if (platforms) {
|
|
239
|
+
if (a.kind !== "project")
|
|
240
|
+
return false;
|
|
241
|
+
if (!a.platforms.some((p) => platforms.has(p)))
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
if (categories) {
|
|
245
|
+
if (!categories.has(a.category))
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
if (tags && !a.tags.some((tag) => tags.has(tag)))
|
|
249
|
+
return false;
|
|
250
|
+
if (labels) {
|
|
251
|
+
if (!a.curation?.labels?.some((l) => labels.has(l)))
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
if (licenses) {
|
|
255
|
+
if (a.kind !== "project")
|
|
256
|
+
return false;
|
|
257
|
+
const license = a.github?.license;
|
|
258
|
+
if (!license || !licenses.has(license))
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
if (statuses) {
|
|
262
|
+
if (a.kind !== "project")
|
|
263
|
+
return false;
|
|
264
|
+
const status = a.health?.status;
|
|
265
|
+
if (!status || !statuses.has(status))
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
if (f.lens) {
|
|
269
|
+
if (!a.curation?.lenses?.includes(f.lens))
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
return true;
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
/** Build a flat list of "active filter" chips for display + removal. */
|
|
276
|
+
export function activeFilterChips(f) {
|
|
277
|
+
const out = [];
|
|
278
|
+
if (f.q && f.q.trim()) {
|
|
279
|
+
out.push({ key: "q", value: "", label: `“${f.q}”` });
|
|
280
|
+
}
|
|
281
|
+
for (const v of f.stacks ?? []) {
|
|
282
|
+
out.push({ key: "stacks", value: v, label: `Stack: ${v}` });
|
|
283
|
+
}
|
|
284
|
+
for (const v of f.platforms ?? []) {
|
|
285
|
+
out.push({ key: "platforms", value: v, label: `Platform: ${v}` });
|
|
286
|
+
}
|
|
287
|
+
for (const v of f.categories ?? []) {
|
|
288
|
+
out.push({ key: "categories", value: v, label: `Category: ${v}` });
|
|
289
|
+
}
|
|
290
|
+
for (const v of f.tags ?? []) {
|
|
291
|
+
out.push({ key: "tags", value: v, label: `Tag: ${v}` });
|
|
292
|
+
}
|
|
293
|
+
for (const v of f.labels ?? []) {
|
|
294
|
+
out.push({ key: "labels", value: v, label: labelDisplay(v) ?? v });
|
|
295
|
+
}
|
|
296
|
+
for (const v of f.licenses ?? []) {
|
|
297
|
+
out.push({ key: "licenses", value: v, label: `License: ${v}` });
|
|
298
|
+
}
|
|
299
|
+
if (f.lens) {
|
|
300
|
+
out.push({ key: "lens", value: f.lens, label: lensDisplay(f.lens) });
|
|
301
|
+
}
|
|
302
|
+
// Status: collapse the "stale,quiet" composite into a single chip.
|
|
303
|
+
if (f.statuses && f.statuses.length) {
|
|
304
|
+
const joined = f.statuses.join(",");
|
|
305
|
+
if (joined === "stale,quiet") {
|
|
306
|
+
out.push({ key: "statuses", value: "stale,quiet", label: statusDisplay("needs-maintainer") });
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
for (const v of f.statuses) {
|
|
310
|
+
out.push({ key: "statuses", value: v, label: statusDisplay(v) });
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return out;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Return a new filters object with one (key, value) removed.
|
|
318
|
+
* - scalar keys (`q`, `lens`) → clears the value
|
|
319
|
+
* - multi-value keys → removes the single matching value
|
|
320
|
+
* Used by the "x" button on each active filter chip.
|
|
321
|
+
* Also resets page to 1 so the user doesn't get stranded on a high page
|
|
322
|
+
* that no longer has results.
|
|
323
|
+
*/
|
|
324
|
+
export function removeFilter(f, key, value) {
|
|
325
|
+
let next;
|
|
326
|
+
if (key === "q" || key === "lens") {
|
|
327
|
+
// Scalar filters are removed entirely rather than treated like arrays.
|
|
328
|
+
const { [key]: _drop, ...rest } = f;
|
|
329
|
+
next = rest;
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
const current = f[key];
|
|
333
|
+
if (!current)
|
|
334
|
+
return f;
|
|
335
|
+
// `needs-maintainer` is represented internally by the composite
|
|
336
|
+
// statuses `stale,quiet`, but is displayed as one removable chip.
|
|
337
|
+
const filtered = key === "statuses" && value === "stale,quiet"
|
|
338
|
+
? []
|
|
339
|
+
: current.filter((v) => v !== value);
|
|
340
|
+
if (filtered.length === 0) {
|
|
341
|
+
const { [key]: _drop, ...rest } = f;
|
|
342
|
+
next = rest;
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
next = { ...f, [key]: filtered };
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
next.page = 1;
|
|
349
|
+
return next;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Build the full list of facet values from the items array, preserving
|
|
353
|
+
* a sensible order (frequency desc, then alphabetical for ties).
|
|
354
|
+
*/
|
|
355
|
+
export function buildFacets(items) {
|
|
356
|
+
const counts = {
|
|
357
|
+
stack: new Map(),
|
|
358
|
+
platform: new Map(),
|
|
359
|
+
category: new Map(),
|
|
360
|
+
tag: new Map(),
|
|
361
|
+
label: new Map(),
|
|
362
|
+
license: new Map(),
|
|
363
|
+
};
|
|
364
|
+
for (const a of items) {
|
|
365
|
+
if (a.kind === "project") {
|
|
366
|
+
const allStacks = new Set([a.stack, ...a.stacks].filter((stack) => Boolean(stack)));
|
|
367
|
+
for (const s of allStacks)
|
|
368
|
+
counts.stack.set(s, (counts.stack.get(s) ?? 0) + 1);
|
|
369
|
+
for (const p of a.platforms)
|
|
370
|
+
counts.platform.set(p, (counts.platform.get(p) ?? 0) + 1);
|
|
371
|
+
const license = a.github?.license;
|
|
372
|
+
if (license)
|
|
373
|
+
counts.license.set(license, (counts.license.get(license) ?? 0) + 1);
|
|
374
|
+
}
|
|
375
|
+
counts.category.set(a.category, (counts.category.get(a.category) ?? 0) + 1);
|
|
376
|
+
for (const tag of a.tags)
|
|
377
|
+
counts.tag.set(tag, (counts.tag.get(tag) ?? 0) + 1);
|
|
378
|
+
for (const l of a.curation?.labels ?? [])
|
|
379
|
+
counts.label.set(l, (counts.label.get(l) ?? 0) + 1);
|
|
380
|
+
}
|
|
381
|
+
const sortByCountThenName = (m) => [...m.entries()]
|
|
382
|
+
.sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
|
|
383
|
+
.map(([value, count]) => ({ value, count }));
|
|
384
|
+
return {
|
|
385
|
+
stacks: sortByCountThenName(counts.stack),
|
|
386
|
+
platforms: sortByCountThenName(counts.platform),
|
|
387
|
+
categories: sortByCountThenName(counts.category),
|
|
388
|
+
tags: sortByCountThenName(counts.tag),
|
|
389
|
+
labels: sortByCountThenName(counts.label),
|
|
390
|
+
licenses: sortByCountThenName(counts.license),
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
// ── V1-published API ─────────────────────────────────────────────────
|
|
394
|
+
// `IndexFilters` / `IndexSort` are the canonical V1 names for the
|
|
395
|
+
// filter-state type. The internal functions (filterRecords, applySort,
|
|
396
|
+
// paginate, buildFacets, etc.) operate on the generic `IndexRecord`
|
|
397
|
+
// shape and are intentionally framework-agnostic.
|
|
398
|
+
//# sourceMappingURL=directory-search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directory-search.js","sourceRoot":"","sources":["../src/directory-search.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAyBlF,0CAA0C;AAC1C,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACxD,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE;IAChD,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAE;IACpD,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE;IAChD,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE;CACxC,CAAC;AAIX,MAAM,YAAY,GAAc,kBAAkB,CAAC;AACnD,MAAM,YAAY,GAAG,CAAC,CAAC;AACvB,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B,MAAM,IAAI,GAAG;IACX,CAAC,EAAE,GAAG;IACN,MAAM,EAAE,OAAO;IACf,SAAS,EAAE,UAAU;IACrB,UAAU,EAAE,UAAU;IACtB,IAAI,EAAE,KAAK;IACX,MAAM,EAAE,OAAO;IACf,QAAQ,EAAE,SAAS;IACnB,QAAQ,EAAE,QAAQ;IAClB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;CACJ,CAAC;AAEX;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,EAAmB;IACzD,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,uEAAuE;IACvE,MAAM,cAAc,GAAG,OAAO,KAAK,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC;IAC5E,MAAM,IAAI,GACR,cAAc,IAAK,YAA6C,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,cAAc,CAAC;QACtG,CAAC,CAAE,cAA4B;QAC/B,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxF,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO;QACL,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5B,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QAC9C,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QACpD,UAAU,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QACtD,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QAC1C,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QAC9C,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QAClD,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QAC/E,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,CAAe;IACrD,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;IACjC,IAAI,CAAC,CAAC,CAAC;QAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE;QAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC1D,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE;QAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAChE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,IAAI,EAAE;QAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAClE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE;QAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACtD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE;QAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC1D,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,IAAI,EAAE;QAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC9D,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM;QAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACpE,IAAI,CAAC,CAAC,IAAI;QAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY;QAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACjE,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY;QAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACzE,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,YAAY,CAAC,CAAe;IAC1C,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,OAAO,CACZ,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC,CAC5B,CAAC;AACJ,CAAC;AAED,2EAA2E;AAC3E,MAAM,CAAC,MAAM,SAAS,GAAG,iBAAiB,CAAC;AAE3C;;;;GAIG;AACH,SAAS,UAAU,CAAC,MAAmB;IACrC,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;AACjE,CAAC;AAED,SAAS,YAAY,CAAC,MAAmB;IACvC,OAAO,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,eAAe,CAAC,MAAmB;IAC1C,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,MAAM,EAAE,QAAQ,IAAI,IAAI,CAAC;IACtE,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC;IAClE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CAAC,MAAmB;IACxC,OAAO,MAAM,CAAC,QAAQ,EAAE,UAAU,IAAI,IAAI,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAoB,EAAE,IAAe;IAC7D,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;IAC1B,MAAM,EAAE,GAAG,CAAC,CAAiB,EAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1E,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,cAAc;YACjB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM;QACR,KAAK,kBAAkB;YACrB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,MAAM;QACR,KAAK,gBAAgB;YACnB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAChE,MAAM;QACR,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB,MAAM,QAAQ,GAAG,CAAC,CAAc,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,MAAM,OAAO,GAAG,CAAC,CAAc,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACtE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBAChB,MAAM,aAAa,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAChD,IAAI,aAAa,KAAK,CAAC;oBAAE,OAAO,aAAa,CAAC;gBAC9C,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;gBAC7C,IAAI,YAAY,KAAK,CAAC;oBAAE,OAAO,YAAY,CAAC;gBAC5C,OAAO,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;YAC3C,CAAC,CAAC,CAAC;YACH,MAAM;QACR,CAAC;QACD,KAAK,cAAc;YACjB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/D,MAAM;IACV,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,QAAQ,CAAI,KAAU,EAAE,IAAY,EAAE,QAAQ,GAAG,SAAS;IACxE,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC;IACpC,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,UAAU,CAAC,SAAiB,EAAE,QAAQ,GAAG,SAAS;IAChE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,aAAa,CAAC,CAAe;IAC3C,OAAO,CAAC,CAAC,IAAI,IAAI,YAAY,CAAC;AAChC,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,aAAa,CAAC,CAAe;IAC3C,OAAO,CAAC,CAAC,IAAI,IAAI,YAAY,CAAC;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,KAAoB,EAAE,CAAe;IACjE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,MAAM,UAAU,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvE,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACrD,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjE,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEjE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACxB,iEAAiE;QACjE,mEAAmE;QACnE,uCAAuC;QACvC,IAAI,CAAC,EAAE,CAAC;YACN,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;YACxE,MAAM,UAAU,GACd,wBAAwB,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;YACzE,MAAM,aAAa,GACjB,CAAC,CAAC,IAAI,KAAK,SAAS;gBAClB,CAAC,CAAC;oBACE,CAAC,CAAC,KAAK;oBACP,GAAG,CAAC,CAAC,MAAM;oBACX,GAAG,CAAC,CAAC,SAAS;oBACd,CAAC,CAAC,WAAW;oBACb,CAAC,CAAC,UAAU,IAAI,EAAE;oBAClB,CAAC,CAAC,YAAY,IAAI,EAAE;oBACpB,GAAG,CAAC,CAAC,OAAO;oBACZ,GAAG,CAAC,CAAC,SAAS;oBACd,CAAC,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE;oBACvB,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;iBACvD;gBACH,CAAC,CAAC,EAAE,CAAC;YACT,MAAM,cAAc,GAClB,CAAC,CAAC,IAAI,KAAK,UAAU;gBACnB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;gBACnC,CAAC,CAAC,EAAE,CAAC;YACT,MAAM,YAAY,GAChB,CAAC,CAAC,IAAI,KAAK,QAAQ;gBACjB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;gBAC5C,CAAC,CAAC,EAAE,CAAC;YACT,MAAM,QAAQ,GAAG;gBACf,UAAU,CAAC,CAAC,CAAC;gBACb,UAAU;gBACV,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,QAAQ;gBACV,GAAG,CAAC,CAAC,IAAI;gBACT,GAAG,aAAa;gBAChB,GAAG,cAAc;gBACjB,GAAG,YAAY;aAChB;iBACE,IAAI,CAAC,GAAG,CAAC;iBACT,WAAW,EAAE,CAAC;YACjB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;QAC1C,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YACvC,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAC7C,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAC3C,CAAC;YACF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;QAC1D,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YACvC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;QAC/D,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;gBAAE,OAAO,KAAK,CAAC;QAChD,CAAC;QAED,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QAE/D,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;QACpE,CAAC;QAED,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YACvC,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;YAClC,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;gBAAE,OAAO,KAAK,CAAC;QACvD,CAAC;QAED,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YACvC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC;YAChC,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,OAAO,KAAK,CAAC;QACrD,CAAC;QAED,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YACX,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;gBAAE,OAAO,KAAK,CAAC;QAC1D,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,iBAAiB,CAC/B,CAAe;IAEf,MAAM,GAAG,GAAgE,EAAE,CAAC;IAE5E,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACtB,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACvD,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QAC/B,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;QAClC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;QACnC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;QAC7B,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QAC/B,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACjC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QACX,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,mEAAmE;IACnE,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;YAC7B,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;QAChG,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,CAAe,EACf,GAAuB,EACvB,KAAa;IAEb,IAAI,IAAkB,CAAC;IACvB,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QAClC,uEAAuE;QACvE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC;QACpC,IAAI,GAAG,IAAI,CAAC;IACd,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAyB,CAAC;QAC/C,IAAI,CAAC,OAAO;YAAE,OAAO,CAAC,CAAC;QACvB,gEAAgE;QAChE,kEAAkE;QAClE,MAAM,QAAQ,GACZ,GAAG,KAAK,UAAU,IAAI,KAAK,KAAK,aAAa;YAC3C,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC;QACzC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC;YACpC,IAAI,GAAG,IAAI,CAAC;QACd,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC;QACnC,CAAC;IACH,CAAC;IACD,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;IACd,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAoB;IAC9C,MAAM,MAAM,GAAG;QACb,KAAK,EAAE,IAAI,GAAG,EAAkB;QAChC,QAAQ,EAAE,IAAI,GAAG,EAAkB;QACnC,QAAQ,EAAE,IAAI,GAAG,EAAkB;QACnC,GAAG,EAAE,IAAI,GAAG,EAAkB;QAC9B,KAAK,EAAE,IAAI,GAAG,EAAkB;QAChC,OAAO,EAAE,IAAI,GAAG,EAAkB;KACnC,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,SAAS,GAAG,IAAI,GAAG,CACvB,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAC1E,CAAC;YACF,KAAK,MAAM,CAAC,IAAI,SAAS;gBAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC/E,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS;gBAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACvF,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;YAClC,IAAI,OAAO;gBAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACnF,CAAC;QACD,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5E,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9E,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE;YAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChG,CAAC;IACD,MAAM,mBAAmB,GAAG,CAAC,CAAsB,EAAE,EAAE,CACrD,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;SACb,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACvD,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACjD,OAAO;QACL,MAAM,EAAE,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC;QACzC,SAAS,EAAE,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC/C,UAAU,EAAE,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC;QAChD,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,GAAG,CAAC;QACrC,MAAM,EAAE,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC;QACzC,QAAQ,EAAE,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,wEAAwE;AACxE,kEAAkE;AAClE,uEAAuE;AACvE,oEAAoE;AACpE,kDAAkD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type TaxonomyRecord = {
|
|
2
|
+
category?: string;
|
|
3
|
+
stack?: string;
|
|
4
|
+
stacks?: string[];
|
|
5
|
+
};
|
|
6
|
+
/** Number of items in the directory, per category name. */
|
|
7
|
+
export declare function countByCategory(items?: TaxonomyRecord[]): Map<string, number>;
|
|
8
|
+
/** Number of items in the directory, per primary stack. */
|
|
9
|
+
export declare function countByStack(items?: TaxonomyRecord[]): Map<string, number>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=directory-taxonomy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directory-taxonomy.d.ts","sourceRoot":"","sources":["../src/directory-taxonomy.ts"],"names":[],"mappings":"AAAA,KAAK,cAAc,GAAG;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,2DAA2D;AAC3D,wBAAgB,eAAe,CAAC,KAAK,GAAE,cAAc,EAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAOjF;AAED,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,KAAK,GAAE,cAAc,EAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAQ9E"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Number of items in the directory, per category name. */
|
|
2
|
+
export function countByCategory(items = []) {
|
|
3
|
+
const m = new Map();
|
|
4
|
+
for (const a of items) {
|
|
5
|
+
const k = a.category || "Other";
|
|
6
|
+
m.set(k, (m.get(k) ?? 0) + 1);
|
|
7
|
+
}
|
|
8
|
+
return m;
|
|
9
|
+
}
|
|
10
|
+
/** Number of items in the directory, per primary stack. */
|
|
11
|
+
export function countByStack(items = []) {
|
|
12
|
+
const m = new Map();
|
|
13
|
+
for (const a of items) {
|
|
14
|
+
const stacks = new Set([a.stack, ...(a.stacks ?? [])].filter(Boolean));
|
|
15
|
+
if (stacks.size === 0)
|
|
16
|
+
stacks.add("Other");
|
|
17
|
+
for (const stack of stacks)
|
|
18
|
+
m.set(stack, (m.get(stack) ?? 0) + 1);
|
|
19
|
+
}
|
|
20
|
+
return m;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=directory-taxonomy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directory-taxonomy.js","sourceRoot":"","sources":["../src/directory-taxonomy.ts"],"names":[],"mappings":"AAMA,2DAA2D;AAC3D,MAAM,UAAU,eAAe,CAAC,QAA0B,EAAE;IAC1D,MAAM,CAAC,GAAG,IAAI,GAAG,EAAkB,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC;QAChC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,YAAY,CAAC,QAA0B,EAAE;IACvD,MAAM,CAAC,GAAG,IAAI,GAAG,EAAkB,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC,CAAC;QACnF,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3C,KAAK,MAAM,KAAK,IAAI,MAAM;YAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,11 +8,13 @@
|
|
|
8
8
|
* To audit: `grep -E '^export ' src/index.ts | sort`
|
|
9
9
|
*/
|
|
10
10
|
export { defineConfig, loadConfig } from "./config.js";
|
|
11
|
-
export type { GroveConfig } from "./schema.js";
|
|
12
|
-
export { blueprintSchema, resourceKindSchema, healthStatusSchema, healthTierSchema, healthBlockSchema, healthEntrySchema, healthFileSchema, decisionSchema, decisionsFileSchema, overrideSchema, overridesFileSchema, projectRecordSchema, resourceRecordSchema, entityRecordSchema, projectTypeSchema, resourceTypeSchema, entityTypeSchema, appLabelSchema, scoreSchema, linksSchema, githubRepositorySchema, githubMetadataSchema, githubLicenseSchema, blueprintKind, } from "./schema.js";
|
|
11
|
+
export type { GroveConfig, GroveConfigInput } from "./schema.js";
|
|
12
|
+
export { blueprintSchema, resourceKindSchema, healthStatusSchema, healthTierSchema, healthBlockSchema, healthEntrySchema, healthFileSchema, decisionSchema, decisionsFileSchema, overrideSchema, overridesFileSchema, projectRecordSchema, resourceRecordSchema, entityRecordSchema, resourceSchema, recordsFileSchema, projectTypeSchema, resourceTypeSchema, entityTypeSchema, appLabelSchema, scoreSchema, linksSchema, githubRepositorySchema, githubMetadataSchema, githubLicenseSchema, blueprintKind, } from "./schema.js";
|
|
13
13
|
export type { Blueprint, ResourceKind, DecisionVisibility, Resource, ProjectRecord, ResourceRecord, EntityRecord, IndexRecord, IndexProjectRecord, IndexResourceRecord, IndexEntityRecord, HealthStatus, HealthTier, HealthEntry, HealthFile, Decision, DecisionsFile, Override, OverridesFile, ProjectType, ResourceType, EntityType, AppLabel, Score, Links, GithubMetadata, GithubRepository, } from "./schema.js";
|
|
14
14
|
export { generate } from "./build-data.js";
|
|
15
15
|
export type { GenerateResult, RecordsFullPayload, RecordsIndexPayload } from "./build-data.js";
|
|
16
|
+
export { prepareDirectory } from "./prepare.js";
|
|
17
|
+
export type { PrepareDirectoryResult } from "./prepare.js";
|
|
16
18
|
export { stringifyRecordYaml } from "./schema.js";
|
|
17
19
|
export { buildSitemap, buildSitemapXml } from "./sitemap.js";
|
|
18
20
|
export { buildLlmsTxt, buildLlmsFullTxt, buildLlmsFiles } from "./llms.js";
|
|
@@ -24,6 +26,8 @@ export type { GithubRepoRef } from "./github.js";
|
|
|
24
26
|
export { enrichFromGithubHtml } from "./enrich.js";
|
|
25
27
|
export type { EnrichedFields, EnrichResult } from "./enrich.js";
|
|
26
28
|
export { rateLimitWaitMs, sleep } from "./github-client.js";
|
|
29
|
+
export { syncContributors } from "./contributors.js";
|
|
30
|
+
export type { Contributor, ContributorSyncResult, SyncContributorsOptions, } from "./contributors.js";
|
|
27
31
|
export type { GhFetchOptions } from "./github-client.js";
|
|
28
32
|
export { classifyHealth } from "./health.js";
|
|
29
33
|
export { detectGithubRepo, parseAwesomeMarkdown, } from "./markdown.js";
|
|
@@ -34,4 +38,11 @@ export type { ParsedEntry, ParsedSection } from "./parseReadme.js";
|
|
|
34
38
|
export { readYamlFile, writeYamlFile, writeTextFile } from "./io.js";
|
|
35
39
|
export { validateProject } from "./validate.js";
|
|
36
40
|
export type { ValidationResult, ValidationIssue, ValidationSeverity } from "./validate.js";
|
|
41
|
+
export * from "./directory-display.js";
|
|
42
|
+
export * from "./directory-format.js";
|
|
43
|
+
export * from "./directory-lenses.js";
|
|
44
|
+
export * from "./directory-repo.js";
|
|
45
|
+
export * from "./directory-scores.js";
|
|
46
|
+
export * from "./directory-search.js";
|
|
47
|
+
export * from "./directory-taxonomy.js";
|
|
37
48
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|