You are an oncology clinic schedule optimizer.

Your job is to assign start_time and end_time for each treatment while satisfying EVERY hard constraint.

Output ONLY the CSV between the required markers.
Never output reasoning.

--------------------------------------------------
UNASSIGNED RULE
--------------------------------------------------

A profile is considered UNASSIGNED when:

start_time = "00:00:00"
end_time   = "00:00:00"

It is ALWAYS better to leave a profile UNASSIGNED than to violate ANY hard constraint.

Never force an assignment.

--------------------------------------------------
TIME RULES
--------------------------------------------------

• T = Schedule Time Block
• end_time = start_time + (service_duration × T minutes)
• All times must align to T-minute boundaries.
• HH:MM:SS format only.
• One treatment per profile.

--------------------------------------------------
HARD CONSTRAINTS (MUST NEVER BE VIOLATED)
--------------------------------------------------

These constraints have ABSOLUTE priority.

A treatment may ONLY be assigned if ALL constraints remain valid.

Otherwise mark the profile UNASSIGNED.

1. Chair Capacity

For EVERY occupied time slot:

occupied_chairs ≤ chair_capacity

Never exceed chair capacity even by 1.

2. RN Capacity

For EVERY slot:

RN Demand =
starts +
ends +
(mid_patients × nurse_factor)

RN Demand ≤ available_RNs

Never exceed available RNs.

3. Staff Hours

Treatment must occur completely inside staff availability.

4. Clinic Hours

start_time >= clinic_start

end_time <= clinic_end

5. Max Starts Per Slot

For EVERY individual slot:

starts_in_slot ≤ configured_max_start_limit

Read the configured value for EACH slot separately.

Do NOT assume all slots share the same limit.

This constraint MUST be validated BEFORE assigning every treatment.

6. Do Not Start

Treatment may never begin inside a Do Not Start window.

7. Do Not Book

Treatment may never occupy any Do Not Book period.

--------------------------------------------------
ASSIGNMENT ALGORITHM
--------------------------------------------------

Sort profiles:

1. Longer duration first
2. profile_id ascending

Process ONE profile at a time.

For each profile:

Search slots from earliest to latest.

A slot is VALID only if assigning the treatment keeps ALL hard constraints valid for EVERY affected slot.

Immediately after assignment:

• update chair occupancy
• update RN demand
• update starts count

All future decisions must use the updated resource counts.

If no valid slot exists:

Leave the profile UNASSIGNED.

Never move or modify already assigned profiles.

--------------------------------------------------
OPTIMIZATION GOALS
--------------------------------------------------

ONLY AFTER satisfying every hard constraint:

1. Maximize assigned profiles
2. Minimize peak chair utilization
3. Spread starts across the clinic day
4. Target roughly 50% AM / 50% PM starts
5. Start long treatments earlier whenever feasible

Optimization goals must NEVER override hard constraints.

--------------------------------------------------
MANDATORY FINAL VALIDATION
--------------------------------------------------

Before producing output, recompute the entire schedule from scratch.

Verify:

✓ Every slot respects chair capacity
✓ Every slot respects RN capacity
✓ Every slot respects Max Starts
✓ No Do Not Start violations
✓ No Do Not Book violations
✓ Clinic hours respected
✓ Staff hours respected
✓ Correct end_time calculations
✓ Same number of rows as input

If ANY violation exists:

Discard the violating assignment(s).

Mark those profiles UNASSIGNED.

Repeat validation until every hard constraint passes.

Only then output the CSV.

## SCHEDULING ALGORITHM
Use the **First Fit Decreasing** strategy:
Sort all profiles by total duration DESCENDING (longest first). For each profile in sorted order, assign it to the EARLIEST available time slot that satisfies ALL constraints (chairs, staff, max starts, clinic hours). Once placed, lock it and move to the next profile. Never revisit a placed profile. This is the recommended construction heuristic from Timefold's scheduling algorithms — it prevents long profiles from being blocked later and naturally spreads load across the day.

## CLINIC CONFIGURATION (dynamically loaded from CSV)
### CLINIC TIMING (for Monday)
- Clinic Hours: 7:00:00 - 17:00:00
- Treatment Room (TTCNP): start >= 7:00:00, end <= 17:00:00
- Lab Hours: start >= 7:00:00, end <= 17:00:00
- Nurse Factor (ongoing mid-treatment): 16% per patient → 1 RN covers up to 6.2 concurrent mid-treatment patients
- Schedule Time Block: 15 minutes per slot (all time calculations use this interval)
- *** IMPORTANT: T = 15. Use 15 minutes for ALL duration calculations, not 15. duration_minutes = service_duration × 15 ***

### RESOURCES (Physical Chairs)
- Treatment Chairs: 24 (max 24 patients using this resource simultaneously)
- Lab Chairs: 2 (max 2 patients using this resource simultaneously)
- Injection Chairs: 1 (max 1 patients using this resource simultaneously)

### STAFF AVAILABILITY (for Monday, Available only)
- RN (Registered Nurse): 07:30:00-16:45:00, 12 available per slot
- Lab Tech: 07:30:00-16:15:00, 1 available per slot
- LPN (Injection Nurse): 07:30:00-17:00:00, 1 available per slot
- MD (Provider): 08:00:00-16:15:00, 2 available per slot
- MA: 07:15:00-16:45:00, 1 available per slot

### DO NOT START RULES (for Monday)
  No Do Not Start rules configured.

### DO NOT BOOK RULES (for Monday)
  No Do Not Book rules configured.

### MAX TREATMENT STARTS PER SLOT (for Monday)
The maximum number of treatments that can START in each 15-minute slot is defined per slot below.
This is a HARD constraint — even if chairs and RNs are available, do not exceed these limits.
  - 07:00:00: max 2 treatment start(s)
  - 07:15:00: max 0 treatment start(s)
  - 07:30:00: max 1 treatment start(s)
  - 07:45:00: max 2 treatment start(s)
  - 08:00:00: max 2 treatment start(s)
  - 08:15:00: max 2 treatment start(s)
  - 08:30:00: max 3 treatment start(s)
  - 08:45:00: max 3 treatment start(s)
  - 09:00:00: max 3 treatment start(s)
  - 09:15:00: max 3 treatment start(s)
  - 09:30:00: max 3 treatment start(s)
  - 09:45:00: max 3 treatment start(s)
  - 10:00:00: max 3 treatment start(s)
  - 10:15:00: max 3 treatment start(s)
  - 10:30:00: max 3 treatment start(s)
  - 10:45:00: max 3 treatment start(s)
  - 11:00:00: max 3 treatment start(s)
  - 11:15:00: max 3 treatment start(s)
  - 11:30:00: max 3 treatment start(s)
  - 11:45:00: max 3 treatment start(s)
  - 12:00:00: max 3 treatment start(s)
  - 12:15:00: max 3 treatment start(s)
  - 12:30:00: max 3 treatment start(s)
  - 12:45:00: max 3 treatment start(s)
  - 13:00:00: max 3 treatment start(s)
  - 13:15:00: max 3 treatment start(s)
  - 13:30:00: max 3 treatment start(s)
  - 13:45:00: max 3 treatment start(s)
  - 14:00:00: max 3 treatment start(s)
  - 14:15:00: max 3 treatment start(s)
  - 14:30:00: max 3 treatment start(s)
  - 14:45:00: max 3 treatment start(s)
  - 15:00:00: max 3 treatment start(s)
  - 15:15:00: max 3 treatment start(s)
  - 15:30:00: max 3 treatment start(s)
  - 15:45:00: max 3 treatment start(s)
  - 16:00:00: max 3 treatment start(s)
  - 16:15:00: max 3 treatment start(s)
  - 16:30:00: max 0 treatment start(s)
  - 16:45:00: max 0 treatment start(s)
  - 17:00:00: max 0 treatment start(s)
  - 17:15:00: max 0 treatment start(s)
  - 17:30:00: max 0 treatment start(s)


## PROFILE LIST TO OPTIMIZE (CSV):
schedule_date,location_id,clinic_name,profile_id,service_id,start_time,service_duration,end_time,service_sequence_id,service_name
5/25/2026,20001,PostFalls,2000901,3,7:00:00,2,7:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000902,3,7:00:00,2,7:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000903,3,7:00:00,2,7:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000904,3,7:00:00,3,7:45:00,4,Treatment
5/25/2026,20001,PostFalls,2000905,3,7:00:00,3,7:45:00,4,Treatment
5/25/2026,20001,PostFalls,2000906,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000907,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000908,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000909,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000910,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000911,3,7:00:00,5,8:15:00,4,Treatment
5/25/2026,20001,PostFalls,2000912,3,7:00:00,5,8:15:00,4,Treatment
5/25/2026,20001,PostFalls,2000913,3,7:00:00,5,8:15:00,4,Treatment
5/25/2026,20001,PostFalls,2000914,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000915,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000916,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000917,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000918,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000919,3,7:00:00,7,8:45:00,4,Treatment
5/25/2026,20001,PostFalls,2000920,3,7:00:00,7,8:45:00,4,Treatment
5/25/2026,20001,PostFalls,2000921,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000922,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000923,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000924,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000925,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000926,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000927,3,7:00:00,10,9:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000928,3,7:00:00,10,9:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000929,3,7:00:00,10,9:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000930,3,7:00:00,10,9:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000931,3,7:00:00,10,9:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000932,3,7:00:00,12,10:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000933,3,7:00:00,12,10:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000934,3,7:00:00,12,10:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000935,3,7:00:00,12,10:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000936,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000937,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000938,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000939,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000940,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000941,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000942,3,7:00:00,4,8:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000943,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000944,3,7:00:00,6,8:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000945,3,7:00:00,8,9:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000946,3,7:00:00,10,9:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000947,3,7:00:00,14,10:30:00,4,Treatment
5/25/2026,20001,PostFalls,2000948,3,7:00:00,16,11:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000949,3,7:00:00,20,12:00:00,4,Treatment
5/25/2026,20001,PostFalls,2000950,3,7:00:00,24,13:00:00,4,Treatment

## OUTPUT
Complete the scheduling algorithm defined in the instructions above, then run the pre-output validation checklist. Only after all checks pass, output the CSV.

Output ONLY the CSV between the markers below. Do NOT include any reasoning, working, justification, or commentary — only the CSV block.

---CSV_START---
(CSV rows here, one per line, no header row)
---CSV_END---

Columns: schedule_date,clinic_id,clinic_name,profile_id,service_id,start_time,service_duration,end_time,service_sequence_id,service_name

Rules:
- Keep schedule_date, clinic_id, clinic_name, profile_id, service_id, service_duration, service_sequence_id, service_name UNCHANGED from input
- Assign NEW start_time and end_time values (HH:MM:SS format)
- end_time = start_time + (service_duration × Schedule_Time_Block_minutes)  [Schedule_Time_Block_minutes is defined in CLINIC TIMING]
- For UNASSIGNED profiles: set start_time="00:00:00" and end_time="00:00:00" for ALL services in that profile
- Output ALL rows (assigned + unassigned) in the exact same order as the input
- Do NOT add quotes around values
- Do NOT include a header row inside the markers
- Do NOT include any text outside the ---CSV_START--- and ---CSV_END--- markers