import SwiftUI extension Reach { var tint: Color { switch self { case .inProcess: return T.good case .systemProcess: return T.info case .kernel: return T.bad case .entitlementGated: return T.warn case .radio: return T.violet case .peripheral: return T.emberSoft } } } extension PrimitiveKind { var tint: Color { switch self { case .oobWrite: return T.ember case .oobRead: return T.warn case .uaf: return T.bad case .infoLeak: return T.violet case .typeConfusion: return T.info case .intOverflow: return T.emberSoft case .probe: return .white.opacity(0.5) } } } extension LabVerdict { var tint: Color { switch self { case .untested: return .white.opacity(0.3) case .running: return T.info case .completed: return T.good case .refused: return T.warn case .processDied: return T.ember } } } // MARK: - Lab struct LabView: View { @EnvironmentObject private var engine: LabEngine @State private var selected: ExploitModule? var body: some View { NavigationStack { ScrollView { VStack(spacing: 18) { ForEach(Catalog.groups, id: \.0) { group in VStack(alignment: .leading, spacing: 8) { SectionLabel(text: group.0) ForEach(group.1) { module in Button { selected = module } label: { moduleRow(module) } .buttonStyle(.plain) } } } } .padding(16) } .background(T.bg.ignoresSafeArea()) .navigationTitle(t("lab.title")) .navigationBarTitleDisplayMode(.inline) .sheet(item: $selected) { module in ModuleDetailView(module: module) .environmentObject(engine) .presentationDetents([.large]) } } } private func moduleRow(_ module: ExploitModule) -> some View { let verdict = engine.journal.verdict(for: module.id) let isRunning = engine.running.contains(module.id) return VStack(alignment: .leading, spacing: 7) { HStack(spacing: 8) { Text(module.title) .font(.system(size: 13.5, weight: .semibold, design: .rounded)) .foregroundColor(.white.opacity(0.92)) .lineLimit(2) .multilineTextAlignment(.leading) Spacer(minLength: 4) if isRunning { ProgressView().scaleEffect(0.6) } else { Pill(text: t(verdict.key), color: verdict.tint) } } HStack(spacing: 6) { Pill(text: module.primitive.label, color: module.primitive.tint) Pill(text: module.reach.label, color: module.reach.tint) Text(module.cve) .font(T.monoSm) .foregroundColor(.white.opacity(0.3)) .lineLimit(1) } Text(module.component) .font(T.monoSm) .foregroundColor(.white.opacity(0.28)) .lineLimit(1) } .padding(12) .frame(maxWidth: .infinity, alignment: .leading) .background(RoundedRectangle(cornerRadius: 12, style: .continuous).fill(T.panel)) .overlay(RoundedRectangle(cornerRadius: 12, style: .continuous).strokeBorder(T.stroke, lineWidth: 1)) } } struct ModuleDetailView: View { let module: ExploitModule @EnvironmentObject private var engine: LabEngine @Environment(\.dismiss) private var dismiss var body: some View { NavigationStack { ScrollView { VStack(spacing: 14) { Card { VStack(alignment: .leading, spacing: 10) { HStack(spacing: 6) { Pill(text: module.primitive.label, color: module.primitive.tint) Pill(text: module.reach.label, color: module.reach.tint) Pill(text: "T\(module.tier)", color: .white.opacity(0.5)) } Text(module.title) .font(.system(size: 19, weight: .bold, design: .rounded)) .foregroundColor(.white) Text(module.component) .font(T.mono) .foregroundColor(.white.opacity(0.4)) Text(module.cve) .font(T.mono) .foregroundColor(T.emberSoft) } } Card { VStack(alignment: .leading, spacing: 8) { SectionLabel(text: t("module.primitive")) Text(module.summary) .font(T.body) .foregroundColor(.white.opacity(0.8)) .fixedSize(horizontal: false, vertical: true) } } Card { VStack(alignment: .leading, spacing: 8) { SectionLabel(text: t("module.notes")) Text(module.notes) .font(T.body) .foregroundColor(.white.opacity(0.65)) .fixedSize(horizontal: false, vertical: true) } } if let outcome = engine.outcome(for: module.id) { Card { VStack(alignment: .leading, spacing: 8) { HStack { SectionLabel(text: t("module.result")) Spacer() Text("\(outcome.elapsedMs) ms").font(T.monoSm).foregroundColor(.white.opacity(0.3)) } Text(outcome.headline) .font(.system(size: 15, weight: .semibold, design: .rounded)) .foregroundColor(outcome.failed ? T.bad : T.good) if !outcome.detail.isEmpty { Text(outcome.detail) .font(T.monoSm) .foregroundColor(.white.opacity(0.6)) .fixedSize(horizontal: false, vertical: true) } ForEach(Array(outcome.evidence.enumerated()), id: \.offset) { _, line in Text("ยท \(line)") .font(T.monoSm) .foregroundColor(.white.opacity(0.42)) } } } } let history = engine.journal.history(for: module.id) if !history.isEmpty { Card { VStack(alignment: .leading, spacing: 6) { SectionLabel(text: t("module.history")) ForEach(history.suffix(6)) { entry in HStack(spacing: 8) { Text(entry.phase) .font(T.monoSm) .foregroundColor(entry.phase == "died" ? T.ember : .white.opacity(0.4)) .frame(width: 46, alignment: .leading) Text(entry.detail) .font(T.monoSm) .foregroundColor(.white.opacity(0.35)) .lineLimit(1) } } } } } RunButton(title: engine.running.contains(module.id) ? t("module.running") : t("module.run"), systemImage: "bolt.fill", tint: module.primitive.tint, disabled: engine.running.contains(module.id)) { engine.run(module) } Text(t("module.warning")) .font(T.tiny) .foregroundColor(.white.opacity(0.32)) .fixedSize(horizontal: false, vertical: true) } .padding(16) } .background(T.bg.ignoresSafeArea()) .navigationTitle(t("tab.lab")) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .topBarTrailing) { Button(t("module.close")) { dismiss() }.tint(T.ember) } } } } }