Download src/shared/deck.ts from tostido/weed-sim: direct link, hf CLI and curl.
- Browser
- Download file 3.76 kB
-
https://huggingface.co/spaces/tostido/weed-sim/resolve/main/src/shared/deck.ts
- Command line
-
hf download hf://spaces/tostido/weed-sim/src/shared/deck.ts
-
curl -L -o deck.ts https://huggingface.co/spaces/tostido/weed-sim/resolve/main/src/shared/deck.ts
3.76 kB
| import { germplasmRecords } from './lab'; | |
| import type { DeckSummary, GermplasmRecord, Rgb, SeedProfile } from './types'; | |
| function mean(values: unknown[]): number { | |
| const numeric = values.filter((value): value is number => typeof value === 'number' && Number.isFinite(value)); | |
| return numeric.length ? Math.round((numeric.reduce((sum, value) => sum + value, 0) / numeric.length) * 10) / 10 : 0; | |
| } | |
| function increment(target: Record<string, number>, key: string | number): void { | |
| const normalized = String(key); | |
| target[normalized] = (target[normalized] ?? 0) + 1; | |
| } | |
| export function deckSummary(seeds: SeedProfile[]): DeckSummary { | |
| const records = germplasmRecords(seeds); | |
| const byStage: Record<string, number> = {}; | |
| const byType: Record<string, number> = {}; | |
| const byGenerationRaw: Record<string, number> = {}; | |
| const byBudFamily: Record<string, number> = {}; | |
| for (const record of records) { | |
| increment(byStage, record.stage); | |
| increment(byType, record.germplasmType); | |
| increment(byGenerationRaw, record.generation); | |
| increment(byBudFamily, record.budFamily); | |
| } | |
| const breedable = records.filter((record) => record.canAttempt && record.stage === 'MATURE'); | |
| const growing = records.filter((record) => record.stage !== 'MATURE'); | |
| const crosses = records.filter((record) => record.parents.every(Boolean)); | |
| const recentCrosses = crosses | |
| .slice(-6) | |
| .reverse() | |
| .map((record) => ({ | |
| id: record.germplasmDbId, | |
| name: record.germplasmName, | |
| generation: record.generation, | |
| pedigree: record.pedigree, | |
| budColor: record.budColor as Rgb, | |
| leafColor: record.leafColor as Rgb, | |
| THC: record.THC, | |
| })); | |
| const generationEntries = Object.entries(byGenerationRaw) | |
| .map(([generation, count]) => [`F${generation}`, count] as const) | |
| .sort(([left], [right]) => left.localeCompare(right)); | |
| const topBloom = [...records] | |
| .sort((left, right) => right.Bloom - left.Bloom) | |
| .slice(0, 6) | |
| .map((record) => ({ | |
| id: record.germplasmDbId, | |
| name: record.germplasmName, | |
| generation: record.generation, | |
| pedigree: record.pedigree, | |
| budColor: record.budColor, | |
| leafColor: record.leafColor, | |
| budPalette: record.budPalette, | |
| Bloom: record.Bloom, | |
| Volatility: record.Volatility, | |
| budPattern: record.budPattern, | |
| colorCount: record.budBloom.colorCount, | |
| hueSpread: record.budBloom.hueSpread, | |
| THC: record.THC, | |
| })); | |
| return { | |
| accessions: records.length, | |
| byStage, | |
| byType: sortRecord(byType), | |
| byGeneration: Object.fromEntries(generationEntries), | |
| byBudFamily: sortRecord(byBudFamily), | |
| maxGeneration: maxGeneration(records), | |
| breedableCount: breedable.length, | |
| growingCount: growing.length, | |
| traitAverages: { | |
| THC: mean(records.map((record) => record.THC)), | |
| CBD: mean(records.map((record) => record.CBD)), | |
| Yield: mean(records.map((record) => record.Yield)), | |
| GrowTime: mean(records.map((record) => record.GrowTime)), | |
| Stability: mean(records.map((record) => record.Stability)), | |
| Volatility: mean(records.map((record) => record.Volatility)), | |
| Bloom: mean(records.map((record) => record.Bloom)), | |
| }, | |
| gamut: records.map((record) => record.budColor), | |
| recentCrosses, | |
| topBloom, | |
| breedable: breedable.map((record) => ({ | |
| id: record.germplasmDbId, | |
| name: record.germplasmName, | |
| })), | |
| }; | |
| } | |
| function sortRecord(record: Record<string, number>): Record<string, number> { | |
| return Object.fromEntries(Object.entries(record).sort(([left], [right]) => left.localeCompare(right))); | |
| } | |
| function maxGeneration(records: GermplasmRecord[]): number { | |
| return records.length ? Math.max(...records.map((record) => record.generation)) : 0; | |
| } | |