{ "comment": "All coordinates are relative: x is offset from screen center divided by screen height; y/w/h are divided by screen height. Filled in by calibrate.py.", "calibrated_on": "2026-07-25 15:01:11", "slots": [ { "index": 1, "cx_rel": -0.6409722222222223, "cy_rel": 0.03611111111111111 }, { "index": 2, "cx_rel": -0.5263888888888889, "cy_rel": 0.03611111111111111 }, { "index": 3, "cx_rel": -0.41180555555555554, "cy_rel": 0.03611111111111111 }, { "index": 4, "cx_rel": -0.2972222222222222, "cy_rel": 0.03611111111111111 }, { "index": 5, "cx_rel": -0.18263888888888888, "cy_rel": 0.03611111111111111 }, { "index": 6, "cx_rel": 0.18055555555555555, "cy_rel": 0.03611111111111111 }, { "index": 7, "cx_rel": 0.2951388888888889, "cy_rel": 0.03611111111111111 }, { "index": 8, "cx_rel": 0.4097222222222222, "cy_rel": 0.03611111111111111 }, { "index": 9, "cx_rel": 0.5243055555555556, "cy_rel": 0.03611111111111111 }, { "index": 10, "cx_rel": 0.6388888888888888, "cy_rel": 0.03611111111111111 } ], "slot_w_rel": 0.07708333333333334, "slot_h_rel": 0.06111111111111111, "crop_trim": { "top": 0.0, "bottom": 0.0, "left": 0.0, "right": 0.0 }, "canonical_size": 96, "match": { "min_score": 0.45, "min_margin": 0.04, "ranked_mask": { "comment": "Ignore the bottom rank-title bar and right-side medal when ranked overlays are detected.", "bottom": 0.32, "right": 0.22 } }, "mode_label": { "comment": "Strip under the draft timer that shows 全英雄选择 / 队长模式 / ...", "y0_rel": 0.045, "y1_rel": 0.072, "x0_rel": 0.40, "x1_rel": 0.60, "min_score": 0.55 }, "grid": { "comment": "Hero-selection grid. min_std separates cards from gaps; unavailable_std sits in the gap between banned/taken cards (8-21 measured) and live ones (33+).", "min_std": 18.0, "unavailable_std": 26.0 }, "text_rows": { "comment": "Rows of text under each top-bar portrait, relative to screen height.", "name": { "y0_rel": 0.075, "y1_rel": 0.09444 }, "role": { "y0_rel": 0.09722, "y1_rel": 0.11319, "min_value": 110, "max_sat": 0.08 } }, "roles": { "comment": "min_iou gates role-label matching. Own slot comes from GSI team_slot.", "min_iou": 0.55 }, "recommend": { "comment": "Full-grid 克/搭/补 from relations + draft_archetypes (push/global/gaps). After self-lock: core+answer items. top_n<=0 = no cap. No AI.", "enabled": true, "top_n": 0, "min_enemies": 1, "min_heroes_for_gaps": 2, "archetypes": true, "relations_path": "shared/data/relations.json", "role_tags": { "1": ["Carry"], "2": ["Carry", "Nuker", "Escape"], "3": ["Initiator", "Durable", "Carry"], "4": ["Support"], "5": ["Support"] }, "items": { "comment": "After self hero locked: core from hero_items + qualitative answers vs enemies. No fears/STRATZ stats.", "enabled": true, "hero_items_path": "web/data/hero_items.json", "items_meta_path": "web/data/items_meta.json", "core_n": 3, "answer_n": 3, "max_total": 6 } }, "gsi": { "comment": "Either trigger state starts one tracking session per match; strategy time is the fallback for joining late.", "port": 3223, "trigger_states": [ "DOTA_GAMERULES_STATE_HERO_SELECTION", "DOTA_GAMERULES_STATE_STRATEGY_TIME" ], "poll_interval": 1.0, "confirm_polls": 2, "revise_gain": 0.15, "session_timeout": 300, "keep_event_frames": true, "dump_selection_every": 0, "strategy_tail_polls": 8, "strategy_gsi_wait": 3.0, "require_foreground": true, "capture_interval": 1.0, "target_slots": 10, "dump_payloads": true }, "player_pages": { "comment": "POST_GAME: poll OpenDota → local pc/player_pages/{account_id}/. public_share=true POSTs /api/players/publish (queue→D1/R2). recent_limit=recent N matches; recent_days=GSI discovery window; enrich_ttl_seconds=web cache TTL (default 600, same as Pages). Default private.", "enabled": true, "public_share": false, "recent_limit": 20, "recent_days": 14, "enrich_ttl_seconds": 600, "poll_attempts": 12, "poll_base_seconds": 30, "publish_url": "https://dota2.refining.dev/api/players/publish", "publish_secret": "", "local_web_origin": "http://127.0.0.1:8765" }, "overlay": { "comment": "克/搭/补 marks + lineup analysis banner + post-lock item icon bar (no role tags under top-bar).", "enabled": true, "mark_size_rel": 0.018, "mark_pad_rel": 0.004, "mark_gap_rel": 0.002, "counter_color": "#2ec4b6", "synergy_color": "#e9a825", "fill_color": "#9b7ebd", "mark_text_color": "#0b1220", "analysis_y_rel": 0.12, "analysis_h_rel": 0.028, "analysis_font_rel": 0.014, "analysis_bg": "#1a2332", "analysis_fg": "#e8eef7", "items_y_rel": 0.16, "item_icon_h_rel": 0.036, "item_gap_rel": 0.01, "item_core_bg": "#1a2332", "item_answer_bg": "#2a1f14", "item_reason_fg": "#e8eef7" }, "calibrated_from": "draft_141704.png" }