'HH:MM'; null/empty -> em dash. */ function rr_time(?string $t): string { if ($t === null || $t === '') return '—'; return substr($t, 0, 5); } /** 7-char Mon..Sun mask -> readable text. */ function rr_run_days_text(?string $mask): string { if (!$mask || strlen($mask) < 7) return 'Running days not confirmed'; if ($mask === '1111111') return 'Daily'; $names = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']; $out = []; for ($i = 0; $i < 7; $i++) if ($mask[$i] === '1') $out[] = $names[$i]; return $out ? implode(', ', $out) : 'Running days not confirmed'; } /** Returns [human label, isUnreserved bool] using train_type text + IR numbering heuristic. */ function rr_classify(string $no, ?string $type): array { $t = strtoupper(trim((string) $type)); $un = false; foreach (['SUBURBAN', 'SUB', 'PASSENGER', 'PASS', 'MEX', 'DEMU', 'MEMU', 'MULTIPLE UNIT', 'EMU'] as $tok) { if ($t !== '' && strpos($t, $tok) !== false) { $un = true; break; } } if (!$un) { $d = $no[0] ?? ''; $reservedToken = ($t !== '' && ( strpos($t, 'EXP') !== false || strpos($t, 'SUPERFAST') !== false || strpos($t, 'MAIL') !== false || strpos($t, 'RAJ') !== false || strpos($t, 'SHAT') !== false || strpos($t, 'DURONTO') !== false || strpos($t, 'VANDE') !== false || strpos($t, 'GARIB') !== false || strpos($t, 'JAN') !== false)); if ($d !== '' && strpos('345679', $d) !== false && !$reservedToken) $un = true; } $label = $un ? 'Unreserved (general / platform ticket)' : 'Reserved (online booking available)'; return [$label, $un]; } /** Pretty train-type label. */ function rr_type_label(?string $type): string { $t = strtoupper(trim((string) $type)); if ($t === '') return 'Train'; $map = [ 'SUPERFAST' => 'Superfast Express', 'MAIL EXPRESS' => 'Mail/Express', 'RAJDHANI' => 'Rajdhani Express', 'SHATABDI' => 'Shatabdi Express', 'DURONTO' => 'Duronto Express', 'VANDE BHARAT' => 'Vande Bharat', 'GARIB RATH' => 'Garib Rath', 'JANSHATABDI' => 'Jan Shatabdi', 'JAN SHATABDI' => 'Jan Shatabdi', 'PASSENGER' => 'Passenger', 'MEMU' => 'MEMU', 'DEMU' => 'DEMU', 'SUBURBAN' => 'Suburban / Local', 'EXPRESS' => 'Express', 'MEX' => 'Mail/Express', 'EXP' => 'Express', 'SF' => 'Superfast Express', 'PASS' => 'Passenger', 'SUB' => 'Suburban / Local', ]; foreach ($map as $k => $v) if (strpos($t, $k) !== false) return $v; return ucwords(strtolower($t)); }