Compare commits

..

1 Commits

Author SHA1 Message Date
c452b69dd6 NAMEGEN-2-FE: 5 neue Namenskategorien (Disney, Pokémon, Englische/Kroatische Städte, US-Bundesstaaten)
- NAMEGEN_USAGES: +disney, +pokemon, +encities, +hrcities, +usstates (jetzt 10 Einträge)
- names.test.ts: Count-Test 5→10, neue toContain-Checks für alle 5 Codes

Gate: vitest 107/107, e2e 160/160, tsc clean
2026-06-06 21:48:08 +02:00
10 changed files with 72 additions and 639 deletions

View File

@@ -40,25 +40,6 @@ npm run build
npm run preview npm run preview
``` ```
## Farbschlag-Katalog (AR-5)
Der Katalog lebt in `src/genetics/catalog.ts` (Single Source of Truth).
Nach jeder Änderung dort den Generator laufen lassen:
```bash
npm run gen:catalog
```
Erzeugt zwei Artefakte und committet beide:
| Datei | Notation | Verwendung |
|---|---|---|
| `src/genetics/colorVarietySeed.generated.json` | Klammer (`e[f]`, `c[chm]`) | UI-Dropdowns, Frontend-Suche |
| `src/genetics/colorVarietySeed.backend.json` | Frozen symbols (`ef`, `cchm`) | EF-Seed-Migrationen (Pam, DATA-Lane) |
Der vitest-Drift-Guard (`catalog-drift.test.ts`) schlägt fehl, wenn
`generated.json` nach einer Katalog-Änderung nicht aktualisiert wurde.
## E2E-Tests (QA-1, Playwright) ## E2E-Tests (QA-1, Playwright)
```bash ```bash
@@ -75,4 +56,4 @@ npx playwright test --project=phone # nur Smartphone-Viewport (390px)
überspringen sich selbst; die übrigen legen eigene Datensätze an. überspringen sich selbst; die übrigen legen eigene Datensätze an.
- Beide Viewports (Smartphone 390px, Laptop 1280px) laufen für jede Spec; - Beide Viewports (Smartphone 390px, Laptop 1280px) laufen für jede Spec;
alle Assertions prüfen die deutschen Oberflächentexte direkt aus alle Assertions prüfen die deutschen Oberflächentexte direkt aus
`src/strings/de.ts`. `src/strings/de.ts`.

View File

@@ -1,49 +0,0 @@
/**
* Katalog-Generator — AR-5
*
* Erzeugt zwei Artefakte aus catalog.ts (Single Source of Truth):
*
* colorVarietySeed.generated.json — Display-Notation (Klammer: e[f]/c[chm]/c[h])
* → Quelle für UI-Dropdowns, Frontend-Suche.
*
* colorVarietySeed.backend.json — Frozen internal symbols (ef/cchm/ch)
* → Quelle für künftige EF-Seed-Migrationen (Pam).
* NICHT in Bracket-Notation ändern — Backend-Parser
* erwartet frozen symbols (CR-11-Matcher-Guardrail).
*
* Ausführen nach jeder Änderung an catalog.ts:
* npm run gen:catalog
*
* Der vitest-Drift-Guard (catalog-drift.test.ts) schlägt fehl, wenn
* generated.json veraltet ist — Fehler macht den fehlenden Generator-Lauf sichtbar.
*/
import { BASE_COLORS, CATALOG, representativeGenotype } from './src/genetics/catalog.ts'
import { LOCUS_ORDER } from './src/genetics/loci.ts'
import type { Genotype } from './src/genetics/genotype.ts'
import { writeFileSync } from 'fs'
/** Internal (frozen) display string — concatenates canonical allele symbols without bracket mapping. */
function toInternalString(g: Genotype): string {
return LOCUS_ORDER.filter(
(locus) => locus !== 'Sls' || !(g.Sls[0] === 'sl' && g.Sls[1] === 'sl'),
)
.map((locus) => (g[locus][0] + g[locus][1]).replace(/\?/g, '-'))
.join(' ')
}
// ── Display artefact (bracket notation) ─────────────────────────────────────
const displayPath = './src/genetics/colorVarietySeed.generated.json'
writeFileSync(displayPath, JSON.stringify(CATALOG, null, 2) + '\n')
console.log(`[gen:catalog] display → ${displayPath} (${CATALOG.length} rows)`)
// ── Backend artefact (frozen internal symbols) ───────────────────────────────
const backendSeed = BASE_COLORS.map((entry, i) => ({
name: entry.name,
...(entry.english !== undefined ? { english: entry.english } : {}),
canonicalGenotype: toInternalString(representativeGenotype(entry)),
sortOrder: i,
...(entry.image !== undefined ? { image: entry.image } : {}),
}))
const backendPath = './src/genetics/colorVarietySeed.backend.json'
writeFileSync(backendPath, JSON.stringify(backendSeed, null, 2) + '\n')
console.log(`[gen:catalog] backend → ${backendPath} (${backendSeed.length} rows)`)

View File

@@ -10,8 +10,7 @@
"preview": "vite preview", "preview": "vite preview",
"test": "vitest run", "test": "vitest run",
"test:watch": "vitest", "test:watch": "vitest",
"e2e": "playwright test", "e2e": "playwright test"
"gen:catalog": "npx tsx gen-seed.mts"
}, },
"dependencies": { "dependencies": {
"jszip": "^3.10.1", "jszip": "^3.10.1",

View File

@@ -62,7 +62,12 @@ describe('NAMEGEN_USAGES', () => {
expect(codes).toContain('mythg') expect(codes).toContain('mythg')
expect(codes).toContain('ger') expect(codes).toContain('ger')
expect(codes).toContain('arb') expect(codes).toContain('arb')
expect(codes).toHaveLength(5) expect(codes).toContain('disney')
expect(codes).toContain('pokemon')
expect(codes).toContain('encities')
expect(codes).toContain('hrcities')
expect(codes).toContain('usstates')
expect(codes).toHaveLength(10)
}) })
it('every usage has a non-empty label', () => { it('every usage has a non-empty label', () => {

View File

@@ -13,6 +13,11 @@ export const NAMEGEN_USAGES = [
{ code: 'mythg', label: 'Griech. Mythologie' }, { code: 'mythg', label: 'Griech. Mythologie' },
{ code: 'ger', label: 'Deutsch' }, { code: 'ger', label: 'Deutsch' },
{ code: 'arb', label: 'Arabisch' }, { code: 'arb', label: 'Arabisch' },
{ code: 'disney', label: 'Disney' },
{ code: 'pokemon', label: 'Pokémon' },
{ code: 'encities', label: 'Englische Städte' },
{ code: 'hrcities', label: 'Kroatische Städte' },
{ code: 'usstates', label: 'US-Bundesstaaten' },
] as const ] as const
export type NamegenUsageCode = (typeof NAMEGEN_USAGES)[number]['code'] export type NamegenUsageCode = (typeof NAMEGEN_USAGES)[number]['code']

View File

@@ -1,24 +0,0 @@
/**
* AR-5 Drift-Guard: colorVarietySeed.generated.json muss mit dem Live-Output
* aus catalog.ts übereinstimmen.
*
* Schlägt dieser Test fehl, wurde catalog.ts verändert ohne danach
* `npm run gen:catalog` auszuführen. Fix: `npm run gen:catalog` laufen lassen
* und die geänderten JSON-Dateien committen.
*/
import { readFileSync } from 'fs'
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'
import { describe, it, expect } from 'vitest'
import { CATALOG } from '../catalog'
const __dir = dirname(fileURLToPath(import.meta.url))
describe('AR-5 Catalog drift-guard', () => {
it('colorVarietySeed.generated.json stimmt mit catalog.ts überein (sonst: npm run gen:catalog)', () => {
const jsonPath = join(__dir, '..', 'colorVarietySeed.generated.json')
const committed = JSON.parse(readFileSync(jsonPath, 'utf-8'))
// CATALOG is readonly — deep equality against the plain parsed array is sufficient.
expect(committed).toEqual(Array.from(CATALOG))
})
})

View File

@@ -377,11 +377,9 @@ describe("GEN-3c: unknown allele displays as '-' (stored as '?')", () => {
}) })
describe('GEN-3c: no Unbekannt when the E locus is known (family fallback)', () => { describe('GEN-3c: no Unbekannt when the E locus is known (family fallback)', () => {
it('eef with unknown other loci -> specific Schimmel variety (GEN-4: Fuchsschimmel is a category)', () => { it('eef with unknown other loci -> Fuchsschimmel (the reported bug case)', () => {
// GEN-4: locusToken ef/e -> 'ef' enables catalog match; family fallback 'Fuchsschimmel' blocked.
// aa + ef/e + C/D/G/P resolved via GEN-3d -> Kohlfuchsschimmel (A:a, C:C, D:D, E:ef, G:G, P:P).
expect(genotypeToFarbschlag(fromDisplayString('aa C- D- eef Gg Pp spsp --'))).toBe( expect(genotypeToFarbschlag(fromDisplayString('aa C- D- eef Gg Pp spsp --'))).toBe(
'Kohlfuchsschimmel', 'Fuchsschimmel',
) )
}) })
it('ee -> Fuchs family, efef -> a Schimmel (never Unbekannt) even with unknowns', () => { it('ee -> Fuchs family, efef -> a Schimmel (never Unbekannt) even with unknowns', () => {
@@ -407,11 +405,9 @@ describe('GEN-3d: dominance tiebreak for unknown loci', () => {
expect(genotypeToFarbschlag(fromDisplayString('AA CC DD EE GG PP sp- rere'))).toBe('Agouti') expect(genotypeToFarbschlag(fromDisplayString('AA CC DD EE GG PP sp- rere'))).toBe('Agouti')
}) })
it('still: eef with unknowns -> specific variety, not category (GEN-4 update)', () => { it('still: eef with unknowns -> Fuchsschimmel (family pin unaffected by tiebreak)', () => {
// GEN-4: 'Fuchsschimmel' is a Farbart/category; the engine now resolves to the
// specific catalog entry (Kohlfuchsschimmel) via the locusToken ef/e -> 'ef' fix.
expect(genotypeToFarbschlag(fromDisplayString('aa C- D- eef Gg Pp spsp --'))).toBe( expect(genotypeToFarbschlag(fromDisplayString('aa C- D- eef Gg Pp spsp --'))).toBe(
'Kohlfuchsschimmel', 'Fuchsschimmel',
) )
}) })
}) })
@@ -565,21 +561,6 @@ describe('GEN-4: Dilute prefix, REW, no-bare-Fuchs', () => {
expect(name('AA Cch DD EE GG pp spsp rere')).not.toBe('REW') // Cc[h] + pp expect(name('AA Cch DD EE GG pp spsp rere')).not.toBe('REW') // Cc[h] + pp
}) })
it('Farbarten (categories) never appear as computed results', () => {
// 'Fuchs', 'Fuchsschimmel', 'Schimmel' etc. are Farbarten — blocked by category guard.
// het ef/e now resolves to specific variety via locusToken ef/e -> 'ef' fix.
expect(genotypeToFarbschlag(fromDisplayString('aa CC DD eef GG PP spsp rere'))).toBe('Kohlfuchsschimmel')
// Agouti ef/e: 'Orangeschimmel' wins (same token-set as Algierfuchsschimmel, listed first)
expect(genotypeToFarbschlag(fromDisplayString('AA CC DD eef GG PP spsp rere'))).toBe('Orangeschimmel')
// Unusual combo not in catalog -> Unbekannt (not 'Fuchsschimmel')
expect(farbschlagFor(fromDisplayString('aa CC dd eef GG PP spsp rere')).unknown).toBe(true)
// FK check: none of the 7 category names are in BASE_COLORS (no DB entries -> no FK risk)
const CATS = ['Standard', 'Colourpoint', 'Dilute', 'Fuchs', 'Fuchsschimmel', 'Schimmel', 'Colourpoint Dilute']
for (const cat of CATS) {
expect(BASE_COLORS.some(e => e.name === cat)).toBe(false)
}
})
it('bare Fuchs never appears — dilute-fox combinations are named specifically', () => { it('bare Fuchs never appears — dilute-fox combinations are named specifically', () => {
expect(name('AA CC dd ee GG PP spsp rere')).toBe('Dilute Algierfuchs') expect(name('AA CC dd ee GG PP spsp rere')).toBe('Dilute Algierfuchs')
expect(name('AA CC dd ee GG pp spsp rere')).toBe('Dilute Goldfuchs') expect(name('AA CC dd ee GG pp spsp rere')).toBe('Dilute Goldfuchs')

View File

@@ -78,9 +78,8 @@ export const BASE_COLORS: readonly FarbschlagEntry[] = [
{ name: 'Kohlfuchs', tokens: { A: 'a', C: 'C', D: 'D', E: 'e', G: 'G', P: 'P' }, image: 'kohlfuchs.jpg' }, { name: 'Kohlfuchs', tokens: { A: 'a', C: 'C', D: 'D', E: 'e', G: 'G', P: 'P' }, image: 'kohlfuchs.jpg' },
{ name: 'Polarfuchs', tokens: { A: 'A', C: 'C', D: 'D', E: 'e', G: 'g', P: 'P' }, image: 'polarfuchs.jpg' }, { name: 'Polarfuchs', tokens: { A: 'A', C: 'C', D: 'D', E: 'e', G: 'g', P: 'P' }, image: 'polarfuchs.jpg' },
{ name: 'Saphir', tokens: { A: 'a', C: 'C', D: 'D', E: 'E', G: 'G', P: 'p' }, image: 'saphir.jpg' }, { name: 'Saphir', tokens: { A: 'a', C: 'C', D: 'D', E: 'E', G: 'G', P: 'p' }, image: 'saphir.jpg' },
// GEN-3a: efef base (agouti, wild C/D/G/P) = Orangeschimmel (breeder C5). // GEN-3a: efef base (otherwise wild C/D/G/P) = Orangeschimmel (breeder C5).
// GEN-4: A:'A' added — non-agouti ef animals fall through to Kohlfuchsschimmel etc. { name: 'Orangeschimmel', tokens: { C: 'C', D: 'D', E: 'ef', G: 'G', P: 'P' }, image: 'schimmel-orangeschimmel.jpg' },
{ name: 'Orangeschimmel', tokens: { A: 'A', C: 'C', D: 'D', E: 'ef', G: 'G', P: 'P' }, image: 'schimmel-orangeschimmel.jpg' },
{ name: 'Topas', tokens: { A: 'A', C: 'C', D: 'D', E: 'E', G: 'G', P: 'p' }, image: 'topas.jpg' }, { name: 'Topas', tokens: { A: 'A', C: 'C', D: 'D', E: 'E', G: 'G', P: 'p' }, image: 'topas.jpg' },
{ name: 'Platin-Hell', tokens: { A: 'a', C: 'C', D: 'D', E: 'E', G: 'G', P: 'p' }, image: 'platin-hell.jpg' }, { name: 'Platin-Hell', tokens: { A: 'a', C: 'C', D: 'D', E: 'E', G: 'G', P: 'p' }, image: 'platin-hell.jpg' },
{ name: 'Dilute Agouti', tokens: { A: 'A', C: 'C', D: 'd', E: 'E', G: 'G', P: 'P' }, image: 'agouti-dd.jpg' }, { name: 'Dilute Agouti', tokens: { A: 'A', C: 'C', D: 'd', E: 'E', G: 'G', P: 'P' }, image: 'agouti-dd.jpg' },
@@ -95,7 +94,6 @@ export const BASE_COLORS: readonly FarbschlagEntry[] = [
{ name: 'Dilute Polarfuchs', tokens: { A: 'A', C: 'C', D: 'd', E: 'e', G: 'g', P: 'P' } }, { name: 'Dilute Polarfuchs', tokens: { A: 'A', C: 'C', D: 'd', E: 'e', G: 'g', P: 'P' } },
// GEN-3a: efef gg base = Silberschimmel (breeder C5) — listed before the // GEN-3a: efef gg base = Silberschimmel (breeder C5) — listed before the
// A-specific Polarfuchsschimmel so the canonical efef-gg reverse-matches here. // A-specific Polarfuchsschimmel so the canonical efef-gg reverse-matches here.
// No A restriction: both agouti (AA) and non-agouti (aa) ef/gg = Silberschimmel.
{ name: 'Silberschimmel', tokens: { C: 'C', D: 'D', E: 'ef', G: 'g', P: 'P' }, image: 'silberschimmel.jpg' }, { name: 'Silberschimmel', tokens: { C: 'C', D: 'D', E: 'ef', G: 'g', P: 'P' }, image: 'silberschimmel.jpg' },
{ name: 'Polarfuchsschimmel', tokens: { A: 'A', C: 'C', D: 'D', E: 'ef', G: 'g', P: 'P' }, image: 'polarfuchsschimmel.jpg' }, { name: 'Polarfuchsschimmel', tokens: { A: 'A', C: 'C', D: 'D', E: 'ef', G: 'g', P: 'P' }, image: 'polarfuchsschimmel.jpg' },
{ name: 'Algierfuchsschimmel', tokens: { A: 'A', C: 'C', D: 'D', E: 'ef', G: 'G', P: 'P' }, image: 'algierfuchsschimmel.jpg' }, { name: 'Algierfuchsschimmel', tokens: { A: 'A', C: 'C', D: 'D', E: 'ef', G: 'G', P: 'P' }, image: 'algierfuchsschimmel.jpg' },
@@ -155,12 +153,10 @@ export interface FarbschlagMatch {
* Expressed token at a locus. GEN-3d: an UNKNOWN allele ('?') is resolved to the * Expressed token at a locus. GEN-3d: an UNKNOWN allele ('?') is resolved to the
* MOST-DOMINANT allele of the locus (the safer default) rather than acting as a * MOST-DOMINANT allele of the locus (the safer default) rather than acting as a
* match-anything wildcard — so an unknown-C animal reads as full-colour 'C', not * match-anything wildcard — so an unknown-C animal reads as full-colour 'C', not
* a c^h/c^chm colourpoint white. The E locus uses the PHENOTYPICALLY EXPRESSED * a c^h/c^chm colourpoint white. The E locus stays PAIR-aware so the Fuchs/
* allele for catalog matching: ee->'e', ef/ef->'ef', e/ef->'ef' (ef is dominant * Schimmel family is distinguishable: ee->'e', e/ef->'eef', ef/ef->'ef'.
* for the Schimmel/roan phenotype, so het ef/e animals match Schimmel catalog * (The Fuchs/Schimmel FAMILY for unknown-E is still handled by eFamily on the
* entries such as Kohlfuchsschimmel). GEN-4: 'eef' removed — 'Fuchsschimmel' * raw pair, which runs before this.)
* is a Farbart/category, not a concrete Farbschlag; the catalog must name the
* variety specifically.
*/ */
function locusToken(g: Genotype, locus: LocusKey): string { function locusToken(g: Genotype, locus: LocusKey): string {
// Default an unknown allele to the WILD-TYPE reading: most-dominant for the // Default an unknown allele to the WILD-TYPE reading: most-dominant for the
@@ -172,9 +168,7 @@ function locusToken(g: Genotype, locus: LocusKey): string {
const [x, y] = g[locus].map((a) => (a === WILDCARD ? fallback : a)) const [x, y] = g[locus].map((a) => (a === WILDCARD ? fallback : a))
if (locus === 'E') { if (locus === 'E') {
if (x === y) return x // ee->'e', efef->'ef', EE->'E' if (x === y) return x // ee->'e', efef->'ef', EE->'E'
// GEN-4: het ef/e → 'ef' (ef is dominant for the Schimmel phenotype; if ((x === 'e' && y === 'ef') || (x === 'ef' && y === 'e')) return 'eef'
// enables catalog entries like Kohlfuchsschimmel to match het animals).
if ((x === 'e' && y === 'ef') || (x === 'ef' && y === 'e')) return 'ef'
return dominantAllele('E', x, y) // E/ef, E/e -> 'E' return dominantAllele('E', x, y) // E/ef, E/e -> 'E'
} }
return dominantAllele(locus, x, y) return dominantAllele(locus, x, y)
@@ -187,12 +181,10 @@ function matches(g: Genotype, entry: FarbschlagEntry): boolean {
} }
/** /**
* E-locus family: used to scope the catalog search to E-aware entries. * GEN-3c family fallback: the E locus alone names the Fuchs/Schimmel family even
* Returns a family tag ('Fuchs'/'Fuchsschimmel'/'Schimmel') when the E locus * when other loci are unknown (so genotypes never fall through to "Unbekannt").
* implies a non-dominant extension pair, or null for full-extension/unknown. * ee -> Fuchs | e/ef -> Fuchsschimmel | ef/ef -> Schimmel | e/? -> Fuchs (for now)
* GEN-4: these family names are Farbarten (categories), NOT concrete Farbschläge. * Returns null when E is dominant (full colour) or fully unknown.
* They are ONLY used here as catalog-search filters; they must NEVER appear as
* computed farbschlag output (the farbschlagFor category guard blocks them).
*/ */
function eFamily(g: Genotype): string | null { function eFamily(g: Genotype): string | null {
const [x, y] = g.E const [x, y] = g.E
@@ -219,10 +211,7 @@ function baseColourFor(g: Genotype): string | null {
const base = family const base = family
? (BASE_COLORS.find((e) => e.tokens.E !== undefined && matches(g, e)) ?? null) ? (BASE_COLORS.find((e) => e.tokens.E !== undefined && matches(g, e)) ?? null)
: (BASE_COLORS.find((e) => matches(g, e)) ?? null) : (BASE_COLORS.find((e) => matches(g, e)) ?? null)
// GEN-4: never fall back to the family name — Fuchs/Fuchsschimmel/Schimmel are return base?.name ?? family
// Farbarten (categories), not concrete Farbschläge. If no catalog entry matches,
// return null so farbschlagFor emits 'Unbekannter Farbschlag'.
return base?.name ?? null
} }
/** /**
@@ -279,15 +268,7 @@ export function farbschlagFor(g: Genotype): FarbschlagMatch {
} }
const baseName = colourpointName(g) ?? baseColourFor(g) const baseName = colourpointName(g) ?? baseColourFor(g)
// GEN-4: safety guard — Farbarten (categories/families) are NEVER valid as if (!baseName) {
// a computed Farbschlag output. If baseName is a category label, treat as
// Unbekannt instead of leaking an invalid name into the UI.
const CATEGORY_NAMES: ReadonlySet<string> = new Set([
'Standard', 'Colourpoint', 'Dilute',
'Fuchs', 'Fuchsschimmel', 'Schimmel',
'Colourpoint Dilute',
])
if (!baseName || CATEGORY_NAMES.has(baseName)) {
return { name: UNKNOWN_FARBSCHLAG, base: null, unknown: true } return { name: UNKNOWN_FARBSCHLAG, base: null, unknown: true }
} }
const name = [baseName, ...modifiers].join(' ') const name = [baseName, ...modifiers].join(' ')

View File

@@ -1,426 +0,0 @@
[
{
"name": "Pink Eyed White (PEW)",
"english": "Pink Eyed White",
"canonicalGenotype": "AA chch DD EE GG pp spsp rere",
"sortOrder": 0,
"image": "rotaugen-weiss-pew-d-sep-e-sep.jpg"
},
{
"name": "Hermelin",
"english": "Dark Tailed White",
"canonicalGenotype": "aa chch DD EE GG PP spsp rere",
"sortOrder": 1,
"image": "hermelin.jpeg"
},
{
"name": "Himalaya",
"english": "Himalayan",
"canonicalGenotype": "AA chch DD EE GG PP spsp rere",
"sortOrder": 2,
"image": "himalaya.jpg"
},
{
"name": "Zobel",
"english": "Sable",
"canonicalGenotype": "aa cchmcchm DD EE gg PP spsp rere",
"sortOrder": 3,
"image": "zobel.jpeg"
},
{
"name": "Rotaugenschimmel",
"english": "Red-Eyed Roan",
"canonicalGenotype": "AA CC DD efef GG pp spsp rere",
"sortOrder": 4,
"image": "rotaugen-schimmel.jpg"
},
{
"name": "Agouti",
"english": "Golden Agouti",
"canonicalGenotype": "AA CC DD EE GG PP spsp rere",
"sortOrder": 5,
"image": "agouti-mit-erklaerung-der-genloci.JPG"
},
{
"name": "Schwarz",
"english": "Black",
"canonicalGenotype": "aa CC DD EE GG PP spsp rere",
"sortOrder": 6,
"image": "schwarz.jpg"
},
{
"name": "Silberagouti",
"english": "Grey Agouti",
"canonicalGenotype": "AA CC DD EE gg PP spsp rere",
"sortOrder": 7,
"image": "silberagouti.jpg"
},
{
"name": "Anthrazit",
"english": "Slate",
"canonicalGenotype": "aa CC DD EE gg PP spsp rere",
"sortOrder": 8,
"image": "anthrazit.jpg"
},
{
"name": "Algierfuchs",
"english": "Dark-Eyed Honey",
"canonicalGenotype": "AA CC DD ee GG PP spsp rere",
"sortOrder": 9,
"image": "algierfuchs.jpg"
},
{
"name": "Blau",
"english": "Blue",
"canonicalGenotype": "aa CC dd EE GG PP spsp rere",
"sortOrder": 10,
"image": "blau-schwarz-dd.JPG"
},
{
"name": "Gold",
"english": "Argente Golden",
"canonicalGenotype": "AA CC DD EE GG pp spsp rere",
"sortOrder": 11,
"image": "gold.jpg"
},
{
"name": "Platin",
"english": "Lilac",
"canonicalGenotype": "aa CC DD EE GG pp spsp rere",
"sortOrder": 12,
"image": "platin.JPG"
},
{
"name": "Goldfuchs",
"english": "Yellow Fox",
"canonicalGenotype": "AA CC DD ee GG pp spsp rere",
"sortOrder": 13,
"image": "goldfuchs.jpg"
},
{
"name": "Rotfuchs",
"english": "Argente Nutmeg",
"canonicalGenotype": "aa CC DD ee GG pp spsp rere",
"sortOrder": 14,
"image": "rotfuchs.JPG"
},
{
"name": "Dilute Gold",
"english": "dd Argente Golden",
"canonicalGenotype": "AA CC dd EE GG pp spsp rere",
"sortOrder": 15,
"image": "gold-dd.jpg"
},
{
"name": "Dilute Platin",
"english": "dd Lilac",
"canonicalGenotype": "aa CC dd EE GG pp spsp rere",
"sortOrder": 16,
"image": "platin-dd.jpg"
},
{
"name": "Altweiss (REW)",
"canonicalGenotype": "aa CC DD EE gg pp spsp rere",
"sortOrder": 17,
"image": "altweiss-rew.jpeg"
},
{
"name": "Apricot (Blassfuchs)",
"canonicalGenotype": "AA CC DD ee gg pp spsp rere",
"sortOrder": 18,
"image": "apricot-blassfuchs.jpg"
},
{
"name": "Blaufuchs",
"canonicalGenotype": "aa CC DD ee gg PP spsp rere",
"sortOrder": 19,
"image": "blaufuchs.jpg"
},
{
"name": "C-Separator",
"canonicalGenotype": "aa CC DD ee gg pp spsp rere",
"sortOrder": 20,
"image": "c-separator.jpg"
},
{
"name": "Elfenbein",
"canonicalGenotype": "AA CC DD EE gg pp spsp rere",
"sortOrder": 21,
"image": "elfenbein.jpg"
},
{
"name": "Kohlfuchs",
"canonicalGenotype": "aa CC DD ee GG PP spsp rere",
"sortOrder": 22,
"image": "kohlfuchs.jpg"
},
{
"name": "Polarfuchs",
"canonicalGenotype": "AA CC DD ee gg PP spsp rere",
"sortOrder": 23,
"image": "polarfuchs.jpg"
},
{
"name": "Saphir",
"canonicalGenotype": "aa CC DD EE GG pp spsp rere",
"sortOrder": 24,
"image": "saphir.jpg"
},
{
"name": "Orangeschimmel",
"canonicalGenotype": "AA CC DD efef GG PP spsp rere",
"sortOrder": 25,
"image": "schimmel-orangeschimmel.jpg"
},
{
"name": "Topas",
"canonicalGenotype": "AA CC DD EE GG pp spsp rere",
"sortOrder": 26,
"image": "topas.jpg"
},
{
"name": "Platin-Hell",
"canonicalGenotype": "aa CC DD EE GG pp spsp rere",
"sortOrder": 27,
"image": "platin-hell.jpg"
},
{
"name": "Dilute Agouti",
"canonicalGenotype": "AA CC dd EE GG PP spsp rere",
"sortOrder": 28,
"image": "agouti-dd.jpg"
},
{
"name": "Dilute Silberagouti",
"canonicalGenotype": "AA CC dd EE gg PP spsp rere",
"sortOrder": 29,
"image": "silberagouti-dd.jpg"
},
{
"name": "Dilute Kohlfuchs",
"canonicalGenotype": "aa CC dd ee GG PP spsp rere",
"sortOrder": 30,
"image": "kohlfuchs-dd.jpg"
},
{
"name": "Dilute Anthrazit",
"canonicalGenotype": "aa CC dd EE gg PP spsp rere",
"sortOrder": 31,
"image": "anthrazit-dd.jpg"
},
{
"name": "Dilute Algierfuchs",
"canonicalGenotype": "AA CC dd ee GG PP spsp rere",
"sortOrder": 32
},
{
"name": "Dilute Goldfuchs",
"canonicalGenotype": "AA CC dd ee GG pp spsp rere",
"sortOrder": 33
},
{
"name": "Dilute Rotfuchs",
"canonicalGenotype": "aa CC dd ee GG pp spsp rere",
"sortOrder": 34
},
{
"name": "Dilute Polarfuchs",
"canonicalGenotype": "AA CC dd ee gg PP spsp rere",
"sortOrder": 35
},
{
"name": "Silberschimmel",
"canonicalGenotype": "AA CC DD efef gg PP spsp rere",
"sortOrder": 36,
"image": "silberschimmel.jpg"
},
{
"name": "Polarfuchsschimmel",
"canonicalGenotype": "AA CC DD efef gg PP spsp rere",
"sortOrder": 37,
"image": "polarfuchsschimmel.jpg"
},
{
"name": "Algierfuchsschimmel",
"canonicalGenotype": "AA CC DD efef GG PP spsp rere",
"sortOrder": 38,
"image": "algierfuchsschimmel.jpg"
},
{
"name": "Kohlfuchsschimmel",
"canonicalGenotype": "aa CC DD efef GG PP spsp rere",
"sortOrder": 39,
"image": "kohlfuchsschimmel.jpg"
},
{
"name": "Blaufuchsschimmel",
"canonicalGenotype": "aa CC DD efef gg PP spsp rere",
"sortOrder": 40,
"image": "blaufuchsschimmel.jpg"
},
{
"name": "Kohlfuchs, hell",
"canonicalGenotype": "aa CC DD ee GG PP spsp rere",
"sortOrder": 41,
"image": "kohlfuchs-hell.jpg"
},
{
"name": "Goldfuchs, hell",
"canonicalGenotype": "AA CC DD ee GG pp spsp rere",
"sortOrder": 42,
"image": "goldfuchs-hell.jpg"
},
{
"name": "Goldfuchsschimmel",
"canonicalGenotype": "AA CC DD efef GG pp spsp rere",
"sortOrder": 43,
"image": "goldfuchsschimmel.jpg"
},
{
"name": "Gold-Hell",
"canonicalGenotype": "AA CC DD EE GG pp spsp rere",
"sortOrder": 44,
"image": "gold-hell.jpg"
},
{
"name": "Blaufuchs, hell",
"canonicalGenotype": "aa CC DD ee gg PP spsp rere",
"sortOrder": 45,
"image": "blaufuchs-hell.jpeg"
},
{
"name": "Rotfuchsschimmel",
"canonicalGenotype": "aa CC DD efef GG pp spsp rere",
"sortOrder": 46,
"image": "rotfuchsschimmel.jpg"
},
{
"name": "Polarfuchs, hell",
"canonicalGenotype": "AA CC DD ee gg PP spsp rere",
"sortOrder": 47,
"image": "polarfuchs-hell.jpeg"
},
{
"name": "Kohlfuchsschimmel, hell",
"canonicalGenotype": "aa CC DD efef GG PP spsp rere",
"sortOrder": 48,
"image": "kohlfuchsschimmel-hell.jpg"
},
{
"name": "Rotfuchs, hell",
"canonicalGenotype": "aa CC DD ee GG pp spsp rere",
"sortOrder": 49,
"image": "rotfuchs-hell.jpg"
},
{
"name": "Kohlfuchs-Hell",
"canonicalGenotype": "aa CC DD ee GG PP spsp rere",
"sortOrder": 50,
"image": "kohlfuchs-hell-2.jpg"
},
{
"name": "Algierfuchs, hell",
"canonicalGenotype": "AA CC DD ee GG PP spsp rere",
"sortOrder": 51,
"image": "algierfuchs-hell.JPG"
},
{
"name": "Dilute Topas",
"canonicalGenotype": "AA CC dd EE GG pp spsp rere",
"sortOrder": 52,
"image": "topas-dd.jpg"
},
{
"name": "Dilute Blaufuchs",
"canonicalGenotype": "aa CC dd ee gg pp spsp rere",
"sortOrder": 53,
"image": "blaufuchs-dd.jpg"
},
{
"name": "Marder",
"canonicalGenotype": "aa cchmcchm DD EE GG PP spsp rere",
"sortOrder": 54,
"image": "marder.JPG"
},
{
"name": "Siam",
"canonicalGenotype": "aa cchmch DD EE GG PP spsp rere",
"sortOrder": 55,
"image": "siam-marder-hell.JPG"
},
{
"name": "Zobel-Hell",
"canonicalGenotype": "aa cchmch DD EE gg PP spsp rere",
"sortOrder": 56,
"image": "zobel-hell.jpg"
},
{
"name": "CP-Agouti",
"canonicalGenotype": "AA cchmcchm DD EE GG PP spsp rere",
"sortOrder": 57,
"image": "agouti-cp.jpg"
},
{
"name": "CP-Agouti-Hell",
"canonicalGenotype": "AA cchmch DD EE GG PP spsp rere",
"sortOrder": 58
},
{
"name": "CP-Silberagouti",
"canonicalGenotype": "AA cchmcchm DD EE gg PP spsp rere",
"sortOrder": 59,
"image": "silberagouti-cp.JPG"
},
{
"name": "CP-Silberagouti-Hell",
"canonicalGenotype": "AA cchmch DD EE gg PP spsp rere",
"sortOrder": 60
},
{
"name": "CP-Algierfuchs",
"canonicalGenotype": "AA cchmcchm DD ee GG PP spsp rere",
"sortOrder": 61,
"image": "algierfuchs-cp.jpg"
},
{
"name": "CP-Algierfuchs-Hell",
"canonicalGenotype": "AA cchmch DD ee GG PP spsp rere",
"sortOrder": 62
},
{
"name": "CP-Polarfuchs",
"canonicalGenotype": "AA cchmcchm DD ee gg PP spsp rere",
"sortOrder": 63,
"image": "polarfuchs-cp.jpg"
},
{
"name": "CP-Polarfuchs-Hell",
"canonicalGenotype": "AA cchmch DD ee gg PP spsp rere",
"sortOrder": 64
},
{
"name": "CP-Fuchs",
"canonicalGenotype": "AA cchmcchm dd ee GG PP spsp rere",
"sortOrder": 65
},
{
"name": "CP-Fuchs-Hell",
"canonicalGenotype": "AA cchmch dd ee GG PP spsp rere",
"sortOrder": 66
},
{
"name": "CP-Blaufuchs",
"canonicalGenotype": "AA cchmcchm dd ee gg PP spsp rere",
"sortOrder": 67
},
{
"name": "CP-Orangeschimmel",
"canonicalGenotype": "AA cchmcchm DD efef GG PP spsp rere",
"sortOrder": 68
},
{
"name": "CP-Orangeschimmel-Hell",
"canonicalGenotype": "AA cchmch DD efef GG PP spsp rere",
"sortOrder": 69
}
]

View File

@@ -105,14 +105,14 @@
"image": "rotfuchs.JPG" "image": "rotfuchs.JPG"
}, },
{ {
"name": "Dilute Gold", "name": "dd Gold",
"english": "dd Argente Golden", "english": "dd Argente Golden",
"canonicalGenotype": "AA CC dd EE GG pp spsp rere", "canonicalGenotype": "AA CC dd EE GG pp spsp rere",
"sortOrder": 15, "sortOrder": 15,
"image": "gold-dd.jpg" "image": "gold-dd.jpg"
}, },
{ {
"name": "Dilute Platin", "name": "dd Platin",
"english": "dd Lilac", "english": "dd Lilac",
"canonicalGenotype": "aa CC dd EE GG pp spsp rere", "canonicalGenotype": "aa CC dd EE GG pp spsp rere",
"sortOrder": 16, "sortOrder": 16,
@@ -185,242 +185,222 @@
"image": "platin-hell.jpg" "image": "platin-hell.jpg"
}, },
{ {
"name": "Dilute Agouti", "name": "Agouti dd",
"canonicalGenotype": "AA CC dd EE GG PP spsp rere", "canonicalGenotype": "AA CC dd EE GG PP spsp rere",
"sortOrder": 28, "sortOrder": 28,
"image": "agouti-dd.jpg" "image": "agouti-dd.jpg"
}, },
{ {
"name": "Dilute Silberagouti", "name": "Silberagouti dd",
"canonicalGenotype": "AA CC dd EE gg PP spsp rere", "canonicalGenotype": "AA CC dd EE gg PP spsp rere",
"sortOrder": 29, "sortOrder": 29,
"image": "silberagouti-dd.jpg" "image": "silberagouti-dd.jpg"
}, },
{ {
"name": "Dilute Kohlfuchs", "name": "Kohlfuchs dd",
"canonicalGenotype": "aa CC dd ee GG PP spsp rere", "canonicalGenotype": "aa CC dd ee GG PP spsp rere",
"sortOrder": 30, "sortOrder": 30,
"image": "kohlfuchs-dd.jpg" "image": "kohlfuchs-dd.jpg"
}, },
{ {
"name": "Dilute Anthrazit", "name": "Anthrazit dd",
"canonicalGenotype": "aa CC dd EE gg PP spsp rere", "canonicalGenotype": "aa CC dd EE gg PP spsp rere",
"sortOrder": 31, "sortOrder": 31,
"image": "anthrazit-dd.jpg" "image": "anthrazit-dd.jpg"
}, },
{
"name": "Dilute Algierfuchs",
"canonicalGenotype": "AA CC dd ee GG PP spsp rere",
"sortOrder": 32
},
{
"name": "Dilute Goldfuchs",
"canonicalGenotype": "AA CC dd ee GG pp spsp rere",
"sortOrder": 33
},
{
"name": "Dilute Rotfuchs",
"canonicalGenotype": "aa CC dd ee GG pp spsp rere",
"sortOrder": 34
},
{
"name": "Dilute Polarfuchs",
"canonicalGenotype": "AA CC dd ee gg PP spsp rere",
"sortOrder": 35
},
{ {
"name": "Silberschimmel", "name": "Silberschimmel",
"canonicalGenotype": "AA CC DD e[f]e[f] gg PP spsp rere", "canonicalGenotype": "AA CC DD e[f]e[f] gg PP spsp rere",
"sortOrder": 36, "sortOrder": 32,
"image": "silberschimmel.jpg" "image": "silberschimmel.jpg"
}, },
{ {
"name": "Polarfuchsschimmel", "name": "Polarfuchsschimmel",
"canonicalGenotype": "AA CC DD e[f]e[f] gg PP spsp rere", "canonicalGenotype": "AA CC DD e[f]e[f] gg PP spsp rere",
"sortOrder": 37, "sortOrder": 33,
"image": "polarfuchsschimmel.jpg" "image": "polarfuchsschimmel.jpg"
}, },
{ {
"name": "Algierfuchsschimmel", "name": "Algierfuchsschimmel",
"canonicalGenotype": "AA CC DD e[f]e[f] GG PP spsp rere", "canonicalGenotype": "AA CC DD e[f]e[f] GG PP spsp rere",
"sortOrder": 38, "sortOrder": 34,
"image": "algierfuchsschimmel.jpg" "image": "algierfuchsschimmel.jpg"
}, },
{ {
"name": "Kohlfuchsschimmel", "name": "Kohlfuchsschimmel",
"canonicalGenotype": "aa CC DD e[f]e[f] GG PP spsp rere", "canonicalGenotype": "aa CC DD e[f]e[f] GG PP spsp rere",
"sortOrder": 39, "sortOrder": 35,
"image": "kohlfuchsschimmel.jpg" "image": "kohlfuchsschimmel.jpg"
}, },
{ {
"name": "Blaufuchsschimmel", "name": "Blaufuchsschimmel",
"canonicalGenotype": "aa CC DD e[f]e[f] gg PP spsp rere", "canonicalGenotype": "aa CC DD e[f]e[f] gg PP spsp rere",
"sortOrder": 40, "sortOrder": 36,
"image": "blaufuchsschimmel.jpg" "image": "blaufuchsschimmel.jpg"
}, },
{ {
"name": "Kohlfuchs, hell", "name": "Kohlfuchs, hell",
"canonicalGenotype": "aa CC DD ee GG PP spsp rere", "canonicalGenotype": "aa CC DD ee GG PP spsp rere",
"sortOrder": 41, "sortOrder": 37,
"image": "kohlfuchs-hell.jpg" "image": "kohlfuchs-hell.jpg"
}, },
{ {
"name": "Goldfuchs, hell", "name": "Goldfuchs, hell",
"canonicalGenotype": "AA CC DD ee GG pp spsp rere", "canonicalGenotype": "AA CC DD ee GG pp spsp rere",
"sortOrder": 42, "sortOrder": 38,
"image": "goldfuchs-hell.jpg" "image": "goldfuchs-hell.jpg"
}, },
{ {
"name": "Goldfuchsschimmel", "name": "Goldfuchsschimmel",
"canonicalGenotype": "AA CC DD e[f]e[f] GG pp spsp rere", "canonicalGenotype": "AA CC DD e[f]e[f] GG pp spsp rere",
"sortOrder": 43, "sortOrder": 39,
"image": "goldfuchsschimmel.jpg" "image": "goldfuchsschimmel.jpg"
}, },
{ {
"name": "Gold-Hell", "name": "Gold-Hell",
"canonicalGenotype": "AA CC DD EE GG pp spsp rere", "canonicalGenotype": "AA CC DD EE GG pp spsp rere",
"sortOrder": 44, "sortOrder": 40,
"image": "gold-hell.jpg" "image": "gold-hell.jpg"
}, },
{ {
"name": "Blaufuchs, hell", "name": "Blaufuchs, hell",
"canonicalGenotype": "aa CC DD ee gg PP spsp rere", "canonicalGenotype": "aa CC DD ee gg PP spsp rere",
"sortOrder": 45, "sortOrder": 41,
"image": "blaufuchs-hell.jpeg" "image": "blaufuchs-hell.jpeg"
}, },
{ {
"name": "Rotfuchsschimmel", "name": "Rotfuchsschimmel",
"canonicalGenotype": "aa CC DD e[f]e[f] GG pp spsp rere", "canonicalGenotype": "aa CC DD e[f]e[f] GG pp spsp rere",
"sortOrder": 46, "sortOrder": 42,
"image": "rotfuchsschimmel.jpg" "image": "rotfuchsschimmel.jpg"
}, },
{ {
"name": "Polarfuchs, hell", "name": "Polarfuchs, hell",
"canonicalGenotype": "AA CC DD ee gg PP spsp rere", "canonicalGenotype": "AA CC DD ee gg PP spsp rere",
"sortOrder": 47, "sortOrder": 43,
"image": "polarfuchs-hell.jpeg" "image": "polarfuchs-hell.jpeg"
}, },
{ {
"name": "Kohlfuchsschimmel, hell", "name": "Kohlfuchsschimmel, hell",
"canonicalGenotype": "aa CC DD e[f]e[f] GG PP spsp rere", "canonicalGenotype": "aa CC DD e[f]e[f] GG PP spsp rere",
"sortOrder": 48, "sortOrder": 44,
"image": "kohlfuchsschimmel-hell.jpg" "image": "kohlfuchsschimmel-hell.jpg"
}, },
{ {
"name": "Rotfuchs, hell", "name": "Rotfuchs, hell",
"canonicalGenotype": "aa CC DD ee GG pp spsp rere", "canonicalGenotype": "aa CC DD ee GG pp spsp rere",
"sortOrder": 49, "sortOrder": 45,
"image": "rotfuchs-hell.jpg" "image": "rotfuchs-hell.jpg"
}, },
{ {
"name": "Kohlfuchs-Hell", "name": "Kohlfuchs-Hell",
"canonicalGenotype": "aa CC DD ee GG PP spsp rere", "canonicalGenotype": "aa CC DD ee GG PP spsp rere",
"sortOrder": 50, "sortOrder": 46,
"image": "kohlfuchs-hell-2.jpg" "image": "kohlfuchs-hell-2.jpg"
}, },
{ {
"name": "Algierfuchs, hell", "name": "Algierfuchs, hell",
"canonicalGenotype": "AA CC DD ee GG PP spsp rere", "canonicalGenotype": "AA CC DD ee GG PP spsp rere",
"sortOrder": 51, "sortOrder": 47,
"image": "algierfuchs-hell.JPG" "image": "algierfuchs-hell.JPG"
}, },
{ {
"name": "Dilute Topas", "name": "Topas dd",
"canonicalGenotype": "AA CC dd EE GG pp spsp rere", "canonicalGenotype": "AA CC dd EE GG pp spsp rere",
"sortOrder": 52, "sortOrder": 48,
"image": "topas-dd.jpg" "image": "topas-dd.jpg"
}, },
{ {
"name": "Dilute Blaufuchs", "name": "Blaufuchs dd",
"canonicalGenotype": "aa CC dd ee gg pp spsp rere", "canonicalGenotype": "aa CC dd ee gg pp spsp rere",
"sortOrder": 53, "sortOrder": 49,
"image": "blaufuchs-dd.jpg" "image": "blaufuchs-dd.jpg"
}, },
{ {
"name": "Marder", "name": "Marder",
"canonicalGenotype": "aa c[chm]c[chm] DD EE GG PP spsp rere", "canonicalGenotype": "aa c[chm]c[chm] DD EE GG PP spsp rere",
"sortOrder": 54, "sortOrder": 50,
"image": "marder.JPG" "image": "marder.JPG"
}, },
{ {
"name": "Siam", "name": "Siam",
"canonicalGenotype": "aa c[chm]c[h] DD EE GG PP spsp rere", "canonicalGenotype": "aa c[chm]c[h] DD EE GG PP spsp rere",
"sortOrder": 55, "sortOrder": 51,
"image": "siam-marder-hell.JPG" "image": "siam-marder-hell.JPG"
}, },
{ {
"name": "Zobel-Hell", "name": "Zobel-Hell",
"canonicalGenotype": "aa c[chm]c[h] DD EE gg PP spsp rere", "canonicalGenotype": "aa c[chm]c[h] DD EE gg PP spsp rere",
"sortOrder": 56, "sortOrder": 52,
"image": "zobel-hell.jpg" "image": "zobel-hell.jpg"
}, },
{ {
"name": "CP-Agouti", "name": "CP-Agouti",
"canonicalGenotype": "AA c[chm]c[chm] DD EE GG PP spsp rere", "canonicalGenotype": "AA c[chm]c[chm] DD EE GG PP spsp rere",
"sortOrder": 57, "sortOrder": 53,
"image": "agouti-cp.jpg" "image": "agouti-cp.jpg"
}, },
{ {
"name": "CP-Agouti-Hell", "name": "CP-Agouti-Hell",
"canonicalGenotype": "AA c[chm]c[h] DD EE GG PP spsp rere", "canonicalGenotype": "AA c[chm]c[h] DD EE GG PP spsp rere",
"sortOrder": 58 "sortOrder": 54
}, },
{ {
"name": "CP-Silberagouti", "name": "CP-Silberagouti",
"canonicalGenotype": "AA c[chm]c[chm] DD EE gg PP spsp rere", "canonicalGenotype": "AA c[chm]c[chm] DD EE gg PP spsp rere",
"sortOrder": 59, "sortOrder": 55,
"image": "silberagouti-cp.JPG" "image": "silberagouti-cp.JPG"
}, },
{ {
"name": "CP-Silberagouti-Hell", "name": "CP-Silberagouti-Hell",
"canonicalGenotype": "AA c[chm]c[h] DD EE gg PP spsp rere", "canonicalGenotype": "AA c[chm]c[h] DD EE gg PP spsp rere",
"sortOrder": 60 "sortOrder": 56
}, },
{ {
"name": "CP-Algierfuchs", "name": "CP-Algierfuchs",
"canonicalGenotype": "AA c[chm]c[chm] DD ee GG PP spsp rere", "canonicalGenotype": "AA c[chm]c[chm] DD ee GG PP spsp rere",
"sortOrder": 61, "sortOrder": 57,
"image": "algierfuchs-cp.jpg" "image": "algierfuchs-cp.jpg"
}, },
{ {
"name": "CP-Algierfuchs-Hell", "name": "CP-Algierfuchs-Hell",
"canonicalGenotype": "AA c[chm]c[h] DD ee GG PP spsp rere", "canonicalGenotype": "AA c[chm]c[h] DD ee GG PP spsp rere",
"sortOrder": 62 "sortOrder": 58
}, },
{ {
"name": "CP-Polarfuchs", "name": "CP-Polarfuchs",
"canonicalGenotype": "AA c[chm]c[chm] DD ee gg PP spsp rere", "canonicalGenotype": "AA c[chm]c[chm] DD ee gg PP spsp rere",
"sortOrder": 63, "sortOrder": 59,
"image": "polarfuchs-cp.jpg" "image": "polarfuchs-cp.jpg"
}, },
{ {
"name": "CP-Polarfuchs-Hell", "name": "CP-Polarfuchs-Hell",
"canonicalGenotype": "AA c[chm]c[h] DD ee gg PP spsp rere", "canonicalGenotype": "AA c[chm]c[h] DD ee gg PP spsp rere",
"sortOrder": 64 "sortOrder": 60
}, },
{ {
"name": "CP-Fuchs", "name": "CP-Fuchs",
"canonicalGenotype": "AA c[chm]c[chm] dd ee GG PP spsp rere", "canonicalGenotype": "AA c[chm]c[chm] dd ee GG PP spsp rere",
"sortOrder": 65 "sortOrder": 61
}, },
{ {
"name": "CP-Fuchs-Hell", "name": "CP-Fuchs-Hell",
"canonicalGenotype": "AA c[chm]c[h] dd ee GG PP spsp rere", "canonicalGenotype": "AA c[chm]c[h] dd ee GG PP spsp rere",
"sortOrder": 66 "sortOrder": 62
}, },
{ {
"name": "CP-Blaufuchs", "name": "CP-Blaufuchs",
"canonicalGenotype": "AA c[chm]c[chm] dd ee gg PP spsp rere", "canonicalGenotype": "AA c[chm]c[chm] dd ee gg PP spsp rere",
"sortOrder": 67 "sortOrder": 63
}, },
{ {
"name": "CP-Orangeschimmel", "name": "CP-Orangeschimmel",
"canonicalGenotype": "AA c[chm]c[chm] DD e[f]e[f] GG PP spsp rere", "canonicalGenotype": "AA c[chm]c[chm] DD e[f]e[f] GG PP spsp rere",
"sortOrder": 68 "sortOrder": 64
}, },
{ {
"name": "CP-Orangeschimmel-Hell", "name": "CP-Orangeschimmel-Hell",
"canonicalGenotype": "AA c[chm]c[h] DD e[f]e[f] GG PP spsp rere", "canonicalGenotype": "AA c[chm]c[h] DD e[f]e[f] GG PP spsp rere",
"sortOrder": 69 "sortOrder": 65
} }
] ]