fix(stats): hide stealth model providers

This commit is contained in:
Adam 2026-09-04 07:32:58 -05:00
parent 3f31139064
commit 4178fd74f1
No known key found for this signature in database
GPG key ID: 9CB48779AF150E75
7 changed files with 176 additions and 83 deletions

View file

@ -24,6 +24,8 @@ import {
findModelCatalogEntry,
formatCatalogLabName,
getModelCatalog,
isKnownCatalogLab,
isProviderlessLab,
type ModelCatalog,
type ModelCatalogEntry,
} from "../routes/model-catalog"
@ -71,7 +73,7 @@ const comparisonModelLimit = 6
type ComparisonModel = {
name: string
lab: string
labName: string
labName?: string
slug: string
catalog: ModelCatalogEntry | null
stats: StatsModelComparisonEntry | null
@ -159,13 +161,19 @@ export default function ModelCompareDetailPage(props: ModelCompareDetailPageProp
let comparisonBodyScroll: HTMLDivElement | undefined
const models = createMemo(() =>
modelSelections().map((model, index) =>
buildComparisonModel(model.lab, model.slug, model.catalog ?? null, stats()?.models[index] ?? null),
buildComparisonModel(
model.lab,
model.slug,
model.catalog ?? null,
stats()?.models[index] ?? null,
catalog()?.labs.map((lab) => lab.id) ?? [],
),
),
)
const title = createMemo(() => `${models()[0].name} vs ${models()[1].name} - AI Model Comparison`)
const description = createMemo(
() =>
`Compare ${models()[0].name} from ${models()[0].labName} and ${models()[1].name} from ${models()[1].labName} on key metrics including benchmarks, price, context length, usage, and model features.`,
`Compare ${comparisonModelLabel(models()[0])} and ${comparisonModelLabel(models()[1])} on key metrics including benchmarks, price, context length, usage, and model features.`,
)
const canonicalPath = createMemo(() => {
if (props.family) return canonicalFamilyComparisonPath(props.family.first, props.family.second)
@ -206,7 +214,7 @@ export default function ModelCompareDetailPage(props: ModelCompareDetailPageProp
"@type": "SoftwareApplication",
name: model.name,
applicationCategory: "AI model",
provider: model.labName,
...(model.labName ? { provider: model.labName } : {}),
})),
}),
)
@ -459,7 +467,9 @@ function CompareDetailSelectButton(props: {
aria-expanded={props.expanded}
onClick={props.onOpen}
>
<LabLogo lab={props.model.lab} label={props.model.labName} size="small" />
<Show when={props.model.labName}>
{(labName) => <LabLogo lab={props.model.lab} label={labName()} size="small" />}
</Show>
<span data-slot="compare-detail-select-name">{props.model.name}</span>
<ChevronDownIcon />
</button>
@ -581,8 +591,7 @@ function CompareModelDetail(props: { model: ModelCatalogEntry }) {
</header>
<div data-slot="compare-model-modal-description">
<p>
{props.model.description ??
`${props.model.name} is an AI model from ${formatCatalogLabName(props.model.lab)}.`}
{props.model.description ?? `${props.model.name} is an AI model.`}
</p>
<span aria-hidden="true" />
</div>
@ -789,9 +798,11 @@ function LabLogo(props: { lab: string; label: string; size: "large" | "small" |
const iconId = () => getProviderIconId(props.lab)
return (
<span data-slot="compare-home-avatar" data-lab={iconId()} data-size={props.size} aria-label={props.label}>
<ProviderIcon aria-hidden="true" id={iconId()} />
</span>
<Show when={!isProviderlessLab(props.lab)}>
<span data-slot="compare-home-avatar" data-lab={iconId()} data-size={props.size} aria-label={props.label}>
<ProviderIcon aria-hidden="true" id={iconId()} />
</span>
</Show>
)
}
@ -832,11 +843,13 @@ function buildComparisonModel(
modelParam: string,
catalog: ModelCatalogEntry | null,
stats: StatsModelComparisonEntry | null,
catalogLabs: readonly string[],
): ComparisonModel {
const lab = catalog?.lab ?? stats?.provider ?? catalogSlug(labParam)
return {
name: catalog?.name ?? stats?.model ?? formatParamName(modelParam),
lab: catalog?.lab ?? stats?.provider ?? catalogSlug(labParam),
labName: formatCatalogLabName(catalog?.lab ?? stats?.provider ?? labParam),
lab,
labName: isKnownCatalogLab(lab, catalogLabs) ? formatCatalogLabName(lab) : undefined,
slug: catalog?.slug ?? stats?.slug ?? catalogSlug(modelParam),
catalog,
stats,
@ -877,7 +890,7 @@ function buildComparisonDetailSections(models: readonly ComparisonModel[]): Comp
rows: [
comparisonDetailRow(
"Author",
models.map((model) => linkedTextCell(model.stats?.author ?? model.labName, labHref(model.lab))),
models.map(providerDetailCell),
),
comparisonDetailRow(
"Context length",
@ -899,7 +912,7 @@ function buildComparisonDetailSections(models: readonly ComparisonModel[]): Comp
),
comparisonDetailRow(
"Providers",
models.map((model) => linkedTextCell(model.labName, labHref(model.lab))),
models.map(providerDetailCell),
),
],
},
@ -1013,6 +1026,15 @@ function comparisonRef(model: ComparisonModel): ComparisonModelRef {
}
}
function comparisonModelLabel(model: ComparisonModel) {
return model.labName ? `${model.name} from ${model.labName}` : model.name
}
function providerDetailCell(model: ComparisonModel): ComparisonDetailCell {
if (!model.labName) return textCell("")
return linkedTextCell(model.stats?.author ?? model.labName ?? "", labHref(model.lab))
}
function textCell(value: string): ComparisonDetailCell {
return { value }
}

View file

@ -17,7 +17,13 @@ import { LocaleLinks } from "../../component/locale-links"
import { useI18n } from "../../context/i18n"
import { useLanguage } from "../../context/language"
import { localizedUrl } from "../../lib/language"
import { findModelCatalogEntry, formatCatalogLabName, loadModelCatalog, type ModelCatalogEntry } from "../model-catalog"
import {
findModelCatalogEntry,
formatCatalogLabName,
isKnownCatalogLab,
loadModelCatalog,
type ModelCatalogEntry,
} from "../model-catalog"
import { SectionHeading } from "../section-heading"
import { runStatsEffect } from "../../stats-runtime"
import { setStatsPageCacheHeaders } from "../stats-cache"
@ -96,7 +102,9 @@ export default function StatsModel() {
const modelName = createMemo(
() => catalogEntry()?.name ?? publicModelName(canonicalModel()) ?? i18n.t("model.fallback"),
)
const labName = createMemo(() => formatCatalogLabName(catalogEntry()?.lab ?? stats()?.provider ?? labParam()))
const lab = createMemo(() => catalogEntry()?.lab ?? stats()?.provider ?? labParam())
const catalogLabs = createMemo(() => page()?.catalog.labs.map((item) => item.id) ?? [])
const labName = createMemo(() => (isKnownCatalogLab(lab(), catalogLabs()) ? formatCatalogLabName(lab()) : undefined))
const formerName = createMemo(() => formerModelName(canonicalModel()))
const searchModelName = createMemo(() => (formerName() ? `${modelName()} (formerly ${formerName()})` : modelName()))
const modelTitle = createMemo(() => i18n.t("model.title", { model: searchModelName() }))
@ -185,9 +193,14 @@ export default function StatsModel() {
<ModelUniqueUsersSection data={stats() ?? null} />
<ModelEfficiencySection data={stats() ?? null} catalog={catalogEntry() ?? null} />
<ModelGeoBreakdownSection data={stats()?.country ?? []} />
<ModelPeersSection data={stats() ?? null} />
<ModelPeersSection data={stats() ?? null} catalogLabs={catalogLabs()} />
<ComparisonCardsSection
pairs={modelComparisonPairs(page()?.catalog.labModels, catalogEntry() ?? null, stats() ?? null)}
pairs={modelComparisonPairs(
page()?.catalog.labModels,
catalogLabs(),
catalogEntry() ?? null,
stats() ?? null,
)}
title="Compare This Model"
description="Other models to compare with this one."
variant="featured"
@ -265,12 +278,13 @@ function ModelHero(props: {
data: StatsModelPageData | null
catalog: ModelCatalogEntry | null
catalogData: ModelPageCatalog | null
labName: string
labName?: string
formerName?: string
}) {
const i18n = useI18n()
const language = useLanguage()
const labId = () => props.catalog?.lab ?? props.data?.provider ?? props.labName
const labId = () => props.catalog?.lab ?? props.data?.provider
const hasLab = () => props.labName !== undefined
const modelName = () => props.catalog?.name ?? props.data?.model ?? i18n.t("model.fallback")
const weights = () => props.catalog?.weights[0]
const labs = () => props.catalogData?.labs ?? []
@ -281,35 +295,31 @@ function ModelHero(props: {
<a data-slot="model-hero-crumb" href={language.route(import.meta.env.BASE_URL)}>
Data
</a>
<span data-slot="model-hero-separator">/</span>
<Show
when={labs().length > 0}
fallback={
<span data-slot="model-hero-crumb" data-menu="true">
<span>{props.labName}</span>
<ChevronDownIcon />
</span>
}
>
<BreadcrumbSelect
ariaLabel="Choose a lab"
label={props.labName}
options={labs().map((lab) => ({
href: language.route(`${import.meta.env.BASE_URL}${lab.id}`),
label: lab.name,
value: lab.id,
}))}
value={providerSlug(labId())}
variant="model"
/>
<Show when={hasLab()}>
<span data-slot="model-hero-separator">/</span>
<Show
when={labs().length > 0}
fallback={<span data-slot="model-hero-crumb">{props.labName}</span>}
>
<BreadcrumbSelect
ariaLabel="Choose a lab"
label={props.labName ?? ""}
options={labs().map((lab) => ({
href: language.route(`${import.meta.env.BASE_URL}${lab.id}`),
label: lab.name,
value: lab.id,
}))}
value={providerSlug(labId() ?? "")}
variant="model"
/>
</Show>
</Show>
<span data-slot="model-hero-separator">/</span>
<Show
when={labModels().length > 0}
fallback={
<span data-slot="model-hero-crumb" data-menu="true" data-current="true" aria-current="page">
<span>{modelName()}</span>
<ChevronDownIcon />
<span data-slot="model-hero-crumb" data-current="true" aria-current="page">
{modelName()}
</span>
}
>
@ -328,9 +338,11 @@ function ModelHero(props: {
</Show>
</nav>
<div data-slot="model-hero-title-row">
<span data-slot="model-hero-avatar">
<ProviderIcon aria-hidden="true" id={getProviderIconId(labId())} />
</span>
<Show when={hasLab()}>
<span data-slot="model-hero-avatar">
<ProviderIcon aria-hidden="true" id={getProviderIconId(labId() ?? "")} />
</span>
</Show>
<h1>{modelName()}</h1>
<div data-slot="model-hero-actions">
<Show when={props.catalog?.openWeights && weights()}>
@ -980,7 +992,7 @@ function GeoCountryList(props: {
)
}
function ModelPeersSection(props: { data: StatsModelPageData | null }) {
function ModelPeersSection(props: { data: StatsModelPageData | null; catalogLabs: readonly string[] }) {
const i18n = useI18n()
return (
<section id="peers" data-section="model-panel">
@ -993,7 +1005,7 @@ function ModelPeersSection(props: { data: StatsModelPageData | null }) {
>
<ol data-component="model-peer-list">
<For each={props.data?.peers ?? []}>
{(peer) => <PeerRow peer={peer} active={peer.model === props.data?.model} />}
{(peer) => <PeerRow peer={peer} active={peer.model === props.data?.model} catalogLabs={props.catalogLabs} />}
</For>
</ol>
</Show>
@ -1011,23 +1023,29 @@ function MetricCard(props: { label: string; value: string; detail?: string; stat
)
}
function PeerRow(props: { peer: ModelPeerEntry; active: boolean }) {
function PeerRow(props: { peer: ModelPeerEntry; active: boolean; catalogLabs: readonly string[] }) {
const language = useLanguage()
const hasProvider = () => isKnownCatalogLab(props.peer.provider, props.catalogLabs)
return (
<li>
<a
href={language.route(`${import.meta.env.BASE_URL}${providerSlug(props.peer.provider)}/${props.peer.slug}`)}
data-active={props.active ? "true" : undefined}
data-providerless={!hasProvider() ? "true" : undefined}
>
<span data-slot="model-peer-rank" aria-label={props.active ? `Rank ${props.peer.rank}` : undefined}>
<Show when={!props.active}>{String(props.peer.rank).padStart(2, "0")}</Show>
</span>
<span data-slot="model-peer-avatar">
<ProviderIcon aria-hidden="true" id={getProviderIconId(props.peer.author)} />
</span>
<Show when={hasProvider()}>
<span data-slot="model-peer-avatar">
<ProviderIcon aria-hidden="true" id={getProviderIconId(props.peer.author)} />
</span>
</Show>
<span data-slot="model-peer-copy">
<strong>{props.peer.model}</strong>
<em>{props.peer.author}</em>
<Show when={hasProvider()}>
<em>{props.peer.author}</em>
</Show>
</span>
<b>{formatTokens(props.peer.tokens)}</b>
</a>
@ -1050,6 +1068,7 @@ function ModelEmptyState(props: { title: string; description: string; compact?:
function modelComparisonPairs(
catalogModels: ModelCatalogOption[] | undefined,
catalogLabs: readonly string[],
catalogEntry: ModelCatalogEntry | null,
data: StatsModelPageData | null,
) {
@ -1064,7 +1083,7 @@ function modelComparisonPairs(
name: peer.model,
lab: peer.provider,
slug: peer.slug,
labName: peer.author,
labName: isKnownCatalogLab(peer.provider, catalogLabs) ? peer.author : undefined,
metric: `#${peer.rank} / ${formatTokens(peer.tokens)}`,
},
detail: "Usage peer",
@ -1090,7 +1109,7 @@ function modelComparisonRef(
name: data.model,
lab: data.provider,
slug: data.slug,
labName: data.author,
labName: undefined,
metric: `#${data.rank}`,
}
}

View file

@ -119,17 +119,24 @@ function ComparisonCardIcon() {
}
function ComparisonPanelCard(props: { pair: ComparisonPair }) {
const firstLabName = () => props.pair.first.labName
const secondLabName = () => props.pair.second.labName
return (
<a data-component="comparison-card" href={canonicalComparisonHref(props.pair.first, props.pair.second)}>
<span>{props.pair.detail}</span>
<strong>
{props.pair.first.name} <em>vs</em> {props.pair.second.name}
</strong>
<p>
<b>{props.pair.first.labName ?? formatCatalogLabName(props.pair.first.lab)}</b>
<i />
<b>{props.pair.second.labName ?? formatCatalogLabName(props.pair.second.lab)}</b>
</p>
<Show when={firstLabName() || secondLabName()}>
<p>
<Show when={firstLabName()}>{(name) => <b>{name()}</b>}</Show>
<Show when={firstLabName() && secondLabName()}>
<i />
</Show>
<Show when={secondLabName()}>{(name) => <b>{name()}</b>}</Show>
</p>
</Show>
<Show when={props.pair.first.metric || props.pair.second.metric}>
<small>
{props.pair.first.metric ?? "Listed"} / {props.pair.second.metric ?? "Listed"}
@ -143,14 +150,16 @@ function ComparisonLabLogo(props: { model: ComparisonModelRef }) {
const iconId = () => providerIconId(props.model.lab)
return (
<span
data-slot="compare-home-avatar"
data-lab={iconId()}
data-size="small"
aria-label={props.model.labName ?? formatCatalogLabName(props.model.lab)}
>
<ProviderIcon aria-hidden="true" id={iconId()} />
</span>
<Show when={props.model.labName}>
<span
data-slot="compare-home-avatar"
data-lab={iconId()}
data-size="small"
aria-label={props.model.labName}
>
<ProviderIcon aria-hidden="true" id={iconId()} />
</span>
</Show>
)
}

View file

@ -9,7 +9,7 @@ const toolUseBenchmarkPattern = /(terminal bench|claw eval|tau ?(?:bench|2|3))/
export type ComparisonRadarModel = {
name: string
labName: string
labName?: string
catalog: ModelCatalogEntry | null
}
@ -61,7 +61,7 @@ export function ComparisonRadar(props: ComparisonRadarProps) {
<i style={{ background: model.color }} aria-hidden="true" />
<span>
<strong>{model.name}</strong>
<small>{model.labName}</small>
<Show when={model.labName}>{(name) => <small>{name()}</small>}</Show>
</span>
</li>
)}

View file

@ -5320,6 +5320,10 @@ body {
text-decoration: none;
}
[data-page="stats"] [data-component="model-peer-list"] a[data-providerless="true"] {
grid-template-columns: 32px minmax(0, 1fr) minmax(64px, auto);
}
[data-page="stats"] [data-component="model-peer-list"] a:hover,
[data-page="stats"] [data-component="model-peer-list"] a[data-active="true"] {
border-color: var(--stats-text);
@ -8483,6 +8487,10 @@ body {
gap: 12px;
}
[data-page="stats"] [data-component="model-peer-list"] a[data-providerless="true"] {
grid-template-columns: 28px minmax(0, 1fr) minmax(56px, auto);
}
[data-page="stats"] [data-slot="model-peer-rank"] {
width: 28px;
}

View file

@ -21,7 +21,7 @@ import { LocaleLinks } from "../component/locale-links"
import { useI18n } from "../context/i18n"
import { useLanguage } from "../context/language"
import { localizedUrl } from "../lib/language"
import { findModelCatalogEntry, loadModelCatalog, type ModelCatalog } from "./model-catalog"
import { findModelCatalogEntry, isKnownCatalogLab, loadModelCatalog, type ModelCatalog } from "./model-catalog"
import { SectionHeading } from "./section-heading"
import { setStatsPageCacheHeaders } from "./stats-cache"
import { ComparisonCardsSection, uniqueComparisonPairs, type ComparisonModelRef } from "./compare-cards"
@ -72,6 +72,7 @@ type StatsHomePageData = {
sessionCost: SessionCostEntry[]
retention: RetentionEntry[]
country: CountryEntry[]
catalogLabs: string[]
}
const countryNumericIds = new Map(
@ -92,6 +93,7 @@ const getData = query(async () => {
sessionCost: stats.sessionCost.Go,
retention: stats.retention,
country: stats.country,
catalogLabs: catalog.labs.map((lab) => lab.id),
} satisfies StatsHomePageData
}, "getStatsHomeData")
@ -147,7 +149,11 @@ export default function StatsHome() {
{(stats) => (
<>
<Hero updatedAt={stats().updatedAt} />
<TopModelsSection data={stats().usage} leaderboard={stats().leaderboard} />
<TopModelsSection
data={stats().usage}
leaderboard={stats().leaderboard}
catalogLabs={stats().catalogLabs}
/>
<UniqueUsersSection data={stats().users} />
<RetentionSection data={stats().retention} />
<SessionCostSection data={stats().sessionCost} />
@ -156,7 +162,7 @@ export default function StatsHome() {
<MarketShareSection data={stats().market} />
<GeoBreakdownSection data={stats().country} />
<ComparisonCardsSection
pairs={homeComparisonPairs(stats().leaderboard)}
pairs={homeComparisonPairs(stats().leaderboard, stats().catalogLabs)}
title="Model Comparisons"
description="Popular model pairs from the leaderboard."
variant="featured"
@ -368,7 +374,7 @@ function formatUpdatedAtLabel(value: { date: string; time: string }) {
return `${value.date}, ${value.time}`
}
function TopModelsSection(props: { data: UsagePoint[]; leaderboard: LeaderboardEntry[] }) {
function TopModelsSection(props: { data: UsagePoint[]; leaderboard: LeaderboardEntry[]; catalogLabs: readonly string[] }) {
const i18n = useI18n()
const [activeModel, setActiveModel] = createSignal<string>()
@ -393,7 +399,12 @@ function TopModelsSection(props: { data: UsagePoint[]; leaderboard: LeaderboardE
<EmptyState title={i18n.t("home.noLeaderboardTitle")} description={i18n.t("home.noLeaderboardDescription")} />
}
>
<Leaderboard data={props.leaderboard} activeModel={activeModel()} onActiveModelChange={setActiveModel} />
<Leaderboard
data={props.leaderboard}
activeModel={activeModel()}
onActiveModelChange={setActiveModel}
catalogLabs={props.catalogLabs}
/>
</Show>
</section>
)
@ -806,6 +817,7 @@ function Leaderboard(props: {
data: LeaderboardEntry[]
activeModel: string | undefined
onActiveModelChange: (model: string | undefined) => void
catalogLabs: readonly string[]
}) {
const featured = createMemo(() => props.data.slice(0, 3))
const compact = createMemo(() => props.data.slice(3))
@ -820,6 +832,7 @@ function Leaderboard(props: {
size="featured"
active={props.activeModel === entry.model}
onActiveModelChange={props.onActiveModelChange}
catalogLabs={props.catalogLabs}
/>
)}
</For>
@ -833,6 +846,7 @@ function Leaderboard(props: {
size="compact"
active={props.activeModel === entry.model}
onActiveModelChange={props.onActiveModelChange}
catalogLabs={props.catalogLabs}
/>
)}
</For>
@ -845,6 +859,7 @@ function Leaderboard(props: {
size="featured"
active={props.activeModel === entry.model}
onActiveModelChange={props.onActiveModelChange}
catalogLabs={props.catalogLabs}
/>
)}
</For>
@ -858,9 +873,11 @@ function LeaderboardCard(props: {
size: "featured" | "compact"
active: boolean
onActiveModelChange: (model: string | undefined) => void
catalogLabs: readonly string[]
}) {
const i18n = useI18n()
const language = useLanguage()
const hasProvider = () => isKnownCatalogLab(props.entry.provider, props.catalogLabs)
return (
<a
data-component="leader-card"
@ -879,16 +896,22 @@ function LeaderboardCard(props: {
onClick={() => props.onActiveModelChange(props.entry.model)}
>
<span data-slot="rank">{String(props.entry.rank).padStart(2, "0")}</span>
<ProviderIcon data-slot="leader-watermark" aria-hidden="true" id={getProviderIconId(props.entry.author)} />
<Show when={hasProvider()}>
<ProviderIcon data-slot="leader-watermark" aria-hidden="true" id={getProviderIconId(props.entry.author)} />
</Show>
<div data-slot="leader-body">
<ProviderIcon data-slot="leader-avatar" aria-hidden="true" id={getProviderIconId(props.entry.author)} />
<Show when={hasProvider()}>
<ProviderIcon data-slot="leader-avatar" aria-hidden="true" id={getProviderIconId(props.entry.author)} />
</Show>
<div data-slot="leader-copy">
<div>
<strong>{props.entry.model}</strong>
<span>{formatBillions(props.entry.tokens)}</span>
</div>
<div>
<span>{props.entry.author}</span>
<Show when={hasProvider()} fallback={<span />}>
<span>{props.entry.author}</span>
</Show>
<span
data-slot="delta"
data-new={props.entry.change === null ? "true" : undefined}
@ -1669,22 +1692,24 @@ function formatSessionCost(value: number) {
return `$${value.toFixed(4)}`
}
function homeComparisonPairs(leaderboard: LeaderboardEntry[]) {
function homeComparisonPairs(leaderboard: LeaderboardEntry[], catalogLabs: readonly string[]) {
return uniqueComparisonPairs(
comparisonPairIndexes.flatMap(([firstIndex, secondIndex, detail]) => {
const first = leaderboard[firstIndex]
const second = leaderboard[secondIndex]
return first && second ? [{ first: leaderboardRef(first), second: leaderboardRef(second), detail }] : []
return first && second
? [{ first: leaderboardRef(first, catalogLabs), second: leaderboardRef(second, catalogLabs), detail }]
: []
}),
)
}
function leaderboardRef(entry: LeaderboardEntry): ComparisonModelRef {
function leaderboardRef(entry: LeaderboardEntry, catalogLabs: readonly string[]): ComparisonModelRef {
return {
name: entry.model,
lab: entry.provider,
slug: modelSlug(entry.model),
labName: entry.author,
labName: isKnownCatalogLab(entry.provider, catalogLabs) ? entry.author : undefined,
metric: `#${entry.rank} / ${formatBillions(entry.tokens)}`,
}
}

View file

@ -114,6 +114,16 @@ export function formatCatalogLabName(lab: string) {
return known[catalogSlug(lab)] ?? lab.replace(/[-_]/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase())
}
export function isProviderlessLab(lab: string | undefined) {
return !lab || catalogSlug(lab) === "unknown"
}
export function isKnownCatalogLab(lab: string | undefined, catalogLabs: readonly string[]) {
if (!lab || isProviderlessLab(lab)) return false
const key = catalogSlug(formatCatalogLabName(lab))
return catalogLabs.some((candidate) => catalogSlug(formatCatalogLabName(candidate)) === key)
}
export function catalogSlug(value: string) {
return value
.trim()