diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f233d8..68bea2f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,3 +38,10 @@ jobs: - name: Tests run: | pytest -q || true + + - name: Fast determinism tests (random subset) + env: + CSV_FILES_DIR: csv_files/testdata + RANDOM_MODES: "1" + run: | + pytest -q code/tests/test_random_determinism.py code/tests/test_random_build_api.py code/tests/test_seeded_builder_minimal.py code/tests/test_builder_rng_seeded_stream.py diff --git a/.gitignore b/.gitignore index 8d51b66..77584b6 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ logs/ deck_files/ csv_files/ !config/card_lists/*.json +!config/themes/*.json !config/deck.json !test_exclude_cards.txt !test_include_exclude_config.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 716ba98..c190493 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +- Random Modes (alpha): added env flags RANDOM_MODES, RANDOM_UI, RANDOM_MAX_ATTEMPTS, RANDOM_TIMEOUT_MS. +- Determinism: CSV_FILES_DIR override to point tests to csv_files/testdata; permalink now carries optional random fields (seed/theme/constraints). # Changelog All notable changes to this project will be documented in this file. @@ -13,14 +15,24 @@ This format follows Keep a Changelog principles and aims for Semantic Versioning ## [Unreleased] ### Added +- Theme governance: whitelist configuration `config/themes/theme_whitelist.yml` (normalization, always_include, protected prefixes/suffixes, enforced synergies, synergy_cap). +- Theme extraction: dynamic ingestion of CSV-only tags (e.g., Kindred families) and PMI-based inferred synergies (positive PMI, co-occurrence threshold) blended with curated pairs. +- Enforced synergy injection for counters/tokens/graveyard clusters (e.g., Proliferate, Counters Matter, Graveyard Matters) before capping. +- Test coverage: `test_theme_whitelist_and_synergy_cap.py` ensuring enforced synergies present and cap (5) respected. +- Dependency: added PyYAML (optional runtime dependency for governance file parsing). - CI: additional checks to improve stability and reproducibility. - Tests: broader coverage for validation and web flows. +- Randomizer groundwork: added a small seeded RNG utility (`code/random_util.py`) and determinism unit tests; threaded RNG through Phase 3 (creatures) and Phase 4 (spells) for deterministic sampling when seeded. +- Random Modes (alpha): thin wrapper entrypoint `code/deck_builder/random_entrypoint.py` to select a commander deterministically by seed, plus a tiny frozen dataset under `csv_files/testdata/` and tests `code/tests/test_random_determinism.py`. ### Changed +- Synergy lists for now capped at 5 entries (precedence: curated > enforced > inferred) to improve UI scannability. +- Curated synergy matrix expanded (tokens, spells, artifacts/enchantments, counters, lands, graveyard, politics, life, tribal umbrellas) with noisy links (e.g., Burn on -1/-1 Counters) suppressed via denylist + PMI filtering. - Tests: refactored to use pytest assertions and cleaned up fixtures/utilities to reduce noise and deprecations. - Tests: HTTP-dependent tests now skip gracefully when the local web server is unavailable. ### Fixed +- Removed one-off / low-signal themes (global frequency <=1) except those protected or explicitly always included via whitelist configuration. - Tests: reduced deprecation warnings and incidental failures; improved consistency and reliability across runs. ## [2.2.10] - 2025-09-11 diff --git a/DOCKER.md b/DOCKER.md index a819b9b..74dfad7 100644 --- a/DOCKER.md +++ b/DOCKER.md @@ -88,6 +88,7 @@ Docker Hub (PowerShell) example: docker run --rm ` -p 8080:8080 ` -e SHOW_LOGS=1 -e SHOW_DIAGNOSTICS=1 -e ENABLE_THEMES=1 -e THEME=system ` + -e RANDOM_MODES=1 -e RANDOM_UI=1 -e RANDOM_MAX_ATTEMPTS=5 -e RANDOM_TIMEOUT_MS=5000 ` -v "${PWD}/deck_files:/app/deck_files" ` -v "${PWD}/logs:/app/logs" ` -v "${PWD}/csv_files:/app/csv_files" ` @@ -127,6 +128,29 @@ GET http://localhost:8080/healthz -> { "status": "ok", "version": "dev", "upti Theme preference reset (client-side): use the header’s Reset Theme control to clear the saved browser preference; the server default (THEME) applies on next paint. +### Random Modes (alpha) and test dataset override + +Enable experimental Random Modes and UI controls in Web runs by setting: + +```yaml +services: + web: + environment: + - RANDOM_MODES=1 + - RANDOM_UI=1 + - RANDOM_MAX_ATTEMPTS=5 + - RANDOM_TIMEOUT_MS=5000 +``` + +For deterministic tests or development, you can point the app to a frozen dataset snapshot: + +```yaml +services: + web: + environment: + - CSV_FILES_DIR=/app/csv_files/testdata +``` + ## Volumes - `/app/deck_files` ↔ `./deck_files` - `/app/logs` ↔ `./logs` @@ -160,6 +184,13 @@ Theme preference reset (client-side): use the header’s Reset Theme control to - WEB_TAG_WORKERS= (process count; set based on CPU/memory) - WEB_VIRTUALIZE=1 (enable virtualization) - SHOW_DIAGNOSTICS=1 (enables diagnostics pages and overlay hotkey `v`) +- RANDOM_MODES=1 (enable random build endpoints) +- RANDOM_UI=1 (show Surprise/Theme/Reroll/Share controls) +- RANDOM_MAX_ATTEMPTS=5 (cap retry attempts) +- RANDOM_TIMEOUT_MS=5000 (per-build timeout in ms) + +Testing/determinism helper (dev): +- CSV_FILES_DIR=csv_files/testdata — override CSV base dir to a frozen set for tests ## Manual build/run ```powershell diff --git a/README.md b/README.md index 0b3840d..a0e12b9 100644 Binary files a/README.md and b/README.md differ diff --git a/RELEASE_NOTES_TEMPLATE.md b/RELEASE_NOTES_TEMPLATE.md index 9279a8f..ae83143 100644 --- a/RELEASE_NOTES_TEMPLATE.md +++ b/RELEASE_NOTES_TEMPLATE.md @@ -1,14 +1,16 @@ # MTG Python Deckbuilder ${VERSION} ### Added -- CI improvements to increase stability and reproducibility of builds/tests. -- Expanded test coverage for validation and web flows. +- Theme whitelist governance (`config/themes/theme_whitelist.yml`) with normalization, enforced synergies, and synergy cap (5). +- Expanded curated synergy matrix plus PMI-based inferred synergies (data-driven) blended with curated anchors. +- Test: `test_theme_whitelist_and_synergy_cap.py` validates enforced synergy presence and cap compliance. +- PyYAML dependency for governance parsing. ### Changed -- Tests refactored to use pytest assertions and streamlined fixtures/utilities to reduce noise and deprecations. -- HTTP-dependent tests skip gracefully when the local web server is unavailable. +- Theme normalization (ETB -> Enter the Battlefield, Self Mill -> Mill, Pillow Fort -> Pillowfort, Reanimator -> Reanimate) applied prior to synergy derivation. +- Synergy output capped to 5 entries per theme (curated > enforced > inferred ordering). ### Fixed -- Reduced deprecation warnings and incidental test failures; improved consistency across runs. +- Removed ultra-rare themes (frequency <=1) except those protected/always included via whitelist. --- \ No newline at end of file diff --git a/code/deck_builder/builder.py b/code/deck_builder/builder.py index e4859c7..be814ff 100644 --- a/code/deck_builder/builder.py +++ b/code/deck_builder/builder.py @@ -74,6 +74,45 @@ class DeckBuilder( ColorBalanceMixin, ReportingMixin ): + # Seedable RNG support (minimal surface area): + # - seed: optional seed value stored for diagnostics + # - _rng: internal Random instance; access via self.rng + seed: Optional[int] = field(default=None, repr=False) + _rng: Any = field(default=None, repr=False) + + @property + def rng(self): + """Lazy, per-builder RNG instance. If a seed was set, use it deterministically.""" + if self._rng is None: + try: + # If a seed was assigned pre-init, use it + if self.seed is not None: + # Import here to avoid any heavy import cycles at module import time + from random_util import set_seed as _set_seed # type: ignore + self._rng = _set_seed(int(self.seed)) + else: + self._rng = random.Random() + except Exception: + # Fallback to module random + self._rng = random + return self._rng + + def set_seed(self, seed: int | str) -> None: + """Set deterministic seed for this builder and reset its RNG instance.""" + try: + from random_util import derive_seed_from_string as _derive, set_seed as _set_seed # type: ignore + s = _derive(seed) + self.seed = int(s) + self._rng = _set_seed(s) + except Exception: + try: + self.seed = int(seed) if not isinstance(seed, int) else seed + r = random.Random() + r.seed(self.seed) + self._rng = r + except Exception: + # Leave RNG as-is on unexpected error + pass def build_deck_full(self): """Orchestrate the full deck build process, chaining all major phases.""" start_ts = datetime.datetime.now() @@ -712,10 +751,8 @@ class DeckBuilder( # RNG Initialization # --------------------------- def _get_rng(self): # lazy init - if self._rng is None: - import random as _r - self._rng = _r - return self._rng + # Delegate to seedable rng property for determinism support + return self.rng # --------------------------- # Data Loading @@ -1003,8 +1040,10 @@ class DeckBuilder( self.determine_color_identity() dfs = [] required = getattr(bc, 'CSV_REQUIRED_COLUMNS', []) + from path_util import csv_dir as _csv_dir + base = _csv_dir() for stem in self.files_to_load: - path = f'csv_files/{stem}_cards.csv' + path = f"{base}/{stem}_cards.csv" try: df = pd.read_csv(path) if required: diff --git a/code/deck_builder/builder_constants.py b/code/deck_builder/builder_constants.py index 78e5749..fd4f06f 100644 --- a/code/deck_builder/builder_constants.py +++ b/code/deck_builder/builder_constants.py @@ -1,5 +1,6 @@ from typing import Dict, List, Final, Tuple, Union, Callable, Any as _Any from settings import CARD_DATA_COLUMNS as CSV_REQUIRED_COLUMNS # unified +from path_util import csv_dir __all__ = [ 'CSV_REQUIRED_COLUMNS' @@ -13,7 +14,7 @@ MAX_FUZZY_CHOICES: Final[int] = 5 # Maximum number of fuzzy match choices # Commander-related constants DUPLICATE_CARD_FORMAT: Final[str] = '{card_name} x {count}' -COMMANDER_CSV_PATH: Final[str] = 'csv_files/commander_cards.csv' +COMMANDER_CSV_PATH: Final[str] = f"{csv_dir()}/commander_cards.csv" DECK_DIRECTORY = '../deck_files' COMMANDER_CONVERTERS: Final[Dict[str, str]] = {'themeTags': ast.literal_eval, 'creatureTypes': ast.literal_eval} # CSV loading converters COMMANDER_POWER_DEFAULT: Final[int] = 0 diff --git a/code/deck_builder/phases/phase3_creatures.py b/code/deck_builder/phases/phase3_creatures.py index a17ff8e..5576cc8 100644 --- a/code/deck_builder/phases/phase3_creatures.py +++ b/code/deck_builder/phases/phase3_creatures.py @@ -121,7 +121,7 @@ class CreatureAdditionMixin: if owned_lower and str(nm).lower() in owned_lower: w *= owned_mult weighted_pool.append((nm, w)) - chosen_all = bu.weighted_sample_without_replacement(weighted_pool, target_cap) + chosen_all = bu.weighted_sample_without_replacement(weighted_pool, target_cap, rng=getattr(self, 'rng', None)) for nm in chosen_all: if commander_name and nm == commander_name: continue @@ -201,7 +201,7 @@ class CreatureAdditionMixin: if owned_lower and str(nm).lower() in owned_lower: base_w *= owned_mult weighted_pool.append((nm, base_w)) - chosen = bu.weighted_sample_without_replacement(weighted_pool, target) + chosen = bu.weighted_sample_without_replacement(weighted_pool, target, rng=getattr(self, 'rng', None)) for nm in chosen: if commander_name and nm == commander_name: continue @@ -507,7 +507,7 @@ class CreatureAdditionMixin: return synergy_bonus = getattr(bc, 'THEME_PRIORITY_BONUS', 1.2) weighted_pool = [(nm, (synergy_bonus if mm >= 2 else 1.0)) for nm, mm in zip(pool['name'], pool['_multiMatch'])] - chosen = bu.weighted_sample_without_replacement(weighted_pool, target) + chosen = bu.weighted_sample_without_replacement(weighted_pool, target, rng=getattr(self, 'rng', None)) added = 0 for nm in chosen: row = pool[pool['name']==nm].iloc[0] @@ -621,7 +621,7 @@ class CreatureAdditionMixin: if owned_lower and str(nm).lower() in owned_lower: w *= owned_mult weighted_pool.append((nm, w)) - chosen_all = bu.weighted_sample_without_replacement(weighted_pool, target_cap) + chosen_all = bu.weighted_sample_without_replacement(weighted_pool, target_cap, rng=getattr(self, 'rng', None)) added = 0 for nm in chosen_all: row = subset_all[subset_all['name'] == nm].iloc[0] diff --git a/code/deck_builder/phases/phase4_spells.py b/code/deck_builder/phases/phase4_spells.py index c972825..af8f0e0 100644 --- a/code/deck_builder/phases/phase4_spells.py +++ b/code/deck_builder/phases/phase4_spells.py @@ -139,7 +139,14 @@ class SpellAdditionMixin: for name, entry in self.card_library.items(): if any(isinstance(t, str) and 'ramp' in t.lower() for t in entry.get('Tags', [])): existing_ramp += 1 - to_add, _bonus = bu.compute_adjusted_target('Ramp', target_total, existing_ramp, self.output_func, plural_word='ramp spells') + to_add, _bonus = bu.compute_adjusted_target( + 'Ramp', + target_total, + existing_ramp, + self.output_func, + plural_word='ramp spells', + rng=getattr(self, 'rng', None) + ) if existing_ramp >= target_total and to_add == 0: return if existing_ramp < target_total: @@ -290,7 +297,14 @@ class SpellAdditionMixin: lt = [str(t).lower() for t in entry.get('Tags', [])] if any(('removal' in t or 'spot removal' in t) for t in lt) and not any(('board wipe' in t or 'mass removal' in t) for t in lt): existing += 1 - to_add, _bonus = bu.compute_adjusted_target('Removal', target, existing, self.output_func, plural_word='removal spells') + to_add, _bonus = bu.compute_adjusted_target( + 'Removal', + target, + existing, + self.output_func, + plural_word='removal spells', + rng=getattr(self, 'rng', None) + ) if existing >= target and to_add == 0: return target = to_add if existing < target else to_add @@ -360,7 +374,14 @@ class SpellAdditionMixin: tags = [str(t).lower() for t in entry.get('Tags', [])] if any(('board wipe' in t or 'mass removal' in t) for t in tags): existing += 1 - to_add, _bonus = bu.compute_adjusted_target('Board wipe', target, existing, self.output_func, plural_word='wipes') + to_add, _bonus = bu.compute_adjusted_target( + 'Board wipe', + target, + existing, + self.output_func, + plural_word='wipes', + rng=getattr(self, 'rng', None) + ) if existing >= target and to_add == 0: return target = to_add if existing < target else to_add @@ -407,7 +428,14 @@ class SpellAdditionMixin: tags = [str(t).lower() for t in entry.get('Tags', [])] if any(('draw' in t) or ('card advantage' in t) for t in tags): existing += 1 - to_add_total, _bonus = bu.compute_adjusted_target('Card advantage', total_target, existing, self.output_func, plural_word='draw spells') + to_add_total, _bonus = bu.compute_adjusted_target( + 'Card advantage', + total_target, + existing, + self.output_func, + plural_word='draw spells', + rng=getattr(self, 'rng', None) + ) if existing >= total_target and to_add_total == 0: return total_target = to_add_total if existing < total_target else to_add_total @@ -540,7 +568,14 @@ class SpellAdditionMixin: tags = [str(t).lower() for t in entry.get('Tags', [])] if any('protection' in t for t in tags): existing += 1 - to_add, _bonus = bu.compute_adjusted_target('Protection', target, existing, self.output_func, plural_word='protection spells') + to_add, _bonus = bu.compute_adjusted_target( + 'Protection', + target, + existing, + self.output_func, + plural_word='protection spells', + rng=getattr(self, 'rng', None) + ) if existing >= target and to_add == 0: return target = to_add if existing < target else to_add @@ -705,7 +740,7 @@ class SpellAdditionMixin: if owned_lower and str(nm).lower() in owned_lower: base_w *= owned_mult weighted_pool.append((nm, base_w)) - chosen = bu.weighted_sample_without_replacement(weighted_pool, target) + chosen = bu.weighted_sample_without_replacement(weighted_pool, target, rng=getattr(self, 'rng', None)) for nm in chosen: row = pool[pool['name'] == nm].iloc[0] self.add_card( diff --git a/code/deck_builder/random_entrypoint.py b/code/deck_builder/random_entrypoint.py new file mode 100644 index 0000000..8df6641 --- /dev/null +++ b/code/deck_builder/random_entrypoint.py @@ -0,0 +1,181 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any, Dict, List, Optional + +import time +import pandas as pd + +from deck_builder import builder_constants as bc +from random_util import get_random, generate_seed + + +@dataclass +class RandomBuildResult: + seed: int + commander: str + theme: Optional[str] + constraints: Optional[Dict[str, Any]] + + def to_dict(self) -> Dict[str, Any]: + return { + "seed": int(self.seed), + "commander": self.commander, + "theme": self.theme, + "constraints": self.constraints or {}, + } + + +def _load_commanders_df() -> pd.DataFrame: + """Load commander CSV using the same path/converters as the builder. + + Uses bc.COMMANDER_CSV_PATH and bc.COMMANDER_CONVERTERS for consistency. + """ + return pd.read_csv(bc.COMMANDER_CSV_PATH, converters=getattr(bc, "COMMANDER_CONVERTERS", None)) + + +def _filter_by_theme(df: pd.DataFrame, theme: Optional[str]) -> pd.DataFrame: + if not theme: + return df + t = str(theme).strip().lower() + try: + mask = df.get("themeTags").apply( + lambda tags: any(str(x).strip().lower() == t for x in (tags or [])) + ) + sub = df[mask] + if len(sub) > 0: + return sub + except Exception: + pass + return df + + +def build_random_deck( + theme: Optional[str] = None, + constraints: Optional[Dict[str, Any]] = None, + seed: Optional[int | str] = None, + attempts: int = 5, + timeout_s: float = 5.0, +) -> RandomBuildResult: + """Thin wrapper for random selection of a commander, deterministic when seeded. + + Contract (initial/minimal): + - Inputs: optional theme filter, optional constraints dict, seed for determinism, + attempts (max reroll attempts), timeout_s (wall clock cap). + - Output: RandomBuildResult with chosen commander and the resolved seed. + + Notes: + - This does NOT run the full deck builder yet; it focuses on picking a commander + deterministically for tests and plumbing. Full pipeline can be layered later. + - Determinism: when `seed` is provided, selection is stable across runs. + - When `seed` is None, a new high-entropy seed is generated and returned. + """ + # Resolve seed and RNG + resolved_seed = int(seed) if isinstance(seed, int) or (isinstance(seed, str) and str(seed).isdigit()) else None + if resolved_seed is None: + resolved_seed = generate_seed() + rng = get_random(resolved_seed) + + # Bounds sanitation + attempts = max(1, int(attempts or 1)) + try: + timeout_s = float(timeout_s) + except Exception: + timeout_s = 5.0 + timeout_s = max(0.1, timeout_s) + + # Load commander pool and apply theme filter (if any) + df_all = _load_commanders_df() + df = _filter_by_theme(df_all, theme) + # Stable ordering then seeded selection for deterministic behavior + names: List[str] = sorted(df["name"].astype(str).tolist()) if not df.empty else [] + if not names: + # Fall back to entire pool by name if theme produced nothing + names = sorted(df_all["name"].astype(str).tolist()) + if not names: + # Absolute fallback for pathological cases + names = ["Unknown Commander"] + + # Simple attempt/timeout loop (placeholder for future constraints checks) + start = time.time() + pick = None + for _ in range(attempts): + if (time.time() - start) > timeout_s: + break + idx = rng.randrange(0, len(names)) + candidate = names[idx] + # For now, accept the first candidate; constraint hooks can be added here. + pick = candidate + break + if pick is None: + # Timeout/attempts exhausted; choose deterministically based on seed modulo + pick = names[resolved_seed % len(names)] + + return RandomBuildResult(seed=int(resolved_seed), commander=pick, theme=theme, constraints=constraints or {}) + + +__all__ = [ + "RandomBuildResult", + "build_random_deck", +] + + +# Full-build wrapper for deterministic end-to-end builds +@dataclass +class RandomFullBuildResult(RandomBuildResult): + decklist: List[Dict[str, Any]] | None = None + diagnostics: Dict[str, Any] | None = None + + +def build_random_full_deck( + theme: Optional[str] = None, + constraints: Optional[Dict[str, Any]] = None, + seed: Optional[int | str] = None, + attempts: int = 5, + timeout_s: float = 5.0, +) -> RandomFullBuildResult: + """Select a commander deterministically, then run a full deck build via DeckBuilder. + + Returns a compact result including the seed, commander, and a summarized decklist. + """ + base = build_random_deck(theme=theme, constraints=constraints, seed=seed, attempts=attempts, timeout_s=timeout_s) + + # Run the full headless build with the chosen commander and the same seed + try: + from headless_runner import run as _run # type: ignore + except Exception as e: + return RandomFullBuildResult( + seed=base.seed, + commander=base.commander, + theme=base.theme, + constraints=base.constraints or {}, + decklist=None, + diagnostics={"error": f"headless runner unavailable: {e}"}, + ) + + builder = _run(command_name=base.commander, seed=base.seed) + + # Summarize the decklist from builder.card_library + deck_items: List[Dict[str, Any]] = [] + try: + lib = getattr(builder, 'card_library', {}) or {} + for name, info in lib.items(): + try: + cnt = int(info.get('Count', 1)) if isinstance(info, dict) else 1 + except Exception: + cnt = 1 + deck_items.append({"name": str(name), "count": cnt}) + deck_items.sort(key=lambda x: (str(x.get("name", "").lower()), int(x.get("count", 0)))) + except Exception: + deck_items = [] + + diags: Dict[str, Any] = {"attempts": 1, "timeout_s": timeout_s} + return RandomFullBuildResult( + seed=base.seed, + commander=base.commander, + theme=base.theme, + constraints=base.constraints or {}, + decklist=deck_items, + diagnostics=diags, + ) + diff --git a/code/headless_runner.py b/code/headless_runner.py index 9d97205..784ff2f 100644 --- a/code/headless_runner.py +++ b/code/headless_runner.py @@ -65,6 +65,7 @@ def run( enforcement_mode: str = "warn", allow_illegal: bool = False, fuzzy_matching: bool = True, + seed: Optional[int | str] = None, ) -> DeckBuilder: """Run a scripted non-interactive deck build and return the DeckBuilder instance.""" scripted_inputs: List[str] = [] @@ -109,6 +110,12 @@ def run( return "" builder = DeckBuilder(input_func=scripted_input) + # Optional deterministic seed for Random Modes (does not affect core when unset) + try: + if seed is not None: + builder.set_seed(seed) # type: ignore[attr-defined] + except Exception: + pass # Mark this run as headless so builder can adjust exports and logging try: builder.headless = True # type: ignore[attr-defined] diff --git a/code/path_util.py b/code/path_util.py new file mode 100644 index 0000000..184910f --- /dev/null +++ b/code/path_util.py @@ -0,0 +1,16 @@ +from __future__ import annotations + +import os + + +def csv_dir() -> str: + """Return the base directory for CSV files. + + Defaults to 'csv_files'. Override with CSV_FILES_DIR for tests or advanced setups. + """ + try: + base = os.getenv("CSV_FILES_DIR") + base = base.strip() if isinstance(base, str) else None + return base or "csv_files" + except Exception: + return "csv_files" diff --git a/code/random_util.py b/code/random_util.py new file mode 100644 index 0000000..0cf2678 --- /dev/null +++ b/code/random_util.py @@ -0,0 +1,69 @@ +from __future__ import annotations + +import hashlib +import secrets +import random +from typing import Union + +""" +Seeded RNG utilities for deterministic behavior. + +Contract (minimal): +- derive_seed_from_string(s): produce a stable, platform-independent int seed from a string or int. +- set_seed(seed): return a new random.Random instance seeded deterministically. +- generate_seed(): return a high-entropy, non-negative int suitable for seeding. +- get_random(seed=None): convenience to obtain a new Random instance (seeded when provided). + +No globals/state: each call returns an independent Random instance. +""" + + +SeedLike = Union[int, str] + + +def _to_bytes(s: str) -> bytes: + try: + return s.encode("utf-8", errors="strict") + except Exception: + # Best-effort fallback + return s.encode("utf-8", errors="ignore") + + +def derive_seed_from_string(seed: SeedLike) -> int: + """Derive a stable positive integer seed from a string or int. + + - int inputs are normalized to a non-negative 63-bit value. + - str inputs use SHA-256 to generate a deterministic 63-bit value. + """ + if isinstance(seed, int): + # Normalize to 63-bit positive + return abs(int(seed)) & ((1 << 63) - 1) + # String path: deterministic, platform-independent + data = _to_bytes(str(seed)) + h = hashlib.sha256(data).digest() + # Use first 8 bytes (64 bits) and mask to 63 bits to avoid sign issues + n = int.from_bytes(h[:8], byteorder="big", signed=False) + return n & ((1 << 63) - 1) + + +def set_seed(seed: SeedLike) -> random.Random: + """Return a new Random instance seeded deterministically from the given seed.""" + r = random.Random() + r.seed(derive_seed_from_string(seed)) + return r + + +def get_random(seed: SeedLike | None = None) -> random.Random: + """Return a new Random instance; seed when provided. + + This avoids mutating the module-global PRNG and keeps streams isolated. + """ + if seed is None: + return random.Random() + return set_seed(seed) + + +def generate_seed() -> int: + """Return a high-entropy positive 63-bit integer suitable for seeding.""" + # secrets is preferred for entropy here; mask to 63 bits for consistency + return secrets.randbits(63) diff --git a/code/scripts/extract_themes.py b/code/scripts/extract_themes.py new file mode 100644 index 0000000..24fb1ef --- /dev/null +++ b/code/scripts/extract_themes.py @@ -0,0 +1,526 @@ +import os +import json +import re +import sys +from collections import Counter +from typing import Dict, List, Set, Any + +import pandas as pd +import itertools +import math +try: + import yaml # type: ignore +except Exception: # pragma: no cover - optional dependency; script warns if missing + yaml = None + +# Ensure local 'code' package shadows stdlib 'code' module +ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +if ROOT not in sys.path: + sys.path.insert(0, ROOT) + +from code.settings import CSV_DIRECTORY # type: ignore +from code.tagging import tag_constants # type: ignore + +BASE_COLORS = { + 'white': 'W', + 'blue': 'U', + 'black': 'B', + 'red': 'R', + 'green': 'G', +} + +COLOR_LETTERS = set(BASE_COLORS.values()) + + +def collect_theme_tags_from_constants() -> Set[str]: + tags: Set[str] = set() + # TYPE_TAG_MAPPING values + for tags_list in tag_constants.TYPE_TAG_MAPPING.values(): + tags.update(tags_list) + # DRAW_RELATED_TAGS + tags.update(tag_constants.DRAW_RELATED_TAGS) + # Some known groupings categories as tags + for tgroup in tag_constants.TAG_GROUPS.values(): + tags.update(tgroup) + # Known specific tags referenced in constants + for name in dir(tag_constants): + if name.endswith('_RELATED_TAGS') or name.endswith('_SPECIFIC_CARDS'): + val = getattr(tag_constants, name) + if isinstance(val, list): + # Only include tag-like strings (skip obvious card names) + for v in val: + if isinstance(v, str) and re.search(r"[A-Za-z]", v) and ' ' in v: + # Heuristic inclusion + pass + return tags + + +def collect_theme_tags_from_tagger_source() -> Set[str]: + tags: Set[str] = set() + tagger_path = os.path.join(os.path.dirname(__file__), '..', 'tagging', 'tagger.py') + tagger_path = os.path.abspath(tagger_path) + with open(tagger_path, 'r', encoding='utf-8') as f: + src = f.read() + # Find tag_utils.apply_tag_vectorized(df, mask, ['Tag1', 'Tag2', ...]) occurrences + vector_calls = re.findall(r"apply_tag_vectorized\([^\)]*\[([^\]]+)\]", src) + for group in vector_calls: + # Split strings within the list literal + parts = re.findall(r"'([^']+)'|\"([^\"]+)\"", group) + for a, b in parts: + s = a or b + if s: + tags.add(s) + # Also capture tags passed via apply_rules([... {'tags': [ ... ]} ...]) + for group in re.findall(r"'tags'\s*:\s*\[([^\]]+)\]", src): + parts = re.findall(r"'([^']+)'|\"([^\"]+)\"", group) + for a, b in parts: + s = a or b + if s: + tags.add(s) + # Also capture tags passed via apply_rules([... {'tags': [ ... ]} ...]) + for group in re.findall(r"['\"]tags['\"]\s*:\s*\[([^\]]+)\]", src): + parts = re.findall(r"'([^']+)'|\"([^\"]+)\"", group) + for a, b in parts: + s = a or b + if s: + tags.add(s) + return tags + + +def tally_tag_frequencies_by_base_color() -> Dict[str, Dict[str, int]]: + result: Dict[str, Dict[str, int]] = {c: Counter() for c in BASE_COLORS.keys()} + # Iterate over per-color CSVs; if not present, skip + for color in BASE_COLORS.keys(): + path = os.path.join(CSV_DIRECTORY, f"{color}_cards.csv") + if not os.path.exists(path): + continue + try: + df = pd.read_csv(path, converters={'themeTags': pd.eval, 'colorIdentity': pd.eval}) + except Exception: + df = pd.read_csv(path) + if 'themeTags' in df.columns: + try: + df['themeTags'] = df['themeTags'].apply(pd.eval) + except Exception: + df['themeTags'] = df['themeTags'].apply(lambda x: []) + if 'colorIdentity' in df.columns: + try: + df['colorIdentity'] = df['colorIdentity'].apply(pd.eval) + except Exception: + pass + if 'themeTags' not in df.columns: + continue + # Derive base colors from colorIdentity if available, else assume single color file + def rows_base_colors(row): + ids = row.get('colorIdentity') if isinstance(row, dict) else row + if isinstance(ids, list): + letters = set(ids) + else: + letters = set() + derived = set() + for name, letter in BASE_COLORS.items(): + if letter in letters: + derived.add(name) + if not derived: + derived.add(color) + return derived + # Iterate rows + for _, row in df.iterrows(): + tags = row['themeTags'] if isinstance(row['themeTags'], list) else [] + # Compute base colors contribution + ci = row['colorIdentity'] if 'colorIdentity' in row else None + letters = set(ci) if isinstance(ci, list) else set() + bases = {name for name, letter in BASE_COLORS.items() if letter in letters} + if not bases: + bases = {color} + for bc in bases: + for t in tags: + result[bc][t] += 1 + # Convert Counters to plain dicts + return {k: dict(v) for k, v in result.items()} + + +def gather_theme_tag_rows() -> List[List[str]]: + """Collect per-card themeTags lists across all base color CSVs. + + Returns a list of themeTags arrays, one per card row where themeTags is present. + """ + rows: List[List[str]] = [] + for color in BASE_COLORS.keys(): + path = os.path.join(CSV_DIRECTORY, f"{color}_cards.csv") + if not os.path.exists(path): + continue + try: + df = pd.read_csv(path, converters={'themeTags': pd.eval}) + except Exception: + df = pd.read_csv(path) + if 'themeTags' in df.columns: + try: + df['themeTags'] = df['themeTags'].apply(pd.eval) + except Exception: + df['themeTags'] = df['themeTags'].apply(lambda x: []) + if 'themeTags' not in df.columns: + continue + for _, row in df.iterrows(): + tags = row['themeTags'] if isinstance(row['themeTags'], list) else [] + if tags: + rows.append(tags) + return rows + + +def compute_cooccurrence(rows: List[List[str]]): + """Compute co-occurrence counts between tags. + + Returns: + - co: dict[tag] -> Counter(other_tag -> co_count) + - counts: Counter[tag] overall occurrence counts + - total_rows: int number of rows (cards considered) + """ + co: Dict[str, Counter] = {} + counts: Counter = Counter() + for tags in rows: + uniq = sorted(set(t for t in tags if isinstance(t, str) and t)) + for t in uniq: + counts[t] += 1 + for a, b in itertools.combinations(uniq, 2): + co.setdefault(a, Counter())[b] += 1 + co.setdefault(b, Counter())[a] += 1 + return co, counts, len(rows) + + +def cooccurrence_scores_for(anchor: str, co: Dict[str, Counter], counts: Counter, total_rows: int) -> List[tuple[str, float, int]]: + """Return list of (other_tag, score, co_count) sorted by score desc. + + Score uses PMI: log2( (co_count * total_rows) / (count_a * count_b) ). + """ + results: List[tuple[str, float, int]] = [] + if anchor not in co: + return results + count_a = max(1, counts.get(anchor, 1)) + for other, co_count in co[anchor].items(): + count_b = max(1, counts.get(other, 1)) + # Avoid div by zero; require minimal counts + if co_count <= 0: + continue + # PMI + pmi = math.log2((co_count * max(1, total_rows)) / (count_a * count_b)) + results.append((other, pmi, co_count)) + results.sort(key=lambda x: (-x[1], -x[2], x[0])) + return results + + +def derive_synergies_for_tags(tags: Set[str]) -> Dict[str, List[str]]: + # Curated baseline mappings for important themes (extended) + pairs = [ + # Tokens / go-wide + ("Tokens Matter", ["Token Creation", "Creature Tokens", "Populate"]), + ("Creature Tokens", ["Tokens Matter", "Token Creation", "Populate"]), + ("Token Creation", ["Tokens Matter", "Creature Tokens", "Populate"]), + # Spells + ("Spellslinger", ["Spells Matter", "Prowess", "Noncreature Spells"]), + ("Noncreature Spells", ["Spellslinger", "Prowess"]), + ("Prowess", ["Spellslinger", "Noncreature Spells"]), + # Artifacts / Enchantments + ("Artifacts Matter", ["Treasure Token", "Equipment", "Vehicles", "Improvise"]), + ("Enchantments Matter", ["Auras", "Constellation", "Card Draw"]), + ("Auras", ["Constellation", "Voltron", "Enchantments Matter"]), + ("Equipment", ["Voltron", "Double Strike", "Warriors Matter"]), + ("Treasure Token", ["Sacrifice Matters", "Artifacts Matter", "Ramp"]), + ("Vehicles", ["Artifacts Matter", "Equipment"]), + # Counters / Proliferate + ("Counters Matter", ["Proliferate", "+1/+1 Counters", "Adapt", "Outlast"]), + ("+1/+1 Counters", ["Proliferate", "Counters Matter", "Adapt", "Evolve"]), + ("-1/-1 Counters", ["Proliferate", "Counters Matter", "Wither", "Persist", "Infect"]), + ("Proliferate", ["Counters Matter", "+1/+1 Counters", "Planeswalkers"]), + # Lands / ramp + ("Lands Matter", ["Landfall", "Domain", "Land Tutors"]), + ("Landfall", ["Lands Matter", "Ramp", "Token Creation"]), + ("Domain", ["Lands Matter", "Ramp"]), + # Combat / Voltron + ("Voltron", ["Equipment", "Auras", "Double Strike"]), + # Card flow + ("Card Draw", ["Loot", "Wheels", "Replacement Draw", "Unconditional Draw", "Conditional Draw"]), + ("Loot", ["Card Draw", "Discard Matters", "Reanimate"]), + ("Wheels", ["Discard Matters", "Card Draw", "Spellslinger"]), + ("Discard Matters", ["Loot", "Wheels", "Hellbent", "Reanimate"]), + # Sacrifice / death + ("Aristocrats", ["Sacrifice", "Death Triggers", "Token Creation"]), + ("Sacrifice", ["Aristocrats", "Death Triggers", "Treasure Token"]), + ("Death Triggers", ["Aristocrats", "Sacrifice"]), + # Graveyard cluster + ("Graveyard Matters", ["Reanimate", "Mill", "Unearth", "Surveil"]), + ("Reanimate", ["Mill", "Graveyard Matters", "Enter the Battlefield"]), + ("Unearth", ["Reanimate", "Graveyard Matters"]), + ("Surveil", ["Mill", "Reanimate", "Graveyard Matters"]), + # Planeswalkers / blink + ("Superfriends", ["Planeswalkers", "Proliferate", "Token Creation"]), + ("Planeswalkers", ["Proliferate", "Superfriends"]), + ("Enter the Battlefield", ["Blink", "Reanimate", "Token Creation"]), + ("Blink", ["Enter the Battlefield", "Flicker", "Token Creation"]), + # Politics / table dynamics + ("Stax", ["Taxing Effects", "Hatebears"]), + ("Monarch", ["Politics", "Group Hug", "Card Draw"]), + ("Group Hug", ["Politics", "Card Draw"]), + # Life + ("Life Matters", ["Lifegain", "Lifedrain", "Extort"]), + ("Lifegain", ["Life Matters", "Lifedrain", "Extort"]), + ("Lifedrain", ["Lifegain", "Life Matters"]), + # Treasure / economy cross-link + ("Ramp", ["Treasure Token", "Land Tutors"]), + ] + m: Dict[str, List[str]] = {} + for base, syn in pairs: + if base in tags: + m[base] = syn + return m + + +def load_whitelist_config() -> Dict[str, Any]: + """Load whitelist governance YAML if present. + + Returns empty dict if file missing or YAML unavailable. + """ + path = os.path.join('config', 'themes', 'theme_whitelist.yml') + if not os.path.exists(path) or yaml is None: + return {} + try: + with open(path, 'r', encoding='utf-8') as f: + data = yaml.safe_load(f) or {} + if not isinstance(data, dict): + return {} + return data + except Exception: + return {} + + +def apply_normalization(tags: Set[str], normalization: Dict[str, str]) -> Set[str]: + if not normalization: + return tags + normalized = set() + for t in tags: + normalized.add(normalization.get(t, t)) + return normalized + + +def should_keep_theme(theme: str, total_count: int, cfg: Dict[str, Any], protected_prefixes: List[str], protected_suffixes: List[str], min_overrides: Dict[str, int]) -> bool: + # Always include explicit always_include list + if theme in cfg.get('always_include', []): + return True + # Protected prefixes/suffixes + for pref in protected_prefixes: + if theme.startswith(pref + ' '): # prefix followed by space + return True + for suff in protected_suffixes: + if theme.endswith(' ' + suff) or theme.endswith(suff): + return True + # Min frequency override + if theme in min_overrides: + return total_count >= min_overrides[theme] + # Default global rule (>1 occurrences) + return total_count > 1 + + +def main() -> None: + whitelist_cfg = load_whitelist_config() + normalization_map: Dict[str, str] = whitelist_cfg.get('normalization', {}) if isinstance(whitelist_cfg.get('normalization', {}), dict) else {} + exclusions: Set[str] = set(whitelist_cfg.get('exclusions', []) or []) + protected_prefixes: List[str] = list(whitelist_cfg.get('protected_prefixes', []) or []) + protected_suffixes: List[str] = list(whitelist_cfg.get('protected_suffixes', []) or []) + min_overrides: Dict[str, int] = whitelist_cfg.get('min_frequency_overrides', {}) or {} + synergy_cap: int = int(whitelist_cfg.get('synergy_cap', 0) or 0) + enforced_synergies_cfg: Dict[str, List[str]] = whitelist_cfg.get('enforced_synergies', {}) or {} + + theme_tags = set() + theme_tags |= collect_theme_tags_from_constants() + theme_tags |= collect_theme_tags_from_tagger_source() + + # Also include any tags that already exist in the per-color CSVs. This captures + # dynamically constructed tags like "{CreatureType} Kindred" that don't appear + # as string literals in source code but are present in data. + try: + csv_rows = gather_theme_tag_rows() + if csv_rows: + for row_tags in csv_rows: + for t in row_tags: + if isinstance(t, str) and t: + theme_tags.add(t) + except Exception: + # If CSVs are unavailable, continue with tags from code only + csv_rows = [] + + # Normalization before other operations (so pruning & synergies use canonical names) + if normalization_map: + theme_tags = apply_normalization(theme_tags, normalization_map) + + # Remove excluded / blacklisted helper tags we might not want to expose as themes + blacklist = {"Draw Triggers"} + theme_tags = {t for t in theme_tags if t and t not in blacklist and t not in exclusions} + + # If we have frequency data, filter out extremely rare themes + # Rule: Drop any theme whose total count across all base colors is <= 1 + # This removes one-off/accidental tags from the theme catalog. + # We apply the filter only when frequencies were computed successfully. + try: + _freq_probe = tally_tag_frequencies_by_base_color() + has_freqs = bool(_freq_probe) + except Exception: + has_freqs = False + + if has_freqs: + def total_count(t: str) -> int: + total = 0 + for color in BASE_COLORS.keys(): + try: + total += int(_freq_probe.get(color, {}).get(t, 0)) + except Exception: + pass + return total + kept: Set[str] = set() + for t in list(theme_tags): + if should_keep_theme(t, total_count(t), whitelist_cfg, protected_prefixes, protected_suffixes, min_overrides): + kept.add(t) + # Merge always_include even if absent + for extra in whitelist_cfg.get('always_include', []) or []: + kept.add(extra if isinstance(extra, str) else str(extra)) + theme_tags = kept + + # Sort tags for stable output + sorted_tags = sorted(theme_tags) + + # Derive synergies mapping + synergies = derive_synergies_for_tags(theme_tags) + + # Tally frequencies by base color if CSVs exist + try: + frequencies = tally_tag_frequencies_by_base_color() + except Exception: + frequencies = {} + + # Co-occurrence synergies (data-driven) if CSVs exist + try: + # Reuse rows from earlier if available; otherwise gather now + rows = csv_rows if 'csv_rows' in locals() and csv_rows else gather_theme_tag_rows() + co_map, tag_counts, total_rows = compute_cooccurrence(rows) + except Exception: + rows = [] + co_map, tag_counts, total_rows = {}, Counter(), 0 + + # Helper: compute primary/secondary colors for a theme + def primary_secondary_for(theme: str, freqs: Dict[str, Dict[str, int]]): + if not freqs: + return None, None + # Collect counts per base color for this theme + items = [] + for color in BASE_COLORS.keys(): + count = 0 + try: + count = int(freqs.get(color, {}).get(theme, 0)) + except Exception: + count = 0 + items.append((color, count)) + # Sort by count desc, then by color name for stability + items.sort(key=lambda x: (-x[1], x[0])) + # If all zeros, return None + if not items or items[0][1] <= 0: + return None, None + color_title = { + 'white': 'White', 'blue': 'Blue', 'black': 'Black', 'red': 'Red', 'green': 'Green' + } + primary = color_title[items[0][0]] + secondary = None + # Find the next non-zero distinct color if available + for c, n in items[1:]: + if n > 0: + secondary = color_title[c] + break + return primary, secondary + + output = [] + def _uniq(seq: List[str]) -> List[str]: + seen = set() + out: List[str] = [] + for x in seq: + if x not in seen: + out.append(x) + seen.add(x) + return out + for t in sorted_tags: + p, s = primary_secondary_for(t, frequencies) + # Build synergy list: curated + top co-occurrences + curated = synergies.get(t, []) + inferred: List[str] = [] + if t in co_map and total_rows > 0: + # Denylist for clearly noisy combos + denylist = { + ('-1/-1 Counters', 'Burn'), + ('-1/-1 Counters', 'Voltron'), + } + # Whitelist focus for specific anchors + focus: Dict[str, List[str]] = { + '-1/-1 Counters': ['Counters Matter', 'Infect', 'Proliferate', 'Wither', 'Persist'], + } + # Compute PMI scores and filter + scored = cooccurrence_scores_for(t, co_map, tag_counts, total_rows) + # Keep only positive PMI and co-occurrence >= 5 (tunable) + filtered = [(o, s, c) for (o, s, c) in scored if s > 0 and c >= 5] + # If focused tags exist, ensure they bubble up first when present + preferred = focus.get(t, []) + if preferred: + # Partition into preferred and others + pref = [x for x in filtered if x[0] in preferred] + others = [x for x in filtered if x[0] not in preferred] + filtered = pref + others + # Select up to 6, skipping denylist and duplicates + for other, _score, _c in filtered: + if (t, other) in denylist or (other, t) in denylist: + continue + if other == t or other in curated or other in inferred: + continue + inferred.append(other) + if len(inferred) >= 6: + break + combined = list(curated) + # Enforced synergies from config (high precedence after curated) + enforced = enforced_synergies_cfg.get(t, []) + for es in enforced: + if es != t and es not in combined: + combined.append(es) + # Legacy automatic enforcement (backwards compatibility) if not already covered by enforced config + if not enforced: + if re.search(r'counter', t, flags=re.IGNORECASE) or t == 'Proliferate': + for needed in ['Counters Matter', 'Proliferate']: + if needed != t and needed not in combined: + combined.append(needed) + if re.search(r'token', t, flags=re.IGNORECASE) and t != 'Tokens Matter': + if 'Tokens Matter' not in combined: + combined.append('Tokens Matter') + # Append inferred last (lowest precedence) + for inf in inferred: + if inf != t and inf not in combined: + combined.append(inf) + # Deduplicate + combined = _uniq(combined) + # Apply synergy cap if configured (>0) + if synergy_cap > 0 and len(combined) > synergy_cap: + combined = combined[:synergy_cap] + entry = { + "theme": t, + "synergies": combined, + } + if p: + entry["primary_color"] = p + if s: + entry["secondary_color"] = s + output.append(entry) + + os.makedirs(os.path.join('config', 'themes'), exist_ok=True) + with open(os.path.join('config', 'themes', 'theme_list.json'), 'w', encoding='utf-8') as f: + json.dump({ + "themes": output, + "frequencies_by_base_color": frequencies, + "generated_from": "tagger + constants", + }, f, indent=2, ensure_ascii=False) + + +if __name__ == "__main__": + main() diff --git a/code/tests/test_builder_rng_seeded_stream.py b/code/tests/test_builder_rng_seeded_stream.py new file mode 100644 index 0000000..0bf5141 --- /dev/null +++ b/code/tests/test_builder_rng_seeded_stream.py @@ -0,0 +1,15 @@ +from __future__ import annotations + +from deck_builder.builder import DeckBuilder + + +def test_builder_rng_same_seed_identical_streams(): + b1 = DeckBuilder() + b1.set_seed('alpha') + seq1 = [b1.rng.random() for _ in range(5)] + + b2 = DeckBuilder() + b2.set_seed('alpha') + seq2 = [b2.rng.random() for _ in range(5)] + + assert seq1 == seq2 diff --git a/code/tests/test_deterministic_sampling.py b/code/tests/test_deterministic_sampling.py new file mode 100644 index 0000000..019a875 --- /dev/null +++ b/code/tests/test_deterministic_sampling.py @@ -0,0 +1,33 @@ +from deck_builder import builder_utils as bu +from random_util import set_seed + + +def test_weighted_sample_deterministic_same_seed(): + pool = [("a", 1), ("b", 2), ("c", 3), ("d", 4)] + k = 3 + rng1 = set_seed(12345) + sel1 = bu.weighted_sample_without_replacement(pool, k, rng=rng1) + # Reset to the same seed and expect the same selection order + rng2 = set_seed(12345) + sel2 = bu.weighted_sample_without_replacement(pool, k, rng=rng2) + assert sel1 == sel2 + + +def test_compute_adjusted_target_deterministic_same_seed(): + # Use a simple output func that collects messages (but we don't assert on them here) + msgs: list[str] = [] + out = msgs.append + original_cfg = 10 + existing = 4 + + rng1 = set_seed(999) + to_add1, bonus1 = bu.compute_adjusted_target( + "Ramp", original_cfg, existing, out, plural_word="ramp spells", rng=rng1 + ) + + rng2 = set_seed(999) + to_add2, bonus2 = bu.compute_adjusted_target( + "Ramp", original_cfg, existing, out, plural_word="ramp spells", rng=rng2 + ) + + assert (to_add1, bonus1) == (to_add2, bonus2) diff --git a/code/tests/test_random_build_api.py b/code/tests/test_random_build_api.py new file mode 100644 index 0000000..b5685cb --- /dev/null +++ b/code/tests/test_random_build_api.py @@ -0,0 +1,22 @@ +from __future__ import annotations + +import importlib +import os +from starlette.testclient import TestClient + + +def test_random_build_api_commander_and_seed(monkeypatch): + # Enable Random Modes and use tiny dataset + monkeypatch.setenv("RANDOM_MODES", "1") + monkeypatch.setenv("CSV_FILES_DIR", os.path.join("csv_files", "testdata")) + + app_module = importlib.import_module('code.web.app') + client = TestClient(app_module.app) + + payload = {"seed": 12345, "theme": "Goblin Kindred"} + r = client.post('/api/random_build', json=payload) + assert r.status_code == 200 + data = r.json() + assert data["seed"] == 12345 + assert isinstance(data.get("commander"), str) + assert data.get("commander") diff --git a/code/tests/test_random_determinism.py b/code/tests/test_random_determinism.py new file mode 100644 index 0000000..3aa0ffe --- /dev/null +++ b/code/tests/test_random_determinism.py @@ -0,0 +1,21 @@ +from __future__ import annotations + +import os +from deck_builder.random_entrypoint import build_random_deck + + +def test_random_build_is_deterministic_with_seed(monkeypatch): + # Force deterministic tiny dataset + monkeypatch.setenv("CSV_FILES_DIR", os.path.join("csv_files", "testdata")) + # Fixed seed should produce same commander consistently + out1 = build_random_deck(seed=12345) + out2 = build_random_deck(seed=12345) + assert out1.commander == out2.commander + assert out1.seed == out2.seed + + +def test_random_build_uses_theme_when_available(monkeypatch): + monkeypatch.setenv("CSV_FILES_DIR", os.path.join("csv_files", "testdata")) + # On tiny dataset, provide a theme that exists or not; either path should not crash + res = build_random_deck(theme="Goblin Kindred", seed=42) + assert isinstance(res.commander, str) and len(res.commander) > 0 diff --git a/code/tests/test_random_full_build_api.py b/code/tests/test_random_full_build_api.py new file mode 100644 index 0000000..3b39b3a --- /dev/null +++ b/code/tests/test_random_full_build_api.py @@ -0,0 +1,25 @@ +from __future__ import annotations + +import importlib +import os +from starlette.testclient import TestClient + + +def test_random_full_build_api_returns_deck_and_permalink(monkeypatch): + # Enable Random Modes and use tiny dataset + monkeypatch.setenv("RANDOM_MODES", "1") + monkeypatch.setenv("CSV_FILES_DIR", os.path.join("csv_files", "testdata")) + + app_module = importlib.import_module('code.web.app') + client = TestClient(app_module.app) + + payload = {"seed": 4242, "theme": "Goblin Kindred"} + r = client.post('/api/random_full_build', json=payload) + assert r.status_code == 200 + data = r.json() + assert data["seed"] == 4242 + assert isinstance(data.get("commander"), str) and data["commander"] + assert isinstance(data.get("decklist"), list) + # Permalink present and shaped like /build/from?state=... + assert data.get("permalink") + assert "/build/from?state=" in data["permalink"] diff --git a/code/tests/test_random_full_build_determinism.py b/code/tests/test_random_full_build_determinism.py new file mode 100644 index 0000000..c64cb89 --- /dev/null +++ b/code/tests/test_random_full_build_determinism.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +import os +from deck_builder.random_entrypoint import build_random_full_deck + + +def test_random_full_build_is_deterministic_on_frozen_dataset(monkeypatch): + # Use frozen dataset for determinism + monkeypatch.setenv("CSV_FILES_DIR", os.path.join("csv_files", "testdata")) + # Fixed seed should produce the same compact decklist + out1 = build_random_full_deck(theme="Goblin Kindred", seed=777) + out2 = build_random_full_deck(theme="Goblin Kindred", seed=777) + + assert out1.seed == out2.seed == 777 + assert out1.commander == out2.commander + assert isinstance(out1.decklist, list) and isinstance(out2.decklist, list) + assert out1.decklist == out2.decklist diff --git a/code/tests/test_random_reroll_endpoints.py b/code/tests/test_random_reroll_endpoints.py new file mode 100644 index 0000000..26cc901 --- /dev/null +++ b/code/tests/test_random_reroll_endpoints.py @@ -0,0 +1,45 @@ +import os +import json + +import pytest + +from fastapi.testclient import TestClient + + +@pytest.fixture(scope="module") +def client(): + # Ensure flags and frozen dataset + os.environ["RANDOM_MODES"] = "1" + os.environ["RANDOM_UI"] = "1" + os.environ["CSV_FILES_DIR"] = os.path.join("csv_files", "testdata") + + from web.app import app + + with TestClient(app) as c: + yield c + + +def test_api_random_reroll_increments_seed(client: TestClient): + r1 = client.post("/api/random_full_build", json={"seed": 123}) + assert r1.status_code == 200, r1.text + data1 = r1.json() + assert data1.get("seed") == 123 + + r2 = client.post("/api/random_reroll", json={"seed": 123}) + assert r2.status_code == 200, r2.text + data2 = r2.json() + assert data2.get("seed") == 124 + assert data2.get("permalink") + + +def test_hx_random_reroll_returns_html(client: TestClient): + headers = {"HX-Request": "true", "Content-Type": "application/json"} + r = client.post("/hx/random_reroll", data=json.dumps({"seed": 42}), headers=headers) + assert r.status_code == 200, r.text + # Accept either HTML fragment or JSON fallback + content_type = r.headers.get("content-type", "") + if "text/html" in content_type: + assert "Seed:" in r.text + else: + j = r.json() + assert j.get("seed") in (42, 43) # depends on increment policy \ No newline at end of file diff --git a/code/tests/test_random_util.py b/code/tests/test_random_util.py new file mode 100644 index 0000000..84401d8 --- /dev/null +++ b/code/tests/test_random_util.py @@ -0,0 +1,37 @@ +from __future__ import annotations + +from random_util import derive_seed_from_string, set_seed, get_random, generate_seed + + +def test_derive_seed_from_string_stable(): + # Known value derived from SHA-256('test-seed') first 8 bytes masked to 63 bits + assert derive_seed_from_string('test-seed') == 6214070892065607348 + # Int passthrough-like behavior (normalized to positive 63-bit) + assert derive_seed_from_string(42) == 42 + assert derive_seed_from_string(-42) == 42 + + +def test_set_seed_deterministic_stream(): + r1 = set_seed('alpha') + r2 = set_seed('alpha') + seq1 = [r1.random() for _ in range(5)] + seq2 = [r2.random() for _ in range(5)] + assert seq1 == seq2 + + +def test_get_random_unseeded_independent(): + a = get_random() + b = get_random() + # Advance a few steps + _ = [a.random() for _ in range(3)] + _ = [b.random() for _ in range(3)] + # They should not be the same object and streams should diverge vs seeded + assert a is not b + + +def test_generate_seed_range(): + s = generate_seed() + assert isinstance(s, int) + assert s >= 0 + # Ensure it's within 63-bit range + assert s < (1 << 63) diff --git a/code/tests/test_seeded_builder_minimal.py b/code/tests/test_seeded_builder_minimal.py new file mode 100644 index 0000000..8413082 --- /dev/null +++ b/code/tests/test_seeded_builder_minimal.py @@ -0,0 +1,18 @@ +from __future__ import annotations + +import os +from code.headless_runner import run + + +def test_headless_seed_threads_into_builder(monkeypatch): + # Use the tiny test dataset for speed/determinism + monkeypatch.setenv("CSV_FILES_DIR", os.path.join("csv_files", "testdata")) + # Use a commander known to be in tiny dataset or fallback path; we rely on search/confirm flow + # Provide a simple name that will fuzzy match one of the entries. + out1 = run(command_name="Krenko", seed=999) + out2 = run(command_name="Krenko", seed=999) + # Determinism: the seed should be set on the builder and identical across runs + assert getattr(out1, "seed", None) == getattr(out2, "seed", None) == 999 + # Basic sanity: commander selection should have occurred + assert isinstance(getattr(out1, "commander_name", ""), str) + assert isinstance(getattr(out2, "commander_name", ""), str) \ No newline at end of file diff --git a/code/tests/test_theme_whitelist_and_synergy_cap.py b/code/tests/test_theme_whitelist_and_synergy_cap.py new file mode 100644 index 0000000..e57b47c --- /dev/null +++ b/code/tests/test_theme_whitelist_and_synergy_cap.py @@ -0,0 +1,84 @@ +import json +import subprocess +import sys +from pathlib import Path + +# This test validates that the whitelist governance + synergy cap logic +# (implemented in extract_themes.py and theme_whitelist.yml) behaves as expected. +# It focuses on a handful of anchor themes to keep runtime fast and deterministic. + +ROOT = Path(__file__).resolve().parents[2] +SCRIPT = ROOT / "code" / "scripts" / "extract_themes.py" +OUTPUT_JSON = ROOT / "config" / "themes" / "theme_list.json" + + +def run_extractor(): + # Re-run extraction so the test always evaluates fresh output. + # Using the current python executable ensures we run inside the active venv. + result = subprocess.run([sys.executable, str(SCRIPT)], capture_output=True, text=True) + assert result.returncode == 0, f"extract_themes.py failed: {result.stderr or result.stdout}" + assert OUTPUT_JSON.exists(), "Expected theme_list.json to be generated" + + +def load_themes(): + data = json.loads(OUTPUT_JSON.read_text(encoding="utf-8")) + themes = data.get("themes", []) + mapping = {t["theme"]: t for t in themes if isinstance(t, dict) and "theme" in t} + return mapping + + +def assert_contains(theme_map, theme_name): + assert theme_name in theme_map, f"Expected theme '{theme_name}' in generated theme list" + + +def test_synergy_cap_and_enforced_inclusions(): + run_extractor() + theme_map = load_themes() + + # Target anchors to validate + anchors = [ + "+1/+1 Counters", + "-1/-1 Counters", + "Counters Matter", + "Reanimate", + "Outlaw Kindred", + ] + for a in anchors: + assert_contains(theme_map, a) + + # Synergy cap check (<=5) + for a in anchors: + syn = theme_map[a]["synergies"] + assert len(syn) <= 5, f"Synergy cap violated for {a}: {syn} (len={len(syn)})" + + # Enforced synergies for counters cluster + plus_syn = set(theme_map["+1/+1 Counters"]["synergies"]) + assert {"Proliferate", "Counters Matter"}.issubset(plus_syn), "+1/+1 Counters missing enforced synergies" + + minus_syn = set(theme_map["-1/-1 Counters"]["synergies"]) + assert {"Proliferate", "Counters Matter"}.issubset(minus_syn), "-1/-1 Counters missing enforced synergies" + + counters_matter_syn = set(theme_map["Counters Matter"]["synergies"]) + assert "Proliferate" in counters_matter_syn, "Counters Matter should include Proliferate" + + # Reanimate anchor (enforced synergy to Graveyard Matters retained while capped) + reanimate_syn = theme_map["Reanimate"]["synergies"] + assert "Graveyard Matters" in reanimate_syn, "Reanimate should include Graveyard Matters" + assert "Enter the Battlefield" in reanimate_syn, "Reanimate should include Enter the Battlefield (curated)" + + # Outlaw Kindred - curated list should remain exactly its 5 intrinsic sub-tribes + outlaw_expected = {"Warlock Kindred", "Pirate Kindred", "Rogue Kindred", "Assassin Kindred", "Mercenary Kindred"} + outlaw_syn = set(theme_map["Outlaw Kindred"]["synergies"]) + assert outlaw_syn == outlaw_expected, f"Outlaw Kindred synergies mismatch. Expected {outlaw_expected}, got {outlaw_syn}" + + # No enforced synergy should be silently truncated if it was required (already ensured by ordering + length checks) + # Additional safety: ensure every enforced synergy appears in its anchor (sampling a subset) + for anchor, required in { + "+1/+1 Counters": ["Proliferate", "Counters Matter"], + "-1/-1 Counters": ["Proliferate", "Counters Matter"], + "Reanimate": ["Graveyard Matters"], + }.items(): + present = set(theme_map[anchor]["synergies"]) + missing = [r for r in required if r not in present] + assert not missing, f"Anchor {anchor} missing enforced synergies: {missing}" + diff --git a/code/web/app.py b/code/web/app.py index f9f19e1..b677eb2 100644 --- a/code/web/app.py +++ b/code/web/app.py @@ -78,6 +78,15 @@ ENABLE_THEMES = _as_bool(os.getenv("ENABLE_THEMES"), False) ENABLE_PWA = _as_bool(os.getenv("ENABLE_PWA"), False) ENABLE_PRESETS = _as_bool(os.getenv("ENABLE_PRESETS"), False) ALLOW_MUST_HAVES = _as_bool(os.getenv("ALLOW_MUST_HAVES"), False) +RANDOM_MODES = _as_bool(os.getenv("RANDOM_MODES"), False) +RANDOM_UI = _as_bool(os.getenv("RANDOM_UI"), False) +def _as_int(val: str | None, default: int) -> int: + try: + return int(val) if val is not None and str(val).strip() != "" else default + except Exception: + return default +RANDOM_MAX_ATTEMPTS = _as_int(os.getenv("RANDOM_MAX_ATTEMPTS"), 5) +RANDOM_TIMEOUT_MS = _as_int(os.getenv("RANDOM_TIMEOUT_MS"), 5000) # Theme default from environment: THEME=light|dark|system (case-insensitive). Defaults to system. _THEME_ENV = (os.getenv("THEME") or "").strip().lower() @@ -96,6 +105,10 @@ templates.env.globals.update({ "enable_presets": ENABLE_PRESETS, "allow_must_haves": ALLOW_MUST_HAVES, "default_theme": DEFAULT_THEME, + "random_modes": RANDOM_MODES, + "random_ui": RANDOM_UI, + "random_max_attempts": RANDOM_MAX_ATTEMPTS, + "random_timeout_ms": RANDOM_TIMEOUT_MS, }) # --- Simple fragment cache for template partials (low-risk, TTL-based) --- @@ -178,11 +191,272 @@ async def status_sys(): "ENABLE_PRESETS": bool(ENABLE_PRESETS), "ALLOW_MUST_HAVES": bool(ALLOW_MUST_HAVES), "DEFAULT_THEME": DEFAULT_THEME, + "RANDOM_MODES": bool(RANDOM_MODES), + "RANDOM_UI": bool(RANDOM_UI), + "RANDOM_MAX_ATTEMPTS": int(RANDOM_MAX_ATTEMPTS), + "RANDOM_TIMEOUT_MS": int(RANDOM_TIMEOUT_MS), }, } except Exception: return {"version": "unknown", "uptime_seconds": 0, "flags": {}} +# --- Random Modes API --- +@app.post("/api/random_build") +async def api_random_build(request: Request): + # Gate behind feature flag + if not RANDOM_MODES: + raise HTTPException(status_code=404, detail="Random Modes disabled") + try: + body = {} + try: + body = await request.json() + if not isinstance(body, dict): + body = {} + except Exception: + body = {} + theme = body.get("theme") + constraints = body.get("constraints") + seed = body.get("seed") + attempts = body.get("attempts", int(RANDOM_MAX_ATTEMPTS)) + timeout_ms = body.get("timeout_ms", int(RANDOM_TIMEOUT_MS)) + # Convert ms -> seconds, clamp minimal + try: + timeout_s = max(0.1, float(timeout_ms) / 1000.0) + except Exception: + timeout_s = max(0.1, float(RANDOM_TIMEOUT_MS) / 1000.0) + # Import on-demand to avoid heavy costs at module import time + from deck_builder.random_entrypoint import build_random_deck # type: ignore + res = build_random_deck( + theme=theme, + constraints=constraints, + seed=seed, + attempts=int(attempts), + timeout_s=float(timeout_s), + ) + rid = getattr(request.state, "request_id", None) + return { + "seed": int(res.seed), + "commander": res.commander, + "theme": res.theme, + "constraints": res.constraints or {}, + "attempts": int(attempts), + "timeout_ms": int(timeout_ms), + "request_id": rid, + } + except HTTPException: + raise + except Exception as ex: + logging.getLogger("web").error(f"random_build failed: {ex}") + raise HTTPException(status_code=500, detail="random_build failed") + + +@app.post("/api/random_full_build") +async def api_random_full_build(request: Request): + # Gate behind feature flag + if not RANDOM_MODES: + raise HTTPException(status_code=404, detail="Random Modes disabled") + try: + body = {} + try: + body = await request.json() + if not isinstance(body, dict): + body = {} + except Exception: + body = {} + theme = body.get("theme") + constraints = body.get("constraints") + seed = body.get("seed") + attempts = body.get("attempts", int(RANDOM_MAX_ATTEMPTS)) + timeout_ms = body.get("timeout_ms", int(RANDOM_TIMEOUT_MS)) + # Convert ms -> seconds, clamp minimal + try: + timeout_s = max(0.1, float(timeout_ms) / 1000.0) + except Exception: + timeout_s = max(0.1, float(RANDOM_TIMEOUT_MS) / 1000.0) + + # Build a full deck deterministically + from deck_builder.random_entrypoint import build_random_full_deck # type: ignore + res = build_random_full_deck( + theme=theme, + constraints=constraints, + seed=seed, + attempts=int(attempts), + timeout_s=float(timeout_s), + ) + + # Create a permalink token reusing the existing format from /build/permalink + payload = { + "commander": res.commander, + # Note: tags/bracket/ideals omitted; random modes focuses on seed replay + "random": { + "seed": int(res.seed), + "theme": res.theme, + "constraints": res.constraints or {}, + }, + } + try: + import base64 + raw = _json.dumps(payload, separators=(",", ":")) + token = base64.urlsafe_b64encode(raw.encode("utf-8")).decode("ascii").rstrip("=") + permalink = f"/build/from?state={token}" + except Exception: + permalink = None + + rid = getattr(request.state, "request_id", None) + return { + "seed": int(res.seed), + "commander": res.commander, + "decklist": res.decklist or [], + "theme": res.theme, + "constraints": res.constraints or {}, + "permalink": permalink, + "attempts": int(attempts), + "timeout_ms": int(timeout_ms), + "request_id": rid, + } + except HTTPException: + raise + except Exception as ex: + logging.getLogger("web").error(f"random_full_build failed: {ex}") + raise HTTPException(status_code=500, detail="random_full_build failed") + + +@app.post("/api/random_reroll") +async def api_random_reroll(request: Request): + # Gate behind feature flag + if not RANDOM_MODES: + raise HTTPException(status_code=404, detail="Random Modes disabled") + try: + body = {} + try: + body = await request.json() + if not isinstance(body, dict): + body = {} + except Exception: + body = {} + theme = body.get("theme") + constraints = body.get("constraints") + last_seed = body.get("seed") + # Simple deterministic reroll policy: increment prior seed when provided; else generate fresh + try: + new_seed = int(last_seed) + 1 if last_seed is not None else None + except Exception: + new_seed = None + if new_seed is None: + from random_util import generate_seed # type: ignore + new_seed = int(generate_seed()) + + # Build with the new seed + timeout_ms = body.get("timeout_ms", int(RANDOM_TIMEOUT_MS)) + try: + timeout_s = max(0.1, float(timeout_ms) / 1000.0) + except Exception: + timeout_s = max(0.1, float(RANDOM_TIMEOUT_MS) / 1000.0) + attempts = body.get("attempts", int(RANDOM_MAX_ATTEMPTS)) + + from deck_builder.random_entrypoint import build_random_full_deck # type: ignore + res = build_random_full_deck( + theme=theme, + constraints=constraints, + seed=new_seed, + attempts=int(attempts), + timeout_s=float(timeout_s), + ) + + payload = { + "commander": res.commander, + "random": { + "seed": int(res.seed), + "theme": res.theme, + "constraints": res.constraints or {}, + }, + } + try: + import base64 + raw = _json.dumps(payload, separators=(",", ":")) + token = base64.urlsafe_b64encode(raw.encode("utf-8")).decode("ascii").rstrip("=") + permalink = f"/build/from?state={token}" + except Exception: + permalink = None + + rid = getattr(request.state, "request_id", None) + return { + "previous_seed": (int(last_seed) if isinstance(last_seed, int) or (isinstance(last_seed, str) and str(last_seed).isdigit()) else None), + "seed": int(res.seed), + "commander": res.commander, + "decklist": res.decklist or [], + "theme": res.theme, + "constraints": res.constraints or {}, + "permalink": permalink, + "attempts": int(attempts), + "timeout_ms": int(timeout_ms), + "request_id": rid, + } + except HTTPException: + raise + except Exception as ex: + logging.getLogger("web").error(f"random_reroll failed: {ex}") + raise HTTPException(status_code=500, detail="random_reroll failed") + + +@app.post("/hx/random_reroll") +async def hx_random_reroll(request: Request): + # Small HTMX endpoint returning a partial HTML fragment for in-page updates + if not RANDOM_UI or not RANDOM_MODES: + raise HTTPException(status_code=404, detail="Random UI disabled") + body = {} + try: + body = await request.json() + if not isinstance(body, dict): + body = {} + except Exception: + body = {} + last_seed = body.get("seed") + theme = body.get("theme") + constraints = body.get("constraints") + try: + new_seed = int(last_seed) + 1 if last_seed is not None else None + except Exception: + new_seed = None + if new_seed is None: + from random_util import generate_seed # type: ignore + new_seed = int(generate_seed()) + + from deck_builder.random_entrypoint import build_random_full_deck # type: ignore + res = build_random_full_deck( + theme=theme, + constraints=constraints, + seed=new_seed, + attempts=int(RANDOM_MAX_ATTEMPTS), + timeout_s=float(RANDOM_TIMEOUT_MS) / 1000.0, + ) + + # Render minimal fragment via Jinja2 + try: + return templates.TemplateResponse( + "partials/random_result.html", # type: ignore + { + "request": request, + "seed": int(res.seed), + "commander": res.commander, + "decklist": res.decklist or [], + "theme": res.theme, + "constraints": res.constraints or {}, + }, + ) + except Exception as ex: + logging.getLogger("web").error(f"hx_random_reroll template error: {ex}") + # Fallback to JSON to avoid total failure + return JSONResponse( + { + "seed": int(res.seed), + "commander": res.commander, + "decklist": res.decklist or [], + "theme": res.theme, + "constraints": res.constraints or {}, + } + ) + # Logs tail endpoint (read-only) @app.get("/status/logs") async def status_logs( diff --git a/code/web/routes/build.py b/code/web/routes/build.py index cfcb88c..84638dc 100644 --- a/code/web/routes/build.py +++ b/code/web/routes/build.py @@ -22,6 +22,7 @@ from html import escape as _esc from deck_builder.builder import DeckBuilder from deck_builder import builder_utils as bu from ..services.combo_utils import detect_all as _detect_all +from path_util import csv_dir as _csv_dir from ..services.alts_utils import get_cached as _alts_get_cached, set_cached as _alts_set_cached # Cache for available card names used by validation endpoints @@ -39,7 +40,7 @@ def _available_cards() -> set[str]: return _AVAILABLE_CARDS_CACHE try: import csv - path = 'csv_files/cards.csv' + path = f"{_csv_dir()}/cards.csv" with open(path, 'r', encoding='utf-8', newline='') as f: reader = csv.DictReader(f) fields = reader.fieldnames or [] @@ -2853,6 +2854,16 @@ async def build_permalink(request: Request): }, "locks": list(sess.get("locks", [])), } + # Optional: random build fields (if present in session) + try: + rb = sess.get("random_build") or {} + if rb: + # Only include known keys to avoid leaking unrelated session data + inc = {k: rb.get(k) for k in ("seed", "theme", "constraints") if k in rb} + if inc: + payload["random"] = inc + except Exception: + pass # Add include/exclude cards and advanced options if feature is enabled if ALLOW_MUST_HAVES: @@ -2899,6 +2910,15 @@ async def build_from(request: Request, state: str | None = None) -> HTMLResponse sess["use_owned_only"] = bool(flags.get("owned_only")) sess["prefer_owned"] = bool(flags.get("prefer_owned")) sess["locks"] = list(data.get("locks", [])) + # Optional random build rehydration + try: + r = data.get("random") or {} + if r: + sess["random_build"] = { + k: r.get(k) for k in ("seed", "theme", "constraints") if k in r + } + except Exception: + pass # Import exclude_cards if feature is enabled and present if ALLOW_MUST_HAVES and data.get("exclude_cards"): diff --git a/code/web/templates/diagnostics/index.html b/code/web/templates/diagnostics/index.html index 5f5601f..03cd3fb 100644 --- a/code/web/templates/diagnostics/index.html +++ b/code/web/templates/diagnostics/index.html @@ -61,7 +61,15 @@ el.innerHTML = '
Version: '+String(v)+'
'+ (st ? '
Server time (UTC): '+String(st)+'
' : '')+ '
Uptime: '+String(up)+'s
'+ - '
Flags: SHOW_LOGS='+ (flags.SHOW_LOGS? '1':'0') +', SHOW_DIAGNOSTICS='+ (flags.SHOW_DIAGNOSTICS? '1':'0') +', SHOW_SETUP='+ (flags.SHOW_SETUP? '1':'0') +'
'; + '
Flags: ' + + 'SHOW_LOGS='+ (flags.SHOW_LOGS? '1':'0') + + ', SHOW_DIAGNOSTICS='+ (flags.SHOW_DIAGNOSTICS? '1':'0') + + ', SHOW_SETUP='+ (flags.SHOW_SETUP? '1':'0') + + ', RANDOM_MODES='+ (flags.RANDOM_MODES? '1':'0') + + ', RANDOM_UI='+ (flags.RANDOM_UI? '1':'0') + + ', RANDOM_MAX_ATTEMPTS='+ String(flags.RANDOM_MAX_ATTEMPTS ?? '') + + ', RANDOM_TIMEOUT_MS='+ String(flags.RANDOM_TIMEOUT_MS ?? '') + + '
'; } catch(_){ el.textContent = 'Unavailable'; } } function load(){ diff --git a/code/web/templates/partials/random_result.html b/code/web/templates/partials/random_result.html new file mode 100644 index 0000000..e91e9f7 --- /dev/null +++ b/code/web/templates/partials/random_result.html @@ -0,0 +1,12 @@ +
+
+ Seed: {{ seed }} + {% if theme %}Theme: {{ theme }}{% endif %} +
+

{{ commander }}

+ +
diff --git a/config/themes/theme_list.json b/config/themes/theme_list.json new file mode 100644 index 0000000..9f718f3 --- /dev/null +++ b/config/themes/theme_list.json @@ -0,0 +1,10899 @@ +{ + "themes": [ + { + "theme": "+1/+1 Counters", + "synergies": [ + "Proliferate", + "Counters Matter", + "Adapt", + "Evolve", + "Hydra Kindred" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "-0/-1 Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "-0/-2 Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black" + }, + { + "theme": "-1/-1 Counters", + "synergies": [ + "Proliferate", + "Counters Matter", + "Wither", + "Persist", + "Infect" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Adamant", + "synergies": [ + "Knight Kindred", + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Human Kindred" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Adapt", + "synergies": [ + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Aggro", + "Combat Matters" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Addendum", + "synergies": [ + "Interaction", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Advisor Kindred", + "synergies": [ + "Historics Matter", + "Legends Matter", + "-1/-1 Counters", + "Conditional Draw", + "Human Kindred" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Aetherborn Kindred", + "synergies": [ + "Rogue Kindred", + "Outlaw Kindred", + "+1/+1 Counters", + "Counters Matter", + "Voltron" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Affinity", + "synergies": [ + "Cost Reduction", + "Artifacts Matter", + "Big Mana", + "Flying", + "Historics Matter" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Afflict", + "synergies": [ + "Zombie Kindred", + "Reanimate", + "Burn", + "Little Fellas" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Afterlife", + "synergies": [ + "Spirit Kindred", + "Sacrifice Matters", + "Aristocrats", + "Creature Tokens", + "Token Creation" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Aftermath", + "synergies": [ + "Mill", + "Big Mana", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Age Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Cumulative upkeep", + "Storage Counters", + "Enchantments Matter" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Aggro", + "synergies": [ + "Combat Matters", + "Voltron", + "+1/+1 Counters", + "Auras", + "Trample" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Airbending", + "synergies": [], + "primary_color": "White" + }, + { + "theme": "Alien Kindred", + "synergies": [ + "Clones", + "Horror Kindred", + "Trample", + "Exile Matters", + "Soldier Kindred" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Alliance", + "synergies": [ + "Druid Kindred", + "Elf Kindred", + "Little Fellas", + "Aggro", + "Combat Matters" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Ally Kindred", + "synergies": [ + "Rally", + "Cohort", + "Earthbend", + "Kor Kindred", + "Peasant Kindred" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Amass", + "synergies": [ + "Army Kindred", + "Orc Kindred", + "Zombie Kindred", + "Creature Tokens", + "+1/+1 Counters" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Amplify", + "synergies": [ + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Aggro", + "Combat Matters" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Angel Kindred", + "synergies": [ + "Vigilance", + "Lifegain", + "Life Matters", + "Flying", + "Lifelink" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Annihilator", + "synergies": [], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Antelope Kindred", + "synergies": [ + "Toughness Matters", + "Little Fellas" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Ape Kindred", + "synergies": [ + "Removal", + "Artifacts Matter", + "Toughness Matters", + "Big Mana", + "Aggro" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Archer Kindred", + "synergies": [ + "Reach", + "Centaur Kindred", + "Elf Kindred", + "Snake Kindred", + "Pingers" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Archon Kindred", + "synergies": [ + "Flying", + "Big Mana", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Aristocrats", + "synergies": [ + "Sacrifice", + "Death Triggers", + "Token Creation", + "Sacrifice Matters", + "Persist" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Armadillo Kindred", + "synergies": [], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Army Kindred", + "synergies": [ + "Amass", + "Orc Kindred", + "Zombie Kindred", + "Creature Tokens", + "+1/+1 Counters" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Artifact Tokens", + "synergies": [ + "Tokens Matter", + "Treasure", + "Servo Kindred", + "Powerstone Token", + "Fabricate" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Artifacts Matter", + "synergies": [ + "Treasure Token", + "Equipment", + "Vehicles", + "Improvise", + "Artifact Tokens" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Artificer Kindred", + "synergies": [ + "Fabricate", + "Servo Kindred", + "Thopter Kindred", + "Powerstone Token", + "Vedalken Kindred" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Ascend", + "synergies": [ + "Creature Tokens", + "Token Creation", + "Tokens Matter", + "Little Fellas", + "Human Kindred" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Assassin Kindred", + "synergies": [ + "Freerunning", + "Outlaw Kindred", + "Deathtouch", + "Cost Reduction", + "Vampire Kindred" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Assembly-Worker Kindred", + "synergies": [], + "primary_color": "White" + }, + { + "theme": "Assist", + "synergies": [ + "Big Mana", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield", + "Interaction" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Astartes Kindred", + "synergies": [ + "Warrior Kindred", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield", + "Burn" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Atog Kindred", + "synergies": [ + "Toughness Matters", + "Little Fellas" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Auras", + "synergies": [ + "Constellation", + "Voltron", + "Enchantments Matter", + "Bestow", + "Umbra armor" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Aurochs Kindred", + "synergies": [], + "primary_color": "Green" + }, + { + "theme": "Avatar Kindred", + "synergies": [ + "Impending", + "Time Counters", + "Horror Kindred", + "Cost Reduction", + "Lifelink" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Awaken", + "synergies": [ + "Elemental Kindred", + "Lands Matter", + "+1/+1 Counters", + "Counters Matter", + "Voltron" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Azra Kindred", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Backgrounds Matter", + "synergies": [ + "Choose a background", + "Historics Matter", + "Legends Matter", + "Treasure", + "Treasure Token" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Backup", + "synergies": [ + "+1/+1 Counters", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield", + "Counters Matter" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Badger Kindred", + "synergies": [], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Banding", + "synergies": [ + "First strike", + "Soldier Kindred", + "Human Kindred", + "Little Fellas", + "Flying" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Barbarian Kindred", + "synergies": [ + "Haste", + "Human Kindred", + "Discard Matters", + "Historics Matter", + "Legends Matter" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Bard Kindred", + "synergies": [ + "Toughness Matters", + "Little Fellas", + "Human Kindred", + "Blink", + "Enter the Battlefield" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Bargain", + "synergies": [ + "Blink", + "Enter the Battlefield", + "Leave the Battlefield", + "Burn", + "Spells Matter" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Basic landcycling", + "synergies": [ + "Landcycling", + "Cycling", + "Loot", + "Ramp", + "Discard Matters" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Basilisk Kindred", + "synergies": [ + "Deathtouch", + "Toughness Matters", + "Little Fellas", + "Aggro", + "Combat Matters" + ], + "primary_color": "Green" + }, + { + "theme": "Bat Kindred", + "synergies": [ + "Lifeloss", + "Lifeloss Triggers", + "Lifegain", + "Life Matters", + "Flying" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Battalion", + "synergies": [ + "Soldier Kindred", + "Human Kindred", + "Aggro", + "Combat Matters", + "Little Fellas" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Battle Cry", + "synergies": [ + "Aggro", + "Combat Matters" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Battles Matter", + "synergies": [ + "Transform", + "Card Draw", + "Big Mana" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Bear Kindred", + "synergies": [ + "Druid Kindred", + "Trample", + "Creature Tokens", + "Historics Matter", + "Legends Matter" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Beast Kindred", + "synergies": [ + "Mutate", + "Goat Kindred", + "Boar Kindred", + "Morph", + "Frog Kindred" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Beaver Kindred", + "synergies": [], + "primary_color": "Green" + }, + { + "theme": "Beeble Kindred", + "synergies": [], + "primary_color": "Blue" + }, + { + "theme": "Behold", + "synergies": [ + "Dragon Kindred", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Beholder Kindred", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Berserker Kindred", + "synergies": [ + "Boast", + "Dash", + "Dwarf Kindred", + "Minotaur Kindred", + "Haste" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Bestow", + "synergies": [ + "Nymph Kindred", + "Equipment Matters", + "Auras", + "Artifacts Matter", + "Enchantments Matter" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Big Mana", + "synergies": [ + "Cost Reduction", + "Convoke", + "Affinity", + "Delve", + "Leviathan Kindred" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Bird Kindred", + "synergies": [ + "Flying", + "Soldier Kindred", + "Morph", + "Little Fellas", + "Landfall" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Blaze Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Red" + }, + { + "theme": "Blink", + "synergies": [ + "Enter the Battlefield", + "Flicker", + "Token Creation", + "Exploit", + "Offspring" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Blitz", + "synergies": [ + "Warrior Kindred", + "Sacrifice Matters", + "Conditional Draw", + "Aristocrats", + "Unconditional Draw" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Blood Token", + "synergies": [ + "Tokens Matter", + "Blood Tokens", + "Bloodthirst", + "Bloodrush", + "Sacrifice to Draw" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Blood Tokens", + "synergies": [ + "Tokens Matter", + "Blood Token", + "Sacrifice to Draw", + "Loot", + "Vampire Kindred" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Bloodrush", + "synergies": [ + "Blood Token", + "Aggro", + "Combat Matters" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Bloodthirst", + "synergies": [ + "Blood Token", + "+1/+1 Counters", + "Warrior Kindred", + "Counters Matter", + "Burn" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Boar Kindred", + "synergies": [ + "Beast Kindred", + "Trample", + "Token Creation", + "Tokens Matter", + "Creature Tokens" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Board Wipes", + "synergies": [ + "Bracket:MassLandDenial", + "Pingers", + "Interaction", + "Lore Counters", + "Sagas Matter" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Boast", + "synergies": [ + "Berserker Kindred", + "Warrior Kindred", + "Human Kindred", + "Little Fellas", + "Aggro" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Bolster", + "synergies": [ + "+1/+1 Counters", + "Combat Tricks", + "Counters Matter", + "Voltron", + "Soldier Kindred" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Bounty Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black" + }, + { + "theme": "Bracket:ExtraTurn", + "synergies": [ + "Spells Matter", + "Spellslinger", + "Big Mana", + "Counters Matter" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Bracket:GameChanger", + "synergies": [ + "Bracket:TutorNonland", + "Draw Triggers", + "Wheels", + "Historics Matter", + "Legends Matter" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Bracket:MassLandDenial", + "synergies": [ + "Board Wipes", + "Interaction", + "Spells Matter", + "Spellslinger", + "Big Mana" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Bracket:TutorNonland", + "synergies": [ + "Transmute", + "Bracket:GameChanger", + "Mercenary Kindred", + "Rebel Kindred", + "Superfriends" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Brushwagg Kindred", + "synergies": [], + "primary_color": "Green" + }, + { + "theme": "Burn", + "synergies": [ + "Pingers", + "Bloodthirst", + "Renown", + "Wither", + "Cipher" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Bushido", + "synergies": [ + "Samurai Kindred", + "Fox Kindred", + "Human Kindred", + "Historics Matter", + "Legends Matter" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Buyback", + "synergies": [ + "Spells Matter", + "Spellslinger", + "Lands Matter", + "Control", + "Removal" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "C'tan Kindred", + "synergies": [], + "primary_color": "Black" + }, + { + "theme": "Camarid Kindred", + "synergies": [], + "primary_color": "Blue" + }, + { + "theme": "Camel Kindred", + "synergies": [], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Cantrips", + "synergies": [ + "Clue Token", + "Investigate", + "Unconditional Draw", + "Sacrifice to Draw", + "Gift" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Capybara Kindred", + "synergies": [], + "primary_color": "Green" + }, + { + "theme": "Card Draw", + "synergies": [ + "Loot", + "Wheels", + "Replacement Draw", + "Unconditional Draw", + "Conditional Draw" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Card Selection", + "synergies": [ + "Explore", + "Map Token", + "Scout Kindred", + "Pirate Kindred", + "Merfolk Kindred" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Carrier Kindred", + "synergies": [ + "Phyrexian Kindred" + ], + "primary_color": "Black" + }, + { + "theme": "Cascade", + "synergies": [ + "Exile Matters", + "Topdeck", + "Big Mana", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Cases Matter", + "synergies": [ + "Enchantments Matter" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Casualty", + "synergies": [ + "Spell Copy", + "Sacrifice Matters", + "Aristocrats", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Cat Kindred", + "synergies": [ + "Forestwalk", + "Energy Counters", + "Vigilance", + "Energy", + "Resource Engine" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Celebration", + "synergies": [ + "Little Fellas" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Centaur Kindred", + "synergies": [ + "Archer Kindred", + "Scout Kindred", + "Druid Kindred", + "Shaman Kindred", + "Warrior Kindred" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Champion", + "synergies": [ + "Aggro", + "Combat Matters" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Changeling", + "synergies": [ + "Shapeshifter Kindred", + "Combat Tricks", + "Little Fellas", + "Interaction", + "Toughness Matters" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Channel", + "synergies": [ + "Spirit Kindred", + "Cost Reduction", + "Lands Matter", + "Historics Matter", + "Legends Matter" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Charge Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Station", + "Mana Rock", + "Artifacts Matter" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Child Kindred", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Chimera Kindred", + "synergies": [ + "Big Mana" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Choose a background", + "synergies": [ + "Backgrounds Matter", + "Historics Matter", + "Legends Matter", + "Elf Kindred", + "Cleric Kindred" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Chroma", + "synergies": [], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Cipher", + "synergies": [ + "Burn", + "Aggro", + "Combat Matters", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Citizen Kindred", + "synergies": [ + "Halfling Kindred", + "Food Token", + "Food", + "Treasure", + "Treasure Token" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Clash", + "synergies": [ + "Warrior Kindred", + "Control", + "Removal", + "Stax", + "Spells Matter" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Cleave", + "synergies": [ + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Cleric Kindred", + "synergies": [ + "Lifegain", + "Life Matters", + "Fox Kindred", + "Kor Kindred", + "Lifegain Triggers" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Cloak", + "synergies": [], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Clones", + "synergies": [ + "Myriad", + "Populate", + "Embalm", + "Eternalize", + "Shapeshifter Kindred" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Clown Kindred", + "synergies": [ + "Robot Kindred", + "Artifacts Matter", + "Tokens Matter", + "Little Fellas" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Clue Token", + "synergies": [ + "Tokens Matter", + "Investigate", + "Detective Kindred", + "Sacrifice to Draw", + "Artifact Tokens" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Cockatrice Kindred", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Cohort", + "synergies": [ + "Ally Kindred", + "Little Fellas" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Collect evidence", + "synergies": [ + "Detective Kindred", + "Mill", + "Big Mana", + "Toughness Matters", + "Little Fellas" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Combat Matters", + "synergies": [ + "Aggro", + "Voltron", + "+1/+1 Counters", + "Auras", + "Trample" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Combat Tricks", + "synergies": [ + "Flash", + "Strive", + "Split second", + "Bolster", + "Overload" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Compleated", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Conditional Draw", + "synergies": [ + "Max speed", + "Start your engines!", + "Blitz", + "Blood Tokens", + "Clue Token" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Conjure", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Connive", + "synergies": [ + "Loot", + "Rogue Kindred", + "Discard Matters", + "Outlaw Kindred", + "+1/+1 Counters" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Conspire", + "synergies": [ + "Spell Copy", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Constellation", + "synergies": [ + "Nymph Kindred", + "Enchantments Matter", + "Toughness Matters", + "Little Fellas", + "Reanimate" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Construct Kindred", + "synergies": [ + "Prototype", + "Unearth", + "Artifacts Matter", + "Artifact Tokens", + "Scry" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Control", + "synergies": [ + "Daybound", + "Nightbound", + "Council's dilemma", + "Soulshift", + "Counterspells" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Converge", + "synergies": [ + "Spells Matter", + "Spellslinger", + "Big Mana" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Convert", + "synergies": [ + "Living metal", + "More Than Meets the Eye", + "Eye Kindred", + "Robot Kindred", + "Vehicles" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Convoke", + "synergies": [ + "Knight Kindred", + "Big Mana", + "Combat Tricks", + "Removal", + "Protection" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Corpse Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black" + }, + { + "theme": "Corrupted", + "synergies": [ + "Poison Counters", + "Infect", + "Phyrexian Kindred", + "Counters Matter", + "Mill" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Cost Reduction", + "synergies": [ + "Affinity", + "Freerunning", + "Waterbending", + "Undaunted", + "Leech Kindred" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Cost Scaling", + "synergies": [ + "Modal", + "Spree", + "Control", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Council's dilemma", + "synergies": [ + "Control", + "Stax", + "Big Mana" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Counters Matter", + "synergies": [ + "Proliferate", + "+1/+1 Counters", + "Adapt", + "Outlast", + "-1/-1 Counters" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Counterspells", + "synergies": [ + "Counters Matter", + "Proliferate", + "Control", + "Stax", + "Interaction" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Coven", + "synergies": [ + "Human Kindred", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield", + "Little Fellas" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Coward Kindred", + "synergies": [], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Coyote Kindred", + "synergies": [], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Crab Kindred", + "synergies": [ + "Toughness Matters", + "Mill", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Craft", + "synergies": [ + "Graveyard Matters", + "Transform", + "Exile Matters", + "Artifacts Matter", + "Mill" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Creature Tokens", + "synergies": [ + "Tokens Matter", + "Token Creation", + "Populate", + "For Mirrodin!", + "Endure" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Crew", + "synergies": [ + "Vehicles", + "Artifacts Matter", + "Treasure Token", + "Trample", + "Vigilance" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Crocodile Kindred", + "synergies": [ + "Counters Matter", + "+1/+1 Counters", + "Toughness Matters", + "Voltron", + "Big Mana" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Cumulative upkeep", + "synergies": [ + "Age Counters", + "Counters Matter", + "Enchantments Matter", + "Trample", + "Stax" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Custodes Kindred", + "synergies": [], + "primary_color": "White" + }, + { + "theme": "Cyberman Kindred", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Cycling", + "synergies": [ + "Landcycling", + "Basic landcycling", + "Plainscycling", + "Mountaincycling", + "Forestcycling" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Cyclops Kindred", + "synergies": [ + "Big Mana", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield", + "Aggro" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Dalek Kindred", + "synergies": [], + "primary_color": "Black" + }, + { + "theme": "Dash", + "synergies": [ + "Orc Kindred", + "Berserker Kindred", + "Warrior Kindred", + "Human Kindred", + "Aggro" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Dauthi Kindred", + "synergies": [ + "Shadow", + "Aggro", + "Combat Matters", + "Little Fellas" + ], + "primary_color": "Black" + }, + { + "theme": "Daybound", + "synergies": [ + "Werewolf Kindred", + "Control", + "Stax", + "Human Kindred", + "Toughness Matters" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Deathtouch", + "synergies": [ + "Basilisk Kindred", + "Scorpion Kindred", + "Gorgon Kindred", + "Assassin Kindred", + "Spider Kindred" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Defender", + "synergies": [ + "Wall Kindred", + "Egg Kindred", + "Plant Kindred", + "Toughness Matters", + "Illusion Kindred" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Defense Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Delay Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Delirium", + "synergies": [ + "Reanimate", + "Mill", + "Horror Kindred", + "Blink", + "Enter the Battlefield" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Delve", + "synergies": [ + "Mill", + "Big Mana", + "Spells Matter", + "Spellslinger", + "Flying" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Demigod Kindred", + "synergies": [ + "Historics Matter", + "Legends Matter", + "Enchantments Matter" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Demon Kindred", + "synergies": [ + "Ogre Kindred", + "Trample", + "Flying", + "Sacrifice Matters", + "Aristocrats" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Demonstrate", + "synergies": [ + "Spell Copy", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Depletion Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Lands Matter" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Descend", + "synergies": [ + "Reanimate", + "Mill" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Deserter Kindred", + "synergies": [], + "primary_color": "White" + }, + { + "theme": "Detain", + "synergies": [ + "Stax", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Detective Kindred", + "synergies": [ + "Collect evidence", + "Investigate", + "Clue Token", + "Disguise", + "Sacrifice to Draw" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Dethrone", + "synergies": [ + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Aggro", + "Combat Matters" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Devil Kindred", + "synergies": [ + "Pingers", + "Haste", + "Conditional Draw", + "Sacrifice Matters", + "Aristocrats" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Devoid", + "synergies": [ + "Ingest", + "Processor Kindred", + "Scion Kindred", + "Drone Kindred", + "Eldrazi Kindred" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Devotion Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Devour", + "synergies": [ + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Aggro", + "Combat Matters" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Dinosaur Kindred", + "synergies": [ + "Enrage", + "Elder Kindred", + "Fight", + "Trample", + "Cycling" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Discard Matters", + "synergies": [ + "Loot", + "Wheels", + "Hellbent", + "Reanimate", + "Cycling" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Discover", + "synergies": [ + "Land Types Matter", + "Exile Matters", + "Topdeck", + "Lands Matter", + "Big Mana" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Disguise", + "synergies": [ + "Detective Kindred", + "Flying", + "+1/+1 Counters", + "Lifegain", + "Life Matters" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Disturb", + "synergies": [ + "Transform", + "Spirit Kindred", + "Mill", + "Human Kindred", + "Little Fellas" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Divinity Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Protection", + "Spirit Kindred", + "Historics Matter" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Djinn Kindred", + "synergies": [ + "Prowess", + "Monk Kindred", + "Flying", + "Toughness Matters", + "Big Mana" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Doctor Kindred", + "synergies": [ + "Doctor's companion", + "Sagas Matter", + "Lore Counters", + "Ore Counters", + "Historics Matter" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Doctor's companion", + "synergies": [ + "Doctor Kindred", + "Sagas Matter", + "Historics Matter", + "Legends Matter", + "Human Kindred" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Dog Kindred", + "synergies": [ + "Menace", + "Elemental Kindred", + "Scout Kindred", + "First strike", + "Phyrexian Kindred" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Domain", + "synergies": [ + "Lands Matter", + "Ramp", + "Topdeck", + "Big Mana", + "Spells Matter" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Doom Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Red" + }, + { + "theme": "Double strike", + "synergies": [ + "Knight Kindred", + "Warrior Kindred", + "Aggro", + "Combat Matters", + "Trample" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Dragon Kindred", + "synergies": [ + "Behold", + "Elder Kindred", + "Megamorph", + "Flying", + "Backgrounds Matter" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Drake Kindred", + "synergies": [ + "Flying", + "Phyrexian Kindred", + "Cost Reduction", + "Toughness Matters", + "Little Fellas" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Dreadnought Kindred", + "synergies": [], + "primary_color": "Blue" + }, + { + "theme": "Dredge", + "synergies": [ + "Unconditional Draw", + "Reanimate", + "Card Draw", + "Mill", + "Spells Matter" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Drone Kindred", + "synergies": [ + "Ingest", + "Spawn Kindred", + "Devoid", + "Scion Kindred", + "Eldrazi Kindred" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Druid Kindred", + "synergies": [ + "Alliance", + "Mana Dork", + "Elf Kindred", + "Ramp", + "Treefolk Kindred" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Dryad Kindred", + "synergies": [ + "Forestwalk", + "Landwalk", + "Mana Dork", + "Ramp", + "Lands Matter" + ], + "primary_color": "Green" + }, + { + "theme": "Dwarf Kindred", + "synergies": [ + "Servo Kindred", + "Berserker Kindred", + "Artificer Kindred", + "Treasure", + "Treasure Token" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Earthbend", + "synergies": [ + "Landfall", + "Ally Kindred", + "Lands Matter", + "+1/+1 Counters", + "Blink" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Echo", + "synergies": [ + "Haste", + "Goblin Kindred", + "Elemental Kindred", + "Blink", + "Enter the Battlefield" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Eerie", + "synergies": [ + "Rooms Matter", + "Enchantments Matter", + "Toughness Matters", + "Human Kindred", + "Little Fellas" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Efreet Kindred", + "synergies": [ + "Flying", + "Burn", + "Interaction", + "Little Fellas" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Egg Kindred", + "synergies": [ + "Defender", + "Sacrifice Matters", + "Aristocrats", + "Toughness Matters", + "Little Fellas" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Elder Kindred", + "synergies": [ + "Dinosaur Kindred", + "Dragon Kindred", + "Historics Matter", + "Legends Matter", + "Flying" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Eldrazi Kindred", + "synergies": [ + "Ingest", + "Processor Kindred", + "Spawn Kindred", + "Scion Kindred", + "Drone Kindred" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Elemental Kindred", + "synergies": [ + "Evoke", + "Awaken", + "Incarnation Kindred", + "Wither", + "Fear" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Elephant Kindred", + "synergies": [ + "Trample", + "Cleric Kindred", + "Soldier Kindred", + "Creature Tokens", + "Blink" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Elf Kindred", + "synergies": [ + "Alliance", + "Druid Kindred", + "Ranger Kindred", + "Archer Kindred", + "Scout Kindred" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Elk Kindred", + "synergies": [ + "Lifegain", + "Life Matters", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Embalm", + "synergies": [ + "Clones", + "Zombie Kindred", + "Reanimate", + "Warrior Kindred", + "Mill" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Emerge", + "synergies": [ + "Eldrazi Kindred", + "Big Mana", + "Toughness Matters" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Employee Kindred", + "synergies": [ + "Open an Attraction", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield", + "Token Creation" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Enchant", + "synergies": [ + "Umbra armor", + "Auras", + "Enchantments Matter", + "Voltron", + "Goad" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Enchantment Tokens", + "synergies": [ + "Tokens Matter", + "Role token", + "Inspired", + "Hero Kindred", + "Equipment Matters" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Enchantments Matter", + "synergies": [ + "Auras", + "Constellation", + "Card Draw", + "Sagas Matter", + "Lore Counters" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Encore", + "synergies": [ + "Pirate Kindred", + "Outlaw Kindred", + "Mill", + "Aggro", + "Combat Matters" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Endure", + "synergies": [ + "Spirit Kindred", + "Creature Tokens", + "Soldier Kindred", + "+1/+1 Counters", + "Token Creation" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Energy", + "synergies": [ + "Resource Engine", + "Energy Counters", + "Servo Kindred", + "Vedalken Kindred", + "Robot Kindred" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Energy Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Energy", + "Resource Engine", + "Servo Kindred" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Enlist", + "synergies": [ + "Toughness Matters", + "Aggro", + "Combat Matters", + "Human Kindred", + "Little Fellas" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Enrage", + "synergies": [ + "Dinosaur Kindred", + "Big Mana", + "Toughness Matters" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Enter the Battlefield", + "synergies": [ + "Blink", + "Reanimate", + "Token Creation", + "Exploit", + "Offspring" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Entwine", + "synergies": [ + "Combat Tricks", + "Spells Matter", + "Spellslinger", + "Removal", + "Interaction" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Eon Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Epic", + "synergies": [ + "Stax", + "Big Mana", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Equip", + "synergies": [ + "Job select", + "For Mirrodin!", + "Living weapon", + "Equipment", + "Germ Kindred" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Equipment", + "synergies": [ + "Voltron", + "Double Strike", + "Warriors Matter", + "Job select", + "Reconfigure" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Equipment Matters", + "synergies": [ + "Equipment", + "Equip", + "Role token", + "Job select", + "Reconfigure" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Escalate", + "synergies": [ + "Interaction", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Escape", + "synergies": [ + "Reanimate", + "Mill", + "+1/+1 Counters", + "Counters Matter", + "Voltron" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Eternalize", + "synergies": [ + "Clones", + "Zombie Kindred", + "Reanimate", + "Mill", + "Human Kindred" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Evoke", + "synergies": [ + "Incarnation Kindred", + "Elemental Kindred", + "Flash", + "Blink", + "Enter the Battlefield" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Evolve", + "synergies": [ + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Toughness Matters", + "Aggro" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Exalted", + "synergies": [ + "Human Kindred", + "Aggro", + "Combat Matters", + "Little Fellas", + "Toughness Matters" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Exert", + "synergies": [ + "Jackal Kindred", + "Warrior Kindred", + "Human Kindred", + "Little Fellas", + "Aggro" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Exhaust", + "synergies": [ + "Vehicles", + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Aggro" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Exile Matters", + "synergies": [ + "Impulse", + "Suspend", + "Foretell", + "Warp", + "Plot" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Experience Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Exploit", + "synergies": [ + "Zombie Kindred", + "Sacrifice Matters", + "Aristocrats", + "Blink", + "Enter the Battlefield" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Explore", + "synergies": [ + "Map Token", + "Card Selection", + "Scout Kindred", + "Pirate Kindred", + "Merfolk Kindred" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Extort", + "synergies": [ + "Pingers", + "Burn", + "Spells Matter", + "Spellslinger", + "Little Fellas" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Eye Kindred", + "synergies": [ + "More Than Meets the Eye", + "Convert", + "Robot Kindred", + "Historics Matter", + "Legends Matter" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Fabricate", + "synergies": [ + "Servo Kindred", + "Artificer Kindred", + "Artifact Tokens", + "+1/+1 Counters", + "Token Creation" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Fade Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Fading", + "Enchantments Matter", + "Interaction" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Fading", + "synergies": [ + "Fade Counters", + "Counters Matter", + "Enchantments Matter", + "Interaction" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Faerie Kindred", + "synergies": [ + "Rogue Kindred", + "Flying", + "Outlaw Kindred", + "Flash", + "Wizard Kindred" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Fateful hour", + "synergies": [ + "Spells Matter", + "Spellslinger" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Fateseal", + "synergies": [], + "primary_color": "Blue" + }, + { + "theme": "Fathomless descent", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Fear", + "synergies": [ + "Horror Kindred", + "Zombie Kindred", + "Elemental Kindred", + "Outlaw Kindred", + "Aggro" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Ferocious", + "synergies": [ + "Big Mana", + "Spells Matter", + "Spellslinger", + "Interaction" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Ferret Kindred", + "synergies": [], + "primary_color": "Green" + }, + { + "theme": "Fight", + "synergies": [ + "Lore Counters", + "Sagas Matter", + "Dinosaur Kindred", + "Ore Counters", + "+1/+1 Counters" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Finality Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Mill", + "Blink", + "Enter the Battlefield" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Firebending", + "synergies": [ + "Mana Dork", + "X Spells", + "Ramp", + "Human Kindred", + "Aggro" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "First strike", + "synergies": [ + "Banding", + "Kithkin Kindred", + "Knight Kindred", + "Partner", + "Minotaur Kindred" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Fish Kindred", + "synergies": [ + "Gift", + "Loot", + "Stax", + "Discard Matters", + "Creature Tokens" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Flagbearer Kindred", + "synergies": [], + "primary_color": "White" + }, + { + "theme": "Flanking", + "synergies": [ + "Knight Kindred", + "Human Kindred", + "Little Fellas" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Flash", + "synergies": [ + "Evoke", + "Combat Tricks", + "Faerie Kindred", + "Wolf Kindred", + "Equip" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Flashback", + "synergies": [ + "Reanimate", + "Mill", + "Spells Matter", + "Spellslinger", + "Clones" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Flood Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Blue" + }, + { + "theme": "Flurry", + "synergies": [ + "Monk Kindred", + "Spells Matter", + "Spellslinger", + "Little Fellas" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Flying", + "synergies": [ + "Phoenix Kindred", + "Archon Kindred", + "Harpy Kindred", + "Kirin Kindred", + "Hippogriff Kindred" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Food", + "synergies": [ + "Food Token", + "Forage", + "Halfling Kindred", + "Squirrel Kindred", + "Artifact Tokens" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Food Token", + "synergies": [ + "Tokens Matter", + "Forage", + "Food", + "Halfling Kindred", + "Squirrel Kindred" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "For Mirrodin!", + "synergies": [ + "Rebel Kindred", + "Equip", + "Equipment", + "Equipment Matters", + "Creature Tokens" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Forage", + "synergies": [ + "Food Token", + "Food", + "Lifegain", + "Life Matters", + "Mill" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Forecast", + "synergies": [ + "Spells Matter", + "Spellslinger" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Forestcycling", + "synergies": [ + "Land Types Matter", + "Cycling", + "Loot", + "Ramp", + "Discard Matters" + ], + "primary_color": "Green" + }, + { + "theme": "Forestwalk", + "synergies": [ + "Dryad Kindred", + "Landwalk", + "Cat Kindred", + "Lands Matter", + "Little Fellas" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Foretell", + "synergies": [ + "Exile Matters", + "Cleric Kindred", + "Spells Matter", + "Spellslinger", + "Control" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Formidable", + "synergies": [ + "Human Kindred", + "Toughness Matters", + "Little Fellas" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Fox Kindred", + "synergies": [ + "Bushido", + "Samurai Kindred", + "Cleric Kindred", + "Lifegain", + "Life Matters" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Fractal Kindred", + "synergies": [ + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Aggro", + "Combat Matters" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Freerunning", + "synergies": [ + "Assassin Kindred", + "Cost Reduction", + "Big Mana", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Frog Kindred", + "synergies": [ + "Reach", + "Beast Kindred", + "Wizard Kindred", + "+1/+1 Counters", + "Blink" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Fungus Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Green" + }, + { + "theme": "Fungus Kindred", + "synergies": [ + "Spore Counters", + "Saproling Kindred", + "Ore Counters", + "Creature Tokens", + "Beast Kindred" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Fuse Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Red" + }, + { + "theme": "Gargoyle Kindred", + "synergies": [ + "Flying", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield", + "Big Mana" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Germ Kindred", + "synergies": [ + "Living weapon", + "Equip", + "Equipment", + "Phyrexian Kindred", + "Equipment Matters" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Giant Kindred", + "synergies": [ + "Monstrosity", + "Berserker Kindred", + "Warrior Kindred", + "Vigilance", + "Trample" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Gift", + "synergies": [ + "Fish Kindred", + "Unconditional Draw", + "Cantrips", + "Token Creation", + "Tokens Matter" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Gith Kindred", + "synergies": [], + "primary_color": "White" + }, + { + "theme": "Glimmer Kindred", + "synergies": [ + "Sacrifice Matters", + "Aristocrats", + "Enchantments Matter", + "Blink", + "Enter the Battlefield" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Gnoll Kindred", + "synergies": [], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Gnome Kindred", + "synergies": [ + "Artifact Tokens", + "Creature Tokens", + "Artifacts Matter", + "Token Creation", + "Tokens Matter" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Goad", + "synergies": [ + "Theft", + "Rogue Kindred", + "Enchant", + "Artifact Tokens", + "Auras" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Goat Kindred", + "synergies": [ + "Beast Kindred", + "+1/+1 Counters", + "Creature Tokens", + "Token Creation", + "Tokens Matter" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Goblin Kindred", + "synergies": [ + "Shaman Kindred", + "Echo", + "Haste", + "Warrior Kindred", + "Mutant Kindred" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "God Kindred", + "synergies": [ + "Indestructible", + "Historics Matter", + "Legends Matter", + "Protection", + "Transform" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Gold Token", + "synergies": [ + "Tokens Matter", + "Artifact Tokens", + "Token Creation", + "Artifacts Matter", + "Aggro" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Golem Kindred", + "synergies": [ + "Artificer Kindred", + "Artifact Tokens", + "Phyrexian Kindred", + "Artifacts Matter", + "Creature Tokens" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Gorgon Kindred", + "synergies": [ + "Deathtouch", + "Removal", + "Toughness Matters", + "Stax", + "Reanimate" + ], + "primary_color": "Black" + }, + { + "theme": "Graft", + "synergies": [ + "Mutant Kindred", + "+1/+1 Counters", + "Counters Matter", + "Blink", + "Enter the Battlefield" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Grandeur", + "synergies": [ + "Historics Matter", + "Legends Matter" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Gravestorm", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Graveyard Matters", + "synergies": [ + "Reanimate", + "Mill", + "Unearth", + "Surveil", + "Craft" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Gremlin Kindred", + "synergies": [ + "Artifacts Matter", + "Little Fellas", + "Aggro", + "Combat Matters" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Griffin Kindred", + "synergies": [ + "Flying", + "Vigilance", + "Toughness Matters", + "Little Fellas", + "Big Mana" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Group Hug", + "synergies": [ + "Politics", + "Card Draw" + ] + }, + { + "theme": "Growth Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Green" + }, + { + "theme": "Guest Kindred", + "synergies": [ + "Blink", + "Enter the Battlefield", + "Leave the Battlefield", + "Toughness Matters", + "Little Fellas" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Hag Kindred", + "synergies": [], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Halfling Kindred", + "synergies": [ + "Peasant Kindred", + "Citizen Kindred", + "Food Token", + "Food", + "Artifact Tokens" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Hamster Kindred", + "synergies": [], + "primary_color": "White" + }, + { + "theme": "Harmonize", + "synergies": [ + "Mill", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Harpy Kindred", + "synergies": [ + "Flying", + "Little Fellas" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Haste", + "synergies": [ + "Hellion Kindred", + "Phoenix Kindred", + "Echo", + "Barbarian Kindred", + "Minotaur Kindred" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Hatching Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Green" + }, + { + "theme": "Hatchling Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Haunt", + "synergies": [ + "Sacrifice Matters", + "Aristocrats", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Healing Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "White" + }, + { + "theme": "Hellbent", + "synergies": [ + "Draw Triggers", + "Wheels", + "Card Draw", + "Burn" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Hellion Kindred", + "synergies": [ + "Haste", + "Trample", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield" + ], + "primary_color": "Red" + }, + { + "theme": "Hero Kindred", + "synergies": [ + "Job select", + "Role token", + "Enchantment Tokens", + "Equip", + "Equipment" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Heroic", + "synergies": [ + "Soldier Kindred", + "Warrior Kindred", + "Human Kindred", + "+1/+1 Counters", + "Wizard Kindred" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Hexproof", + "synergies": [ + "Hexproof from", + "Protection", + "Stax", + "Interaction", + "Beast Kindred" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Hexproof from", + "synergies": [ + "Hexproof", + "Protection", + "Interaction" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Hideaway", + "synergies": [ + "Topdeck", + "Lands Matter" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Hippo Kindred", + "synergies": [], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Hippogriff Kindred", + "synergies": [ + "Flying", + "Little Fellas" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Historics Matter", + "synergies": [ + "Legends Matter", + "Superfriends", + "Backgrounds Matter", + "Choose a background", + "Doctor's companion" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Hit Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black" + }, + { + "theme": "Homarid Kindred", + "synergies": [ + "Little Fellas" + ], + "primary_color": "Blue" + }, + { + "theme": "Homunculus Kindred", + "synergies": [ + "Little Fellas", + "Toughness Matters", + "Card Draw" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Horror Kindred", + "synergies": [ + "Impending", + "Fear", + "Alien Kindred", + "Nightmare Kindred", + "Swampwalk" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Horse Kindred", + "synergies": [ + "Saddle", + "Mount Kindred", + "Historics Matter", + "Legends Matter", + "Blink" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Horsemanship", + "synergies": [ + "Soldier Kindred", + "Human Kindred", + "Historics Matter", + "Legends Matter", + "Warrior Kindred" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Hour Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Human Kindred", + "synergies": [ + "Horsemanship", + "Training", + "Mystic Kindred", + "Daybound", + "Firebending" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Hydra Kindred", + "synergies": [ + "X Spells", + "Trample", + "+1/+1 Counters", + "Reach", + "Counters Matter" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Hyena Kindred", + "synergies": [], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Ice Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Illusion Kindred", + "synergies": [ + "Morph", + "Wall Kindred", + "Defender", + "Flying", + "Draw Triggers" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Imp Kindred", + "synergies": [ + "Phyrexian Kindred", + "Flying", + "Discard Matters", + "Little Fellas", + "Burn" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Impending", + "synergies": [ + "Avatar Kindred", + "Time Counters", + "Horror Kindred", + "Counters Matter", + "Enchantments Matter" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Imprint", + "synergies": [], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Improvise", + "synergies": [ + "Artifacts Matter", + "Big Mana", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Impulse", + "synergies": [ + "Junk Tokens", + "Junk Token", + "Exile Matters", + "Superfriends", + "Treasure" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Incarnation Kindred", + "synergies": [ + "Evoke", + "Elemental Kindred", + "Reanimate", + "Mill", + "Big Mana" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Incubate", + "synergies": [ + "Incubator Token", + "Transform", + "Phyrexian Kindred", + "Artifact Tokens", + "+1/+1 Counters" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Incubator Token", + "synergies": [ + "Tokens Matter", + "Incubate", + "Transform", + "Phyrexian Kindred", + "Artifact Tokens" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Indestructible", + "synergies": [ + "God Kindred", + "Protection", + "Historics Matter", + "Legends Matter", + "Interaction" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Infect", + "synergies": [ + "Poison Counters", + "Proliferate", + "Toxic", + "Corrupted", + "Mite Kindred" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Infection Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Ingest", + "synergies": [ + "Drone Kindred", + "Devoid", + "Eldrazi Kindred", + "Burn", + "Aggro" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Inkling Kindred", + "synergies": [], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Insect Kindred", + "synergies": [ + "Landfall", + "Poison Counters", + "Druid Kindred", + "Horror Kindred", + "Time Counters" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Inspired", + "synergies": [ + "Enchantment Tokens", + "Creature Tokens", + "Token Creation", + "Tokens Matter", + "Toughness Matters" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Interaction", + "synergies": [ + "Removal", + "Combat Tricks", + "Protection", + "Board Wipes", + "Counterspells" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Intimidate", + "synergies": [ + "Zombie Kindred", + "Reanimate", + "Little Fellas", + "Voltron", + "Big Mana" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Investigate", + "synergies": [ + "Clue Token", + "Detective Kindred", + "Sacrifice to Draw", + "Artifact Tokens", + "Cantrips" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Islandcycling", + "synergies": [ + "Landcycling", + "Cycling", + "Loot", + "Ramp", + "Discard Matters" + ], + "primary_color": "Blue" + }, + { + "theme": "Islandwalk", + "synergies": [ + "Landwalk", + "Merfolk Kindred", + "Lands Matter", + "Little Fellas", + "Toughness Matters" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Jackal Kindred", + "synergies": [ + "Exert", + "Zombie Kindred", + "Warrior Kindred", + "Reanimate", + "Little Fellas" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Jellyfish Kindred", + "synergies": [ + "Flying", + "Toughness Matters", + "Little Fellas", + "Blink", + "Enter the Battlefield" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Job select", + "synergies": [ + "Hero Kindred", + "Equip", + "Equipment", + "Equipment Matters", + "Creature Tokens" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Join forces", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Judgment Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "White" + }, + { + "theme": "Juggernaut Kindred", + "synergies": [], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Jump", + "synergies": [ + "Jump-start", + "Mill", + "Card Draw", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Jump-start", + "synergies": [ + "Jump", + "Mill", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Junk Token", + "synergies": [ + "Tokens Matter", + "Junk Tokens", + "Impulse", + "Artifact Tokens", + "Exile Matters" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Junk Tokens", + "synergies": [ + "Tokens Matter", + "Junk Token", + "Impulse", + "Artifact Tokens", + "Exile Matters" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Kavu Kindred", + "synergies": [ + "Kicker", + "+1/+1 Counters", + "Soldier Kindred", + "Lands Matter", + "Counters Matter" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Ki Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Spirit Kindred", + "Historics Matter", + "Legends Matter" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Kicker", + "synergies": [ + "Kavu Kindred", + "Merfolk Kindred", + "+1/+1 Counters", + "Removal", + "Combat Tricks" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Kinship", + "synergies": [ + "Shaman Kindred", + "Topdeck", + "Little Fellas" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Kirin Kindred", + "synergies": [ + "Spirit Kindred", + "Flying", + "Historics Matter", + "Legends Matter", + "Little Fellas" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Kithkin Kindred", + "synergies": [ + "Soldier Kindred", + "First strike", + "Cleric Kindred", + "Knight Kindred", + "Little Fellas" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Knight Kindred", + "synergies": [ + "Flanking", + "Adamant", + "First strike", + "Double strike", + "Kithkin Kindred" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Kobold Kindred", + "synergies": [ + "Toughness Matters", + "Little Fellas", + "Aggro", + "Combat Matters" + ], + "primary_color": "Red" + }, + { + "theme": "Kor Kindred", + "synergies": [ + "Ally Kindred", + "Scout Kindred", + "Cleric Kindred", + "Soldier Kindred", + "Equipment Matters" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Kraken Kindred", + "synergies": [ + "Draw Triggers", + "Wheels", + "Protection", + "Creature Tokens", + "Stax" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Lamia Kindred", + "synergies": [], + "primary_color": "Black" + }, + { + "theme": "Lammasu Kindred", + "synergies": [], + "primary_color": "White" + }, + { + "theme": "Land Types Matter", + "synergies": [ + "Plainscycling", + "Mountaincycling", + "Forestcycling", + "Swampcycling", + "Discover" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Landcycling", + "synergies": [ + "Basic landcycling", + "Islandcycling", + "Cycling", + "Loot", + "Ramp" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Landfall", + "synergies": [ + "Lands Matter", + "Ramp", + "Token Creation", + "Earthbend", + "Quest Counters" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Lands Matter", + "synergies": [ + "Landfall", + "Domain", + "Land Tutors", + "Land Types Matter", + "Landwalk" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Landwalk", + "synergies": [ + "Swampwalk", + "Islandwalk", + "Forestwalk", + "Mountainwalk", + "Wraith Kindred" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Learn", + "synergies": [ + "Discard Matters", + "Unconditional Draw", + "Card Draw", + "Lifegain", + "Life Matters" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Leave the Battlefield", + "synergies": [ + "Blink", + "Enter the Battlefield", + "Exploit", + "Offspring", + "Fabricate" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Leech Kindred", + "synergies": [ + "Cost Reduction", + "Lifegain", + "Life Matters", + "Little Fellas", + "Burn" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Legends Matter", + "synergies": [ + "Historics Matter", + "Superfriends", + "Backgrounds Matter", + "Choose a background", + "Doctor's companion" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Level Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Level Up", + "Wizard Kindred", + "Warrior Kindred" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Level Up", + "synergies": [ + "Level Counters", + "Counters Matter", + "Warrior Kindred", + "Human Kindred", + "Little Fellas" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Leviathan Kindred", + "synergies": [ + "Trample", + "Big Mana", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Lhurgoyf Kindred", + "synergies": [ + "Aggro", + "Combat Matters" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Licid Kindred", + "synergies": [ + "Equipment Matters", + "Auras", + "Artifacts Matter", + "Enchantments Matter", + "Voltron" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Lieutenant", + "synergies": [ + "Flying", + "Aggro", + "Combat Matters", + "Big Mana" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Life Matters", + "synergies": [ + "Lifegain", + "Lifedrain", + "Extort", + "Cleric Kindred", + "Lifelink" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Life to Draw", + "synergies": [ + "Card Draw", + "Enchantments Matter" + ], + "primary_color": "Black" + }, + { + "theme": "Lifegain", + "synergies": [ + "Life Matters", + "Lifedrain", + "Extort", + "Cleric Kindred", + "Lifelink" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Lifegain Triggers", + "synergies": [ + "Vampire Kindred", + "Lifelink", + "Lifegain", + "Life Matters", + "Cleric Kindred" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Lifelink", + "synergies": [ + "Lifegain Triggers", + "Lifegain", + "Life Matters", + "Vampire Kindred", + "Angel Kindred" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Lifeloss", + "synergies": [ + "Lifeloss Triggers", + "Bat Kindred", + "Life Matters", + "Lifegain", + "Flying" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Lifeloss Triggers", + "synergies": [ + "Lifeloss", + "Bat Kindred", + "Life Matters", + "Lifegain", + "Flying" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Little Fellas", + "synergies": [ + "Banding", + "Licid Kindred", + "Spike Kindred", + "Soltari Kindred", + "Training" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Living metal", + "synergies": [ + "Convert", + "Vehicles", + "Historics Matter", + "Legends Matter", + "Artifacts Matter" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Living weapon", + "synergies": [ + "Germ Kindred", + "Equip", + "Equipment", + "Phyrexian Kindred", + "Equipment Matters" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Lizard Kindred", + "synergies": [ + "Menace", + "Shaman Kindred", + "Outlaw Kindred", + "Haste", + "Warrior Kindred" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Loot", + "synergies": [ + "Card Draw", + "Discard Matters", + "Reanimate", + "Cycling", + "Blood Tokens" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Lore Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Read Ahead", + "Sagas Matter", + "Ore Counters" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Loyalty Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Superfriends", + "Planeswalkers", + "Super Friends" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Madness", + "synergies": [ + "Discard Matters", + "Vampire Kindred", + "Reanimate", + "Mill", + "Lifegain" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Magecraft", + "synergies": [ + "Transform", + "Wizard Kindred", + "Human Kindred", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Mana Dork", + "synergies": [ + "Firebending", + "Scion Kindred", + "Spawn Kindred", + "Ramp", + "Myr Kindred" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Mana Rock", + "synergies": [ + "Myr Kindred", + "Charge Counters", + "Ramp", + "Robot Kindred", + "Mana Dork" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Manifest", + "synergies": [ + "Manifest dread", + "Topdeck", + "Equipment Matters", + "Reanimate", + "Mill" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Manifest dread", + "synergies": [ + "Manifest", + "Topdeck", + "Reanimate", + "Mill", + "+1/+1 Counters" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Manticore Kindred", + "synergies": [ + "Burn", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Map Token", + "synergies": [ + "Tokens Matter", + "Explore", + "Card Selection", + "Artifact Tokens", + "Token Creation" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Max speed", + "synergies": [ + "Start your engines!", + "Vehicles", + "Scout Kindred", + "Conditional Draw", + "Burn" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Mayhem", + "synergies": [ + "Discard Matters", + "Mill" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Megamorph", + "synergies": [ + "Dragon Kindred", + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Aggro" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Meld", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Melee", + "synergies": [ + "Aggro", + "Combat Matters", + "Little Fellas" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Menace", + "synergies": [ + "Warlock Kindred", + "Blood Token", + "Pirate Kindred", + "Dog Kindred", + "Werewolf Kindred" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Mentor", + "synergies": [ + "Soldier Kindred", + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Aggro" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Mercenary Kindred", + "synergies": [ + "Outlaw Kindred", + "Bracket:TutorNonland", + "Horror Kindred", + "Phyrexian Kindred", + "Human Kindred" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Merfolk Kindred", + "synergies": [ + "Islandwalk", + "Explore", + "Card Selection", + "Wizard Kindred", + "Landwalk" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Metalcraft", + "synergies": [ + "Transform", + "Artifacts Matter", + "Human Kindred", + "Flying", + "Toughness Matters" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Metathran Kindred", + "synergies": [ + "Little Fellas" + ], + "primary_color": "Blue" + }, + { + "theme": "Mill", + "synergies": [ + "Surveil", + "Threshold", + "Delirium", + "Madness", + "Delve" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Minion Kindred", + "synergies": [ + "Threshold", + "Phyrexian Kindred", + "Human Kindred", + "Reanimate", + "Sacrifice Matters" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Minotaur Kindred", + "synergies": [ + "Berserker Kindred", + "Shaman Kindred", + "Haste", + "Warrior Kindred", + "First strike" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Miracle", + "synergies": [ + "Topdeck", + "Big Mana", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Mite Kindred", + "synergies": [ + "Poison Counters", + "Infect", + "Phyrexian Kindred", + "Artifact Tokens", + "Creature Tokens" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Mobilize", + "synergies": [ + "Warrior Kindred", + "Creature Tokens", + "Token Creation", + "Tokens Matter", + "Toughness Matters" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Modal", + "synergies": [ + "Cost Scaling", + "Spree", + "Control", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Modular", + "synergies": [ + "Sacrifice Matters", + "Aristocrats", + "+1/+1 Counters", + "Artifacts Matter", + "Counters Matter" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Mole Kindred", + "synergies": [ + "Little Fellas" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Monarch", + "synergies": [ + "Politics", + "Group Hug", + "Card Draw", + "Outlaw Kindred", + "Soldier Kindred" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Monger Kindred", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Mongoose Kindred", + "synergies": [], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Monk Kindred", + "synergies": [ + "Flurry", + "Prowess", + "Djinn Kindred", + "Human Kindred", + "Vigilance" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Monkey Kindred", + "synergies": [ + "Little Fellas", + "Aggro", + "Combat Matters" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Monstrosity", + "synergies": [ + "Giant Kindred", + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Aggro" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Moonfolk Kindred", + "synergies": [ + "Wizard Kindred", + "Flying", + "Toughness Matters", + "Artifacts Matter", + "Little Fellas" + ], + "primary_color": "Blue" + }, + { + "theme": "Morbid", + "synergies": [ + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Token Creation", + "Blink" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "More Than Meets the Eye", + "synergies": [ + "Convert", + "Eye Kindred", + "Robot Kindred", + "Historics Matter", + "Legends Matter" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Morph", + "synergies": [ + "Beast Kindred", + "Illusion Kindred", + "Wizard Kindred", + "Cleric Kindred", + "Bird Kindred" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Mount Kindred", + "synergies": [ + "Saddle", + "Pilot Kindred", + "Horse Kindred", + "Vehicles", + "Vigilance" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Mountaincycling", + "synergies": [ + "Land Types Matter", + "Cycling", + "Loot", + "Ramp", + "Discard Matters" + ], + "primary_color": "Red" + }, + { + "theme": "Mountainwalk", + "synergies": [ + "Landwalk", + "Lands Matter", + "Little Fellas" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Mouse Kindred", + "synergies": [ + "Valiant", + "Soldier Kindred", + "Little Fellas", + "Counters Matter", + "Toughness Matters" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Multikicker", + "synergies": [ + "+1/+1 Counters", + "Counters Matter", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Multiple Copies", + "synergies": [ + "Little Fellas" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Mutant Kindred", + "synergies": [ + "Graft", + "Rad Counters", + "Zombie Kindred", + "Goblin Kindred", + "+1/+1 Counters" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Mutate", + "synergies": [ + "Beast Kindred", + "Flying", + "Toughness Matters", + "Big Mana", + "Aggro" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Myr Kindred", + "synergies": [ + "Mana Rock", + "Mana Dork", + "Ramp", + "Artifacts Matter", + "Little Fellas" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Myriad", + "synergies": [ + "Clones", + "Planeswalkers", + "Super Friends", + "Aggro", + "Combat Matters" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Mystic Kindred", + "synergies": [ + "Human Kindred", + "Little Fellas" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Nautilus Kindred", + "synergies": [], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Necron Kindred", + "synergies": [ + "Unearth", + "Artifacts Matter", + "Wizard Kindred", + "Mill", + "Blink" + ], + "primary_color": "Black" + }, + { + "theme": "Net Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Blue" + }, + { + "theme": "Nightbound", + "synergies": [ + "Werewolf Kindred", + "Control", + "Stax", + "Aggro", + "Combat Matters" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Nightmare Kindred", + "synergies": [ + "Horror Kindred", + "Beast Kindred", + "Draw Triggers", + "Blink", + "Enter the Battlefield" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Nightstalker Kindred", + "synergies": [ + "Little Fellas", + "Big Mana" + ], + "primary_color": "Black" + }, + { + "theme": "Ninja Kindred", + "synergies": [ + "Ninjutsu", + "Rat Kindred", + "Burn", + "Human Kindred", + "Big Mana" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Ninjutsu", + "synergies": [ + "Ninja Kindred", + "Rat Kindred", + "Burn", + "Big Mana", + "Human Kindred" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Noble Kindred", + "synergies": [ + "Vampire Kindred", + "Historics Matter", + "Legends Matter", + "Lifelink", + "Elf Kindred" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Nomad Kindred", + "synergies": [ + "Threshold", + "Human Kindred", + "Reanimate", + "Little Fellas", + "Mill" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Nymph Kindred", + "synergies": [ + "Constellation", + "Bestow", + "Equipment Matters", + "Enchantments Matter", + "Auras" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Octopus Kindred", + "synergies": [ + "Rogue Kindred", + "Loot", + "Outlaw Kindred", + "Wizard Kindred", + "Discard Matters" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Offering", + "synergies": [ + "Spirit Kindred", + "Historics Matter", + "Legends Matter", + "Big Mana", + "Spells Matter" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Offspring", + "synergies": [ + "Pingers", + "Outlaw Kindred", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Ogre Kindred", + "synergies": [ + "Demon Kindred", + "Warrior Kindred", + "Shaman Kindred", + "Rogue Kindred", + "Outlaw Kindred" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Oil Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Phyrexian Kindred", + "Artifacts Matter", + "Warrior Kindred" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Omen Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Ooze Kindred", + "synergies": [ + "Clones", + "+1/+1 Counters", + "Counters Matter", + "Creature Tokens", + "Voltron" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Open an Attraction", + "synergies": [ + "Employee Kindred", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield", + "Little Fellas" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Orb Kindred", + "synergies": [], + "primary_color": "Blue" + }, + { + "theme": "Orc Kindred", + "synergies": [ + "Army Kindred", + "Amass", + "Dash", + "Pirate Kindred", + "Treasure" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Ore Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Lore Counters", + "Spore Counters", + "Read Ahead" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Orgg Kindred", + "synergies": [], + "primary_color": "Red" + }, + { + "theme": "Otter Kindred", + "synergies": [ + "Wizard Kindred", + "Artifacts Matter", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Ouphe Kindred", + "synergies": [ + "Stax", + "Little Fellas" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Outlast", + "synergies": [ + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Toughness Matters", + "Human Kindred" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Outlaw Kindred", + "synergies": [ + "Warlock Kindred", + "Pirate Kindred", + "Rogue Kindred", + "Assassin Kindred", + "Mercenary Kindred" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Overload", + "synergies": [ + "Combat Tricks", + "Removal", + "Spells Matter", + "Spellslinger", + "Interaction" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Ox Kindred", + "synergies": [ + "Token Creation", + "Tokens Matter", + "Toughness Matters", + "Artifacts Matter", + "Aggro" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Oyster Kindred", + "synergies": [], + "primary_color": "Blue" + }, + { + "theme": "Pack tactics", + "synergies": [ + "Aggro", + "Combat Matters" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Pangolin Kindred", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Paradox", + "synergies": [ + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Parley", + "synergies": [ + "Draw Triggers", + "Wheels", + "Card Draw" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Partner", + "synergies": [ + "Partner with", + "Performer Kindred", + "Historics Matter", + "Legends Matter", + "Pirate Kindred" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Partner with", + "synergies": [ + "Partner", + "Historics Matter", + "Legends Matter", + "Blink", + "Enter the Battlefield" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Peasant Kindred", + "synergies": [ + "Halfling Kindred", + "Food Token", + "Food", + "Ally Kindred", + "Transform" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Pegasus Kindred", + "synergies": [ + "Flying", + "Little Fellas", + "Toughness Matters" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Performer Kindred", + "synergies": [ + "Partner", + "Historics Matter", + "Legends Matter", + "Blink", + "Enter the Battlefield" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Persist", + "synergies": [ + "-1/-1 Counters", + "Sacrifice Matters", + "Aristocrats", + "Blink", + "Enter the Battlefield" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Pest Kindred", + "synergies": [ + "Sacrifice Matters", + "Aristocrats", + "Creature Tokens", + "Token Creation", + "Tokens Matter" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Phasing", + "synergies": [ + "Flying", + "Little Fellas" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Phoenix Kindred", + "synergies": [ + "Haste", + "Flying", + "Mill", + "Blink", + "Enter the Battlefield" + ], + "primary_color": "Red" + }, + { + "theme": "Phyrexian Kindred", + "synergies": [ + "Germ Kindred", + "Carrier Kindred", + "Living weapon", + "Toxic", + "Incubator Token" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Pillowfort", + "synergies": [] + }, + { + "theme": "Pilot Kindred", + "synergies": [ + "Vehicles", + "Mount Kindred", + "Artifacts Matter", + "Creature Tokens", + "Token Creation" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Pingers", + "synergies": [ + "Extort", + "Devil Kindred", + "Offspring", + "Role token", + "Board Wipes" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Pirate Kindred", + "synergies": [ + "Siren Kindred", + "Raid", + "Encore", + "Outlaw Kindred", + "Explore" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Plague Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black" + }, + { + "theme": "Plainscycling", + "synergies": [ + "Land Types Matter", + "Cycling", + "Loot", + "Ramp", + "Discard Matters" + ], + "primary_color": "White" + }, + { + "theme": "Plainswalk", + "synergies": [], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Planeswalkers", + "synergies": [ + "Proliferate", + "Superfriends", + "Super Friends", + "Myriad", + "Loyalty Counters" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Plant Kindred", + "synergies": [ + "Defender", + "Wall Kindred", + "Landfall", + "Reach", + "Mana Dork" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Plot", + "synergies": [ + "Exile Matters", + "Rogue Kindred", + "Outlaw Kindred", + "Unconditional Draw", + "Card Draw" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Poison Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Toxic", + "Corrupted", + "Mite Kindred" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Politics", + "synergies": [] + }, + { + "theme": "Populate", + "synergies": [ + "Clones", + "Creature Tokens", + "Token Creation", + "Tokens Matter", + "Enchantments Matter" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Porcupine Kindred", + "synergies": [], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Possum Kindred", + "synergies": [], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Powerstone Token", + "synergies": [ + "Tokens Matter", + "Artifact Tokens", + "Artificer Kindred", + "Mana Dork", + "Ramp" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Praetor Kindred", + "synergies": [ + "Phyrexian Kindred", + "Transform", + "Historics Matter", + "Legends Matter", + "Big Mana" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Primarch Kindred", + "synergies": [], + "primary_color": "Black" + }, + { + "theme": "Processor Kindred", + "synergies": [ + "Devoid", + "Eldrazi Kindred", + "Exile Matters" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Proliferate", + "synergies": [ + "Counters Matter", + "+1/+1 Counters", + "Planeswalkers", + "Infect", + "-1/-1 Counters" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Protection", + "synergies": [ + "Ward", + "Hexproof", + "Indestructible", + "Shroud", + "Divinity Counters" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Prototype", + "synergies": [ + "Construct Kindred", + "Artifacts Matter", + "Big Mana", + "Blink", + "Enter the Battlefield" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Provoke", + "synergies": [ + "Aggro", + "Combat Matters", + "Big Mana" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Prowess", + "synergies": [ + "Spellslinger", + "Noncreature Spells", + "Monk Kindred", + "Djinn Kindred", + "Artifacts Matter" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Prowl", + "synergies": [ + "Rogue Kindred", + "Outlaw Kindred", + "Aggro", + "Combat Matters", + "Spells Matter" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Quest Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Landfall", + "Enchantments Matter", + "Lands Matter" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Rabbit Kindred", + "synergies": [ + "Warrior Kindred", + "Creature Tokens", + "Lands Matter", + "Token Creation", + "Tokens Matter" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Raccoon Kindred", + "synergies": [ + "Warrior Kindred", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield", + "Aggro" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Rad Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Mutant Kindred", + "Zombie Kindred", + "Mill" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Radiance", + "synergies": [ + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Raid", + "synergies": [ + "Pirate Kindred", + "Outlaw Kindred", + "Draw Triggers", + "Wheels", + "Warrior Kindred" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Rally", + "synergies": [ + "Ally Kindred", + "Little Fellas" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Ramp", + "synergies": [ + "Treasure Token", + "Land Tutors", + "Mana Dork", + "Mana Rock", + "Landcycling" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Rampage", + "synergies": [ + "Big Mana" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Ranger Kindred", + "synergies": [ + "Elf Kindred", + "Scout Kindred", + "Reach", + "Ramp", + "Lands Matter" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Rat Kindred", + "synergies": [ + "Ninjutsu", + "Ninja Kindred", + "Threshold", + "Warlock Kindred", + "Poison Counters" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Ravenous", + "synergies": [ + "Tyranid Kindred", + "X Spells", + "+1/+1 Counters", + "Counters Matter", + "Voltron" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Reach", + "synergies": [ + "Spider Kindred", + "Archer Kindred", + "Plant Kindred", + "Ranger Kindred", + "Frog Kindred" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Read Ahead", + "synergies": [ + "Lore Counters", + "Sagas Matter", + "Ore Counters", + "Counters Matter", + "Creature Tokens" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Reanimate", + "synergies": [ + "Mill", + "Graveyard Matters", + "Enter the Battlefield", + "Zombie Kindred", + "Flashback" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Reanimator", + "synergies": [ + "Graveyard Matters", + "Reanimate" + ] + }, + { + "theme": "Rebel Kindred", + "synergies": [ + "For Mirrodin!", + "Equip", + "Equipment", + "Bracket:TutorNonland", + "Equipment Matters" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Rebound", + "synergies": [ + "Exile Matters", + "Spells Matter", + "Spellslinger", + "Interaction", + "Big Mana" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Reconfigure", + "synergies": [ + "Equipment", + "Equipment Matters", + "Artifacts Matter", + "Voltron", + "Aggro" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Recover", + "synergies": [ + "Reanimate", + "Mill", + "Interaction", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Reflection Kindred", + "synergies": [], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Reinforce", + "synergies": [ + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Aggro", + "Combat Matters" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Removal", + "synergies": [ + "Soulshift", + "Interaction", + "Control", + "Gift", + "Replicate" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Renew", + "synergies": [ + "Mill", + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Aggro" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Renown", + "synergies": [ + "+1/+1 Counters", + "Soldier Kindred", + "Counters Matter", + "Burn", + "Voltron" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Replacement Draw", + "synergies": [ + "Card Draw" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Replicate", + "synergies": [ + "Spell Copy", + "Control", + "Stax", + "Removal", + "Spells Matter" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Resource Engine", + "synergies": [ + "Energy", + "Energy Counters", + "Servo Kindred", + "Vedalken Kindred", + "Robot Kindred" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Retrace", + "synergies": [ + "Mill", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Revolt", + "synergies": [ + "Warrior Kindred", + "+1/+1 Counters", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Rhino Kindred", + "synergies": [ + "Trample", + "Soldier Kindred", + "Warrior Kindred", + "Creature Tokens", + "Big Mana" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Rigger Kindred", + "synergies": [], + "primary_color": "Black" + }, + { + "theme": "Riot", + "synergies": [ + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Aggro", + "Combat Matters" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Ripple", + "synergies": [ + "Topdeck" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Robot Kindred", + "synergies": [ + "More Than Meets the Eye", + "Clown Kindred", + "Convert", + "Eye Kindred", + "Warp" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Rogue Kindred", + "synergies": [ + "Prowl", + "Outlaw Kindred", + "Connive", + "Aetherborn Kindred", + "Tiefling Kindred" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Role token", + "synergies": [ + "Tokens Matter", + "Enchantment Tokens", + "Hero Kindred", + "Equipment Matters", + "Auras" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Roll to Visit Your Attractions", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Rooms Matter", + "synergies": [ + "Eerie", + "Enchantments Matter", + "Big Mana", + "Pingers", + "Spirit Kindred" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Sacrifice Matters", + "synergies": [ + "Persist", + "Modular", + "Zubera Kindred", + "Aristocrats", + "Blitz" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Sacrifice to Draw", + "synergies": [ + "Clue Token", + "Investigate", + "Blood Tokens", + "Blood Token", + "Detective Kindred" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Saddle", + "synergies": [ + "Mount Kindred", + "Horse Kindred", + "Aggro", + "Combat Matters", + "+1/+1 Counters" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Sagas Matter", + "synergies": [ + "Lore Counters", + "Read Ahead", + "Ore Counters", + "Doctor Kindred", + "Doctor's companion" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Salamander Kindred", + "synergies": [ + "Little Fellas", + "Mill", + "Counters Matter", + "Aggro", + "Combat Matters" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Samurai Kindred", + "synergies": [ + "Bushido", + "Fox Kindred", + "Equipment Matters", + "Historics Matter", + "Legends Matter" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Sand Kindred", + "synergies": [], + "primary_color": "Green" + }, + { + "theme": "Saproling Kindred", + "synergies": [ + "Spore Counters", + "Fungus Kindred", + "Ore Counters", + "Creature Tokens", + "Token Creation" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Satyr Kindred", + "synergies": [ + "Ramp", + "Lands Matter", + "Sacrifice Matters", + "Aristocrats", + "Little Fellas" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Scarecrow Kindred", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Scavenge", + "synergies": [ + "+1/+1 Counters", + "Mill", + "Counters Matter", + "Voltron", + "Aggro" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Scientist Kindred", + "synergies": [ + "Historics Matter", + "Legends Matter", + "Toughness Matters", + "Human Kindred", + "Little Fellas" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Scion Kindred", + "synergies": [ + "Devoid", + "Eldrazi Kindred", + "Drone Kindred", + "Mana Dork", + "Ramp" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Scorpion Kindred", + "synergies": [ + "Deathtouch", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield", + "Little Fellas" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Scout Kindred", + "synergies": [ + "Explore", + "Card Selection", + "Max speed", + "Start your engines!", + "Ranger Kindred" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Scream Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black" + }, + { + "theme": "Scry", + "synergies": [ + "Topdeck", + "Role token", + "Enchantment Tokens", + "Sphinx Kindred", + "Construct Kindred" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Sculpture Kindred", + "synergies": [], + "primary_color": "White" + }, + { + "theme": "Secret council", + "synergies": [], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Serf Kindred", + "synergies": [], + "primary_color": "Black" + }, + { + "theme": "Serpent Kindred", + "synergies": [ + "Cycling", + "Cost Reduction", + "Stax", + "Loot", + "Big Mana" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Servo Kindred", + "synergies": [ + "Fabricate", + "Artificer Kindred", + "Energy Counters", + "Energy", + "Resource Engine" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Shade Kindred", + "synergies": [ + "Little Fellas", + "Flying", + "Toughness Matters", + "Counters Matter" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Shadow", + "synergies": [ + "Dauthi Kindred", + "Soltari Kindred", + "Thalakos Kindred", + "Soldier Kindred", + "Aggro" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Shaman Kindred", + "synergies": [ + "Kinship", + "Minotaur Kindred", + "Troll Kindred", + "Treefolk Kindred", + "Ogre Kindred" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Shapeshifter Kindred", + "synergies": [ + "Changeling", + "Clones", + "Flash", + "Little Fellas", + "Protection" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Shark Kindred", + "synergies": [ + "Stax", + "Toughness Matters", + "Interaction", + "Big Mana", + "Aggro" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Sheep Kindred", + "synergies": [], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Shield Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Soldier Kindred", + "Lifegain", + "Life Matters" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Shrines Matter", + "synergies": [ + "Historics Matter", + "Legends Matter", + "Enchantments Matter" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Shroud", + "synergies": [ + "Protection", + "Interaction", + "Toughness Matters", + "Big Mana", + "Counters Matter" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Siren Kindred", + "synergies": [ + "Pirate Kindred", + "Outlaw Kindred", + "Flying", + "Artifacts Matter", + "Toughness Matters" + ], + "primary_color": "Blue" + }, + { + "theme": "Skeleton Kindred", + "synergies": [ + "Outlaw Kindred", + "Exile Matters", + "Mill", + "Warrior Kindred", + "Blink" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Skulk", + "synergies": [ + "Little Fellas", + "Aggro", + "Combat Matters" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Skunk Kindred", + "synergies": [], + "primary_color": "Black" + }, + { + "theme": "Slime Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Slith Kindred", + "synergies": [ + "+1/+1 Counters", + "Counters Matter", + "Burn", + "Voltron", + "Aggro" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Sliver Kindred", + "synergies": [ + "Little Fellas", + "Pingers", + "Burn" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Sloth Kindred", + "synergies": [], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Slug Kindred", + "synergies": [ + "Little Fellas" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Snail Kindred", + "synergies": [], + "primary_color": "Black" + }, + { + "theme": "Snake Kindred", + "synergies": [ + "Swampwalk", + "Deathtouch", + "Archer Kindred", + "Poison Counters", + "Shaman Kindred" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Soldier Kindred", + "synergies": [ + "Horsemanship", + "Battalion", + "Mentor", + "Endure", + "Banding" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Soltari Kindred", + "synergies": [ + "Shadow", + "Little Fellas", + "Aggro", + "Combat Matters" + ], + "primary_color": "White" + }, + { + "theme": "Soul Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black" + }, + { + "theme": "Soulbond", + "synergies": [ + "Human Kindred", + "Little Fellas", + "Toughness Matters", + "Big Mana" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Soulshift", + "synergies": [ + "Spirit Kindred", + "Control", + "Removal", + "Mill", + "Interaction" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Spawn Kindred", + "synergies": [ + "Eldrazi Kindred", + "Drone Kindred", + "Devoid", + "Mana Dork", + "Ramp" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Spectacle", + "synergies": [ + "Burn", + "Aggro", + "Combat Matters", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Specter Kindred", + "synergies": [ + "Draw Triggers", + "Wheels", + "Flying", + "Burn", + "Card Draw" + ], + "primary_color": "Black" + }, + { + "theme": "Spell Copy", + "synergies": [ + "Storm", + "Replicate", + "Casualty", + "Demonstrate", + "Conspire" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Spell mastery", + "synergies": [ + "Reanimate", + "Mill", + "Spells Matter", + "Spellslinger", + "Interaction" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Spells Matter", + "synergies": [ + "Spellslinger", + "Cantrips", + "Counterspells", + "Spell Copy", + "Flashback" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Spellshaper Kindred", + "synergies": [ + "Discard Matters", + "Human Kindred", + "Little Fellas", + "Ramp", + "Removal" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Spellslinger", + "synergies": [ + "Spells Matter", + "Prowess", + "Noncreature Spells", + "Cantrips", + "Counterspells" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Sphinx Kindred", + "synergies": [ + "Scry", + "Flying", + "Topdeck", + "Conditional Draw", + "Draw Triggers" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Spider Kindred", + "synergies": [ + "Reach", + "Deathtouch", + "Toughness Matters", + "Creature Tokens", + "+1/+1 Counters" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Spike Kindred", + "synergies": [ + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Aggro", + "Combat Matters" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Spirit Kindred", + "synergies": [ + "Soulshift", + "Ki Counters", + "Endure", + "Afterlife", + "Zubera Kindred" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Splice", + "synergies": [ + "Spells Matter", + "Spellslinger", + "Removal", + "Interaction" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Split second", + "synergies": [ + "Stax", + "Combat Tricks", + "Interaction", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Sponge Kindred", + "synergies": [], + "primary_color": "Blue" + }, + { + "theme": "Spore Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Fungus Kindred", + "Saproling Kindred", + "Ore Counters" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Spree", + "synergies": [ + "Cost Scaling", + "Modal", + "Control", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Squad", + "synergies": [ + "Blink", + "Enter the Battlefield", + "Leave the Battlefield", + "Human Kindred", + "Tokens Matter" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Squid Kindred", + "synergies": [ + "Little Fellas" + ], + "primary_color": "Blue" + }, + { + "theme": "Squirrel Kindred", + "synergies": [ + "Food Token", + "Food", + "Warlock Kindred", + "Tokens Matter", + "Token Creation" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Starfish Kindred", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Start your engines!", + "synergies": [ + "Max speed", + "Vehicles", + "Scout Kindred", + "Conditional Draw", + "Burn" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Stash Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Station", + "synergies": [ + "Charge Counters", + "Flying", + "Artifacts Matter", + "Counters Matter", + "Lands Matter" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Stax", + "synergies": [ + "Taxing Effects", + "Hatebears", + "Split second", + "Detain", + "Epic" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Storage Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Age Counters", + "Lands Matter" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Storm", + "synergies": [ + "Spell Copy", + "Control", + "Stax", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Strive", + "synergies": [ + "Combat Tricks", + "Spells Matter", + "Spellslinger", + "Interaction" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Stun Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Stax", + "Wizard Kindred", + "Blink" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Super Friends", + "synergies": [ + "Planeswalkers", + "Superfriends", + "Proliferate", + "Myriad", + "Loyalty Counters" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Superfriends", + "synergies": [ + "Planeswalkers", + "Proliferate", + "Token Creation", + "Loyalty Counters", + "Super Friends" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Support", + "synergies": [ + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Aggro", + "Combat Matters" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Surge", + "synergies": [ + "Big Mana", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Surrakar Kindred", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Surveil", + "synergies": [ + "Mill", + "Reanimate", + "Graveyard Matters", + "Topdeck", + "Rogue Kindred" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Survival", + "synergies": [ + "Survivor Kindred", + "Human Kindred" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Survivor Kindred", + "synergies": [ + "Survival", + "Human Kindred" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Suspect", + "synergies": [ + "Blink", + "Enter the Battlefield", + "Leave the Battlefield" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Suspend", + "synergies": [ + "Time Travel", + "Time Counters", + "Exile Matters", + "Counters Matter", + "Big Mana" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Swampcycling", + "synergies": [ + "Land Types Matter", + "Cycling", + "Loot", + "Ramp", + "Discard Matters" + ], + "primary_color": "Black" + }, + { + "theme": "Swampwalk", + "synergies": [ + "Wraith Kindred", + "Landwalk", + "Snake Kindred", + "Lands Matter", + "Horror Kindred" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Sweep", + "synergies": [], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Synth Kindred", + "synergies": [], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Tempting offer", + "synergies": [ + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Red", + "secondary_color": "White" + }, + { + "theme": "Tentacle Kindred", + "synergies": [], + "primary_color": "Blue" + }, + { + "theme": "Thalakos Kindred", + "synergies": [ + "Shadow", + "Aggro", + "Combat Matters", + "Little Fellas" + ], + "primary_color": "Blue" + }, + { + "theme": "Theft", + "synergies": [ + "Goad", + "Sacrifice to Draw", + "Sacrifice Matters", + "Treasure Token", + "Aristocrats" + ], + "primary_color": "Red", + "secondary_color": "Blue" + }, + { + "theme": "Thopter Kindred", + "synergies": [ + "Artificer Kindred", + "Artifact Tokens", + "Creature Tokens", + "Token Creation", + "Tokens Matter" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Threshold", + "synergies": [ + "Nomad Kindred", + "Minion Kindred", + "Rat Kindred", + "Reanimate", + "Mill" + ], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Thrull Kindred", + "synergies": [ + "Sacrifice Matters", + "Aristocrats", + "Creature Tokens", + "Token Creation", + "Tokens Matter" + ], + "primary_color": "Black", + "secondary_color": "White" + }, + { + "theme": "Tide Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Blue" + }, + { + "theme": "Tiefling Kindred", + "synergies": [ + "Rogue Kindred", + "Outlaw Kindred", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Time Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Vanishing", + "Time Travel", + "Impending" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Time Travel", + "synergies": [ + "Time Counters", + "Suspend", + "Exile Matters", + "Counters Matter" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Token Creation", + "synergies": [ + "Tokens Matter", + "Creature Tokens", + "Populate", + "Artifact Tokens", + "Treasure" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Token Modification", + "synergies": [ + "Tokens Matter", + "Clones", + "Planeswalkers", + "Super Friends", + "Token Creation" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Tokens Matter", + "synergies": [ + "Token Creation", + "Creature Tokens", + "Populate", + "Artifact Tokens", + "Treasure" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Topdeck", + "synergies": [ + "Scry", + "Surveil", + "Miracle", + "Hideaway", + "Kinship" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Toughness Matters", + "synergies": [ + "Defender", + "Egg Kindred", + "Wall Kindred", + "Atog Kindred", + "Kobold Kindred" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Toxic", + "synergies": [ + "Poison Counters", + "Infect", + "Phyrexian Kindred", + "Counters Matter", + "Artifacts Matter" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Toy Kindred", + "synergies": [ + "Artifacts Matter", + "Little Fellas" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Training", + "synergies": [ + "+1/+1 Counters", + "Human Kindred", + "Counters Matter", + "Voltron", + "Toughness Matters" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Trample", + "synergies": [ + "Rhino Kindred", + "Wurm Kindred", + "Hydra Kindred", + "Hellion Kindred", + "Boar Kindred" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Transform", + "synergies": [ + "Incubator Token", + "Incubate", + "Metalcraft", + "Craft", + "Battles Matter" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Transmute", + "synergies": [ + "Bracket:TutorNonland", + "Toughness Matters", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Treasure", + "synergies": [ + "Treasure Token", + "Artifact Tokens", + "Pirate Kindred", + "Citizen Kindred", + "Token Creation" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Treasure Token", + "synergies": [ + "Sacrifice Matters", + "Artifacts Matter", + "Ramp", + "Treasure", + "Artifact Tokens" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Treefolk Kindred", + "synergies": [ + "Druid Kindred", + "Reach", + "Shaman Kindred", + "Land Types Matter", + "Trample" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Tribute", + "synergies": [ + "+1/+1 Counters", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield", + "Counters Matter" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Trilobite Kindred", + "synergies": [], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Troll Kindred", + "synergies": [ + "Shaman Kindred", + "Trample", + "Warrior Kindred", + "Protection", + "+1/+1 Counters" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Turtle Kindred", + "synergies": [ + "Ward", + "Protection", + "Toughness Matters", + "Stax", + "Interaction" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Tyranid Kindred", + "synergies": [ + "Ravenous", + "X Spells", + "Ramp", + "+1/+1 Counters", + "Counters Matter" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Umbra armor", + "synergies": [ + "Enchant", + "Auras", + "Enchantments Matter", + "Voltron", + "Aggro" + ], + "primary_color": "Green", + "secondary_color": "Blue" + }, + { + "theme": "Unconditional Draw", + "synergies": [ + "Dredge", + "Learn", + "Blitz", + "Cantrips", + "Gift" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Undaunted", + "synergies": [ + "Cost Reduction", + "Big Mana", + "Spells Matter", + "Spellslinger" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Undergrowth", + "synergies": [ + "Reanimate", + "Mill", + "Blink", + "Enter the Battlefield", + "Leave the Battlefield" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "Undying", + "synergies": [ + "Sacrifice Matters", + "Aristocrats", + "+1/+1 Counters", + "Zombie Kindred", + "Counters Matter" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Unearth", + "synergies": [ + "Reanimate", + "Graveyard Matters", + "Necron Kindred", + "Construct Kindred", + "Mill" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Unicorn Kindred", + "synergies": [ + "Lifegain", + "Life Matters", + "Toughness Matters", + "Little Fellas", + "Enchantments Matter" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Unleash", + "synergies": [ + "+1/+1 Counters", + "Counters Matter", + "Voltron", + "Aggro", + "Combat Matters" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "Valiant", + "synergies": [ + "Mouse Kindred" + ], + "primary_color": "White", + "secondary_color": "Red" + }, + { + "theme": "Vampire Kindred", + "synergies": [ + "Blood Tokens", + "Blood Token", + "Lifegain Triggers", + "Madness", + "Noble Kindred" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Vanishing", + "synergies": [ + "Time Counters", + "Counters Matter", + "Enchantments Matter" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Varmint Kindred", + "synergies": [], + "primary_color": "Black", + "secondary_color": "Green" + }, + { + "theme": "Vedalken Kindred", + "synergies": [ + "Artificer Kindred", + "Energy Counters", + "Energy", + "Resource Engine", + "Wizard Kindred" + ], + "primary_color": "Blue" + }, + { + "theme": "Vehicles", + "synergies": [ + "Artifacts Matter", + "Equipment", + "Crew", + "Pilot Kindred", + "Living metal" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Venture into the dungeon", + "synergies": [ + "Historics Matter", + "Legends Matter", + "Aggro", + "Combat Matters", + "Artifacts Matter" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Verse Counters", + "synergies": [ + "Counters Matter", + "Proliferate", + "Enchantments Matter" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Vigilance", + "synergies": [ + "Angel Kindred", + "Mount Kindred", + "Griffin Kindred", + "Crew", + "Cat Kindred" + ], + "primary_color": "White", + "secondary_color": "Green" + }, + { + "theme": "Void", + "synergies": [ + "Warp", + "Exile Matters", + "Card Draw", + "Burn", + "Aggro" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Void Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black" + }, + { + "theme": "Voltron", + "synergies": [ + "Equipment", + "Auras", + "Double Strike", + "+1/+1 Counters", + "Equipment Matters" + ], + "primary_color": "Green", + "secondary_color": "White" + }, + { + "theme": "Wall Kindred", + "synergies": [ + "Defender", + "Plant Kindred", + "Illusion Kindred", + "Toughness Matters", + "Stax" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "Ward", + "synergies": [ + "Turtle Kindred", + "Protection", + "Dragon Kindred", + "Interaction", + "Stax" + ], + "primary_color": "Blue", + "secondary_color": "Green" + }, + { + "theme": "Warlock Kindred", + "synergies": [ + "Outlaw Kindred", + "Squirrel Kindred", + "Rat Kindred", + "Food Token", + "Food" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Warp", + "synergies": [ + "Void", + "Robot Kindred", + "Exile Matters", + "Draw Triggers", + "Wheels" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Warrior Kindred", + "synergies": [ + "Mobilize", + "Exert", + "Astartes Kindred", + "Blitz", + "Jackal Kindred" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Waterbending", + "synergies": [ + "Cost Reduction", + "Card Draw", + "Big Mana" + ], + "primary_color": "Blue", + "secondary_color": "White" + }, + { + "theme": "Weasel Kindred", + "synergies": [], + "primary_color": "White" + }, + { + "theme": "Weird Kindred", + "synergies": [], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "Werewolf Kindred", + "synergies": [ + "Daybound", + "Nightbound", + "Transform", + "Wolf Kindred", + "Eldrazi Kindred" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Whale Kindred", + "synergies": [ + "Flying", + "Big Mana", + "Toughness Matters", + "Aggro", + "Combat Matters" + ], + "primary_color": "Blue" + }, + { + "theme": "Wheels", + "synergies": [ + "Discard Matters", + "Card Draw", + "Spellslinger", + "Draw Triggers", + "Hellbent" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Will of the Planeswalkers", + "synergies": [ + "Spells Matter", + "Spellslinger" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Will of the council", + "synergies": [ + "Spells Matter", + "Spellslinger" + ], + "primary_color": "White", + "secondary_color": "Black" + }, + { + "theme": "Wind Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Green" + }, + { + "theme": "Wish Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Wither", + "synergies": [ + "-1/-1 Counters", + "Elemental Kindred", + "Warrior Kindred", + "Counters Matter", + "Burn" + ], + "primary_color": "Black", + "secondary_color": "Red" + }, + { + "theme": "Wizard Kindred", + "synergies": [ + "Moonfolk Kindred", + "Vedalken Kindred", + "Otter Kindred", + "Magecraft", + "Merfolk Kindred" + ], + "primary_color": "Blue", + "secondary_color": "Black" + }, + { + "theme": "Wizardcycling", + "synergies": [], + "primary_color": "Blue" + }, + { + "theme": "Wolf Kindred", + "synergies": [ + "Werewolf Kindred", + "Flash", + "Creature Tokens", + "Token Creation", + "Tokens Matter" + ], + "primary_color": "Green", + "secondary_color": "Red" + }, + { + "theme": "Wolverine Kindred", + "synergies": [ + "Little Fellas" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Wombat Kindred", + "synergies": [], + "primary_color": "Green" + }, + { + "theme": "Worm Kindred", + "synergies": [ + "Sacrifice Matters", + "Aristocrats", + "Little Fellas", + "Aggro", + "Combat Matters" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Wraith Kindred", + "synergies": [ + "Swampwalk", + "Landwalk", + "Lands Matter", + "Big Mana" + ], + "primary_color": "Black" + }, + { + "theme": "Wurm Kindred", + "synergies": [ + "Trample", + "Phyrexian Kindred", + "Big Mana", + "+1/+1 Counters", + "Aggro" + ], + "primary_color": "Green", + "secondary_color": "Black" + }, + { + "theme": "X Spells", + "synergies": [ + "Ravenous", + "Firebending", + "Hydra Kindred", + "Tyranid Kindred", + "Cost Reduction" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Yeti Kindred", + "synergies": [ + "Big Mana" + ], + "primary_color": "Red", + "secondary_color": "Green" + }, + { + "theme": "Zombie Kindred", + "synergies": [ + "Embalm", + "Eternalize", + "Afflict", + "Exploit", + "Army Kindred" + ], + "primary_color": "Black", + "secondary_color": "Blue" + }, + { + "theme": "Zubera Kindred", + "synergies": [ + "Spirit Kindred", + "Sacrifice Matters", + "Aristocrats", + "Toughness Matters", + "Little Fellas" + ], + "primary_color": "Blue", + "secondary_color": "Red" + }, + { + "theme": "\\+0/\\+1 Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "White", + "secondary_color": "Blue" + }, + { + "theme": "\\+1/\\+0 Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Red", + "secondary_color": "Black" + }, + { + "theme": "\\+2/\\+2 Counters", + "synergies": [ + "Counters Matter", + "Proliferate" + ], + "primary_color": "Black", + "secondary_color": "Green" + } + ], + "frequencies_by_base_color": { + "white": { + "Aggro": 1338, + "Artifacts Matter": 703, + "Combat Matters": 1338, + "Equip": 55, + "Equipment": 57, + "Equipment Matters": 211, + "Voltron": 931, + "Big Mana": 1009, + "Bird Kindred": 163, + "Blink": 737, + "Enter the Battlefield": 737, + "Flying": 685, + "Guest Kindred": 3, + "Leave the Battlefield": 741, + "Life Matters": 1099, + "Lifegain": 1098, + "Little Fellas": 1698, + "Toughness Matters": 908, + "Mill": 394, + "Spells Matter": 1155, + "Spellslinger": 1155, + "Auras": 371, + "Enchantments Matter": 956, + "Cantrips": 88, + "Card Draw": 308, + "Combat Tricks": 215, + "Interaction": 1060, + "Unconditional Draw": 133, + "Cost Reduction": 67, + "Flash": 111, + "Scry": 60, + "Topdeck": 141, + "Waterbending": 1, + "Ally Kindred": 48, + "Avatar Kindred": 24, + "Historics Matter": 353, + "Human Kindred": 1140, + "Legends Matter": 353, + "Vigilance": 258, + "Airbending": 4, + "Counters Matter": 676, + "Creature Tokens": 499, + "Exile Matters": 109, + "Experience Counters": 1, + "Token Creation": 581, + "Tokens Matter": 590, + "Lifelink": 229, + "Beast Kindred": 30, + "Sloth Kindred": 3, + "Lands Matter": 169, + "Gargoyle Kindred": 11, + "Protection": 332, + "Griffin Kindred": 43, + "Cleric Kindred": 368, + "Backgrounds Matter": 11, + "Choose a background": 5, + "Soldier Kindred": 634, + "Warrior Kindred": 155, + "Control": 221, + "Removal": 407, + "Aristocrats": 154, + "Haunt": 4, + "Sacrifice Matters": 154, + "Thrull Kindred": 2, + "Lammasu Kindred": 3, + "Stax": 450, + "+1/+1 Counters": 459, + "Spirit Kindred": 224, + "X Spells": 60, + "Cat Kindred": 133, + "Entwine": 6, + "Bolster": 13, + "Outlast": 7, + "Enchant": 271, + "Bracket:TutorNonland": 58, + "Knight Kindred": 238, + "Battle Cry": 5, + "Burn": 286, + "Survival": 5, + "Survivor Kindred": 5, + "Artifact Tokens": 134, + "Charge Counters": 11, + "Clones": 40, + "Station": 5, + "Vampire Kindred": 36, + "Gnome Kindred": 14, + "Angel Kindred": 219, + "Theft": 11, + "Planeswalkers": 78, + "Super Friends": 78, + "Alien Kindred": 2, + "Emerge": 1, + "Board Wipes": 143, + "Landfall": 19, + "Double strike": 41, + "Eternalize": 4, + "Reanimate": 188, + "Zombie Kindred": 28, + "First strike": 129, + "Scout Kindred": 54, + "Construct Kindred": 15, + "Convoke": 25, + "Vehicles": 65, + "Dwarf Kindred": 45, + "Crew": 19, + "Ramp": 70, + "Elephant Kindred": 31, + "Performer Kindred": 7, + "Support": 7, + "Lifegain Triggers": 35, + "Hero Kindred": 15, + "Stun Counters": 5, + "Take 59 Flights of Stairs": 1, + "Take the Elevator": 1, + "Pilot Kindred": 18, + "Artificer Kindred": 49, + "Energy": 21, + "Energy Counters": 20, + "Resource Engine": 21, + "Servo Kindred": 11, + "Dog Kindred": 35, + "Defender": 59, + "Giant Kindred": 41, + "Wall Kindred": 44, + "Goblin Kindred": 3, + "Revolt": 6, + "Lore Counters": 40, + "Ore Counters": 46, + "Sagas Matter": 56, + "Superfriends": 33, + "Loyalty Counters": 10, + "Strive": 4, + "Exalted": 8, + "Heroic": 14, + "Cycling": 67, + "Discard Matters": 109, + "Loot": 71, + "Haste": 1, + "Trample": 15, + "Partner": 17, + "Dragon Kindred": 27, + "Land Types Matter": 40, + "Phyrexian Kindred": 64, + "Plainscycling": 10, + "Samurai Kindred": 39, + "Kirin Kindred": 7, + "Leech Kindred": 1, + "Wizard Kindred": 80, + "Reach": 8, + "Mount Kindred": 18, + "Monk Kindred": 52, + "Flurry": 3, + "Elf Kindred": 17, + "Partner with": 7, + "Assassin Kindred": 4, + "Outlaw Kindred": 26, + "Warp": 8, + "Buyback": 9, + "Join forces": 1, + "Rogue Kindred": 21, + "Draw Triggers": 33, + "Replacement Draw": 2, + "Wheels": 38, + "Nymph Kindred": 4, + "Coven": 10, + "Peasant Kindred": 19, + "Transform": 70, + "Kithkin Kindred": 53, + "Rebel Kindred": 51, + "Endure": 3, + "Flashback": 16, + "Mana Rock": 16, + "Elder Kindred": 3, + "Faerie Kindred": 8, + "Delirium": 10, + "Encore": 4, + "Fabricate": 4, + "Embalm": 6, + "Split second": 2, + "Devoid": 2, + "Eldrazi Kindred": 8, + "Lieutenant": 4, + "Advisor Kindred": 31, + "Affinity": 8, + "Citizen Kindred": 26, + "Conditional Draw": 57, + "Mercenary Kindred": 13, + "-1/-1 Counters": 27, + "Clue Token": 22, + "Investigate": 20, + "Sacrifice to Draw": 26, + "Infect": 35, + "Poison Counters": 24, + "Toxic": 7, + "Token Modification": 9, + "Multikicker": 3, + "Corrupted": 5, + "Food": 25, + "Food Token": 20, + "Bushido": 20, + "Enlist": 5, + "Archer Kindred": 17, + "Pegasus Kindred": 24, + "Modular": 3, + "Assembly-Worker Kindred": 2, + "Arrow Counters": 1, + "Halfling Kindred": 12, + "Archon Kindred": 15, + "Monarch": 10, + "Constellation": 8, + "Bargain": 2, + "Fox Kindred": 37, + "Kor Kindred": 77, + "Metalcraft": 9, + "Kicker": 18, + "Adamant": 3, + "Oil Counters": 3, + "Orc Kindred": 6, + "Bracket:MassLandDenial": 14, + "Dinosaur Kindred": 29, + "Sliver Kindred": 21, + "Armadillo Kindred": 1, + "Ward": 13, + "Horse Kindred": 11, + "Celebration": 5, + "Mouse Kindred": 13, + "Addendum": 5, + "Rebound": 9, + "Domain": 6, + "Noble Kindred": 23, + "Bard Kindred": 5, + "Clown Kindred": 5, + "Robot Kindred": 25, + "Spell Copy": 10, + "Storm": 3, + "Brand-new Sky": 1, + "Card Selection": 7, + "Explore": 7, + "Eye Kindred": 4, + "Suspend": 16, + "Time Counters": 25, + "Incubator Token": 12, + "Shadow": 11, + "Spider Kindred": 2, + "Atog Kindred": 1, + "Disguise": 7, + "Gold Counters": 1, + "Gold Token": 4, + "Prototype": 3, + "Indestructible": 11, + "Counterspells": 22, + "Plot": 4, + "Morph": 23, + "Vanishing": 6, + "Megamorph": 5, + "Threshold": 19, + "Amplify": 2, + "Spellshaper Kindred": 10, + "Changeling": 9, + "Shapeshifter Kindred": 9, + "Boast": 4, + "Detain": 5, + "Wind Walk": 1, + "Miracle": 6, + "Doctor Kindred": 10, + "Doctor's companion": 8, + "History Teacher": 1, + "Thopter Kindred": 3, + "Ox Kindred": 13, + "Extort": 4, + "Pingers": 19, + "Mite Kindred": 7, + "Radiance": 4, + "Myriad": 5, + "Treasure": 11, + "Treasure Token": 13, + "Ability": 1, + "Attack": 1, + "Item": 1, + "Magic": 1, + "Finality Counters": 2, + "Lure the Unwary": 1, + "Insect Kindred": 6, + "Bat Kindred": 11, + "Enrage": 3, + "Disturb": 10, + "Flanking": 15, + "Banding": 19, + "Unicorn Kindred": 25, + "Druid Kindred": 6, + "Enchantment Tokens": 13, + "Role token": 7, + "Elemental Kindred": 33, + "Elk Kindred": 8, + "Fish Kindred": 2, + "Mentor": 5, + "Golem Kindred": 12, + "Ninja Kindred": 1, + "Ninjutsu": 1, + "Escalate": 3, + "Splice": 5, + "Hippogriff Kindred": 6, + "Backup": 6, + "Shield Counters": 9, + "Blessing Counters": 1, + "Nomad Kindred": 19, + "Channel": 6, + "Battalion": 6, + "Alliance": 3, + "Saddle": 10, + "Rabbit Kindred": 19, + "Fateful hour": 6, + "Reinforce": 5, + "Soulbond": 4, + "Sheep Kindred": 3, + "Weasel Kindred": 1, + "Possum Kindred": 1, + "Assist": 4, + "Horror Kindred": 14, + "Shroud": 1, + "Unity Counters": 1, + "Licid Kindred": 2, + "Camel Kindred": 5, + "Warlock Kindred": 5, + "Lhurgoyf Kindred": 1, + "Devour": 1, + "Goat Kindred": 8, + "Level Counters": 8, + "Level Up": 7, + "Cases Matter": 4, + "Detective Kindred": 17, + "Bestow": 11, + "Omen Counters": 1, + "Healing Tears": 1, + "Retrace": 1, + "Champion": 2, + "Sweep": 2, + "Collection Counters": 1, + "Ogre Kindred": 2, + "Jump": 1, + "Craft": 4, + "Graveyard Matters": 4, + "Magecraft": 3, + "Landwalk": 6, + "Mountainwalk": 2, + "Venture into the dungeon": 10, + "Ranger Kindred": 7, + "Reconfigure": 3, + "Flagbearer Kindred": 3, + "Mana Dork": 8, + "Surveil": 4, + "Age Counters": 15, + "Cumulative upkeep": 13, + "Hideaway": 3, + "Inkling Kindred": 1, + "Crash Landing": 1, + "Impulse": 3, + "Junk Token": 1, + "Junk Tokens": 2, + "Employee Kindred": 4, + "Open an Attraction": 2, + "Renown": 8, + "Boar Kindred": 2, + "Foretell": 12, + "Will of the council": 3, + "Homunculus Kindred": 2, + "Strife Counters": 1, + "Gift": 6, + "Mutate": 4, + "Eerie": 3, + "Rooms Matter": 13, + "Melee": 4, + "Mobilize": 3, + "Job select": 5, + "Hope Counters": 1, + "Evoke": 7, + "Demigod Kindred": 1, + "Chimera Kindred": 1, + "Mold Earth": 1, + "Fade Counters": 2, + "Fading": 2, + "Astartes Kindred": 6, + "Provoke": 3, + "God Kindred": 11, + "Delay Counters": 1, + "Exert": 7, + "Dragonfire Dive": 1, + "Jackal Kindred": 1, + "Freerunning": 1, + "Intervention Counters": 1, + "Toy Kindred": 4, + "Sculpture Kindred": 1, + "Prowess": 5, + "Gae Bolg": 1, + "Bracket:GameChanger": 6, + "Coyote Kindred": 1, + "Aftermath": 1, + "Fear": 1, + "Umbra armor": 4, + "Wurm Kindred": 2, + "Praetor Kindred": 3, + "Incubate": 10, + "Undaunted": 2, + "Escape": 2, + "Awaken": 4, + "Epic": 1, + "Glimmer Kindred": 4, + "Lifeloss": 6, + "Lifeloss Triggers": 6, + "Demonstrate": 1, + "Imprint": 1, + "Populate": 8, + "Judgment Counters": 2, + "Rhino Kindred": 12, + "Ki Counters": 3, + "Swampwalk": 2, + "Hunger Counters": 1, + "Nightmare Kindred": 5, + "Cleave": 1, + "Proliferate": 9, + "Cost Scaling": 5, + "Modal": 5, + "Spree": 5, + "Offspring": 4, + "Valiant": 4, + "Jellyfish Kindred": 1, + "Depletion Counters": 2, + "Storage Counters": 2, + "Madness": 2, + "Healing Counters": 2, + "The Allagan Eye": 1, + "Squad": 5, + "Map Token": 1, + "Spell mastery": 3, + "Meld": 1, + "Gith Kindred": 2, + "Psychic Defense": 1, + "Basic landcycling": 2, + "Landcycling": 2, + "For Mirrodin!": 5, + "Incarnation Kindred": 5, + "Shrines Matter": 4, + "Inspired": 2, + "Myr Kindred": 4, + "Antelope Kindred": 3, + "Plainswalk": 2, + "Powerstone Token": 4, + "Demon Kindred": 3, + "Rites of Banishment": 1, + "Training": 5, + "Horsemanship": 7, + "Snake Kindred": 1, + "Manifest": 6, + "Learn": 4, + "Hare Apparent": 1, + "Multiple Copies": 2, + "Merfolk Kindred": 6, + "Squirrel Kindred": 2, + "Task Counters": 1, + "Echo": 3, + "Rally": 5, + "Slith Kindred": 2, + "Discover": 1, + "Hoofprint Counters": 1, + "Monstrosity": 4, + "Soulshift": 5, + "Science Teacher": 1, + "Scientist Kindred": 2, + "Javelin Counters": 1, + "Credit Counters": 1, + "Protection Fighting Style": 1, + "Tiefling Kindred": 1, + "Connive": 2, + "Ascend": 6, + "Duty Counters": 1, + "Goad": 5, + "Afterlife": 5, + "Treefolk Kindred": 3, + "Valor Counters": 1, + "Battles Matter": 3, + "-1/-0 Counters": 1, + "Ravenous": 1, + "Hamster Kindred": 1, + "Divinity Counters": 2, + "Djinn Kindred": 2, + "Efreet Kindred": 1, + "Persist": 2, + "Kinship": 2, + "-0/-1 Counters": 1, + "Deserter Kindred": 1, + "Hexproof": 2, + "Hexproof from": 1, + "Adapt": 1, + "Centaur Kindred": 5, + "Max speed": 6, + "Start your engines!": 6, + "Council's dilemma": 1, + "Chroma": 2, + "Aegis Counters": 1, + "Read Ahead": 2, + "Quest Counters": 6, + "Machina": 1, + "Reprieve Counters": 1, + "Germ Kindred": 1, + "Living weapon": 1, + "Raid": 3, + "Conspire": 1, + "Cohort": 4, + "Morbid": 1, + "Saproling Kindred": 2, + "Spore Counters": 2, + "Mystic Kindred": 4, + "Incarnation Counters": 1, + "Clash": 5, + "Improvise": 1, + "Grandeur": 1, + "Tribute": 1, + "Carrion Counters": 1, + "Behold": 1, + "Impending": 1, + "First Contact": 1, + "Synth Kindred": 1, + "Forecast": 5, + "Fungus Kindred": 1, + "Will of the Planeswalkers": 1, + "Offering": 1, + "Sphinx Kindred": 1, + "Skeleton Kindred": 2, + "Devotion Counters": 1, + "Unearth": 5, + "Converge": 2, + "Vow Counters": 1, + "Convert": 4, + "More Than Meets the Eye": 2, + "Living metal": 2, + "Study Counters": 1, + "Isolation Counters": 1, + "Coward Kindred": 1, + "Natural Shelter": 1, + "Cura": 1, + "Curaga": 1, + "Cure": 1, + "Egg Kindred": 1, + "Bad Wolf": 1, + "Wolf Kindred": 2, + "Parley": 1, + "\\+0/\\+1 Counters": 3, + "Keen Sight": 1, + "Training Counters": 1, + "Verse Counters": 2, + "Shade Kindred": 1, + "Shaman Kindred": 1, + "The Nuka-Cola Challenge": 1, + "Blood Token": 1, + "Blood Tokens": 1, + "Conjure": 1, + "Zubera Kindred": 1, + "Illusion Kindred": 2, + "Werewolf Kindred": 1, + "Otter Kindred": 1, + "Soltari Kindred": 9, + "Echo Counters": 1, + "Feather Counters": 1, + "Grav-cannon": 1, + "Concealed Position": 1, + "Intimidate": 1, + "Reflection Kindred": 1, + "Story Counters": 1, + "Mutant Kindred": 1, + "Overload": 2, + "Harpy Kindred": 1, + "Recover": 1, + "Ripple": 1, + "Brave Heart": 1, + "Tempest Hawk": 1, + "Tempting offer": 2, + "Collect evidence": 1, + "Enlightened Counters": 1, + "Time Travel": 2, + "Crushing Teeth": 1, + "Currency Counters": 1, + "Trap Counters": 1, + "Companion": 1, + "Praesidium Protectiva": 1, + "Hyena Kindred": 1, + "Cloak": 2, + "Manifest dread": 1, + "Bear Kindred": 1, + "Blessing of Light": 1, + "Aegis of the Emperor": 1, + "Custodes Kindred": 1, + "Berserker Kindred": 1, + "Invitation Counters": 1, + "Look to the Stars": 1, + "Monger Kindred": 1, + "Ice Counters": 1, + "Wild Card": 1, + "Call for Aid": 1, + "Stall for Time": 1, + "Pray for Protection": 1, + "Strike a Deal": 1 + }, + "blue": { + "Blink": 576, + "Enter the Battlefield": 576, + "Guest Kindred": 3, + "Human Kindred": 550, + "Leave the Battlefield": 576, + "Little Fellas": 1444, + "Outlaw Kindred": 218, + "Rogue Kindred": 150, + "Casualty": 5, + "Spell Copy": 80, + "Spells Matter": 1745, + "Spellslinger": 1745, + "Topdeck": 420, + "Bird Kindred": 149, + "Flying": 779, + "Toughness Matters": 917, + "Aggro": 903, + "Aristocrats": 119, + "Auras": 348, + "Combat Matters": 903, + "Enchant": 305, + "Enchantments Matter": 747, + "Sacrifice Matters": 110, + "Theft": 115, + "Voltron": 601, + "Big Mana": 1255, + "Elf Kindred": 11, + "Mill": 578, + "Reanimate": 498, + "Shaman Kindred": 11, + "Insect Kindred": 9, + "Transform": 69, + "Horror Kindred": 49, + "Eye Kindred": 3, + "Manifest": 14, + "Manifest dread": 9, + "Control": 670, + "Counterspells": 350, + "Interaction": 902, + "Stax": 919, + "Fish Kindred": 44, + "Flash": 170, + "Probing Telepathy": 1, + "Protection": 158, + "Ward": 39, + "Threshold": 9, + "Historics Matter": 299, + "Legends Matter": 299, + "Noble Kindred": 13, + "Octopus Kindred": 44, + "Removal": 249, + "Creature Tokens": 194, + "Devoid": 34, + "Eldrazi Kindred": 42, + "Ramp": 88, + "Scion Kindred": 6, + "Token Creation": 273, + "Tokens Matter": 275, + "+1/+1 Counters": 224, + "Counters Matter": 482, + "Drake Kindred": 75, + "Kicker": 29, + "Card Draw": 1054, + "Discard Matters": 327, + "Loot": 247, + "Wizard Kindred": 532, + "Cost Reduction": 144, + "Artifacts Matter": 632, + "Equipment Matters": 91, + "Lands Matter": 198, + "Conditional Draw": 194, + "Defender": 69, + "Draw Triggers": 171, + "Wall Kindred": 41, + "Wheels": 211, + "Artifact Tokens": 107, + "Thopter Kindred": 17, + "Cantrips": 193, + "Unconditional Draw": 451, + "Board Wipes": 56, + "Bracket:MassLandDenial": 8, + "Burn": 229, + "Equipment": 25, + "Reconfigure": 3, + "Charge Counters": 12, + "Illusion Kindred": 104, + "Raid": 8, + "Artificer Kindred": 59, + "Doctor Kindred": 9, + "Doctor's companion": 6, + "Ultimate Sacrifice": 1, + "Drone Kindred": 22, + "Zombie Kindred": 83, + "Turtle Kindred": 21, + "Avatar Kindred": 13, + "Exile Matters": 143, + "Suspend": 24, + "Time Counters": 33, + "Impulse": 11, + "Soldier Kindred": 83, + "Combat Tricks": 132, + "Strive": 4, + "Cleric Kindred": 24, + "Enchantment Tokens": 11, + "Inspired": 5, + "Life Matters": 38, + "Lifegain": 38, + "Beast Kindred": 47, + "Elemental Kindred": 110, + "Energy": 24, + "Energy Counters": 22, + "Resource Engine": 24, + "Vehicles": 45, + "Sacrifice to Draw": 76, + "Servo Kindred": 1, + "Vedalken Kindred": 55, + "Max speed": 4, + "Start your engines!": 4, + "Scry": 140, + "X Spells": 110, + "Shapeshifter Kindred": 58, + "Evoke": 6, + "Leviathan Kindred": 21, + "Whale Kindred": 17, + "Detective Kindred": 20, + "Sphinx Kindred": 61, + "Renew": 3, + "Advisor Kindred": 32, + "Merfolk Kindred": 216, + "Robot Kindred": 20, + "Stun Counters": 46, + "Cleave": 4, + "Spellshaper Kindred": 11, + "Reflection Kindred": 2, + "Storm": 9, + "Time Travel": 3, + "Domain": 6, + "Siren Kindred": 20, + "Backgrounds Matter": 13, + "Choose a background": 7, + "Halfling Kindred": 1, + "Partner": 18, + "Partner with": 9, + "Vigilance": 50, + "Bracket:ExtraTurn": 30, + "Foretell": 13, + "God Kindred": 8, + "Flashback": 28, + "Changeling": 9, + "Frog Kindred": 20, + "Salamander Kindred": 8, + "Encore": 4, + "Pirate Kindred": 68, + "Warrior Kindred": 44, + "Treasure": 13, + "Treasure Token": 15, + "Lore Counters": 25, + "Ore Counters": 30, + "Sagas Matter": 33, + "Age Counters": 27, + "Cumulative upkeep": 20, + "Bracket:TutorNonland": 61, + "Crab Kindred": 35, + "Dragon Kindred": 45, + "Elder Kindred": 4, + "Hexproof": 21, + "Faerie Kindred": 82, + "Mana Dork": 47, + "Morph": 43, + "Pingers": 23, + "Flood Counters": 3, + "Manifestation Counters": 1, + "Clones": 145, + "Cipher": 7, + "Prototype": 4, + "Learn": 4, + "Aura Swap": 1, + "Mutate": 5, + "Monarch": 8, + "Quest Counters": 4, + "Magecraft": 4, + "Giant Kindred": 18, + "Mount Kindred": 2, + "Saddle": 1, + "Metalcraft": 8, + "Addendum": 3, + "Heroic": 10, + "Convoke": 11, + "Angel Kindred": 3, + "Spirit Kindred": 152, + "Nightmare Kindred": 17, + "Role token": 6, + "Infect": 34, + "Poison Counters": 9, + "Equip": 21, + "Affinity": 20, + "Incubate": 4, + "Incubator Token": 4, + "Phyrexian Kindred": 51, + "Project Image": 1, + "Hero Kindred": 5, + "Job select": 4, + "Shark Kindred": 10, + "Oil Counters": 12, + "Alien Kindred": 8, + "Planeswalkers": 72, + "Super Friends": 72, + "Amass": 13, + "Army Kindred": 13, + "Embalm": 5, + "Scout Kindred": 29, + "Cycling": 74, + "Jellyfish Kindred": 21, + "Rat Kindred": 8, + "Performer Kindred": 8, + "Sheep Kindred": 2, + "Disturb": 10, + "Peasant Kindred": 3, + "Griffin Kindred": 3, + "Beeble Kindred": 3, + "Venture into the dungeon": 7, + "Improvise": 8, + "Cloak": 2, + "Collect evidence": 5, + "Trample": 16, + "Megamorph": 9, + "Serpent Kindred": 46, + "Islandwalk": 21, + "Landwalk": 39, + "Adapt": 5, + "Mutant Kindred": 18, + "Ingest": 4, + "Crew": 22, + "Kraken Kindred": 30, + "Horse Kindred": 8, + "Egg Kindred": 2, + "-1/-1 Counters": 39, + "For Mirrodin!": 1, + "Rebel Kindred": 2, + "Rebound": 9, + "Support": 2, + "Mana Rock": 22, + "Overload": 6, + "Haste": 2, + "Homunculus Kindred": 22, + "Rooms Matter": 17, + "Card Selection": 10, + "Explore": 10, + "Map Token": 5, + "Unearth": 6, + "Craft": 6, + "Net Counters": 2, + "Djinn Kindred": 35, + "Phasing": 10, + "Converge": 4, + "Hag Kindred": 2, + "Corrupted": 2, + "Clash": 7, + "Madness": 7, + "Shield Counters": 4, + "Myriad": 2, + "Snake Kindred": 25, + "Assassin Kindred": 7, + "Disguise": 4, + "Landfall": 16, + "Shroud": 8, + "Spell mastery": 4, + "Demigod Kindred": 1, + "Ki Counters": 3, + "Surveil": 52, + "Buyback": 9, + "Cases Matter": 3, + "Clue Token": 30, + "Investigate": 30, + "Knight Kindred": 19, + "Shred Counters": 1, + "Dog Kindred": 7, + "Nautilus Kindred": 3, + "Mayhem": 1, + "Eternalize": 3, + "Level Counters": 9, + "Connive": 11, + "Squid Kindred": 7, + "Jump": 5, + "Jump-start": 5, + "Monstrosity": 4, + "Cat Kindred": 8, + "Atog Kindred": 2, + "Vanishing": 4, + "Gnome Kindred": 4, + "Evolve": 5, + "Kirin Kindred": 1, + "Fade Counters": 3, + "Fading": 3, + "Awaken": 5, + "Undaunted": 1, + "Kavu Kindred": 2, + "Golem Kindred": 5, + "Warp": 7, + "Lhurgoyf Kindred": 1, + "Construct Kindred": 18, + "Open an Attraction": 3, + "Roll to Visit Your Attractions": 1, + "Aftermath": 1, + "Surge": 6, + "Bracket:GameChanger": 14, + "Replicate": 10, + "Splice": 9, + "Proliferate": 23, + "Recover": 1, + "Land Types Matter": 20, + "Polyp Counters": 1, + "\\+0/\\+1 Counters": 1, + "Level Up": 7, + "Ally Kindred": 16, + "Goblin Kindred": 2, + "Orc Kindred": 8, + "Voyage Counters": 1, + "Descend": 5, + "Ninja Kindred": 18, + "Ninjutsu": 12, + "Goad": 9, + "Umbra armor": 4, + "Dinosaur Kindred": 7, + "Emerge": 6, + "Worm Kindred": 2, + "Processor Kindred": 4, + "Bestow": 7, + "Prowess": 29, + "Boar Kindred": 1, + "Cyberman Kindred": 1, + "Graft": 4, + "Islandcycling": 8, + "Landcycling": 10, + "Mentor": 1, + "Otter Kindred": 11, + "Soulbond": 7, + "Depletion Counters": 2, + "Homarid Kindred": 8, + "Mercenary Kindred": 2, + "Skeleton Kindred": 3, + "Dreadnought Kindred": 1, + "Ascend": 7, + "Miracle": 3, + "Sliver Kindred": 16, + "Delve": 10, + "Bargain": 5, + "Warlock Kindred": 8, + "Behold": 1, + "Avoidance": 1, + "Exploit": 8, + "Transmute": 6, + "Plot": 10, + "Wish Counters": 1, + "Scientist Kindred": 7, + "Licid Kindred": 3, + "Token Modification": 3, + "Incubation Counters": 1, + "Entwine": 5, + "Yeti Kindred": 2, + "Shadow": 9, + "Spawn Kindred": 5, + "Trilobite Kindred": 3, + "Freerunning": 2, + "Tiefling Kindred": 2, + "Two-Headed Coin": 1, + "Monk Kindred": 20, + "Pilot Kindred": 7, + "Multikicker": 3, + "Glimmer Kindred": 2, + "Vortex Counters": 1, + "Prowl": 5, + "Eerie": 6, + "Delay Counters": 1, + "Druid Kindred": 3, + "-0/-1 Counters": 1, + "Epic": 1, + "Afflict": 2, + "Citizen Kindred": 8, + "Council's dilemma": 2, + "Offspring": 3, + "Waterbending": 8, + "Zubera Kindred": 2, + "Moonfolk Kindred": 25, + "Skulk": 8, + "Gravestorm": 1, + "Ferocious": 3, + "Cascade": 3, + "Delirium": 6, + "Read Ahead": 2, + "Wurm Kindred": 2, + "Exalted": 2, + "Hippogriff Kindred": 3, + "Assist": 4, + "Neurotraumal Rod": 1, + "Tyranid Kindred": 2, + "Children of the Cult": 1, + "Genestealer's Kiss": 1, + "Infection Counters": 1, + "Powerstone Token": 6, + "Undying": 4, + "Conspire": 1, + "Channel": 8, + "Oyster Kindred": 1, + "Elephant Kindred": 1, + "Retrace": 2, + "Persist": 2, + "Escape": 4, + "Shrines Matter": 3, + "Gold Token": 1, + "Nymph Kindred": 4, + "Forecast": 3, + "Crocodile Kindred": 3, + "Aberrant Tinkering": 1, + "Germ Kindred": 1, + "Samurai Kindred": 1, + "Incarnation Kindred": 3, + "Fetch Counters": 1, + "Efreet Kindred": 4, + "Horsemanship": 7, + "Demon Kindred": 2, + "Discover": 3, + "Tide Counters": 2, + "Camarid Kindred": 1, + "Weird Kindred": 4, + "Ooze Kindred": 2, + "Blizzaga": 1, + "Blizzara": 1, + "Blizzard": 1, + "Ice Counters": 3, + "Lizard Kindred": 5, + "Ceremorphosis": 1, + "First strike": 3, + "Split second": 5, + "Detain": 3, + "Kor Kindred": 2, + "Kinship": 2, + "Fractal Kindred": 2, + "Gift": 4, + "Battles Matter": 4, + "Graveyard Matters": 5, + "Superfriends": 32, + "Loyalty Counters": 7, + "Compleated": 1, + "Replacement Draw": 3, + "Cost Scaling": 5, + "Modal": 5, + "Spree": 5, + "Come Fly With Me": 1, + "Convert": 2, + "More Than Meets the Eye": 1, + "Living metal": 1, + "Praetor Kindred": 3, + "Confounding Clouds": 1, + "Affirmative": 1, + "Negative": 1, + "Experience Counters": 1, + "Exhaust": 6, + "Indestructible": 3, + "Homunculus Servant": 1, + "Kithkin Kindred": 1, + "Flanking": 1, + "Minotaur Kindred": 1, + "Ingenuity Counters": 1, + "Treasure Counters": 1, + "Verse Counters": 3, + "Grandeur": 1, + "Architect of Deception": 1, + "Lieutenant": 2, + "Hatchling Counters": 1, + "Werewolf Kindred": 1, + "Wolf Kindred": 1, + "Spider Kindred": 1, + "Eon Counters": 1, + "Dethrone": 2, + "Lifegain Triggers": 1, + "Lifeloss": 1, + "Lifeloss Triggers": 1, + "Woman Who Walked the Earth": 1, + "Basic landcycling": 2, + "Fateseal": 2, + "Rabbit Kindred": 2, + "Metathran Kindred": 5, + "Hour Counters": 1, + "Join forces": 1, + "Rad Counters": 3, + "Myr Kindred": 4, + "Champion": 3, + "Bard Kindred": 2, + "Employee Kindred": 2, + "Music Counters": 1, + "Divinity Counters": 1, + "Tentacle Kindred": 2, + "Synth Kindred": 2, + "Bigby's Hand": 1, + "Fox Kindred": 1, + "Annihilator": 1, + "Sonic Booster": 1, + "Foreshadow Counters": 1, + "Conjure": 1, + "Paradox": 2, + "Impending": 1, + "Will of the Planeswalkers": 1, + "Offering": 1, + "Chimera Kindred": 4, + "Multiple Copies": 1, + "Persistent Petitioners": 1, + "Reach": 1, + "Bear Kindred": 1, + "Orb Kindred": 1, + "Imprint": 1, + "Will of the council": 2, + "Ape Kindred": 1, + "Page Counters": 1, + "Constellation": 6, + "Blue Magic": 1, + "Ranger Kindred": 3, + "Echo": 1, + "Demonstrate": 1, + "Dwarf Kindred": 1, + "Hagneia": 1, + "Backup": 1, + "Monger Kindred": 1, + "Storage Counters": 2, + "Chroma": 1, + "Leech Kindred": 1, + "Scorpion Kindred": 1, + "Troll Kindred": 1, + "Lifelink": 1, + "Hideaway": 3, + "Benediction of the Omnissiah": 1, + "Squad": 2, + "Starfish Kindred": 2, + "Tribute": 1, + "Psychic Abomination": 1, + "Slith Kindred": 1, + "Slime Counters": 1, + "Elk Kindred": 2, + "Fathomless descent": 1, + "Omen Counters": 1, + "Squirrel Kindred": 1, + "Station": 5, + "Fateful hour": 1, + "Web-slinging": 1, + "Gargoyle Kindred": 2, + "Wizardcycling": 2, + "Parley": 1, + "Scarecrow Kindred": 1, + "Food": 4, + "Food Token": 4, + "Ripple": 1, + "Surrakar Kindred": 2, + "Blood Token": 1, + "Blood Tokens": 1, + "Flurry": 2, + "Plant Kindred": 2, + "Imp Kindred": 1, + "Hourglass Counters": 1, + "Tempting offer": 1, + "Juggernaut Kindred": 1, + "Thalakos Kindred": 7, + "Water Always Wins": 1, + "Knowledge Counters": 1, + "Sponge Kindred": 2, + "Minion Kindred": 1, + "Parallel Universe": 1, + "Rejection Counters": 1, + "Secret council": 1, + "Porcupine Kindred": 1, + "Adamant": 3, + "Sleight of Hand": 1, + "Toy Kindred": 1, + "Toxic": 1, + "Harmonize": 3, + "Possession Counters": 1, + "Astartes Kindred": 1, + "Suppressing Fire": 1, + "Sleep Counters": 1, + "Hexproof from": 1, + "Menace": 1, + "Gust of Wind": 1, + "Coin Counters": 1, + "Archer Kindred": 1, + "Hive Mind": 1, + "Body-print": 1 + }, + "black": { + "Blink": 763, + "Enter the Battlefield": 763, + "Guest Kindred": 6, + "Leave the Battlefield": 763, + "Little Fellas": 1364, + "Mill": 986, + "Open an Attraction": 5, + "Reanimate": 987, + "Roll to Visit Your Attractions": 2, + "Zombie Kindred": 498, + "Alien Kindred": 6, + "Child Kindred": 1, + "Life Matters": 848, + "Lifegain": 845, + "Lifelink": 166, + "Big Mana": 1224, + "Spells Matter": 1379, + "Spellslinger": 1379, + "X Spells": 82, + "Aggro": 1220, + "Aristocrats": 660, + "Combat Matters": 1220, + "First strike": 19, + "Sacrifice Matters": 656, + "Toughness Matters": 543, + "Creature Tokens": 304, + "Demon Kindred": 166, + "Flying": 482, + "Harpy Kindred": 11, + "Token Creation": 420, + "Tokens Matter": 421, + "Combat Tricks": 174, + "Interaction": 878, + "Horror Kindred": 184, + "Basic landcycling": 2, + "Burn": 1021, + "Card Draw": 643, + "Cycling": 48, + "Discard Matters": 230, + "Landcycling": 2, + "Lands Matter": 194, + "Loot": 78, + "Ramp": 60, + "Eldrazi Kindred": 31, + "Emerge": 3, + "Leech Kindred": 13, + "Board Wipes": 133, + "Clones": 16, + "Nightmare Kindred": 43, + "Outlaw Kindred": 373, + "Warlock Kindred": 72, + "Assassin Kindred": 84, + "Human Kindred": 476, + "Nightstalker Kindred": 12, + "Draw Triggers": 280, + "Wheels": 298, + "Stax": 246, + "Trample": 54, + "Specter Kindred": 21, + "Centaur Kindred": 3, + "Protection": 95, + "Warrior Kindred": 168, + "Intimidate": 13, + "Spirit Kindred": 146, + "Artifacts Matter": 438, + "Control": 218, + "Cost Reduction": 69, + "Equipment Matters": 83, + "Shaman Kindred": 61, + "Transform": 76, + "Voltron": 652, + "Auras": 239, + "Enchant": 207, + "Enchantments Matter": 606, + "Pingers": 234, + "Historics Matter": 337, + "Legends Matter": 337, + "Venture into the dungeon": 6, + "Wizard Kindred": 114, + "+1/+1 Counters": 380, + "Counters Matter": 637, + "Deathtouch": 137, + "Dragon Kindred": 30, + "Megamorph": 4, + "Bat Kindred": 39, + "Conditional Draw": 80, + "God Kindred": 12, + "Cleric Kindred": 121, + "Vampire Kindred": 274, + "Rogue Kindred": 180, + "Flash": 53, + "Phyrexian Kindred": 165, + "Shapeshifter Kindred": 11, + "Bracket:GameChanger": 11, + "Topdeck": 169, + "Crocodile Kindred": 12, + "Druid Kindred": 6, + "Renew": 4, + "Artifact Tokens": 136, + "Artificer Kindred": 17, + "Energy": 8, + "Energy Counters": 8, + "Resource Engine": 8, + "Servo Kindred": 8, + "Aetherborn Kindred": 17, + "Unconditional Draw": 159, + "Delve": 13, + "Ally Kindred": 17, + "Lizard Kindred": 13, + "Ogre Kindred": 35, + "Sacrifice to Draw": 86, + "Constellation": 6, + "Removal": 482, + "Mercenary Kindred": 43, + "Heroic": 4, + "Backgrounds Matter": 12, + "Theft": 95, + "Eye Kindred": 9, + "Djinn Kindred": 5, + "Haste": 30, + "Monkey Kindred": 2, + "Dash": 7, + "Orc Kindred": 33, + "Exile Matters": 124, + "Scream Counters": 2, + "Disguise": 4, + "Menace": 134, + "Madness": 29, + "Void": 10, + "Ward": 17, + "Warp": 14, + "Skeleton Kindred": 66, + "Charge Counters": 9, + "Mana Rock": 12, + "Craft": 6, + "Graveyard Matters": 5, + "Fabricate": 5, + "Construct Kindred": 10, + "Insect Kindred": 79, + "-1/-1 Counters": 89, + "Afflict": 4, + "Elder Kindred": 6, + "Angel Kindred": 10, + "Pirate Kindred": 31, + "Corrupted": 7, + "Infect": 59, + "Poison Counters": 48, + "Lord of the Pyrrhian Legions": 1, + "Necron Kindred": 25, + "Beast Kindred": 37, + "Frog Kindred": 8, + "Landwalk": 40, + "Swampwalk": 25, + "Morph": 24, + "Bird Kindred": 33, + "Cantrips": 82, + "Surveil": 41, + "Modular": 1, + "Gorgon Kindred": 18, + "Unearth": 19, + "Oil Counters": 3, + "Archon Kindred": 1, + "Backup": 4, + "Endurant": 1, + "Squad": 3, + "Noble Kindred": 31, + "Starscourge": 1, + "Blood Token": 31, + "Life to Draw": 8, + "Planeswalkers": 58, + "Super Friends": 58, + "Golem Kindred": 5, + "Partner": 17, + "Thrull Kindred": 22, + "\\+1/\\+2 Counters": 1, + "Flashback": 22, + "Knight Kindred": 74, + "Rat Kindred": 97, + "Zubera Kindred": 1, + "Elemental Kindred": 36, + "Superfriends": 26, + "Powerstone Token": 4, + "Devil Kindred": 3, + "Replacement Draw": 3, + "Soldier Kindred": 59, + "Goblin Kindred": 45, + "Prowl": 5, + "Shade Kindred": 32, + "Avatar Kindred": 19, + "Fear": 31, + "Mobilize": 3, + "Bracket:TutorNonland": 88, + "Elf Kindred": 42, + "Azra Kindred": 5, + "Ninja Kindred": 17, + "Ninjutsu": 13, + "Bargain": 5, + "Pilot Kindred": 4, + "Vehicles": 29, + "Food": 31, + "Food Token": 30, + "Scorpion Kindred": 9, + "Beholder Kindred": 4, + "Bestow": 8, + "Eerie": 2, + "Rooms Matter": 14, + "Dwarf Kindred": 4, + "Minion Kindred": 38, + "Daybound": 4, + "Werewolf Kindred": 10, + "Nightbound": 4, + "Dog Kindred": 17, + "Myriad": 2, + "Amass": 19, + "Indestructible": 9, + "Suspect": 5, + "Wurm Kindred": 9, + "\\+2/\\+2 Counters": 2, + "Defender": 27, + "Wall Kindred": 20, + "Faerie Kindred": 30, + "Lhurgoyf Kindred": 4, + "Mana Dork": 28, + "Sliver Kindred": 15, + "Extort": 5, + "Detective Kindred": 6, + "Improvise": 4, + "Devoid": 31, + "Citizen Kindred": 7, + "Raid": 10, + "Entwine": 6, + "Rebel Kindred": 6, + "Toxic": 7, + "Threshold": 25, + "Will of the council": 2, + "Gravestorm": 1, + "Spell Copy": 15, + "Storm": 3, + "Horse Kindred": 9, + "Cat Kindred": 16, + "Land Types Matter": 36, + "Equip": 32, + "Equipment": 35, + "Hero Kindred": 2, + "Job select": 4, + "Buy Information": 1, + "Hire a Mercenary": 1, + "Sell Contraband": 1, + "Treasure": 48, + "Treasure Token": 50, + "Treefolk Kindred": 6, + "Plot": 5, + "Spectacle": 5, + "Reconfigure": 3, + "Partner with": 7, + "Metalcraft": 1, + "Army Kindred": 17, + "Imp Kindred": 36, + "Pest Kindred": 4, + "Giant Kindred": 20, + "Incubate": 8, + "Incubator Token": 8, + "Proliferate": 10, + "Convert": 4, + "More Than Meets the Eye": 2, + "Robot Kindred": 7, + "Living metal": 2, + "Mutant Kindred": 12, + "Rad Counters": 6, + "Kicker": 26, + "Blood Tokens": 18, + "Counterspells": 7, + "Lifegain Triggers": 20, + "Assist": 3, + "Quest Counters": 5, + "Landfall": 16, + "Multikicker": 2, + "Bloodthirst": 4, + "Berserker Kindred": 23, + "Devotion Counters": 1, + "Connive": 7, + "Clash": 5, + "Serpent Kindred": 1, + "Wraith Kindred": 11, + "Spellshaper Kindred": 11, + "Forestwalk": 1, + "Champion": 1, + "Ore Counters": 30, + "Echo": 2, + "Bard Kindred": 1, + "Squirrel Kindred": 11, + "Fungus Kindred": 12, + "Scavenge": 4, + "Scry": 27, + "Escalate": 2, + "Age Counters": 12, + "Storage Counters": 2, + "Archer Kindred": 6, + "Bounty Counters": 2, + "Lore Counters": 27, + "Read Ahead": 2, + "Sagas Matter": 29, + "Transmute": 5, + "Bracket:MassLandDenial": 4, + "Overload": 2, + "Encore": 5, + "Freerunning": 6, + "Buyback": 9, + "Choose a background": 6, + "Tunnel Snakes Rule!": 1, + "Undying": 8, + "Flanking": 4, + "Changeling": 8, + "Horsemanship": 7, + "Council's dilemma": 1, + "Crab Kindred": 3, + "Scion Kindred": 4, + "Crew": 10, + "Wolf Kindred": 3, + "Cases Matter": 2, + "Kor Kindred": 1, + "Fish Kindred": 4, + "Slug Kindred": 5, + "Adamant": 3, + "Mount Kindred": 2, + "Saddle": 1, + "Snake Kindred": 31, + "Behold": 1, + "Nymph Kindred": 3, + "Mutate": 5, + "Hideaway": 2, + "Animate Chains": 1, + "Finality Counters": 10, + "Suspend": 11, + "Time Counters": 14, + "Escape": 10, + "Atomic Transmutation": 1, + "Fathomless descent": 3, + "Wither": 6, + "Goat Kindred": 3, + "Troll Kindred": 3, + "Gift": 4, + "Convoke": 12, + "Enchantment Tokens": 10, + "Role token": 8, + "Loyalty Counters": 7, + "Rebound": 3, + "Ooze Kindred": 8, + "Spawn Kindred": 4, + "Advisor Kindred": 8, + "Licid Kindred": 2, + "Monarch": 9, + "Disturb": 1, + "Soulshift": 9, + "Corpse Counters": 4, + "Strive": 2, + "Haunt": 4, + "Drone Kindred": 13, + "Ingest": 3, + "Spite Counters": 1, + "Minotaur Kindred": 14, + "Bushido": 6, + "Samurai Kindred": 9, + "Undaunted": 1, + "Casualty": 6, + "Hellbent": 11, + "Survival": 1, + "Survivor Kindred": 1, + "Earthbend": 1, + "Dredge": 6, + "Dalek Kindred": 4, + "Exterminate!": 1, + "Spell mastery": 4, + "Chaosbringer": 1, + "Offspring": 4, + "Dauthi Kindred": 11, + "Shadow": 15, + "Jackal Kindred": 5, + "Void Counters": 2, + "Unleash": 4, + "Employee Kindred": 6, + "Card Selection": 10, + "Explore": 10, + "Collect evidence": 3, + "Plot Counters": 1, + "Vanishing": 2, + "Worm Kindred": 7, + "Cyberman Kindred": 1, + "Tiefling Kindred": 6, + "Saproling Kindred": 4, + "Cockatrice Kindred": 1, + "Spore Counters": 1, + "Afterlife": 3, + "Lieutenant": 2, + "Delirium": 15, + "Affinity": 3, + "Despair Counters": 1, + "Peasant Kindred": 6, + "Bear Kindred": 1, + "Verse Counters": 2, + "Satyr Kindred": 2, + "Infection Counters": 2, + "Outlast": 2, + "Conspire": 1, + "Reach": 2, + "Soulbond": 1, + "Spider Kindred": 4, + "Junk Token": 1, + "Skunk Kindred": 1, + "Domain": 7, + "Cohort": 3, + "Ice Counters": 1, + "Boast": 4, + "Incarnation Kindred": 3, + "Cleave": 2, + "Foretell": 9, + "Adapt": 4, + "Eternalize": 1, + "Germ Kindred": 2, + "Living weapon": 2, + "Ascend": 5, + "Ouphe Kindred": 1, + "Exalted": 5, + "Cumulative upkeep": 10, + "Drake Kindred": 6, + "-2/-2 Counters": 1, + "Praetor Kindred": 6, + "\\+1/\\+0 Counters": 1, + "Descend": 4, + "Elephant Kindred": 2, + "Amplify": 3, + "Glimmer Kindred": 2, + "Miracle": 2, + "Station": 4, + "Hexproof": 5, + "Hexproof from": 2, + "Fox Kindred": 1, + "Defense Counters": 1, + "Slith Kindred": 2, + "Salamander Kindred": 3, + "Hatchling Counters": 1, + "Replicate": 1, + "Split second": 5, + "Cyclops Kindred": 3, + "Goad": 5, + "Learn": 3, + "Inkling Kindred": 2, + "Map Token": 1, + "Skulk": 5, + "Revolt": 3, + "Hag Kindred": 1, + "Devour": 3, + "Forage": 1, + "Exploit": 12, + "Flesh Flayer": 1, + "Gremlin Kindred": 2, + "Transfigure": 1, + " Blood Counters": 1, + "Investigate": 8, + "Inspired": 5, + "Clue Token": 7, + "\\+0/\\+2 Counters": 1, + "Recover": 3, + "Max speed": 6, + "Start your engines!": 8, + "Manifest": 7, + "Death Ray": 1, + "Disintegration Ray": 1, + "Vigilance": 1, + "Channel": 3, + "Gold Token": 2, + "Blitz": 4, + "Impulse": 4, + "Illusion Kindred": 2, + "Pangolin Kindred": 2, + "Swampcycling": 7, + "Evolve": 1, + "Shrines Matter": 3, + "Halfling Kindred": 8, + "Lifeloss": 8, + "Lifeloss Triggers": 8, + "Turtle Kindred": 2, + "Prototype": 2, + "Splice": 4, + "Meld": 1, + "Lamia Kindred": 2, + "Scout Kindred": 9, + "Performer Kindred": 2, + "Reverberating Summons": 1, + "-0/-2 Counters": 2, + "Evoke": 5, + "Dinosaur Kindred": 8, + "Merfolk Kindred": 5, + "Morbid": 9, + "Level Counters": 4, + "Level Up": 4, + "Ritual Counters": 1, + "Multi-threat Eliminator": 1, + "Discover": 2, + "Ki Counters": 3, + "Boar Kindred": 3, + "Exhaust": 1, + "Soul Counters": 4, + "Monstrosity": 3, + "Secrets of the Soul": 1, + "Grand Strategist": 1, + "Phaeron": 1, + "Demonstrate": 1, + "Kirin Kindred": 1, + "Manifest dread": 2, + "Cost Scaling": 4, + "Modal": 4, + "Spree": 4, + "Body Thief": 1, + "Devour Intellect": 1, + "Battles Matter": 4, + "Efreet Kindred": 1, + "Jump": 1, + "Rally": 1, + "Rabbit Kindred": 1, + "Endure": 4, + "Grandeur": 1, + "-0/-1 Counters": 3, + "Monk Kindred": 1, + "Hippo Kindred": 1, + "Myr Kindred": 2, + "Persist": 4, + "Enmitic Exterminator": 1, + "Undergrowth": 4, + "Guardian Protocols": 1, + "Mannequin Counters": 1, + "Bad Breath": 1, + "Plant Kindred": 2, + "Manticore Kindred": 1, + "Hit Counters": 2, + "Cipher": 5, + "Hour Counters": 1, + "Processor Kindred": 2, + "Awaken": 3, + "Mold Harvest": 1, + "Nautilus Kindred": 1, + "Rigger Kindred": 1, + "Astartes Kindred": 4, + "Primarch Kindred": 1, + "Primarch of the Death Guard": 1, + "Divinity Counters": 1, + "Psychic Blades": 1, + "Feeding Counters": 1, + "Multiple Copies": 4, + "Nazgûl": 1, + "Atog Kindred": 1, + "Synaptic Disintegrator": 1, + "Relentless March": 1, + "Aftermath": 1, + "Epic": 1, + "Kinship": 2, + "Revival Counters": 1, + "Mutsunokami": 1, + "Weird Insight": 1, + "Weird Kindred": 1, + "Scarecrow Kindred": 3, + "Eon Counters": 1, + "Impending": 1, + "Toy Kindred": 2, + "Converge": 2, + "Fade Counters": 3, + "Fading": 3, + "Will of the Planeswalkers": 1, + "Offering": 1, + "Depletion Counters": 1, + "Carrier Kindred": 5, + "Rot Fly": 1, + "Dynastic Advisor": 1, + "Curse of the Walking Pox": 1, + "Executioner Round": 1, + "Hyperfrag Round": 1, + "Mayhem": 3, + "Magecraft": 2, + "Populate": 1, + "Harbinger of Despair": 1, + "Octopus Kindred": 2, + "Starfish Kindred": 2, + "Kithkin Kindred": 1, + "Rat Colony": 1, + "Retrace": 2, + "Mole Kindred": 1, + "Relentless Rats": 1, + "Decayed": 1, + "Kraken Kindred": 1, + "Blight Counters": 1, + "Phalanx Commander": 1, + "Blood Chalice": 1, + "Conjure": 1, + "Elite Troops": 1, + "Monger Kindred": 1, + "Coward Kindred": 1, + "Serf Kindred": 1, + "Super Nova": 1, + "Shadowborn Apostle": 1, + "C'tan Kindred": 2, + "Drain Life": 1, + "Matter Absorption": 1, + "Spear of the Void Dragon": 1, + "Join forces": 1, + "Surrakar Kindred": 2, + "Tribute": 1, + "Ape Kindred": 2, + "Sweep": 1, + "Hyperphase Threshers": 1, + "Command Protocols": 1, + "Snail Kindred": 1, + "Cascade": 1, + "Jolly Gutpipes": 1, + "Spike Kindred": 1, + "Mite Kindred": 1, + "Blood Drain": 1, + "Ripple": 1, + "My Will Be Done": 1, + "The Seven-fold Chant": 1, + "Bracket:ExtraTurn": 1, + "Tempting offer": 1, + "Prey Counters": 1, + "Firebending": 1, + "Necrodermis Counters": 1, + "Varmint Kindred": 1, + "Consume Anomaly": 1, + "Stash Counters": 1, + "Pegasus Kindred": 1, + "Chef's Knife": 1, + "Stun Counters": 2, + "Plague Counters": 2, + "Prismatic Gallery": 1, + "Dynastic Codes": 1, + "Targeting Relay": 1, + "Demigod Kindred": 1, + "Horrific Symbiosis": 1, + "Chroma": 1, + "Barbarian Kindred": 2, + "Rat Tail": 1, + "Devourer of Souls": 1, + "Spiked Retribution": 1, + "Death Gigas": 1, + "Galian Beast": 1, + "Hellmasker": 1, + "Deal with the Black Guardian": 1, + "Doctor Kindred": 1, + "Doctor's companion": 1, + "Compleated": 1, + "Toxic Spores": 1, + "Wish Counters": 1, + "Camel Kindred": 1, + "Petrification Counters": 1, + "My First Friend": 1, + "Burning Chains": 1 + }, + "red": { + "Burn": 1652, + "Enchantments Matter": 578, + "Blink": 454, + "Enter the Battlefield": 454, + "Goblin Kindred": 393, + "Guest Kindred": 4, + "Leave the Battlefield": 454, + "Little Fellas": 1255, + "Mana Dork": 58, + "Ramp": 98, + "Spells Matter": 1539, + "Spellslinger": 1539, + "Aggro": 1416, + "Combat Matters": 1416, + "Combat Tricks": 159, + "Discard Matters": 302, + "Interaction": 653, + "Madness": 18, + "Mill": 341, + "Reanimate": 262, + "Flashback": 45, + "Artifacts Matter": 699, + "Exile Matters": 253, + "Human Kindred": 557, + "Impulse": 143, + "Monk Kindred": 19, + "Prowess": 20, + "Removal": 211, + "Card Draw": 350, + "Learn": 5, + "Unconditional Draw": 154, + "Intimidate": 5, + "Warrior Kindred": 363, + "Cantrips": 78, + "Draw Triggers": 54, + "Heavy Rock Cutter": 1, + "Tyranid Kindred": 4, + "Wheels": 58, + "+1/+1 Counters": 247, + "Counters Matter": 434, + "Renown": 5, + "Voltron": 537, + "Auras": 196, + "Enchant": 159, + "Goad": 29, + "Rad Counters": 2, + "Big Mana": 1244, + "Stax": 333, + "Theft": 130, + "Lands Matter": 251, + "Control": 154, + "Historics Matter": 310, + "Legends Matter": 310, + "Spirit Kindred": 71, + "Clash": 5, + "Minotaur Kindred": 73, + "Pilot Kindred": 10, + "Vehicles": 36, + "Berserker Kindred": 88, + "Rampage": 4, + "Toughness Matters": 471, + "Beast Kindred": 88, + "Artifact Tokens": 176, + "Artificer Kindred": 51, + "Creature Tokens": 265, + "Energy": 29, + "Energy Counters": 26, + "First strike": 96, + "Resource Engine": 29, + "Servo Kindred": 1, + "Token Creation": 417, + "Tokens Matter": 423, + "Defender": 35, + "Reach": 45, + "Wall Kindred": 29, + "Aetherborn Kindred": 1, + "Revolt": 1, + "Pingers": 345, + "Outlaw Kindred": 164, + "Rogue Kindred": 95, + "Transform": 76, + "Werewolf Kindred": 63, + "Board Wipes": 264, + "Lizard Kindred": 85, + "Offspring": 5, + "Sacrifice to Draw": 37, + "Insect Kindred": 19, + "Exert": 11, + "Haste": 330, + "Aristocrats": 200, + "Sacrifice Matters": 194, + "Zombie Kindred": 16, + "Dog Kindred": 36, + "Morph": 24, + "Scout Kindred": 29, + "Bird Kindred": 15, + "Flying": 236, + "Equipment Matters": 143, + "Samurai Kindred": 20, + "Shaman Kindred": 177, + "Protection": 31, + "Conditional Draw": 42, + "Phyrexian Kindred": 44, + "Ally Kindred": 19, + "Giant Kindred": 88, + "Landfall": 26, + "Phoenix Kindred": 33, + "Cohort": 2, + "Elemental Kindred": 216, + "Dragon Kindred": 187, + "Trample": 189, + "Heroic": 8, + "Soldier Kindred": 93, + "Angel Kindred": 3, + "Life Matters": 92, + "Lifegain": 92, + "Otter Kindred": 7, + "Wizard Kindred": 95, + "Treasure": 109, + "Treasure Token": 111, + "Partner": 17, + "-1/-1 Counters": 26, + "Infect": 7, + "Ore Counters": 33, + "Planeswalkers": 67, + "Super Friends": 67, + "Vampire Kindred": 55, + "X Spells": 135, + "Land Types Matter": 30, + "Backgrounds Matter": 13, + "Choose a background": 7, + "Cleric Kindred": 13, + "Dwarf Kindred": 66, + "Dinosaur Kindred": 60, + "Topdeck": 123, + "Cost Reduction": 80, + "Doctor Kindred": 6, + "Doctor's companion": 6, + "Partner with": 8, + "Suspend": 20, + "Time Counters": 24, + "Demigod Kindred": 1, + "Satyr Kindred": 14, + "Elder Kindred": 2, + "Fade Counters": 1, + "Fading": 1, + "Hydra Kindred": 6, + "Kavu Kindred": 28, + "Jackal Kindred": 13, + "Incarnation Kindred": 3, + "Pirate Kindred": 53, + "Citizen Kindred": 14, + "Bracket:MassLandDenial": 29, + "Spellshaper Kindred": 12, + "Ox Kindred": 7, + "Cat Kindred": 30, + "Modular": 3, + "Riot": 5, + "Menace": 90, + "Verse Counters": 3, + "Orc Kindred": 48, + "Boast": 7, + "Raid": 16, + "Blood Token": 32, + "Blood Tokens": 13, + "Loot": 78, + "Counterspells": 9, + "Unearth": 11, + "Magecraft": 2, + "Flash": 30, + "Astartes Kindred": 5, + "Demon Kindred": 15, + "Ruinous Ascension": 1, + "Amass": 11, + "Army Kindred": 10, + "Robot Kindred": 21, + "Wolf Kindred": 19, + "Efreet Kindred": 13, + "Megamorph": 5, + "Formidable": 5, + "Ogre Kindred": 72, + "Atog Kindred": 2, + "Casualty": 3, + "Spell Copy": 68, + "Advisor Kindred": 6, + "Devil Kindred": 46, + "Cascade": 15, + "Rebel Kindred": 13, + "Echo": 23, + "Nomad Kindred": 6, + "Avatar Kindred": 9, + "Oil Counters": 13, + "Azra Kindred": 1, + "Elf Kindred": 3, + "Barbarian Kindred": 34, + "Enlist": 4, + "Kor Kindred": 1, + "\\+1/\\+0 Counters": 4, + "Daybound": 12, + "Nightbound": 12, + "Horsemanship": 6, + "Landwalk": 27, + "Threshold": 12, + "Equip": 52, + "Equipment": 58, + "For Mirrodin!": 5, + "Entwine": 6, + "Sliver Kindred": 20, + "Gremlin Kindred": 12, + "Mentor": 4, + "Ferocious": 6, + "Devoid": 25, + "Eldrazi Kindred": 26, + "Sweep": 1, + "Gargoyle Kindred": 2, + "Goat Kindred": 7, + "Pack tactics": 4, + "Basic landcycling": 2, + "Cycling": 58, + "Landcycling": 2, + "Bushido": 8, + "Enchantment Tokens": 11, + "Role token": 8, + "Mountaincycling": 9, + "Horror Kindred": 13, + "Celebration": 5, + "Wurm Kindred": 4, + "Scorching Ray": 1, + "God Kindred": 9, + "Metalcraft": 6, + "Hellbent": 7, + "Ki Counters": 3, + "Changeling": 5, + "Boar Kindred": 14, + "Double strike": 32, + "Offering": 2, + "Flanking": 6, + "Knight Kindred": 54, + "Blow Up": 1, + "Strive": 4, + "Construct Kindred": 13, + "Prototype": 4, + "Fight": 16, + "Bloodthirst": 8, + "Crown of Madness": 1, + "Delirium": 12, + "Devastating Charge": 1, + "Unleash": 5, + "Ooze Kindred": 4, + "Wolverine Kindred": 7, + "Cyclops Kindred": 24, + "Gift": 4, + "Death Counters": 1, + "Plainswalk": 1, + "Scarecrow Kindred": 1, + "Faerie Kindred": 2, + "Assassin Kindred": 12, + "Awaken": 1, + "Coward Kindred": 4, + "Disguise": 6, + "Scry": 31, + "Fuse Counters": 4, + "Battalion": 5, + "Miracle": 3, + "Lore Counters": 29, + "Sagas Matter": 31, + "Crew": 13, + "Exhaust": 7, + "Escalate": 3, + "Golem Kindred": 12, + "Improvise": 5, + "Surge": 5, + "Ranger Kindred": 1, + "Age Counters": 10, + "Cumulative upkeep": 7, + "Shark Kindred": 3, + "Mouse Kindred": 9, + "Indestructible": 6, + "Discover": 9, + "Card Selection": 2, + "Explore": 1, + "Raccoon Kindred": 10, + "Kicker": 27, + "Thopter Kindred": 8, + "Reinforce": 1, + "Level Counters": 3, + "Level Up": 3, + "Mercenary Kindred": 16, + "Plot": 9, + "Morbid": 4, + "Reconfigure": 6, + "Spawn Kindred": 5, + "Clones": 40, + "Conspire": 1, + "Convoke": 8, + "Zubera Kindred": 2, + "Max speed": 6, + "Start your engines!": 8, + "Orgg Kindred": 4, + "Proliferate": 2, + "Horse Kindred": 6, + "Mount Kindred": 9, + "Saddle": 5, + "Devour": 5, + "Hellion Kindred": 17, + "Shield Counters": 1, + "Drake Kindred": 7, + "Mountainwalk": 14, + "Mana Rock": 18, + "Employee Kindred": 6, + "Cases Matter": 2, + "Cost Scaling": 4, + "Modal": 4, + "Spree": 4, + "Suspect": 4, + "Rev Counters": 1, + "Luck Counters": 1, + "Superfriends": 39, + "Loyalty Counters": 6, + "Bracket:TutorNonland": 24, + "Champion": 3, + "Shapeshifter Kindred": 5, + "Harmonize": 3, + "Imp Kindred": 2, + "Lord of Chaos": 1, + "Fury Counters": 1, + "Peasant Kindred": 6, + "Rat Kindred": 8, + "Rooms Matter": 11, + "Rally": 3, + "Affinity": 11, + "Salamander Kindred": 4, + "Clown Kindred": 8, + "Radiance": 4, + "Noble Kindred": 13, + "Monkey Kindred": 6, + "Toy Kindred": 3, + "Mutate": 3, + "Encore": 4, + "Domain": 6, + "Multikicker": 4, + "Manticore Kindred": 9, + "Treefolk Kindred": 1, + "Licid Kindred": 2, + "Flurry": 3, + "Monarch": 6, + "Time Travel": 2, + "Storm": 14, + "Backup": 7, + "Yeti Kindred": 9, + "Demonstrate": 2, + "Provoke": 2, + "Bard Kindred": 10, + "Junk Token": 7, + "Junk Tokens": 7, + "Kobold Kindred": 12, + "Foretell": 9, + "Coyote Kindred": 1, + "Gold Token": 2, + "Hero Kindred": 6, + "Gift of Chaos": 1, + "Warlock Kindred": 9, + "Beholder Kindred": 1, + "Monstrosity": 7, + "Dash": 12, + "Charge Counters": 17, + "Station": 4, + "Retrace": 5, + "Bracket:GameChanger": 4, + "Melee": 2, + "Descent Counters": 1, + "Desertwalk": 1, + "Splice": 7, + "Bestow": 6, + "Collect evidence": 2, + "Populate": 2, + "Lhurgoyf Kindred": 3, + "Performer Kindred": 6, + "Alliance": 4, + "Gnome Kindred": 3, + "Craft": 6, + "Graveyard Matters": 5, + "Jump": 5, + "Jump-start": 4, + "Undaunted": 1, + "Soulbond": 5, + "Egg Kindred": 4, + "Elk Kindred": 1, + "Dragon's Approach": 1, + "Multiple Copies": 2, + "Surveil": 2, + "Hunters for Hire": 1, + "Quest Counters": 5, + "\\+0/\\+1 Counters": 1, + "\\+2/\\+2 Counters": 1, + "Ward": 3, + "Storage Counters": 2, + "Overload": 8, + "Eternalize": 1, + "Drone Kindred": 10, + "Mayhem": 3, + "Trilobite Kindred": 1, + "Myriad": 6, + "Tiefling Kindred": 4, + "Adamant": 3, + "Valiant": 3, + "Djinn Kindred": 7, + "Glimmer Kindred": 1, + "Dethrone": 4, + "Escape": 5, + "Powerstone Token": 5, + "Bio-plasmic Barrage": 1, + "Ravenous": 1, + "Cloak": 1, + "Spell mastery": 3, + "Druid Kindred": 2, + "Rebound": 5, + "Archer Kindred": 15, + "Poison Counters": 3, + "Buyback": 7, + "Evoke": 6, + "Nightmare Kindred": 8, + "Inspired": 3, + "Detective Kindred": 6, + "Ape Kindred": 7, + "Manifest": 4, + "Chroma": 3, + "Bracket:ExtraTurn": 3, + "Enthralling Performance": 1, + "Fira": 1, + "Firaga": 1, + "Fire": 1, + "Firebending": 5, + "Snake Kindred": 1, + "Blaze Counters": 2, + "Flame Counters": 1, + "Tribute": 4, + "Skeleton Kindred": 2, + "Mutant Kindred": 9, + "Paradox": 4, + "Undying": 6, + "Food": 2, + "Food Token": 2, + "Constellation": 1, + "Nymph Kindred": 3, + "Enrage": 5, + "Frog Kindred": 1, + "Myr Kindred": 2, + "Afflict": 4, + "Warp": 11, + "Incubate": 3, + "Incubator Token": 3, + "Persist": 2, + "Finality Counters": 1, + "Channel": 7, + "Stash Counters": 2, + "Gnoll Kindred": 1, + "Shrines Matter": 3, + "Open an Attraction": 2, + "Exalted": 1, + "Islandwalk": 1, + "Battle Cry": 5, + "Troll Kindred": 3, + "Meld": 1, + "Aim Counters": 1, + "Wither": 6, + "Embalm": 1, + "Pressure Counters": 1, + "Locus of Slaanesh": 1, + "Emerge": 1, + "Annihilator": 1, + "Slivercycling": 1, + "Hyena Kindred": 2, + "Recover": 1, + "Doom Counters": 2, + "Aftermath": 2, + "Exploit": 1, + "Eerie": 1, + "Clue Token": 3, + "Investigate": 3, + "Vicious Mockery": 1, + "Imprint": 1, + "Battles Matter": 5, + "Alien Kindred": 3, + "Blitz": 8, + "Converge": 2, + "Void": 3, + "Symphony of Pain": 1, + "Vanishing": 2, + "Berzerker": 1, + "Sigil of Corruption": 1, + "The Betrayer": 1, + "Venture into the dungeon": 2, + "Amplify": 1, + "Frenzied Rampage": 1, + "Rhino Kindred": 2, + "Forestwalk": 1, + "Serpent Kindred": 2, + "Assist": 2, + "Spectacle": 3, + "Loud Ruckus": 1, + "Lieutenant": 3, + "Scorpion Kindred": 2, + "Stun Counters": 1, + "Delve": 1, + "Join forces": 1, + "Illusion Kindred": 1, + "Detonate": 1, + "Disarm": 1, + "Worm Kindred": 2, + "Mine Counters": 1, + "Juggernaut Kindred": 1, + "Secret council": 1, + "Behold": 2, + "Freerunning": 2, + "Mongoose Kindred": 1, + "Kinship": 3, + "Divinity Counters": 1, + "Banding": 1, + "Spider Kindred": 2, + "Sonic Blaster": 1, + "Elephant Kindred": 2, + "Pangolin Kindred": 1, + "Impending": 1, + "Will of the Planeswalkers": 1, + "Squad": 2, + "Support": 1, + "Plant Kindred": 2, + "Selfie Shot": 1, + "Bloodrush": 6, + "Replicate": 4, + "Porcupine Kindred": 1, + "Rabbit Kindred": 1, + "Weird Kindred": 2, + "Bargain": 3, + "Fish Kindred": 2, + "Job select": 3, + "Ice Counters": 1, + "Shell Counters": 1, + "Badger Kindred": 2, + "Wage Counters": 1, + "Leech Kindred": 1, + "Murasame": 1, + "Depletion Counters": 1, + "Bio-Plasmic Scream": 1, + "Family Gathering": 1, + "Family gathering": 1, + "Allure of Slaanesh": 1, + "Fire Cross": 1, + "Seven Dwarves": 1, + "Dredge": 1, + "Mobilize": 3, + "Temporal Foresight": 1, + "Double Overdrive": 1, + "Split second": 4, + "Grandeur": 2, + "Kirin Kindred": 1, + "Convert": 2, + "Eye Kindred": 1, + "More Than Meets the Eye": 1, + "Living metal": 1, + "Slith Kindred": 1, + "Ember Counters": 1, + "Hideaway": 1, + "Mantle of Inspiration": 1, + "Ascend": 2, + "Ripple": 1, + "Synth Kindred": 1, + "Vigilance": 2, + "Tempting offer": 2, + "Read Ahead": 2, + "Advanced Species": 1, + "Summon": 1, + "Slug Kindred": 1, + "Thundaga": 1, + "Thundara": 1, + "Thunder": 1, + "Manifest dread": 2, + "Conjure": 1, + "Contested Counters": 1, + "Epic": 1, + "Praetor Kindred": 3, + "Survivor Kindred": 2, + "Ingest": 1, + "Chimera Kindred": 1, + "Monger Kindred": 1, + "Child Kindred": 1, + "Centaur Kindred": 1, + "Token Modification": 1, + "Turtle Kindred": 1, + "Bribe the Guards": 1, + "Threaten the Merchant": 1, + "Ninja Kindred": 1, + "Ninjutsu": 1 + }, + "green": { + "+1/+1 Counters": 788, + "Aggro": 1513, + "Alien Kindred": 8, + "Big Mana": 1369, + "Blink": 579, + "Combat Matters": 1513, + "Counters Matter": 993, + "Dinosaur Kindred": 87, + "Enter the Battlefield": 579, + "Leave the Battlefield": 579, + "Trample": 341, + "Voltron": 1039, + "Creature Tokens": 423, + "Enchantments Matter": 670, + "Goblin Kindred": 5, + "Human Kindred": 379, + "Merfolk Kindred": 29, + "Token Creation": 523, + "Tokens Matter": 532, + "Artifacts Matter": 455, + "Burn": 309, + "Heavy Power Hammer": 1, + "Interaction": 666, + "Little Fellas": 1385, + "Mutant Kindred": 27, + "Ravenous": 7, + "Removal": 251, + "Tyranid Kindred": 16, + "X Spells": 119, + "-1/-1 Counters": 66, + "Age Counters": 19, + "Cumulative upkeep": 15, + "Elemental Kindred": 159, + "Card Draw": 353, + "Lands Matter": 614, + "Topdeck": 259, + "Unconditional Draw": 153, + "Auras": 244, + "Cantrips": 74, + "Enchant": 191, + "Spells Matter": 1138, + "Spellslinger": 1138, + "Dog Kindred": 30, + "Shaman Kindred": 117, + "Life Matters": 346, + "Lifegain": 346, + "Lifelink": 5, + "Warrior Kindred": 262, + "Combat Tricks": 178, + "Druid Kindred": 254, + "Elf Kindred": 406, + "Mana Dork": 199, + "Ramp": 510, + "Toughness Matters": 671, + "Doctor Kindred": 6, + "Doctor's companion": 5, + "Fight": 74, + "Historics Matter": 263, + "Legends Matter": 263, + "Nitro-9": 1, + "Rebel Kindred": 3, + "Equipment Matters": 80, + "Reach": 219, + "Spider Kindred": 70, + "Deathtouch": 55, + "Ooze Kindred": 33, + "Backgrounds Matter": 11, + "Cost Reduction": 73, + "Dragon Kindred": 29, + "Flashback": 31, + "Mill": 521, + "Reanimate": 332, + "Squirrel Kindred": 33, + "Echo": 13, + "Insect Kindred": 120, + "Beast Kindred": 267, + "Evolve": 9, + "Lizard Kindred": 29, + "Infect": 64, + "Phyrexian Kindred": 71, + "Planeswalkers": 69, + "Proliferate": 21, + "Super Friends": 69, + "Vigilance": 90, + "Archer Kindred": 50, + "Megamorph": 8, + "Aristocrats": 183, + "Ouphe Kindred": 14, + "Persist": 2, + "Sacrifice Matters": 165, + "Artifact Tokens": 111, + "Artificer Kindred": 19, + "Energy": 19, + "Energy Counters": 19, + "Resource Engine": 19, + "Servo Kindred": 6, + "Flash": 63, + "Cat Kindred": 69, + "Spell Copy": 11, + "Storm": 5, + "Exhaust": 7, + "Detective Kindred": 9, + "Bargain": 5, + "Knight Kindred": 18, + "Lifegain Triggers": 6, + "Elephant Kindred": 43, + "Cycling": 52, + "Discard Matters": 86, + "Loot": 52, + "Vehicles": 25, + "Revolt": 6, + "Scout Kindred": 97, + "Stax": 282, + "Protection": 194, + "Faerie Kindred": 13, + "Soldier Kindred": 37, + "Mount Kindred": 14, + "Saddle": 9, + "Troll Kindred": 29, + "Crocodile Kindred": 11, + "Shroud": 21, + "Brushwagg Kindred": 4, + "Exile Matters": 89, + "Outlaw Kindred": 31, + "Plant Kindred": 76, + "Plot": 8, + "Warlock Kindred": 5, + "Employee Kindred": 5, + "Kavu Kindred": 14, + "Bear Kindred": 48, + "Control": 169, + "Treefolk Kindred": 87, + "Barbarian Kindred": 2, + "Snake Kindred": 92, + "Wolf Kindred": 82, + "Junk Token": 3, + "Landwalk": 58, + "Swampwalk": 10, + "Bracket:TutorNonland": 66, + "Collect evidence": 6, + "Partner": 14, + "Treasure": 26, + "Treasure Token": 25, + "Turtle Kindred": 12, + "Ward": 25, + "Elder Kindred": 3, + "Flying": 49, + "Mana Rock": 16, + "Convoke": 19, + "Ape Kindred": 26, + "Spell mastery": 3, + "Avatar Kindred": 16, + "Cascade": 4, + "Heroic": 6, + "Rooms Matter": 9, + "Frog Kindred": 26, + "Threshold": 22, + "Enrage": 10, + "Chimera Kindred": 4, + "Hydra Kindred": 45, + "Training": 3, + "Graft": 7, + "Board Wipes": 53, + "Channel": 11, + "Spirit Kindred": 103, + "Manifest": 16, + "Giant Kindred": 29, + "Monstrosity": 10, + "Clones": 42, + "Populate": 6, + "Sloth Kindred": 3, + "Hexproof": 34, + "Defender": 40, + "Boar Kindred": 30, + "Landfall": 68, + "Conditional Draw": 85, + "Powerstone Token": 2, + "Wurm Kindred": 81, + "Superfriends": 28, + "Werewolf Kindred": 75, + "Oil Counters": 8, + "Madness": 2, + "Scry": 26, + "Noble Kindred": 12, + "Monk Kindred": 27, + "Formidable": 8, + "Charge Counters": 10, + "Station": 5, + "Performer Kindred": 10, + "Alliance": 5, + "Ranger Kindred": 33, + "Coven": 7, + "Aurochs Kindred": 4, + "Elk Kindred": 23, + "Mutate": 5, + "Daybound": 13, + "Nightbound": 13, + "Counterspells": 9, + "Dryad Kindred": 38, + "Eldrazi Kindred": 38, + "Spawn Kindred": 12, + "Haste": 38, + "Legendary landwalk": 1, + "Lore Counters": 31, + "Ore Counters": 52, + "Sagas Matter": 33, + "Transform": 75, + "Delirium": 17, + "Badger Kindred": 8, + "Earthbend": 8, + "Mole Kindred": 6, + "Dwarf Kindred": 3, + "Food": 57, + "Food Token": 54, + "Raccoon Kindred": 13, + "Forestcycling": 8, + "Land Types Matter": 58, + "Kicker": 39, + "Stun Counters": 2, + "Finality Counters": 3, + "Reinforce": 5, + "Scavenge": 7, + "Pingers": 22, + "Equip": 27, + "Equipment": 29, + "Hero Kindred": 3, + "Job select": 2, + "Berserker Kindred": 8, + "Enlist": 3, + "Affinity": 2, + "Bird Kindred": 22, + "Grandeur": 1, + "Manifest dread": 11, + "Adapt": 8, + "Devoid": 22, + "Capybara Kindred": 1, + "Descend": 4, + "Shark Kindred": 1, + "Blood Token": 11, + "Bloodthirst": 7, + "Draw Triggers": 52, + "Foretell": 7, + "Wheels": 53, + "Centaur Kindred": 54, + "Theft": 15, + "Umbra armor": 6, + "Level Counters": 4, + "Level Up": 4, + "Ally Kindred": 19, + "Quest Counters": 4, + "Delve": 2, + "Intimidate": 2, + "Genomic Enhancement": 1, + "Wizard Kindred": 22, + "Morph": 26, + "Drone Kindred": 13, + "Scion Kindred": 7, + "Exert": 6, + "Jackal Kindred": 5, + "Fade Counters": 5, + "Fading": 5, + "Miracle": 2, + "Poison Counters": 39, + "Incubate": 4, + "Incubator Token": 4, + "Toxic": 12, + "Devour": 6, + "Scorpion Kindred": 4, + "Guest Kindred": 3, + "Ticket Counters": 1, + "Mongoose Kindred": 3, + "Soulshift": 12, + "Bestow": 9, + "Satyr Kindred": 17, + "Golem Kindred": 13, + "Prototype": 6, + "Kirin Kindred": 1, + "Saproling Kindred": 49, + "Halfling Kindred": 8, + "Peasant Kindred": 9, + "Incarnation Kindred": 4, + "Impulse": 2, + "Junk Tokens": 2, + "Domain": 18, + "Clue Token": 16, + "Investigate": 16, + "Sacrifice to Draw": 31, + "Evoke": 5, + "Rhino Kindred": 35, + "Provoke": 3, + "Sliver Kindred": 18, + "Warp": 8, + "Brood Telepathy": 1, + "Cleric Kindred": 23, + "Ki Counters": 3, + "Hippo Kindred": 5, + "Islandwalk": 7, + "Forage": 4, + "Offspring": 4, + "Bolster": 8, + "Hyena Kindred": 2, + "Morbid": 12, + "Rogue Kindred": 25, + "Blitz": 4, + "Citizen Kindred": 26, + "Myriad": 5, + "Fungus Kindred": 47, + "Amplify": 3, + "Crew": 9, + "Goat Kindred": 3, + "Metalcraft": 3, + "Gnome Kindred": 2, + "Wall Kindred": 21, + "Tiefling Kindred": 1, + "Cases Matter": 2, + "Forestwalk": 21, + "Survival": 5, + "Survivor Kindred": 5, + "Partner with": 5, + "Card Selection": 18, + "Explore": 18, + "Escape": 3, + "Changeling": 11, + "Shapeshifter Kindred": 12, + "Renew": 4, + "Champion": 3, + "Assist": 2, + "Acorn Counters": 1, + "Bracket:MassLandDenial": 6, + "Backup": 6, + "Natural Recovery": 1, + "Proclamator Hailer": 1, + "Fateful hour": 2, + "Gathered Swarm": 1, + "Cockatrice Kindred": 1, + "Pupa Counters": 1, + "Ninja Kindred": 4, + "Ninjutsu": 3, + "Worm Kindred": 2, + "Escalate": 1, + "Join forces": 1, + "Germ Kindred": 2, + "Living weapon": 2, + "Strive": 5, + "Open an Attraction": 3, + "Bard Kindred": 9, + "Constellation": 11, + "Buyback": 5, + "Pest Kindred": 3, + "Corrupted": 5, + "Discover": 5, + "Myr Kindred": 1, + "Exalted": 2, + "Monarch": 5, + "Suspend": 12, + "Time Counters": 14, + "Rampage": 3, + "Bracket:GameChanger": 8, + "Fabricate": 4, + "Disguise": 7, + "Horror Kindred": 28, + "Enchantment Tokens": 8, + "Role token": 5, + "Wind Counters": 2, + "Basilisk Kindred": 11, + "Cost Scaling": 3, + "Modal": 3, + "Spree": 3, + "Spellshaper Kindred": 11, + "Vanishing": 3, + "Emerge": 3, + "Surveil": 9, + "Wolverine Kindred": 4, + "Pilot Kindred": 4, + "Sand Kindred": 2, + "Immune": 1, + "Egg Kindred": 2, + "Soulbond": 8, + "Robot Kindred": 5, + "Token Modification": 7, + "Magecraft": 2, + "Zubera Kindred": 1, + "Rabbit Kindred": 10, + "Nymph Kindred": 4, + "Nonbasic landwalk": 1, + "Choose a background": 6, + "Endure": 3, + "Awaken": 1, + "Fish Kindred": 2, + "Advisor Kindred": 11, + "Venture into the dungeon": 6, + "First strike": 5, + "Spore Counters": 15, + "Antelope Kindred": 7, + "Fractal Kindred": 4, + "Epic": 1, + "Glimmer Kindred": 1, + "Djinn Kindred": 3, + "Hideaway": 3, + "Shield Counters": 5, + "Leviathan Kindred": 2, + "Eternalize": 3, + "Ferocious": 10, + "Zombie Kindred": 11, + "Melee": 2, + "Overload": 2, + "Nightmare Kindred": 1, + "Fox Kindred": 2, + "Learn": 3, + "Encore": 1, + "Salamander Kindred": 2, + "Ogre Kindred": 3, + "Clash": 6, + "Drake Kindred": 3, + "Entwine": 7, + "Atog Kindred": 1, + "Retrace": 3, + "Mercenary Kindred": 3, + "\\+2/\\+2 Counters": 1, + "Squad": 1, + "Adamant": 3, + "Hexproof from": 2, + "Loyalty Counters": 3, + "Sheep Kindred": 1, + "Support": 7, + "Beaver Kindred": 1, + "Conspire": 1, + "Converge": 4, + "Mountainwalk": 1, + "Rad Counters": 4, + "Multikicker": 4, + "Gnoll Kindred": 1, + "Pack tactics": 3, + "Shrines Matter": 3, + "God Kindred": 6, + "Ox Kindred": 5, + "Dredge": 5, + "Skeleton Kindred": 1, + "Undergrowth": 6, + "Paradox": 2, + "Crab Kindred": 1, + "Riot": 3, + "Kithkin Kindred": 3, + "Slime Counters": 1, + "Devouring Monster": 1, + "Rapacious Hunger": 1, + "Replicate": 1, + "Demonstrate": 1, + "Samurai Kindred": 5, + "Tower Counters": 1, + "Mite Kindred": 1, + "Depletion Counters": 1, + "Cloak": 1, + "Frenzied Metabolism": 1, + "Titanic": 1, + "Storage Counters": 2, + "Renown": 6, + "Embalm": 1, + "Boast": 1, + "Endless Swarm": 1, + "Undying": 4, + "Rat Kindred": 1, + "Efreet Kindred": 2, + "Indestructible": 9, + "Parley": 3, + "Harmony Counters": 1, + "Orc Kindred": 1, + "Battles Matter": 5, + "Bushido": 2, + "Leech Kindred": 2, + "Craft": 3, + "Graveyard Matters": 2, + "Flanking": 1, + "Ferret Kindred": 1, + "10,000 Needles": 1, + "Wither": 3, + "Yeti Kindred": 3, + "Phasing": 1, + "Splice": 4, + "Assassin Kindred": 2, + "Split second": 4, + "Horsemanship": 1, + "Kinship": 3, + "Lhurgoyf Kindred": 5, + "Pheromone Trail": 1, + "Awakening Counters": 1, + "Construct Kindred": 6, + "Vitality Counters": 1, + "Outlast": 2, + "Gift": 4, + "Max speed": 1, + "Start your engines!": 2, + "Lieutenant": 2, + "Unearth": 3, + "Verse Counters": 3, + "Fungus Counters": 2, + "Slug Kindred": 2, + "Growth Counters": 2, + "Horse Kindred": 9, + "Aftermath": 1, + "Infesting Spores": 1, + "Divinity Counters": 1, + "Harmonize": 3, + "Tribute": 3, + "Strategic Coordinator": 1, + "Compleated": 1, + "Unicorn Kindred": 2, + "Nomad Kindred": 1, + "Licid Kindred": 2, + "Fast Healing": 1, + "Council's dilemma": 3, + "Basic landcycling": 3, + "Landcycling": 3, + "Impending": 1, + "Mama's Coming": 1, + "Dethrone": 1, + "Will of the Planeswalkers": 1, + "Offering": 1, + "Inspired": 2, + "Chroma": 2, + "Behold": 1, + "Defense Counters": 1, + "Goad": 1, + "Rebound": 3, + "Ribbon Counters": 1, + "Scientist Kindred": 2, + "Vanguard Species": 1, + "Camel Kindred": 1, + "Wombat Kindred": 1, + "Possum Kindred": 2, + "Pangolin Kindred": 2, + "Demigod Kindred": 1, + "Recover": 1, + "Bloodrush": 4, + "Hag Kindred": 1, + "Monkey Kindred": 4, + "Undaunted": 1, + "Bracket:ExtraTurn": 1, + "Map Token": 2, + "Conjure": 1, + "Conjure Elemental": 1, + "Multiple Copies": 1, + "Slime Against Humanity": 1, + "Slith Kindred": 1, + "Spike Kindred": 10, + "Armadillo Kindred": 1, + "Spore Chimney": 1, + "Monger Kindred": 1, + "Mouse Kindred": 1, + "Supply Counters": 1, + "Abraxas": 1, + "Ripple": 1, + "Replacement Draw": 1, + "For Mirrodin!": 1, + "Rally": 2, + "Reconfigure": 2, + "Mystic Kindred": 2, + "Knickknack Counters": 1, + "Tempting offer": 1, + "Ascend": 2, + "Death Frenzy": 1, + "Hatching Counters": 2, + "Gold Token": 1, + "Read Ahead": 2, + "Bear Witness": 1, + "Final Heaven": 1, + "Meteor Strikes": 1, + "Somersault": 1, + "Banding": 1, + "Meld": 1, + "Velocity Counters": 1, + "Hypertoxic Miasma": 1, + "Dash": 1, + "Mentor": 1, + "Nest Counters": 1, + "Toy Kindred": 1, + "Shieldwall": 1, + "Freerunning": 1, + "Menace": 1, + "Processor Kindred": 1, + "Varmint Kindred": 1, + "Praetor Kindred": 3, + "-0/-1 Counters": 1, + "Scarecrow Kindred": 1, + "Gather Your Courage": 1, + "Run and Hide": 1, + "Plainswalk": 1 + } + }, + "generated_from": "tagger + constants" +} \ No newline at end of file diff --git a/config/themes/theme_whitelist.yml b/config/themes/theme_whitelist.yml new file mode 100644 index 0000000..609fb84 --- /dev/null +++ b/config/themes/theme_whitelist.yml @@ -0,0 +1,99 @@ +# Theme whitelist & governance configuration +# This file stabilizes the public theme taxonomy and synergy output. +# +# Sections: +# always_include: themes that must always appear even if frequency is low or zero +# protected_prefixes: any theme starting with one of these prefixes is never pruned +# protected_suffixes: any theme ending with one of these suffixes is never pruned +# min_frequency_overrides: per-theme minimum frequency required to retain (overrides global >1 rule) +# normalization: canonical name mapping (old -> new) +# exclusions: themes forcibly removed after normalization +# enforced_synergies: mapping of theme -> list of synergies that must be injected (before capping) +# synergy_cap: integer maximum number of synergies to emit per theme (after merging curated/enforced/inferred) +# notes: free-form documentation +# +# IMPORTANT: After editing, re-run: python code/scripts/extract_themes.py + +always_include: + - Superfriends + - Storm + - Group Hug + - Pillowfort + - Stax + - Politics + - Reanimator + - Reanimate + - Graveyard Matters + - Treasure Token + - Tokens Matter + - Counters Matter + - +1/+1 Counters + - -1/-1 Counters + - Landfall + - Lands Matter + - Outlaw Kindred + +protected_prefixes: + - Angel + - Dragon + - Elf + - Goblin + - Zombie + - Soldier + - Vampire + - Wizard + - Merfolk + - Spirit + - Sliver + - Dinosaur + - Construct + - Warrior + - Demon + - Hydra + - Treefolk + +protected_suffixes: + - Kindred + +min_frequency_overrides: + Storm: 0 + Group Hug: 0 + Pillowfort: 0 + Politics: 0 + Treasure Token: 0 + Monarch: 0 + Initiative: 0 + Pillow Fort: 0 # alias that may appear; normalization may fold it + +normalization: + ETB: Enter the Battlefield + Self Mill: Mill + Pillow Fort: Pillowfort + Reanimator: Reanimate # unify under single anchor; both appear in always_include for safety + +exclusions: + - Draw Triggers + - Placeholder + - Test Tag + +# Mandatory synergy injections independent of curated or inferred values. +# These are merged before the synergy cap is enforced. +enforced_synergies: + Counters Matter: [Proliferate] + +1/+1 Counters: [Proliferate, Counters Matter] + -1/-1 Counters: [Proliferate, Counters Matter] + Proliferate: [Counters Matter] + Creature Tokens: [Tokens Matter] + Token Creation: [Tokens Matter] + Treasure Token: [Artifacts Matter] + Reanimate: [Graveyard Matters] + Reanimator: [Graveyard Matters, Reanimate] + Graveyard Matters: [Reanimate] + +synergy_cap: 5 + +notes: | + The synergy_cap trims verbose or noisy lists to improve UI scannability. + Precedence order when capping: curated > enforced > inferred (PMI). + Enforced synergies are guaranteed inclusion (unless they duplicate existing entries). + Protected prefixes/suffixes prevent pruning of tribal / kindred families even if low frequency. diff --git a/docker-compose.yml b/docker-compose.yml index b1c7de6..471ede5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,6 +20,12 @@ services: ALLOW_MUST_HAVES: "1" # 1=enable must-include/must-exclude cards feature; 0=disable SHOW_MISC_POOL: "0" + # Random Modes (feature flags) + RANDOM_MODES: "0" # 1=enable random build endpoints and backend features + RANDOM_UI: "0" # 1=show Surprise/Theme/Reroll/Share controls in UI + RANDOM_MAX_ATTEMPTS: "5" # cap retry attempts + RANDOM_TIMEOUT_MS: "5000" # per-build timeout in ms + # Theming THEME: "dark" # system|light|dark diff --git a/dockerhub-docker-compose.yml b/dockerhub-docker-compose.yml index dca2f58..b6bcf07 100644 --- a/dockerhub-docker-compose.yml +++ b/dockerhub-docker-compose.yml @@ -21,6 +21,12 @@ services: WEB_VIRTUALIZE: "1" ALLOW_MUST_HAVES: "1" # 1=enable must-include/must-exclude cards feature; 0=disable + # Random Modes (feature flags) + RANDOM_MODES: "0" # 1=enable random build endpoints and backend features + RANDOM_UI: "0" # 1=show Surprise/Theme/Reroll/Share controls in UI + RANDOM_MAX_ATTEMPTS: "5" # cap retry attempts + RANDOM_TIMEOUT_MS: "5000" # per-build timeout in ms + # Theming THEME: "system" diff --git a/requirements.txt b/requirements.txt index 8c24cbb..8034289 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,4 +14,7 @@ python-multipart>=0.0.9 # Config/schema validation pydantic>=2.5.0 +# YAML parsing for theme whitelist governance +PyYAML>=6.0 + # Development dependencies are in requirements-dev.txt \ No newline at end of file