{"files": {"main.py": "from core import run\nfrom policy import POLICY\ndef evaluate(payload):\n    return run(payload, POLICY)\n", "core.py": "from datetime import datetime, timedelta, timezone, date\nfrom zoneinfo import ZoneInfo\nfrom helpers import parse_aware_datetime, intervals_overlap\n\ndef run(payload, policy):\n    selected_items = []\n    blocked_items = []\n    rejected_items = []\n    if not isinstance(payload, dict):\n        return {'selected': [], 'blocked': [], 'rejected': []}\n    policy = dict(policy) if isinstance(policy, dict) else {}\n    adjacency_allowed = policy.get('adjacency_allowed', True)\n    blackout_day_raw = policy.get('blackout_day')\n    cancelled_blocks = policy.get('cancelled_blocks', True)\n    capacity = policy.get('capacity', 1)\n    cutoff_hour = policy.get('cutoff_hour', 17)\n    cutoff_inclusive = policy.get('cutoff_inclusive', True)\n    duplicate_policy = policy.get('duplicate_policy', 'first')\n    duration_max = policy.get('duration_max', 120)\n    lead_minutes = policy.get('lead_minutes', 30)\n    priority_high_first = policy.get('priority_high_first', True)\n    report_order = policy.get('report_order', 'id')\n    timezone_name = policy.get('timezone', 'UTC')\n    try:\n        tz = ZoneInfo(timezone_name)\n    except Exception:\n        tz = timezone.utc\n    blackout_date = None\n    if isinstance(blackout_day_raw, str):\n        try:\n            blackout_date = date.fromisoformat(blackout_day_raw.strip())\n        except Exception:\n            blackout_date = None\n    appointments = payload.get('appointments')\n    if not isinstance(appointments, list):\n        appointments = []\n    deduped = {}\n    for idx, appt in enumerate(appointments):\n        if not isinstance(appt, dict):\n            continue\n        appt_id = appt.get('id')\n        if not isinstance(appt_id, str):\n            continue\n        if duplicate_policy == 'last':\n            deduped[appt_id] = (idx, appt)\n        else:\n            if appt_id not in deduped:\n                deduped[appt_id] = (idx, appt)\n    retained = [(appt_id, idx, appt) for appt_id, (idx, appt) in deduped.items()]\n    now_dt = parse_aware_datetime(payload.get('now'))\n    if now_dt is None:\n        rejected_items.extend((appt_id, idx) for appt_id, idx, appt in retained)\n        return _format_output(selected_items, blocked_items, rejected_items, report_order)\n    now_utc = now_dt.astimezone(timezone.utc)\n    try:\n        lead_delta = timedelta(minutes=lead_minutes)\n    except Exception:\n        lead_delta = timedelta(minutes=30)\n    earliest_start_utc = now_utc + lead_delta\n    candidates = []\n    for appt_id, idx, appt in retained:\n        cancelled = appt.get('cancelled')\n        duration = appt.get('duration')\n        priority = appt.get('priority')\n        start_raw = appt.get('start')\n        valid = True\n        if not isinstance(cancelled, bool):\n            valid = False\n        if isinstance(duration, bool) or not isinstance(duration, int):\n            valid = False\n        if isinstance(priority, bool) or not isinstance(priority, int):\n            valid = False\n        start_dt = None\n        start_utc = None\n        end_utc = None\n        if valid:\n            if duration <= 0 or duration > duration_max:\n                valid = False\n        if valid:\n            start_dt = parse_aware_datetime(start_raw)\n            if start_dt is None:\n                valid = False\n        if valid:\n            start_utc = start_dt.astimezone(timezone.utc)\n            if start_utc < earliest_start_utc:\n                valid = False\n        if valid:\n            local_start = start_utc.astimezone(tz)\n            if blackout_date is not None and local_start.date() == blackout_date:\n                valid = False\n        if valid:\n            end_utc = start_utc + timedelta(minutes=duration)\n            local_day = local_start.date()\n            try:\n                cutoff_dt = datetime(local_day.year, local_day.month, local_day.day, hour=cutoff_hour, minute=0, second=0, tzinfo=tz)\n            except Exception:\n                valid = False\n            else:\n                if cutoff_inclusive:\n                    if end_utc > cutoff_dt:\n                        valid = False\n                else:\n                    if end_utc >= cutoff_dt:\n                        valid = False\n        if valid and cancelled and not cancelled_blocks:\n            valid = False\n        if not valid:\n            rejected_items.append((appt_id, idx))\n            continue\n        candidates.append({'id': appt_id, 'index': idx, 'priority': priority, 'cancelled': cancelled, 'start_utc': start_utc, 'end_utc': end_utc})\n    if priority_high_first:\n        candidates_sorted = sorted(candidates, key=lambda c: (-c['priority'], c['index']))\n    else:\n        candidates_sorted = sorted(candidates, key=lambda c: (c['priority'], c['index']))\n    accepted_intervals = []\n    try:\n        cap_value = int(capacity)\n    except Exception:\n        cap_value = 1\n    for cand in candidates_sorted:\n        overlap_count = 0\n        for s, e in accepted_intervals:\n            if intervals_overlap(cand['start_utc'], cand['end_utc'], s, e, adjacency_allowed):\n                overlap_count += 1\n        if overlap_count < cap_value:\n            accepted_intervals.append((cand['start_utc'], cand['end_utc']))\n            if cand['cancelled']:\n                blocked_items.append((cand['id'], cand['index']))\n            else:\n                selected_items.append((cand['id'], cand['index']))\n        else:\n            rejected_items.append((cand['id'], cand['index']))\n    return _format_output(selected_items, blocked_items, rejected_items, report_order)\n\ndef _format_output(selected_items, blocked_items, rejected_items, report_order):\n    def ordered(items):\n        if report_order == 'original':\n            return [appt_id for appt_id, idx in sorted(items, key=lambda x: x[1])]\n        return [appt_id for appt_id, idx in sorted(items, key=lambda x: x[0])]\n    return {'selected': ordered(selected_items), 'blocked': ordered(blocked_items), 'rejected': ordered(rejected_items)}\n", "policy.py": "POLICY = {\"adjacency_allowed\": true, \"blackout_day\": \"2026-11-01\", \"cancelled_blocks\": true, \"capacity\": 1, \"cutoff_hour\": 17, \"cutoff_inclusive\": true, \"duplicate_policy\": \"first\", \"duration_max\": 120, \"lead_minutes\": 30, \"priority_high_first\": true, \"report_order\": \"id\", \"timezone\": \"America/New_York\"}\n", "helpers.py": "from datetime import datetime\n\ndef parse_aware_datetime(value):\n    if not isinstance(value, str):\n        return None\n    text = value.strip()\n    if not text:\n        return None\n    if text.endswith('Z') or text.endswith('z'):\n        text = text[:-1] + '+00:00'\n    try:\n        parsed = datetime.fromisoformat(text)\n    except Exception:\n        return None\n    if parsed.tzinfo is None or parsed.utcoffset() is None:\n        return None\n    return parsed\n\ndef intervals_overlap(start_a, end_a, start_b, end_b, adjacency_allowed):\n    if adjacency_allowed:\n        return start_a < end_b and start_b < end_a\n    return start_a <= end_b and start_b <= end_a\n"}}